PluginProbe
Elementor Website Builder – more than just a page builder / 3.28.0-dev2
Elementor Website Builder – more than just a page builder v3.28.0-dev2
4.3.1 4.3.0 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 All 454 releases
← All changes | modules/atomic-widgets/props-resolver/props-resolver.php +87 -34 4.3.0 → 3.28.0-dev2 View file →
@@ -11,23 +11,44 @@
11 11 if ( ! defined( 'ABSPATH' ) ) {
12 12 exit; // Exit if accessed directly.
13 13 }
14 14
15 -abstract class Props_Resolver {
16 - protected static array $instances = [];
15 +class Props_Resolver {
16 + /**
17 + * Each transformer can return a value that is also a transformable value,
18 + * which means that it can be transformed again by another transformer.
19 + * This constant defines the maximum depth of transformations to avoid infinite loops.
20 + */
21 + const TRANSFORM_DEPTH_LIMIT = 3;
17 22
18 - protected Transformers_Registry $transformers_registry;
23 + const CONTEXT_SETTINGS = 'settings';
24 + const CONTEXT_STYLES = 'styles';
19 25
20 - protected function __construct( Transformers_Registry $transformers_registry ) {
26 + /**
27 + * @var array<string, Props_Resolver>
28 + */
29 + private static array $instances = [];
30 +
31 + private Transformers_Registry $transformers_registry;
32 +
33 + private function __construct( Transformers_Registry $transformers_registry ) {
21 34 $this->transformers_registry = $transformers_registry;
22 35 }
23 36
24 - protected static function instance( string $context ) {
25 - if ( ! isset( static::$instances[ $context ] ) ) {
26 - $instance = new static( new Transformers_Registry() );
37 + public static function for_styles(): self {
38 + return self::instance( self::CONTEXT_STYLES );
39 + }
27 40
28 - static::$instances[ $context ] = $instance;
41 + public static function for_settings(): self {
42 + return self::instance( self::CONTEXT_SETTINGS );
43 + }
29 44
45 + private static function instance( string $context ): self {
46 + if ( ! isset( self::$instances[ $context ] ) ) {
47 + $instance = new self( new Transformers_Registry() );
48 +
49 + self::$instances[ $context ] = $instance;
50 +
30 51 do_action(
31 52 "elementor/atomic-widgets/$context/transformers/register",
32 53 $instance->get_transformers_registry(),
33 54 $instance
@@ -33,13 +54,13 @@
33 54 $instance
34 55 );
35 56 }
36 57
37 - return static::$instances[ $context ];
58 + return self::$instances[ $context ];
38 59 }
39 60
40 61 public static function reset(): void {
41 - static::$instances = [];
62 + self::$instances = [];
42 63 }
43 64
44 65 public function get_transformers_registry(): Transformers_Registry {
45 66 return $this->transformers_registry;
@@ -44,9 +65,39 @@
44 65 public function get_transformers_registry(): Transformers_Registry {
45 66 return $this->transformers_registry;
46 67 }
47 68
48 - protected function transform( $value, $key, Prop_Type $prop_type ) {
69 + public function resolve( array $schema, array $props ): array {
70 + $resolved = [];
71 +
72 + foreach ( $schema as $key => $prop_type ) {
73 + if ( ! ( $prop_type instanceof Prop_Type ) ) {
74 + continue;
75 + }
76 +
77 + $resolved[ $key ] = $props[ $key ] ?? $prop_type->get_default();
78 + }
79 +
80 + return $this->assign_values( $resolved, $schema );
81 + }
82 +
83 + private function transform( $value, $key, Prop_Type $prop_type, int $depth = 0 ) {
84 + if ( null === $value ) {
85 + return null;
86 + }
87 +
88 + if ( ! $this->is_transformable( $value ) ) {
89 + return $value;
90 + }
91 +
92 + if ( $depth >= self::TRANSFORM_DEPTH_LIMIT ) {
93 + return null;
94 + }
95 +
96 + if ( isset( $value['disabled'] ) && true === $value['disabled'] ) {
97 + return null;
98 + }
99 +
49 100 if ( $prop_type instanceof Union_Prop_Type ) {
50 101 $prop_type = $prop_type->get_prop_type( $value['$$type'] );
51 102
52 103 if ( ! $prop_type ) {
@@ -53,12 +104,8 @@
53 104 return null;
54 105 }
55 106 }
56 107
57 - if ( $value['$$type'] !== $prop_type::get_key() ) {
58 - return null;
59 - }
60 -
61 108 if ( $prop_type instanceof Object_Prop_Type ) {
62 109 if ( ! is_array( $value['value'] ) ) {
63 110 return null;
64 111 }
@@ -73,19 +120,12 @@
73 120 if ( ! is_array( $value['value'] ) ) {
74 121 return null;
75 122 }
76 123
77 - $resolved_items = [];
78 -
79 - foreach ( $value['value'] as $item ) {
80 - $resolved = $this->resolve_item( $item, null, $prop_type->get_item_type() );
81 -
82 - if ( null !== $resolved ) {
83 - $resolved_items[] = $resolved;
84 - }
85 - }
86 -
87 - $value['value'] = $resolved_items;
124 + $value['value'] = $this->assign_values(
125 + $value['value'],
126 + $prop_type->get_item_type()
127 + );
88 128 }
89 129
90 130 $transformer = $this->transformers_registry->get( $value['$$type'] );
91 131
@@ -93,20 +133,17 @@
93 133 return null;
94 134 }
95 135
96 136 try {
97 - $context = Props_Resolver_Context::make()
98 - ->set_key( $key )
99 - ->set_disabled( (bool) ( $value['disabled'] ?? false ) )
100 - ->set_prop_type( $prop_type );
137 + $transformed_value = $transformer->transform( $value['value'], $key );
101 138
102 - return $transformer->transform( $value['value'], $context );
139 + return $this->transform( $transformed_value, $key, $prop_type, $depth + 1 );
103 140 } catch ( Exception $e ) {
104 141 return null;
105 142 }
106 143 }
107 144
108 - protected function is_transformable( $value ): bool {
145 + private function is_transformable( $value ): bool {
109 146 return (
110 147 ! empty( $value['$$type'] ) &&
111 148 array_key_exists( 'value', $value )
112 149 );
@@ -111,8 +148,24 @@
111 148 array_key_exists( 'value', $value )
112 149 );
113 150 }
114 151
115 - abstract public function resolve( array $schema, array $props ): array;
152 + private function assign_values( $values, $schema ) {
153 + $assigned = [];
116 154
117 - abstract protected function resolve_item( $value, $key, Prop_Type $prop_type );
155 + foreach ( $values as $key => $value ) {
156 + $prop_type = $schema instanceof Prop_Type ? $schema : $schema[ $key ];
157 +
158 + $transformed = $this->transform( $value, $key, $prop_type );
159 +
160 + if ( Multi_Props::is( $transformed ) ) {
161 + $assigned = array_merge( $assigned, Multi_Props::get_value( $transformed ) );
162 +
163 + continue;
164 + }
165 +
166 + $assigned[ $key ] = $transformed;
167 + }
168 +
169 + return $assigned;
170 + }
118 171 }