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 +143 -13 4.0.94.3.0-beta3 View file →
@@ -4,8 +4,11 @@
4 4
5 5 use Elementor\Element_Base;
6 6 use Elementor\Modules\AtomicWidgets\Controls\Base\Atomic_Control_Base;
7 7 use Elementor\Modules\AtomicWidgets\Controls\Section;
8 +use Elementor\Modules\AtomicWidgets\Elements\Atomic_Form\Atomic_Form;
9 +use Elementor\Modules\AtomicWidgets\Elements\Loader\Frontend_Assets_Loader;
10 +use Elementor\Modules\AtomicWidgets\Logger\Logger;
8 11 use Elementor\Modules\AtomicWidgets\PropsResolver\Render_Props_Resolver;
9 12 use Elementor\Modules\AtomicWidgets\PropTypes\Contracts\Prop_Type;
10 13 use Elementor\Modules\AtomicWidgets\Styles\Style_Schema;
11 14 use Elementor\Modules\AtomicWidgets\Parsers\Props_Parser;
@@ -13,8 +16,9 @@
13 16 use Elementor\Modules\AtomicWidgets\PropTypes\Attributes_Prop_Type;
14 17 use Elementor\Modules\AtomicWidgets\PropTypes\Key_Value_Prop_Type;
15 18 use Elementor\Modules\AtomicWidgets\PropTypes\Link_Prop_Type;
16 19 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
20 +use Elementor\Modules\AtomicWidgets\PropTypes\Prop_Duplication_Behavior;
17 21 use Elementor\Utils;
18 22 use Elementor\Modules\Components\PropTypes\Overridable_Prop_Type;
19 23 use Elementor\Modules\AtomicWidgets\Styles\Atomic_Widget_Styles;
20 24
@@ -26,9 +30,20 @@
26 30 * @mixin Element_Base
27 31 */
28 32 trait Has_Atomic_Base {
29 33 use Has_Base_Styles;
34 + use Has_Base_Settings;
30 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 +
31 46 public function has_widget_inner_wrapper(): bool {
32 47 return false;
33 48 }
34 49
@@ -85,23 +100,74 @@
85 100
86 101 private function parse_atomic_styles( array $data ): array {
87 102 $styles = $data['styles'] ?? [];
88 103 $style_parser = Style_Parser::make( Style_Schema::get() );
104 + $validated_styles = [];
89 105
90 106 foreach ( $styles as $style_id => $style ) {
91 107 $result = $style_parser->parse( $style );
92 108
93 109 if ( ! $result->is_valid() ) {
94 - $widget_id = $data['id'] ?? 'unknown';
95 - 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;
96 119 }
97 120
98 - $styles[ $style_id ] = $result->unwrap();
121 + $validated_styles[ $style_id ] = $result->unwrap();
99 122 }
100 123
101 - return $styles;
124 + return $validated_styles;
102 125 }
103 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 +
104 170 private function parse_atomic_settings( array $settings ): array {
105 171 $schema = static::get_props_schema();
106 172 $props_parser = Props_Parser::make( $schema );
107 173
@@ -181,18 +247,43 @@
181 247 final public function get_data_for_save() {
182 248 $data = parent::get_data_for_save();
183 249
184 250 $data['version'] = $this->version;
185 - $data['settings'] = $this->parse_atomic_settings( $data['settings'] );
186 - $data['styles'] = $this->parse_atomic_styles( $data );
187 - $data['editor_settings'] = $this->parse_editor_settings( $data['editor_settings'] );
188 251
189 - if ( isset( $data['interactions'] ) && ! empty( $data['interactions'] ) ) {
190 - $data['interactions'] = $this->transform_interactions_for_save( $data['interactions'] );
191 - } else {
192 - $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;
193 283 }
194 - return $data;
284 +
285 + unset( $data[ $key ] );
195 286 }
196 287
197 288 private function transform_interactions_for_save( $interactions ) {
198 289 $decoded = $this->decode_interactions_data( $interactions );
@@ -248,8 +339,13 @@
248 339 );
249 340 $props['attributes'] = Attributes_Prop_Type::generate( $merged_attribute_values );
250 341
251 342 $parsed = Render_Props_Resolver::for_settings()->resolve( $schema, $props );
343 +
344 + return $this->transform_link_for_render( $parsed );
345 + }
346 +
347 + protected function transform_link_for_render( array $parsed ): array {
252 348 $link_attributes = isset( $parsed['link'] ) ? $this->get_link_attributes_string( $parsed['link'] ) : '';
253 349
254 350 $parsed['link'] = ! empty( $link_attributes ) ? [
255 351 'tag' => $parsed['link']['tag'],
@@ -296,15 +392,24 @@
296 392 if ( isset( $data['title'] ) && is_string( $data['title'] ) ) {
297 393 $editor_data['title'] = sanitize_text_field( $data['title'] );
298 394 }
299 395
396 + if ( isset( $data['grid_outline'] ) && is_bool( $data['grid_outline'] ) ) {
397 + $editor_data['grid_outline'] = $data['grid_outline'];
398 + }
399 +
300 400 return $editor_data;
301 401 }
302 402
303 403 public static function get_props_schema(): array {
304 404 $schema = static::define_props_schema();
305 - $schema['_cssid'] = String_Prop_Type::make()->meta( Overridable_Prop_Type::ignore() );
306 405
406 + if ( ! isset( $schema['_cssid'] ) ) {
407 + $schema['_cssid'] = String_Prop_Type::make()
408 + ->meta( Overridable_Prop_Type::ignore() )
409 + ->meta( Prop_Duplication_Behavior::clear() );
410 + }
411 +
307 412 return apply_filters(
308 413 'elementor/atomic-widgets/props-schema',
309 414 $schema
310 415 );
@@ -395,6 +500,31 @@
395 500 $parts[] = sprintf( '%s="%s"', $key, esc_attr( $value ) );
396 501 }
397 502
398 503 return implode( ' ', $parts );
504 + }
505 +
506 + public function has_action_link() {
507 + if ( ! $this->get_id() ) {
508 + return true;
509 + }
510 +
511 + $link_settings = $this->get_atomic_setting( 'link' ) ?? null;
512 + $attributes = $this->get_link_attributes( $link_settings );
513 +
514 + return isset( $attributes['data-action-link'] );
515 + }
516 +
517 + public function get_script_depends() {
518 + $depends = parent::get_script_depends();
519 +
520 + if ( $this->has_action_link() ) {
521 + $depends[] = Frontend_Assets_Loader::ACTION_LINK_HANDLERS_HANDLE;
522 + }
523 +
524 + if ( Atomic_Form::is_instance_form( $this ) ) {
525 + $depends[] = Frontend_Assets_Loader::FORM_HANDLERS_HANDLE;
526 + }
527 +
528 + return $depends;
399 529 }
400 530 }