PluginProbe
Elementor Website Builder – more than just a page builder / 3.4.0-dev9
Elementor Website Builder – more than just a page builder v3.4.0-dev9
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 +90 -147 4.2.33.4.0-dev9 View file →
@@ -1,9 +1,8 @@
1 1 <?php
2 2 namespace Elementor;
3 3
4 -use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
5 -use Elementor\Utils;
4 +use Elementor\Core\Page_Assets\Data_Managers\Widgets_Css as Widgets_Css_Data_Manager;
6 5
7 6 if ( ! defined( 'ABSPATH' ) ) {
8 7 exit; // Exit if accessed directly.
9 8 }
@@ -33,10 +32,8 @@
33 32 * @var bool
34 33 */
35 34 protected $_has_template_content = true;
36 35
37 - private $is_first_section = true;
38 -
39 36 /**
40 37 * Registered Runtime Widgets.
41 38 *
42 39 * Registering in runtime all widgets that are being used on the page.
@@ -48,8 +45,10 @@
48 45 * @var array
49 46 */
50 47 public static $registered_runtime_widgets = [];
51 48
49 + private static $widgets_css_data_manager;
50 +
52 51 /**
53 52 * Get element type.
54 53 *
55 54 * Retrieve the element type, in this case `widget`.
@@ -106,22 +105,8 @@
106 105 return [ 'general' ];
107 106 }
108 107
109 108 /**
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 109 * Widget base constructor.
125 110 *
126 111 * Initializing the widget base class.
127 112 *
@@ -139,9 +124,9 @@
139 124
140 125 $is_type_instance = $this->is_type_instance();
141 126
142 127 if ( ! $is_type_instance && null === $args ) {
143 - throw new \Exception( 'An `$args` argument is required when initializing a full widget instance.' );
128 + throw new \Exception( '`$args` argument is required when initializing a full widget instance.' );
144 129 }
145 130
146 131 if ( $is_type_instance ) {
147 132 if ( $this->has_own_method( '_register_skins', self::class ) ) {
@@ -183,11 +168,11 @@
183 168 */
184 169 public function get_stack( $with_common_controls = true ) {
185 170 $stack = parent::get_stack();
186 171
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() );
172 + if ( $with_common_controls && 'common' !== $this->get_unique_name() ) {
173 + /** @var Widget_Common $common_widget */
174 + $common_widget = Plugin::$instance->widgets_manager->get_widget_types( 'common' );
190 175
191 176 $stack['controls'] = array_merge( $stack['controls'], $common_widget->get_controls() );
192 177
193 178 $stack['tabs'] = array_merge( $stack['tabs'], $common_widget->get_tabs_controls() );
@@ -195,16 +180,8 @@
195 180
196 181 return $stack;
197 182 }
198 183
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 184 /**
208 185 * Get widget controls pointer index.
209 186 *
210 187 * Retrieve widget pointer index where the next control should be added.
@@ -241,21 +218,8 @@
241 218 return true;
242 219 }
243 220
244 221 /**
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 222 * Start widget controls section.
259 223 *
260 224 * Used to add a new section of controls to the widget. Regular controls and
261 225 * skin controls.
@@ -271,12 +235,14 @@
271 235 */
272 236 public function start_controls_section( $section_id, array $args = [] ) {
273 237 parent::start_controls_section( $section_id, $args );
274 238
275 - if ( $this->is_first_section ) {
239 + static $is_first_section = true;
240 +
241 + if ( $is_first_section ) {
276 242 $this->register_skin_control();
277 243
278 - $this->is_first_section = false;
244 + $is_first_section = false;
279 245 }
280 246 }
281 247
282 248 /**
@@ -300,9 +266,9 @@
300 266 foreach ( $skins as $skin_id => $skin ) {
301 267 $skin_options[ $skin_id ] = $skin->get_title();
302 268 }
303 269
304 - // Get the first item for default value.
270 + // Get the first item for default value
305 271 $default_value = array_keys( $skin_options );
306 272 $default_value = array_shift( $default_value );
307 273
308 274 if ( 1 >= count( $skin_options ) ) {
@@ -332,12 +298,12 @@
332 298 * Register widget skins - deprecated prefixed method
333 299 *
334 300 * @since 1.7.12
335 301 * @access protected
336 - * @deprecated 3.1.0 Use `register_skins()` method instead.
302 + * @deprecated 3.1.0
337 303 */
338 304 protected function _register_skins() {
339 - Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', 'register_skins()' );
305 + Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', __CLASS__ . '::register_skins()' );
340 306
341 307 $this->register_skins();
342 308 }
343 309
@@ -378,23 +344,10 @@
378 344 'keywords' => $this->get_keywords(),
379 345 'categories' => $this->get_categories(),
380 346 'html_wrapper_class' => $this->get_html_wrapper_class(),
381 347 '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 348 ];
387 349
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 350 $stack = Plugin::$instance->controls_manager->get_element_stack( $this );
398 351
399 352 if ( $stack ) {
400 353 $config['controls'] = $this->get_stack( false )['controls'];
@@ -400,9 +353,9 @@
400 353 $config['controls'] = $this->get_stack( false )['controls'];
401 354 $config['tabs_controls'] = $this->get_tabs_controls();
402 355 }
403 356
404 - return array_replace_recursive( parent::get_initial_config(), $config );
357 + return array_merge( parent::get_initial_config(), $config );
405 358 }
406 359
407 360 /**
408 361 * @since 2.3.1
@@ -423,15 +376,15 @@
423 376 *
424 377 * @param string $template_content Template content.
425 378 */
426 379 protected function print_template_content( $template_content ) {
427 - if ( $this->has_widget_inner_wrapper() ) : ?>
380 + ?>
428 381 <div class="elementor-widget-container">
429 - <?php endif;
430 - Utils::print_unescaped_internal_string( $template_content );
431 - if ( $this->has_widget_inner_wrapper() ) : ?>
382 + <?php
383 + echo $template_content; // XSS ok.
384 + ?>
432 385 </div>
433 - <?php endif;
386 + <?php
434 387 }
435 388
436 389 /**
437 390 * Parse text editor.
@@ -541,17 +494,18 @@
541 494 *
542 495 * Used to add Light-Box-related data attributes to links that open media files.
543 496 *
544 497 * @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.
498 + * @param int $id The ID of the image
499 + * @param string $lightbox_setting_key The setting key that dictates weather to open the image in a lightbox
500 + * @param string $group_id Unique ID for a group of lightbox images
501 + * @param bool $overwrite Optional. Whether to overwrite existing
502 + * attribute. Default is false, not to overwrite.
550 503 *
551 504 * @return Widget_Base Current instance of the widget.
552 505 * @since 2.9.0
553 506 * @access public
507 + *
554 508 */
555 509 public function add_lightbox_data_attributes( $element, $id = null, $lightbox_setting_key = null, $group_id = null, $overwrite = false ) {
556 510 $kit = Plugin::$instance->kits_manager->get_active_kit();
557 511
@@ -570,19 +524,10 @@
570 524 }
571 525
572 526 $attributes['data-elementor-open-lightbox'] = 'yes';
573 527
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 528 if ( $group_id ) {
582 529 $attributes['data-elementor-lightbox-slideshow'] = $group_id;
583 -
584 - $action_hash_params['slideshow'] = $group_id;
585 530 }
586 531
587 532 if ( $id ) {
588 533 $lightbox_image_attributes = Plugin::$instance->images_manager->get_lightbox_image_attributes( $id );
@@ -595,10 +540,8 @@
595 540 $attributes['data-elementor-lightbox-description'] = $lightbox_image_attributes['description'];
596 541 }
597 542 }
598 543
599 - $attributes['data-e-action-hash'] = Plugin::instance()->frontend->create_action_hash( 'lightbox', $action_hash_params );
600 -
601 544 $this->add_render_attribute( $element, $attributes, null, $overwrite );
602 545
603 546 return $this;
604 547 }
@@ -640,16 +583,20 @@
640 583
641 584 if ( empty( $widget_content ) ) {
642 585 return;
643 586 }
644 - if ( $this->has_widget_inner_wrapper() ) : ?>
587 + ?>
645 588 <div class="elementor-widget-container">
646 - <?php endif; ?>
647 589 <?php
648 - if ( $this->is_widget_first_render( $this->get_group_name() ) ) {
590 + if ( $this->is_widget_first_render() ) {
591 +
649 592 $this->register_runtime_widget( $this->get_group_name() );
593 +
594 + $this->print_widget_css();
650 595 }
651 596
597 + // get_name
598 +
652 599 /**
653 600 * Render widget content.
654 601 *
655 602 * Filters the widget content before it's rendered.
@@ -659,17 +606,17 @@
659 606 * @param string $widget_content The content of the widget.
660 607 * @param Widget_Base $this The widget.
661 608 */
662 609 $widget_content = apply_filters( 'elementor/widget/render_content', $widget_content, $this );
663 - Utils::print_unescaped_internal_string( $widget_content );
610 +
611 + echo $widget_content; // XSS ok.
664 612 ?>
665 - <?php if ( $this->has_widget_inner_wrapper() ) : ?>
666 613 </div>
667 - <?php endif;
614 + <?php
668 615 }
669 616
670 - protected function is_widget_first_render( $widget_name ) {
671 - return ! in_array( $widget_name, self::$registered_runtime_widgets, true );
617 + protected function is_widget_first_render() {
618 + return ! in_array( $this->get_group_name(), self::$registered_runtime_widgets, true );
672 619 }
673 620
674 621 /**
675 622 * Render widget plain content.
@@ -696,16 +643,8 @@
696 643 public function render_plain_content() {
697 644 $this->render_content();
698 645 }
699 646
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 647 /**
709 648 * Before widget rendering.
710 649 *
711 650 * Used to add stuff before the widget `_wrapper` element.
@@ -787,12 +726,12 @@
787 726 *
788 727 * Script tags are allowed on frontend according to the WP theme securing policy.
789 728 *
790 729 * @param string $setting
791 - * @param null $repeater_name
792 - * @param null $index
730 + * @param null $repeater_name
731 + * @param null $index
793 732 */
794 - final public function print_unescaped_setting( $setting, $repeater_name = null, $index = null ) {
733 + final protected function print_unescaped_setting( $setting, $repeater_name = null, $index = null ) {
795 734 if ( $repeater_name ) {
796 735 $repeater = $this->get_settings_for_display( $repeater_name );
797 736 $output = $repeater[ $index ][ $setting ];
798 737 } else {
@@ -855,9 +794,9 @@
855 794 * @access protected
856 795 *
857 796 * @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
858 797 * @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`).
798 + * @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
860 799 *
861 800 * @return string The repeater setting key (e.g. `tabs.3.tab_title`).
862 801 */
863 802 protected function get_repeater_setting_key( $setting_key, $repeater_key, $repeater_item_index ) {
@@ -1014,16 +953,15 @@
1014 953 return $this->get_name();
1015 954 }
1016 955
1017 956 /**
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.
957 + * @param string $plugin_title Plugin's title
958 + * @param string $since Plugin version widget was deprecated
959 + * @param string $last Plugin version in which the widget will be removed
960 + * @param string $replacement Widget replacement
1022 961 */
1023 962 protected function deprecated_notice( $plugin_title, $since, $last = '', $replacement = '' ) {
1024 - $this->start_controls_section(
1025 - 'Deprecated',
963 + $this->start_controls_section( 'Deprecated',
1026 964 [
1027 965 'label' => esc_html__( 'Deprecated', 'elementor' ),
1028 966 ]
1029 967 );
@@ -1040,22 +978,9 @@
1040 978 ]
1041 979 );
1042 980
1043 981 $this->end_controls_section();
1044 - }
1045 982
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 983 }
1059 984
1060 985 public function register_runtime_widget( $widget_name ) {
1061 986 self::$registered_runtime_widgets[] = $widget_name;
@@ -1060,32 +985,50 @@
1060 985 public function register_runtime_widget( $widget_name ) {
1061 986 self::$registered_runtime_widgets[] = $widget_name;
1062 987 }
1063 988
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 - ] );
989 + public function get_css_config() {
990 + $widget_name = $this->get_group_name();
1080 991
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 - );
992 + $direction = is_rtl() ? '-rtl' : '';
993 +
994 + $css_file_path = 'css/widget-' . $widget_name . $direction . '.min.css';
995 +
996 + return [
997 + 'key' => $widget_name,
998 + 'version' => ELEMENTOR_VERSION,
999 + 'file_path' => ELEMENTOR_ASSETS_PATH . $css_file_path,
1000 + 'data' => [
1001 + 'file_url' => ELEMENTOR_ASSETS_URL . $css_file_path,
1002 + ],
1003 + ];
1004 + }
1005 +
1006 + private function get_widget_css() {
1007 + $widgets_css_data_manager = $this->get_widgets_css_data_manager();
1008 +
1009 + $widget_css = $widgets_css_data_manager->get_asset_data( $this->get_css_config() );
1010 +
1011 + return $widget_css;
1012 +
1013 + }
1014 +
1015 + private function print_widget_css() {
1016 + $is_edit_mode = Plugin::$instance->editor->is_edit_mode();
1017 + $is_preview_mode = Plugin::$instance->preview->is_preview_mode();
1018 + $is_optimized_mode = Plugin::$instance->experiments->is_feature_active( 'e_optimized_css_loading' );
1019 +
1020 + if ( Utils::is_script_debug() || $is_edit_mode || $is_preview_mode || ! $is_optimized_mode ) {
1021 + return;
1022 + }
1023 +
1024 + echo wp_kses_post( $this->get_widget_css() );
1025 + }
1026 +
1027 + private function get_widgets_css_data_manager() {
1028 + if ( ! self::$widgets_css_data_manager ) {
1029 + self::$widgets_css_data_manager = new Widgets_Css_Data_Manager();
1030 + }
1031 +
1032 + return self::$widgets_css_data_manager;
1090 1033 }
1091 1034 }