File manager - Edit - /home/contenidosenred/public_html/OD/wp-admin/includes/219846/elementor.zip
Back
PK (am[D:R��# �# data/base/endpoint.phpnu �[��� <?php namespace Elementor\Data\Base; use Elementor\Data\Manager; use WP_REST_Server; abstract class Endpoint { 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\Base\Controller */ protected $controller; /** * Loaded sub endpoint(s). * * @var \Elementor\Data\Base\SubEndpoint[] */ private $sub_endpoints = []; /** * Get format suffix. * * Examples: * '{one_parameter_name}'. * '{one_parameter_name}/{two_parameter_name}/'. * '{one_parameter_name}/whatever/anything/{two_parameter_name}/' and so on for each endpoint or sub-endpoint. * * @return string current location will later be added automatically. */ public static function get_format() { return ''; } /** * Endpoint constructor. * * run `$this->>register()`. * * @param \Elementor\Data\Base\Controller $controller * * @throws \Exception */ public function __construct( $controller ) { if ( ! ( $controller instanceof Controller ) ) { throw new \Exception( 'Invalid controller' ); } $this->controller = $controller; $this->register(); } /** * Get endpoint name. * * @return string */ abstract public function get_name(); /** * Get base route. * * Removing 'index' from endpoint. * * @return string */ public function get_base_route() { $endpoint_name = $this->get_name(); // TODO: Allow this only for internal routes. // TODO: Make difference between internal and external endpoints. if ( 'index' === $endpoint_name ) { $endpoint_name = ''; } return '/' . $this->controller->get_rest_base() . '/' . $endpoint_name; } /** * Register the endpoint. * * By default: register get items route. * * @throws \Exception */ protected function register() { $this->register_items_route(); } /** * Register sub endpoint. * * @param string $route * @param string $endpoint_class * * @return \Elementor\Data\Base\SubEndpoint * @throws \Exception */ protected function register_sub_endpoint( $route, $endpoint_class ) { $endpoint_instance = new $endpoint_class( $route, $this ); if ( ! ( $endpoint_instance instanceof SubEndpoint ) ) { throw new \Exception( 'Invalid endpoint instance.' ); } $endpoint_route = $route . '/' . $endpoint_instance->get_name(); $this->sub_endpoints[ $endpoint_route ] = $endpoint_instance; $component_name = $endpoint_instance->controller->get_rest_base(); $parent_instance = $endpoint_instance->get_parent(); $parent_name = $endpoint_instance->get_name(); $parent_format_suffix = $parent_instance::get_format(); $current_format_suffix = $endpoint_instance::get_format(); $command = $component_name . '/' . $parent_name; $format = $component_name . '/' . $parent_format_suffix . '/' . $parent_name . '/' . $current_format_suffix; Manager::instance()->register_endpoint_format( $command, $format ); return $endpoint_instance; } /** * Base callback. * * All reset requests from the client should pass this function. * * @param string $methods * @param \WP_REST_Request $request * @param bool $is_multi * * @return mixed|\WP_Error|\WP_HTTP_Response|\WP_REST_Response * @throws \Exception */ public function base_callback( $methods, $request, $is_multi = false ) { // TODO: Find better solution. $json_params = $request->get_json_params(); if ( $json_params ) { $request->set_body_params( $json_params ); } // TODO: Handle permission callback. 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; default: throw new \Exception( 'Invalid method.' ); } return rest_ensure_response( $result ); } /** * 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. */ public function get_items( $request ) { return $this->controller->get_items( $request ); } /** * 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. */ public function get_item( $id, $request ) { return $this->controller->get_item( $request ); } /** * 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 ); } /** * 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. */ public function create_item( $id, $request ) { return $this->controller->create_item( $request ); } /** * 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 $this->controller->create_items( $request ); } /** * 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. */ public function update_item( $id, $request ) { return $this->controller->update_item( $request ); } /** * 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 $this->controller->update_items( $request ); } /** * 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. */ public function delete_item( $id, $request ) { return $this->controller->delete_item( $request ); } /** * 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 $this->controller->delete_items( $request ); } /** * Register item route. * * @param array $args * @param string $route * @param string $methods * * @throws \Exception */ public function register_item_route( $methods = WP_REST_Server::READABLE, $args = [], $route = '/' ) { $args = array_merge( [ 'id' => [ 'description' => 'Unique identifier for the object.', 'type' => 'string', ], ], $args ); if ( isset( $args['id'] ) && $args['id'] ) { $route .= '(?P<id>[\w]+)/'; } $this->register_route( $route, $methods, function ( $request ) use ( $methods ) { return $this->base_callback( $methods, $request ); }, $args ); } /** * Register items route. * * @param string $methods * * @throws \Exception */ public function register_items_route( $methods = WP_REST_Server::READABLE ) { $this->register_route( '', $methods, function ( $request ) use ( $methods ) { return $this->base_callback( $methods, $request, true ); } ); } /** * Register route. * * @param string $route * @param string $methods * @param null $callback * @param array $args * * @return bool * @throws \Exception */ public function register_route( $route = '', $methods = WP_REST_Server::READABLE, $callback = null, $args = [] ) { if ( ! in_array( $methods, self::AVAILABLE_METHODS, true ) ) { throw new \Exception( 'Invalid method.' ); } $route = $this->get_base_route() . $route; 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 ); }, ], ] ); } } PK (am[UW�{� � data/base/sub-endpoint.phpnu �[��� <?php namespace Elementor\Data\Base; // TODO: Add test. abstract class SubEndpoint extends Endpoint { /** * @var Endpoint */ protected $parent_endpoint; /** * @var string */ protected $parent_route = ''; public function __construct( $parent_route, $parent_endpoint ) { $this->parent_endpoint = $parent_endpoint; $this->parent_route = $parent_route; parent::__construct( $this->parent_endpoint->controller ); } /** * Get parent route. * * @return \Elementor\Data\Base\Endpoint */ public function get_parent() { return $this->parent_endpoint; } public function get_base_route() { $controller_name = $this->controller->get_name(); return $controller_name . '/' . $this->parent_route . $this->get_name(); } } PK (am[���� � data/base/processor/before.phpnu �[��� <?php namespace Elementor\Data\Base\Processor; use Elementor\Data\Base\Processor; 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 ); } PK (am[�j� � data/base/processor/after.phpnu �[��� <?php namespace Elementor\Data\Base\Processor; use Elementor\Data\Base\Processor; 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 ); } PK (am[�;��j j data/base/controller.phpnu �[��� <?php namespace Elementor\Data\Base; use Elementor\Data\Manager; use WP_REST_Controller; use WP_REST_Server; abstract class Controller extends WP_REST_Controller { /** * Loaded endpoint(s). * * @var \Elementor\Data\Base\Endpoint[] */ public $endpoints = []; /** * Loaded processor(s). * * @var \Elementor\Data\Base\Processor[][] */ public $processors = []; /** * Controller constructor. * * Register endpoints on 'rest_api_init'. * */ public function __construct() { // TODO: Controllers and endpoints can have common interface. $this->namespace = Manager::ROOT_NAMESPACE . '/v' . Manager::VERSION; $this->rest_base = Manager::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(); } ); } ); } /** * Get controller name. * * @return string */ abstract public function get_name(); /** * Get controller namespace. * * @return string */ public function get_namespace() { return $this->namespace; } /** * Get controller reset base. * * @return string */ public function get_rest_base() { return $this->rest_base; } /** * Get controller route. * * @return string */ public function get_controller_route() { return $this->get_namespace() . '/' . $this->get_rest_base(); } /** * Retrieves the index for a 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 processors. * * @param string $command * * @return \Elementor\Data\Base\Processor[] */ public function get_processors( $command ) { $result = []; if ( isset( $this->processors[ $command ] ) ) { $result = $this->processors[ $command ]; } return $result; } 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 ] ); } /** * Register endpoints. */ abstract public function register_endpoints(); /** * Register processors. */ public function register_processors() { } /** * Register internal endpoints. */ protected function register_internal_endpoints() { register_rest_route( $this->get_namespace(), '/' . $this->get_rest_base(), [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => array( $this, 'get_items' ), 'args' => [], 'permission_callback' => function ( $request ) { return $this->get_permission_callback( $request ); }, ], ] ); } /** * Register endpoint. * * @param string $endpoint_class * * @return \Elementor\Data\Base\Endpoint */ protected function register_endpoint( $endpoint_class ) { $endpoint_instance = new $endpoint_class( $this ); // TODO: Validate instance like in register_sub_endpoint(). $endpoint_route = $this->get_name() . '/' . $endpoint_instance->get_name(); $this->endpoints[ $endpoint_route ] = $endpoint_instance; $command = $endpoint_route; $format = $endpoint_instance::get_format(); if ( $command ) { $format = $command . '/' . $format; } else { $format = $format . $command; } // `$e.data.registerFormat()`. Manager::instance()->register_endpoint_format( $command, $format ); return $endpoint_instance; } /** * Register a processor. * * That will be later attached to the endpoint class. * * @param string $processor_class * * @return \Elementor\Data\Base\Processor $processor_instance */ protected function register_processor( $processor_class ) { $processor_instance = new $processor_class( $this ); // TODO: Validate processor instance. $command = $processor_instance->get_command(); if ( ! isset( $this->processors[ $command ] ) ) { $this->processors[ $command ] = []; } $this->processors[ $command ] [] = $processor_instance; return $processor_instance; } /** * Register. * * Endpoints & processors. */ protected function register() { $this->register_internal_endpoints(); $this->register_endpoints(); // Aka hooks. $this->register_processors(); } /** * Retrieves a recursive collection of all endpoint(s), items. * * Get items recursive, will run overall endpoints of the current controller. * For each endpoint it will run `$endpoint->getItems( $request ) // the $request passed in get_items_recursive`. * Will skip $skip_endpoints endpoint(s). * * Example, scenario: * Controller 'test-controller'. * Controller endpoints: 'endpoint1', 'endpoint2'. * Endpoint2 get_items method: `get_items() { return 'test' }`. * Call `Controller.get_items_recursive( ['endpoint1'] )`, result: [ 'endpoint2' => 'test' ]; * * @param array $skip_endpoints * * @return array */ public function get_items_recursive( $skip_endpoints = [] ) { $response = []; foreach ( $this->endpoints as $endpoint ) { // Skip self. if ( in_array( $endpoint, $skip_endpoints, true ) ) { continue; } $response[ $endpoint->get_name() ] = $endpoint->get_items( null ); } return $response; } /** * Get permission callback. * * Default controller permission callback. * By default endpoint will inherit the permission callback from the controller. * By default permission is `current_user_can( 'administrator' );`. * * @param \WP_REST_Request $request * * @return bool */ public function get_permission_callback( $request ) { // The function is public since endpoint need to access it. switch ( $request->get_method() ) { case 'GET': case 'POST': case 'UPDATE': case 'PUT': case 'DELETE': case 'PATCH': return current_user_can( 'administrator' ); } return false; } } PK (am[��ۼ � data/base/processor.phpnu �[��� <?php namespace Elementor\Data\Base; abstract class Processor { /** * Controller. * * @var \Elementor\Data\Base\Controller */ private $controller; /** * Processor constructor. * * @param \Elementor\Data\Base\Controller $controller */ public function __construct( $controller ) { $this->controller = $controller; } /** * Get processor command. * * @return string */ abstract public function get_command(); } PK (am[;D]% % data/manager.phpnu �[��� <?php namespace Elementor\Data; use Elementor\Core\Base\Module as BaseModule; use Elementor\Data\Base\Processor; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } class Manager extends BaseModule { const ROOT_NAMESPACE = 'elementor'; const REST_BASE = ''; const VERSION = '1'; /** * @var \WP_REST_Server */ private $server; /** * @var boolean */ private $is_internal = false; /** * @var array */ private $cache = []; /** * Loaded controllers. * * @var \Elementor\Data\Base\Controller[] */ public $controllers = []; /** * Loaded command(s) format. * * @var string[] */ public $command_formats = []; /** * Fix issue with 'Potentially polymorphic call. The code may be inoperable depending on the actual class instance passed as the argument.'. * * @return \Elementor\Core\Base\Module|\Elementor\Data\Manager */ public static function instance() { return ( parent::instance() ); } public function __construct() { add_action( 'rest_api_init', [ $this, 'register_rest_error_handler' ] ); } public function get_name() { return 'data-manager'; } /** * @return \Elementor\Data\Base\Controller[] */ public function get_controllers() { return $this->controllers; } 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 string $controller_class_name * * @return \Elementor\Data\Base\Controller */ public function register_controller( $controller_class_name ) { $controller_instance = new $controller_class_name(); return $this->register_controller_instance( $controller_instance ); } /** * Register controller instance. * * @param \Elementor\Data\Base\Controller $controller_instance * * @return \Elementor\Data\Base\Controller */ public function register_controller_instance( $controller_instance ) { // TODO: Validate 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 ] = rtrim( $format, '/' ); } public function register_rest_error_handler() { // TODO: Remove - Find better solution. return; if ( ! $this->is_internal() ) { $logger_manager = \Elementor\Core\Logger\Manager::instance(); set_error_handler( [ $logger_manager, 'rest_error_handler' ], E_ALL ); } } /** * Find controller instance. * * By given command name. * * @param string $command * * @return false|\Elementor\Data\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 = rtrim( $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\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\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 { // TODO: error 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 * * @return \WP_REST_Response */ private function run_request( $endpoint, $args, $method ) { $this->run_server(); $endpoint = '/' . self::ROOT_NAMESPACE . '/v' . self::VERSION . '/' . $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' ) { $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; } } PK (am[��y7b b elementor.phpnu �[��� <?php /** * Plugin Name: Elementor * Description: The Elementor Website Builder has it all: drag and drop page builder, pixel perfect design, mobile responsive editing, and more. Get started now! * Plugin URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=plugin-uri&utm_medium=wp-dash * Author: Elementor.com * Version: 3.4.6 * Author URI: https://elementor.com/?utm_source=wp-plugins&utm_campaign=author-uri&utm_medium=wp-dash * * Text Domain: elementor * * @package Elementor * @category Core * * Elementor is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * Elementor is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } define( 'ELEMENTOR_VERSION', '3.4.6' ); define( 'ELEMENTOR_PREVIOUS_STABLE_VERSION', '3.1.4' ); define( 'ELEMENTOR__FILE__', __FILE__ ); define( 'ELEMENTOR_PLUGIN_BASE', plugin_basename( ELEMENTOR__FILE__ ) ); define( 'ELEMENTOR_PATH', plugin_dir_path( ELEMENTOR__FILE__ ) ); if ( defined( 'ELEMENTOR_TESTS' ) && ELEMENTOR_TESTS ) { define( 'ELEMENTOR_URL', 'file://' . ELEMENTOR_PATH ); } else { define( 'ELEMENTOR_URL', plugins_url( '/', ELEMENTOR__FILE__ ) ); } define( 'ELEMENTOR_MODULES_PATH', plugin_dir_path( ELEMENTOR__FILE__ ) . '/modules' ); define( 'ELEMENTOR_ASSETS_PATH', ELEMENTOR_PATH . 'assets/' ); define( 'ELEMENTOR_ASSETS_URL', ELEMENTOR_URL . 'assets/' ); add_action( 'plugins_loaded', 'elementor_load_plugin_textdomain' ); if ( ! version_compare( PHP_VERSION, '5.6', '>=' ) ) { add_action( 'admin_notices', 'elementor_fail_php_version' ); } elseif ( ! version_compare( get_bloginfo( 'version' ), '5.2', '>=' ) ) { add_action( 'admin_notices', 'elementor_fail_wp_version' ); } else { require ELEMENTOR_PATH . 'includes/plugin.php'; } /** * Load Elementor textdomain. * * Load gettext translate for Elementor text domain. * * @since 1.0.0 * * @return void */ function elementor_load_plugin_textdomain() { load_plugin_textdomain( 'elementor' ); } /** * Elementor admin notice for minimum PHP version. * * Warning when the site doesn't have the minimum required PHP version. * * @since 1.0.0 * * @return void */ function elementor_fail_php_version() { /* translators: %s: PHP version. */ $message = sprintf( esc_html__( 'Elementor requires PHP version %s+, plugin is currently NOT RUNNING.', 'elementor' ), '5.6' ); $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) ); echo wp_kses_post( $html_message ); } /** * Elementor admin notice for minimum WordPress version. * * Warning when the site doesn't have the minimum required WordPress version. * * @since 1.5.0 * * @return void */ function elementor_fail_wp_version() { /* translators: %s: WordPress version. */ $message = sprintf( esc_html__( 'Elementor requires WordPress version %s+. Because you are using an earlier version, the plugin is currently NOT RUNNING.', 'elementor' ), '5.2' ); $html_message = sprintf( '<div class="error">%s</div>', wpautop( $message ) ); echo wp_kses_post( $html_message ); } PK (am[N_}/B /B modules/landing-pages/module.phpnu �[��� <?php namespace Elementor\Modules\LandingPages; use Elementor\Core\Base\Module as BaseModule; use Elementor\Core\Documents_Manager; use Elementor\Core\Experiments\Manager as Experiments_Manager; use Elementor\Modules\LandingPages\Documents\Landing_Page; use Elementor\Modules\LandingPages\Module as Landing_Pages_Module; use Elementor\Plugin; use Elementor\TemplateLibrary\Source_Local; use Elementor\Utils; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Module extends BaseModule { const DOCUMENT_TYPE = 'landing-page'; const CPT = 'e-landing-page'; const ADMIN_PAGE_SLUG = 'edit.php?post_type=' . self::CPT; private $posts; private $trashed_posts; private $new_lp_url; private $permalink_structure; public function get_name() { return 'landing-pages'; } /** * Get Experimental Data * * Implementation of this method makes the module an experiment. * * @since 3.1.0 * * @return array */ public static function get_experimental_data() { return [ 'name' => 'landing-pages', 'title' => esc_html__( 'Landing Pages', 'elementor' ), 'description' => esc_html__( 'Adds a new Elementor content type that allows creating beautiful landing pages instantly in a streamlined workflow.', 'elementor' ), 'release_status' => Experiments_Manager::RELEASE_STATUS_BETA, 'default' => Experiments_Manager::STATE_ACTIVE, ]; } /** * Get Trashed Landing Pages Posts * * Returns the posts property of a WP_Query run for Landing Pages with post_status of 'trash'. * * @since 3.1.0 * * @return array trashed posts */ private function get_trashed_landing_page_posts() { if ( $this->trashed_posts ) { return $this->trashed_posts; } // `'posts_per_page' => 1` is because this is only used as an indicator to whether there are any trashed landing pages. $trashed_posts_query = new \WP_Query( [ 'post_type' => self::CPT, 'post_status' => 'trash', 'posts_per_page' => 1, 'meta_key' => '_elementor_template_type', 'meta_value' => self::DOCUMENT_TYPE, ] ); $this->trashed_posts = $trashed_posts_query->posts; return $this->trashed_posts; } /** * Get Landing Pages Posts * * Returns the posts property of a WP_Query run for posts with the Landing Pages CPT. * * @since 3.1.0 * * @return array posts */ private function get_landing_page_posts() { if ( $this->posts ) { return $this->posts; } // `'posts_per_page' => 1` is because this is only used as an indicator to whether there are any landing pages. $posts_query = new \WP_Query( [ 'post_type' => self::CPT, 'post_status' => 'any', 'posts_per_page' => 1, 'meta_key' => '_elementor_template_type', 'meta_value' => self::DOCUMENT_TYPE, ] ); $this->posts = $posts_query->posts; return $this->posts; } /** * Is Elementor Landing Page. * * Check whether the post is an Elementor Landing Page. * * @since 3.1.0 * @access public * * @param \WP_Post $post Post Object * * @return bool Whether the post was built with Elementor. */ public function is_elementor_landing_page( $post ) { return self::CPT === $post->post_type; } /** * Add Submenu Page * * Adds the 'Landing Pages' submenu item to the 'Templates' menu item. * * @since 3.1.0 */ private function add_submenu_page() { $posts = $this->get_landing_page_posts(); // If there are no Landing Pages, show the "Create Your First Landing Page" page. // If there are, show the pages table. if ( ! empty( $posts ) ) { $landing_page_menu_slug = self::ADMIN_PAGE_SLUG; $landing_page_menu_callback = null; } else { $landing_page_menu_slug = self::CPT; $landing_page_menu_callback = [ $this, 'print_empty_landing_pages_page' ]; } $landing_pages_title = esc_html__( 'Landing Pages', 'elementor' ); add_submenu_page( Source_Local::ADMIN_MENU_SLUG, $landing_pages_title, $landing_pages_title, 'manage_options', $landing_page_menu_slug, $landing_page_menu_callback ); } /** * Get 'Add New' Landing Page URL * * Retrieves the custom URL for the admin dashboard's 'Add New' button in the Landing Pages admin screen. This URL * creates a new Landing Pages and directly opens the Elementor Editor with the Template Library modal open on the * Landing Pages tab. * * @since 3.1.0 * * @return string */ private function get_add_new_landing_page_url() { if ( ! $this->new_lp_url ) { $this->new_lp_url = Plugin::$instance->documents->get_create_new_post_url( self::CPT, self::DOCUMENT_TYPE ) . '#library'; } return $this->new_lp_url; } /** * Get Empty Landing Pages Page * * Prints the HTML content of the page that is displayed when there are no existing landing pages in the DB. * Added as the callback to add_submenu_page. * * @since 3.1.0 */ public function print_empty_landing_pages_page() { $template_sources = Plugin::$instance->templates_manager->get_registered_sources(); $source_local = $template_sources['local']; $trashed_posts = $this->get_trashed_landing_page_posts(); ?> <div class="e-landing-pages-empty"> <?php /** @var Source_Local $source_local */ $source_local->print_blank_state_template( esc_html__( 'Landing Page', 'elementor' ), $this->get_add_new_landing_page_url(), esc_html__( 'Build Effective Landing Pages for your business\' marketing campaigns.', 'elementor' ) ); if ( ! empty( $trashed_posts ) ) : ?> <div class="e-trashed-items"> <?php printf( /* translators: %1$s Link open tag, %2$s: Link close tag. */ esc_html__( 'Or view %1$sTrashed Items%1$s', 'elementor' ), '<a href="' . esc_url( admin_url( 'edit.php?post_status=trash&post_type=' . self::CPT ) ) . '">', '</a>' ); ?> </div> <?php endif; ?> </div> <?php } /** * Is Current Admin Page Edit LP * * Checks whether the current page is a native WordPress edit page for a landing page. */ private function is_landing_page_admin_edit() { $screen = get_current_screen(); if ( 'post' === $screen->base ) { return $this->is_elementor_landing_page( get_post() ); } return false; } /** * Admin Localize Settings * * Enables adding properties to the globally available elementorAdmin.config JS object in the Admin Dashboard. * Runs on the 'elementor/admin/localize_settings' filter. * * @since 3.1.0 * * @param $settings * @return array|null */ private function admin_localize_settings( $settings ) { $additional_settings = [ 'urls' => [ 'addNewLandingPageUrl' => $this->get_add_new_landing_page_url(), ], 'landingPages' => [ 'landingPagesHasPages' => [] !== $this->get_landing_page_posts(), 'isLandingPageAdminEdit' => $this->is_landing_page_admin_edit(), ], ]; return array_replace_recursive( $settings, $additional_settings ); } /** * Register Landing Pages CPT * * @since 3.1.0 */ private function register_landing_page_cpt() { $labels = [ 'name' => esc_html__( 'Landing Pages', 'elementor' ), 'singular_name' => esc_html__( 'Landing Page', 'elementor' ), 'add_new' => esc_html__( 'Add New', 'elementor' ), 'add_new_item' => esc_html__( 'Add New Landing Page', 'elementor' ), 'edit_item' => esc_html__( 'Edit Landing Page', 'elementor' ), 'new_item' => esc_html__( 'New Landing Page', 'elementor' ), 'all_items' => esc_html__( 'All Landing Pages', 'elementor' ), 'view_item' => esc_html__( 'View Landing Page', 'elementor' ), 'search_items' => esc_html__( 'Search Landing Pages', 'elementor' ), 'not_found' => esc_html__( 'No landing pages found', 'elementor' ), 'not_found_in_trash' => esc_html__( 'No landing pages found in trash', 'elementor' ), 'parent_item_colon' => '', 'menu_name' => esc_html__( 'Landing Pages', 'elementor' ), ]; $args = [ 'labels' => $labels, 'public' => true, 'show_in_menu' => 'edit.php?post_type=elementor_library&tabs_group=library', 'capability_type' => 'page', 'taxonomies' => [ Source_Local::TAXONOMY_TYPE_SLUG ], 'supports' => [ 'title', 'editor', 'comments', 'revisions', 'trackbacks', 'author', 'excerpt', 'page-attributes', 'thumbnail', 'custom-fields', 'post-formats', 'elementor' ], ]; register_post_type( self::CPT, $args ); } /** * Remove Post Type Slug * * Landing Pages are supposed to act exactly like pages. This includes their URLs being directly under the site's * domain name. Since "Landing Pages" is a CPT, WordPress automatically adds the landing page slug as a prefix to * it's posts' permalinks. This method checks if the post's post type is Landing Pages, and if it is, it removes * the CPT slug from the requested post URL. * * Runs on the 'post_type_link' filter. * * @since 3.1.0 * * @param $post_link * @param $post * @param $leavename * @return string|string[] */ private function remove_post_type_slug( $post_link, $post, $leavename ) { // Only try to modify the permalink if the post is a Landing Page. if ( self::CPT !== $post->post_type || 'publish' !== $post->post_status ) { return $post_link; } // Any slug prefixes need to be removed from the post link. return get_home_url() . '/' . $post->post_name . '/'; } /** * Adjust Landing Page Query * * Since Landing Pages are a CPT but should act like pages, the WP_Query that is used to fetch the page from the * database needs to be adjusted. This method adds the Landing Pages CPT to the list of queried post types, to * make sure the database query finds the correct Landing Page to display. * Runs on the 'pre_get_posts' action. * * @since 3.1.0 * * @param \WP_Query $query */ private function adjust_landing_page_query( \WP_Query $query ) { // Only handle actual pages. if ( ! $query->is_main_query() // If the query is not for a page. || ! isset( $query->query['page'] ) // If the query is for a static home/blog page. || is_home() // If the post type comes already set, the main query is probably a custom one made by another plugin. // In this case we do not want to intervene in order to not cause a conflict. || isset( $query->query['post_type'] ) ) { return; } // Create the post types property as an array and include the landing pages CPT in it. $query_post_types = [ 'post', 'page', self::CPT ]; // Since WordPress determined this is supposed to be a page, we'll pre-set the post_type query arg to make sure // it includes the Landing Page CPT, so when the query is parsed, our CPT will be a legitimate match to the // Landing Page's permalink (that is directly under the domain, without a CPT slug prefix). In some cases, // The 'name' property will be set, and in others it is the 'pagename', so we have to cover both cases. if ( ! empty( $query->query['name'] ) ) { $query->set( 'post_type', $query_post_types ); } elseif ( ! empty( $query->query['pagename'] ) && false === strpos( $query->query['pagename'], '/' ) ) { $query->set( 'post_type', $query_post_types ); // We also need to set the name query var since redirect_guess_404_permalink() relies on it. add_filter( 'pre_redirect_guess_404_permalink', function( $value ) use ( $query ) { set_query_var( 'name', $query->query['pagename'] ); return $value; } ); } } /** * Handle 404 * * This method runs after a page is not found in the database, but before a page is returned as a 404. * These cases are handled in this filter callback, that runs on the 'pre_handle_404' filter. * * In some cases (such as when a site uses custom permalink structures), WordPress's WP_Query does not identify a * Landing Page's URL as a post belonging to the Landing Page CPT. Some cases are handled successfully by the * adjust_landing_page_query() method, but some are not and still trigger a 404 process. This method handles such * cases by overriding the $wp_query global to fetch the correct landing page post entry. * * For example, since Landing Pages slugs come directly after the site domain name, WP_Query might parse the post * as a category page. Since there is no category matching the slug, it triggers a 404 process. In this case, we * run a query for a Landing Page post with the passed slug ($query->query['category_name']. If a Landing Page * with the passed slug is found, we override the global $wp_query with the new, correct query. * * @param $current_value * @param $query * @return false */ private function handle_404( $current_value, $query ) { global $wp_query; // If another plugin/theme already used this filter, exit here to avoid conflicts. if ( $current_value ) { return $current_value; } if ( // Make sure we only intervene in the main query. ! $query->is_main_query() // If a post was found, this is not a 404 case, so do not intervene. || ! empty( $query->posts ) // This filter is only meant to deal with wrong queries where the only query var is 'category_name'. // If there is no 'category_name' query var, do not intervene. || empty( $query->query['category_name'] ) // If the query is for a real taxonomy (determined by it including a table to search in, such as the // wp_term_relationships table), do not intervene. || ! empty( $query->tax_query->table_aliases ) ) { return false; } // Search for a Landing Page with the same name passed as the 'category name'. $possible_new_query = new \WP_Query( [ 'post_type' => self::CPT, 'name' => $query->query['category_name'], ] ); // Only if such a Landing Page is found, override the query to fetch the correct page. if ( ! empty( $possible_new_query->posts ) ) { $wp_query = $possible_new_query; //phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited } return false; } public function __construct() { $this->permalink_structure = get_option( 'permalink_structure' ); $this->register_landing_page_cpt(); // If there is a permalink structure set to the site, run the hooks that modify the Landing Pages permalinks to // match WordPress' native 'Pages' post type. if ( '' !== $this->permalink_structure ) { // Landing Pages' post link needs to be modified to be identical to the pages permalink structure. This // needs to happen in both the admin and the front end, since post links are also used in the admin pages. add_filter( 'post_type_link', function( $post_link, $post, $leavename ) { return $this->remove_post_type_slug( $post_link, $post, $leavename ); }, 10, 3 ); // The query itself only has to be manipulated when pages are viewed in the front end. if ( ! is_admin() || wp_doing_ajax() ) { add_action( 'pre_get_posts', function ( $query ) { $this->adjust_landing_page_query( $query ); } ); // Handle cases where visiting a Landing Page's URL returns 404. add_filter( 'pre_handle_404', function ( $value, $query ) { return $this->handle_404( $value, $query ); }, 10, 2 ); } } add_action( 'elementor/documents/register', function( Documents_Manager $documents_manager ) { $documents_manager->register_document_type( self::DOCUMENT_TYPE, Landing_Page::get_class_full_name() ); } ); add_action( 'admin_menu', function() { $this->add_submenu_page(); }, 30 ); // Add the custom 'Add New' link for Landing Pages into Elementor's admin config. add_action( 'elementor/admin/localize_settings', function( array $settings ) { return $this->admin_localize_settings( $settings ); } ); add_filter( 'elementor/template_library/sources/local/register_taxonomy_cpts', function( array $cpts ) { $cpts[] = self::CPT; return $cpts; } ); // In the Landing Pages Admin Table page - Overwrite Template type column header title. add_action( 'manage_' . Landing_Pages_Module::CPT . '_posts_columns', function( $posts_columns ) { /** @var Source_Local $source_local */ $source_local = Plugin::$instance->templates_manager->get_source( 'local' ); return $source_local->admin_columns_headers( $posts_columns ); } ); // In the Landing Pages Admin Table page - Overwrite Template type column row values. add_action( 'manage_' . Landing_Pages_Module::CPT . '_posts_custom_column', function( $column_name, $post_id ) { /** @var Landing_Page $document */ $document = Plugin::$instance->documents->get( $post_id ); $document->admin_columns_content( $column_name ); }, 10, 2 ); // Overwrite the Admin Bar's 'New +' Landing Page URL with the link that creates the new LP in Elementor // with the Template Library modal open. add_action( 'admin_bar_menu', function( $admin_bar ) { // Get the Landing Page menu node. $new_landing_page_node = $admin_bar->get_node( 'new-e-landing-page' ); if ( $new_landing_page_node ) { $new_landing_page_node->href = $this->get_add_new_landing_page_url(); $admin_bar->add_node( $new_landing_page_node ); } }, 100 ); } } PK (am[�FTa a 0 modules/landing-pages/documents/landing-page.phpnu �[��� <?php namespace Elementor\Modules\LandingPages\Documents; use Elementor\Core\DocumentTypes\PageBase; use Elementor\Modules\LandingPages\Module as Landing_Pages_Module; use Elementor\Modules\Library\Traits\Library; use Elementor\Modules\PageTemplates\Module as Page_Templates_Module; use Elementor\Plugin; use Elementor\TemplateLibrary\Source_Local; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly } class Landing_Page extends PageBase { // Library Document Trait use Library; public static function get_properties() { $properties = parent::get_properties(); $properties['support_kit'] = true; $properties['show_in_library'] = true; $properties['cpt'] = [ Landing_Pages_Module::CPT ]; return $properties; } /** * @access public */ public function get_name() { return Landing_Pages_Module::DOCUMENT_TYPE; } /** * @access public * @static */ public static function get_title() { return esc_html__( 'Landing Page', 'elementor' ); } /** * @access public * @static */ public static function get_plural_title() { return __( 'Landing Pages', 'elementor' ); } /** * Save Document. * * Save an Elementor document. * * @since 3.1.0 * @access public * * @param $data * * @return bool */ public function save( $data ) { // This is for the first time a Landing Page is created. It is done in order to load a new Landing Page with // 'Canvas' as the default page template. if ( empty( $data['settings']['template'] ) ) { $data['settings']['template'] = Page_Templates_Module::TEMPLATE_CANVAS; } return parent::save( $data ); } /** * Admin Columns Content * * @since 3.1.0 * * @param $column_name * @access public */ public function admin_columns_content( $column_name ) { if ( 'elementor_library_type' === $column_name ) { $this->print_admin_column_type(); } } protected function get_remote_library_config() { $config = [ 'type' => 'lp', 'default_route' => 'templates/landing-pages', 'autoImportSettings' => true, ]; return array_replace_recursive( parent::get_remote_library_config(), $config ); } } PK (am[:��p3 3 modules/admin-top-bar/module.phpnu �[��� <?php namespace Elementor\Modules\AdminTopBar; use Elementor\Core\Base\App as BaseApp; use Elementor\Core\Experiments\Manager; use Elementor\Utils; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } class Module extends BaseApp { /** * @return bool */ public static function is_active() { return is_admin(); } public static function get_experimental_data() { return [ 'name' => 'admin-top-bar', 'title' => esc_html__( 'Admin Top Bar', 'elementor' ), 'description' => esc_html__( 'Adds a top bar to elementors pages in admin area.', 'elementor' ), 'release_status' => Manager::RELEASE_STATUS_BETA, 'new_site' => [ 'default_active' => true, ], ]; } /** * @return string */ public function get_name() { return 'admin-top-bar'; } private function render_admin_top_bar() { ?> <div id="e-admin-top-bar-root"> </div> <?php } /** * Enqueue admin scripts */ private function enqueue_scripts() { wp_enqueue_style( 'elementor-admin-top-bar-fonts', 'https://fonts.googleapis.com/css2?family=Roboto&display=swap', [], ELEMENTOR_VERSION ); wp_enqueue_style( 'elementor-admin-top-bar', $this->get_css_assets_url( 'admin-top-bar', null, 'default', true ), [], ELEMENTOR_VERSION ); wp_enqueue_script( 'elementor-admin-top-bar', $this->get_js_assets_url( 'admin-top-bar' ), [ 'elementor-common', 'react', 'react-dom', ], ELEMENTOR_VERSION, true ); $min_suffix = Utils::is_script_debug() ? '' : '.min'; wp_enqueue_script( 'tipsy', ELEMENTOR_ASSETS_URL . 'lib/tipsy/tipsy' . $min_suffix . '.js', [ 'jquery', ], '1.0.0', true ); $this->print_config(); } /** * Module constructor. */ public function __construct() { parent::__construct(); add_action( 'in_admin_header', function () { $this->render_admin_top_bar(); } ); add_action( 'admin_enqueue_scripts', function () { $this->enqueue_scripts(); } ); add_action( 'elementor/init', function () { $settings = []; $settings['is_administrator'] = current_user_can( 'manage_options' ); /** @var \Elementor\Core\Common\Modules\Connect\Apps\Library $library */ $library = Plugin::$instance->common->get_component( 'connect' )->get_app( 'library' ); if ( $library ) { $settings = array_merge( $settings, [ 'is_user_connected' => $library->is_connected(), 'connect_url' => $library->get_admin_url( 'authorize' ), ] ); } $this->set_settings( $settings ); do_action( 'elementor/admin-top-bar/init', $this ); }, 12 /* After component 'connect' register the apps */ ); } } PK (am[U^n/ 2 modules/history/views/revisions-panel-template.phpnu �[��� <?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } ?> <script type="text/template" id="tmpl-elementor-panel-revisions"> <div class="elementor-panel-box"> <div class="elementor-panel-scheme-buttons"> <div class="elementor-panel-scheme-button-wrapper elementor-panel-scheme-discard"> <button class="elementor-button" disabled> <i class="eicon-close" aria-hidden="true"></i> <?php echo esc_html__( 'Discard', 'elementor' ); ?> </button> </div> <div class="elementor-panel-scheme-button-wrapper elementor-panel-scheme-save"> <button class="elementor-button elementor-button-success" disabled> <?php echo esc_html__( 'Apply', 'elementor' ); ?> </button> </div> </div> </div> <div class="elementor-panel-box"> <div class="elementor-panel-heading"> <div class="elementor-panel-heading-title"><?php echo esc_html__( 'Revisions', 'elementor' ); ?></div> </div> <div id="elementor-revisions-list" class="elementor-panel-box-content"></div> </div> </script> <script type="text/template" id="tmpl-elementor-panel-revisions-no-revisions"> <# var no_revisions_1 = '<?php echo esc_html__( 'Revision history lets you save your previous versions of your work, and restore them any time.', 'elementor' ); ?>', no_revisions_2 = '<?php echo esc_html__( 'Start designing your page and you will be able to see the entire revision history here.', 'elementor' ); ?>', revisions_disabled_1 = '<?php echo esc_html__( 'It looks like the post revision feature is unavailable in your website.', 'elementor' ); ?>', revisions_disabled_2 = '<?php printf( /* translators: %1$s Link open tag, %2$s: Link close tag. */ esc_html__( 'Learn more about %1$sWordPress revisions%2$s', 'elementor' ), '<a target="_blank" href="https://go.elementor.com/wordpress-revisions/">', '</a>' ); ?>'; #> <img class="elementor-nerd-box-icon" src="<?php // PHPCS - Safe Elementor SVG echo ELEMENTOR_ASSETS_URL . 'images/information.svg' // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" /> <div class="elementor-nerd-box-title"><?php echo esc_html__( 'No Revisions Saved Yet', 'elementor' ); ?></div> <div class="elementor-nerd-box-message">{{{ elementor.config.document.revisions.enabled ? no_revisions_1 : revisions_disabled_1 }}}</div> <div class="elementor-nerd-box-message">{{{ elementor.config.document.revisions.enabled ? no_revisions_2 : revisions_disabled_2 }}}</div> </script> <script type="text/template" id="tmpl-elementor-panel-revisions-loading"> <i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i> </script> <script type="text/template" id="tmpl-elementor-panel-revisions-revision-item"> <div class="elementor-revision-item__wrapper {{ type }}"> <div class="elementor-revision-item__gravatar">{{{ gravatar }}}</div> <div class="elementor-revision-item__details"> <div class="elementor-revision-date" title="{{{ new Date( timestamp * 1000 ) }}}">{{{ date }}}</div> <div class="elementor-revision-meta"> <span>{{{ typeLabel }}}</span> <?php echo esc_html__( 'By', 'elementor' ); ?> {{{ author }}} <span>(#{{{ id }}})</span> </div> </div> <div class="elementor-revision-item__tools"> <# if ( 'current' === type ) { #> <i class="elementor-revision-item__tools-current eicon-star" aria-hidden="true"></i> <span class="elementor-screen-only"><?php echo esc_html__( 'Current', 'elementor' ); ?></span> <# } #> <i class="elementor-revision-item__tools-spinner eicon-loading eicon-animation-spin" aria-hidden="true"></i> </div> </div> </script> PK (am[/e�] ] 0 modules/history/views/history-panel-template.phpnu �[��� <?php if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } ?> <script type="text/template" id="tmpl-elementor-panel-history-page"> <div id="elementor-panel-elements-navigation" class="elementor-panel-navigation"> <div class="elementor-component-tab elementor-panel-navigation-tab" data-tab="actions"><?php echo esc_html__( 'Actions', 'elementor' ); ?></div> <div class="elementor-component-tab elementor-panel-navigation-tab" data-tab="revisions"><?php echo esc_html__( 'Revisions', 'elementor' ); ?></div> </div> <div id="elementor-panel-history-content"></div> </script> <script type="text/template" id="tmpl-elementor-panel-history-tab"> <div id="elementor-history-list"></div> <div class="elementor-history-revisions-message"><?php echo esc_html__( 'Switch to Revisions tab for older versions', 'elementor' ); ?></div> </script> <script type="text/template" id="tmpl-elementor-panel-history-no-items"> <img class="elementor-nerd-box-icon" src="<?php // PHPCS - Safe Elementor SVG echo ELEMENTOR_ASSETS_URL . 'images/information.svg'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>" /> <div class="elementor-nerd-box-title"><?php echo esc_html__( 'No History Yet', 'elementor' ); ?></div> <div class="elementor-nerd-box-message"><?php echo esc_html__( 'Once you start working, you\'ll be able to redo / undo any action you make in the editor.', 'elementor' ); ?></div> </script> <script type="text/template" id="tmpl-elementor-panel-history-item"> <div class="elementor-history-item__details"> <span class="elementor-history-item__title">{{{ title }}}</span> <span class="elementor-history-item__subtitle">{{{ subTitle }}}</span> <span class="elementor-history-item__action">{{{ action }}}</span> </div> <div class="elementor-history-item__icon"> <span class="eicon" aria-hidden="true"></span> </div> </script> PK (am[��] modules/history/module.phpnu �[��� <?php namespace Elementor\Modules\History; use Elementor\Core\Base\Module as BaseModule; use Elementor\Plugin; if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly. } /** * Elementor history module. * * Elementor history module handler class is responsible for registering and * managing Elementor history modules. * * @since 1.7.0 */ class Module extends BaseModule { /** * Get module name. * * Retrieve the history module name. * * @since 1.7.0 * @access public * * @return string Module name. */ public function get_name() { return 'history'; } /** * Localize settings. * * Add new localized settings for the history module. * * Fired by `elementor/editor/localize_settings` filter. * * @since 1.7.0 * @access public * @deprecated 3.1.0 * * @return array Localized settings. */ public function localize_settings() { Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0' ); return []; } /** * @since 2.3.0 * @access public */ public function add_templates() { Plugin::$instance->common->add_template( __DIR__ . '/views/history-panel-template.php' ); Plugin::$instance->common->add_template( __DIR__ . '/views/revisions-panel-template.php' ); } /** * History module constructor. * * Initializing Elementor history module. * * @since 1.7.0 * @access public */ public function __construct() { add_action( 'elementor/editor/init', [ $this, 'add_templates' ] ); } } PK (am[�0��'