PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.3
Elementor Website Builder – more than just a page builder v4.2.3
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 4.2.3, at data/v2/manager.php

401 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 public function register_endpoint_format( $command, $format ) {
102 $this->command_formats[ $command ] = untrailingslashit( $format );
103 }
104
105 /**
106 * Find controller instance.
107 *
108 * By given command name.
109 *
110 * @param string $command
111 *
112 * @return false|\Elementor\Data\V2\Base\Controller
113 */
114 public function find_controller_instance( $command ) {
115 $command_parts = explode( '/', $command );
116 $assumed_command_parts = [];
117
118 foreach ( $command_parts as $command_part ) {
119 $assumed_command_parts [] = $command_part;
120
121 foreach ( $this->controllers as $controller_name => $controller ) {
122 $assumed_command = implode( '/', $assumed_command_parts );
123
124 if ( $assumed_command === $controller_name ) {
125 return $controller;
126 }
127 }
128 }
129
130 return false;
131 }
132
133 /**
134 * Command extract args.
135 *
136 * @param string $command
137 * @param array $args
138 *
139 * @return \stdClass
140 */
141 public function command_extract_args( $command, $args = [] ) {
142 $result = new \stdClass();
143 $result->command = $command;
144 $result->args = $args;
145
146 if ( false !== strpos( $command, '?' ) ) {
147 $command_parts = explode( '?', $command );
148 $pure_command = $command_parts[0];
149 $query_string = $command_parts[1];
150
151 parse_str( $query_string, $temp );
152
153 $result->command = untrailingslashit( $pure_command );
154 $result->args = array_merge( $args, $temp );
155 }
156
157 return $result;
158 }
159
160 /**
161 * Command to endpoint.
162 *
163 * Format is required otherwise $command will returned.
164 *
165 * @param string $command
166 * @param string $format
167 * @param array $args
168 *
169 * @return string endpoint
170 */
171 public function command_to_endpoint( $command, $format, $args ) {
172 $endpoint = $command;
173
174 if ( $format ) {
175 $formatted = $format;
176
177 array_walk( $args, function ( $val, $key ) use ( &$formatted ) {
178 $formatted = str_replace( '{' . $key . '}', $val, $formatted );
179 } );
180
181 // Remove remaining format if not requested via `$args`.
182 if ( strstr( $formatted, '/{' ) ) {
183 /**
184 * Example:
185 * $command = 'example/documents';
186 * $format = 'example/documents/{document_id}/elements/{element_id}';
187 * $formatted = 'example/documents/1618/elements/{element_id}';
188 * Result:
189 * $formatted = 'example/documents/1618/elements';
190 */
191 $formatted = substr( $formatted, 0, strpos( $formatted, '/{' ) );
192 }
193
194 $endpoint = $formatted;
195 }
196
197 return $endpoint;
198 }
199
200 /**
201 * Run server.
202 *
203 * Init WordPress reset api.
204 *
205 * @return \WP_REST_Server
206 */
207 public function run_server() {
208 /**
209 * If run_server() called means, that rest api is simulated from the backend.
210 */
211 $this->is_internal = true;
212
213 if ( ! $this->server ) {
214 // Remove all 'rest_api_init' actions.
215 remove_all_actions( 'rest_api_init' );
216
217 // Call custom reset api loader.
218 do_action( 'elementor_rest_api_before_init' );
219
220 $this->server = rest_get_server(); // Init API.
221 }
222
223 return $this->server;
224 }
225
226 /**
227 * Kill server.
228 *
229 * Free server and controllers.
230 */
231 public function kill_server() {
232 global $wp_rest_server;
233
234 $this->controllers = [];
235 $this->command_formats = [];
236 $this->server = false;
237 $this->is_internal = false;
238 $this->cache = [];
239 $wp_rest_server = false;
240 }
241
242 /**
243 * Run processor.
244 *
245 * @param Processor $processor
246 * @param array $data
247 *
248 * @return mixed
249 */
250 public function run_processor( $processor, $data ) {
251 if ( call_user_func_array( [ $processor, 'get_conditions' ], $data ) ) {
252 return call_user_func_array( [ $processor, 'apply' ], $data );
253 }
254
255 return null;
256 }
257
258 /**
259 * Run processors.
260 *
261 * Filter them by class.
262 *
263 * @param Processor[] $processors
264 * @param string $filter_by_class
265 * @param array $data
266 *
267 * @return false|array
268 */
269 public function run_processors( $processors, $filter_by_class, $data ) {
270 foreach ( $processors as $processor ) {
271 if ( $processor instanceof $filter_by_class ) {
272 if ( Processor\Before::class === $filter_by_class ) {
273 $this->run_processor( $processor, $data );
274 } elseif ( Processor\After::class === $filter_by_class ) {
275 $result = $this->run_processor( $processor, $data );
276 if ( $result ) {
277 $data[1] = $result;
278 }
279 } else {
280 trigger_error( "Invalid processor filter: '\${ $filter_by_class }'" ); // phpcs:ignore
281 break;
282 }
283 }
284 }
285
286 return isset( $data[1] ) ? $data[1] : false;
287 }
288
289 /**
290 * Run request.
291 *
292 * Simulate rest API from within the backend.
293 * Use args as query.
294 *
295 * @param string $endpoint
296 * @param array $args
297 * @param string $method
298 * @param string $name_space Optional.
299 * @param string $version Optional.
300 *
301 * @return \WP_REST_Response
302 */
303 public function run_request( $endpoint, $args = [], $method = \WP_REST_Server::READABLE, $name_space = self::ROOT_NAMESPACE, $version = self::VERSION ) {
304 $this->run_server();
305
306 $endpoint = '/' . $name_space . '/v' . $version . '/' . trim( $endpoint, '/' );
307
308 // Run reset api.
309 $request = new \WP_REST_Request( $method, $endpoint );
310
311 if ( 'GET' === $method ) {
312 $request->set_query_params( $args );
313 } else {
314 $request->set_body_params( $args );
315 }
316
317 return rest_do_request( $request );
318 }
319
320 /**
321 * Run endpoint.
322 *
323 * Wrapper for `$this->run_request` return `$response->getData()` instead of `$response`.
324 *
325 * @param string $endpoint
326 * @param array $args
327 * @param string $method
328 *
329 * @return array
330 */
331 public function run_endpoint( $endpoint, $args = [], $method = 'GET' ) {
332 // The method become public since it used in `Elementor\Data\V2\Base\Endpoint\Index\AllChildren`.
333 $response = $this->run_request( $endpoint, $args, $method );
334
335 return $response->get_data();
336 }
337
338 /**
339 * Run ( simulated reset api ).
340 *
341 * Do:
342 * Init reset server.
343 * Run before processors.
344 * Run command as reset api endpoint from internal.
345 * Run after processors.
346 *
347 * @param string $command
348 * @param array $args
349 * @param string $method
350 *
351 * @return array|false processed result
352 */
353 public function run( $command, $args = [], $method = 'GET' ) {
354 $key = crc32( $command . '-' . wp_json_encode( $args ) . '-' . $method );
355 $cache = $this->get_cache( $key );
356
357 if ( $cache ) {
358 return $cache;
359 }
360
361 $this->run_server();
362
363 $controller_instance = $this->find_controller_instance( $command );
364
365 if ( ! $controller_instance ) {
366 $this->set_cache( $key, [] );
367 return [];
368 }
369
370 $extracted_command = $this->command_extract_args( $command, $args );
371 $command = $extracted_command->command;
372 $args = $extracted_command->args;
373
374 $format = isset( $this->command_formats[ $command ] ) ? $this->command_formats[ $command ] : false;
375
376 $command_processors = $controller_instance->get_processors( $command );
377
378 $endpoint = $this->command_to_endpoint( $command, $format, $args );
379
380 $this->run_processors( $command_processors, Processor\Before::class, [ $args ] );
381
382 $response = $this->run_request( $endpoint, $args, $method );
383 $result = $response->get_data();
384
385 if ( $response->is_error() ) {
386 $this->set_cache( $key, [] );
387 return [];
388 }
389
390 $result = $this->run_processors( $command_processors, Processor\After::class, [ $args, $result ] );
391
392 $this->set_cache( $key, $result );
393
394 return $result;
395 }
396
397 public function is_internal() {
398 return $this->is_internal;
399 }
400 }
401