403Webshell
Server IP : 46.105.57.169  /  Your IP : 216.73.216.67
Web Server : Apache
System : Linux webm002.cluster120.gra.hosting.ovh.net 6.18.42-ovh-vps-grsec-zfs+ #1 SMP PREEMPT_DYNAMIC Wed Aug 5 15:59:48 CEST 2026 x86_64
User : verseaumee ( 152031)
PHP Version : 8.5.7
Disable Function : _dyuweyrj4,_dyuweyrj4r,dl
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/verseaumee/123click/assets/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/verseaumee/123click/assets/v2.tar
base/endpoint/index/sub-index-endpoint.php000064400000002740150777225640014654 0ustar00<?php
namespace Elementor\Data\V2\Base\Endpoint\Index;

use Elementor\Data\V2\Base\Endpoint\Index;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
/**
 * Class SubIndexEndpoint is default `Base\Endpoint\Index` of `SubController`,
 * it was created to handle base_route and format for child controller, index endpoint.
 * In case `SubController` were used and the default method of `Controller::register_index_endpoint` ain't overridden.
 * this class will give support to have such routes, eg: 'alpha/{id}/beta/{sub_id}' without using additional endpoints.
 */
final class Sub_Index_Endpoint extends Index {
	/***
	 * @var \Elementor\Data\V2\Base\Controller
	 */
	public $controller;

	public function get_format() {
		return $this->controller->get_parent()->get_name() . '/{id}/' . $this->controller->get_name() . '/{sub_id}';
	}

	public function get_base_route() {
		$parent_controller = $this->controller->get_parent();
		$parent_index_endpoint = $parent_controller->index_endpoint;
		$parent_controller_route = '';

		// In case `$parent_index_endpoint` is AllChildren, it cannot support id_arg_name.
		if ( ! $parent_index_endpoint instanceof AllChildren ) {
			$parent_controller_route = "(?P<{$parent_index_endpoint->id_arg_name}>[\w]+)";
		}

		return untrailingslashit('/' . implode( '/', array_filter( [
			trim( $parent_index_endpoint->get_base_route(), '/' ),
			$parent_controller_route,
			$this->controller->get_name(),
			$this->get_public_name(),
		] ) ) );
	}
}
base/endpoint/index/all-children.php000064400000003570150777225640013500 0ustar00<?php
namespace Elementor\Data\V2\Base\Endpoint\Index;

use Elementor\Data\V2\Base\Endpoint\Index;
use Elementor\Data\V2\Manager;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}
/**
 * class AllChildren, is optional endpoint.
 * Used in cases where the endpoints are static & there no use of dynamic endpoints( alpha/{id} ), eg:
 * 'settings' - controller
 * 'settings/products' - endpoint
 * 'settings/partners' - endpoint
 *
 * When 'settings' is requested, it should return results of all endpoints ( except it self ):
 * 'settings/products
 * 'settings/partners'
 * By running 'get_items' of each endpoint.
 */
class AllChildren extends Index {
	public function get_format() {
		return $this->controller->get_name() . '/index';
	}

	/*
	 * Retrieves a result(s) of all controller endpoint(s), items.
	 *
	 * Run overall endpoints of the current controller.
	 *
	 * Example, scenario:
	 * 'settings' - controller
	 * 'settings/products' - endpoint
	 * 'settings/partners' - endpoint
	 * Result:
	 * [
	 *  'products' => [
	 *      0 => ...
	 *      1 => ...
	 *  ],
	 *  'partners' => [
	 *      0 => ...
	 *      1 => ...
	 *  ],
	 * ]
	 */
	public function get_items( $request ) {
		$response = [];

		foreach ( $this->controller->get_sub_controllers() as $controller ) {
			$controller_route = $this->get_controller()->get_base_route() . '/' . $controller->get_name();
			$result = Manager::instance()->run_request( $controller_route );

			if ( ! $result->is_error() ) {
				$response[ $controller->get_name() ] = $result->get_data();
			}
		}

		foreach ( $this->controller->endpoints as $endpoint ) {
			// Skip self.
			if ( $endpoint === $this ) {
				continue;
			}

			$result = Manager::instance()->run_request( $endpoint->get_base_route() );

			if ( ! $result->is_error() ) {
				$response[ $endpoint->get_name() ] = $result->get_data();
			}
		}

		return $response;
	}
}
base/endpoint/index.php000064400000003172150777225640011140 0ustar00<?php
namespace Elementor\Data\V2\Base\Endpoint;

