PluginProbe
Elementor Website Builder – more than just a page builder / 3.24.8
Elementor Website Builder – more than just a page builder v3.24.8
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 +213 -39 4.0.73.24.8 View file →
@@ -1,9 +1,10 @@
1 1 <?php
2 2 namespace Elementor;
3 3
4 +use Elementor\Core\Page_Assets\Data_Managers\Responsive_Widgets as Responsive_Widgets_Data_Manager;
5 +use Elementor\Core\Page_Assets\Data_Managers\Widgets_Css as Widgets_Css_Data_Manager;
4 6 use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
5 -use Elementor\Utils;
6 7
7 8 if ( ! defined( 'ABSPATH' ) ) {
8 9 exit; // Exit if accessed directly.
9 10 }
@@ -48,8 +49,14 @@
48 49 * @var array
49 50 */
50 51 public static $registered_runtime_widgets = [];
51 52
53 + public static $registered_inline_css_widgets = [];
54 +
55 + private static $widgets_css_data_manager;
56 +
57 + private static $responsive_widgets_data_manager;
58 +
52 59 /**
53 60 * Get element type.
54 61 *
55 62 * Retrieve the element type, in this case `widget`.
@@ -183,11 +190,11 @@
183 190 */
184 191 public function get_stack( $with_common_controls = true ) {
185 192 $stack = parent::get_stack();
186 193
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() );
194 + if ( $with_common_controls && 'common' !== $this->get_unique_name() ) {
195 + /** @var Widget_Common $common_widget */
196 + $common_widget = Plugin::$instance->widgets_manager->get_widget_types( 'common' );
190 197
191 198 $stack['controls'] = array_merge( $stack['controls'], $common_widget->get_controls() );
192 199
193 200 $stack['tabs'] = array_merge( $stack['tabs'], $common_widget->get_tabs_controls() );
@@ -195,16 +202,8 @@
195 202
196 203 return $stack;
197 204 }
198 205
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 206 /**
208 207 * Get widget controls pointer index.
209 208 *
210 209 * Retrieve widget pointer index where the next control should be added.
@@ -300,9 +299,9 @@
300 299 foreach ( $skins as $skin_id => $skin ) {
301 300 $skin_options[ $skin_id ] = $skin->get_title();
302 301 }
303 302
304 - // Get the first item for default value.
303 + // Get the first item for default value
305 304 $default_value = array_keys( $skin_options );
306 305 $default_value = array_shift( $default_value );
307 306
308 307 if ( 1 >= count( $skin_options ) ) {
@@ -381,9 +380,8 @@
381 380 'show_in_panel' => $this->show_in_panel(),
382 381 'hide_on_search' => $this->hide_on_search(),
383 382 'upsale_data' => $this->get_upsale_data(),
384 383 'is_dynamic_content' => $this->is_dynamic_content(),
385 - 'has_widget_inner_wrapper' => $this->has_widget_inner_wrapper(),
386 384 ];
387 385
388 386 if ( isset( $config['upsale_data'] ) && is_array( $config['upsale_data'] ) ) {
389 387 $filter_name = 'elementor/widgets/' . $this->get_name() . '/custom_promotion';
@@ -423,15 +421,15 @@
423 421 *
424 422 * @param string $template_content Template content.
425 423 */
426 424 protected function print_template_content( $template_content ) {
427 - if ( $this->has_widget_inner_wrapper() ) : ?>
425 + ?>
428 426 <div class="elementor-widget-container">
429 - <?php endif;
430 - Utils::print_unescaped_internal_string( $template_content );
431 - if ( $this->has_widget_inner_wrapper() ) : ?>
427 + <?php
428 + echo $template_content; // XSS ok.
429 + ?>
432 430 </div>
433 - <?php endif;
431 + <?php
434 432 }
435 433
436 434 /**
437 435 * Parse text editor.
@@ -541,17 +539,18 @@
541 539 *
542 540 * Used to add Light-Box-related data attributes to links that open media files.
543 541 *
544 542 * @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.
543 + * @param int $id The ID of the image
544 + * @param string $lightbox_setting_key The setting key that dictates whether to open the image in a lightbox
545 + * @param string $group_id Unique ID for a group of lightbox images
546 + * @param bool $overwrite Optional. Whether to overwrite existing
547 + * attribute. Default is false, not to overwrite.
550 548 *
551 549 * @return Widget_Base Current instance of the widget.
552 550 * @since 2.9.0
553 551 * @access public
552 + *
554 553 */
555 554 public function add_lightbox_data_attributes( $element, $id = null, $lightbox_setting_key = null, $group_id = null, $overwrite = false ) {
556 555 $kit = Plugin::$instance->kits_manager->get_active_kit();
557 556
@@ -640,16 +639,19 @@
640 639
641 640 if ( empty( $widget_content ) ) {
642 641 return;
643 642 }
644 - if ( $this->has_widget_inner_wrapper() ) : ?>
643 + ?>
645 644 <div class="elementor-widget-container">
646 - <?php endif; ?>
647 645 <?php
648 646 if ( $this->is_widget_first_render( $this->get_group_name() ) ) {
649 647 $this->register_runtime_widget( $this->get_group_name() );
650 648 }
651 649
650 + // $this->print_widget_css();
651 +
652 + // get_name
653 +
652 654 /**
653 655 * Render widget content.
654 656 *
655 657 * Filters the widget content before it's rendered.
@@ -659,13 +661,13 @@
659 661 * @param string $widget_content The content of the widget.
660 662 * @param Widget_Base $this The widget.
661 663 */
662 664 $widget_content = apply_filters( 'elementor/widget/render_content', $widget_content, $this );
663 - Utils::print_unescaped_internal_string( $widget_content );
665 +
666 + echo $widget_content; // XSS ok.
664 667 ?>
665 - <?php if ( $this->has_widget_inner_wrapper() ) : ?>
666 668 </div>
667 - <?php endif;
669 + <?php
668 670 }
669 671
670 672 protected function is_widget_first_render( $widget_name ) {
671 673 return ! in_array( $widget_name, self::$registered_runtime_widgets, true );
@@ -779,10 +781,10 @@
779 781 *
780 782 * Script tags are allowed on frontend according to the WP theme securing policy.
781 783 *
782 784 * @param string $setting
783 - * @param null $repeater_name
784 - * @param null $index
785 + * @param null $repeater_name
786 + * @param null $index
785 787 */
786 788 final public function print_unescaped_setting( $setting, $repeater_name = null, $index = null ) {
787 789 if ( $repeater_name ) {
788 790 $repeater = $this->get_settings_for_display( $repeater_name );
@@ -847,9 +849,9 @@
847 849 * @access protected
848 850 *
849 851 * @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
850 852 * @param string $repeater_key The repeater key containing the array of all the items in the repeater (e.g. `tabs`).
851 - * @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
853 + * @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
852 854 *
853 855 * @return string The repeater setting key (e.g. `tabs.3.tab_title`).
854 856 */
855 857 protected function get_repeater_setting_key( $setting_key, $repeater_key, $repeater_item_index ) {
@@ -1006,13 +1008,27 @@
1006 1008 return $this->get_name();
1007 1009 }
1008 1010
1009 1011 /**
1010 - * @param string $plugin_title Plugin's title.
1011 - * @param string $since Plugin version widget was deprecated.
1012 - * @param string $last Plugin version in which the widget will be removed.
1013 - * @param string $replacement Widget replacement.
1012 + * Get Inline CSS dependencies.
1013 + *
1014 + * Retrieve a list of inline CSS dependencies that the element requires.
1015 + *
1016 + * @since 3.3.0
1017 + * @access public
1018 + *
1019 + * @return array.
1014 1020 */
1021 + public function get_inline_css_depends() {
1022 + return [];
1023 + }
1024 +
1025 + /**
1026 + * @param string $plugin_title Plugin's title
1027 + * @param string $since Plugin version widget was deprecated
1028 + * @param string $last Plugin version in which the widget will be removed
1029 + * @param string $replacement Widget replacement
1030 + */
1015 1031 protected function deprecated_notice( $plugin_title, $since, $last = '', $replacement = '' ) {
1016 1032 $this->start_controls_section(
1017 1033 'Deprecated',
1018 1034 [
@@ -1052,16 +1068,63 @@
1052 1068 public function register_runtime_widget( $widget_name ) {
1053 1069 self::$registered_runtime_widgets[] = $widget_name;
1054 1070 }
1055 1071
1072 + public function get_widget_css_config( $widget_name ) {
1073 + $direction = is_rtl() ? '-rtl' : '';
1074 +
1075 + $has_custom_breakpoints = $this->is_custom_breakpoints_widget();
1076 +
1077 + $file_name = 'widget-' . $widget_name . $direction . '.min.css';
1078 +
1079 + // The URL of the widget's external CSS file that is loaded in case that the CSS content is too large to be printed inline.
1080 + $file_url = Plugin::$instance->frontend->get_frontend_file_url( $file_name, $has_custom_breakpoints );
1081 +
1082 + // The local path of the widget's CSS file that is being read and saved in the DB when the CSS content should be printed inline.
1083 + $file_path = Plugin::$instance->frontend->get_frontend_file_path( $file_name, $has_custom_breakpoints );
1084 +
1085 + $file_timestamp = file_exists( $file_path ) ? filemtime( $file_path ) : ELEMENTOR_VERSION;
1086 +
1087 + return [
1088 + 'key' => $widget_name,
1089 + 'version' => ELEMENTOR_VERSION,
1090 + 'file_path' => $file_path,
1091 + 'data' => [
1092 + 'file_url' => $file_url . '?ver=' . $file_timestamp,
1093 + ],
1094 + ];
1095 + }
1096 +
1097 + public function get_css_config() {
1098 + return $this->get_widget_css_config( $this->get_group_name() );
1099 + }
1100 +
1101 + public function get_responsive_widgets_config() {
1102 + $responsive_widgets_data_manager = $this->get_responsive_widgets_data_manager();
1103 +
1104 + return [
1105 + 'key' => $responsive_widgets_data_manager::RESPONSIVE_WIDGETS_DATABASE_KEY,
1106 + 'version' => ELEMENTOR_VERSION,
1107 + 'file_path' => ELEMENTOR_ASSETS_PATH . $responsive_widgets_data_manager::RESPONSIVE_WIDGETS_FILE_PATH,
1108 + ];
1109 + }
1110 +
1111 + public function get_responsive_widgets() {
1112 + $responsive_widgets_data_manager = $this->get_responsive_widgets_data_manager();
1113 +
1114 + $config = $this->get_responsive_widgets_config();
1115 +
1116 + return $responsive_widgets_data_manager->get_asset_data_from_config( $config );
1117 + }
1118 +
1056 1119 /**
1057 1120 * Mark widget as deprecated.
1058 1121 *
1059 1122 * Use `get_deprecation_message()` method to print the message control at specific location in register_controls().
1060 1123 *
1061 - * @param string $version The version of Elementor that deprecated the widget.
1062 - * @param string $message A message regarding the deprecation.
1063 - * @param string $replacement The widget that should be used instead.
1124 + * @param $version string The version of Elementor that deprecated the widget.
1125 + * @param $message string A message regarding the deprecation.
1126 + * @param $replacement string The widget that should be used instead.
1064 1127 */
1065 1128 protected function add_deprecation_message( $version, $message, $replacement ) {
1066 1129 // Expose the config for handling in JS.
1067 1130 $this->set_config( 'deprecation', [
@@ -1078,6 +1141,117 @@
1078 1141 'content' => $message,
1079 1142 'separator' => 'after',
1080 1143 ]
1081 1144 );
1145 + }
1146 +
1147 + /**
1148 + * Get Responsive Widgets Data Manager.
1149 + *
1150 + * Retrieve the data manager that handles widgets that are using media queries for custom-breakpoints values.
1151 + *
1152 + * @since 3.5.0
1153 + * @access protected
1154 + *
1155 + * @return Responsive_Widgets_Data_Manager
1156 + */
1157 + protected function get_responsive_widgets_data_manager() {
1158 + if ( ! self::$responsive_widgets_data_manager ) {
1159 + self::$responsive_widgets_data_manager = new Responsive_Widgets_Data_Manager();
1160 + }
1161 +
1162 + return self::$responsive_widgets_data_manager;
1163 + }
1164 +
1165 + /**
1166 + * Is Custom Breakpoints Widget.
1167 + *
1168 + * Checking if there are active custom-breakpoints and if the widget use them.
1169 + *
1170 + * @since 3.5.0
1171 + * @access protected
1172 + *
1173 + * @return boolean
1174 + */
1175 + protected function is_custom_breakpoints_widget() {
1176 + $has_custom_breakpoints = Plugin::$instance->breakpoints->has_custom_breakpoints();
1177 +
1178 + if ( $has_custom_breakpoints ) {
1179 + $responsive_widgets = $this->get_responsive_widgets();
1180 +
1181 + // The $widget_name can also represents a widgets group name, therefore we need to use the current widget name to check if it's responsive widget.
1182 + $current_widget_name = $this->get_name();
1183 +
1184 + // If the widget is not implementing custom-breakpoints media queries then it has no custom- css file.
1185 + if ( ! isset( $responsive_widgets[ $current_widget_name ] ) ) {
1186 + $has_custom_breakpoints = false;
1187 + }
1188 + }
1189 +
1190 + return $has_custom_breakpoints;
1191 + }
1192 +
1193 + private function get_widget_css() {
1194 + $widgets_css_data_manager = $this->get_widgets_css_data_manager();
1195 +
1196 + $widgets_list = $this->get_inline_css_depends();
1197 +
1198 + $widgets_list[] = $this->get_group_name();
1199 +
1200 + $widget_css = '';
1201 +
1202 + foreach ( $widgets_list as $widget_data ) {
1203 + $widget_name = isset( $widget_data['name'] ) ? $widget_data['name'] : $widget_data;
1204 +
1205 + if ( ! in_array( $widget_name, self::$registered_inline_css_widgets, true ) ) {
1206 + if ( $this->get_group_name() === $widget_name ) {
1207 + $config = $this->get_css_config();
1208 + } else {
1209 + /**
1210 + * The core-dependency allowing to create a dependency specifically with the core widgets.
1211 + * Otherwise, the config will be taken from the class that inherits from Widget_Base.
1212 + */
1213 + $is_core_dependency = isset( $widget_data['is_core_dependency'] ) ? true : false;
1214 +
1215 + $config = $is_core_dependency ? self::get_widget_css_config( $widget_name ) : $this->get_widget_css_config( $widget_name );
1216 + }
1217 +
1218 + $widget_css .= $widgets_css_data_manager->get_asset_data_from_config( $config );
1219 +
1220 + self::$registered_inline_css_widgets[] = $widget_name;
1221 + }
1222 + }
1223 +
1224 + return $widget_css;
1225 +
1226 + }
1227 +
1228 + private function is_inline_css_mode() {
1229 + static $is_active;
1230 +
1231 + if ( null === $is_active ) {
1232 + $is_edit_mode = Plugin::$instance->editor->is_edit_mode();
1233 + $is_preview_mode = Plugin::$instance->preview->is_preview_mode();
1234 + $is_optimized_mode = Plugin::$instance->experiments->is_feature_active( 'e_optimized_css_loading' );
1235 +
1236 + $is_active = ( Utils::is_script_debug() || $is_edit_mode || $is_preview_mode || ! $is_optimized_mode ) ? false : true;
1237 + }
1238 +
1239 + return $is_active;
1240 + }
1241 +
1242 + private function print_widget_css() {
1243 + if ( ! $this->is_inline_css_mode() ) {
1244 + return;
1245 + }
1246 +
1247 + Utils::print_unescaped_internal_string( $this->get_widget_css() );
1248 + }
1249 +
1250 + private function get_widgets_css_data_manager() {
1251 + if ( ! self::$widgets_css_data_manager ) {
1252 + self::$widgets_css_data_manager = new Widgets_Css_Data_Manager();
1253 + }
1254 +
1255 + return self::$widgets_css_data_manager;
1082 1256 }
1083 1257 }