PluginProbe
Elementor Website Builder – more than just a page builder / 3.25.5
Elementor Website Builder – more than just a page builder v3.25.5
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
elementor / modules / atomic-widgets / props-resolver / props-resolver.php

props-resolver.php in Elementor Website Builder – more than just a page builder 3.25.5, at modules/atomic-widgets/props-resolver/props-resolver.php

137 lines 3.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\AtomicWidgets\PropsResolver;
4
5 use Elementor\Modules\AtomicWidgets\PropTypes\Prop_Type;
6 use Exception;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly.
10 }
11
12 class Props_Resolver {
13 /**
14 * Each transformer can return a value that is also a transformable value,
15 * which means that it can be transformed again by another transformer.
16 * This constant defines the maximum depth of transformations to avoid infinite loops.
17 */
18 const TRANSFORM_DEPTH_LIMIT = 3;
19
20 const CONTEXT_SETTINGS = 'settings';
21 const CONTEXT_STYLES = 'styles';
22
23 /**
24 * @var array<string, Props_Resolver>
25 */
26 private static array $instances = [];
27
28 private Transformers_Registry $transformers;
29
30 private function __construct( Transformers_Registry $transformers ) {
31 $this->transformers = $transformers;
32 }
33
34 public static function for_styles() {
35 return self::instance( self::CONTEXT_STYLES );
36 }
37
38 public static function for_settings() {
39 return self::instance( self::CONTEXT_SETTINGS );
40 }
41
42 private static function instance( string $context, bool $fresh = false ): self {
43 if ( ! isset( self::$instances[ $context ] ) || $fresh ) {
44 $registry = new Transformers_Registry();
45
46 do_action( "elementor/atomic-widgets/{$context}/transformers/register", $registry );
47
48 self::$instances[ $context ] = new self( $registry );
49 }
50
51 return self::$instances[ $context ];
52 }
53
54 public function resolve( array $schema, array $props ): array {
55 $resolved_props = [];
56
57 foreach ( $schema as $key => $prop_type ) {
58 if ( ! ( $prop_type instanceof Prop_Type ) ) {
59 continue;
60 }
61
62 if ( ! array_key_exists( $key, $props ) ) {
63 $resolved_props[ $key ] = $prop_type->get_default();
64 continue;
65 }
66
67 $resolved_props[ $key ] = $props[ $key ];
68
69 // Merge the top-level defaults for transformable props.
70 if (
71 $this->is_nested_transformable( $resolved_props[ $key ] ) &&
72 $this->is_nested_transformable( $prop_type->get_default() )
73 ) {
74 $resolved_props[ $key ]['value'] = array_merge(
75 $prop_type->get_default()['value'],
76 $resolved_props[ $key ]['value']
77 );
78 }
79 }
80
81 return array_map(
82 fn( $value ) => $this->transform( $value ),
83 $resolved_props
84 );
85 }
86
87 private function transform( $value, int $depth = 0 ) {
88 if ( ! $value || ! $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
100 // Transform nested transformable values recursively.
101 if ( is_array( $value['value'] ) ) {
102 $value['value'] = array_map(
103 fn( $item ) => $this->transform( $item ),
104 $value['value']
105 );
106 }
107
108 $transformer = $this->transformers->get( $value['$$type'] );
109
110 if ( ! ( $transformer instanceof Transformer_Base ) ) {
111 return null;
112 }
113
114 try {
115 $transformed_value = $transformer->transform( $value['value'] );
116
117 return $this->transform( $transformed_value, $depth + 1 );
118 } catch ( Exception $e ) {
119 return null;
120 }
121 }
122
123 private function is_transformable( $value ): bool {
124 return (
125 ! empty( $value['$$type'] ) &&
126 array_key_exists( 'value', $value )
127 );
128 }
129
130 private function is_nested_transformable( $value ): bool {
131 return (
132 $this->is_transformable( $value ) &&
133 is_array( $value['value'] )
134 );
135 }
136 }
137