PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0-beta2
Elementor Website Builder – more than just a page builder v4.3.0-beta2
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
elementor / modules / components / variants / component-variant-parser.php

component-variant-parser.php in Elementor Website Builder – more than just a page builder 4.3.0-beta2, at modules/components/variants/component-variant-parser.php

181 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\Components\Variants;
4
5 use Elementor\Core\Utils\Api\Parse_Result;
6 use Elementor\Modules\AtomicWidgets\PropTypes\Classes_Prop_Type;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit;
10 }
11
12 class Component_Variant_Parser {
13 const REQUIRED_FIELDS = [ 'id', 'label' ];
14 const ACTION_ADD = 'add';
15 const NESTED_VARIANT_KEY = 'variant';
16
17 public static function make(): self {
18 return new self();
19 }
20
21 public function parse( array $variant ): Parse_Result {
22 $result = Parse_Result::make();
23
24 foreach ( self::REQUIRED_FIELDS as $field ) {
25 if ( ! isset( $variant[ $field ] ) || ! is_string( $variant[ $field ] ) || '' === $variant[ $field ] ) {
26 $result->errors()->add( $field, 'missing_field' );
27 }
28 }
29
30 if ( ! $result->is_valid() ) {
31 return $result;
32 }
33
34 $widgets_result = $this->parse_widgets( $variant['widgets'] ?? [] );
35
36 if ( ! $widgets_result->is_valid() ) {
37 $result->errors()->merge( $widgets_result->errors(), 'widgets' );
38
39 return $result;
40 }
41
42 return $result->wrap( [
43 'id' => sanitize_key( $variant['id'] ),
44 'label' => sanitize_text_field( $variant['label'] ),
45 'widgets' => $widgets_result->unwrap(),
46 ] );
47 }
48
49 private function parse_widgets( array $widgets ): Parse_Result {
50 $result = Parse_Result::make();
51 $sanitized = [];
52
53 foreach ( $widgets as $element_id => $entry ) {
54 if ( ! is_string( $element_id ) || '' === $element_id ) {
55 $result->errors()->add( (string) $element_id, 'invalid_element_id' );
56 continue;
57 }
58
59 if ( ! is_array( $entry ) ) {
60 $result->errors()->add( $element_id, 'invalid_entry' );
61 continue;
62 }
63
64 $entry_result = $this->parse_widget_entry( $entry );
65
66 if ( ! $entry_result->is_valid() ) {
67 $result->errors()->merge( $entry_result->errors(), $element_id );
68 continue;
69 }
70
71 $sanitized[ sanitize_key( $element_id ) ] = $entry_result->unwrap();
72 }
73
74 if ( ! $result->is_valid() ) {
75 return $result;
76 }
77
78 return $result->wrap( $sanitized );
79 }
80
81 private function parse_widget_entry( array $entry ): Parse_Result {
82 $result = Parse_Result::make();
83 $sanitized = [];
84
85 if ( isset( $entry['settings'] ) ) {
86 $settings_result = $this->parse_settings( $entry['settings'] );
87
88 if ( ! $settings_result->is_valid() ) {
89 $result->errors()->merge( $settings_result->errors(), 'settings' );
90
91 return $result;
92 }
93
94 $sanitized_settings = $settings_result->unwrap();
95
96 if ( ! empty( $sanitized_settings ) ) {
97 $sanitized['settings'] = $sanitized_settings;
98 }
99 }
100
101 if ( isset( $entry[ self::NESTED_VARIANT_KEY ] ) ) {
102 $nested = $entry[ self::NESTED_VARIANT_KEY ];
103
104 if ( ! is_string( $nested ) || '' === $nested ) {
105 $result->errors()->add( self::NESTED_VARIANT_KEY, 'invalid_variant_id' );
106
107 return $result;
108 }
109
110 $sanitized[ self::NESTED_VARIANT_KEY ] = sanitize_key( $nested );
111 }
112
113 return $result->wrap( $sanitized );
114 }
115
116 private function parse_settings( array $settings ): Parse_Result {
117 $result = Parse_Result::make();
118
119 if ( isset( $settings[ self::NESTED_VARIANT_KEY ] ) ) {
120 $result->errors()->add( self::NESTED_VARIANT_KEY, 'nested_variant_forbidden' );
121
122 return $result;
123 }
124
125 $sanitized = [];
126
127 if ( isset( $settings['classes'] ) ) {
128 $classes_result = $this->parse_classes( $settings['classes'] );
129
130 if ( ! $classes_result->is_valid() ) {
131 $result->errors()->merge( $classes_result->errors(), 'classes' );
132
133 return $result;
134 }
135
136 $sanitized_classes = $classes_result->unwrap();
137
138 if ( ! empty( $sanitized_classes ) ) {
139 $sanitized['classes'] = $sanitized_classes;
140 }
141 }
142
143 return $result->wrap( $sanitized );
144 }
145
146 private function parse_classes( array $classes ): Parse_Result {
147 $result = Parse_Result::make();
148
149 if ( ! isset( $classes[ self::ACTION_ADD ] ) ) {
150 return $result->wrap( [] );
151 }
152
153 $add_list = $classes[ self::ACTION_ADD ];
154
155 if ( ! is_array( $add_list ) ) {
156 $result->errors()->add( self::ACTION_ADD, 'invalid_structure' );
157
158 return $result;
159 }
160
161 $transformable = [
162 '$$type' => Classes_Prop_Type::get_key(),
163 'value' => $add_list,
164 ];
165
166 $classes_prop_type = Classes_Prop_Type::make();
167
168 if ( ! $classes_prop_type->validate( $transformable ) ) {
169 $result->errors()->add( self::ACTION_ADD, 'invalid_class_id' );
170
171 return $result;
172 }
173
174 $sanitized = $classes_prop_type->sanitize( $transformable );
175
176 return $result->wrap( [
177 self::ACTION_ADD => array_values( $sanitized['value'] ),
178 ] );
179 }
180 }
181