ormatted, 0, strpos( $formatted, '/{' ) ); } $endpoint = $formatted; } return $endpoint; } /** * Run server. * * Init WordPress reset api. * * @return \WP_REST_Server */ public function run_server() { /** * If run_server() called means, that rest api is simulated from the backend. */ $this->is_internal = true; if ( ! $this->server ) { // Remove all 'rest_api_init' actions. remove_all_actions( 'rest_api_init' ); // Call custom reset api loader. do_action( 'elementor_rest_api_before_init' ); $this->server = rest_get_server(); // Init API. } return $this->server; } /** * Kill server. * * Free server and controllers. */ public function kill_server() { global $wp_rest_server; $this->controllers = []; $this->command_formats = []; $this->server = false; $this->is_internal = false; $this->cache = []; $wp_rest_server = false; } /** * Run processor. * * @param \Elementor\Data\V2\Base\Processor $processor * @param array $data * * @return mixed */ public function run_processor( $processor, $data ) { if ( call_user_func_array( [ $processor, 'get_conditions' ], $data ) ) { return call_user_func_array( [ $processor, 'apply' ], $data ); } return null; } /** * Run processors. * * Filter them by class. * * @param \Elementor\Data\V2\Base\Processor[] $processors * @param string $filter_by_class * @param array $data * * @return false|array */ public function run_processors( $processors, $filter_by_class, $data ) { foreach ( $processors as $processor ) { if ( $processor instanceof $filter_by_class ) { if ( Processor\Before::class === $filter_by_class ) { $this->run_processor( $processor, $data ); } elseif ( Processor\After::class === $filter_by_class ) { $result = $this->run_processor( $processor, $data ); if ( $result ) { $data[1] = $result; } } else { trigger_error( "Invalid processor filter: '\${ $filter_by_class }'" ); // phpcs:ignore break; } } } return isset( $data[1] ) ? $data[1] : false; } /** * Run request. * * Simulate rest API from within the backend. * Use args as query. * * @param string $endpoint * @param array $args * @param string $method * @param string $namespace (optional) * @param string $version (optional) * * @return \WP_REST_Response */ public function run_request( $endpoint, $args = [], $method = \WP_REST_Server::READABLE, $namespace = self::ROOT_NAMESPACE, $version = self::VERSION ) { $this->run_server(); $endpoint = '/' . $namespace . '/v' . $version . '/' . trim( $endpoint, '/' ); // Run reset api. $request = new \WP_REST_Request( $method, $endpoint ); if ( 'GET' === $method ) { $request->set_query_params( $args ); } else { $request->set_body_params( $args ); } return rest_do_request( $request ); } /** * Run endpoint. * * Wrapper for `$this->run_request` return `$response->getData()` instead of `$response`. * * @param string $endpoint * @param array $args * @param string $method * * @return array */ public function run_endpoint( $endpoint, $args = [], $method = 'GET' ) { // The method become public since it used in `Elementor\Data\V2\Base\Endpoint\Index\AllChildren`. $response = $this->run_request( $endpoint, $args, $method ); return $response->get_data(); } /** * Run ( simulated reset api ). * * Do: * Init reset server. * Run before processors. * Run command as reset api endpoint from internal. * Run after processors. * * @param string $command * @param array $args * @param string $method * * @return array|false processed result */ public function run( $command, $args = [], $method = 'GET' ) { $key = crc32( $command . '-' . wp_json_encode( $args ) . '-' . $method ); $cache = $this->get_cache( $key ); if ( $cache ) { return $cache; } $this->run_server(); $controller_instance = $this->find_controller_instance( $command ); if ( ! $controller_instance ) { $this->set_cache( $key, [] ); return []; } $extracted_command = $this->command_extract_args( $command, $args ); $command = $extracted_command->command; $args = $extracted_command->args; $format = isset( $this->command_formats[ $command ] ) ? $this->command_formats[ $command ] : false; $command_processors = $controller_instance->get_processors( $command ); $endpoint = $this->command_to_endpoint( $command, $format, $args ); $this->run_processors( $command_processors, Processor\Before::class, [ $args ] ); $response = $this->run_request( $endpoint, $args, $method ); $result = $response->get_data(); if ( $response->is_error() ) { $this->set_cache( $key, [] ); return []; } $result = $this->run_processors( $command_processors, Processor\After::class, [ $args, $result ] ); $this->set_cache( $key, $result ); return $result; } public function is_internal() { return $this->is_internal; } }