| Server IP : 146.59.209.152 / Your IP : 216.73.216.46 Web Server : Apache System : Linux webm005.cluster131.gra.hosting.ovh.net 5.15.167-ovh-vps-grsec-zfs-classid #1 SMP Tue Sep 17 08:14:20 UTC 2024 x86_64 User : infrafs ( 43850) PHP Version : 8.2.29 Disable Function : _dyuweyrj4,_dyuweyrj4r,dl MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : OFF | Pkexec : OFF Directory : /home/i/n/f/infrafs/INFRABIKEIT/wp-content/plugins/ |
Upload File : |
modules/kit-library/module.php 0000644 00000004571 15133211754 0012454 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Source_Local;
use Elementor\Core\Base\Module as BaseModule;
use Elementor\Core\App\Modules\KitLibrary\Connect\Kit_Library;
use Elementor\Core\Common\Modules\Connect\Module as ConnectModule;
use Elementor\Core\App\Modules\KitLibrary\Data\Kits\Controller as Kits_Controller;
use Elementor\Core\App\Modules\KitLibrary\Data\Taxonomies\Controller as Taxonomies_Controller;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Module extends BaseModule {
/**
* Get name.
*
* @access public
*
* @return string
*/
public function get_name() {
return 'kit-library';
}
/**
* Register the admin menu.
*/
private function register_admin_menu() {
add_submenu_page(
Source_Local::ADMIN_MENU_SLUG,
__( 'Kit Library', 'elementor' ),
__( 'Kit Library', 'elementor' ),
'manage_options',
Plugin::$instance->app->get_base_url() . '#/kit-library'
);
}
private function set_kit_library_settings() {
if ( ! Plugin::$instance->common ) {
return;
}
/** @var ConnectModule $connect */
$connect = Plugin::$instance->common->get_component( 'connect' );
/** @var Kit_Library $kit_library */
$kit_library = $connect->get_app( 'kit-library' );
Plugin::$instance->app->set_settings( 'kit-library', [
'has_access_to_module' => current_user_can( 'administrator' ),
'subscription_plans' => $connect->get_subscription_plans( 'wp-kit-library' ),
'is_pro' => false,
'is_library_connected' => $kit_library->is_connected(),
'library_connect_url' => $kit_library->get_admin_url( 'authorize' ),
'access_level' => ConnectModule::ACCESS_LEVEL_CORE,
] );
}
/**
* Module constructor.
*/
public function __construct() {
Plugin::$instance->data_manager->register_controller( Kits_Controller::class );
Plugin::$instance->data_manager->register_controller( Taxonomies_Controller::class );
add_action( 'admin_menu', function () {
$this->register_admin_menu();
}, 50 /* after Elementor page */ );
add_action( 'elementor/connect/apps/register', function ( ConnectModule $connect_module ) {
$connect_module->register_app( 'kit-library', Kit_Library::get_class_name() );
} );
add_action( 'elementor/init', function () {
$this->set_kit_library_settings();
}, 12 /** after the initiation of the connect kit library */ );
}
}
modules/kit-library/data/repository.php 0000644 00000016426 15133211754 0014321 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data;
use Elementor\Core\Utils\Collection;
use Elementor\Modules\Library\User_Favorites;
use Elementor\Core\App\Modules\KitLibrary\Connect\Kit_Library;
use Elementor\Core\App\Modules\KitLibrary\Data\Exceptions\Wp_Error_Exception;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Repository {
const TAXONOMIES_KEYS = [ 'tags', 'categories', 'features', 'types' ];
const KITS_CACHE_KEY = 'elementor_remote_kits';
const KITS_TAXONOMIES_CACHE_KEY = 'elementor_remote_kits_taxonomies';
const KITS_CACHE_TTL_HOURS = 12;
const KITS_TAXONOMIES_CACHE_TTL_HOURS = 12;
/**
* @var Kit_Library
*/
protected $api;
/**
* @var User_Favorites
*/
protected $user_favorites;
/**
* Get all kits.
*
* @param false $force_api_request
*
* @return Collection
* @throws Wp_Error_Exception
*/
public function get_all( $force_api_request = false ) {
return $this->get_kits_data( $force_api_request )
->map( function ( $kit ) {
return $this->transform_kit_api_response( $kit );
} );
}
/**
* Get specific kit.
*
* @param $id
* @param array $options
*
* @return array|null
* @throws Wp_Error_Exception
*/
public function find( $id, $options = [] ) {
$options = wp_parse_args( $options, [
'manifest_included' => true,
] );
$item = $this->get_kits_data()
->find( function ( $kit ) use ( $id ) {
return $kit->_id === $id;
} );
if ( ! $item ) {
return null;
}
$manifest = null;
if ( $options['manifest_included'] ) {
$manifest = $this->api->get_manifest( $id );
if ( is_wp_error( $manifest ) ) {
throw new Wp_Error_Exception( $manifest );
}
}
return $this->transform_kit_api_response( $item, $manifest );
}
/**
* @param false $force_api_request
*
* @return Collection
* @throws Wp_Error_Exception
*/
public function get_taxonomies( $force_api_request = false ) {
return $this->get_taxonomies_data( $force_api_request )
->only( static::TAXONOMIES_KEYS )
->reduce( function ( Collection $carry, $taxonomies, $type ) {
return $carry->merge( array_map( function ( $taxonomy ) use ( $type ) {
return [
'text' => $taxonomy->name,
'type' => $type,
];
}, $taxonomies ) );
}, new Collection( [] ) )
->unique( [ 'text', 'type' ] );
}
/**
* @param $id
*
* @return array
* @throws Wp_Error_Exception
*/
public function get_download_link( $id ) {
$response = $this->api->download_link( $id );
if ( is_wp_error( $response ) ) {
throw new Wp_Error_Exception( $response );
}
return [ 'download_link' => $response->download_link ];
}
/**
* @param $id
*
* @return array
* @throws Wp_Error_Exception
* @throws \Exception
*/
public function add_to_favorites( $id ) {
$kit = $this->find( $id, [ 'manifest_included' => false ] );
if ( ! $kit ) {
throw new Wp_Error_Exception(
new \WP_Error( 404, __( 'Kit not found', 'elementor' ) )
);
}
$this->user_favorites->add( 'elementor', 'kits', $kit['id'] );
$kit['is_favorite'] = true;
return $kit;
}
/**
* @param $id
*
* @return array
* @throws Wp_Error_Exception
* @throws \Exception
*/
public function remove_from_favorites( $id ) {
$kit = $this->find( $id, [ 'manifest_included' => false ] );
if ( ! $kit ) {
throw new Wp_Error_Exception(
new \WP_Error( 404, __( 'Kit not found', 'elementor' ) )
);
}
$this->user_favorites->remove( 'elementor', 'kits', $kit['id'] );
$kit['is_favorite'] = false;
return $kit;
}
/**
* @param bool $force_api_request
*
* @return Collection
* @throws Wp_Error_Exception
*/
private function get_kits_data( $force_api_request = false ) {
$data = get_transient( static::KITS_CACHE_KEY );
if ( ! $data || $force_api_request ) {
$data = $this->api->get_all();
if ( is_wp_error( $data ) ) {
throw new Wp_Error_Exception( $data );
}
set_transient( static::KITS_CACHE_KEY, $data, static::KITS_CACHE_TTL_HOURS * HOUR_IN_SECONDS );
}
return new Collection( $data );
}
/**
* @param bool $force_api_request
*
* @return Collection
* @throws Wp_Error_Exception
*/
private function get_taxonomies_data( $force_api_request = false ) {
$data = get_transient( static::KITS_TAXONOMIES_CACHE_KEY );
if ( ! $data || $force_api_request ) {
$data = $this->api->get_taxonomies();
if ( is_wp_error( $data ) ) {
throw new Wp_Error_Exception( $data );
}
set_transient( static::KITS_TAXONOMIES_CACHE_KEY, $data, static::KITS_TAXONOMIES_CACHE_TTL_HOURS * HOUR_IN_SECONDS );
}
return new Collection( (array) $data );
}
/**
* @param $kit
* @param null $manifest
*
* @return array
*/
private function transform_kit_api_response( $kit, $manifest = null ) {
$taxonomies = array_reduce( static::TAXONOMIES_KEYS, function ( $current, $key ) use ( $kit ) {
return array_merge( $current, array_map( function ( $taxonomy ) {
return $taxonomy->name;
}, $kit->{$key} ) );
}, [] );
return array_merge(
[
'id' => $kit->_id,
'title' => $kit->title,
'thumbnail_url' => $kit->thumbnail,
'access_level' => $kit->access_level,
'keywords' => $kit->keywords,
'taxonomies' => $taxonomies,
'is_favorite' => $this->user_favorites->exists( 'elementor', 'kits', $kit->_id ),
// TODO: Remove all the isset when the API stable.
'trend_index' => isset( $kit->trend_index ) ? $kit->trend_index : 0,
'featured_index' => isset( $kit->featured_index ) ? $kit->featured_index : 0,
'popularity_index' => isset( $kit->popularity_index ) ? $kit->popularity_index : 0,
'created_at' => isset( $kit->created_at ) ? $kit->created_at : null,
'updated_at' => isset( $kit->updated_at ) ? $kit->updated_at : null,
//
],
$manifest ? $this->transform_manifest_api_response( $manifest ) : []
);
}
/**
* @param $manifest
*
* @return array
*/
private function transform_manifest_api_response( $manifest ) {
$manifest_content = ( new Collection( (array) $manifest->content ) )
->reduce( function ( $carry, $content, $type ) {
$mapped_documents = array_map( function ( $document ) use ( $type ) {
// TODO: Fix it!
// Hack to override a bug when a document with type of 'wp-page' is declared as 'wp-post'.
if ( 'page' === $type ) {
$document->doc_type = 'wp-page';
}
return $document;
}, (array) $content );
return $carry + $mapped_documents;
}, [] );
$content = ( new Collection( (array) $manifest->templates ) )
->union( $manifest_content )
->map( function ( $manifest_item, $key ) {
return [
'id' => isset( $manifest_item->id ) ? $manifest_item->id : $key,
'title' => $manifest_item->title,
'doc_type' => $manifest_item->doc_type,
'thumbnail_url' => $manifest_item->thumbnail,
'preview_url' => isset( $manifest_item->url ) ? $manifest_item->url : null,
];
} );
return [
'description' => $manifest->description,
'preview_url' => isset( $manifest->site ) ? $manifest->site : '',
'documents' => $content->values(),
];
}
/**
* Repository constructor.
*
* @param Kit_Library $kit_library
* @param User_Favorites $user_favorites
*/
public function __construct( Kit_Library $kit_library, User_Favorites $user_favorites ) {
$this->api = $kit_library;
$this->user_favorites = $user_favorites;
}
}
modules/kit-library/data/exceptions/wp-error-exception.php 0000644 00000001102 15133211754 0020015 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Exceptions;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
// TODO: Maybe transfer into base/data
class Wp_Error_Exception extends \Exception {
/**
* @var \WP_Error
*/
protected $error;
public function __construct( \WP_Error $error ) {
// If the code is not an http code it transfer it into 500 (Server Error).
$code = (int) $error->get_error_code();
$code = 0 === $code ? 500 : $code;
parent::__construct( $error->get_error_message(), $code );
$this->error = $error;
}
}
modules/kit-library/data/base-controller.php 0000644 00000001223 15133211754 0015162 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data;
use Elementor\Plugin;
use Elementor\Data\Base\Controller;
use Elementor\Modules\Library\User_Favorites;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
abstract class Base_Controller extends Controller {
/**
* @var Repository
*/
private $repository;
/**
* @return Repository
*/
public function get_repository() {
if ( ! $this->repository ) {
$this->repository = new Repository(
Plugin::$instance->common->get_component( 'connect' )->get_app( 'kit-library' ),
new User_Favorites( get_current_user_id() )
);
}
return $this->repository;
}
}
modules/kit-library/data/kits/controller.php 0000644 00000004054 15133211754 0015231 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Kits;
use Elementor\Core\App\Modules\KitLibrary\Data\Base_Controller;
use Elementor\Core\App\Modules\KitLibrary\Data\Exceptions\Wp_Error_Exception;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Controller extends Base_Controller {
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|array
*/
public function get_items( $request ) {
try {
$data = $this->get_repository()->get_all( $request->get_param( 'force' ) );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
return [
'data' => $data->values(),
];
}
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|array
*/
public function get_item( $request ) {
try {
$data = $this->get_repository()->find( $request->get_param( 'id' ) );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
if ( ! $data ) {
return new \WP_Error( 'kit_not_exists', __( 'Kit not exists.', 'elementor' ), [ 'status' => 404 ] );
}
return [
'data' => $data,
];
}
/**
* @return string
*/
public function get_name() {
return 'kits';
}
/**
* Must implement.
*/
public function register_endpoints() {
$this->register_endpoint( Endpoints\Download_Link::class );
$this->register_endpoint( Endpoints\Favorites::class );
}
/**
* Register internal endpoint.
*/
protected function register_internal_endpoints() {
// Register as internal to remove the default endpoint generated by the base controller.
$this->register_endpoint( Endpoints\Index::class );
}
}
modules/kit-library/data/kits/endpoints/download-link.php 0000644 00000002623 15133211754 0017613 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Kits\Endpoints;
use Elementor\Data\Base\Endpoint;
use Elementor\Core\App\Modules\KitLibrary\Data\Kits\Controller;
use Elementor\Core\App\Modules\KitLibrary\Data\Exceptions\Wp_Error_Exception;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @property Controller $controller
*/
class Download_Link extends Endpoint {
public function get_name() {
return 'download-link';
}
protected function register() {
$this->register_route(
'/(?P<id>[\w-]+)/',
\WP_REST_Server::READABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::READABLE, $request, false );
},
[
'id' => [
'description' => 'Unique identifier for the object.',
'type' => 'string',
'required' => true,
],
]
);
}
public function get_item( $id, $request ) {
$repository = $this->controller->get_repository();
try {
$data = $repository->get_download_link( $id );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
return [
'data' => $data,
'meta' => [
'nonce' => wp_create_nonce( 'kit-library-import' ),
],
];
}
}
modules/kit-library/data/kits/endpoints/favorites.php 0000644 00000004674 15133211754 0017063 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Kits\Endpoints;
use Elementor\Core\App\Modules\KitLibrary\Data\Kits\Controller;
use Elementor\Core\App\Modules\KitLibrary\Data\Exceptions\Wp_Error_Exception;
use Elementor\Data\Base\Endpoint;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @property Controller $controller
*/
class Favorites extends Endpoint {
public function get_name() {
return 'favorites';
}
protected function register() {
$this->register_route(
'/(?P<id>[\w-]+)/',
\WP_REST_Server::CREATABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::CREATABLE, $request, false );
},
[
'id' => [
'description' => 'Unique identifier for the object.',
'type' => 'string',
'required' => true,
],
]
);
$this->register_route(
'/(?P<id>[\w-]+)/',
\WP_REST_Server::DELETABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::DELETABLE, $request, false );
},
[
'id' => [
'description' => 'Unique identifier for the object.',
'type' => 'string',
'required' => true,
],
]
);
}
/**
* @param string $id
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
*/
public function create_item( $id, $request ) {
$repository = $this->controller->get_repository();
try {
$kit = $repository->add_to_favorites( $id );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
return new \WP_REST_Response( [
'data' => $kit,
] );
}
/**
* @param string $id
* @param \WP_REST_Request $request
*
* @return \WP_Error|\WP_REST_Response
*/
public function delete_item( $id, $request ) {
$repository = $this->controller->get_repository();
try {
$kit = $repository->remove_from_favorites( $id );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
return new \WP_REST_Response( [
'data' => $kit,
] );
}
}
modules/kit-library/data/kits/endpoints/index.php 0000644 00000001742 15133211754 0016161 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Kits\Endpoints;
use Elementor\Data\Base\Endpoint;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Index extends Endpoint {
public function get_name() {
return 'index';
}
protected function register() {
$this->register_route(
'',
\WP_REST_Server::READABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
},
[
'force' => [
'description' => 'Force an API request and skip the cache.',
'required' => false,
'default' => false,
'type' => 'boolean',
],
]
);
$this->register_route(
'(?P<id>[\w-]+)/',
\WP_REST_Server::READABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::READABLE, $request, false );
},
[
'id' => [
'description' => 'Unique identifier for the object.',
'type' => 'string',
'required' => true,
],
]
);
}
}
modules/kit-library/data/taxonomies/controller.php 0000644 00000002354 15133211754 0016446 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Taxonomies;
use Elementor\Core\App\Modules\KitLibrary\Data\Base_Controller;
use Elementor\Core\App\Modules\KitLibrary\Data\Exceptions\Wp_Error_Exception;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Controller extends Base_Controller {
public function get_name() {
return 'kit-taxonomies';
}
public function register_endpoints() {
//
}
/**
* Register internal endpoint.
*/
protected function register_internal_endpoints() {
// Register as internal to remove the default endpoint generated by the base controller.
$this->register_endpoint( Endpoints\Index::class );
}
/**
* @param \WP_REST_Request $request
*
* @return \WP_Error|array
*/
public function get_items( $request ) {
try {
$data = $this->get_repository()->get_taxonomies( $request->get_param( 'force' ) );
} catch ( Wp_Error_Exception $exception ) {
return new \WP_Error( $exception->getCode(), $exception->getMessage(), [ 'status' => $exception->getCode() ] );
} catch ( \Exception $exception ) {
return new \WP_Error( 'server_error', __( 'Something went wrong.', 'elementor' ), [ 'status' => 500 ] );
}
return [
'data' => $data->values(),
];
}
}
modules/kit-library/data/taxonomies/endpoints/index.php 0000644 00000001231 15133211754 0017366 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Data\Taxonomies\Endpoints;
use Elementor\Data\Base\Endpoint;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Index extends Endpoint {
public function get_name() {
return 'index';
}
protected function register() {
$this->register_route(
'',
\WP_REST_Server::READABLE,
function ( $request ) {
return $this->base_callback( \WP_REST_Server::READABLE, $request, true );
},
[
'force' => [
'description' => 'Force an API request and skip the cache.',
'required' => false,
'default' => false,
'type' => 'boolean',
],
]
);
}
}
modules/kit-library/connect/kit-library.php 0000644 00000002034 15133211754 0015041 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\KitLibrary\Connect;
use Elementor\Core\Common\Modules\Connect\Apps\Library;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Kit_Library extends Library {
const DEFAULT_BASE_ENDPOINT = 'https://my.elementor.com/api/v1/kits-library';
const FALLBACK_BASE_ENDPOINT = 'https://ms-8874.elementor.com/api/v1/kits-library';
public function get_title() {
return __( 'Kit Library', 'elementor' );
}
public function get_all() {
return $this->http_request( 'GET', 'kits' );
}
public function get_taxonomies() {
return $this->http_request( 'GET', 'taxonomies' );
}
public function get_manifest( $id ) {
return $this->http_request( 'GET', "kits/{$id}/manifest" );
}
public function download_link( $id ) {
return $this->http_request( 'GET', "kits/{$id}/download-link" );
}
protected function get_api_url() {
return [
static::DEFAULT_BASE_ENDPOINT,
static::FALLBACK_BASE_ENDPOINT,
];
}
protected function init() {
// Remove parent init actions.
}
}
modules/site-editor/module.php 0000644 00000002061 15133211754 0012443 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\SiteEditor;
use Elementor\Core\Base\Module as BaseModule;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Site Editor Module
*
* Responsible for initializing Elementor App functionality
*/
class Module extends BaseModule {
/**
* Get name.
*
* @access public
*
* @return string
*/
public function get_name() {
return 'site-editor';
}
public function add_menu_in_admin_bar( $admin_bar_config ) {
$admin_bar_config['elementor_edit_page']['children'][] = [
'id' => 'elementor_app_site_editor',
'title' => esc_html__( 'Theme Builder', 'elementor' ),
'sub_title' => esc_html__( 'Site', 'elementor' ),
'href' => Plugin::$instance->app->get_settings( 'menu_url' ),
'class' => 'elementor-app-link',
'parent_class' => 'elementor-second-section',
];
return $admin_bar_config;
}
public function __construct() {
add_filter( 'elementor/frontend/admin_bar/settings', [ $this, 'add_menu_in_admin_bar' ] ); // After kit (Site settings)
}
}
modules/import-export/wp-cli.php 0000644 00000013113 15133211754 0012752 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport;
use Elementor\Plugin;
use Elementor\Core\App\Modules\KitLibrary\Connect\Kit_Library;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Wp_Cli extends \WP_CLI_Command {
/**
* Export a Kit
*
* [--include]
* Which type of content to include. Possible values are 'content', 'templates', 'site-settings'.
* if this parameter won't be specified, All data types will be included.
*
* ## EXAMPLES
*
* 1. wp elementor kit export path/to/export-file-name.zip
* - This will export all site data to the specified file name.
*
* 2. wp elementor kit export path/to/export-file-name.zip --include=kit-settings,content
* - This will export only site settings and content.
*
* @param array $args
* @param array $assoc_args
*/
public function export( $args, $assoc_args ) {
if ( empty( $args[0] ) ) {
\WP_CLI::error( 'Please specify a file name' );
}
\WP_CLI::line( 'Kit export started.' );
$export_settings = [
'include' => [ 'content', 'templates', 'settings' ],
];
foreach ( $assoc_args as $key => $value ) {
$import_settings[ $key ] = explode( ',', $value );
}
$export_settings = array_merge( $export_settings, $assoc_args );
try {
$exporter = new Export( $export_settings );
$result = $exporter->run();
rename( $result['file_name'], $args[0] );
} catch ( \Error $error ) {
\WP_CLI::error( $error->getMessage() );
}
\WP_CLI::success( 'Kit exported successfully.' );
}
/**
* Import a Kit
*
* [--include]
* Which type of content to include. Possible values are 'content', 'templates', 'site-settings'.
* if this parameter won't be specified, All data types will be included.
*
* [--overrideConditions]
* Templates ids to override conditions for.
*
* [--sourceType]
* Which source type is used in the current session. Available values are 'local', 'remote', 'library'.
* The default value is 'local'
*
* ## EXAMPLES
*
* 1. wp elementor kit import path/to/elementor-kit.zip
* - This will import the whole kit file content.
*
* 2. wp elementor kit import path/to/elementor-kit.zip --include=site-settings,content
* - This will import only site settings and content.
*
* 3. wp elementor kit import path/to/elementor-kit.zip --overrideConditions=3478,4520
* - This will import all content and will override conditions for the given template ids.
*
* @param array $args
* @param array $assoc_args
*/
public function import( array $args, array $assoc_args ) {
if ( ! current_user_can( 'administrator' ) ) {
\WP_CLI::error( 'You must run this command as an admin user' );
}
if ( empty( $args[0] ) ) {
\WP_CLI::error( 'Please specify a file to import' );
}
\WP_CLI::line( 'Kit export started' );
\WP_CLI::line( 'Extracting zip archive...' );
$assoc_args = wp_parse_args( $assoc_args, [
'sourceType' => 'local',
] );
$url = null;
$file_path = $args[0];
if ( 'library' === $assoc_args['sourceType'] ) {
$url = $this->get_url_from_library( $args[0] );
} elseif ( 'remote' === $assoc_args['sourceType'] ) {
$url = $args[0];
}
if ( $url ) {
$file_path = $this->create_temp_file_from_url( $url );
}
$extraction_result = Plugin::$instance->uploads_manager->extract_and_validate_zip( $file_path, [ 'json', 'xml' ] );
if ( is_wp_error( $extraction_result ) ) {
\WP_CLI::error( $extraction_result->get_error_message() );
}
$import_settings = [
'include' => [ 'templates', 'content', 'site-settings' ],
'directory' => $extraction_result['extraction_directory'],
];
foreach ( $assoc_args as $key => $value ) {
$import_settings[ $key ] = explode( ',', $value );
}
try {
\WP_CLI::line( 'Importing data...' );
$import = new Import( $import_settings );
Plugin::$instance->app->get_component( 'import-export' )->import = $import;
$import->run();
\WP_CLI::line( 'Removing temp files...' );
Plugin::$instance->uploads_manager->remove_file_or_dir( $import_settings['directory'] );
// The file was created from remote or library request and it should be removed.
if ( $url ) {
Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_path ) );
}
\WP_CLI::success( 'Kit imported successfully' );
} catch ( \Error $error ) {
Plugin::$instance->uploads_manager->remove_file_or_dir( $import_settings['directory'] );
\WP_CLI::error( $error->getMessage() );
}
}
/**
* Helper to get kit url by the kit id
* TODO: Maybe extract it.
*
* @param $kit_id
*
* @return string
*/
private function get_url_from_library( $kit_id ) {
/** @var Kit_Library $app */
$app = Plugin::$instance->common->get_component( 'connect' )->get_app( 'kit-library' );
if ( ! $app ) {
\WP_CLI::error( 'Kit library app not found' );
}
$response = $app->download_link( $kit_id );
if ( is_wp_error( $response ) ) {
\WP_CLI::error( "Library Response: {$response->get_error_message()}" );
}
return $response->download_link;
}
/**
* Helper to get kit zip file path by the kit url
* TODO: Maybe extract it.
*
* @param $url
*
* @return string
*/
private function create_temp_file_from_url( $url ) {
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) ) {
\WP_CLI::error( "Download file url: {$response->get_error_message()}" );
}
if ( 200 !== $response['response']['code'] ) {
\WP_CLI::error( "Download file url: {$response['response']['message']}" );
}
return Plugin::$instance->uploads_manager->create_temp_file( $response['body'], 'kit.zip' );
}
}
modules/import-export/import.php 0000644 00000003233 15133211754 0013073 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport;
use Elementor\Core\App\Modules\ImportExport\Compatibility\Base_Adapter;
use Elementor\Core\App\Modules\ImportExport\Compatibility\Envato;
use Elementor\Core\App\Modules\ImportExport\Compatibility\Kit_Library;
use Elementor\Core\App\Modules\ImportExport\Directories\Root;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Import extends Iterator {
/**
* @var Base_Adapter[]
*/
private $adapters = [];
final public function run() {
$this->temp_dir = $this->get_settings( 'directory' );
$manifest_data = $this->read_json_file( 'manifest' );
$manifest_data = $this->adapt_manifest_structure( $manifest_data );
$root_directory = new Root( $this );
return $root_directory->run_import( $manifest_data );
}
final public function read_json_file( $name ) {
$name = $this->get_archive_file_full_path( $name . '.json' );
return json_decode( file_get_contents( $name, true ), true );
}
final public function get_adapters() {
return $this->adapters;
}
final public function adapt_manifest_structure( array $manifest_data ) {
$this->init_adapters( $manifest_data );
foreach ( $this->adapters as $adapter ) {
$manifest_data = $adapter->get_manifest_data( $manifest_data );
}
return $manifest_data;
}
private function init_adapters( array $manifest_data ) {
/** @var Base_Adapter[] $adapter_types */
$adapter_types = [ Envato::class, Kit_Library::class ];
foreach ( $adapter_types as $adapter_type ) {
if ( $adapter_type::is_compatibility_needed( $manifest_data, $this->get_settings() ) ) {
$this->adapters[] = new $adapter_type( $this );
}
}
}
}
modules/import-export/module.php 0000644 00000022534 15133211754 0013053 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport;
use Elementor\Core\Base\Document;
use Elementor\Core\Base\Module as BaseModule;
use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Source_Local;
use Elementor\Tools;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
/**
* Import Export Module
*
* Responsible for initializing Elementor App functionality
*/
class Module extends BaseModule {
const FORMAT_VERSION = '1.0';
const EXPORT_TRIGGER_KEY = 'elementor_export_kit';
const IMPORT_TRIGGER_KEY = 'elementor_import_kit';
/**
* @var Export
*/
public $export;
/**
* @var Import
*/
public $import;
/**
* Get name.
*
* @access public
*
* @return string
*/
public function get_name() {
return 'import-export';
}
public function get_init_settings() {
if ( ! Plugin::$instance->app->is_current() ) {
return [];
}
$export_nonce = wp_create_nonce( 'elementor_export' );
$export_url = add_query_arg( [ 'nonce' => $export_nonce ], Plugin::$instance->app->get_base_url() );
return [
'exportURL' => $export_url,
'summaryTitles' => $this->get_summary_titles(),
];
}
public function get_summary_titles() {
$summary_titles = [];
$document_types = Plugin::$instance->documents->get_document_types();
foreach ( $document_types as $name => $document_type ) {
$summary_titles['templates'][ $name ] = [
'single' => $document_type::get_title(),
'plural' => $document_type::get_plural_title(),
];
}
$post_types = get_post_types_by_support( 'elementor' );
foreach ( $post_types as $post_type ) {
if ( Source_Local::CPT === $post_type ) {
continue;
}
$post_type_object = get_post_type_object( $post_type );
$summary_titles['content'][ $post_type ] = [
'single' => $post_type_object->labels->singular_name,
'plural' => $post_type_object->label,
];
}
$active_kit = Plugin::$instance->kits_manager->get_active_kit();
foreach ( $active_kit->get_tabs() as $key => $tab ) {
$summary_titles['site-settings'][ $key ] = $tab->get_title();
}
return $summary_titles;
}
private function import_stage_1() {
// PHPCS - Already validated in caller function.
if ( ! empty( $_POST['e_import_file'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Missing
$file_url = $_POST['e_import_file']; // phpcs:ignore WordPress.Security.NonceVerification.Missing
if ( ! filter_var( $file_url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED ) || 0 !== strpos( $file_url, 'http' ) ) {
throw new \Error( __( 'Invalid URL', 'elementor' ) );
}
$remote_zip_request = wp_remote_get( $file_url );
if ( is_wp_error( $remote_zip_request ) ) {
throw new \Error( $remote_zip_request->get_error_message() );
}
if ( 200 !== $remote_zip_request['response']['code'] ) {
throw new \Error( $remote_zip_request['response']['message'] );
}
$file_name = Plugin::$instance->uploads_manager->create_temp_file( $remote_zip_request['body'], 'kit.zip' );
} else {
// PHPCS - Already validated in caller function.
$file_name = $_FILES['e_import_file']['tmp_name']; // phpcs:ignore WordPress.Security.NonceVerification.Missing
}
$extraction_result = Plugin::$instance->uploads_manager->extract_and_validate_zip( $file_name, [ 'json', 'xml' ] );
if ( ! empty( $file_url ) ) {
Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
}
$session_dir = $extraction_result['extraction_directory'];
$manifest_data = json_decode( file_get_contents( $session_dir . 'manifest.json', true ), true );
$manifest_data = $this->import->adapt_manifest_structure( $manifest_data );
$result = [
'session' => basename( $session_dir ),
'manifest' => $manifest_data,
];
$result = apply_filters( 'elementor/import/stage_1/result', $result );
return $result;
}
private function import_stage_2( $settings_directory ) {
set_time_limit( 0 );
$result = $this->import->run();
Plugin::$instance->uploads_manager->remove_file_or_dir( $settings_directory );
return $result;
}
private function on_admin_init() {
if ( ! isset( $_POST['action'] ) || self::IMPORT_TRIGGER_KEY !== $_POST['action'] || ! wp_verify_nonce( $_POST['nonce'], Ajax::NONCE_KEY ) ) {
return;
}
$import_settings = json_decode( stripslashes( $_POST['data'] ), true );
$import_settings['directory'] = Plugin::$instance->uploads_manager->get_temp_dir() . $import_settings['session'] . '/';
$this->import = new Import( $import_settings );
try {
if ( 1 === $import_settings['stage'] ) {
$result = $this->import_stage_1();
} elseif ( 2 === $import_settings['stage'] ) {
$result = $this->import_stage_2( $import_settings['directory'] );
}
wp_send_json_success( $result );
} catch ( \Error $error ) {
wp_send_json_error( $error->getMessage() );
}
}
private function on_init() {
if ( ! isset( $_GET[ self::EXPORT_TRIGGER_KEY ] ) || ! wp_verify_nonce( $_GET['nonce'], 'elementor_export' ) ) {
return;
}
$export_settings = $_GET[ self::EXPORT_TRIGGER_KEY ];
try {
$this->export = new Export( self::merge_properties( [], $export_settings, [ 'include', 'kitInfo' ] ) );
$export_result = $this->export->run();
$file_name = $export_result['file_name'];
$file = file_get_contents( $file_name, true );
Plugin::$instance->uploads_manager->remove_file_or_dir( dirname( $file_name ) );
wp_send_json_success( [
'manifest' => $export_result['manifest'],
'file' => base64_encode( $file ),
] );
} catch ( \Error $error ) {
wp_die( esc_html( $error->getMessage() ) );
}
}
private function render_import_export_tab_content() {
$intro_text_link = sprintf( '<a href="https://go.elementor.com/wp-dash-import-export-general" target="_blank">%s</a>', esc_html__( 'Learn more', 'elementor' ) );
$intro_text = sprintf(
/* translators: 1: New line break, 2: Learn More link. */
__( 'Design sites faster with a template kit that contains some or all components of a complete site, like templates, content & site settings.%1$sYou can import a kit and apply it to your site, or export the elements from this site to be used anywhere else. %2$s', 'elementor' ),
'<br>',
$intro_text_link
);
$content_data = [
'export' => [
'title' => esc_html__( 'Export a Template Kit', 'elementor' ),
'button' => [
'url' => Plugin::$instance->app->get_base_url() . '#/export',
'text' => esc_html__( 'Start Export', 'elementor' ),
],
'description' => esc_html__( 'Bundle your whole site - or just some of its elements - to be used for another website.', 'elementor' ),
'link' => [
'url' => 'https://go.elementor.com/wp-dash-import-export-export-flow',
'text' => esc_html__( 'Learn More', 'elementor' ),
],
],
'import' => [
'title' => esc_html__( 'Import a Template Kit', 'elementor' ),
'button' => [
'url' => Plugin::$instance->app->get_base_url() . '#/import',
'text' => esc_html__( 'Start Import', 'elementor' ),
],
'description' => esc_html__( 'Apply the design and settings of another site to this one.', 'elementor' ),
'link' => [
'url' => 'https://go.elementor.com/wp-dash-import-export-import-flow',
'text' => esc_html__( 'Learn More', 'elementor' ),
],
],
];
$info_text = esc_html__( 'Even after you import and apply a Template Kit, you can undo it by restoring a previous version of your site.', 'elementor' ) . '<br>' . esc_html__( 'Open Site Settings > History > Revisions.', 'elementor' );
?>
<div class="tab-import-export-kit__content">
<p class="tab-import-export-kit__info"><?php Utils::print_unescaped_internal_string( $intro_text ); ?></p>
<div class="tab-import-export-kit__wrapper">
<?php foreach ( $content_data as $data ) { ?>
<div class="tab-import-export-kit__container">
<div class="tab-import-export-kit__box">
<h2><?php Utils::print_unescaped_internal_string( $data['title'] ); ?></h2>
<a href="<?php Utils::print_unescaped_internal_string( $data['button']['url'] ); ?>" class="elementor-button elementor-button-success">
<?php Utils::print_unescaped_internal_string( $data['button']['text'] ); ?>
</a>
</div>
<p><?php Utils::print_unescaped_internal_string( $data['description'] ); ?></p>
<a href="<?php Utils::print_unescaped_internal_string( $data['link']['url'] ); ?>" target="_blank"><?php Utils::print_unescaped_internal_string( $data['link']['text'] ); ?></a>
</div>
<?php } ?>
</div>
<p class="tab-import-export-kit__info"><?php Utils::print_unescaped_internal_string( $info_text ); ?></p>
</div>
<?php
}
public function register_settings_tab( Tools $tools ) {
$tools->add_tab( 'import-export-kit', [
'label' => esc_html__( 'Import / Export Kit', 'elementor' ),
'sections' => [
'intro' => [
'label' => esc_html__( 'Template Kits', 'elementor' ),
'callback' => function() {
$this->render_import_export_tab_content();
},
'fields' => [],
],
],
] );
}
public function __construct() {
add_action( 'init', function() {
$this->on_init();
} );
add_action( 'admin_init', function() {
$this->on_admin_init();
} );
$page_id = Tools::PAGE_ID;
add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_tab' ] );
if ( Utils::is_wp_cli() ) {
\WP_CLI::add_command( 'elementor kit', WP_CLI::class );
}
}
}
modules/import-export/directories/root.php 0000644 00000006170 15133211754 0015063 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Core\App\Modules\ImportExport\Module;
use Elementor\Core\Settings\Page\Manager as PageManager;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Root extends Base {
protected function get_name() {
return '';
}
protected function export() {
$kit = Plugin::$instance->kits_manager->get_active_kit();
$exporter_settings = $this->exporter->get_settings();
$include = $exporter_settings['include'];
$include_site_settings = in_array( 'settings', $include, true );
if ( $include_site_settings ) {
$kit_data = $kit->get_export_data();
$excluded_kit_settings_keys = [
'site_name',
'site_description',
'site_logo',
'site_favicon',
];
foreach ( $excluded_kit_settings_keys as $setting_key ) {
unset( $kit_data['settings'][ $setting_key ] );
}
$this->exporter->add_json_file( 'site-settings', $kit_data );
}
$kit_post = $kit->get_post();
$manifest_data = [
'name' => sanitize_title( $exporter_settings['kitInfo']['title'] ),
'title' => $exporter_settings['kitInfo']['title'],
'description' => $exporter_settings['kitInfo']['description'],
'author' => get_the_author_meta( 'display_name', $kit_post->post_author ),
'version' => Module::FORMAT_VERSION,
'elementor_version' => ELEMENTOR_VERSION,
'created' => gmdate( 'Y-m-d H:i:s' ),
'thumbnail' => get_the_post_thumbnail_url( $kit_post ),
'site' => get_site_url(),
];
if ( $include_site_settings ) {
$kit_tabs = $kit->get_tabs();
unset( $kit_tabs['settings-site-identity'] );
$manifest_data['site-settings'] = array_keys( $kit_tabs );
}
return $manifest_data;
}
protected function import( array $import_settings ) {
$include = $this->importer->get_settings( 'include' );
if ( ! in_array( 'settings', $include, true ) ) {
return;
}
$kit = Plugin::$instance->kits_manager->get_active_kit();
$old_settings = $kit->get_meta( PageManager::META_KEY );
if ( ! $old_settings ) {
$old_settings = [];
}
$new_settings = $this->importer->read_json_file( 'site-settings' );
$new_settings = $new_settings['settings'];
if ( ! empty( $old_settings['custom_colors'] ) ) {
$new_settings['custom_colors'] = array_merge( $old_settings['custom_colors'], $new_settings['custom_colors'] );
}
if ( ! empty( $old_settings['custom_typography'] ) ) {
$new_settings['custom_typography'] = array_merge( $old_settings['custom_typography'], $new_settings['custom_typography'] );
}
$new_settings = array_replace_recursive( $old_settings, $new_settings );
$kit->save( [ 'settings' => $new_settings ] );
}
protected function get_default_sub_directories() {
$sub_directories = [];
$include = $this->iterator->get_settings( 'include' );
if ( in_array( 'templates', $include, true ) ) {
$sub_directories[] = new Templates( $this->iterator, $this );
}
if ( in_array( 'content', $include, true ) ) {
$sub_directories[] = new Content( $this->iterator, $this );
$sub_directories[] = new WP_Content( $this->iterator, $this );
}
return $sub_directories;
}
}
modules/import-export/directories/content.php 0000644 00000001170 15133211754 0015545 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\TemplateLibrary\Source_Local;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Content extends Base {
protected function get_name() {
return 'content';
}
protected function get_default_sub_directories() {
$post_types = get_post_types_by_support( 'elementor' );
$sub_directories = [];
foreach ( $post_types as $post_type ) {
if ( Source_Local::CPT === $post_type ) {
continue;
}
$sub_directories[] = new Post_Type( $this->iterator, $this, $post_type );
}
return $sub_directories;
}
}
modules/import-export/directories/base.php 0000644 00000005513 15133211754 0015012 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Core\App\Modules\ImportExport\Export;
use Elementor\Core\App\Modules\ImportExport\Import;
use Elementor\Core\App\Modules\ImportExport\Iterator;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
abstract class Base {
/**
* @var Base[]
*/
private $sub_directories = [];
/**
* @var Base
*/
private $parent;
/**
* @var Iterator
*/
protected $iterator;
/**
* @var Export
*/
protected $exporter;
/**
* @var Import
*/
protected $importer;
abstract protected function get_name();
public function __construct( Iterator $iterator, Base $parent = null ) {
$this->iterator = $iterator;
if ( $iterator instanceof Export ) {
$this->exporter = $iterator;
} else {
$this->importer = $iterator;
}
$this->parent = $parent;
$this->register_directories();
}
final public function get_path() {
$path = $this->get_name();
if ( $this->parent ) {
$parent_name = $this->parent->get_name();
if ( $parent_name ) {
$parent_name .= '/';
}
$path = $parent_name . $path;
}
return $path;
}
final public function run_export() {
$this->exporter->set_current_archive_path( $this->get_path() );
$manifest_data = $this->export();
foreach ( $this->sub_directories as $sub_directory ) {
$manifest_data[ $sub_directory->get_name() ] = $sub_directory->run_export();
}
return $manifest_data;
}
final public function run_import( array $settings ) {
$this->importer->set_current_archive_path( $this->get_path() );
$meta_data = $this->import( $settings );
foreach ( $this->sub_directories as $sub_directory ) {
$sub_directory_name = $sub_directory->get_name();
if ( ! isset( $settings[ $sub_directory_name ] ) ) {
continue;
}
$meta_data[ $sub_directory_name ] = $sub_directory->run_import( $settings[ $sub_directory_name ] );
}
return $meta_data;
}
/**
* @return array
*/
protected function export() {
return [];
}
/**
* @param array $import_settings
*
* @return array
*/
protected function import( array $import_settings ) {
return [];
}
protected function get_default_sub_directories() {
return [];
}
private function register_directories() {
$sub_directories = $this->get_default_sub_directories();
$path = $this->get_path();
/**
* Kit sub directories.
*
* Filters sub directories when importing/exporting kits.
*
* The dynamic portion of the hook name, `$path`, refers to the directory path.
*
* @param array $sub_directories A list of sub directories.
* @param Elementor\Core\App\Modules\ImportExport\Directories\Base $this The base class instance.
*/
$sub_directories = apply_filters( "elementor/kit/import-export/directory/{$path}", $sub_directories, $this );
$this->sub_directories = $sub_directories;
}
}
modules/import-export/directories/wp-post-type.php 0000644 00000002545 15133211754 0016472 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Core\App\Modules\ImportExport\Iterator;
use Elementor\Core\Utils\ImportExport\WP_Exporter;
use Elementor\Core\Utils\ImportExport\WP_Import;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class WP_Post_Type extends Base {
private $post_type;
protected function get_name() {
return $this->post_type;
}
public function __construct( Iterator $iterator, Base $parent, $post_type ) {
parent::__construct( $iterator, $parent );
$this->post_type = $post_type;
}
public function export() {
$wp_exporter = new WP_Exporter( [
'content' => $this->post_type,
'status' => 'publish',
'limit' => 20,
'meta_query' => [
[
'key' => '_elementor_edit_mode',
'compare' => 'NOT EXISTS',
],
],
'include_post_featured_image_as_attachment' => true, // Will export 'featured_image' as attachment.
] );
$export_result = $wp_exporter->run();
$this->exporter->add_file( $this->post_type . '.xml', $export_result['xml'] );
return $export_result['ids'];
}
protected function import( array $import_settings ) {
$wp_importer = new WP_Import( $this->importer->get_archive_file_full_path( $this->post_type . '.xml' ), [
'fetch_attachments' => true,
] );
$result = $wp_importer->run();
return $result['summary']['posts'];
}
}
modules/import-export/directories/wp-content.php 0000644 00000001436 15133211754 0016176 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Modules\LandingPages\Module as Landing_Pages_Module;
use Elementor\TemplateLibrary\Source_Local;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class WP_Content extends Base {
protected function get_name() {
return 'wp-content';
}
protected function get_default_sub_directories() {
$post_types = get_post_types( [
'public' => true,
'can_export' => true,
] );
unset(
$post_types['attachment'],
$post_types[ Landing_Pages_Module::CPT ],
$post_types[ Source_Local::CPT ]
);
$sub_directories = [];
foreach ( $post_types as $post_type ) {
$sub_directories[] = new WP_Post_Type( $this->iterator, $this, $post_type );
}
return $sub_directories;
}
}
modules/import-export/directories/templates.php 0000644 00000004661 15133211754 0016101 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Core\Base\Document;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Source_Local;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Templates extends Base {
protected function get_name() {
return 'templates';
}
protected function export() {
$template_types = array_values( Source_Local::get_template_types() );
$query_args = [
'post_type' => Source_Local::CPT,
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => Document::TYPE_META_KEY,
'value' => $template_types,
],
],
];
$templates_query = new \WP_Query( $query_args );
$manifest_data = [];
foreach ( $templates_query->posts as $template_post ) {
$template_id = $template_post->ID;
$template_document = Plugin::$instance->documents->get( $template_id );
$template_export_data = $template_document->get_export_data();
$this->exporter->add_json_file( $template_id, $template_export_data );
$manifest_data[ $template_id ] = $template_document->get_export_summary();
}
return $manifest_data;
}
protected function import( array $import_settings ) {
$result = [
'succeed' => [],
'failed' => [],
];
foreach ( $import_settings as $id => $template_settings ) {
try {
$import = $this->import_template( $id, $template_settings );
if ( is_wp_error( $import ) ) {
$result['failed'][ $id ] = $import->get_error_message();
continue;
}
$result['succeed'][ $id ] = $import;
} catch ( \Error $error ) {
$result['failed'][ $id ] = $error->getMessage();
}
}
return $result;
}
private function import_template( $id, array $template_settings ) {
$template_data = $this->importer->read_json_file( $id );
$doc_type = $template_settings['doc_type'];
$new_document = Plugin::$instance->documents->create(
$doc_type,
[
'post_title' => $template_settings['title'],
'post_type' => Source_Local::CPT,
'post_status' => 'publish',
]
);
if ( is_wp_error( $new_document ) ) {
return $new_document;
}
$template_data['import_settings'] = $template_settings;
$template_data['id'] = $id;
foreach ( $this->importer->get_adapters() as $adapter ) {
$template_data = $adapter->get_template_data( $template_data, $template_settings );
}
$new_document->import( $template_data );
return $new_document->get_main_id();
}
}
modules/import-export/directories/post-type.php 0000644 00000006402 15133211754 0016042 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Directories;
use Elementor\Core\App\Modules\ImportExport\Iterator;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Post_Type extends Base {
private $post_type;
private $show_page_on_front;
private $page_on_front_id;
public function __construct( Iterator $iterator, Base $parent, $post_type ) {
parent::__construct( $iterator, $parent );
$this->post_type = $post_type;
if ( 'page' === $post_type ) {
$this->init_page_on_front_data();
}
}
public function export() {
$query_args = [
'post_type' => $this->post_type,
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_elementor_data',
'compare' => 'EXISTS',
],
[
'key' => '_elementor_data',
'compare' => '!=',
'value' => '[]',
],
],
];
$query = new \WP_Query( $query_args );
$manifest_data = [];
foreach ( $query->posts as $post ) {
$document = Plugin::$instance->documents->get( $post->ID );
$post_manifest_data = [
'title' => $post->post_title,
'excerpt' => $post->post_excerpt,
'doc_type' => $document->get_name(),
'thumbnail' => get_the_post_thumbnail_url( $post ),
'url' => get_permalink( $post ),
];
if ( $post->ID === $this->page_on_front_id ) {
$post_manifest_data['show_on_front'] = true;
}
$manifest_data[ $post->ID ] = $post_manifest_data;
$this->exporter->add_json_file( $post->ID, $document->get_export_data() );
}
return $manifest_data;
}
public function import_post( $id, array $post_settings ) {
$post_data = $this->importer->read_json_file( $id );
$post_attributes = [
'post_title' => $post_settings['title'],
'post_type' => $this->post_type,
'post_status' => 'publish',
];
if ( ! empty( $post_settings['excerpt'] ) ) {
$post_attributes['post_excerpt'] = $post_settings['excerpt'];
}
$new_document = Plugin::$instance->documents->create(
$post_settings['doc_type'],
$post_attributes
);
if ( is_wp_error( $new_document ) ) {
return $new_document;
}
$post_data['import_settings'] = $post_settings;
$new_document->import( $post_data );
$new_id = $new_document->get_main_id();
if ( ! empty( $post_settings['show_on_front'] ) ) {
update_option( 'page_on_front', $new_id );
if ( ! $this->show_page_on_front ) {
update_option( 'show_on_front', 'page' );
}
}
return $new_id;
}
protected function get_name() {
return $this->post_type;
}
protected function import( array $import_settings ) {
$result = [
'succeed' => [],
'failed' => [],
];
foreach ( $import_settings as $id => $post_settings ) {
try {
$import = $this->import_post( $id, $post_settings );
if ( is_wp_error( $import ) ) {
$result['failed'][ $id ] = $import->get_error_message();
continue;
}
$result['succeed'][ $id ] = $import;
} catch ( \Error $error ) {
$result['failed'][ $id ] = $error->getMessage();
}
}
return $result;
}
private function init_page_on_front_data() {
$this->show_page_on_front = 'page' === get_option( 'show_on_front' );
if ( $this->show_page_on_front && $this->exporter ) {
$this->page_on_front_id = (int) get_option( 'page_on_front' );
}
}
}
modules/import-export/iterator.php 0000644 00000002036 15133211754 0013412 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport;
use Elementor\Core\Base\Base_Object;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
abstract class Iterator extends Base_Object {
protected $temp_dir;
private $current_archive_path = '';
abstract public function run();
protected function get_archive_file_path( $file_name ) {
return $this->get_current_archive_path() . $file_name;
}
public function get_archive_file_full_path( $file_name ) {
return $this->temp_dir . $this->get_archive_file_path( $file_name );
}
public function get_current_archive_path() {
return $this->current_archive_path;
}
public function set_current_archive_path( $path ) {
if ( $path ) {
$path .= '/';
}
$this->current_archive_path = $path;
}
public function __construct( array $settings ) {
if ( ! class_exists( '\ZipArchive' ) ) {
throw new \Error( 'ZipArchive module is not installed on the server. You must install this module to perform the process.' );
}
$this->set_settings( $settings );
}
}
modules/import-export/compatibility/base-adapter.php 0000644 00000001317 15133211754 0016763 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Compatibility;
use Elementor\Core\App\Modules\ImportExport\Import;
use Elementor\Core\Base\Base_Object;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
abstract class Base_Adapter extends Base_Object {
protected $importer;
public static function is_compatibility_needed( array $manifest_data, array $import_settings ) {
return false;
}
public function get_manifest_data( array $manifest_data ) {
return $manifest_data;
}
public function get_template_data( array $template_data, array $template_settings ) {
return $template_data;
}
public function __construct( Import $importer ) {
$this->importer = $importer;
}
}
modules/import-export/compatibility/kit-library.php 0000644 00000001432 15133211754 0016662 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Compatibility;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Kit_Library extends Base_Adapter {
public static function is_compatibility_needed( array $manifest_data, array $import_settings ) {
return ! empty( $import_settings['referrer'] ) && 'kit-library' === $import_settings['referrer'];
}
public function get_manifest_data( array $manifest_data ) {
if ( ! empty( $manifest_data['content']['page'] ) ) {
foreach ( $manifest_data['content']['page'] as & $page ) {
$page['thumbnail'] = false;
}
}
if ( ! empty( $manifest_data['templates'] ) ) {
foreach ( $manifest_data['templates'] as & $template ) {
$template['thumbnail'] = false;
}
}
return $manifest_data;
}
}
modules/import-export/compatibility/envato.php 0000644 00000005076 15133211754 0015735 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport\Compatibility;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Envato extends Base_Adapter {
public static function is_compatibility_needed( array $manifest_data, array $import_settings ) {
return ! empty( $manifest_data['manifest_version'] );
}
public function get_manifest_data( array $manifest_data ) {
$templates = $manifest_data['templates'];
$manifest_data['templates'] = [];
foreach ( $templates as $template ) {
// Envato store their global kit styles as a 'global.json' template file, this needs to be converted to 'site-settings.json' file
if ( ! empty( $template['metadata']['template_type'] ) && 'global-styles' === $template['metadata']['template_type'] ) {
$global_file_data = $this->importer->read_json_file( str_replace( '.json', '', $template['source'] ) );
$site_settings = [ 'settings' => $global_file_data['page_settings'] ];
$site_settings_file_destination = $this->importer->get_archive_file_full_path( 'site-settings.json' );
file_put_contents( $site_settings_file_destination, wp_json_encode( $site_settings ) );
// Getting the site-settings because Envato stores them in one of the posts.
$kit = Plugin::$instance->kits_manager->get_active_kit();
$kit_tabs = $kit->get_tabs();
unset( $kit_tabs['settings-site-identity'] );
$manifest_data['site-settings'] = array_keys( $kit_tabs );
continue;
}
// Evanto uses "type" instead of "doc_type"
$template['doc_type'] = $template['type'];
// Evanto uses for "name" instead of "title"
$template['title'] = $template['name'];
// Envato specifying an exact path to the template rather than using its "ID" as an index.
// This extracts the "file name" part out of our exact source list and we treat that as an ID.
$file_name_without_extension = str_replace( '.json', '', basename( $template['source'] ) );
// Append the template to the global list:
$manifest_data['templates'][ $file_name_without_extension ] = $template;
}
return $manifest_data;
}
public function get_template_data( array $template_data, array $template_settings ) {
if ( ! empty( $template_data['metadata']['elementor_pro_conditions'] ) ) {
foreach ( $template_data['metadata']['elementor_pro_conditions'] as $condition ) {
list ( $type, $name, $sub_name, $sub_id ) = array_pad( explode( '/', $condition ), 4, '' );
$template_data['import_settings']['conditions'][] = compact( 'type', 'name', 'sub_name', 'sub_id' );
}
}
return $template_data;
}
}
modules/import-export/export.php 0000644 00000003237 15133211754 0013106 0 ustar 00 <?php
namespace Elementor\Core\App\Modules\ImportExport;
use Elementor\Core\App\Modules\ImportExport\Directories\Root;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Export extends Iterator {
/**
* @var \ZipArchive
*/
private $zip_archive;
private $archive_file_name;
final public function run() {
ob_start();
$this->init_zip_archive();
$root_directory = new Root( $this );
$manifest_data = $root_directory->run_export();
/**
* Manifest data from exported kit.
*
* Filters the manifest data of any exported kit.
*
* @param array $manifest_data Manifest data.
* @param Export $this The export instance.
*/
$manifest_data = apply_filters( 'elementor/kit/export/manifest-data', $manifest_data, $this );
$this->set_current_archive_path( '' );
$this->add_json_file( 'manifest', $manifest_data );
$this->zip_archive->close();
return [
'manifest' => $manifest_data,
'file_name' => $this->archive_file_name,
];
}
public function add_json_file( $name, $content, $json_flags = null ) {
$this->add_file( $name . '.json', wp_json_encode( $content, $json_flags ) );
}
public function add_file( $file_name, $content ) {
$this->zip_archive->addFromString( $this->get_archive_file_path( $file_name ), $content );
}
private function init_zip_archive() {
$zip_archive = new \ZipArchive();
$this->temp_dir = Plugin::$instance->uploads_manager->create_unique_dir();
$this->archive_file_name = $this->temp_dir . 'kit.zip';
$zip_archive->open( $this->archive_file_name, \ZipArchive::CREATE | \ZipArchive::OVERWRITE );
$this->zip_archive = $zip_archive;
}
}
view.php 0000644 00000001331 15133211754 0006227 0 ustar 00 <?php
namespace Elementor\Core\App;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
/**
* @var App $this
*/
$theme_class = 'dark' === $this->get_elementor_ui_theme_preference() ? 'eps-theme-dark' : '';
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title><?php echo esc_html__( 'Elementor', 'elementor' ) . ' ... '; ?></title>
<base target="_parent">
<?php wp_print_styles(); ?>
</head>
<body class="<?php Utils::print_unescaped_internal_string( $theme_class ); ?>">
<div id="e-app"></div>
<?php wp_print_footer_scripts(); ?>
</body>
</html>
app.php 0000644 00000014031 15133211754 0006036 0 ustar 00 <?php
namespace Elementor\Core\App;
use Elementor\Core\Base\App as BaseApp;
use Elementor\Core\Settings\Manager as SettingsManager;
use Elementor\Plugin;
use Elementor\TemplateLibrary\Source_Local;
use Elementor\Utils;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class App extends BaseApp {
const PAGE_ID = 'elementor-app';
/**
* Get module name.
*
* Retrieve the module name.
*
* @since 3.0.0
* @access public
*
* @return string Module name.
*/
public function get_name() {
return 'app';
}
public function get_base_url() {
return admin_url( 'admin.php?page=' . self::PAGE_ID . '&ver=' . ELEMENTOR_VERSION );
}
public function register_admin_menu() {
add_submenu_page(
Source_Local::ADMIN_MENU_SLUG,
esc_html__( 'Theme Builder', 'elementor' ),
esc_html__( 'Theme Builder', 'elementor' ),
'manage_options',
self::PAGE_ID
);
}
public function fix_submenu( $menu ) {
global $submenu;
if ( is_multisite() && is_network_admin() ) {
return $menu;
}
// Non admin role / custom wp menu.
if ( empty( $submenu[ Source_Local::ADMIN_MENU_SLUG ] ) ) {
return $menu;
}
// Hack to add a link to sub menu.
foreach ( $submenu[ Source_Local::ADMIN_MENU_SLUG ] as &$item ) {
if ( self::PAGE_ID === $item[2] ) {
$item[2] = $this->get_settings( 'menu_url' ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$item[4] = 'elementor-app-link'; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
}
return $menu;
}
public function is_current() {
return ( ! empty( $_GET['page'] ) && self::PAGE_ID === $_GET['page'] );
}
public function admin_init() {
do_action( 'elementor/app/init', $this );
$this->enqueue_assets();
// Setup default heartbeat options
// TODO: Enable heartbeat.
add_filter( 'heartbeat_settings', function( $settings ) {
$settings['interval'] = 15;
return $settings;
} );
$this->render();
die;
}
protected function get_init_settings() {
return [
'menu_url' => $this->get_base_url() . '#site-editor/promotion',
'assets_url' => ELEMENTOR_ASSETS_URL,
'return_url' => isset( $_SERVER['HTTP_REFERER'] ) ? $_SERVER['HTTP_REFERER'] : admin_url(),
'hasPro' => Utils::has_pro(),
'admin_url' => admin_url(),
'login_url' => wp_login_url(),
];
}
private function render() {
require __DIR__ . '/view.php';
}
/**
* Get Elementor UI theme preference.
*
* Retrieve the user UI theme preference as defined by editor preferences manager.
*
* @since 3.0.0
* @access private
*
* @return string Preferred UI theme.
*/
private function get_elementor_ui_theme_preference() {
$editor_preferences = SettingsManager::get_settings_managers( 'editorPreferences' );
return $editor_preferences->get_model()->get_settings( 'ui_theme' );
}
/**
* Enqueue dark theme detection script.
*
* Enqueues an inline script that detects user-agent settings for dark mode and adds a complimentary class to the body tag.
*
* @since 3.0.0
* @access private
*/
private function enqueue_dark_theme_detection_script() {
if ( 'auto' === $this->get_elementor_ui_theme_preference() ) {
wp_add_inline_script( 'elementor-app',
'if ( window.matchMedia && window.matchMedia( `(prefers-color-scheme: dark)` ).matches )
{ document.body.classList.add( `eps-theme-dark` ); }' );
}
}
private function enqueue_assets() {
Plugin::$instance->init_common();
Plugin::$instance->common->register_scripts();
wp_register_style(
'select2',
$this->get_css_assets_url( 'e-select2', 'assets/lib/e-select2/css/' ),
[],
'4.0.6-rc.1'
);
wp_register_style(
'elementor-icons',
$this->get_css_assets_url( 'elementor-icons', 'assets/lib/eicons/css/' ),
[],
'5.13.0'
);
wp_register_style(
'elementor-common',
$this->get_css_assets_url( 'common', null, 'default', true ),
[],
ELEMENTOR_VERSION
);
wp_register_style(
'select2',
ELEMENTOR_ASSETS_URL . 'lib/e-select2/css/e-select2.css',
[],
'4.0.6-rc.1'
);
wp_enqueue_style(
'elementor-app',
$this->get_css_assets_url( 'app', null, 'default', true ),
[
'select2',
'elementor-icons',
'elementor-common',
'select2',
],
ELEMENTOR_VERSION
);
wp_enqueue_script(
'elementor-app-packages',
$this->get_js_assets_url( 'app-packages' ),
[
'wp-i18n',
'react',
],
ELEMENTOR_VERSION,
true
);
wp_register_script(
'select2',
$this->get_js_assets_url( 'e-select2.full', 'assets/lib/e-select2/js/' ),
[
'jquery',
],
'4.0.6-rc.1',
true
);
wp_enqueue_script(
'elementor-app',
$this->get_js_assets_url( 'app' ),
[
'wp-url',
'wp-i18n',
'react',
'react-dom',
'select2',
],
ELEMENTOR_VERSION,
true
);
$this->enqueue_dark_theme_detection_script();
wp_set_script_translations( 'elementor-app-packages', 'elementor' );
wp_set_script_translations( 'elementor-app', 'elementor' );
$this->print_config();
}
public function enqueue_app_loader() {
wp_enqueue_script(
'elementor-app-loader',
$this->get_js_assets_url( 'app-loader' ),
[
'elementor-common',
],
ELEMENTOR_VERSION,
true
);
$this->print_config( 'elementor-app-loader' );
}
public function __construct() {
$this->add_component( 'site-editor', new Modules\SiteEditor\Module() );
if ( current_user_can( 'manage_options' ) && Plugin::$instance->experiments->is_feature_active( 'e_import_export' ) || Utils::is_wp_cli() ) {
$this->add_component( 'import-export', new Modules\ImportExport\Module() );
// Kit library is depended on import-export
$this->add_component( 'kit-library', new Modules\KitLibrary\Module() );
}
add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 21 /* after Elementor page */ );
// Happens after WP plugin page validation.
add_filter( 'add_menu_classes', [ $this, 'fix_submenu' ] );
if ( $this->is_current() ) {
add_action( 'admin_init', [ $this, 'admin_init' ], 0 );
} else {
add_action( 'elementor/common/after_register_scripts', [ $this, 'enqueue_app_loader' ] );
}
}
}