Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/data/v2/manager.php

Keine Baseline-Datei – Diff nur gegen leer.
Zur Liste
1 -
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 +