use Elementor\Data\V2\Base\Endpoint;
use WP_REST_Server;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class Index extends Endpoint {
	public function get_name() {
		return 'index';
	}

	public function get_format() {
		return "{$this->controller->get_full_name()}/{id}";
	}

	public function get_public_name() {
		return '';
	}

	public function get_items( $request ) {
		return $this->controller->get_items( $request );
	}

	public function get_item( $id, $request ) {
		return $this->controller->get_item( $request );
	}

	public function create_items( $request ) {
		return $this->controller->create_items( $request );
	}

	public function create_item( $id, $request ) {
		return $this->controller->create_item( $request );
	}

	public function update_items( $request ) {
		return $this->controller->update_items( $request );
	}

	public function update_item( $id, $request ) {
		return $this->controller->update_item( $request );
	}

	public function delete_items( $request ) {
		return $this->controller->delete_items( $request );
	}

	public function delete_item( $id, $request ) {
		return $this->controller->delete_item( $request );
	}

	public function register_items_route( $methods = WP_REST_Server::READABLE, $args = [] ) {
		parent::register_items_route( $methods, array_merge( $this->controller->get_items_args( $methods ), $args ) );
	}

	public function register_item_route( $methods = WP_REST_Server::READABLE, $args = [], $route = '/' ) {
		parent::register_item_route( $methods, array_merge( $this->controller->get_item_args( $methods ), $args ), $route );
	}
}
base/exceptions/data-exception.php000064400000002155150777225640013277 0ustar00<?php
namespace Elementor\Data\V2\Base\Exceptions;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class Data_Exception extends \Exception {
	protected $custom_data = [
		'code' => '',
		'data' => [],
	];

	public function get_code() {
		return 'reset-http-error';
	}

	public function get_message() {
		return '501 Not Implemented';
	}

	public function get_data() {
		return [
			'status' => $this->get_http_error_code(), // 'status' is used by WP to pass the http error code.
		];
	}

	public function to_wp_error() {
		return new \WP_Error( $this->custom_data['code'], $this->message, $this->custom_data['data'] );
	}

	protected function get_http_error_code() {
		return 501; // 501 Not Implemented
	}

	protected function apply() {}

	public function __construct( $message = '', $code = '', $data = [] ) {
		$this->message = empty( $message ) ? $this->get_message() : $message;
		$this->custom_data['code'] = empty( $code ) ? $this->get_code() : $code;
		$this->custom_data['data'] = empty( $data ) ? $this->get_data() : $data;

		parent::__construct( $this->message, 0, null );

		$this->apply();
	}
}
base/exceptions/wp-error-exception.php000064400000000561150777225640014142 0ustar00<?php
namespace Elementor\Data\V2\Base\Exceptions;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class WP_Error_Exception extends Data_Exception {
	public function __construct( \WP_Error $wp_error ) {
		parent::__construct( $wp_error->get_error_message(), $wp_error->get_error_code(), [
			'status' => $wp_error->get_error_code(),
		] );
	}
}
base/exceptions/error-404.php000064400000000533150777225640012026 0ustar00<?php
namespace Elementor\Data\V2\Base\Exceptions;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class Error_404 extends Data_Exception {

	protected function get_http_error_code() {
		return 404;
	}

	public function get_code() {
		return 'not-found';
	}

	public function get_message() {
		return '404 not found';
	}
}
base/exceptions/error-500.php000064400000000556150777225640012030 0ustar00<?php
namespace Elementor\Data\V2\Base\Exceptions;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

class Error_500 extends Data_Exception {

	protected function get_http_error_code() {
		return 500;
	}

	public function get_code() {
		return 'internal-server-error';
	}

	public function get_message() {
		return 'Something went wrong';
	}
}
base/processor/after.php000064400000001041150777225640011322 0ustar00<?php
namespace Elementor\Data\V2\Base\Processor;

use Elementor\Data\V2\Base\Processor;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

abstract class After extends Processor {

	/**
	 * Get conditions for running processor.
	 *
	 * @param array $args
	 * @param mixed $result
	 *
	 * @return bool
	 */
	public function get_conditions( $args, $result ) {
		return true;
	}

	/**
	 * Apply processor.
	 *
	 * @param $args
	 * @param $result
	 *
	 * @return mixed
	 */
	abstract public function apply( $args, $result );
}
base/processor/before.php000064400000000746150777225640011476 0ustar00<?php
namespace Elementor\Data\V2\Base\Processor;

use Elementor\Data\V2\Base\Processor;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

abstract class Before extends Processor {

	/**
	 * Get conditions for running processor.
	 * @param array $args
	 *
	 * @return bool
	 */
	public function get_conditions( $args ) {
		return true;
	}

	/**
	 * Apply processor.
	 *
	 * @param array $args
	 *
	 * @return mixed
	 */
	abstract public function apply( $args );
}
base/base-route.php000064400000024422150777225640010260 0ustar00<?php
namespace Elementor\Data\V2\Base;

