PluginProbe
Elementor Website Builder – more than just a page builder / 4.3.0
Elementor Website Builder – more than just a page builder v4.3.0
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
elementor / modules / atomic-widgets / utils / atomic-prop-remap-handlers.php

atomic-prop-remap-handlers.php in Elementor Website Builder – more than just a page builder 4.3.0, at modules/atomic-widgets/utils/atomic-prop-remap-handlers.php

223 lines 6.7 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\Utils;
4
5 use Elementor\Modules\AtomicWidgets\DynamicTags\Dynamic_Prop_Type;
6 use Elementor\Modules\AtomicWidgets\PropTypes\Link_Prop_Type;
7 use Elementor\Modules\AtomicWidgets\PropTypes\Query_Array_Prop_Type;
8 use Elementor\Modules\AtomicWidgets\PropTypes\Query_Filter_Array_Prop_Type;
9 use Elementor\Modules\AtomicWidgets\PropTypes\Query_Filter_Prop_Type;
10 use Elementor\Modules\AtomicWidgets\PropTypes\Query_Prop_Type;
11 use Elementor\Plugin;
12
13 if ( ! defined( 'ABSPATH' ) ) {
14 exit; // Exit if accessed directly.
15 }
16
17 class Atomic_Prop_Remap_Handlers {
18 private const KIND_BY_SETTING_KEY = [
19 'post_id' => Atomic_Prop_Remap::KIND_POST,
20 'attachment_id' => Atomic_Prop_Remap::KIND_POST,
21 'template_id' => Atomic_Prop_Remap::KIND_POST,
22 'popup' => Atomic_Prop_Remap::KIND_POST,
23 'taxonomy_id' => Atomic_Prop_Remap::KIND_TERM,
24 'term_id' => Atomic_Prop_Remap::KIND_TERM,
25 'author_id' => Atomic_Prop_Remap::KIND_USER,
26 'user_id' => Atomic_Prop_Remap::KIND_USER,
27 ];
28
29 private const KIND_BY_FILTER_KEY = [
30 Atomic_Prop_Remap::FILTER_KEY_TERMS => Atomic_Prop_Remap::KIND_TERM,
31 Atomic_Prop_Remap::FILTER_KEY_AUTHORS => Atomic_Prop_Remap::KIND_USER,
32 Atomic_Prop_Remap::FILTER_KEY_MANUAL_SELECTION => Atomic_Prop_Remap::KIND_POST,
33 Atomic_Prop_Remap::FILTER_KEY_CURRENT_POST => null,
34 ];
35
36 private static ?self $instance = null;
37
38 /**
39 * @var callable|null
40 */
41 private $tag_resolver = null;
42
43 public static function register(): void {
44 $instance = self::instance();
45
46 Atomic_Prop_Remap_Registry::register( Query_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_query( ...$args ) );
47 Atomic_Prop_Remap_Registry::register( Query_Array_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_descend_value( ...$args ) );
48 Atomic_Prop_Remap_Registry::register( Query_Filter_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_query_filter( ...$args ) );
49 Atomic_Prop_Remap_Registry::register( Query_Filter_Array_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_descend_value( ...$args ) );
50 Atomic_Prop_Remap_Registry::register( Link_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_link( ...$args ) );
51 Atomic_Prop_Remap_Registry::register( Dynamic_Prop_Type::get_key(), fn( ...$args ) => $instance->remap_dynamic( ...$args ) );
52 }
53
54 public static function set_tag_resolver( ?callable $resolver ): void {
55 self::instance()->tag_resolver = $resolver;
56 }
57
58 private static function instance(): self {
59 if ( null === self::$instance ) {
60 self::$instance = new self();
61 }
62
63 return self::$instance;
64 }
65
66 private function remap_query( array $atomic, array $replacements, callable $descend, array $context = [] ): array {
67 $kind = $context['kind'] ?? null;
68
69 if ( null === $kind ) {
70 return $atomic;
71 }
72
73 $value = $atomic['value'] ?? null;
74
75 if ( ! is_array( $value ) || ! array_key_exists( 'id', $value ) ) {
76 return $atomic;
77 }
78
79 $value['id'] = Atomic_Prop_Remap::remap_id( $value['id'], $kind, $replacements );
80 $atomic['value'] = $value;
81
82 return $atomic;
83 }
84
85 private function remap_descend_value( array $atomic, array $replacements, callable $descend, array $context = [] ): array {
86 if ( isset( $atomic['value'] ) ) {
87 $atomic['value'] = $descend( $atomic['value'], $context );
88 }
89
90 return $atomic;
91 }
92
93 private function remap_query_filter( array $atomic, array $replacements, callable $descend, array $context = [] ): array {
94 $value = $atomic['value'] ?? null;
95
96 if ( ! is_array( $value ) ) {
97 return $atomic;
98 }
99
100 $filter_key = Atomic_Prop_Remap::extract_string( $value['key'] ?? null );
101 $kind = array_key_exists( $filter_key, self::KIND_BY_FILTER_KEY )
102 ? self::KIND_BY_FILTER_KEY[ $filter_key ]
103 : ( $context['kind'] ?? null );
104
105 $child_context = $context;
106 $child_context['kind'] = $kind;
107
108 if ( isset( $value['values'] ) ) {
109 $value['values'] = $descend( $value['values'], $child_context );
110 }
111
112 $atomic['value'] = $value;
113
114 return $atomic;
115 }
116
117 private function remap_link( array $atomic, array $replacements, callable $descend, array $context = [] ): array {
118 $value = $atomic['value'] ?? null;
119
120 if ( ! is_array( $value ) ) {
121 return $atomic;
122 }
123
124 if ( isset( $value['destination'] ) ) {
125 $destination_context = $context;
126 $destination_context['kind'] = Atomic_Prop_Remap::KIND_POST;
127 $value['destination'] = $descend( $value['destination'], $destination_context );
128 }
129
130 $atomic['value'] = $value;
131
132 return $atomic;
133 }
134
135 private function remap_dynamic( array $atomic, array $replacements, callable $descend, array $context = [] ): array {
136 $value = $atomic['value'] ?? null;
137
138 if ( ! is_array( $value ) ) {
139 return $atomic;
140 }
141
142 $settings = $value['settings'] ?? [];
143
144 if ( $this->is_legacy_flat_settings( $settings ) ) {
145 $value = $this->remap_dynamic_via_tag( $value, $replacements );
146 $settings = $value['settings'] ?? [];
147 }
148
149 if ( is_array( $settings ) ) {
150 foreach ( $settings as $setting_key => $setting_value ) {
151 $child_context = $context;
152 $child_context['kind'] = self::KIND_BY_SETTING_KEY[ $setting_key ] ?? ( $context['kind'] ?? null );
153 $settings[ $setting_key ] = $descend( $setting_value, $child_context );
154 }
155
156 $value['settings'] = $settings;
157 }
158
159 $atomic['value'] = $value;
160
161 return $atomic;
162 }
163
164 private function remap_dynamic_via_tag( array $value, array $replacements ): array {
165 $name = $value['name'] ?? '';
166
167 if ( ! is_string( $name ) || '' === $name ) {
168 return $value;
169 }
170
171 $tag = $this->resolve_tag( $name, $value['settings'] ?? [] );
172
173 if ( ! is_object( $tag ) ) {
174 return $value;
175 }
176
177 $config = [
178 'id' => '',
179 'name' => $name,
180 'settings' => $value['settings'] ?? [],
181 ];
182
183 if ( method_exists( $tag, 'on_import_replace_dynamic_content' ) ) {
184 $config = $tag::on_import_replace_dynamic_content( $config, $replacements['post_ids'] ?? [] );
185 } elseif ( method_exists( $tag, 'on_import_update_dynamic_content' ) ) {
186 $controls = method_exists( $tag, 'get_controls' ) ? $tag->get_controls() : [];
187 $config = $tag::on_import_update_dynamic_content( $config, $replacements, $controls );
188 }
189
190 if ( isset( $config['settings'] ) && is_array( $config['settings'] ) ) {
191 $value['settings'] = $config['settings'];
192 }
193
194 return $value;
195 }
196
197 private function resolve_tag( string $name, array $settings ) {
198 if ( $this->tag_resolver ) {
199 return ( $this->tag_resolver )( $name, $settings );
200 }
201
202 if ( ! class_exists( Plugin::class ) || empty( Plugin::$instance->dynamic_tags ) ) {
203 return null;
204 }
205
206 return Plugin::$instance->dynamic_tags->create_tag( '', $name, $settings );
207 }
208
209 private function is_legacy_flat_settings( $settings ): bool {
210 if ( ! is_array( $settings ) || empty( $settings ) ) {
211 return false;
212 }
213
214 foreach ( $settings as $setting ) {
215 if ( is_array( $setting ) && isset( $setting['$$type'] ) ) {
216 return false;
217 }
218 }
219
220 return true;
221 }
222 }
223