PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta3
Elementor Website Builder – more than just a page builder v4.3.0-beta3
4.3.0-beta3 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 All 452 releases
← All changes | modules/atomic-widgets/elements/base/has-atomic-base.php +108 -13 4.1.34.3.0-beta3 View file →
@@ -6,8 +6,9 @@
6 6 use Elementor\Modules\AtomicWidgets\Controls\Base\Atomic_Control_Base;
7 7 use Elementor\Modules\AtomicWidgets\Controls\Section;
8 8 use Elementor\Modules\AtomicWidgets\Elements\Atomic_Form\Atomic_Form;
9 9 use Elementor\Modules\AtomicWidgets\Elements\Loader\Frontend_Assets_Loader;
10 +use Elementor\Modules\AtomicWidgets\Logger\Logger;
10 11 use Elementor\Modules\AtomicWidgets\PropsResolver\Render_Props_Resolver;
11 12 use Elementor\Modules\AtomicWidgets\PropTypes\Contracts\Prop_Type;
12 13 use Elementor\Modules\AtomicWidgets\Styles\Style_Schema;
13 14 use Elementor\Modules\AtomicWidgets\Parsers\Props_Parser;
@@ -15,8 +16,9 @@
15 16 use Elementor\Modules\AtomicWidgets\PropTypes\Attributes_Prop_Type;
16 17 use Elementor\Modules\AtomicWidgets\PropTypes\Key_Value_Prop_Type;
17 18 use Elementor\Modules\AtomicWidgets\PropTypes\Link_Prop_Type;
18 19 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
20 +use Elementor\Modules\AtomicWidgets\PropTypes\Prop_Duplication_Behavior;
19 21 use Elementor\Utils;
20 22 use Elementor\Modules\Components\PropTypes\Overridable_Prop_Type;
21 23 use Elementor\Modules\AtomicWidgets\Styles\Atomic_Widget_Styles;
22 24
@@ -28,9 +30,20 @@
28 30 * @mixin Element_Base
29 31 */
30 32 trait Has_Atomic_Base {
31 33 use Has_Base_Styles;
34 + use Has_Base_Settings;
32 35
36 + public static function html_tag_follows_link(): bool {
37 + return true;
38 + }
39 +
40 + public static function get_computed_html_tag( array $settings ): string {
41 + return Html_Tag_Computer::compute( $settings, 'div', [
42 + Html_Tag_Computer::FOLLOW_LINK_OPTION => static::html_tag_follows_link(),
43 + ] );
44 + }
45 +
33 46 public function has_widget_inner_wrapper(): bool {
34 47 return false;
35 48 }
36 49
@@ -87,23 +100,74 @@
87 100
88 101 private function parse_atomic_styles( array $data ): array {
89 102 $styles = $data['styles'] ?? [];
90 103 $style_parser = Style_Parser::make( Style_Schema::get() );
104 + $validated_styles = [];
91 105
92 106 foreach ( $styles as $style_id => $style ) {
93 107 $result = $style_parser->parse( $style );
94 108
95 109 if ( ! $result->is_valid() ) {
96 - $widget_id = $data['id'] ?? 'unknown';
97 - throw new \Exception( esc_html( "Styles validation failed for style `$style_id`. Widget ID: `$widget_id`. " . $result->errors()->to_string() ) );
110 + Logger::warning(
111 + $this->format_styles_validation_error_message(
112 + $style_id,
113 + $data,
114 + $style,
115 + $result->errors()->to_string()
116 + )
117 + );
118 + continue;
98 119 }
99 120
100 - $styles[ $style_id ] = $result->unwrap();
121 + $validated_styles[ $style_id ] = $result->unwrap();
101 122 }
102 123
103 - return $styles;
124 + return $validated_styles;
104 125 }
105 126
127 + private function format_styles_validation_error_message(
128 + string $style_id,
129 + array $data,
130 + array $style,
131 + string $validation_errors
132 + ): string {
133 + $widget_id = $data['id'] ?? 'unknown';
134 + $structure_label = $this->get_editor_structure_label( $data );
135 + $style_label = isset( $style['label'] ) && is_string( $style['label'] ) ? $style['label'] : null;
136 +
137 + $message_parts = [
138 + "Styles validation failed for style `$style_id` (widget `$widget_id`)",
139 + ];
140 +
141 + if ( $structure_label ) {
142 + $message_parts[] = "Structure label: `$structure_label`";
143 + } else {
144 + $element_name = $this->get_title();
145 +
146 + if ( '' === $element_name ) {
147 + $element_name = $this->get_name();
148 + }
149 +
150 + $message_parts[] = "Element: `$element_name`";
151 + }
152 +
153 + if ( $style_label ) {
154 + $message_parts[] = "Style label: `$style_label`";
155 + }
156 +
157 + return implode( '. ', $message_parts ) . '. ' . $validation_errors;
158 + }
159 +
160 + private function get_editor_structure_label( array $data ): ?string {
161 + $title = $data['editor_settings']['title'] ?? $this->editor_settings['title'] ?? null;
162 +
163 + if ( ! is_string( $title ) || '' === $title ) {
164 + return null;
165 + }
166 +
167 + return $title;
168 + }
169 +
106 170 private function parse_atomic_settings( array $settings ): array {
107 171 $schema = static::get_props_schema();
108 172 $props_parser = Props_Parser::make( $schema );
109 173
@@ -183,18 +247,43 @@
183 247 final public function get_data_for_save() {
184 248 $data = parent::get_data_for_save();
185 249
186 250 $data['version'] = $this->version;
187 - $data['settings'] = $this->parse_atomic_settings( $data['settings'] );
188 - $data['styles'] = $this->parse_atomic_styles( $data );
189 - $data['editor_settings'] = $this->parse_editor_settings( $data['editor_settings'] );
190 251
191 - if ( isset( $data['interactions'] ) && ! empty( $data['interactions'] ) ) {
192 - $data['interactions'] = $this->transform_interactions_for_save( $data['interactions'] );
193 - } else {
194 - $data['interactions'] = [];
252 + $this->set_data_field_for_save(
253 + $data,
254 + 'settings',
255 + $this->parse_atomic_settings( $data['settings'] ?? [] )
256 + );
257 +
258 + $this->set_data_field_for_save(
259 + $data,
260 + 'styles',
261 + $this->parse_atomic_styles( $data )
262 + );
263 +
264 + $this->set_data_field_for_save(
265 + $data,
266 + 'editor_settings',
267 + $this->parse_editor_settings( $data['editor_settings'] ?? [] )
268 + );
269 +
270 + $this->set_data_field_for_save(
271 + $data,
272 + 'interactions',
273 + $this->transform_interactions_for_save( $data['interactions'] ?? [] )
274 + );
275 +
276 + return $data;
277 + }
278 +
279 + private function set_data_field_for_save( array &$data, string $key, $value ): void {
280 + if ( ! empty( $value ) ) {
281 + $data[ $key ] = $value;
282 + return;
195 283 }
196 - return $data;
284 +
285 + unset( $data[ $key ] );
197 286 }
198 287
199 288 private function transform_interactions_for_save( $interactions ) {
200 289 $decoded = $this->decode_interactions_data( $interactions );
@@ -303,8 +392,12 @@
303 392 if ( isset( $data['title'] ) && is_string( $data['title'] ) ) {
304 393 $editor_data['title'] = sanitize_text_field( $data['title'] );
305 394 }
306 395
396 + if ( isset( $data['grid_outline'] ) && is_bool( $data['grid_outline'] ) ) {
397 + $editor_data['grid_outline'] = $data['grid_outline'];
398 + }
399 +
307 400 return $editor_data;
308 401 }
309 402
310 403 public static function get_props_schema(): array {
@@ -310,9 +403,11 @@
310 403 public static function get_props_schema(): array {
311 404 $schema = static::define_props_schema();
312 405
313 406 if ( ! isset( $schema['_cssid'] ) ) {
314 - $schema['_cssid'] = String_Prop_Type::make()->meta( Overridable_Prop_Type::ignore() );
407 + $schema['_cssid'] = String_Prop_Type::make()
408 + ->meta( Overridable_Prop_Type::ignore() )
409 + ->meta( Prop_Duplication_Behavior::clear() );
315 410 }
316 411
317 412 return apply_filters(
318 413 'elementor/atomic-widgets/props-schema',