use Elementor\Data\V2\Base\Exceptions\Data_Exception;
use Elementor\Data\V2\Base\Exceptions\Error_500;
use WP_REST_Server;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * Class purpose is to separate routing logic into one file.
 */
abstract class Base_Route {
	const AVAILABLE_METHODS = [
		WP_REST_Server::READABLE,
		WP_REST_Server::CREATABLE,
		WP_REST_Server::EDITABLE,
		WP_REST_Server::DELETABLE,
		WP_REST_Server::ALLMETHODS,
	];

	/**
	 * Controller of current endpoint.
	 *
	 * @var \Elementor\Data\V2\Base\Controller
	 */
	protected $controller;

	/**
	 * Current route, effect only in case the endpoint behave like sub-endpoint.
	 *
	 * @var string
	 */
	protected $route;

	/**
	 * All register routes.
	 *
	 * @var array
	 */
	protected $routes = [];

	/**
	 * Registered item route.
	 *
	 * @var array|null
	 */
	protected $item_route = null;

	protected $id_arg_name = 'id';
	protected $id_arg_type_regex = '[\d]+';

	/**
	 * Ensure start-with and end-with slashes.
	 *
	 * '/' => '/'
	 * 'abc' => '/abc/'
	 * '/abc' => '/abc/'
	 * 'abc/' => '/abc/'
	 * '/abc/' => '/abc/'
	 *
	 * @param string $route
	 *
	 * @return string
	 */
	private function ensure_slashes( $route ) {
		if ( '/' !== $route[0] ) {
			$route = '/' . $route;
		}

		return trailingslashit( $route );
	}

	/**
	 * Get base route.
	 * This method should always return the base route starts with '/' and ends without '/'.
	 *
	 * @return string
	 */
	public function get_base_route() {
		$name = $this->get_public_name();
		$parent = $this->get_parent();
		$parent_base = $parent->get_base_route();
		$route = '/';

		if ( ! ( $parent instanceof Controller ) ) {
			$route = $parent->item_route ? $parent->item_route['route'] . '/' : $this->route;
		}

		return untrailingslashit( '/' . trim( $parent_base . $route . $name, '/' ) );
	}

	/**
	 * Get permission callback.
	 *
	 * By default get permission callback from the controller.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return boolean
	 */
	public function get_permission_callback( $request ) {
		return $this->controller->get_permission_callback( $request );
	}

	/**
	 * Retrieves a collection of items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function get_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Retrieves one item from the collection.
	 *
	 * @param string $id
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function get_item( $id, $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Creates multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function create_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Creates one item.
	 *
	 * @param string $id id of request item.
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function create_item( $id, $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Updates multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function update_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Updates one item.
	 *
	 * @param string $id id of request item.
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function update_item( $id, $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Delete multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function delete_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Delete one item.
	 *
	 * @param string $id id of request item.
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	protected function delete_item( $id, $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Register the endpoint.
	 *
	 * By default: register get items route.
	 */
	protected function register() {
		$this->register_items_route();
	}

	protected function register_route( $route = '', $methods = WP_REST_Server::READABLE, $args = [] ) {
		if ( ! in_array( $methods, self::AVAILABLE_METHODS, true ) ) {
			trigger_error( "Invalid method: '$methods'.", E_USER_ERROR ); // phpcs:ignore
		}

		$route = $this->get_base_route() . $route;

		$this->routes [] = [
			'args' => $args,
			'route' => $route,
		];

		/**
		 * Determine behaviour of `base_callback()` and `get_permission_callback()`:
		 * For `base_callback()` which applying the action.
		 * Whether it's a one item request and should call `get_item_permission_callback()` or it's mutil items request and should call `get_items_permission_callback()`.
		 */
		$is_multi = ! empty( $args['is_multi'] );

		if ( $is_multi ) {
			unset( $args['is_multi'] );
		}

		$callback = function ( $request ) use ( $methods, $args, $is_multi ) {
			return $this->base_callback( $methods, $request, $is_multi );
		};

		return register_rest_route( $this->controller->get_namespace(), $route, [
			[
				'args' => $args,
				'methods' => $methods,
				'callback' => $callback,
				'permission_callback' => function ( $request ) {
					return $this->get_permission_callback( $request );
				},
			],
		] );
	}

	/**
	 * Register items route.
	 *
	 * @param string $methods
	 * @param array $args
	 */
	public function register_items_route( $methods = WP_REST_Server::READABLE, $args = [] ) {
		$args['is_multi'] = true;

		$this->register_route( '', $methods, $args );
	}

