manager.php (7787B)
1 <?php 2 namespace Elementor\Core\Settings\Base; 3 4 use Elementor\Core\Common\Modules\Ajax\Module as Ajax; 5 use Elementor\Plugin; 6 7 if ( ! defined( 'ABSPATH' ) ) { 8 exit; // Exit if accessed directly. 9 } 10 11 /** 12 * Elementor settings base manager. 13 * 14 * Elementor settings base manager handler class is responsible for registering 15 * and managing Elementor settings base managers. 16 * 17 * @since 1.6.0 18 * @abstract 19 */ 20 abstract class Manager { 21 22 /** 23 * Models cache. 24 * 25 * Holds all the models. 26 * 27 * @since 1.6.0 28 * @access private 29 * 30 * @var Model[] 31 */ 32 private $models_cache = []; 33 34 /** 35 * Settings base manager constructor. 36 * 37 * Initializing Elementor settings base manager. 38 * 39 * @since 1.6.0 40 * @access public 41 */ 42 public function __construct() { 43 add_action( 'elementor/editor/init', [ $this, 'on_elementor_editor_init' ] ); 44 45 add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] ); 46 } 47 48 /** 49 * Register ajax actions. 50 * 51 * Add new actions to handle data after an ajax requests returned. 52 * 53 * Fired by `elementor/ajax/register_actions` action. 54 * 55 * @since 2.0.0 56 * @access public 57 * 58 * @param Ajax $ajax_manager 59 */ 60 public function register_ajax_actions( $ajax_manager ) { 61 $name = $this->get_name(); 62 63 $ajax_manager->register_ajax_action( "save_{$name}_settings", [ $this, 'ajax_save_settings' ] ); 64 } 65 66 /** 67 * Get model for config. 68 * 69 * Retrieve the model for settings configuration. 70 * 71 * @since 1.6.0 72 * @access public 73 * @abstract 74 * 75 * @return Model The model object. 76 */ 77 abstract public function get_model_for_config(); 78 79 /** 80 * Get manager name. 81 * 82 * Retrieve settings manager name. 83 * 84 * @since 1.6.0 85 * @access public 86 * @abstract 87 */ 88 abstract public function get_name(); 89 90 /** 91 * Get model. 92 * 93 * Retrieve the model for any given model ID. 94 * 95 * @since 1.6.0 96 * @access public 97 * 98 * @param int $id Optional. Model ID. Default is `0`. 99 * 100 * @return Model The model. 101 */ 102 final public function get_model( $id = 0 ) { 103 if ( ! isset( $this->models_cache[ $id ] ) ) { 104 $this->create_model( $id ); 105 } 106 107 return $this->models_cache[ $id ]; 108 } 109 110 /** 111 * Ajax request to save settings. 112 * 113 * Save settings using an ajax request. 114 * 115 * @since 1.6.0 116 * @access public 117 * 118 * @param array $request Ajax request. 119 * 120 * @return array Ajax response data. 121 */ 122 final public function ajax_save_settings( $request ) { 123 $data = $request['data']; 124 125 $id = 0; 126 127 if ( ! empty( $request['id'] ) ) { 128 $id = $request['id']; 129 } 130 131 $this->ajax_before_save_settings( $data, $id ); 132 133 $this->save_settings( $data, $id ); 134 135 $settings_name = $this->get_name(); 136 137 $success_response_data = []; 138 139 /** 140 * Settings success response data. 141 * 142 * Filters the success response data when saving settings using ajax. 143 * 144 * The dynamic portion of the hook name, `$settings_name`, refers to the settings name. 145 * 146 * @since 2.0.0 147 * 148 * @param array $success_response_data Success response data. 149 * @param int $id Settings ID. 150 * @param array $data Settings data. 151 */ 152 $success_response_data = apply_filters( "elementor/settings/{$settings_name}/success_response_data", $success_response_data, $id, $data ); 153 154 return $success_response_data; 155 } 156 157 /** 158 * Save settings. 159 * 160 * Save settings to the database. 161 * 162 * @since 1.6.0 163 * @access public 164 * 165 * @param array $settings Settings. 166 * @param int $id Optional. Post ID. Default is `0`. 167 */ 168 public function save_settings( array $settings, $id = 0 ) { 169 $special_settings = $this->get_special_settings_names(); 170 171 $settings_to_save = $settings; 172 173 foreach ( $special_settings as $special_setting ) { 174 if ( isset( $settings_to_save[ $special_setting ] ) ) { 175 unset( $settings_to_save[ $special_setting ] ); 176 } 177 } 178 179 $this->save_settings_to_db( $settings_to_save, $id ); 180 181 // Clear cache after save. 182 if ( isset( $this->models_cache[ $id ] ) ) { 183 unset( $this->models_cache[ $id ] ); 184 } 185 } 186 187 /** 188 * On Elementor init. 189 * 190 * Add editor template for the settings 191 * 192 * Fired by `elementor/init` action. 193 * 194 * @since 2.3.0 195 * @access public 196 */ 197 public function on_elementor_editor_init() { 198 Plugin::$instance->common->add_template( $this->get_editor_template(), 'text' ); 199 } 200 201 /** 202 * Get saved settings. 203 * 204 * Retrieve the saved settings from the database. 205 * 206 * @since 1.6.0 207 * @access protected 208 * @abstract 209 * 210 * @param int $id Post ID. 211 */ 212 abstract protected function get_saved_settings( $id ); 213 214 /** 215 * Save settings to DB. 216 * 217 * Save settings to the database. 218 * 219 * @since 1.6.0 220 * @access protected 221 * @abstract 222 * 223 * @param array $settings Settings. 224 * @param int $id Post ID. 225 */ 226 abstract protected function save_settings_to_db( array $settings, $id ); 227 228 /** 229 * Get special settings names. 230 * 231 * Retrieve the names of the special settings that are not saved as regular 232 * settings. Those settings have a separate saving process. 233 * 234 * @since 1.6.0 235 * @access protected 236 * 237 * @return array Special settings names. 238 */ 239 protected function get_special_settings_names() { 240 return []; 241 } 242 243 /** 244 * Ajax before saving settings. 245 * 246 * Validate the data before saving it and updating the data in the database. 247 * 248 * @since 1.6.0 249 * @access public 250 * 251 * @param array $data Post data. 252 * @param int $id Post ID. 253 */ 254 public function ajax_before_save_settings( array $data, $id ) {} 255 256 /** 257 * Print the setting template content in the editor. 258 * 259 * Used to generate the control HTML in the editor using Underscore JS 260 * template. The variables for the class are available using `data` JS 261 * object. 262 * 263 * @since 1.6.0 264 * @access protected 265 * 266 * @param string $name Settings panel name. 267 */ 268 protected function print_editor_template_content( $name ) { 269 ?> 270 <# 271 const tabs = elementor.config.settings.<?php 272 // PHPCS - the variable $name does not contain a user input value. 273 echo $name; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 274 ?>.tabs; 275 276 if ( Object.values( tabs ).length > 1 ) { #> 277 <div class="elementor-panel-navigation"> 278 <# _.each( tabs, function( tabTitle, tabSlug ) { 279 $e.bc.ensureTab( 'panel/<?php 280 // PHPCS - the variable $name does not contain a user input value. 281 echo $name; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped 282 ?>-settings', tabSlug ); #> 283 <div class="elementor-component-tab elementor-panel-navigation-tab elementor-tab-control-{{ tabSlug }}" data-tab="{{ tabSlug }}"> 284 <a href="#">{{{ tabTitle }}}</a> 285 </div> 286 <# } ); #> 287 </div> 288 <# } #> 289 <div id="elementor-panel-<?php echo esc_attr( $name ); ?>-settings-controls"></div> 290 <?php 291 } 292 293 /** 294 * Create model. 295 * 296 * Create a new model object for any given model ID and store the object in 297 * models cache property for later use. 298 * 299 * @since 1.6.0 300 * @access private 301 * 302 * @param int $id Model ID. 303 */ 304 private function create_model( $id ) { 305 $class_parts = explode( '\\', get_called_class() ); 306 307 array_splice( $class_parts, count( $class_parts ) - 1, 1, 'Model' ); 308 309 $class_name = implode( '\\', $class_parts ); 310 311 $this->models_cache[ $id ] = new $class_name( [ 312 'id' => $id, 313 'settings' => $this->get_saved_settings( $id ), 314 ] ); 315 } 316 317 /** 318 * Get editor template. 319 * 320 * Retrieve the final HTML for the editor. 321 * 322 * @since 1.6.0 323 * @access private 324 * 325 * @return string Settings editor template. 326 */ 327 private function get_editor_template() { 328 $name = $this->get_name(); 329 330 ob_start(); 331 ?> 332 <script type="text/template" id="tmpl-elementor-panel-<?php echo esc_attr( $name ); ?>-settings"> 333 <?php $this->print_editor_template_content( $name ); ?> 334 </script> 335 <?php 336 337 return ob_get_clean(); 338 } 339 }