PluginProbe
Elementor Website Builder – more than just a page builder / 3.0.13
Elementor Website Builder – more than just a page builder v3.0.13
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
← All changes | includes/base/widget-base.php +45 -248 4.2.23.0.13 View file →
@@ -1,10 +1,7 @@
1 1 <?php
2 2 namespace Elementor;
3 3
4 -use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
5 -use Elementor\Utils;
6 -
7 4 if ( ! defined( 'ABSPATH' ) ) {
8 5 exit; // Exit if accessed directly.
9 6 }
10 7
@@ -19,8 +16,9 @@
19 16 * @since 1.0.0
20 17 * @abstract
21 18 */
22 19 abstract class Widget_Base extends Element_Base {
20 +
23 21 /**
24 22 * Whether the widget has content.
25 23 *
26 24 * Used in cases where the widget has no content. When widgets uses only
@@ -33,24 +31,9 @@
33 31 * @var bool
34 32 */
35 33 protected $_has_template_content = true;
36 34
37 - private $is_first_section = true;
38 -
39 35 /**
40 - * Registered Runtime Widgets.
41 - *
42 - * Registering in runtime all widgets that are being used on the page.
43 - *
44 - * @since 3.3.0
45 - * @access public
46 - * @static
47 - *
48 - * @var array
49 - */
50 - public static $registered_runtime_widgets = [];
51 -
52 - /**
53 36 * Get element type.
54 37 *
55 38 * Retrieve the element type, in this case `widget`.
56 39 *
@@ -106,22 +89,8 @@
106 89 return [ 'general' ];
107 90 }
108 91
109 92 /**
110 - * Get widget upsale data.
111 - *
112 - * Retrieve the widget promotion data.
113 - *
114 - * @since 3.18.0
115 - * @access protected
116 - *
117 - * @return array|null Widget promotion data.
118 - */
119 - protected function get_upsale_data() {
120 - return null;
121 - }
122 -
123 - /**
124 93 * Widget base constructor.
125 94 *
126 95 * Initializing the widget base class.
127 96 *
@@ -139,20 +108,14 @@
139 108
140 109 $is_type_instance = $this->is_type_instance();
141 110
142 111 if ( ! $is_type_instance && null === $args ) {
143 - throw new \Exception( 'An `$args` argument is required when initializing a full widget instance.' );
112 + throw new \Exception( '`$args` argument is required when initializing a full widget instance.' );
144 113 }
145 114
146 115 if ( $is_type_instance ) {
147 - if ( $this->has_own_method( '_register_skins', self::class ) ) {
148 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_register_skins', '3.1.0', __CLASS__ . '::register_skins()' );
116 + $this->_register_skins();
149 117
150 - $this->_register_skins();
151 - } else {
152 - $this->register_skins();
153 - }
154 -
155 118 $widget_name = $this->get_name();
156 119
157 120 /**
158 121 * Widget skin init.
@@ -183,11 +146,11 @@
183 146 */
184 147 public function get_stack( $with_common_controls = true ) {
185 148 $stack = parent::get_stack();
186 149
187 - if ( $with_common_controls && ! $this instanceof Widget_Common_Base ) {
188 - /** @var Widget_Common_Base $common_widget */
189 - $common_widget = Plugin::$instance->widgets_manager->get_widget_types( $this->get_common_widget_name() );
150 + if ( $with_common_controls && 'common' !== $this->get_unique_name() ) {
151 + /** @var Widget_Common $common_widget */
152 + $common_widget = Plugin::$instance->widgets_manager->get_widget_types( 'common' );
190 153
191 154 $stack['controls'] = array_merge( $stack['controls'], $common_widget->get_controls() );
192 155
193 156 $stack['tabs'] = array_merge( $stack['tabs'], $common_widget->get_tabs_controls() );
@@ -195,16 +158,8 @@
195 158
196 159 return $stack;
197 160 }
198 161
199 - private function get_common_widget_name() {
200 - if ( Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ) ) {
201 - return $this->has_widget_inner_wrapper() ? 'common' : 'common-optimized';
202 - }
203 -
204 - return 'common';
205 - }
206 -
207 162 /**
208 163 * Get widget controls pointer index.
209 164 *
210 165 * Retrieve widget pointer index where the next control should be added.
@@ -241,21 +196,8 @@
241 196 return true;
242 197 }
243 198
244 199 /**
245 - * Hide on search.
246 - *
247 - * Whether to hide the widget on search in the panel or not. By default returns false.
248 - *
249 - * @access public
250 - *
251 - * @return bool Whether to hide the widget when searching for widget or not.
252 - */
253 - public function hide_on_search() {
254 - return false;
255 - }
256 -
257 - /**
258 200 * Start widget controls section.
259 201 *
260 202 * Used to add a new section of controls to the widget. Regular controls and
261 203 * skin controls.
@@ -271,12 +213,14 @@
271 213 */
272 214 public function start_controls_section( $section_id, array $args = [] ) {
273 215 parent::start_controls_section( $section_id, $args );
274 216
275 - if ( $this->is_first_section ) {
217 + static $is_first_section = true;
218 +
219 + if ( $is_first_section ) {
276 220 $this->register_skin_control();
277 221
278 - $this->is_first_section = false;
222 + $is_first_section = false;
279 223 }
280 224 }
281 225
282 226 /**
@@ -293,9 +237,9 @@
293 237 if ( ! empty( $skins ) ) {
294 238 $skin_options = [];
295 239
296 240 if ( $this->_has_template_content ) {
297 - $skin_options[''] = esc_html__( 'Default', 'elementor' );
241 + $skin_options[''] = __( 'Default', 'elementor' );
298 242 }
299 243
300 244 foreach ( $skins as $skin_id => $skin ) {
301 245 $skin_options[ $skin_id ] = $skin->get_title();
@@ -300,9 +244,9 @@
300 244 foreach ( $skins as $skin_id => $skin ) {
301 245 $skin_options[ $skin_id ] = $skin->get_title();
302 246 }
303 247
304 - // Get the first item for default value.
248 + // Get the first item for default value
305 249 $default_value = array_keys( $skin_options );
306 250 $default_value = array_shift( $default_value );
307 251
308 252 if ( 1 >= count( $skin_options ) ) {
@@ -308,9 +252,9 @@
308 252 if ( 1 >= count( $skin_options ) ) {
309 253 $this->add_control(
310 254 '_skin',
311 255 [
312 - 'label' => esc_html__( 'Skin', 'elementor' ),
256 + 'label' => __( 'Skin', 'elementor' ),
313 257 'type' => Controls_Manager::HIDDEN,
314 258 'default' => $default_value,
315 259 ]
316 260 );
@@ -317,9 +261,9 @@
317 261 } else {
318 262 $this->add_control(
319 263 '_skin',
320 264 [
321 - 'label' => esc_html__( 'Skin', 'elementor' ),
265 + 'label' => __( 'Skin', 'elementor' ),
322 266 'type' => Controls_Manager::SELECT,
323 267 'default' => $default_value,
324 268 'options' => $skin_options,
325 269 ]
@@ -328,21 +272,8 @@
328 272 }
329 273 }
330 274
331 275 /**
332 - * Register widget skins - deprecated prefixed method
333 - *
334 - * @since 1.7.12
335 - * @access protected
336 - * @deprecated 3.1.0 Use `register_skins()` method instead.
337 - */
338 - protected function _register_skins() {
339 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', 'register_skins()' );
340 -
341 - $this->register_skins();
342 - }
343 -
344 - /**
345 276 * Register widget skins.
346 277 *
347 278 * This method is activated while initializing the widget base class. It is
348 279 * used to assign skins to widgets with `add_skin()` method.
@@ -348,16 +279,16 @@
348 279 * used to assign skins to widgets with `add_skin()` method.
349 280 *
350 281 * Usage:
351 282 *
352 - * protected function register_skins() {
283 + * protected function _register_skins() {
353 284 * $this->add_skin( new Skin_Classic( $this ) );
354 285 * }
355 286 *
356 - * @since 3.1.0
287 + * @since 1.7.12
357 288 * @access protected
358 289 */
359 - protected function register_skins() {}
290 + protected function _register_skins() {}
360 291
361 292 /**
362 293 * Get initial config.
363 294 *
@@ -378,23 +309,10 @@
378 309 'keywords' => $this->get_keywords(),
379 310 'categories' => $this->get_categories(),
380 311 'html_wrapper_class' => $this->get_html_wrapper_class(),
381 312 'show_in_panel' => $this->show_in_panel(),
382 - 'hide_on_search' => $this->hide_on_search(),
383 - 'upsale_data' => Plugin::$instance->experiments->is_feature_active( 'e_panel_promotions' ) ? null : $this->get_upsale_data(),
384 - 'is_dynamic_content' => $this->is_dynamic_content(),
385 - 'has_widget_inner_wrapper' => $this->has_widget_inner_wrapper(),
386 313 ];
387 314
388 - if ( isset( $config['upsale_data'] ) && is_array( $config['upsale_data'] ) ) {
389 - $filter_name = 'elementor/widgets/' . $this->get_name() . '/custom_promotion';
390 - $config['upsale_data'] = Filtered_Promotions_Manager::get_filtered_promotion_data( $config['upsale_data'], $filter_name, 'upgrade_url' );
391 - }
392 -
393 - if ( isset( $config['upsale_data']['image'] ) ) {
394 - $config['upsale_data']['image'] = esc_url( $config['upsale_data']['image'] );
395 - }
396 -
397 315 $stack = Plugin::$instance->controls_manager->get_element_stack( $this );
398 316
399 317 if ( $stack ) {
400 318 $config['controls'] = $this->get_stack( false )['controls'];
@@ -400,9 +318,9 @@
400 318 $config['controls'] = $this->get_stack( false )['controls'];
401 319 $config['tabs_controls'] = $this->get_tabs_controls();
402 320 }
403 321
404 - return array_replace_recursive( parent::get_initial_config(), $config );
322 + return array_merge( parent::get_initial_config(), $config );
405 323 }
406 324
407 325 /**
408 326 * @since 2.3.1
@@ -423,15 +341,15 @@
423 341 *
424 342 * @param string $template_content Template content.
425 343 */
426 344 protected function print_template_content( $template_content ) {
427 - if ( $this->has_widget_inner_wrapper() ) : ?>
345 + ?>
428 346 <div class="elementor-widget-container">
429 - <?php endif;
430 - Utils::print_unescaped_internal_string( $template_content );
431 - if ( $this->has_widget_inner_wrapper() ) : ?>
347 + <?php
348 + echo $template_content; // XSS ok.
349 + ?>
432 350 </div>
433 - <?php endif;
351 + <?php
434 352 }
435 353
436 354 /**
437 355 * Parse text editor.
@@ -461,22 +379,8 @@
461 379 return $content;
462 380 }
463 381
464 382 /**
465 - * Safe print parsed text editor.
466 - *
467 - * @uses static::parse_text_editor.
468 - *
469 - * @access protected
470 - *
471 - * @param string $content Text editor content.
472 - */
473 - final protected function print_text_editor( $content ) {
474 - // PHPCS - the method `parse_text_editor` is safe.
475 - echo static::parse_text_editor( $content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
476 - }
477 -
478 - /**
479 383 * Get HTML wrapper class.
480 384 *
481 385 * Retrieve the widget container class. Can be used to override the
482 386 * container class for specific widgets.
@@ -495,10 +399,10 @@
495 399 *
496 400 * @since 1.0.0
497 401 * @access protected
498 402 */
499 - protected function add_render_attributes() {
500 - parent::add_render_attributes();
403 + protected function _add_render_attributes() {
404 + parent::_add_render_attributes();
501 405
502 406 $this->add_render_attribute(
503 407 '_wrapper', 'class', [
504 408 'elementor-widget',
@@ -541,17 +445,18 @@
541 445 *
542 446 * Used to add Light-Box-related data attributes to links that open media files.
543 447 *
544 448 * @param array|string $element The link HTML element.
545 - * @param int $id The ID of the image.
546 - * @param string $lightbox_setting_key The setting key that dictates whether to open the image in a lightbox.
547 - * @param string $group_id Unique ID for a group of lightbox images.
548 - * @param bool $overwrite Optional. Whether to overwrite existing
549 - * attribute. Default is false, not to overwrite.
449 + * @param int $id The ID of the image
450 + * @param string $lightbox_setting_key The setting key that dictates weather to open the image in a lightbox
451 + * @param string $group_id Unique ID for a group of lightbox images
452 + * @param bool $overwrite Optional. Whether to overwrite existing
453 + * attribute. Default is false, not to overwrite.
550 454 *
551 455 * @return Widget_Base Current instance of the widget.
552 456 * @since 2.9.0
553 457 * @access public
458 + *
554 459 */
555 460 public function add_lightbox_data_attributes( $element, $id = null, $lightbox_setting_key = null, $group_id = null, $overwrite = false ) {
556 461 $kit = Plugin::$instance->kits_manager->get_active_kit();
557 462
@@ -558,9 +463,9 @@
558 463 $is_global_image_lightbox_enabled = 'yes' === $kit->get_settings( 'global_image_lightbox' );
559 464
560 465 if ( 'no' === $lightbox_setting_key ) {
561 466 if ( $is_global_image_lightbox_enabled ) {
562 - $this->add_render_attribute( $element, 'data-elementor-open-lightbox', 'no', $overwrite );
467 + $this->add_render_attribute( $element, 'data-elementor-open-lightbox', 'no' );
563 468 }
564 469
565 470 return $this;
566 471 }
@@ -570,19 +475,10 @@
570 475 }
571 476
572 477 $attributes['data-elementor-open-lightbox'] = 'yes';
573 478
574 - $action_hash_params = [];
575 -
576 - if ( $id ) {
577 - $action_hash_params['id'] = $id;
578 - $action_hash_params['url'] = wp_get_attachment_url( $id );
579 - }
580 -
581 479 if ( $group_id ) {
582 480 $attributes['data-elementor-lightbox-slideshow'] = $group_id;
583 -
584 - $action_hash_params['slideshow'] = $group_id;
585 481 }
586 482
587 483 if ( $id ) {
588 484 $lightbox_image_attributes = Plugin::$instance->images_manager->get_lightbox_image_attributes( $id );
@@ -595,10 +491,8 @@
595 491 $attributes['data-elementor-lightbox-description'] = $lightbox_image_attributes['description'];
596 492 }
597 493 }
598 494
599 - $attributes['data-e-action-hash'] = Plugin::instance()->frontend->create_action_hash( 'lightbox', $action_hash_params );
600 -
601 495 $this->add_render_attribute( $element, $attributes, null, $overwrite );
602 496
603 497 return $this;
604 498 }
@@ -640,15 +534,11 @@
640 534
641 535 if ( empty( $widget_content ) ) {
642 536 return;
643 537 }
644 - if ( $this->has_widget_inner_wrapper() ) : ?>
538 + ?>
645 539 <div class="elementor-widget-container">
646 - <?php endif; ?>
647 540 <?php
648 - if ( $this->is_widget_first_render( $this->get_group_name() ) ) {
649 - $this->register_runtime_widget( $this->get_group_name() );
650 - }
651 541
652 542 /**
653 543 * Render widget content.
654 544 *
@@ -659,19 +549,15 @@
659 549 * @param string $widget_content The content of the widget.
660 550 * @param Widget_Base $this The widget.
661 551 */
662 552 $widget_content = apply_filters( 'elementor/widget/render_content', $widget_content, $this );
663 - Utils::print_unescaped_internal_string( $widget_content );
553 +
554 + echo $widget_content; // XSS ok.
664 555 ?>
665 - <?php if ( $this->has_widget_inner_wrapper() ) : ?>
666 556 </div>
667 - <?php endif;
557 + <?php
668 558 }
669 559
670 - protected function is_widget_first_render( $widget_name ) {
671 - return ! in_array( $widget_name, self::$registered_runtime_widgets, true );
672 - }
673 -
674 560 /**
675 561 * Render widget plain content.
676 562 *
677 563 * Elementor saves the page content in a unique way, but it's not the way
@@ -696,16 +582,8 @@
696 582 public function render_plain_content() {
697 583 $this->render_content();
698 584 }
699 585
700 - public function render_markdown(): string {
701 - ob_start();
702 - $this->render_content();
703 - $html = ob_get_clean();
704 -
705 - return wp_strip_all_tags( $html );
706 - }
707 -
708 586 /**
709 587 * Before widget rendering.
710 588 *
711 589 * Used to add stuff before the widget `_wrapper` element.
@@ -777,33 +655,13 @@
777 655 *
778 656 * @since 1.0.0
779 657 * @access protected
780 658 */
781 - protected function print_content() {
659 + protected function _print_content() {
782 660 $this->render_content();
783 661 }
784 662
785 663 /**
786 - * Print a setting content without escaping.
787 - *
788 - * Script tags are allowed on frontend according to the WP theme securing policy.
789 - *
790 - * @param string $setting
791 - * @param null $repeater_name
792 - * @param null $index
793 - */
794 - final public function print_unescaped_setting( $setting, $repeater_name = null, $index = null ) {
795 - if ( $repeater_name ) {
796 - $repeater = $this->get_settings_for_display( $repeater_name );
797 - $output = $repeater[ $index ][ $setting ];
798 - } else {
799 - $output = $this->get_settings_for_display( $setting );
800 - }
801 -
802 - echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
803 - }
804 -
805 - /**
806 664 * Get default data.
807 665 *
808 666 * Retrieve the default widget data. Used to reset the data on initialization.
809 667 *
@@ -855,9 +713,9 @@
855 713 * @access protected
856 714 *
857 715 * @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
858 716 * @param string $repeater_key The repeater key containing the array of all the items in the repeater (e.g. `tabs`).
859 - * @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
717 + * @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
860 718 *
861 719 * @return string The repeater setting key (e.g. `tabs.3.tab_title`).
862 720 */
863 721 protected function get_repeater_setting_key( $setting_key, $repeater_key, $repeater_item_index ) {
@@ -906,9 +764,9 @@
906 764 /**
907 765 * Add new skin.
908 766 *
909 767 * Register new widget skin to allow the user to set custom designs. Must be
910 - * called inside the `register_skins()` method.
768 + * called inside the `_register_skins()` method.
911 769 *
912 770 * @since 1.0.0
913 771 * @access public
914 772 *
@@ -999,33 +857,17 @@
999 857 return Plugin::$instance->skins_manager->get_skins( $this );
1000 858 }
1001 859
1002 860 /**
1003 - * Get group name.
1004 - *
1005 - * Some widgets need to use group names, this method allows you to create them.
1006 - * By default it retrieves the regular name.
1007 - *
1008 - * @since 3.3.0
1009 - * @access public
1010 - *
1011 - * @return string Unique name.
861 + * @param string $plugin_title Plugin's title
862 + * @param string $since Plugin version widget was deprecated
863 + * @param string $last Plugin version in which the widget will be removed
864 + * @param string $replacement Widget replacement
1012 865 */
1013 - public function get_group_name() {
1014 - return $this->get_name();
1015 - }
1016 -
1017 - /**
1018 - * @param string $plugin_title Plugin's title.
1019 - * @param string $since Plugin version widget was deprecated.
1020 - * @param string $last Plugin version in which the widget will be removed.
1021 - * @param string $replacement Widget replacement.
1022 - */
1023 866 protected function deprecated_notice( $plugin_title, $since, $last = '', $replacement = '' ) {
1024 - $this->start_controls_section(
1025 - 'Deprecated',
867 + $this->start_controls_section( 'Deprecated',
1026 868 [
1027 - 'label' => esc_html__( 'Deprecated', 'elementor' ),
869 + 'label' => __( 'Deprecated', 'elementor' ),
1028 870 ]
1029 871 );
1030 872
1031 873 $this->add_control(
@@ -1040,52 +882,7 @@
1040 882 ]
1041 883 );
1042 884
1043 885 $this->end_controls_section();
1044 - }
1045 886
1046 - /**
1047 - * Init controls.
1048 - *
1049 - * Reset the `is_first_section` flag to true, so when the Stacks are cleared
1050 - * all the controls will be registered again with their skins and settings.
1051 - *
1052 - * @since 3.14.0
1053 - * @access protected
1054 - */
1055 - protected function init_controls() {
1056 - $this->is_first_section = true;
1057 - parent::init_controls();
1058 - }
1059 -
1060 - public function register_runtime_widget( $widget_name ) {
1061 - self::$registered_runtime_widgets[] = $widget_name;
1062 - }
1063 -
1064 - /**
1065 - * Mark widget as deprecated.
1066 - *
1067 - * Use `get_deprecation_message()` method to print the message control at specific location in register_controls().
1068 - *
1069 - * @param string $version The version of Elementor that deprecated the widget.
1070 - * @param string $message A message regarding the deprecation.
1071 - * @param string $replacement The widget that should be used instead.
1072 - */
1073 - protected function add_deprecation_message( $version, $message, $replacement ) {
1074 - // Expose the config for handling in JS.
1075 - $this->set_config( 'deprecation', [
1076 - 'version' => $version,
1077 - 'message' => $message,
1078 - 'replacement' => $replacement,
1079 - ] );
1080 -
1081 - $this->add_control(
1082 - 'deprecation_message',
1083 - [
1084 - 'type' => Controls_Manager::ALERT,
1085 - 'alert_type' => 'info',
1086 - 'content' => $message,
1087 - 'separator' => 'after',
1088 - ]
1089 - );
1090 887 }
1091 888 }