	/**
	 * Register item route.
	 *
	 * @param string $route
	 * @param array $args
	 * @param string $methods
	 */
	public function register_item_route( $methods = WP_REST_Server::READABLE, $args = [], $route = '/' ) {
		if ( ! empty( $args['id_arg_name'] ) ) {
			$this->id_arg_name = $args['id_arg_name'];

			unset( $args['id_arg_name'] );
		}

		if ( ! empty( $args['id_arg_type_regex'] ) ) {
			$this->id_arg_type_regex = $args['id_arg_type_regex'];

			unset( $args['id_arg_type_regex'] );
		}

		$args = array_merge( [
			$this->id_arg_name => [
				'description' => 'Unique identifier for the object.',
				'type' => 'string',
				'required' => true,
			],
		], $args );

		$route .= '(?P<' . $this->id_arg_name . '>' . $this->id_arg_type_regex . ')';

		$this->item_route = [
			'args' => $args,
			'route' => $route,
		];

		$this->register_route( $route, $methods, $args );
	}

	/**
	 * Base callback.
	 * All reset requests from the client should pass this function.
	 *
	 * @param string $methods
	 * @param \WP_REST_Request $request
	 * @param bool $is_multi
	 * @param array $args
	 *
	 * @return mixed|\WP_Error|\WP_HTTP_Response|\WP_REST_Response
	 */
	public function base_callback( $methods, $request, $is_multi = false, $args = [] ) {
		if ( $request ) {
			$json_params = $request->get_json_params();

			if ( $json_params ) {
				$request->set_body_params( $json_params );
			}
		}

		$args = wp_parse_args( $args, [
			'is_debug' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
		] );

		$result = new \WP_Error( 'invalid_methods', 'route not supported.' );

		$request->set_param( 'is_multi', $is_multi );

		try {
			switch ( $methods ) {
				case WP_REST_Server::READABLE:
					$result = $is_multi ? $this->get_items( $request ) : $this->get_item( $request->get_param( 'id' ), $request );
					break;

				case WP_REST_Server::CREATABLE:
					$result = $is_multi ? $this->create_items( $request ) : $this->create_item( $request->get_param( 'id' ), $request );
					break;

				case WP_REST_Server::EDITABLE:
					$result = $is_multi ? $this->update_items( $request ) : $this->update_item( $request->get_param( 'id' ), $request );
					break;

				case WP_REST_Server::DELETABLE:
					$result = $is_multi ? $this->delete_items( $request ) : $this->delete_item( $request->get_param( 'id' ), $request );
					break;
			}
		} catch ( Data_Exception $e ) {
			$result = $e->to_wp_error();
		} catch ( \Exception $e ) {
			if ( empty( $args['is_debug'] ) ) {
				$result = ( new Error_500() )->to_wp_error();
			} else {
				// For frontend.
				$exception_mapping = [
					'trace' => $e->getTrace(),
					'file' => $e->getFile(),
					'line' => $e->getLine(),
				];

				$e->debug = $exception_mapping;

				$result = ( new Data_Exception( $e->getMessage(), $e->getCode(), $e ) )->to_wp_error();
			}
		}

		return rest_ensure_response( $result );
	}

	/**
	 * Constructor.
	 *
	 * run `$this->register()`.
	 *
	 * @param \Elementor\Data\V2\Base\Controller $controller
	 * @param string $route
	 */
	protected function __construct( Controller $controller, $route ) {
		$this->controller = $controller;
		$this->route = $this->ensure_slashes( $route );

		$this->register();
	}
}
base/endpoint.php000064400000005741150777225640010035 0ustar00<?php
namespace Elementor\Data\V2\Base;

use Elementor\Data\V2\Manager;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

abstract class Endpoint extends Base_Route {
	/**
	 * Current parent.
	 *
	 * @var \Elementor\Data\V2\Base\Controller|\Elementor\Data\V2\Base\Endpoint
	 */
	protected $parent;

	/**
	 * Loaded sub endpoint(s).
	 *
	 * @var \Elementor\Data\V2\Base\Endpoint[]
	 */
	protected $sub_endpoints = [];

	/**
	 * Get endpoint name.
	 *
	 * @return string
	 */
	abstract public function get_name();

	/**
	 *
	 * Get endpoint format.
	 * The formats that generated using this function, will be used only be `Data\Manager::run()`.
	 *
	 * @return string
	 */
	abstract public function get_format();

	/**
	 * Get controller.
	 *
	 * @return \Elementor\Data\V2\Base\Controller
	 */
	public function get_controller() {
		return $this->controller;
	}

	/**
	 * Get current parent.
	 *
	 * @return \Elementor\Data\V2\Base\Controller|\Elementor\Data\V2\Base\Endpoint
	 */
	public function get_parent() {
		return $this->parent;
	}

