PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.8
Elementor Website Builder – more than just a page builder v3.6.8
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 / data / v2 / manager.php

manager.php in Elementor Website Builder – more than just a page builder 3.6.8, at data/v2/manager.php

402 lines 8.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor\Data\V2;
3
4 use Elementor\Core\Base\Module as BaseModule;
5 use Elementor\Data\V2\Base\Processor;
6 use Elementor\Data\V2\Base\Controller;
7
8 if ( ! defined( 'ABSPATH' ) ) {
9 exit; // Exit if accessed directly
10 }
11
12 /**
13 * @method static \Elementor\Data\V2\Manager instance()
14 */
15 class Manager extends BaseModule {
16
17 const ROOT_NAMESPACE = 'elementor';
18
19 const VERSION = '1';
20
21 /**
22 * @var \WP_REST_Server
23 */
24 private $server;
25
26 /**
27 * @var boolean
28 */
29 private $is_internal = false;
30
31 /**
32 * @var array
33 */
34 private $cache = [];
35
36 /**
37 * Loaded controllers.
38 *
39 * @var \Elementor\Data\V2\Base\Controller[]
40 */
41 public $controllers = [];
42
43 /**
44 * Loaded command(s) format.
45 *
46 * @var string[]
47 */
48 public $command_formats = [];
49
50 public function get_name() {
51 return 'data-manager-v2';
52 }
53
54 /**
55 * @return \Elementor\Data\V2\Base\Controller[]
56 */
57 public function get_controllers() {
58 return $this->controllers;
59 }
60
61 /**
62 * @param string $name
63 *
64 * @return \Elementor\Data\V2\Base\Controller|false
65 */
66 public function get_controller( $name ) {
67 if ( isset( $this->controllers[ $name ] ) ) {
68 return $this->controllers[ $name ];
69 }
70
71 return false;
72 }
73
74 private function get_cache( $key ) {
75 return self::get_items( $this->cache, $key );
76 }
77
78 private function set_cache( $key, $value ) {
79 $this->cache[ $key ] = $value;
80 }
81
82 /**
83 * Register controller.
84 *
85 * @param \Elementor\Data\V2\Base\Controller $controller_instance
86 *
87 * @return \Elementor\Data\V2\Base\Controller
88 */
89 public function register_controller( Controller $controller_instance ) {
90 $this->controllers[ $controller_instance->get_name() ] = $controller_instance;
91
92 return $controller_instance;
93 }
94
95 /**
96 * Register endpoint format.
97 *
98 * @param string $command
99 * @param string $format
100 *
101 */
102 public function register_endpoint_format( $command, $format ) {
103 $this->command_formats[ $command ] = untrailingslashit( $format );
104 }
105
106 /**
107 * Find controller instance.
108 *
109 * By given command name.
110 *
111 * @param string $command
112 *
113 * @return false|\Elementor\Data\V2\Base\Controller
114 */
115 public function find_controller_instance( $command ) {
116 $command_parts = explode( '/', $command );
117 $assumed_command_parts = [];
118
119 foreach ( $command_parts as $command_part ) {
120 $assumed_command_parts [] = $command_part;
121
122 foreach ( $this->controllers as $controller_name => $controller ) {
123 $assumed_command = implode( '/', $assumed_command_parts );
124
125 if ( $assumed_command === $controller_name ) {
126 return $controller;
127 }
128 }
129 }
130
131 return false;
132 }
133
134 /**
135 * Command extract args.
136 *
137 * @param string $command
138 * @param array $args
139 *
140 * @return \stdClass
141 */
142 public function command_extract_args( $command, $args = [] ) {
143 $result = new \stdClass();
144 $result->command = $command;
145 $result->args = $args;
146
147 if ( false !== strpos( $command, '?' ) ) {
148 $command_parts = explode( '?', $command );
149 $pure_command = $command_parts[0];
150 $query_string = $command_parts[1];
151
152 parse_str( $query_string, $temp );
153
154 $result->command = untrailingslashit( $pure_command );
155 $result->args = array_merge( $args, $temp );
156 }
157
158 return $result;
159 }
160
161 /**
162 * Command to endpoint.
163 *
164 * Format is required otherwise $command will returned.
165 *
166 * @param string $command
167 * @param string $format
168 * @param array $args
169 *
170 * @return string endpoint
171 */
172 public function command_to_endpoint( $command, $format, $args ) {
173 $endpoint = $command;
174
175 if ( $format ) {
176 $formatted = $format;
177
178 array_walk( $args, function ( $val, $key ) use ( &$formatted ) {
179 $formatted = str_replace( '{' . $key . '}', $val, $formatted );
180 } );
181
182 // Remove remaining format if not requested via `$args`.
183 if ( strstr( $formatted, '/{' ) ) {
184 /**
185 * Example:
186 * $command = 'example/documents';
187 * $format = 'example/documents/{document_id}/elements/{element_id}';
188 * $formatted = 'example/documents/1618/elements/{element_id}';
189 * Result:
190 * $formatted = 'example/documents/1618/elements';
191 */
192 $formatted = substr( $formatted, 0, strpos( $formatted, '/{' ) );
193 }
194
195 $endpoint = $formatted;
196 }
197
198 return $endpoint;
199 }
200
201 /**
202 * Run server.
203 *
204 * Init WordPress reset api.
205 *
206 * @return \WP_REST_Server
207 */
208 public function run_server() {
209 /**
210 * If run_server() called means, that rest api is simulated from the backend.
211 */
212 $this->is_internal = true;
213
214 if ( ! $this->server ) {
215 // Remove all 'rest_api_init' actions.
216 remove_all_actions( 'rest_api_init' );
217
218 // Call custom reset api loader.
219 do_action( 'elementor_rest_api_before_init' );
220
221 $this->server = rest_get_server(); // Init API.
222 }
223
224 return $this->server;
225 }
226
227 /**
228 * Kill server.
229 *
230 * Free server and controllers.
231 */
232 public function kill_server() {
233 global $wp_rest_server;
234
235 $this->controllers = [];
236 $this->command_formats = [];
237 $this->server = false;
238 $this->is_internal = false;
239 $this->cache = [];
240 $wp_rest_server = false;
241 }
242
243 /**
244 * Run processor.
245 *
246 * @param \Elementor\Data\V2\Base\Processor $processor
247 * @param array $data
248 *
249 * @return mixed
250 */
251 public function run_processor( $processor, $data ) {
252 if ( call_user_func_array( [ $processor, 'get_conditions' ], $data ) ) {
253 return call_user_func_array( [ $processor, 'apply' ], $data );
254 }
255
256 return null;
257 }
258
259 /**
260 * Run processors.
261 *
262 * Filter them by class.
263 *
264 * @param \Elementor\Data\V2\Base\Processor[] $processors
265 * @param string $filter_by_class
266 * @param array $data
267 *
268 * @return false|array
269 */
270 public function run_processors( $processors, $filter_by_class, $data ) {
271 foreach ( $processors as $processor ) {
272 if ( $processor instanceof $filter_by_class ) {
273 if ( Processor\Before::class === $filter_by_class ) {
274 $this->run_processor( $processor, $data );
275 } elseif ( Processor\After::class === $filter_by_class ) {
276 $result = $this->run_processor( $processor, $data );
277 if ( $result ) {
278 $data[1] = $result;
279 }
280 } else {
281 trigger_error( "Invalid processor filter: '${ $filter_by_class }'" ); // phpcs:ignore
282 break;
283 }
284 }
285 }
286
287 return isset( $data[1] ) ? $data[1] : false;
288 }
289
290 /**
291 * Run request.
292 *
293 * Simulate rest API from within the backend.
294 * Use args as query.
295 *
296 * @param string $endpoint
297 * @param array $args
298 * @param string $method
299 * @param string $namespace (optional)
300 * @param string $version (optional)
301 *
302 * @return \WP_REST_Response
303 */
304 public function run_request( $endpoint, $args = [], $method = \WP_REST_Server::READABLE, $namespace = self::ROOT_NAMESPACE, $version = self::VERSION ) {
305 $this->run_server();
306
307 $endpoint = '/' . $namespace . '/v' . $version . '/' . trim( $endpoint, '/' );
308
309 // Run reset api.
310 $request = new \WP_REST_Request( $method, $endpoint );
311
312 if ( 'GET' === $method ) {
313 $request->set_query_params( $args );
314 } else {
315 $request->set_body_params( $args );
316 }
317
318 return rest_do_request( $request );
319 }
320
321 /**
322 * Run endpoint.
323 *
324 * Wrapper for `$this->run_request` return `$response->getData()` instead of `$response`.
325 *
326 * @param string $endpoint
327 * @param array $args
328 * @param string $method
329 *
330 * @return array
331 */
332 public function run_endpoint( $endpoint, $args = [], $method = 'GET' ) {
333 // The method become public since it used in `Elementor\Data\V2\Base\Endpoint\Index\AllChildren`.
334 $response = $this->run_request( $endpoint, $args, $method );
335
336 return $response->get_data();
337 }
338
339 /**
340 * Run ( simulated reset api ).
341 *
342 * Do:
343 * Init reset server.
344 * Run before processors.
345 * Run command as reset api endpoint from internal.
346 * Run after processors.
347 *
348 * @param string $command
349 * @param array $args
350 * @param string $method
351 *
352 * @return array|false processed result
353 */
354 public function run( $command, $args = [], $method = 'GET' ) {
355 $key = crc32( $command . '-' . wp_json_encode( $args ) . '-' . $method );
356 $cache = $this->get_cache( $key );
357
358 if ( $cache ) {
359 return $cache;
360 }
361
362 $this->run_server();
363
364 $controller_instance = $this->find_controller_instance( $command );
365
366 if ( ! $controller_instance ) {
367 $this->set_cache( $key, [] );
368 return [];
369 }
370
371 $extracted_command = $this->command_extract_args( $command, $args );
372 $command = $extracted_command->command;
373 $args = $extracted_command->args;
374
375 $format = isset( $this->command_formats[ $command ] ) ? $this->command_formats[ $command ] : false;
376
377 $command_processors = $controller_instance->get_processors( $command );
378
379 $endpoint = $this->command_to_endpoint( $command, $format, $args );
380
381 $this->run_processors( $command_processors, Processor\Before::class, [ $args ] );
382
383 $response = $this->run_request( $endpoint, $args, $method );
384 $result = $response->get_data();
385
386 if ( $response->is_error() ) {
387 $this->set_cache( $key, [] );
388 return [];
389 }
390
391 $result = $this->run_processors( $command_processors, Processor\After::class, [ $args, $result ] );
392
393 $this->set_cache( $key, $result );
394
395 return $result;
396 }
397
398 public function is_internal() {
399 return $this->is_internal;
400 }
401 }
402