/var/www/html/wp-content/plugins/elementor/modules/atomic-widgets/props-resolver/props-resolver.php


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<?php

namespace Elementor\Modules\AtomicWidgets\PropsResolver;

use 
Elementor\Modules\AtomicWidgets\PropTypes\Base\Array_Prop_Type;
use 
Elementor\Modules\AtomicWidgets\PropTypes\Base\Object_Prop_Type;
use 
Elementor\Modules\AtomicWidgets\PropTypes\Contracts\Prop_Type;
use 
Elementor\Modules\AtomicWidgets\PropTypes\Union_Prop_Type;
use 
Exception;

if ( ! 
defined'ABSPATH' ) ) {
    exit; 
// Exit if accessed directly.
}

class 
Props_Resolver {
    
/**
     * Each transformer can return a value that is also a transformable value,
     * which means that it can be transformed again by another transformer.
     * This constant defines the maximum depth of transformations to avoid infinite loops.
     */
    
const TRANSFORM_DEPTH_LIMIT 3;

    const 
CONTEXT_SETTINGS 'settings';
    const 
CONTEXT_STYLES 'styles';

    
/**
     * @var array<string, Props_Resolver>
     */
    
private static array $instances = [];

    private 
Transformers_Registry $transformers;

    private function 
__constructTransformers_Registry $transformers ) {
        
$this->transformers $transformers;
    }

    public static function 
for_styles(): self {
        return 
self::instanceself::CONTEXT_STYLES );
    }

    public static function 
for_settings(): self {
        return 
self::instanceself::CONTEXT_SETTINGS );
    }

    private static function 
instancestring $context ): self {
        if ( ! isset( 
self::$instances$context ] ) ) {
            
$registry = new Transformers_Registry();

            
do_action"elementor/atomic-widgets/$context/transformers/register"$registry );

            
self::$instances$context ] = new self$registry );
        }

        return 
self::$instances$context ];
    }

    public static function 
reset(): void {
        
self::$instances = [];
    }

    public function 
resolve( array $schema, array $props ): array {
        
$resolved = [];

        foreach ( 
$schema as $key => $prop_type ) {
            if ( ! ( 
$prop_type instanceof Prop_Type ) ) {
                continue;
            }

            
$resolved$key ] = $props$key ] ?? $prop_type->get_default();
        }

        return 
$this->assign_values$resolved$schema );
    }

    private function 
transform$value$keyProp_Type $prop_typeint $depth ) {
        if ( ! 
$value || ! $this->is_transformable$value ) ) {
            return 
$value;
        }

        if ( 
$depth >= self::TRANSFORM_DEPTH_LIMIT ) {
            return 
null;
        }

        if ( isset( 
$value['disabled'] ) && true === $value['disabled'] ) {
            return 
null;
        }

        if ( 
$prop_type instanceof Union_Prop_Type ) {
            
$prop_type $prop_type->get_prop_type$value['$$type'] );

            if ( ! 
$prop_type ) {
                return 
null;
            }
        }

        if ( 
$prop_type instanceof Object_Prop_Type ) {
            if ( ! 
is_array$value['value'] ) ) {
                return 
null;
            }

            
$value['value'] = $this->resolve(
                
$prop_type->get_shape(),
                
$value['value']
            );
        }

        if ( 
$prop_type instanceof Array_Prop_Type ) {
            if ( ! 
is_array$value['value'] ) ) {
                return 
null;
            }

            
$value['value'] = $this->assign_values(
                
$value['value'],
                
$prop_type->get_item_type()
            );
        }

        
$transformer $this->transformers->get$value['$$type'] );

        if ( ! ( 
$transformer instanceof Transformer_Base ) ) {
            return 
null;
        }

        try {
            
$transformed_value $transformer->transform$value['value'], $key );

            return 
$this->transform$transformed_value$key$prop_type$depth );
        } catch ( 
Exception $e ) {
            return 
null;
        }
    }

    private function 
is_transformable$value ): bool {
        return (
            ! empty( 
$value['$$type'] ) &&
            
array_key_exists'value'$value )
        );
    }

    private function 
assign_values$values$schema ) {
        
$assigned = [];

        foreach ( 
$values as $key => $value ) {
            
$prop_type $schema instanceof Prop_Type $schema $schema$key ];

            
$transformed $this->transform$value$key$prop_type );

            if ( 
Multi_Props::is$transformed ) ) {
                
$assigned array_merge$assignedMulti_Props::get_value$transformed ) );

                continue;
            }

            
$assigned$key ] = $transformed;
        }

        return 
$assigned;
    }
}