	/**
	 * Get public name.
	 *
	 * @return string
	 */
	public function get_public_name() {
		return $this->get_name();
	}

	/**
	 * Get full command name ( including index ).
	 *
	 * @return string
	 */
	public function get_full_command() {
		$parent = $this->get_parent();

		if ( $parent instanceof Controller ) {
			return $this->controller->get_full_name() . '/' . $this->get_name();
		}

		return $this->get_name_ancestry();
	}

	/**
	 * Get name ancestry format, example: 'alpha/beta/delta'.
	 *
	 * @return string
	 */
	public function get_name_ancestry() {
		$ancestors = $this->get_ancestors();
		$ancestors_names = [];

		foreach ( $ancestors as $ancestor ) {
			$ancestors_names [] = $ancestor->get_name();
		}

		return implode( '/', $ancestors_names );
	}

	/**
	 * Register sub endpoint.
	 *
	 * @param \Elementor\Data\V2\Base\Endpoint $endpoint
	 *
	 * @return \Elementor\Data\V2\Base\Endpoint
	 */
	public function register_sub_endpoint( Endpoint $endpoint ) {
		$command = $endpoint->get_full_command();
		$format = $endpoint->get_format();

		$this->sub_endpoints[ $command ] = $endpoint;

		Manager::instance()->register_endpoint_format( $command, $format );

		return $endpoint;
	}

	/**
	 * Get ancestors.
	 *
	 * @return \Elementor\Data\V2\Base\Endpoint[]
	 */
	private function get_ancestors() {
		$ancestors = [];
		$current = $this;

		do {
			if ( $current ) {
				$ancestors [] = $current;
			}

			$current = $current->get_parent();
		} while ( $current );

		return array_reverse( $ancestors );
	}

	/**
	 * Endpoint constructor.
	 *
	 * @param \Elementor\Data\V2\Base\Controller|\Elementor\Data\V2\Base\Endpoint $parent
	 * @param string $route
	 */
	public function __construct( $parent, $route = '/' ) {
		$controller = $parent;
		$this->parent = $parent;

		// In case, its behave like sub-endpoint.
		if ( ! ( $parent instanceof Controller ) ) {
			$controller = $parent->get_controller();
		}

		parent::__construct( $controller, $route );
	}
}
base/controller.php000064400000027211150777225640010374 0ustar00<?php
namespace Elementor\Data\V2\Base;

use Elementor\Data\V2\Base\Exceptions\WP_Error_Exception;
use Elementor\Data\V2\Manager;
use WP_REST_Controller;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * TODO: Utilize 'WP_REST_Controller' as much as possible.
 */
abstract class Controller extends WP_REST_Controller {

	/**
	 * Loaded endpoint(s).
	 *
	 * @var \Elementor\Data\V2\Base\Endpoint[]
	 */
	public $endpoints = [];

	/**
	 * Index endpoint.
	 *
	 * @var \Elementor\Data\V2\Base\Endpoint\Index
	 */
	public $index_endpoint = null;

	/**
	 * Loaded processor(s).
	 *
	 * @var \Elementor\Data\V2\Base\Processor[][]
	 */
	public $processors = [];

	/**
	 * @var \Elementor\Data\V2\Base\Controller|null
	 */
	private $parent = null;

	/**
	 * @var \Elementor\Data\V2\Base\Controller[]
	 */
	private $sub_controllers = [];

	public static function get_default_namespace() {
		return Manager::ROOT_NAMESPACE;
	}

	public static function get_default_version() {
		return Manager::VERSION;
	}

	/**
	 * Get controller name.
	 *
	 * @return string
	 */
	abstract public function get_name();

	/**
	 * Register endpoints.
	 */
	public function register_endpoints() {
	}

	public function register_routes() {
		_doing_it_wrong( 'Elementor\Data\V2\Controller::register_routes', sprintf( "Method '%s' deprecated. use `register_endpoints()`.", __METHOD__ ), '3.5.0' );
	}

	/**
	 * Get parent controller name.
	 *
	 * @note: If `get_parent_name()` provided, controller will work as sub-controller.
	 *
	 * @returns null|string
	 */
	public function get_parent_name() {
		return null;
	}

	/**
	 * Get full controller name.
	 *
	 * The method exist to handle situations when parent exist, to include the parent name.
	 *
	 * @return string
	 */
	public function get_full_name() {
		if ( ! $this->parent ) {
			return $this->get_name();
		}

		return $this->parent->get_name() . '/' . $this->get_name();
	}

	/**
	 * Get controller namespace.
	 *
	 * @return string
	 */
	public function get_namespace() {
		return $this->namespace;
	}

