first commit

This commit is contained in:
2024-07-31 13:12:38 +07:00
commit b4e8cbe182
10213 changed files with 3125839 additions and 0 deletions

View File

@@ -0,0 +1,152 @@
<?php
namespace Elementor\Modules\KitElementsDefaults\Data;
use Elementor\Core\Frontend\Performance;
use Elementor\Modules\KitElementsDefaults\Module;
use Elementor\Modules\KitElementsDefaults\Utils\Settings_Sanitizer;
use Elementor\Plugin;
use Elementor\Data\V2\Base\Exceptions\Error_404;
use Elementor\Data\V2\Base\Controller as Base_Controller;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Controller extends Base_Controller {
public function get_name() {
return 'kit-elements-defaults';
}
public function register_endpoints() {
$this->index_endpoint->register_item_route(\WP_REST_Server::EDITABLE, [
'id_arg_name' => 'type',
'id_arg_type_regex' => '[\w\-\_]+',
'type' => [
'type' => 'string',
'description' => 'The type of the element.',
'required' => true,
'validate_callback' => function( $type ) {
return $this->validate_type( $type );
},
],
'settings' => [
'description' => 'All the default values for the requested type',
'required' => true,
'type' => 'object',
'validate_callback' => function( $settings ) {
return is_array( $settings );
},
'sanitize_callback' => function( $settings, \WP_REST_Request $request ) {
Performance::set_use_style_controls( true );
$sanitizer = new Settings_Sanitizer(
Plugin::$instance->elements_manager,
array_keys( Plugin::$instance->widgets_manager->get_widget_types() )
);
$sanitized_data = $sanitizer
->for( $request->get_param( 'type' ) )
->using( $settings )
->remove_invalid_settings()
->kses_deep()
->get();
Performance::set_use_style_controls( false );
return $sanitized_data;
},
],
] );
$this->index_endpoint->register_item_route(\WP_REST_Server::DELETABLE, [
'id_arg_name' => 'type',
'id_arg_type_regex' => '[\w\-\_]+',
'type' => [
'type' => 'string',
'description' => 'The type of the element.',
'required' => true,
'validate_callback' => function( $type ) {
return $this->validate_type( $type );
},
],
] );
}
public function get_collection_params() {
return [];
}
public function get_items( $request ) {
$this->validate_kit();
$kit = Plugin::$instance->kits_manager->get_active_kit();
return (object) $kit->get_json_meta( Module::META_KEY );
}
public function update_item( $request ) {
$this->validate_kit();
$kit = Plugin::$instance->kits_manager->get_active_kit();
$data = $kit->get_json_meta( Module::META_KEY );
$data[ $request->get_param( 'type' ) ] = $request->get_param( 'settings' );
$kit->update_json_meta( Module::META_KEY, $data );
return (object) [];
}
public function delete_item( $request ) {
$this->validate_kit();
$kit = Plugin::$instance->kits_manager->get_active_kit();
$data = $kit->get_json_meta( Module::META_KEY );
unset( $data[ $request->get_param( 'type' ) ] );
$kit->update_json_meta( Module::META_KEY, $data );
return (object) [];
}
private function validate_kit() {
$kit = Plugin::$instance->kits_manager->get_active_kit();
$is_valid_kit = $kit && $kit->get_main_id();
if ( ! $is_valid_kit ) {
throw new Error_404( 'Kit doesn\'t exist.' );
}
}
private function validate_type( $param ) {
$element_types = array_keys( Plugin::$instance->elements_manager->get_element_types() );
$widget_types = array_keys( Plugin::$instance->widgets_manager->get_widget_types() );
return in_array(
$param,
array_merge( $element_types, $widget_types ),
true
);
}
public function get_items_permissions_check( $request ) {
return current_user_can( 'edit_posts' );
}
// TODO: Should be removed once the infra will support it.
public function get_item_permissions_check( $request ) {
return $this->get_items_permissions_check( $request );
}
public function update_item_permissions_check( $request ) {
return current_user_can( 'manage_options' );
}
public function delete_item_permissions_check( $request ) {
return current_user_can( 'manage_options' );
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Elementor\Modules\KitElementsDefaults\ImportExport;
use Elementor\App\Modules\ImportExport\Processes\Export;
use Elementor\App\Modules\ImportExport\Processes\Import;
use Elementor\Modules\KitElementsDefaults\ImportExport\Runners\Export as Export_Runner;
use Elementor\Modules\KitElementsDefaults\ImportExport\Runners\Import as Import_Runner;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Import_Export {
const FILE_NAME = 'kit-elements-defaults';
public function register() {
// Revert kit is working by default, using the site-settings runner.
add_action( 'elementor/import-export/export-kit', function ( Export $export ) {
$export->register( new Export_Runner() );
} );
add_action( 'elementor/import-export/import-kit', function ( Import $import ) {
$import->register( new Import_Runner() );
} );
}
}

View File

@@ -0,0 +1,71 @@
<?php
namespace Elementor\Modules\KitElementsDefaults\ImportExport\Runners;
use Elementor\Modules\KitElementsDefaults\ImportExport\Import_Export;
use Elementor\Plugin;
use Elementor\Core\Utils\Collection;
use Elementor\Modules\KitElementsDefaults\Module;
use Elementor\Modules\KitElementsDefaults\Utils\Settings_Sanitizer;
use Elementor\App\Modules\ImportExport\Runners\Export\Export_Runner_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Export extends Export_Runner_Base {
public static function get_name() : string {
return 'elements-default-values';
}
public function should_export( array $data ) {
// Together with site-settings.
return (
isset( $data['include'] ) &&
in_array( 'settings', $data['include'], true )
);
}
public function export( array $data ) {
$kit = Plugin::$instance->kits_manager->get_active_kit();
if ( ! $kit ) {
return [
'manifest' => [],
'files' => [],
];
}
$default_values = $kit->get_json_meta( Module::META_KEY );
if ( ! $default_values ) {
return [
'manifest' => [],
'files' => [],
];
}
$sanitizer = new Settings_Sanitizer(
Plugin::$instance->elements_manager,
array_keys( Plugin::$instance->widgets_manager->get_widget_types() )
);
$default_values = ( new Collection( $default_values ) )
->map( function ( $settings, $type ) use ( $sanitizer, $kit ) {
return $sanitizer
->for( $type )
->using( $settings )
->remove_invalid_settings()
->kses_deep()
->prepare_for_export( $kit )
->get();
} )
->all();
return [
'files' => [
'path' => Import_Export::FILE_NAME,
'data' => $default_values,
],
];
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Elementor\Modules\KitElementsDefaults\ImportExport\Runners;
use Elementor\Modules\KitElementsDefaults\ImportExport\Import_Export;
use Elementor\Plugin;
use Elementor\Core\Utils\Collection;
use Elementor\Modules\KitElementsDefaults\Module;
use Elementor\App\Modules\ImportExport\Utils as ImportExportUtils;
use Elementor\Modules\KitElementsDefaults\Utils\Settings_Sanitizer;
use Elementor\App\Modules\ImportExport\Runners\Import\Import_Runner_Base;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Import extends Import_Runner_Base {
public static function get_name() : string {
return 'elements-default-values';
}
public function should_import( array $data ) {
// Together with site-settings.
return (
isset( $data['include'] ) &&
in_array( 'settings', $data['include'], true ) &&
! empty( $data['site_settings']['settings'] ) &&
! empty( $data['extracted_directory_path'] )
);
}
public function import( array $data, array $imported_data ) {
$kit = Plugin::$instance->kits_manager->get_active_kit();
$file_name = Import_Export::FILE_NAME;
$default_values = ImportExportUtils::read_json_file( "{$data['extracted_directory_path']}/{$file_name}.json" );
if ( ! $kit || ! $default_values ) {
return [];
}
$element_types = array_keys( Plugin::$instance->elements_manager->get_element_types() );
$widget_types = array_keys( Plugin::$instance->widgets_manager->get_widget_types() );
$types = array_merge( $element_types, $widget_types );
$sanitizer = new Settings_Sanitizer(
Plugin::$instance->elements_manager,
$widget_types
);
$default_values = ( new Collection( $default_values ) )
->filter( function ( $settings, $type ) use ( $types ) {
return in_array( $type, $types, true );
} )
->map( function ( $settings, $type ) use ( $sanitizer, $kit ) {
return $sanitizer
->for( $type )
->using( $settings )
->remove_invalid_settings()
->kses_deep()
->prepare_for_import( $kit )
->get();
} )
->all();
$kit->update_json_meta( Module::META_KEY, $default_values );
return $default_values;
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Elementor\Modules\KitElementsDefaults;
use Elementor\Core\Experiments\Manager as Experiments_Manager;
use Elementor\Core\Base\Module as BaseModule;
use Elementor\Modules\KitElementsDefaults\Data\Controller;
use Elementor\Plugin;
use Elementor\Modules\KitElementsDefaults\ImportExport\Import_Export;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Module extends BaseModule {
const META_KEY = '_elementor_elements_default_values';
public function get_name() {
return 'kit-elements-defaults';
}
private function enqueue_scripts() {
wp_enqueue_script(
'elementor-kit-elements-defaults-editor',
$this->get_js_assets_url( 'kit-elements-defaults-editor' ),
[
'elementor-common',
'elementor-editor-modules',
'elementor-editor-document',
'wp-i18n',
],
ELEMENTOR_VERSION,
true
);
wp_set_script_translations( 'elementor-kit-elements-defaults-editor', 'elementor' );
}
public function __construct() {
parent::__construct();
add_action( 'elementor/editor/before_enqueue_scripts', function () {
$this->enqueue_scripts();
} );
Plugin::$instance->data_manager_v2->register_controller( new Controller() );
( new Usage() )->register();
if ( is_admin() ) {
( new Import_Export() )->register();
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Elementor\Modules\KitElementsDefaults;
use Elementor\Plugin;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
class Usage {
public function register() {
add_filter( 'elementor/tracker/send_tracking_data_params', function ( array $params ) {
$params['usages']['kit']['defaults'] = $this->get_usage_data();
return $params;
} );
}
private function get_usage_data() {
$elements_defaults = $this->get_elements_defaults() ?? [];
return [
'count' => count( $elements_defaults ),
'elements' => array_keys( $elements_defaults ),
];
}
private function get_elements_defaults() {
$kit = Plugin::$instance->kits_manager->get_active_kit();
return $kit->get_json_meta( Module::META_KEY );
}
}

View File

@@ -0,0 +1,280 @@
<?php
namespace Elementor\Modules\KitElementsDefaults\Utils;
use Elementor\Core\Breakpoints\Manager as Breakpoints_Manager;
use Elementor\Element_Base;
use Elementor\Elements_Manager;
use Elementor\Core\Base\Document;
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}
class Settings_Sanitizer {
const SPECIAL_SETTINGS = [
'__dynamic__',
'__globals__',
];
/**
* @var Elements_Manager
*/
private $elements_manager;
/**
* @var array
*/
private $widget_types;
/**
* @var Element_Base | null
*/
private $pending_element = null;
/**
* @var array | null
*/
private $pending_settings = null;
/**
* @param Elements_Manager $elements_manager
* @param array $widget_types
*/
public function __construct( Elements_Manager $elements_manager, array $widget_types = [] ) {
$this->elements_manager = $elements_manager;
$this->widget_types = $widget_types;
}
/**
* @param $type
*
* @return $this
*/
public function for( $type ) {
$this->pending_element = $this->create_element( $type );
return $this;
}
/**
* @param $settings
*
* @return $this
*/
public function using( $settings ) {
$this->pending_settings = $settings;
return $this;
}
/**
* @return $this
*/
public function reset() {
$this->pending_element = null;
$this->pending_settings = null;
return $this;
}
/**
* @return bool
*/
public function is_prepared() {
return $this->pending_element && is_array( $this->pending_settings );
}
/**
* @return $this
*/
public function remove_invalid_settings() {
if ( ! $this->is_prepared() ) {
return $this;
}
$valid_settings_keys = $this->get_valid_settings_keys(
$this->pending_element->get_controls()
);
$this->pending_settings = $this->filter_invalid_settings(
$this->pending_settings,
array_merge( $valid_settings_keys, self::SPECIAL_SETTINGS )
);
foreach ( self::SPECIAL_SETTINGS as $special_setting ) {
if ( ! isset( $this->pending_settings[ $special_setting ] ) ) {
continue;
}
$this->pending_settings[ $special_setting ] = $this->filter_invalid_settings(
$this->pending_settings[ $special_setting ],
$valid_settings_keys
);
}
return $this;
}
public function kses_deep() {
if ( ! $this->is_prepared() ) {
return $this;
}
$this->pending_settings = map_deep( $this->pending_settings, function( $value ) {
if ( ! is_string( $value ) ) {
return $value;
}
return wp_kses_post( $value );
} );
return $this;
}
/**
* @param Document $document
*
* @return $this
*/
public function prepare_for_export( Document $document ) {
return $this->run_import_export_sanitize_process( $document, 'on_export' );
}
/**
* @param Document $document
*
* @return $this
*/
public function prepare_for_import( Document $document ) {
return $this->run_import_export_sanitize_process( $document, 'on_import' );
}
/**
* @return array
*/
public function get() {
if ( ! $this->is_prepared() ) {
return [];
}
$settings = $this->pending_settings;
$this->reset();
return $settings;
}
/**
* @param string $type
* @param array $settings
*
* @return Element_Base|null
*/
private function create_element( $type ) {
$is_widget = in_array( $type, $this->widget_types, true );
$is_inner_section = 'inner-section' === $type;
if ( $is_inner_section ) {
return $this->elements_manager->create_element_instance( [
'elType' => 'section',
'isInner' => true,
'id' => '0',
] );
}
if ( $is_widget ) {
return $this->elements_manager->create_element_instance( [
'elType' => 'widget',
'widgetType' => $type,
'id' => '0',
] );
}
return $this->elements_manager->create_element_instance( [
'elType' => $type,
'id' => '0',
] );
}
/**
* @param Document $document
* @param $process_type
*
* @return $this
*/
private function run_import_export_sanitize_process( Document $document, $process_type ) {
if ( ! $this->is_prepared() ) {
return $this;
}
$result = $document->process_element_import_export(
$this->pending_element,
$process_type,
[ 'settings' => $this->pending_settings ]
);
if ( empty( $result['settings'] ) ) {
return $this;
}
$this->pending_settings = $result['settings'];
return $this;
}
/**
* Get all the available settings of a specific element, including responsive settings.
*
* @param array $controls
*
* @return array
*/
private function get_valid_settings_keys( $controls ) {
if ( ! $controls ) {
return [];
}
$control_keys = array_keys( $controls );
$optional_responsive_keys = [
Breakpoints_Manager::BREAKPOINT_KEY_MOBILE,
Breakpoints_Manager::BREAKPOINT_KEY_MOBILE_EXTRA,
Breakpoints_Manager::BREAKPOINT_KEY_TABLET,
Breakpoints_Manager::BREAKPOINT_KEY_TABLET_EXTRA,
Breakpoints_Manager::BREAKPOINT_KEY_LAPTOP,
Breakpoints_Manager::BREAKPOINT_KEY_WIDESCREEN,
];
$settings = [];
foreach ( $control_keys as $control_key ) {
// Add the responsive settings.
foreach ( $optional_responsive_keys as $responsive_key ) {
$settings[] = "{$control_key}_{$responsive_key}";
}
// Add the setting itself (not responsive).
$settings[] = $control_key;
}
return $settings;
}
/**
* Remove invalid settings.
*
* @param $settings
* @param $valid_settings_keys
*
* @return array
*/
private function filter_invalid_settings( $settings, $valid_settings_keys ) {
return array_filter(
$settings,
function ( $setting_key ) use ( $valid_settings_keys ) {
return in_array( $setting_key, $valid_settings_keys, true );
},
ARRAY_FILTER_USE_KEY
);
}
}