	/**
	 * Get controller reset base.
	 *
	 * @return string
	 */
	public function get_base_route() {
		if ( ! $this->parent ) {
			return $this->rest_base;
		}

		return $this->parent->get_base_route() . '/' . $this->get_name();
	}

	/**
	 * Get controller route.
	 *
	 * @return string
	 */
	public function get_controller_route() {
		return $this->get_namespace() . '/' . $this->get_base_route();
	}

	/**
	 * Retrieves rest route(s) index for current controller.
	 *
	 * @return \WP_REST_Response|\WP_Error
	 */
	public function get_controller_index() {
		$server = rest_get_server();
		$routes = $server->get_routes();

		$endpoints = array_intersect_key( $server->get_routes(), $routes );

		$controller_route = $this->get_controller_route();

		array_walk( $endpoints, function ( &$item, $endpoint ) use ( &$endpoints, $controller_route ) {
			if ( ! strstr( $endpoint, $controller_route ) ) {
				unset( $endpoints[ $endpoint ] );
			}
		} );

		$data = [
			'namespace' => $this->get_namespace(),
			'controller' => $controller_route,
			'routes' => $server->get_data_for_routes( $endpoints ),
		];

		$response = rest_ensure_response( $data );

		// Link to the root index.
		$response->add_link( 'up', rest_url( '/' ) );

		return $response;
	}

	/**
	 * Get items args of index endpoint.
	 *
	 * Is method is used when `get_collection_params()` is not enough, and need of knowing the methods is required.
	 *
	 * @param string $methods
	 *
	 * @return array
	 */
	public function get_items_args( $methods ) {
		if ( \WP_REST_Server::READABLE === $methods ) {
			return $this->get_collection_params();
		}

		return [];
	}

	/**
	 * Get item args of index endpoint.
	 *
	 * @param string $methods
	 *
	 * @return array
	 */
	public function get_item_args( $methods ) {
		return [];
	}

	/**
	 * Get permission callback.
	 *
	 * Default controller permission callback.
	 * By default endpoint will inherit the permission callback from the controller.
	 *
	 * @param \WP_REST_Request $request
	 *
	 * @return bool
	 */
	public function get_permission_callback( $request ) {
		$is_multi = (bool) $request->get_param( 'is_multi' );

		$result = false;

		// The function is public since endpoint need to access it.
		// Utilize 'WP_REST_Controller' get_permission_check methods.
		switch ( $request->get_method() ) {
			case 'GET':
				$result = $is_multi ? $this->get_items_permissions_check( $request ) : $this->get_item_permissions_check( $request );
				break;
			case 'POST':
				$result = $is_multi ? $this->create_items_permissions_check( $request ) : $this->create_item_permissions_check( $request );
				break;
			case 'UPDATE':
			case 'PUT':
			case 'PATCH':
				$result = $is_multi ? $this->update_items_permissions_check( $request ) : $this->update_item_permissions_check( $request );
				break;

			case 'DELETE':
				$result = $is_multi ? $this->delete_items_permissions_check( $request ) : $this->delete_item_permissions_check( $request );
				break;
		}

		if ( $result instanceof \WP_Error ) {
			throw new WP_Error_Exception( $result );
		}

		return $result;
	}

	/**
	 * Checks if a given request has access to create items.
	 **
	 *
	 * @param \WP_REST_Request $request Full details about the request.
	 *
	 * @return true|\WP_Error True if the request has access to create items, WP_Error object otherwise.
	 */
	public function create_items_permissions_check( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Checks if a given request has access to update items.
	 *
	 * @param \WP_REST_Request $request Full details about the request.
	 *
	 * @return true|\WP_Error True if the request has access to update the item, WP_Error object otherwise.
	 */
	public function update_items_permissions_check( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Checks if a given request has access to delete items.
	 *
	 * @param \WP_REST_Request $request Full details about the request.
	 *
	 * @return true|\WP_Error True if the request has access to delete the item, WP_Error object otherwise.
	 */
	public function delete_items_permissions_check( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	public function get_items( $request ) {
		return $this->get_controller_index();
	}

	/**
	 * Creates multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function create_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Updates multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function update_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Delete multiple items.
	 *
	 * @param \WP_REST_Request $request Full data about the request.
	 *
	 * @return \WP_Error|\WP_REST_Response Response object on success, or WP_Error object on failure.
	 */
	public function delete_items( $request ) {
		return new \WP_Error( 'invalid-method', sprintf( "Method '%s' not implemented. Must be overridden in subclass.", __METHOD__ ), [ 'status' => 405 ] );
	}

	/**
	 * Get the parent controller.
	 *
	 * @return \Elementor\Data\V2\Base\Controller|null
	 */
	public function get_parent() {
		return $this->parent;
	}

	/**
	 * Get sub controller(s).
	 *
	 * @return \Elementor\Data\V2\Base\Controller[]
	 */
	public function get_sub_controllers() {
		return $this->sub_controllers;
	}

	/**
	 * Get processors.
	 *
	 * @param string $command
	 *
	 * @return \Elementor\Data\V2\Base\Processor[]
	 */
	public function get_processors( $command ) {
		$result = [];

		if ( isset( $this->processors[ $command ] ) ) {
			$result = $this->processors[ $command ];
		}

		return $result;
	}

	/**
	 * Register processors.
	 */
	public function register_processors() {
	}

	/**
	 * Register index endpoint.
	 */
	protected function register_index_endpoint() {
		if ( ! $this->parent ) {
			$this->register_endpoint( new Endpoint\Index( $this ) );

			return;
		}

		$this->register_endpoint( new Endpoint\Index\Sub_Index_Endpoint( $this ) );
	}

	/**
	 * Register endpoint.
	 *
	 * @param \Elementor\Data\V2\Base\Endpoint $endpoint
	 *
	 * @return \Elementor\Data\V2\Base\Endpoint
	 */
	protected function register_endpoint( Endpoint $endpoint ) {
		$command = $endpoint->get_full_command();

		if ( $endpoint instanceof Endpoint\Index ) {
			$this->index_endpoint = $endpoint;
		} else {
			$this->endpoints[ $command ] = $endpoint;
		}

		$format = $endpoint->get_format();

		// `$e.data.registerFormat()`.
		Manager::instance()->register_endpoint_format( $command, $format );

		return $endpoint;
	}

	/**
	 * Register a processor.
	 *
	 * That will be later attached to the endpoint class.
	 *
	 * @param Processor $processor
	 *
	 * @return \Elementor\Data\V2\Base\Processor $processor_instance
	 */
	protected function register_processor( Processor $processor ) {
		$command = $processor->get_command();

		if ( ! isset( $this->processors[ $command ] ) ) {
			$this->processors[ $command ] = [];
		}

		$this->processors[ $command ] [] = $processor;

		return $processor;
	}

	/**
	 * Register.
	 *
	 * Endpoints & processors.
	 */
	protected function register() {
		$this->register_index_endpoint();
		$this->register_endpoints();

		// Aka hooks.
		$this->register_processors();
	}

	/**
	 * Get collection params by 'additionalProperties' context.
	 *
	 * @param string $context
	 *
	 * @return array
	 */
	protected function get_collection_params_by_additional_props_context( $context ) {
		$result = [];

		$collection_params = $this->get_collection_params();

		foreach ( $collection_params as $collection_param_key => $collection_param ) {
			if ( isset( $collection_param['additionalProperties']['context'] ) && $context === $collection_param['additionalProperties']['context'] ) {
				$result[ $collection_param_key ] = $collection_param;
			}
		}

		return $result;
	}

	/**
	 * When `$this->get_parent_name` is extended, the controller will have a parent, and will know to behave like a sub-controller.
	 *
	 * @param string $parent_name
	 */
	private function act_as_sub_controller( $parent_name ) {
		$this->parent = Manager::instance()->get_controller( $parent_name );

		if ( ! $this->parent ) {
			trigger_error( "Cannot find parent controller: '$parent_name'", E_USER_ERROR ); // phpcs:ignore
		}

		$this->parent->sub_controllers [] = $this;
	}

	/**
	 * Controller constructor.
	 *
	 * Register endpoints on 'rest_api_init'.
	 */
	public function __construct() {
		$this->namespace = static::get_default_namespace() . '/v' . static::get_default_version();
		$this->rest_base = $this->get_name();

		add_action( 'rest_api_init', function () {
			$this->register(); // Because 'register' is protected.
		} );

		/**
		 * Since all actions were removed for custom internal REST server.
		 * Re-add the actions.
		 */
		add_action( 'elementor_rest_api_before_init', function () {
			add_action( 'rest_api_init', function () {
				$this->register();
			} );
		} );

		$parent_name = $this->get_parent_name();
		if ( $parent_name ) {
			$this->act_as_sub_controller( $parent_name );
		}
	}
}
base/processor.php000064400000001547150777225640010234 0ustar00<?php
namespace Elementor\Data\V2\Base;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * Processor is just typically HOOK, who called before or after a command runs.
 * It exist to simulate frontend ($e.data) like mechanism with commands and hooks, since each
 * controller or endpoint is reachable via command (get_format).
 * The `Elementor\Data\V2\Manager::run` is able to run them with the ability to reach the endpoint.
 */
abstract class Processor {

	/**
	 * Controller.
	 *
	 * @var \Elementor\Data\V2\Base\Controller
	 */
	private $controller;

	/**
	 * Get processor command.
	 *
	 * @return string
	 */
	abstract public function get_command();

	/**
	 * Processor constructor.
	 *
	 * @param \Elementor\Data\V2\Base\Controller $controller
	 */
	public function __construct( $controller ) {
		$this->controller = $controller;
	}
}
manager.php000064400000021640150777225640006711 0ustar00<?php
namespace Elementor\Data\V2;

use Elementor\Core\Base\Module as BaseModule;
use Elementor\Data\V2\Base\Processor;
use Elementor\Data\V2\Base\Controller;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * @method static \Elementor\Data\V2\Manager instance()
 */
class Manager extends BaseModule {

	const ROOT_NAMESPACE = 'elementor';

	const VERSION = '1';

	/**
	 * @var \WP_REST_Server
	 */
	private $server;

	/**
	 * @var boolean
	 */
	private $is_internal = false;

	/**
	 * @var array
	 */
	private $cache = [];

	/**
	 * Loaded controllers.
	 *
	 * @var \Elementor\Data\V2\Base\Controller[]
	 */
	public $controllers = [];

	/**
	 * Loaded command(s) format.
	 *
	 * @var string[]
	 */
	public $command_formats = [];

	public function get_name() {
		return 'data-manager-v2';
	}

	/**
	 * @return \Elementor\Data\V2\Base\Controller[]
	 */
	public function get_controllers() {
		return $this->controllers;
	}

	/**
	 * @param string $name
	 *
	 * @return \Elementor\Data\V2\Base\Controller|false
	 */
	public function get_controller( $name ) {
		if ( isset( $this->controllers[ $name ] ) ) {
			return $this->controllers[ $name ];
		}

		return false;
	}

	private function get_cache( $key ) {
		return self::get_items( $this->cache, $key );
	}

	private function set_cache( $key, $value ) {
		$this->cache[ $key ] = $value;
	}

	/**
	 * Register controller.
	 *
	 * @param \Elementor\Data\V2\Base\Controller $controller_instance
	 *
	 * @return \Elementor\Data\V2\Base\Controller
	 */
	public function register_controller( Controller $controller_instance ) {
		$this->controllers[ $controller_instance->get_name() ] = $controller_instance;

		return $controller_instance;
	}

	/**
	 * Register endpoint format.
	 *
	 * @param string $command
	 * @param string $format
	 *
	 */
	public function register_endpoint_format( $command, $format ) {
		$this->command_formats[ $command ] = untrailingslashit( $format );
	}

	/**
	 * Find controller instance.
	 *
	 * By given command name.
	 *
	 * @param string $command
	 *
	 * @return false|\Elementor\Data\V2\Base\Controller
	 */
	public function find_controller_instance( $command ) {
		$command_parts = explode( '/', $command );
		$assumed_command_parts = [];

		foreach ( $command_parts as $command_part ) {
			$assumed_command_parts [] = $command_part;

			foreach ( $this->controllers as $controller_name => $controller ) {
				$assumed_command = implode( '/', $assumed_command_parts );

				if ( $assumed_command === $controller_name ) {
					return $controller;
				}
			}
		}

		return false;
	}

	/**
	 * Command extract args.
	 *
	 * @param string $command
	 * @param array $args
	 *
	 * @return \stdClass
	 */
	public function command_extract_args( $command, $args = [] ) {
		$result = new \stdClass();
		$result->command = $command;
		$result->args = $args;

		if ( false !== strpos( $command, '?' ) ) {
			$command_parts = explode( '?', $command );
			$pure_command = $command_parts[0];
			$query_string = $command_parts[1];

			parse_str( $query_string, $temp );

			$result->command = untrailingslashit( $pure_command );
			$result->args = array_merge( $args, $temp );
		}

		return $result;
	}

	/**
	 * Command to endpoint.
	 *
	 * Format is required otherwise $command will returned.
	 *
	 * @param string $command
	 * @param string $format
	 * @param array  $args
	 *
	 * @return string endpoint
	 */
	public function command_to_endpoint( $command, $format, $args ) {
		$endpoint = $command;

		if ( $format ) {
			$formatted = $format;

			array_walk( $args, function ( $val, $key ) use ( &$formatted ) {
				$formatted = str_replace( '{' . $key . '}', $val, $formatted );
			} );

			// Remove remaining format if not requested via `$args`.
			if ( strstr( $formatted, '/{' ) ) {
				/**
				 * Example:
				 * $command = 'example/documents';
				 * $format = 'example/documents/{document_id}/elements/{element_id}';
				 * $formatted = 'example/documents/1618/elements/{element_id}';
				 * Result:
				 * $formatted = 'example/documents/1618/elements';
				 */
				$formatted = substr( $formatted, 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;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit