first commit
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
$user = wp_get_current_user();
|
||||
|
||||
$ajax = Plugin::$instance->common->get_component( 'ajax' );
|
||||
|
||||
$beta_tester_email = $user->user_email;
|
||||
|
||||
/**
|
||||
* Print beta tester dialog.
|
||||
*
|
||||
* Display a dialog box to suggest the user to opt-in to the beta testers newsletter.
|
||||
*
|
||||
* Fired by `admin_footer` filter.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
*/
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-beta-tester">
|
||||
<form id="elementor-beta-tester-form" method="post">
|
||||
<input type="hidden" name="_nonce" value="<?php echo $ajax->create_nonce(); ?>">
|
||||
<input type="hidden" name="action" value="elementor_beta_tester_signup" />
|
||||
<div id="elementor-beta-tester-form__caption"><?php echo __( 'Get Beta Updates', 'elementor' ); ?></div>
|
||||
<div id="elementor-beta-tester-form__description"><?php echo __( 'As a beta tester, you’ll receive an update that includes a testing version of Elementor and its content directly to your Email', 'elementor' ); ?></div>
|
||||
<div id="elementor-beta-tester-form__input-wrapper">
|
||||
<input id="elementor-beta-tester-form__email" name="beta_tester_email" type="email" placeholder="<?php echo __( 'Your Email', 'elementor' ); ?>" required value="<?php echo $beta_tester_email; ?>" />
|
||||
<button id="elementor-beta-tester-form__submit" class="elementor-button elementor-button-success">
|
||||
<span class="elementor-state-icon">
|
||||
<i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
</span>
|
||||
<?php echo __( 'Sign Up', 'elementor' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<div id="elementor-beta-tester-form__terms">
|
||||
<?php echo sprintf( __( 'By clicking Sign Up, you agree to Elementor\'s <a href="%1$s">Terms of Service</a> and <a href="%2$s">Privacy Policy</a>', 'elementor' ), Beta_Testers::NEWSLETTER_TERMS_URL, Beta_Testers::NEWSLETTER_PRIVACY_URL ); ?>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Base\Document;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
$document_types = Plugin::$instance->documents->get_document_types();
|
||||
|
||||
$types = [];
|
||||
|
||||
$selected = get_query_var( 'elementor_library_type' );
|
||||
|
||||
foreach ( $document_types as $document_type ) {
|
||||
if ( $document_type::get_property( 'show_in_library' ) ) {
|
||||
/**
|
||||
* @var Document $instance
|
||||
*/
|
||||
$instance = new $document_type();
|
||||
|
||||
$types[ $instance->get_name() ] = $document_type::get_title();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create new template library dialog types.
|
||||
*
|
||||
* Filters the dialog types when printing new template dialog.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param array $types Types data.
|
||||
* @param Document $document_types Document types.
|
||||
*/
|
||||
$types = apply_filters( 'elementor/template-library/create_new_dialog_types', $types, $document_types );
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-new-template">
|
||||
<div id="elementor-new-template__description">
|
||||
<div id="elementor-new-template__description__title"><?php echo __( 'Templates Help You <span>Work Efficiently</span>', 'elementor' ); ?></div>
|
||||
<div id="elementor-new-template__description__content"><?php echo __( 'Use templates to create the different pieces of your site, and reuse them with one click whenever needed.', 'elementor' ); ?></div>
|
||||
<?php
|
||||
/*
|
||||
<div id="elementor-new-template__take_a_tour">
|
||||
<i class="eicon-play-o"></i>
|
||||
<a href="#"><?php echo __( 'Take The Video Tour', 'elementor' ); ?></a>
|
||||
</div>
|
||||
*/
|
||||
?>
|
||||
</div>
|
||||
<form id="elementor-new-template__form" action="<?php esc_url( admin_url( '/edit.php' ) ); ?>">
|
||||
<input type="hidden" name="post_type" value="elementor_library">
|
||||
<input type="hidden" name="action" value="elementor_new_post">
|
||||
<input type="hidden" name="_wpnonce" value="<?php echo wp_create_nonce( 'elementor_action_new_post' ); ?>">
|
||||
<div id="elementor-new-template__form__title"><?php echo __( 'Choose Template Type', 'elementor' ); ?></div>
|
||||
<div id="elementor-new-template__form__template-type__wrapper" class="elementor-form-field">
|
||||
<label for="elementor-new-template__form__template-type" class="elementor-form-field__label"><?php echo __( 'Select the type of template you want to work on', 'elementor' ); ?></label>
|
||||
<div class="elementor-form-field__select__wrapper">
|
||||
<select id="elementor-new-template__form__template-type" class="elementor-form-field__select" name="template_type" required>
|
||||
<option value=""><?php echo __( 'Select', 'elementor' ); ?>...</option>
|
||||
<?php
|
||||
foreach ( $types as $value => $type_title ) {
|
||||
printf( '<option value="%1$s" %2$s>%3$s</option>', $value, selected( $selected, $value, false ), $type_title );
|
||||
}
|
||||
?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
/**
|
||||
* Template library dialog fields.
|
||||
*
|
||||
* Fires after Elementor template library dialog fields are displayed.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
do_action( 'elementor/template-library/create_new_dialog_fields' );
|
||||
?>
|
||||
|
||||
<div id="elementor-new-template__form__post-title__wrapper" class="elementor-form-field">
|
||||
<label for="elementor-new-template__form__post-title" class="elementor-form-field__label">
|
||||
<?php echo __( 'Name your template', 'elementor' ); ?>
|
||||
</label>
|
||||
<div class="elementor-form-field__text__wrapper">
|
||||
<input type="text" placeholder="<?php echo esc_attr__( 'Enter template name (optional)', 'elementor' ); ?>" id="elementor-new-template__form__post-title" class="elementor-form-field__text" name="post_data[post_title]">
|
||||
</div>
|
||||
</div>
|
||||
<button id="elementor-new-template__form__submit" class="elementor-button elementor-button-success"><?php echo __( 'Create Template', 'elementor' ); ?></button>
|
||||
</form>
|
||||
</script>
|
||||
@@ -0,0 +1,290 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Common\Modules\Connect\Apps\Library;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor API.
|
||||
*
|
||||
* Elementor API handler class is responsible for communicating with Elementor
|
||||
* remote servers retrieving templates data and to send uninstall feedback.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Api {
|
||||
|
||||
/**
|
||||
* Elementor library option key.
|
||||
*/
|
||||
const LIBRARY_OPTION_KEY = 'elementor_remote_info_library';
|
||||
|
||||
/**
|
||||
* Elementor feed option key.
|
||||
*/
|
||||
const FEED_OPTION_KEY = 'elementor_remote_info_feed_data';
|
||||
|
||||
/**
|
||||
* API info URL.
|
||||
*
|
||||
* Holds the URL of the info API.
|
||||
*
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @var string API info URL.
|
||||
*/
|
||||
public static $api_info_url = 'https://my.elementor.com/api/v1/info/';
|
||||
|
||||
/**
|
||||
* API feedback URL.
|
||||
*
|
||||
* Holds the URL of the feedback API.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string API feedback URL.
|
||||
*/
|
||||
private static $api_feedback_url = 'https://my.elementor.com/api/v1/feedback/';
|
||||
|
||||
/**
|
||||
* Get info data.
|
||||
*
|
||||
* This function notifies the user of upgrade notices, new templates and contributors.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data retrieval or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array|false Info data, or false.
|
||||
*/
|
||||
private static function get_info_data( $force_update = false ) {
|
||||
$cache_key = 'elementor_remote_info_api_data_' . ELEMENTOR_VERSION;
|
||||
|
||||
$info_data = get_transient( $cache_key );
|
||||
|
||||
if ( $force_update || false === $info_data ) {
|
||||
$timeout = ( $force_update ) ? 25 : 8;
|
||||
|
||||
$response = wp_remote_get( self::$api_info_url, [
|
||||
'timeout' => $timeout,
|
||||
'body' => [
|
||||
// Which API version is used.
|
||||
'api_version' => ELEMENTOR_VERSION,
|
||||
// Which language to return.
|
||||
'site_lang' => get_bloginfo( 'language' ),
|
||||
],
|
||||
] );
|
||||
|
||||
if ( is_wp_error( $response ) || 200 !== (int) wp_remote_retrieve_response_code( $response ) ) {
|
||||
set_transient( $cache_key, [], 2 * HOUR_IN_SECONDS );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$info_data = json_decode( wp_remote_retrieve_body( $response ), true );
|
||||
|
||||
if ( empty( $info_data ) || ! is_array( $info_data ) ) {
|
||||
set_transient( $cache_key, [], 2 * HOUR_IN_SECONDS );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $info_data['library'] ) ) {
|
||||
update_option( self::LIBRARY_OPTION_KEY, $info_data['library'], 'no' );
|
||||
|
||||
unset( $info_data['library'] );
|
||||
}
|
||||
|
||||
if ( isset( $info_data['feed'] ) ) {
|
||||
update_option( self::FEED_OPTION_KEY, $info_data['feed'], 'no' );
|
||||
|
||||
unset( $info_data['feed'] );
|
||||
}
|
||||
|
||||
set_transient( $cache_key, $info_data, 12 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $info_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get upgrade notice.
|
||||
*
|
||||
* Retrieve the upgrade notice if one exists, or false otherwise.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array|false Upgrade notice, or false none exist.
|
||||
*/
|
||||
public static function get_upgrade_notice() {
|
||||
$data = self::get_info_data();
|
||||
|
||||
if ( empty( $data['upgrade_notice'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data['upgrade_notice'];
|
||||
}
|
||||
|
||||
public static function get_admin_notice() {
|
||||
$data = self::get_info_data();
|
||||
if ( empty( $data['admin_notice'] ) ) {
|
||||
return false;
|
||||
}
|
||||
return $data['admin_notice'];
|
||||
}
|
||||
|
||||
public static function get_canary_deployment_info( $force = false ) {
|
||||
$data = self::get_info_data( $force );
|
||||
|
||||
if ( empty( $data['canary_deployment'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $data['canary_deployment'];
|
||||
}
|
||||
|
||||
public static function get_promotion_widgets() {
|
||||
$data = self::get_info_data();
|
||||
|
||||
return $data['pro_widgets'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates data.
|
||||
*
|
||||
* Retrieve the templates data from a remote server.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data update or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array The templates data.
|
||||
*/
|
||||
public static function get_library_data( $force_update = false ) {
|
||||
self::get_info_data( $force_update );
|
||||
|
||||
$library_data = get_option( self::LIBRARY_OPTION_KEY );
|
||||
|
||||
if ( empty( $library_data ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $library_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get feed data.
|
||||
*
|
||||
* Retrieve the feed info data from remote elementor server.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param bool $force_update Optional. Whether to force the data update or
|
||||
* not. Default is false.
|
||||
*
|
||||
* @return array Feed data.
|
||||
*/
|
||||
public static function get_feed_data( $force_update = false ) {
|
||||
self::get_info_data( $force_update );
|
||||
|
||||
$feed = get_option( self::FEED_OPTION_KEY );
|
||||
|
||||
if ( empty( $feed ) ) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template content.
|
||||
*
|
||||
* Retrieve the templates content received from a remote server.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param int $template_id The template ID.
|
||||
*
|
||||
* @return object|\WP_Error The template content.
|
||||
*/
|
||||
public static function get_template_content( $template_id ) {
|
||||
/** @var Library $library */
|
||||
$library = Plugin::$instance->common->get_component( 'connect' )->get_app( 'library' );
|
||||
|
||||
return $library->get_template_content( $template_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Send Feedback.
|
||||
*
|
||||
* Fires a request to Elementor server with the feedback data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $feedback_key Feedback key.
|
||||
* @param string $feedback_text Feedback text.
|
||||
*
|
||||
* @return array The response of the request.
|
||||
*/
|
||||
public static function send_feedback( $feedback_key, $feedback_text ) {
|
||||
return wp_remote_post( self::$api_feedback_url, [
|
||||
'timeout' => 30,
|
||||
'body' => [
|
||||
'api_version' => ELEMENTOR_VERSION,
|
||||
'site_lang' => get_bloginfo( 'language' ),
|
||||
'feedback_key' => $feedback_key,
|
||||
'feedback' => $feedback_text,
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax reset API data.
|
||||
*
|
||||
* Reset Elementor library API data using an ajax call.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function ajax_reset_api_data() {
|
||||
check_ajax_referer( 'elementor_reset_library', '_nonce' );
|
||||
|
||||
self::get_info_data( true );
|
||||
|
||||
wp_send_json_success();
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor API.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function init() {
|
||||
add_action( 'wp_ajax_elementor_reset_library', [ __CLASS__, 'ajax_reset_api_data' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,314 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor autoloader.
|
||||
*
|
||||
* Elementor autoloader handler class is responsible for loading the different
|
||||
* classes needed to run the plugin.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Autoloader {
|
||||
|
||||
/**
|
||||
* Classes map.
|
||||
*
|
||||
* Maps Elementor classes to file names.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Classes used by elementor.
|
||||
*/
|
||||
private static $classes_map;
|
||||
|
||||
/**
|
||||
* Classes aliases.
|
||||
*
|
||||
* Maps Elementor classes to aliases.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Classes aliases.
|
||||
*/
|
||||
private static $classes_aliases;
|
||||
|
||||
/**
|
||||
* Run autoloader.
|
||||
*
|
||||
* Register a function as `__autoload()` implementation.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function run() {
|
||||
spl_autoload_register( [ __CLASS__, 'autoload' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get classes aliases.
|
||||
*
|
||||
* Retrieve the classes aliases names.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Classes aliases.
|
||||
*/
|
||||
public static function get_classes_aliases() {
|
||||
if ( ! self::$classes_aliases ) {
|
||||
self::init_classes_aliases();
|
||||
}
|
||||
|
||||
return self::$classes_aliases;
|
||||
}
|
||||
|
||||
public static function get_classes_map() {
|
||||
if ( ! self::$classes_map ) {
|
||||
self::init_classes_map();
|
||||
}
|
||||
|
||||
return self::$classes_map;
|
||||
}
|
||||
|
||||
private static function init_classes_map() {
|
||||
self::$classes_map = [
|
||||
'Api' => 'includes/api.php',
|
||||
'Base_Control' => 'includes/controls/base.php',
|
||||
'Base_Data_Control' => 'includes/controls/base-data.php',
|
||||
'Base_UI_Control' => 'includes/controls/base-ui.php',
|
||||
'Beta_Testers' => 'includes/beta-testers.php',
|
||||
'Compatibility' => 'includes/compatibility.php',
|
||||
'Conditions' => 'includes/conditions.php',
|
||||
'Controls_Manager' => 'includes/managers/controls.php',
|
||||
'Controls_Stack' => 'includes/base/controls-stack.php',
|
||||
'Sub_Controls_Stack' => 'includes/base/sub-controls-stack.php',
|
||||
'DB' => 'includes/db.php',
|
||||
'Elements_Manager' => 'includes/managers/elements.php',
|
||||
'Embed' => 'includes/embed.php',
|
||||
'Fonts' => 'includes/fonts.php',
|
||||
'Frontend' => 'includes/frontend.php',
|
||||
'Group_Control_Base' => 'includes/controls/groups/base.php',
|
||||
'Group_Control_Interface' => 'includes/interfaces/group-control.php',
|
||||
'Heartbeat' => 'includes/heartbeat.php',
|
||||
'Images_Manager' => 'includes/managers/image.php',
|
||||
'Maintenance' => 'includes/maintenance.php',
|
||||
'Maintenance_Mode' => 'includes/maintenance-mode.php',
|
||||
'Preview' => 'includes/preview.php',
|
||||
'Rollback' => 'includes/rollback.php',
|
||||
'Settings' => 'includes/settings/settings.php',
|
||||
'Settings_Controls' => 'includes/settings/controls.php',
|
||||
'Settings_Validations' => 'includes/settings/validations.php',
|
||||
'Settings_Page' => 'includes/settings/settings-page.php',
|
||||
'Shapes' => 'includes/shapes.php',
|
||||
'Skins_Manager' => 'includes/managers/skins.php',
|
||||
'Icons_Manager' => 'includes/managers/icons.php',
|
||||
'Stylesheet' => 'includes/stylesheet.php',
|
||||
'System_Info\Main' => 'includes/settings/system-info/main.php',
|
||||
'TemplateLibrary\Classes\Import_Images' => 'includes/template-library/classes/class-import-images.php',
|
||||
'TemplateLibrary\Manager' => 'includes/template-library/manager.php',
|
||||
'TemplateLibrary\Source_Base' => 'includes/template-library/sources/base.php',
|
||||
'TemplateLibrary\Source_Local' => 'includes/template-library/sources/local.php',
|
||||
'TemplateLibrary\Source_Remote' => 'includes/template-library/sources/remote.php',
|
||||
'Tools' => 'includes/settings/tools.php',
|
||||
'Tracker' => 'includes/tracker.php',
|
||||
'User' => 'includes/user.php',
|
||||
'Utils' => 'includes/utils.php',
|
||||
'Widget_WordPress' => 'includes/widgets/wordpress.php',
|
||||
'Widgets_Manager' => 'includes/managers/widgets.php',
|
||||
'WordPress_Widgets_Manager' => 'includes/managers/wordpress-widgets.php',
|
||||
];
|
||||
|
||||
$controls_names = Controls_Manager::get_controls_names();
|
||||
|
||||
$controls_names = array_merge( $controls_names, [
|
||||
'base_multiple',
|
||||
'base_units',
|
||||
] );
|
||||
|
||||
foreach ( $controls_names as $control_name ) {
|
||||
$class_name = 'Control_' . self::normalize_class_name( $control_name, '_' );
|
||||
|
||||
self::$classes_map[ $class_name ] = 'includes/controls/' . str_replace( '_', '-', $control_name ) . '.php';
|
||||
}
|
||||
|
||||
$controls_groups_names = Controls_Manager::get_groups_names();
|
||||
|
||||
foreach ( $controls_groups_names as $group_name ) {
|
||||
$class_name = 'Group_Control_' . self::normalize_class_name( str_replace( '-', '_', $group_name ), '_' );
|
||||
|
||||
self::$classes_map[ $class_name ] = 'includes/controls/groups/' . $group_name . '.php';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize Class Name
|
||||
*
|
||||
* Used to convert control names to class name,
|
||||
* a ucwords polyfill for php versions not supporting delimiter parameter
|
||||
* reference : https://github.com/elementor/elementor/issues/7310#issuecomment-469593385
|
||||
*
|
||||
* @param $string
|
||||
* @param string $delimiter
|
||||
*
|
||||
* @todo Remove once we bump minimum php version to 5.6
|
||||
* @return mixed
|
||||
*/
|
||||
private static function normalize_class_name( $string, $delimiter = ' ' ) {
|
||||
return str_replace( ' ', $delimiter, ucwords( str_replace( $delimiter, ' ', $string ) ) );
|
||||
}
|
||||
|
||||
private static function init_classes_aliases() {
|
||||
self::$classes_aliases = [
|
||||
'Core\Ajax' => [
|
||||
'replacement' => 'Core\Common\Modules\Ajax\Module',
|
||||
'version' => '2.3.0',
|
||||
],
|
||||
'Editor' => [
|
||||
'replacement' => 'Core\Editor\Editor',
|
||||
'version' => '2.6.0',
|
||||
],
|
||||
'Scheme_Base' => [
|
||||
'replacement' => 'Core\Schemes\Base',
|
||||
'version' => '2.8.0',
|
||||
],
|
||||
'Scheme_Color' => [
|
||||
'replacement' => 'Core\Schemes\Color',
|
||||
'version' => '2.8.0',
|
||||
],
|
||||
'Scheme_Color_Picker' => [
|
||||
'replacement' => 'Core\Schemes\Color_Picker',
|
||||
'version' => '2.8.0',
|
||||
],
|
||||
'Schemes_Manager' => [
|
||||
'replacement' => 'Core\Schemes\Manager',
|
||||
'version' => '2.8.0',
|
||||
],
|
||||
'Scheme_Typography' => [
|
||||
'replacement' => 'Core\Schemes\Typography',
|
||||
'version' => '2.8.0',
|
||||
],
|
||||
'System_Info\Main' => [
|
||||
'replacement' => 'Modules\System_Info\Module',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\Abstracts\Base_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\Base',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\Server_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\Server',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\MU_Plugins_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\MU_Plugins',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\Network_Plugins_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\Network_Plugins',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\Plugins_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\Plugins',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\Theme_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\Theme',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Classes\User_Reporter' => [
|
||||
'replacement' => 'Modules\System_Info\Reporters\User',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
'System_Info\Helpers\Model_Helper' => [
|
||||
'replacement' => 'Modules\System_Info\Helpers\Model_Helper',
|
||||
'version' => '2.9.0',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load class.
|
||||
*
|
||||
* For a given class name, require the class file.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param string $relative_class_name Class name.
|
||||
*/
|
||||
private static function load_class( $relative_class_name ) {
|
||||
$classes_map = self::get_classes_map();
|
||||
|
||||
if ( isset( $classes_map[ $relative_class_name ] ) ) {
|
||||
$filename = ELEMENTOR_PATH . '/' . $classes_map[ $relative_class_name ];
|
||||
} else {
|
||||
$filename = strtolower(
|
||||
preg_replace(
|
||||
[ '/([a-z])([A-Z])/', '/_/', '/\\\/' ],
|
||||
[ '$1-$2', '-', DIRECTORY_SEPARATOR ],
|
||||
$relative_class_name
|
||||
)
|
||||
);
|
||||
|
||||
$filename = ELEMENTOR_PATH . $filename . '.php';
|
||||
}
|
||||
|
||||
if ( is_readable( $filename ) ) {
|
||||
require $filename;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Autoload.
|
||||
*
|
||||
* For a given class, check if it exist and load it.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param string $class Class name.
|
||||
*/
|
||||
private static function autoload( $class ) {
|
||||
if ( 0 !== strpos( $class, __NAMESPACE__ . '\\' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$relative_class_name = preg_replace( '/^' . __NAMESPACE__ . '\\\/', '', $class );
|
||||
|
||||
$classes_aliases = self::get_classes_aliases();
|
||||
|
||||
$has_class_alias = isset( $classes_aliases[ $relative_class_name ] );
|
||||
|
||||
// Backward Compatibility: Save old class name for set an alias after the new class is loaded
|
||||
if ( $has_class_alias ) {
|
||||
$alias_data = $classes_aliases[ $relative_class_name ];
|
||||
|
||||
$relative_class_name = $alias_data['replacement'];
|
||||
}
|
||||
|
||||
$final_class_name = __NAMESPACE__ . '\\' . $relative_class_name;
|
||||
|
||||
if ( ! class_exists( $final_class_name ) ) {
|
||||
self::load_class( $relative_class_name );
|
||||
}
|
||||
|
||||
if ( $has_class_alias ) {
|
||||
class_alias( $final_class_name, $class );
|
||||
|
||||
Utils::handle_deprecation( $class, $alias_data['version'], $final_class_name );
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,988 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor element base.
|
||||
*
|
||||
* An abstract class to register new Elementor elements. It extended the
|
||||
* `Controls_Stack` class to inherit its properties.
|
||||
*
|
||||
* This abstract class must be extended in order to register new elements.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Element_Base extends Controls_Stack {
|
||||
|
||||
/**
|
||||
* Child elements.
|
||||
*
|
||||
* Holds all the child elements of the element.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var Element_Base[]
|
||||
*/
|
||||
private $children;
|
||||
|
||||
/**
|
||||
* Element render attributes.
|
||||
*
|
||||
* Holds all the render attributes of the element. Used to store data like
|
||||
* the HTML class name and the class value, or HTML element ID name and value.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $render_attributes = [];
|
||||
|
||||
/**
|
||||
* Element default arguments.
|
||||
*
|
||||
* Holds all the default arguments of the element. Used to store additional
|
||||
* data. For example WordPress widgets use this to store widget names.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $default_args = [];
|
||||
|
||||
/**
|
||||
* Is type instance.
|
||||
*
|
||||
* Whether the element is an instance of that type or not.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $is_type_instance = true;
|
||||
|
||||
/**
|
||||
* Depended scripts.
|
||||
*
|
||||
* Holds all the element depended scripts to enqueue.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $depended_scripts = [];
|
||||
|
||||
/**
|
||||
* Depended styles.
|
||||
*
|
||||
* Holds all the element depended styles to enqueue.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $depended_styles = [];
|
||||
|
||||
/**
|
||||
* Add script depends.
|
||||
*
|
||||
* Register new script to enqueue by the handler.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $handler Depend script handler.
|
||||
*/
|
||||
public function add_script_depends( $handler ) {
|
||||
$this->depended_scripts[] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add style depends.
|
||||
*
|
||||
* Register new style to enqueue by the handler.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $handler Depend style handler.
|
||||
*/
|
||||
public function add_style_depends( $handler ) {
|
||||
$this->depended_styles[] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get script dependencies.
|
||||
*
|
||||
* Retrieve the list of script dependencies the element requires.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Element scripts dependencies.
|
||||
*/
|
||||
public function get_script_depends() {
|
||||
return $this->depended_scripts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts.
|
||||
*
|
||||
* Registers all the scripts defined as element dependencies and enqueues
|
||||
* them. Use `get_script_depends()` method to add custom script dependencies.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*/
|
||||
final public function enqueue_scripts() {
|
||||
$deprecated_scripts = [
|
||||
'jquery-slick' => [
|
||||
'version' => '2.7.0',
|
||||
'replacement' => 'Swiper',
|
||||
],
|
||||
];
|
||||
|
||||
foreach ( $this->get_script_depends() as $script ) {
|
||||
if ( isset( $deprecated_scripts[ $script ] ) ) {
|
||||
Utils::handle_deprecation( $script, $deprecated_scripts[ $script ]['version'], $deprecated_scripts[ $script ]['replacement'] );
|
||||
}
|
||||
|
||||
wp_enqueue_script( $script );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get style dependencies.
|
||||
*
|
||||
* Retrieve the list of style dependencies the element requires.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Element styles dependencies.
|
||||
*/
|
||||
public function get_style_depends() {
|
||||
return $this->depended_styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles.
|
||||
*
|
||||
* Registers all the styles defined as element dependencies and enqueues
|
||||
* them. Use `get_style_depends()` method to add custom style dependencies.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*/
|
||||
final public function enqueue_styles() {
|
||||
foreach ( $this->get_style_depends() as $style ) {
|
||||
wp_enqueue_style( $style );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 1.0.0
|
||||
* @deprecated 2.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
final public static function add_edit_tool() {}
|
||||
|
||||
/**
|
||||
* @since 2.2.0
|
||||
* @deprecated 2.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
final public static function is_edit_buttons_enabled() {
|
||||
return get_option( 'elementor_edit_buttons' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default child type.
|
||||
*
|
||||
* Retrieve the default child type based on element data.
|
||||
*
|
||||
* Note that not all elements support children.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*
|
||||
* @param array $element_data Element data.
|
||||
*
|
||||
* @return Element_Base
|
||||
*/
|
||||
abstract protected function _get_default_child_type( array $element_data );
|
||||
|
||||
/**
|
||||
* Before element rendering.
|
||||
*
|
||||
* Used to add stuff before the element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function before_render() {}
|
||||
|
||||
/**
|
||||
* After element rendering.
|
||||
*
|
||||
* Used to add stuff after the element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function after_render() {}
|
||||
|
||||
/**
|
||||
* Get element title.
|
||||
*
|
||||
* Retrieve the element title.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Element title.
|
||||
*/
|
||||
public function get_title() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element icon.
|
||||
*
|
||||
* Retrieve the element icon.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Element icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
return 'eicon-columns';
|
||||
}
|
||||
|
||||
public function get_help_url() {
|
||||
return 'https://go.elementor.com/widget-' . $this->get_name();
|
||||
}
|
||||
|
||||
public function get_custom_help_url() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the reload preview is required.
|
||||
*
|
||||
* Used to determine whether the reload preview is required or not.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether the reload preview is required.
|
||||
*/
|
||||
public function is_reload_preview_required() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.1
|
||||
* @access protected
|
||||
*/
|
||||
protected function should_print_empty() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child elements.
|
||||
*
|
||||
* Retrieve all the child elements of this element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return Element_Base[] Child elements.
|
||||
*/
|
||||
public function get_children() {
|
||||
if ( null === $this->children ) {
|
||||
$this->init_children();
|
||||
}
|
||||
|
||||
return $this->children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default arguments.
|
||||
*
|
||||
* Retrieve the element default arguments. Used to return all the default
|
||||
* arguments or a specific default argument, if one is set.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $item Optional. Default is null.
|
||||
*
|
||||
* @return array Default argument(s).
|
||||
*/
|
||||
public function get_default_args( $item = null ) {
|
||||
return self::get_items( $this->default_args, $item );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new child element.
|
||||
*
|
||||
* Register new child element to allow hierarchy.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @param array $child_data Child element data.
|
||||
* @param array $child_args Child element arguments.
|
||||
*
|
||||
* @return Element_Base|false Child element instance, or false if failed.
|
||||
*/
|
||||
public function add_child( array $child_data, array $child_args = [] ) {
|
||||
if ( null === $this->children ) {
|
||||
$this->init_children();
|
||||
}
|
||||
|
||||
$child_type = $this->get_child_type( $child_data );
|
||||
|
||||
if ( ! $child_type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$child = Plugin::$instance->elements_manager->create_element_instance( $child_data, $child_args, $child_type );
|
||||
|
||||
if ( $child ) {
|
||||
$this->children[] = $child;
|
||||
}
|
||||
|
||||
return $child;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add render attribute.
|
||||
*
|
||||
* Used to add attributes to a specific HTML element.
|
||||
*
|
||||
* The HTML tag is represented by the element parameter, then you need to
|
||||
* define the attribute key and the attribute key. The final result will be:
|
||||
* `<element attribute_key="attribute_value">`.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* `$this->add_render_attribute( 'wrapper', 'class', 'custom-widget-wrapper-class' );`
|
||||
* `$this->add_render_attribute( 'widget', 'id', 'custom-widget-id' );`
|
||||
* `$this->add_render_attribute( 'button', [ 'class' => 'custom-button-class', 'id' => 'custom-button-id' ] );`
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $element The HTML element.
|
||||
* @param array|string $key Optional. Attribute key. Default is null.
|
||||
* @param array|string $value Optional. Attribute value. Default is null.
|
||||
* @param bool $overwrite Optional. Whether to overwrite existing
|
||||
* attribute. Default is false, not to overwrite.
|
||||
*
|
||||
* @return Element_Base Current instance of the element.
|
||||
*/
|
||||
public function add_render_attribute( $element, $key = null, $value = null, $overwrite = false ) {
|
||||
if ( is_array( $element ) ) {
|
||||
foreach ( $element as $element_key => $attributes ) {
|
||||
$this->add_render_attribute( $element_key, $attributes, null, $overwrite );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( is_array( $key ) ) {
|
||||
foreach ( $key as $attribute_key => $attributes ) {
|
||||
$this->add_render_attribute( $element, $attribute_key, $attributes, $overwrite );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( empty( $this->render_attributes[ $element ][ $key ] ) ) {
|
||||
$this->render_attributes[ $element ][ $key ] = [];
|
||||
}
|
||||
|
||||
settype( $value, 'array' );
|
||||
|
||||
if ( $overwrite ) {
|
||||
$this->render_attributes[ $element ][ $key ] = $value;
|
||||
} else {
|
||||
$this->render_attributes[ $element ][ $key ] = array_merge( $this->render_attributes[ $element ][ $key ], $value );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add link render attributes.
|
||||
*
|
||||
* Used to add link tag attributes to a specific HTML element.
|
||||
*
|
||||
* The HTML link tag is represented by the element parameter. The `url_control` parameter
|
||||
* needs to be an array of link settings in the same format they are set by Elementor's URL control.
|
||||
*
|
||||
* Example usage:
|
||||
*
|
||||
* `$this->add_link_attributes( 'button', $settings['link'] );`
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $element The HTML element.
|
||||
* @param array $url_control Array of link settings.
|
||||
* @param bool $overwrite Optional. Whether to overwrite existing
|
||||
* attribute. Default is false, not to overwrite.
|
||||
*
|
||||
* @return Element_Base Current instance of the element.
|
||||
*/
|
||||
|
||||
public function add_link_attributes( $element, array $url_control, $overwrite = false ) {
|
||||
$attributes = [];
|
||||
|
||||
if ( ! empty( $url_control['url'] ) ) {
|
||||
$allowed_protocols = array_merge( wp_allowed_protocols(), [ 'skype', 'viber' ] );
|
||||
|
||||
$attributes['href'] = esc_url( $url_control['url'], $allowed_protocols );
|
||||
}
|
||||
|
||||
if ( ! empty( $url_control['is_external'] ) ) {
|
||||
$attributes['target'] = '_blank';
|
||||
}
|
||||
|
||||
if ( ! empty( $url_control['nofollow'] ) ) {
|
||||
$attributes['rel'] = 'nofollow';
|
||||
}
|
||||
|
||||
if ( ! empty( $url_control['custom_attributes'] ) ) {
|
||||
// Custom URL attributes should come as a string of comma-delimited key|value pairs
|
||||
$attributes = array_merge( $attributes, Utils::parse_custom_attributes( $url_control['custom_attributes'] ) );
|
||||
}
|
||||
|
||||
if ( $attributes ) {
|
||||
$this->add_render_attribute( $element, $attributes, $overwrite );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Render Attributes
|
||||
*
|
||||
* Used to retrieve render attribute.
|
||||
*
|
||||
* The returned array is either all elements and their attributes if no `$element` is specified, an array of all
|
||||
* attributes of a specific element or a specific attribute properties if `$key` is specified.
|
||||
*
|
||||
* Returns null if one of the requested parameters isn't set.
|
||||
*
|
||||
* @since 2.2.6
|
||||
* @access public
|
||||
* @param string $element
|
||||
* @param string $key
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_render_attributes( $element = '', $key = '' ) {
|
||||
$attributes = $this->render_attributes;
|
||||
|
||||
if ( $element ) {
|
||||
if ( ! isset( $attributes[ $element ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attributes = $attributes[ $element ];
|
||||
|
||||
if ( $key ) {
|
||||
if ( ! isset( $attributes[ $key ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$attributes = $attributes[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set render attribute.
|
||||
*
|
||||
* Used to set the value of the HTML element render attribute or to update
|
||||
* an existing render attribute.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $element The HTML element.
|
||||
* @param array|string $key Optional. Attribute key. Default is null.
|
||||
* @param array|string $value Optional. Attribute value. Default is null.
|
||||
*
|
||||
* @return Element_Base Current instance of the element.
|
||||
*/
|
||||
public function set_render_attribute( $element, $key = null, $value = null ) {
|
||||
return $this->add_render_attribute( $element, $key, $value, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove render attribute.
|
||||
*
|
||||
* Used to remove an element (with its keys and their values), key (with its values),
|
||||
* or value/s from an HTML element's render attribute.
|
||||
*
|
||||
* @since 2.7.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $element The HTML element.
|
||||
* @param string $key Optional. Attribute key. Default is null.
|
||||
* @param array|string $values Optional. Attribute value/s. Default is null.
|
||||
*/
|
||||
public function remove_render_attribute( $element, $key = null, $values = null ) {
|
||||
if ( $key && ! isset( $this->render_attributes[ $element ][ $key ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $values ) {
|
||||
$values = (array) $values;
|
||||
|
||||
$this->render_attributes[ $element ][ $key ] = array_diff( $this->render_attributes[ $element ][ $key ], $values );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $key ) {
|
||||
unset( $this->render_attributes[ $element ][ $key ] );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $this->render_attributes[ $element ] ) ) {
|
||||
unset( $this->render_attributes[ $element ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get render attribute string.
|
||||
*
|
||||
* Used to retrieve the value of the render attribute.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $element The element.
|
||||
*
|
||||
* @return string Render attribute string, or an empty string if the attribute
|
||||
* is empty or not exist.
|
||||
*/
|
||||
public function get_render_attribute_string( $element ) {
|
||||
if ( empty( $this->render_attributes[ $element ] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Utils::render_html_attributes( $this->render_attributes[ $element ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print render attribute string.
|
||||
*
|
||||
* Used to output the rendered attribute.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array|string $element The element.
|
||||
*/
|
||||
public function print_render_attribute_string( $element ) {
|
||||
echo $this->get_render_attribute_string( $element ); // XSS ok.
|
||||
}
|
||||
|
||||
/**
|
||||
* Print element.
|
||||
*
|
||||
* Used to generate the element final HTML on the frontend and the editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function print_element() {
|
||||
$element_type = $this->get_type();
|
||||
|
||||
/**
|
||||
* Before frontend element render.
|
||||
*
|
||||
* Fires before Elementor element is rendered in the frontend.
|
||||
*
|
||||
* @since 2.2.0
|
||||
*
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
do_action( 'elementor/frontend/before_render', $this );
|
||||
|
||||
/**
|
||||
* Before frontend element render.
|
||||
*
|
||||
* Fires before Elementor element is rendered in the frontend.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$element_type`, refers to the element type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
do_action( "elementor/frontend/{$element_type}/before_render", $this );
|
||||
|
||||
ob_start();
|
||||
$this->_print_content();
|
||||
$content = ob_get_clean();
|
||||
|
||||
$should_render = ( ! empty( $content ) || $this->should_print_empty() );
|
||||
|
||||
/**
|
||||
* Should the element be rendered for frontend
|
||||
*
|
||||
* Filters if the element should be rendered on frontend.
|
||||
*
|
||||
* @since 2.3.3
|
||||
*
|
||||
* @param bool true The element.
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
$should_render = apply_filters( "elementor/frontend/{$element_type}/should_render", $should_render, $this );
|
||||
|
||||
if ( $should_render ) {
|
||||
$this->_add_render_attributes();
|
||||
|
||||
$this->before_render();
|
||||
echo $content;
|
||||
$this->after_render();
|
||||
|
||||
$this->enqueue_scripts();
|
||||
$this->enqueue_styles();
|
||||
}
|
||||
|
||||
/**
|
||||
* After frontend element render.
|
||||
*
|
||||
* Fires after Elementor element is rendered in the frontend.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$element_type`, refers to the element type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
do_action( "elementor/frontend/{$element_type}/after_render", $this );
|
||||
|
||||
/**
|
||||
* After frontend element render.
|
||||
*
|
||||
* Fires after Elementor element is rendered in the frontend.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
do_action( 'elementor/frontend/after_render', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element raw data.
|
||||
*
|
||||
* Retrieve the raw element data, including the id, type, settings, child
|
||||
* elements and whether it is an inner element.
|
||||
*
|
||||
* The data with the HTML used always to display the data, but the Elementor
|
||||
* editor uses the raw data without the HTML in order not to render the data
|
||||
* again.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param bool $with_html_content Optional. Whether to return the data with
|
||||
* HTML content or without. Used for caching.
|
||||
* Default is false, without HTML.
|
||||
*
|
||||
* @return array Element raw data.
|
||||
*/
|
||||
public function get_raw_data( $with_html_content = false ) {
|
||||
$data = $this->get_data();
|
||||
|
||||
$elements = [];
|
||||
|
||||
foreach ( $this->get_children() as $child ) {
|
||||
$elements[] = $child->get_raw_data( $with_html_content );
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $this->get_id(),
|
||||
'elType' => $data['elType'],
|
||||
'settings' => $data['settings'],
|
||||
'elements' => $elements,
|
||||
'isInner' => $data['isInner'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get unique selector.
|
||||
*
|
||||
* Retrieve the unique selector of the element. Used to set a unique HTML
|
||||
* class for each HTML element. This way Elementor can set custom styles for
|
||||
* each element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Unique selector.
|
||||
*/
|
||||
public function get_unique_selector() {
|
||||
return '.elementor-element-' . $this->get_id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is type instance.
|
||||
*
|
||||
* Used to determine whether the element is an instance of that type or not.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether the element is an instance of that type.
|
||||
*/
|
||||
public function is_type_instance() {
|
||||
return $this->is_type_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add render attributes.
|
||||
*
|
||||
* Used to add attributes to the current element wrapper HTML tag.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _add_render_attributes() {
|
||||
$id = $this->get_id();
|
||||
|
||||
$settings = $this->get_settings_for_display();
|
||||
$frontend_settings = $this->get_frontend_settings();
|
||||
$controls = $this->get_controls();
|
||||
|
||||
$this->add_render_attribute( '_wrapper', [
|
||||
'class' => [
|
||||
'elementor-element',
|
||||
'elementor-element-' . $id,
|
||||
],
|
||||
'data-id' => $id,
|
||||
'data-element_type' => $this->get_type(),
|
||||
] );
|
||||
|
||||
$class_settings = [];
|
||||
|
||||
foreach ( $settings as $setting_key => $setting ) {
|
||||
if ( isset( $controls[ $setting_key ]['prefix_class'] ) ) {
|
||||
$class_settings[ $setting_key ] = $setting;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $class_settings as $setting_key => $setting ) {
|
||||
if ( empty( $setting ) && '0' !== $setting ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->add_render_attribute( '_wrapper', 'class', $controls[ $setting_key ]['prefix_class'] . $setting );
|
||||
}
|
||||
|
||||
if ( ! empty( $settings['animation'] ) || ! empty( $settings['_animation'] ) ) {
|
||||
$is_static_render_mode = Plugin::$instance->frontend->is_static_render_mode();
|
||||
|
||||
if ( ! $is_static_render_mode ) {
|
||||
// Hide the element until the animation begins
|
||||
$this->add_render_attribute( '_wrapper', 'class', 'elementor-invisible' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $settings['_element_id'] ) ) {
|
||||
$this->add_render_attribute( '_wrapper', 'id', trim( $settings['_element_id'] ) );
|
||||
}
|
||||
|
||||
if ( $frontend_settings ) {
|
||||
$this->add_render_attribute( '_wrapper', 'data-settings', wp_json_encode( $frontend_settings ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* After element attribute rendered.
|
||||
*
|
||||
* Fires after the attributes of the element HTML tag are rendered.
|
||||
*
|
||||
* @since 2.3.0
|
||||
*
|
||||
* @param Element_Base $this The element.
|
||||
*/
|
||||
do_action( 'elementor/element/after_add_attributes', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default data.
|
||||
*
|
||||
* Retrieve the default element data. Used to reset the data on initialization.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default data.
|
||||
*/
|
||||
protected function get_default_data() {
|
||||
$data = parent::get_default_data();
|
||||
|
||||
return array_merge(
|
||||
$data, [
|
||||
'elements' => [],
|
||||
'isInner' => false,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print element content.
|
||||
*
|
||||
* Output the element final HTML on the frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _print_content() {
|
||||
foreach ( $this->get_children() as $child ) {
|
||||
$child->print_element();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get initial config.
|
||||
*
|
||||
* Retrieve the current element initial configuration.
|
||||
*
|
||||
* Adds more configuration on top of the controls list and the tabs assigned
|
||||
* to the control. This method also adds element name, type, icon and more.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array The initial config.
|
||||
*/
|
||||
protected function get_initial_config() {
|
||||
$config = [
|
||||
'name' => $this->get_name(),
|
||||
'elType' => $this->get_type(),
|
||||
'title' => $this->get_title(),
|
||||
'icon' => $this->get_icon(),
|
||||
'reload_preview' => $this->is_reload_preview_required(),
|
||||
];
|
||||
|
||||
if ( preg_match( '/^' . __NAMESPACE__ . '(Pro)?\\\\/', get_called_class() ) ) {
|
||||
$config['help_url'] = $this->get_help_url();
|
||||
} else {
|
||||
$config['help_url'] = $this->get_custom_help_url();
|
||||
}
|
||||
|
||||
if ( ! $this->is_editable() ) {
|
||||
$config['editable'] = false;
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child type.
|
||||
*
|
||||
* Retrieve the element child type based on element data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $element_data Element ID.
|
||||
*
|
||||
* @return Element_Base|false Child type or false if type not found.
|
||||
*/
|
||||
private function get_child_type( $element_data ) {
|
||||
$child_type = $this->_get_default_child_type( $element_data );
|
||||
|
||||
// If it's not a valid widget ( like a deactivated plugin )
|
||||
if ( ! $child_type ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Element child type.
|
||||
*
|
||||
* Filters the child type of the element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Element_Base $child_type The child element.
|
||||
* @param array $element_data The original element ID.
|
||||
* @param Element_Base $this The original element.
|
||||
*/
|
||||
$child_type = apply_filters( 'elementor/element/get_child_type', $child_type, $element_data, $this );
|
||||
|
||||
return $child_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize children.
|
||||
*
|
||||
* Initializing the element child elements.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function init_children() {
|
||||
$this->children = [];
|
||||
|
||||
$children_data = $this->get_data( 'elements' );
|
||||
|
||||
if ( ! $children_data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $children_data as $child_data ) {
|
||||
if ( ! $child_data ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->add_child( $child_data );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Element base constructor.
|
||||
*
|
||||
* Initializing the element base class using `$data` and `$args`.
|
||||
*
|
||||
* The `$data` parameter is required for a normal instance because of the
|
||||
* way Elementor renders data when initializing elements.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Optional. Element data. Default is an empty array.
|
||||
* @param array|null $args Optional. Element default arguments. Default is null.
|
||||
**/
|
||||
public function __construct( array $data = [], array $args = null ) {
|
||||
if ( $data ) {
|
||||
$this->is_type_instance = false;
|
||||
} elseif ( $args ) {
|
||||
$this->default_args = $args;
|
||||
}
|
||||
|
||||
parent::__construct( $data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,249 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor skin base.
|
||||
*
|
||||
* An abstract class to register new skins for Elementor widgets. Skins allows
|
||||
* you to add new templates, set custom controls and more.
|
||||
*
|
||||
* To register new skins for your widget use the `add_skin()` method inside the
|
||||
* widget's `_register_skins()` method.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Skin_Base extends Sub_Controls_Stack {
|
||||
|
||||
/**
|
||||
* Parent widget.
|
||||
*
|
||||
* Holds the parent widget of the skin. Default value is null, no parent widget.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var Widget_Base|null
|
||||
*/
|
||||
protected $parent = null;
|
||||
|
||||
/**
|
||||
* Skin base constructor.
|
||||
*
|
||||
* Initializing the skin base class by setting parent widget and registering
|
||||
* controls actions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @param Widget_Base $parent
|
||||
*/
|
||||
public function __construct( Widget_Base $parent ) {
|
||||
parent::__construct( $parent );
|
||||
|
||||
$this->_register_controls_actions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render skin.
|
||||
*
|
||||
* Generates the final HTML on the frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function render();
|
||||
|
||||
/**
|
||||
* Register skin controls actions.
|
||||
*
|
||||
* Run on init and used to register new skins to be injected to the widget.
|
||||
* This method is used to register new actions that specify the location of
|
||||
* the skin in the widget.
|
||||
*
|
||||
* Example usage:
|
||||
* `add_action( 'elementor/element/{widget_id}/{section_id}/before_section_end', [ $this, 'register_controls' ] );`
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _register_controls_actions() {}
|
||||
|
||||
/**
|
||||
* Get skin control ID.
|
||||
*
|
||||
* Retrieve the skin control ID. Note that skin controls have special prefix
|
||||
* to distinguish them from regular controls, and from controls in other
|
||||
* skins.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $control_base_id Control base ID.
|
||||
*
|
||||
* @return string Control ID.
|
||||
*/
|
||||
protected function get_control_id( $control_base_id ) {
|
||||
$skin_id = str_replace( '-', '_', $this->get_id() );
|
||||
return $skin_id . '_' . $control_base_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get skin settings.
|
||||
*
|
||||
* Retrieve all the skin settings or, when requested, a specific setting.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @TODO: rename to get_setting() and create backward compatibility.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $control_base_id Control base ID.
|
||||
*
|
||||
* @return Widget_Base Widget instance.
|
||||
*/
|
||||
public function get_instance_value( $control_base_id ) {
|
||||
$control_id = $this->get_control_id( $control_base_id );
|
||||
return $this->parent->get_settings( $control_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls section.
|
||||
*
|
||||
* Used to add a new section of controls to the skin.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Section ID.
|
||||
* @param array $args Section arguments.
|
||||
*/
|
||||
public function start_controls_section( $id, $args = [] ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::start_controls_section( $id, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new skin control.
|
||||
*
|
||||
* Register a single control to the allow the user to set/update skin data.
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments.
|
||||
* @param array $options
|
||||
*
|
||||
* @return bool True if skin added, False otherwise.
|
||||
|
||||
* @since 3.0.0 New `$options` parameter added.
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function add_control( $id, $args = [], $options = [] ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
return parent::add_control( $id, $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update skin control.
|
||||
*
|
||||
* Change the value of an existing skin control.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @since 1.8.1 New `$options` parameter added.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments. Only the new fields you want to update.
|
||||
* @param array $options Optional. Some additional options.
|
||||
*/
|
||||
public function update_control( $id, $args, array $options = [] ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::update_control( $id, $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new responsive skin control.
|
||||
*
|
||||
* Register a set of controls to allow editing based on user screen size.
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
* @param array $args Responsive control arguments.
|
||||
* @param array $options
|
||||
*
|
||||
* @since 1.0.5
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function add_responsive_control( $id, $args, $options = [] ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::add_responsive_control( $id, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls tab.
|
||||
*
|
||||
* Used to add a new tab inside a group of tabs.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments.
|
||||
*/
|
||||
public function start_controls_tab( $id, $args ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::start_controls_tab( $id, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start skin controls tabs.
|
||||
*
|
||||
* Used to add a new set of tabs inside a section.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
*/
|
||||
public function start_controls_tabs( $id ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::start_controls_tabs( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new group control.
|
||||
*
|
||||
* Register a set of related controls grouped together as a single unified
|
||||
* control.
|
||||
*
|
||||
* @param string $group_name Group control name.
|
||||
* @param array $args Group control arguments. Default is an empty array.
|
||||
* @param array $options
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
final public function add_group_control( $group_name, $args = [], $options = [] ) {
|
||||
$args['condition']['_skin'] = $this->get_id();
|
||||
parent::add_group_control( $group_name, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set parent widget.
|
||||
*
|
||||
* Used to define the parent widget of the skin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Widget_Base $parent Parent widget.
|
||||
*/
|
||||
public function set_parent( $parent ) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor sub controls stack.
|
||||
*
|
||||
* An abstract class that can be used to divide a large ControlsStack into small parts.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Sub_Controls_Stack {
|
||||
/**
|
||||
* @var Controls_Stack
|
||||
*/
|
||||
protected $parent;
|
||||
|
||||
/**
|
||||
* Get self ID.
|
||||
*
|
||||
* Retrieve the self ID.
|
||||
*
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function get_id();
|
||||
|
||||
/**
|
||||
* Get self title.
|
||||
*
|
||||
* Retrieve the self title.
|
||||
*
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function get_title();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* Initializing the base class by setting parent stack.
|
||||
*
|
||||
* @access public
|
||||
* @param Controls_Stack $parent
|
||||
*/
|
||||
public function __construct( $parent ) {
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control ID.
|
||||
*
|
||||
* Retrieve the control ID. Note that the sub controls stack may have a special prefix
|
||||
* to distinguish them from regular controls, and from controls in other
|
||||
* sub stack.
|
||||
*
|
||||
* By default do nothing, and return the original id.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @param string $control_base_id Control base ID.
|
||||
*
|
||||
* @return string Control ID.
|
||||
*/
|
||||
protected function get_control_id( $control_base_id ) {
|
||||
return $control_base_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new control.
|
||||
*
|
||||
* Register a single control to allow the user to set/update data.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments.
|
||||
* @param array $options
|
||||
*
|
||||
* @return bool True if added, False otherwise.
|
||||
*/
|
||||
public function add_control( $id, $args, $options = [] ) {
|
||||
return $this->parent->add_control( $this->get_control_id( $id ), $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update control.
|
||||
*
|
||||
* Change the value of an existing control.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
* @param array $args Control arguments. Only the new fields you want to update.
|
||||
* @param array $options Optional. Some additional options.
|
||||
*/
|
||||
public function update_control( $id, $args, array $options = [] ) {
|
||||
$this->parent->update_control( $this->get_control_id( $id ), $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove control.
|
||||
*
|
||||
* Unregister an existing control.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
*/
|
||||
public function remove_control( $id ) {
|
||||
$this->parent->remove_control( $this->get_control_id( $id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new group control.
|
||||
*
|
||||
* Register a set of related controls grouped together as a single unified
|
||||
* control.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $group_name Group control name.
|
||||
* @param array $args Group control arguments. Default is an empty array.
|
||||
* @param array $options
|
||||
*
|
||||
*/
|
||||
public function add_group_control( $group_name, $args, $options = [] ) {
|
||||
$args['name'] = $this->get_control_id( $args['name'] );
|
||||
$this->parent->add_group_control( $group_name, $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new responsive control.
|
||||
*
|
||||
* Register a set of controls to allow editing based on user screen size.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
* @param array $args Responsive control arguments.
|
||||
* @param array $options
|
||||
*/
|
||||
public function add_responsive_control( $id, $args, $options = [] ) {
|
||||
$this->parent->add_responsive_control( $this->get_control_id( $id ), $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Update responsive control.
|
||||
*
|
||||
* Change the value of an existing responsive control.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
* @param array $args Responsive control arguments.
|
||||
*/
|
||||
public function update_responsive_control( $id, $args ) {
|
||||
$this->parent->update_responsive_control( $this->get_control_id( $id ), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove responsive control.
|
||||
*
|
||||
* Unregister an existing responsive control.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Responsive control ID.
|
||||
*/
|
||||
public function remove_responsive_control( $id ) {
|
||||
$this->parent->remove_responsive_control( $this->get_control_id( $id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Start controls section.
|
||||
*
|
||||
* Used to add a new section of controls to the stack.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Section ID.
|
||||
* @param array $args Section arguments.
|
||||
*/
|
||||
|
||||
public function start_controls_section( $id, $args = [] ) {
|
||||
$this->parent->start_controls_section( $this->get_control_id( $id ), $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* End controls section.
|
||||
*
|
||||
* Used to close an existing open controls section.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function end_controls_section() {
|
||||
$this->parent->end_controls_section();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start controls tabs.
|
||||
*
|
||||
* Used to add a new set of tabs inside a section.
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Control ID.
|
||||
*/
|
||||
public function start_controls_tabs( $id ) {
|
||||
$this->parent->start_controls_tabs( $this->get_control_id( $id ) );
|
||||
}
|
||||
|
||||
public function start_controls_tab( $id, $args ) {
|
||||
$this->parent->start_controls_tab( $this->get_control_id( $id ), $args );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* End controls tabs.
|
||||
*
|
||||
* Used to close an existing open controls tabs.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function end_controls_tab() {
|
||||
$this->parent->end_controls_tab();
|
||||
}
|
||||
|
||||
/**
|
||||
* End controls tabs.
|
||||
*
|
||||
* Used to close an existing open controls tabs.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function end_controls_tabs() {
|
||||
$this->parent->end_controls_tabs();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,887 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor widget base.
|
||||
*
|
||||
* An abstract class to register new Elementor widgets. It extended the
|
||||
* `Element_Base` class to inherit its properties.
|
||||
*
|
||||
* This abstract class must be extended in order to register new widgets.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Widget_Base extends Element_Base {
|
||||
|
||||
/**
|
||||
* Whether the widget has content.
|
||||
*
|
||||
* Used in cases where the widget has no content. When widgets uses only
|
||||
* skins to display dynamic content generated on the server. For example the
|
||||
* posts widget in Elementor Pro. Default is true, the widget has content
|
||||
* template.
|
||||
*
|
||||
* @access protected
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $_has_template_content = true;
|
||||
|
||||
/**
|
||||
* Get element type.
|
||||
*
|
||||
* Retrieve the element type, in this case `widget`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string The type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'widget';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget icon.
|
||||
*
|
||||
* Retrieve the widget icon.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Widget icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
return 'eicon-apps';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget keywords.
|
||||
*
|
||||
* Retrieve the widget keywords.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @return array Widget keywords.
|
||||
*/
|
||||
public function get_keywords() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget categories.
|
||||
*
|
||||
* Retrieve the widget categories.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @return array Widget categories.
|
||||
*/
|
||||
public function get_categories() {
|
||||
return [ 'general' ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Widget base constructor.
|
||||
*
|
||||
* Initializing the widget base class.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @throws \Exception If arguments are missing when initializing a full widget
|
||||
* instance.
|
||||
*
|
||||
* @param array $data Widget data. Default is an empty array.
|
||||
* @param array|null $args Optional. Widget default arguments. Default is null.
|
||||
*/
|
||||
public function __construct( $data = [], $args = null ) {
|
||||
parent::__construct( $data, $args );
|
||||
|
||||
$is_type_instance = $this->is_type_instance();
|
||||
|
||||
if ( ! $is_type_instance && null === $args ) {
|
||||
throw new \Exception( '`$args` argument is required when initializing a full widget instance.' );
|
||||
}
|
||||
|
||||
if ( $is_type_instance ) {
|
||||
$this->_register_skins();
|
||||
|
||||
$widget_name = $this->get_name();
|
||||
/**
|
||||
* Widget skin init.
|
||||
*
|
||||
* Fires when Elementor widget is being initialized.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$widget_name`, refers to the widget name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Widget_Base $this The current widget.
|
||||
*/
|
||||
do_action( "elementor/widget/{$widget_name}/skins_init", $this );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stack.
|
||||
*
|
||||
* Retrieve the widget stack of controls.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @param bool $with_common_controls Optional. Whether to include the common controls. Default is true.
|
||||
*
|
||||
* @return array Widget stack of controls.
|
||||
*/
|
||||
public function get_stack( $with_common_controls = true ) {
|
||||
$stack = parent::get_stack();
|
||||
|
||||
if ( $with_common_controls && 'common' !== $this->get_unique_name() ) {
|
||||
/** @var Widget_Common $common_widget */
|
||||
$common_widget = Plugin::$instance->widgets_manager->get_widget_types( 'common' );
|
||||
|
||||
$stack['controls'] = array_merge( $stack['controls'], $common_widget->get_controls() );
|
||||
|
||||
$stack['tabs'] = array_merge( $stack['tabs'], $common_widget->get_tabs_controls() );
|
||||
}
|
||||
|
||||
return $stack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget controls pointer index.
|
||||
*
|
||||
* Retrieve widget pointer index where the next control should be added.
|
||||
*
|
||||
* While using injection point, it will return the injection point index. Otherwise index of the last control of the
|
||||
* current widget itself without the common controls, plus one.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @return int Widget controls pointer index.
|
||||
*/
|
||||
public function get_pointer_index() {
|
||||
$injection_point = $this->get_injection_point();
|
||||
|
||||
if ( null !== $injection_point ) {
|
||||
return $injection_point['index'];
|
||||
}
|
||||
|
||||
return count( $this->get_stack( false )['controls'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show in panel.
|
||||
*
|
||||
* Whether to show the widget in the panel or not. By default returns true.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return bool Whether to show the widget in the panel or not.
|
||||
*/
|
||||
public function show_in_panel() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start widget controls section.
|
||||
*
|
||||
* Used to add a new section of controls to the widget. Regular controls and
|
||||
* skin controls.
|
||||
*
|
||||
* Note that when you add new controls to widgets they must be wrapped by
|
||||
* `start_controls_section()` and `end_controls_section()`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $section_id Section ID.
|
||||
* @param array $args Section arguments Optional.
|
||||
*/
|
||||
public function start_controls_section( $section_id, array $args = [] ) {
|
||||
parent::start_controls_section( $section_id, $args );
|
||||
|
||||
static $is_first_section = true;
|
||||
|
||||
if ( $is_first_section ) {
|
||||
$this->register_skin_control();
|
||||
|
||||
$is_first_section = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register the Skin Control if the widget has skins.
|
||||
*
|
||||
* An internal method that is used to add a skin control to the widget.
|
||||
* Added at the top of the controls section.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function register_skin_control() {
|
||||
$skins = $this->get_skins();
|
||||
if ( ! empty( $skins ) ) {
|
||||
$skin_options = [];
|
||||
|
||||
if ( $this->_has_template_content ) {
|
||||
$skin_options[''] = __( 'Default', 'elementor' );
|
||||
}
|
||||
|
||||
foreach ( $skins as $skin_id => $skin ) {
|
||||
$skin_options[ $skin_id ] = $skin->get_title();
|
||||
}
|
||||
|
||||
// Get the first item for default value
|
||||
$default_value = array_keys( $skin_options );
|
||||
$default_value = array_shift( $default_value );
|
||||
|
||||
if ( 1 >= count( $skin_options ) ) {
|
||||
$this->add_control(
|
||||
'_skin',
|
||||
[
|
||||
'label' => __( 'Skin', 'elementor' ),
|
||||
'type' => Controls_Manager::HIDDEN,
|
||||
'default' => $default_value,
|
||||
]
|
||||
);
|
||||
} else {
|
||||
$this->add_control(
|
||||
'_skin',
|
||||
[
|
||||
'label' => __( 'Skin', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => $default_value,
|
||||
'options' => $skin_options,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widget skins.
|
||||
*
|
||||
* This method is activated while initializing the widget base class. It is
|
||||
* used to assign skins to widgets with `add_skin()` method.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* protected function _register_skins() {
|
||||
* $this->add_skin( new Skin_Classic( $this ) );
|
||||
* }
|
||||
*
|
||||
* @since 1.7.12
|
||||
* @access protected
|
||||
*/
|
||||
protected function _register_skins() {}
|
||||
|
||||
/**
|
||||
* Get initial config.
|
||||
*
|
||||
* Retrieve the current widget initial configuration.
|
||||
*
|
||||
* Adds more configuration on top of the controls list, the tabs assigned to
|
||||
* the control, element name, type, icon and more. This method also adds
|
||||
* widget type, keywords and categories.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array The initial widget config.
|
||||
*/
|
||||
protected function get_initial_config() {
|
||||
$config = [
|
||||
'widget_type' => $this->get_name(),
|
||||
'keywords' => $this->get_keywords(),
|
||||
'categories' => $this->get_categories(),
|
||||
'html_wrapper_class' => $this->get_html_wrapper_class(),
|
||||
'show_in_panel' => $this->show_in_panel(),
|
||||
];
|
||||
|
||||
$stack = Plugin::$instance->controls_manager->get_element_stack( $this );
|
||||
|
||||
if ( $stack ) {
|
||||
$config['controls'] = $this->get_stack( false )['controls'];
|
||||
$config['tabs_controls'] = $this->get_tabs_controls();
|
||||
}
|
||||
|
||||
return array_merge( parent::get_initial_config(), $config );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.1
|
||||
* @access protected
|
||||
*/
|
||||
protected function should_print_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print widget content template.
|
||||
*
|
||||
* Used to generate the widget content template on the editor, using a
|
||||
* Backbone JavaScript template.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $template_content Template content.
|
||||
*/
|
||||
protected function print_template_content( $template_content ) {
|
||||
?>
|
||||
<div class="elementor-widget-container">
|
||||
<?php
|
||||
echo $template_content; // XSS ok.
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse text editor.
|
||||
*
|
||||
* Parses the content from rich text editor with shortcodes, oEmbed and
|
||||
* filtered data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $content Text editor content.
|
||||
*
|
||||
* @return string Parsed content.
|
||||
*/
|
||||
protected function parse_text_editor( $content ) {
|
||||
/** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */
|
||||
$content = apply_filters( 'widget_text', $content, $this->get_settings() );
|
||||
|
||||
$content = shortcode_unautop( $content );
|
||||
$content = do_shortcode( $content );
|
||||
$content = wptexturize( $content );
|
||||
|
||||
if ( $GLOBALS['wp_embed'] instanceof \WP_Embed ) {
|
||||
$content = $GLOBALS['wp_embed']->autoembed( $content );
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTML wrapper class.
|
||||
*
|
||||
* Retrieve the widget container class. Can be used to override the
|
||||
* container class for specific widgets.
|
||||
*
|
||||
* @since 2.0.9
|
||||
* @access protected
|
||||
*/
|
||||
protected function get_html_wrapper_class() {
|
||||
return 'elementor-widget-' . $this->get_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add widget render attributes.
|
||||
*
|
||||
* Used to add attributes to the current widget wrapper HTML tag.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _add_render_attributes() {
|
||||
parent::_add_render_attributes();
|
||||
|
||||
$this->add_render_attribute(
|
||||
'_wrapper', 'class', [
|
||||
'elementor-widget',
|
||||
$this->get_html_wrapper_class(),
|
||||
]
|
||||
);
|
||||
|
||||
$settings = $this->get_settings();
|
||||
|
||||
$this->add_render_attribute( '_wrapper', 'data-widget_type', $this->get_name() . '.' . ( ! empty( $settings['_skin'] ) ? $settings['_skin'] : 'default' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add lightbox data to image link.
|
||||
*
|
||||
* Used to add lightbox data attributes to image link HTML.
|
||||
*
|
||||
* @since 2.9.1
|
||||
* @access public
|
||||
*
|
||||
* @param string $link_html Image link HTML.
|
||||
* @param string $id Attachment id.
|
||||
*
|
||||
* @return string Image link HTML with lightbox data attributes.
|
||||
*/
|
||||
public function add_lightbox_data_to_image_link( $link_html, $id ) {
|
||||
$settings = $this->get_settings_for_display();
|
||||
$open_lightbox = isset( $settings['open_lightbox'] ) ? $settings['open_lightbox'] : null;
|
||||
|
||||
if ( Plugin::$instance->editor->is_edit_mode() ) {
|
||||
$this->add_render_attribute( 'link', 'class', 'elementor-clickable', true );
|
||||
}
|
||||
|
||||
$this->add_lightbox_data_attributes( 'link', $id, $open_lightbox, $this->get_id(), true );
|
||||
return preg_replace( '/^<a/', '<a ' . $this->get_render_attribute_string( 'link' ), $link_html );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Light-Box attributes.
|
||||
*
|
||||
* Used to add Light-Box-related data attributes to links that open media files.
|
||||
*
|
||||
* @param array|string $element The link HTML element.
|
||||
* @param int $id The ID of the image
|
||||
* @param string $lightbox_setting_key The setting key that dictates weather to open the image in a lightbox
|
||||
* @param string $group_id Unique ID for a group of lightbox images
|
||||
* @param bool $overwrite Optional. Whether to overwrite existing
|
||||
* attribute. Default is false, not to overwrite.
|
||||
*
|
||||
* @return Widget_Base Current instance of the widget.
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
*/
|
||||
public function add_lightbox_data_attributes( $element, $id = null, $lightbox_setting_key = null, $group_id = null, $overwrite = false ) {
|
||||
$kit = Plugin::$instance->kits_manager->get_active_kit();
|
||||
|
||||
$is_global_image_lightbox_enabled = 'yes' === $kit->get_settings( 'global_image_lightbox' );
|
||||
|
||||
if ( 'no' === $lightbox_setting_key ) {
|
||||
if ( $is_global_image_lightbox_enabled ) {
|
||||
$this->add_render_attribute( $element, 'data-elementor-open-lightbox', 'no' );
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
if ( 'yes' !== $lightbox_setting_key && ! $is_global_image_lightbox_enabled ) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
$attributes['data-elementor-open-lightbox'] = 'yes';
|
||||
|
||||
if ( $group_id ) {
|
||||
$attributes['data-elementor-lightbox-slideshow'] = $group_id;
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
$lightbox_image_attributes = Plugin::$instance->images_manager->get_lightbox_image_attributes( $id );
|
||||
|
||||
if ( isset( $lightbox_image_attributes['title'] ) ) {
|
||||
$attributes['data-elementor-lightbox-title'] = $lightbox_image_attributes['title'];
|
||||
}
|
||||
|
||||
if ( isset( $lightbox_image_attributes['description'] ) ) {
|
||||
$attributes['data-elementor-lightbox-description'] = $lightbox_image_attributes['description'];
|
||||
}
|
||||
}
|
||||
|
||||
$this->add_render_attribute( $element, $attributes, null, $overwrite );
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widget output on the frontend.
|
||||
*
|
||||
* Used to generate the final HTML displayed on the frontend.
|
||||
*
|
||||
* Note that if skin is selected, it will be rendered by the skin itself,
|
||||
* not the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render_content() {
|
||||
/**
|
||||
* Before widget render content.
|
||||
*
|
||||
* Fires before Elementor widget is being rendered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Widget_Base $this The current widget.
|
||||
*/
|
||||
do_action( 'elementor/widget/before_render_content', $this );
|
||||
|
||||
ob_start();
|
||||
|
||||
$skin = $this->get_current_skin();
|
||||
if ( $skin ) {
|
||||
$skin->set_parent( $this );
|
||||
$skin->render();
|
||||
} else {
|
||||
$this->render();
|
||||
}
|
||||
|
||||
$widget_content = ob_get_clean();
|
||||
|
||||
if ( empty( $widget_content ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div class="elementor-widget-container">
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Render widget content.
|
||||
*
|
||||
* Filters the widget content before it's rendered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param string $widget_content The content of the widget.
|
||||
* @param Widget_Base $this The widget.
|
||||
*/
|
||||
$widget_content = apply_filters( 'elementor/widget/render_content', $widget_content, $this );
|
||||
|
||||
echo $widget_content; // XSS ok.
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widget plain content.
|
||||
*
|
||||
* Elementor saves the page content in a unique way, but it's not the way
|
||||
* WordPress saves data. This method is used to save generated HTML to the
|
||||
* database as plain content the WordPress way.
|
||||
*
|
||||
* When rendering plain content, it allows other WordPress plugins to
|
||||
* interact with the content - to search, check SEO and other purposes. It
|
||||
* also allows the site to keep working even if Elementor is deactivated.
|
||||
*
|
||||
* Note that if the widget uses shortcodes to display the data, the best
|
||||
* practice is to return the shortcode itself.
|
||||
*
|
||||
* Also note that if the widget don't display any content it should return
|
||||
* an empty string. For example Elementor Pro Form Widget uses this method
|
||||
* to return an empty string because there is no content to return. This way
|
||||
* if Elementor Pro will be deactivated there won't be any form to display.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render_plain_content() {
|
||||
$this->render_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Before widget rendering.
|
||||
*
|
||||
* Used to add stuff before the widget `_wrapper` element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function before_render() {
|
||||
?>
|
||||
<div <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* After widget rendering.
|
||||
*
|
||||
* Used to add stuff after the widget `_wrapper` element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function after_render() {
|
||||
?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the element raw data.
|
||||
*
|
||||
* Retrieve the raw element data, including the id, type, settings, child
|
||||
* elements and whether it is an inner element.
|
||||
*
|
||||
* The data with the HTML used always to display the data, but the Elementor
|
||||
* editor uses the raw data without the HTML in order not to render the data
|
||||
* again.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param bool $with_html_content Optional. Whether to return the data with
|
||||
* HTML content or without. Used for caching.
|
||||
* Default is false, without HTML.
|
||||
*
|
||||
* @return array Element raw data.
|
||||
*/
|
||||
public function get_raw_data( $with_html_content = false ) {
|
||||
$data = parent::get_raw_data( $with_html_content );
|
||||
|
||||
unset( $data['isInner'] );
|
||||
|
||||
$data['widgetType'] = $this->get_data( 'widgetType' );
|
||||
|
||||
if ( $with_html_content ) {
|
||||
ob_start();
|
||||
|
||||
$this->render_content();
|
||||
|
||||
$data['htmlCache'] = ob_get_clean();
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print widget content.
|
||||
*
|
||||
* Output the widget final HTML on the frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function _print_content() {
|
||||
$this->render_content();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default data.
|
||||
*
|
||||
* Retrieve the default widget data. Used to reset the data on initialization.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default data.
|
||||
*/
|
||||
protected function get_default_data() {
|
||||
$data = parent::get_default_data();
|
||||
|
||||
$data['widgetType'] = '';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default child type.
|
||||
*
|
||||
* Retrieve the widget child type based on element data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $element_data Widget ID.
|
||||
*
|
||||
* @return array|false Child type or false if it's not a valid widget.
|
||||
*/
|
||||
protected function _get_default_child_type( array $element_data ) {
|
||||
return Plugin::$instance->elements_manager->get_element_types( 'section' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater setting key.
|
||||
*
|
||||
* Retrieve the unique setting key for the current repeater item. Used to connect the current element in the
|
||||
* repeater to it's settings model and it's control in the panel.
|
||||
*
|
||||
* PHP usage (inside `Widget_Base::render()` method):
|
||||
*
|
||||
* $tabs = $this->get_settings( 'tabs' );
|
||||
* foreach ( $tabs as $index => $item ) {
|
||||
* $tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
|
||||
* $this->add_inline_editing_attributes( $tab_title_setting_key, 'none' );
|
||||
* echo '<div ' . $this->get_render_attribute_string( $tab_title_setting_key ) . '>' . $item['tab_title'] . '</div>';
|
||||
* }
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
|
||||
* @param string $repeater_key The repeater key containing the array of all the items in the repeater (e.g. `tabs`).
|
||||
* @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
|
||||
*
|
||||
* @return string The repeater setting key (e.g. `tabs.3.tab_title`).
|
||||
*/
|
||||
protected function get_repeater_setting_key( $setting_key, $repeater_key, $repeater_item_index ) {
|
||||
return implode( '.', [ $repeater_key, $repeater_item_index, $setting_key ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add inline editing attributes.
|
||||
*
|
||||
* Define specific area in the element to be editable inline. The element can have several areas, with this method
|
||||
* you can set the area inside the element that can be edited inline. You can also define the type of toolbar the
|
||||
* user will see, whether it will be a basic toolbar or an advanced one.
|
||||
*
|
||||
* Note: When you use wysiwyg control use the advanced toolbar, with textarea control use the basic toolbar. Text
|
||||
* control should not have toolbar.
|
||||
*
|
||||
* PHP usage (inside `Widget_Base::render()` method):
|
||||
*
|
||||
* $this->add_inline_editing_attributes( 'text', 'advanced' );
|
||||
* echo '<div ' . $this->get_render_attribute_string( 'text' ) . '>' . $this->get_settings( 'text' ) . '</div>';
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $key Element key.
|
||||
* @param string $toolbar Optional. Toolbar type. Accepted values are `advanced`, `basic` or `none`. Default is
|
||||
* `basic`.
|
||||
*/
|
||||
protected function add_inline_editing_attributes( $key, $toolbar = 'basic' ) {
|
||||
if ( ! Plugin::$instance->editor->is_edit_mode() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->add_render_attribute( $key, [
|
||||
'class' => 'elementor-inline-editing',
|
||||
'data-elementor-setting-key' => $key,
|
||||
] );
|
||||
|
||||
if ( 'basic' !== $toolbar ) {
|
||||
$this->add_render_attribute( $key, [
|
||||
'data-elementor-inline-editing-toolbar' => $toolbar,
|
||||
] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new skin.
|
||||
*
|
||||
* Register new widget skin to allow the user to set custom designs. Must be
|
||||
* called inside the `_register_skins()` method.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Skin_Base $skin Skin instance.
|
||||
*/
|
||||
public function add_skin( Skin_Base $skin ) {
|
||||
Plugin::$instance->skins_manager->add_skin( $this, $skin );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get single skin.
|
||||
*
|
||||
* Retrieve a single skin based on skin ID, from all the skin assigned to
|
||||
* the widget. If the skin does not exist or not assigned to the widget,
|
||||
* return false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $skin_id Skin ID.
|
||||
*
|
||||
* @return string|false Single skin, or false.
|
||||
*/
|
||||
public function get_skin( $skin_id ) {
|
||||
$skins = $this->get_skins();
|
||||
if ( isset( $skins[ $skin_id ] ) ) {
|
||||
return $skins[ $skin_id ];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current skin ID.
|
||||
*
|
||||
* Retrieve the ID of the current skin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Current skin.
|
||||
*/
|
||||
public function get_current_skin_id() {
|
||||
return $this->get_settings( '_skin' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current skin.
|
||||
*
|
||||
* Retrieve the current skin, or if non exist return false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return Skin_Base|false Current skin or false.
|
||||
*/
|
||||
public function get_current_skin() {
|
||||
return $this->get_skin( $this->get_current_skin_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove widget skin.
|
||||
*
|
||||
* Unregister an existing skin and remove it from the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $skin_id Skin ID.
|
||||
*
|
||||
* @return \WP_Error|true Whether the skin was removed successfully from the widget.
|
||||
*/
|
||||
public function remove_skin( $skin_id ) {
|
||||
return Plugin::$instance->skins_manager->remove_skin( $this, $skin_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget skins.
|
||||
*
|
||||
* Retrieve all the skin assigned to the widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return Skin_Base[]
|
||||
*/
|
||||
public function get_skins() {
|
||||
return Plugin::$instance->skins_manager->get_skins( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $plugin_title Plugin's title
|
||||
* @param string $since Plugin version widget was deprecated
|
||||
* @param string $last Plugin version in which the widget will be removed
|
||||
* @param string $replacement Widget replacement
|
||||
*/
|
||||
protected function deprecated_notice( $plugin_title, $since, $last = '', $replacement = '' ) {
|
||||
$this->start_controls_section( 'Deprecated',
|
||||
[
|
||||
'label' => __( 'Deprecated', 'elementor' ),
|
||||
]
|
||||
);
|
||||
|
||||
$this->add_control(
|
||||
'deprecated_notice',
|
||||
[
|
||||
'type' => Controls_Manager::DEPRECATED_NOTICE,
|
||||
'widget' => $this->get_title(),
|
||||
'since' => $since,
|
||||
'last' => $last,
|
||||
'plugin' => $plugin_title,
|
||||
'replacement' => $replacement,
|
||||
]
|
||||
);
|
||||
|
||||
$this->end_controls_section();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor beta testers.
|
||||
*
|
||||
* Elementor beta testers handler class is responsible for the Beta Testers
|
||||
* feature that allows developers to test Elementor beta versions.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class Beta_Testers {
|
||||
|
||||
const NEWSLETTER_TERMS_URL = 'https://go.elementor.com/beta-testers-newsletter-terms';
|
||||
|
||||
const NEWSLETTER_PRIVACY_URL = 'https://go.elementor.com/beta-testers-newsletter-privacy';
|
||||
|
||||
const BETA_TESTER_SIGNUP = 'beta_tester_signup';
|
||||
|
||||
/**
|
||||
* Transient key.
|
||||
*
|
||||
* Holds the Elementor beta testers transient key.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var string Transient key.
|
||||
*/
|
||||
private $transient_key;
|
||||
|
||||
/**
|
||||
* Get beta version.
|
||||
*
|
||||
* Retrieve Elementor beta version from wp.org plugin repository.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
*
|
||||
* @return string|false Beta version or false.
|
||||
*/
|
||||
private function get_beta_version() {
|
||||
$beta_version = get_site_transient( $this->transient_key );
|
||||
|
||||
if ( false === $beta_version ) {
|
||||
$beta_version = 'false';
|
||||
|
||||
$response = wp_remote_get( 'https://plugins.svn.wordpress.org/elementor/trunk/readme.txt' );
|
||||
|
||||
if ( ! is_wp_error( $response ) && ! empty( $response['body'] ) ) {
|
||||
preg_match( '/Beta tag: (.*)/i', $response['body'], $matches );
|
||||
if ( isset( $matches[1] ) ) {
|
||||
$beta_version = $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
set_site_transient( $this->transient_key, $beta_version, 6 * HOUR_IN_SECONDS );
|
||||
}
|
||||
|
||||
return $beta_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check version.
|
||||
*
|
||||
* Checks whether a beta version exist, and retrieve the version data.
|
||||
*
|
||||
* Fired by `pre_set_site_transient_update_plugins` filter, before WordPress
|
||||
* runs the plugin update checker.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $transient Plugin version data.
|
||||
*
|
||||
* @return array Plugin version data.
|
||||
*/
|
||||
public function check_version( $transient ) {
|
||||
if ( empty( $transient->checked ) ) {
|
||||
return $transient;
|
||||
}
|
||||
|
||||
delete_site_transient( $this->transient_key );
|
||||
|
||||
$plugin_slug = basename( ELEMENTOR__FILE__, '.php' );
|
||||
|
||||
$beta_version = $this->get_beta_version();
|
||||
if ( 'false' !== $beta_version && version_compare( $beta_version, ELEMENTOR_VERSION, '>' ) ) {
|
||||
$response = new \stdClass();
|
||||
$response->plugin = $plugin_slug;
|
||||
$response->slug = $plugin_slug;
|
||||
$response->new_version = $beta_version;
|
||||
$response->url = 'https://elementor.com/';
|
||||
$response->package = sprintf( 'https://downloads.wordpress.org/plugin/elementor.%s.zip', $beta_version );
|
||||
|
||||
$transient->response[ ELEMENTOR_PLUGIN_BASE ] = $response;
|
||||
}
|
||||
|
||||
return $transient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Beta testers constructor.
|
||||
*
|
||||
* Initializing Elementor beta testers.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( 'yes' !== get_option( 'elementor_beta', 'no' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->transient_key = md5( 'elementor_beta_testers_response_key' );
|
||||
|
||||
add_filter( 'pre_set_site_transient_update_plugins', [ $this, 'check_version' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,398 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\DocumentTypes\PageBase;
|
||||
use Elementor\TemplateLibrary\Source_Local;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor compatibility.
|
||||
*
|
||||
* Elementor compatibility handler class is responsible for compatibility with
|
||||
* external plugins. The class resolves different issues with non-compatible
|
||||
* plugins.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Compatibility {
|
||||
|
||||
/**
|
||||
* Register actions.
|
||||
*
|
||||
* Run Elementor compatibility with external plugins using custom filters and
|
||||
* actions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function register_actions() {
|
||||
add_action( 'init', [ __CLASS__, 'init' ] );
|
||||
|
||||
self::polylang_compatibility();
|
||||
|
||||
if ( is_admin() || defined( 'WP_LOAD_IMPORTERS' ) ) {
|
||||
add_filter( 'wp_import_post_meta', [ __CLASS__, 'on_wp_import_post_meta' ] );
|
||||
add_filter( 'wxr_importer.pre_process.post_meta', [ __CLASS__, 'on_wxr_importer_pre_process_post_meta' ] );
|
||||
}
|
||||
|
||||
add_action( 'elementor/maintenance_mode/mode_changed', [ __CLASS__, 'clear_3rd_party_cache' ] );
|
||||
|
||||
add_action( 'elementor/element/before_section_start', [ __CLASS__, 'document_post_deprecated_hooks' ], 10, 3 );
|
||||
add_action( 'elementor/element/after_section_start', [ __CLASS__, 'document_post_deprecated_hooks' ], 10, 3 );
|
||||
add_action( 'elementor/element/before_section_end', [ __CLASS__, 'document_post_deprecated_hooks' ], 10, 3 );
|
||||
add_action( 'elementor/element/after_section_end', [ __CLASS__, 'document_post_deprecated_hooks' ], 10, 3 );
|
||||
}
|
||||
|
||||
public static function document_post_deprecated_hooks( $instance, $section_id, $args ) {
|
||||
if ( ! $instance instanceof PageBase ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$current_action = current_action();
|
||||
$current_action = explode( '/', $current_action );
|
||||
$current_sub_action = $current_action[2];
|
||||
|
||||
$deprecated_action = "elementor/element/post/{$section_id}/{$current_sub_action}";
|
||||
|
||||
if ( ! has_action( $deprecated_action ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Hard deprecation on 3.1.0.
|
||||
// $replacement = "`elementor/element/wp-post/{$section_id}/{$current_sub_action}` or `elementor/element/wp-page/{$section_id}/{$current_sub_action}`";
|
||||
// _deprecated_hook( $deprecated_action, '2.7.0', $replacement );
|
||||
|
||||
do_action( $deprecated_action, $instance, $section_id, $args );
|
||||
}
|
||||
|
||||
public static function clear_3rd_party_cache() {
|
||||
// W3 Total Cache.
|
||||
if ( function_exists( 'w3tc_flush_all' ) ) {
|
||||
w3tc_flush_all();
|
||||
}
|
||||
|
||||
// WP Fastest Cache.
|
||||
if ( ! empty( $GLOBALS['wp_fastest_cache'] ) && method_exists( $GLOBALS['wp_fastest_cache'], 'deleteCache' ) ) {
|
||||
$GLOBALS['wp_fastest_cache']->deleteCache();
|
||||
}
|
||||
|
||||
// WP Super Cache
|
||||
if ( function_exists( 'wp_cache_clean_cache' ) ) {
|
||||
global $file_prefix;
|
||||
wp_cache_clean_cache( $file_prefix, true );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new button to gutenberg.
|
||||
*
|
||||
* Insert new "Elementor" button to the gutenberg editor to create new post
|
||||
* using Elementor page builder.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function add_new_button_to_gutenberg() {
|
||||
global $typenow;
|
||||
if ( ! User::is_current_user_can_edit_post_type( $typenow ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Introduced in WP 5.0
|
||||
if ( function_exists( 'use_block_editor_for_post' ) && ! use_block_editor_for_post( $typenow ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Deprecated/removed in Gutenberg plugin v5.3.0
|
||||
if ( function_exists( 'gutenberg_can_edit_post_type' ) && ! gutenberg_can_edit_post_type( $typenow ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
document.addEventListener( 'DOMContentLoaded', function() {
|
||||
var dropdown = document.querySelector( '#split-page-title-action .dropdown' );
|
||||
|
||||
if ( ! dropdown ) {
|
||||
return;
|
||||
}
|
||||
|
||||
var url = '<?php echo esc_url( Utils::get_create_new_post_url( $typenow ) ); ?>';
|
||||
|
||||
dropdown.insertAdjacentHTML( 'afterbegin', '<a href="' + url + '">Elementor</a>' );
|
||||
} );
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor compatibility with external plugins.
|
||||
*
|
||||
* Fired by `init` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function init() {
|
||||
// Hotfix for NextGEN Gallery plugin.
|
||||
if ( defined( 'NGG_PLUGIN_VERSION' ) ) {
|
||||
add_filter( 'elementor/document/urls/edit', function( $edit_link ) {
|
||||
return add_query_arg( 'display_gallery_iframe', '', $edit_link );
|
||||
} );
|
||||
}
|
||||
|
||||
// Exclude our Library from Yoast SEO plugin.
|
||||
add_filter( 'wpseo_sitemaps_supported_post_types', [ __CLASS__, 'filter_library_post_type' ] );
|
||||
add_filter( 'wpseo_accessible_post_types', [ __CLASS__, 'filter_library_post_type' ] );
|
||||
add_filter( 'wpseo_sitemap_exclude_post_type', function( $retval, $post_type ) {
|
||||
if ( Source_Local::CPT === $post_type ) {
|
||||
$retval = true;
|
||||
}
|
||||
|
||||
return $retval;
|
||||
}, 10, 2 );
|
||||
|
||||
// Disable optimize files in Editor from Autoptimize plugin.
|
||||
add_filter( 'autoptimize_filter_noptimize', function( $retval ) {
|
||||
if ( Plugin::$instance->editor->is_edit_mode() ) {
|
||||
$retval = true;
|
||||
}
|
||||
|
||||
return $retval;
|
||||
} );
|
||||
|
||||
// Add the description (content) tab for a new product, so it can be edited with Elementor.
|
||||
add_filter( 'woocommerce_product_tabs', function( $tabs ) {
|
||||
if ( ! isset( $tabs['description'] ) && Plugin::$instance->preview->is_preview_mode() ) {
|
||||
$post = get_post();
|
||||
if ( empty( $post->post_content ) ) {
|
||||
$tabs['description'] = [
|
||||
'title' => __( 'Description', 'elementor' ),
|
||||
'priority' => 10,
|
||||
'callback' => 'woocommerce_product_description_tab',
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
} );
|
||||
|
||||
// Fix WC session not defined in editor.
|
||||
if ( class_exists( 'woocommerce' ) ) {
|
||||
add_action( 'elementor/editor/before_enqueue_scripts', function() {
|
||||
remove_action( 'woocommerce_shortcode_before_product_cat_loop', 'wc_print_notices' );
|
||||
remove_action( 'woocommerce_before_shop_loop', 'wc_print_notices' );
|
||||
remove_action( 'woocommerce_before_single_product', 'wc_print_notices' );
|
||||
} );
|
||||
|
||||
add_filter( 'elementor/maintenance_mode/is_login_page', function( $value ) {
|
||||
|
||||
// Support Woocommerce Account Page.
|
||||
if ( is_account_page() && ! is_user_logged_in() ) {
|
||||
$value = true;
|
||||
}
|
||||
return $value;
|
||||
} );
|
||||
}
|
||||
|
||||
// Fix Jetpack Contact Form in Editor Mode.
|
||||
if ( class_exists( 'Grunion_Editor_View' ) ) {
|
||||
add_action( 'elementor/editor/before_enqueue_scripts', function() {
|
||||
remove_action( 'media_buttons', 'grunion_media_button', 999 );
|
||||
remove_action( 'admin_enqueue_scripts', 'grunion_enable_spam_recheck' );
|
||||
|
||||
remove_action( 'admin_notices', [ 'Grunion_Editor_View', 'handle_editor_view_js' ] );
|
||||
remove_action( 'admin_head', [ 'Grunion_Editor_View', 'admin_head' ] );
|
||||
} );
|
||||
}
|
||||
|
||||
// Fix Popup Maker in Editor Mode.
|
||||
if ( class_exists( 'PUM_Admin_Shortcode_UI' ) ) {
|
||||
add_action( 'elementor/editor/before_enqueue_scripts', function() {
|
||||
$pum_admin_instance = \PUM_Admin_Shortcode_UI::instance();
|
||||
|
||||
remove_action( 'print_media_templates', [ $pum_admin_instance, 'print_media_templates' ] );
|
||||
remove_action( 'admin_print_footer_scripts', [ $pum_admin_instance, 'admin_print_footer_scripts' ], 100 );
|
||||
remove_action( 'wp_ajax_pum_do_shortcode', [ $pum_admin_instance, 'wp_ajax_pum_do_shortcode' ] );
|
||||
|
||||
remove_action( 'admin_enqueue_scripts', [ $pum_admin_instance, 'admin_enqueue_scripts' ] );
|
||||
|
||||
remove_filter( 'pum_admin_var', [ $pum_admin_instance, 'pum_admin_var' ] );
|
||||
} );
|
||||
}
|
||||
|
||||
// Fix Preview URL for https://github.com/wpmudev/domain-mapping plugin
|
||||
if ( class_exists( 'domain_map' ) ) {
|
||||
add_filter( 'elementor/document/urls/preview', function( $preview_url ) {
|
||||
if ( wp_parse_url( $preview_url, PHP_URL_HOST ) !== $_SERVER['HTTP_HOST'] ) {
|
||||
$preview_url = \domain_map::utils()->unswap_url( $preview_url );
|
||||
$preview_url = add_query_arg( [
|
||||
'dm' => \Domainmap_Module_Mapping::BYPASS,
|
||||
], $preview_url );
|
||||
}
|
||||
|
||||
return $preview_url;
|
||||
} );
|
||||
}
|
||||
|
||||
// Gutenberg
|
||||
if ( function_exists( 'gutenberg_init' ) ) {
|
||||
add_action( 'admin_print_scripts-edit.php', [ __CLASS__, 'add_new_button_to_gutenberg' ], 11 );
|
||||
}
|
||||
}
|
||||
|
||||
public static function filter_library_post_type( $post_types ) {
|
||||
unset( $post_types[ Source_Local::CPT ] );
|
||||
|
||||
return $post_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Polylang compatibility.
|
||||
*
|
||||
* Fix Polylang compatibility with Elementor.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
private static function polylang_compatibility() {
|
||||
// Fix language if the `get_user_locale` is difference from the `get_locale
|
||||
if ( isset( $_REQUEST['action'] ) && 0 === strpos( $_REQUEST['action'], 'elementor' ) ) {
|
||||
add_action( 'set_current_user', function() {
|
||||
global $current_user;
|
||||
$current_user->locale = get_locale();
|
||||
} );
|
||||
|
||||
// Fix for Polylang
|
||||
define( 'PLL_AJAX_ON_FRONT', true );
|
||||
|
||||
add_action( 'pll_pre_init', function( $polylang ) {
|
||||
if ( isset( $_REQUEST['post'] ) ) {
|
||||
$post_language = $polylang->model->post->get_language( $_REQUEST['post'], 'locale' );
|
||||
if ( ! empty( $post_language ) ) {
|
||||
$_REQUEST['lang'] = $post_language->locale;
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
// Copy elementor data while polylang creates a translation copy
|
||||
add_filter( 'pll_copy_post_metas', [ __CLASS__, 'save_polylang_meta' ], 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save polylang meta.
|
||||
*
|
||||
* Copy elementor data while polylang creates a translation copy.
|
||||
*
|
||||
* Fired by `pll_copy_post_metas` filter.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $keys List of custom fields names.
|
||||
* @param bool $sync True if it is synchronization, false if it is a copy.
|
||||
* @param int $from ID of the post from which we copy information.
|
||||
* @param int $to ID of the post to which we paste information.
|
||||
*
|
||||
* @return array List of custom fields names.
|
||||
*/
|
||||
public static function save_polylang_meta( $keys, $sync, $from, $to ) {
|
||||
// Copy only for a new post.
|
||||
if ( ! $sync ) {
|
||||
Plugin::$instance->db->copy_elementor_meta( $from, $to );
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process post meta before WP importer.
|
||||
*
|
||||
* Normalize Elementor post meta on import, We need the `wp_slash` in order
|
||||
* to avoid the unslashing during the `add_post_meta`.
|
||||
*
|
||||
* Fired by `wp_import_post_meta` filter.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $post_meta Post meta.
|
||||
*
|
||||
* @return array Updated post meta.
|
||||
*/
|
||||
public static function on_wp_import_post_meta( $post_meta ) {
|
||||
$is_wp_importer_before_0_7 = self::is_wp_importer_before_0_7();
|
||||
|
||||
if ( $is_wp_importer_before_0_7 ) {
|
||||
foreach ( $post_meta as &$meta ) {
|
||||
if ( '_elementor_data' === $meta['key'] ) {
|
||||
$meta['value'] = wp_slash( $meta['value'] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $post_meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is WP Importer Before 0.7
|
||||
*
|
||||
* Checks if WP Importer is installed, and whether its version is older than 0.7.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_wp_importer_before_0_7() {
|
||||
$wp_importer = get_plugins( '/wordpress-importer' );
|
||||
|
||||
if ( ! empty( $wp_importer ) ) {
|
||||
$wp_importer_version = $wp_importer['wordpress-importer.php']['Version'];
|
||||
|
||||
if ( version_compare( $wp_importer_version, '0.7', '<' ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process post meta before WXR importer.
|
||||
*
|
||||
* Normalize Elementor post meta on import with the new WP_importer, We need
|
||||
* the `wp_slash` in order to avoid the unslashing during the `add_post_meta`.
|
||||
*
|
||||
* Fired by `wxr_importer.pre_process.post_meta` filter.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $post_meta Post meta.
|
||||
*
|
||||
* @return array Updated post meta.
|
||||
*/
|
||||
public static function on_wxr_importer_pre_process_post_meta( $post_meta ) {
|
||||
$is_wp_importer_before_0_7 = self::is_wp_importer_before_0_7();
|
||||
|
||||
if ( $is_wp_importer_before_0_7 ) {
|
||||
if ( '_elementor_data' === $post_meta['key'] ) {
|
||||
$post_meta['value'] = wp_slash( $post_meta['value'] );
|
||||
}
|
||||
}
|
||||
|
||||
return $post_meta;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor conditions.
|
||||
*
|
||||
* Elementor conditions handler class introduce the compare conditions and the
|
||||
* check conditions methods.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Conditions {
|
||||
|
||||
/**
|
||||
* Compare conditions.
|
||||
*
|
||||
* Whether the two values comply the comparison operator.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param mixed $left_value First value to compare.
|
||||
* @param mixed $right_value Second value to compare.
|
||||
* @param string $operator Comparison operator.
|
||||
*
|
||||
* @return bool Whether the two values complies the comparison operator.
|
||||
*/
|
||||
public static function compare( $left_value, $right_value, $operator ) {
|
||||
switch ( $operator ) {
|
||||
case '==':
|
||||
return $left_value == $right_value;
|
||||
case '!=':
|
||||
return $left_value != $right_value;
|
||||
case '!==':
|
||||
return $left_value !== $right_value;
|
||||
case 'in':
|
||||
return in_array( $left_value, $right_value, true );
|
||||
case '!in':
|
||||
return ! in_array( $left_value, $right_value, true );
|
||||
case 'contains':
|
||||
return in_array( $right_value, $left_value, true );
|
||||
case '!contains':
|
||||
return ! in_array( $right_value, $left_value, true );
|
||||
case '<':
|
||||
return $left_value < $right_value;
|
||||
case '<=':
|
||||
return $left_value <= $right_value;
|
||||
case '>':
|
||||
return $left_value > $right_value;
|
||||
case '>=':
|
||||
return $left_value >= $right_value;
|
||||
default:
|
||||
return $left_value === $right_value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check conditions.
|
||||
*
|
||||
* Whether the comparison conditions comply.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $conditions The conditions to check.
|
||||
* @param array $comparison The comparison parameter.
|
||||
*
|
||||
* @return bool Whether the comparison conditions comply.
|
||||
*/
|
||||
public static function check( array $conditions, array $comparison ) {
|
||||
$is_or_condition = isset( $conditions['relation'] ) && 'or' === $conditions['relation'];
|
||||
|
||||
$condition_succeed = ! $is_or_condition;
|
||||
|
||||
foreach ( $conditions['terms'] as $term ) {
|
||||
if ( ! empty( $term['terms'] ) ) {
|
||||
$comparison_result = self::check( $term, $comparison );
|
||||
} else {
|
||||
preg_match( '/(\w+)(?:\[(\w+)])?/', $term['name'], $parsed_name );
|
||||
|
||||
$value = $comparison[ $parsed_name[1] ];
|
||||
|
||||
if ( ! empty( $parsed_name[2] ) ) {
|
||||
$value = $value[ $parsed_name[2] ];
|
||||
}
|
||||
|
||||
$operator = null;
|
||||
|
||||
if ( ! empty( $term['operator'] ) ) {
|
||||
$operator = $term['operator'];
|
||||
}
|
||||
|
||||
$comparison_result = self::compare( $value, $term['value'], $operator );
|
||||
}
|
||||
|
||||
if ( $is_or_condition ) {
|
||||
if ( $comparison_result ) {
|
||||
return true;
|
||||
}
|
||||
} elseif ( ! $comparison_result ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return $condition_succeed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor animation control.
|
||||
*
|
||||
* A base control for creating entrance animation control. Displays a select box
|
||||
* with the available entrance animation effects @see Control_Animation::get_animations() .
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Animation extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Retrieve the animation control type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'animation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve default control settings.
|
||||
*
|
||||
* Get the default settings of the control. Used to return the default
|
||||
* settings while initializing the control.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
$default_settings['label_block'] = true;
|
||||
$default_settings['render_type'] = 'none';
|
||||
|
||||
return $default_settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get animations list.
|
||||
*
|
||||
* Retrieve the list of all the available animations.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Control type.
|
||||
*/
|
||||
public static function get_animations() {
|
||||
$animations = [
|
||||
'Fading' => [
|
||||
'fadeIn' => 'Fade In',
|
||||
'fadeInDown' => 'Fade In Down',
|
||||
'fadeInLeft' => 'Fade In Left',
|
||||
'fadeInRight' => 'Fade In Right',
|
||||
'fadeInUp' => 'Fade In Up',
|
||||
],
|
||||
'Zooming' => [
|
||||
'zoomIn' => 'Zoom In',
|
||||
'zoomInDown' => 'Zoom In Down',
|
||||
'zoomInLeft' => 'Zoom In Left',
|
||||
'zoomInRight' => 'Zoom In Right',
|
||||
'zoomInUp' => 'Zoom In Up',
|
||||
],
|
||||
'Bouncing' => [
|
||||
'bounceIn' => 'Bounce In',
|
||||
'bounceInDown' => 'Bounce In Down',
|
||||
'bounceInLeft' => 'Bounce In Left',
|
||||
'bounceInRight' => 'Bounce In Right',
|
||||
'bounceInUp' => 'Bounce In Up',
|
||||
],
|
||||
'Sliding' => [
|
||||
'slideInDown' => 'Slide In Down',
|
||||
'slideInLeft' => 'Slide In Left',
|
||||
'slideInRight' => 'Slide In Right',
|
||||
'slideInUp' => 'Slide In Up',
|
||||
],
|
||||
'Rotating' => [
|
||||
'rotateIn' => 'Rotate In',
|
||||
'rotateInDownLeft' => 'Rotate In Down Left',
|
||||
'rotateInDownRight' => 'Rotate In Down Right',
|
||||
'rotateInUpLeft' => 'Rotate In Up Left',
|
||||
'rotateInUpRight' => 'Rotate In Up Right',
|
||||
],
|
||||
'Attention Seekers' => [
|
||||
'bounce' => 'Bounce',
|
||||
'flash' => 'Flash',
|
||||
'pulse' => 'Pulse',
|
||||
'rubberBand' => 'Rubber Band',
|
||||
'shake' => 'Shake',
|
||||
'headShake' => 'Head Shake',
|
||||
'swing' => 'Swing',
|
||||
'tada' => 'Tada',
|
||||
'wobble' => 'Wobble',
|
||||
'jello' => 'Jello',
|
||||
],
|
||||
'Light Speed' => [
|
||||
'lightSpeedIn' => 'Light Speed In',
|
||||
],
|
||||
'Specials' => [
|
||||
'rollIn' => 'Roll In',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Element appearance animations list.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @param array $additional_animations Additional Animations array.
|
||||
*/
|
||||
$additional_animations = apply_filters( 'elementor/controls/animations/additional_animations', [] );
|
||||
|
||||
return array_merge( $animations, $additional_animations );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render animations control template.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<select id="<?php echo $control_uid; ?>" data-setting="{{ data.name }}">
|
||||
<option value=""><?php echo __( 'Default', 'elementor' ); ?></option>
|
||||
<option value="none"><?php echo __( 'None', 'elementor' ); ?></option>
|
||||
<?php foreach ( static::get_animations() as $animations_group_name => $animations_group ) : ?>
|
||||
<optgroup label="<?php echo $animations_group_name; ?>">
|
||||
<?php foreach ( $animations_group as $animation_name => $animation_title ) : ?>
|
||||
<option value="<?php echo $animation_name; ?>"><?php echo $animation_title; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor base data control.
|
||||
*
|
||||
* An abstract class for creating new data controls in the panel.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Base_Data_Control extends Base_Control {
|
||||
|
||||
/**
|
||||
* Get data control default value.
|
||||
*
|
||||
* Retrieve the default value of the data control. Used to return the default
|
||||
* values while initializing the data control.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data control value.
|
||||
*
|
||||
* Retrieve the value of the data control from a specific Controls_Stack settings.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $control Control
|
||||
* @param array $settings Element settings
|
||||
*
|
||||
* @return mixed Control values.
|
||||
*/
|
||||
public function get_value( $control, $settings ) {
|
||||
if ( ! isset( $control['default'] ) ) {
|
||||
$control['default'] = $this->get_default_value();
|
||||
}
|
||||
|
||||
if ( isset( $settings[ $control['name'] ] ) ) {
|
||||
$value = $settings[ $control['name'] ];
|
||||
} else {
|
||||
$value = $control['default'];
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse dynamic tags.
|
||||
*
|
||||
* Iterates through all the controls and renders all the dynamic tags.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $dynamic_value The dynamic tag text.
|
||||
* @param array $dynamic_settings The dynamic tag settings.
|
||||
*
|
||||
* @return string|string[]|mixed A string or an array of strings with the
|
||||
* return value from each tag callback function.
|
||||
*/
|
||||
public function parse_tags( $dynamic_value, $dynamic_settings ) {
|
||||
$current_dynamic_settings = $this->get_settings( 'dynamic' );
|
||||
|
||||
if ( is_array( $current_dynamic_settings ) ) {
|
||||
$dynamic_settings = array_merge( $current_dynamic_settings, $dynamic_settings );
|
||||
}
|
||||
|
||||
return Plugin::$instance->dynamic_tags->parse_tags_text( $dynamic_value, $dynamic_settings, [ Plugin::$instance->dynamic_tags, 'get_tag_data_content' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data control style value.
|
||||
*
|
||||
* Retrieve the style of the control. Used when adding CSS rules to the control
|
||||
* while extracting CSS from the `selectors` data argument.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @since 2.3.3 New `$control_data` parameter added.
|
||||
* @access public
|
||||
*
|
||||
* @param string $css_property CSS property.
|
||||
* @param string $control_value Control value.
|
||||
* @param array $control_data Control Data.
|
||||
*
|
||||
* @return string Control style value.
|
||||
*/
|
||||
public function get_style_value( $css_property, $control_value, array $control_data ) {
|
||||
if ( 'DEFAULT' === $css_property ) {
|
||||
return $control_data['default'];
|
||||
}
|
||||
|
||||
return $control_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data control unique ID.
|
||||
*
|
||||
* Retrieve the unique ID of the control. Used to set a uniq CSS ID for the
|
||||
* element.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @param string $input_type Input type. Default is 'default'.
|
||||
*
|
||||
* @return string Unique ID.
|
||||
*/
|
||||
protected function get_control_uid( $input_type = 'default' ) {
|
||||
return 'elementor-control-' . $input_type . '-{{{ data._cid }}}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
abstract class Base_Icon_Font {
|
||||
|
||||
/**
|
||||
* Get Icon type.
|
||||
*
|
||||
* Retrieve the icon type.
|
||||
*
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function get_type();
|
||||
|
||||
/**
|
||||
* Enqueue Icon scripts and styles.
|
||||
*
|
||||
* Used to register and enqueue custom scripts and styles used by the Icon.
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
abstract public function enqueue();
|
||||
|
||||
/**
|
||||
* get_css_prefix
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_css_prefix();
|
||||
|
||||
abstract public function get_icons();
|
||||
|
||||
public function __construct() {}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor control base multiple.
|
||||
*
|
||||
* An abstract class for creating new controls in the panel that return
|
||||
* more than a single value. Each value of the multi-value control will
|
||||
* be returned as an item in a `key => value` array.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Control_Base_Multiple extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get multiple control default value.
|
||||
*
|
||||
* Retrieve the default value of the multiple control. Used to return the default
|
||||
* values while initializing the multiple control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple control value.
|
||||
*
|
||||
* Retrieve the value of the multiple control from a specific Controls_Stack settings.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $control Control
|
||||
* @param array $settings Settings
|
||||
*
|
||||
* @return mixed Control values.
|
||||
*/
|
||||
public function get_value( $control, $settings ) {
|
||||
$value = parent::get_value( $control, $settings );
|
||||
|
||||
if ( empty( $control['default'] ) ) {
|
||||
$control['default'] = [];
|
||||
}
|
||||
|
||||
if ( ! is_array( $value ) ) {
|
||||
$value = [];
|
||||
}
|
||||
|
||||
$control['default'] = array_merge(
|
||||
$this->get_default_value(),
|
||||
$control['default']
|
||||
);
|
||||
|
||||
return array_merge(
|
||||
$control['default'],
|
||||
$value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get multiple control style value.
|
||||
*
|
||||
* Retrieve the style of the control. Used when adding CSS rules to the control
|
||||
* while extracting CSS from the `selectors` data argument.
|
||||
*
|
||||
* @since 1.0.5
|
||||
* @since 2.3.3 New `$control_data` parameter added.
|
||||
* @access public
|
||||
*
|
||||
* @param string $css_property CSS property.
|
||||
* @param array $control_value Control value.
|
||||
* @param array $control_data Control Data.
|
||||
*
|
||||
* @return array Control style value.
|
||||
*/
|
||||
public function get_style_value( $css_property, $control_value, array $control_data ) {
|
||||
return $control_value[ strtolower( $css_property ) ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor base UI control.
|
||||
*
|
||||
* An abstract class for creating new UI controls in the panel.
|
||||
*
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Base_UI_Control extends Base_Control {
|
||||
|
||||
/**
|
||||
* Get features.
|
||||
*
|
||||
* Retrieve the list of all the available features.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Features array.
|
||||
*/
|
||||
public static function get_features() {
|
||||
return [ 'ui' ];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor control base units.
|
||||
*
|
||||
* An abstract class for creating new unit controls in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Control_Base_Units extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get units control default value.
|
||||
*
|
||||
* Retrieve the default value of the units control. Used to return the default
|
||||
* values while initializing the units control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'unit' => 'px',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get units control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the units control. Used to return the default
|
||||
* settings while initializing the units control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'size_units' => [ 'px' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
'step' => 1,
|
||||
],
|
||||
'em' => [
|
||||
'min' => 0.1,
|
||||
'max' => 10,
|
||||
'step' => 0.1,
|
||||
],
|
||||
'rem' => [
|
||||
'min' => 0.1,
|
||||
'max' => 10,
|
||||
'step' => 0.1,
|
||||
],
|
||||
'%' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
'step' => 1,
|
||||
],
|
||||
'deg' => [
|
||||
'min' => 0,
|
||||
'max' => 360,
|
||||
'step' => 1,
|
||||
],
|
||||
'vh' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
'step' => 1,
|
||||
],
|
||||
'vw' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
'step' => 1,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Print units control settings.
|
||||
*
|
||||
* Used to generate the units control template in the editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function print_units_template() {
|
||||
?>
|
||||
<# if ( data.size_units && data.size_units.length > 1 ) { #>
|
||||
<div class="elementor-units-choices">
|
||||
<# _.each( data.size_units, function( unit ) { #>
|
||||
<input id="elementor-choose-{{ data._cid + data.name + unit }}" type="radio" name="elementor-choose-{{ data.name + data._cid }}" data-setting="unit" value="{{ unit }}">
|
||||
<label class="elementor-units-choices-label" for="elementor-choose-{{ data._cid + data.name + unit }}">{{{ unit }}}</label>
|
||||
<# } ); #>
|
||||
</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Base\Base_Object;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor base control.
|
||||
*
|
||||
* An abstract class for creating new controls in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Base_Control extends Base_Object {
|
||||
|
||||
/**
|
||||
* Base settings.
|
||||
*
|
||||
* Holds all the base settings of the control.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $_base_settings = [
|
||||
'label' => '',
|
||||
'description' => '',
|
||||
'show_label' => true,
|
||||
'label_block' => false,
|
||||
'separator' => 'default',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get features.
|
||||
*
|
||||
* Retrieve the list of all the available features. Currently Elementor uses only
|
||||
* the `UI` feature.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Features array.
|
||||
*/
|
||||
public static function get_features() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Retrieve the control type.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function get_type();
|
||||
|
||||
/**
|
||||
* Control base constructor.
|
||||
*
|
||||
* Initializing the control base class.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->set_settings( array_merge( $this->_base_settings, $this->get_default_settings() ) );
|
||||
|
||||
$this->set_settings( 'features', static::get_features() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue control scripts and styles.
|
||||
*
|
||||
* Used to register and enqueue custom scripts and styles used by the control.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue() {}
|
||||
|
||||
/**
|
||||
* Control content template.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* Note that the content template is wrapped by Base_Control::print_template().
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*/
|
||||
abstract public function content_template();
|
||||
|
||||
/**
|
||||
* Print control template.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
final public function print_template() {
|
||||
?>
|
||||
<script type="text/html" id="tmpl-elementor-control-<?php echo esc_attr( $this->get_type() ); ?>-content">
|
||||
<div class="elementor-control-content">
|
||||
<?php
|
||||
// TODO: This is for backwards compatibility starting from 2.9.0
|
||||
// This `if` statement should be removed when the method is removed
|
||||
if ( method_exists( $this, '_content_template' ) ) {
|
||||
$this->_content_template();
|
||||
} else {
|
||||
$this->content_template();
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default control settings.
|
||||
*
|
||||
* Retrieve the default settings of the control. Used to return the default
|
||||
* settings while initializing the control.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor box shadow control.
|
||||
*
|
||||
* A base control for creating box shadows control. Displays input fields for
|
||||
* horizontal shadow, vertical shadow, shadow blur, shadow spread and shadow
|
||||
* color.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Box_Shadow extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get box shadow control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `box_shadow`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'box_shadow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get box shadow control default value.
|
||||
*
|
||||
* Retrieve the default value of the box shadow control. Used to return the
|
||||
* default values while initializing the box shadow control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'horizontal' => 0,
|
||||
'vertical' => 0,
|
||||
'blur' => 10,
|
||||
'spread' => 0,
|
||||
'color' => 'rgba(0,0,0,0.5)',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get box shadow control sliders.
|
||||
*
|
||||
* Retrieve the sliders of the box shadow control. Sliders are used while
|
||||
* rendering the control output in the editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control sliders.
|
||||
*/
|
||||
public function get_sliders() {
|
||||
return [
|
||||
'horizontal' => [
|
||||
'label' => __( 'Horizontal', 'elementor' ),
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'vertical' => [
|
||||
'label' => __( 'Vertical', 'elementor' ),
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'blur' => [
|
||||
'label' => __( 'Blur', 'elementor' ),
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
],
|
||||
'spread' => [
|
||||
'label' => __( 'Spread', 'elementor' ),
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render box shadow control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-shadow-box">
|
||||
<div class="elementor-control-field elementor-color-picker-wrapper">
|
||||
<label class="elementor-control-title"><?php echo __( 'Color', 'elementor' ); ?></label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-1">
|
||||
<div class="elementor-color-picker-placeholder"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
foreach ( $this->get_sliders() as $slider_name => $slider ) :
|
||||
$control_uid = $this->get_control_uid( $slider_name );
|
||||
?>
|
||||
<div class="elementor-shadow-slider elementor-control-type-slider">
|
||||
<label for="<?php echo esc_attr( $control_uid ); ?>" class="elementor-control-title"><?php echo $slider['label']; ?></label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<div class="elementor-slider" data-input="<?php echo esc_attr( $slider_name ); ?>"></div>
|
||||
<div class="elementor-slider-input elementor-control-unit-2">
|
||||
<input id="<?php echo esc_attr( $control_uid ); ?>" type="number" min="<?php echo esc_attr( $slider['min'] ); ?>" max="<?php echo esc_attr( $slider['max'] ); ?>" data-setting="<?php echo esc_attr( $slider_name ); ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor button control.
|
||||
*
|
||||
* A base control for creating a button control. Displays a button that can
|
||||
* trigger an event.
|
||||
*
|
||||
* @since 1.9.0
|
||||
*/
|
||||
class Control_Button extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get button control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `button`.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'button';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get button control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the button control. Used to
|
||||
* return the default settings while initializing the button
|
||||
* control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'text' => '',
|
||||
'event' => '',
|
||||
'button_type' => 'default',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render button control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<button type="button" class="elementor-button elementor-button-{{{ data.button_type }}}" data-event="{{{ data.event }}}">{{{ data.text }}}</button>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor choose control.
|
||||
*
|
||||
* A base control for creating choose control. Displays radio buttons styled as
|
||||
* groups of buttons with icons for each option.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Choose extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get choose control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `choose`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'choose';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render choose control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid( '{{value}}' );
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<div class="elementor-choices">
|
||||
<# _.each( data.options, function( options, value ) { #>
|
||||
<input id="<?php echo $control_uid; ?>" type="radio" name="elementor-choose-{{ data.name }}-{{ data._cid }}" value="{{ value }}">
|
||||
<label class="elementor-choices-label elementor-control-unit-1 tooltip-target" for="<?php echo $control_uid; ?>" data-tooltip="{{ options.title }}" title="{{ options.title }}">
|
||||
<i class="{{ options.icon }}" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only">{{{ options.title }}}</span>
|
||||
</label>
|
||||
<# } ); #>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get choose control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the choose control. Used to return the
|
||||
* default settings while initializing the choose control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'options' => [],
|
||||
'toggle' => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor code control.
|
||||
*
|
||||
* A base control for creating code control. Displays a code editor textarea.
|
||||
* Based on Ace editor (@see https://ace.c9.io/).
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Code extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get code control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `code`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'code';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get code control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the code control. Used to return the default
|
||||
* settings while initializing the code control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'language' => 'html', // html/css
|
||||
'rows' => 10,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render code control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<textarea id="<?php echo $control_uid; ?>" rows="{{ data.rows }}" class="elementor-input-style elementor-code-editor" data-setting="{{ data.name }}"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor color control.
|
||||
*
|
||||
* A base control for creating color control. Displays a color picker field with
|
||||
* an alpha slider. Includes a customizable color palette that can be preset by
|
||||
* the user. Accepts a `scheme` argument that allows you to set a value from the
|
||||
* active color scheme as the default value returned by the control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Color extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get color control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `color`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'color';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render color control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label || '' }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-dynamic-switcher-wrapper elementor-control-unit-5">
|
||||
<div class="elementor-color-picker-placeholder"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the color control. Used to return the default
|
||||
* settings while initializing the color control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'alpha' => true,
|
||||
'scheme' => '',
|
||||
'dynamic' => [
|
||||
'categories' => [
|
||||
TagsModule::COLOR_CATEGORY,
|
||||
],
|
||||
'active' => true,
|
||||
],
|
||||
'global' => [
|
||||
'active' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor date/time control.
|
||||
*
|
||||
* A base control for creating date time control. Displays a date/time picker
|
||||
* based on the Flatpickr library @see https://chmln.github.io/flatpickr/ .
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Date_Time extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get date time control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `date_time`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'date_time';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get date time control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the date time control. Used to return the
|
||||
* default settings while initializing the date time control.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'picker_options' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render date time control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<input id="<?php echo $control_uid; ?>" placeholder="{{ data.placeholder }}" class="elementor-date-time-picker flatpickr" type="text" data-setting="{{ data.name }}">
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor Deprecated Notice control.
|
||||
*
|
||||
* A base control specific for creating Deprecation Notices control.
|
||||
* Displays a warning notice in the panel.
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
class Control_Deprecated_Notice extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get deprecated-notice control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `deprecated_notice`.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'deprecated_notice';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render deprecated notice control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<# if ( data.label ) { #>
|
||||
<span class="elementor-control-title">{{{ data.label }}}</span>
|
||||
<#
|
||||
}
|
||||
let notice = elementor.translate( 'deprecated_notice', [ data.widget, data.plugin, data.since ] );
|
||||
if ( data.replacement ) {
|
||||
notice += '<br>' + elementor.translate( 'deprecated_notice_replacement', [ data.replacement ] );
|
||||
}
|
||||
if ( data.last ) {
|
||||
notice += '<br>' + elementor.translate( 'deprecated_notice_last', [ data.widget, data.plugin, data.last ] );
|
||||
}
|
||||
#>
|
||||
<div class="elementor-control-deprecated-notice elementor-panel-alert elementor-panel-alert-warning">{{{ notice }}}</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get deprecated-notice control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the deprecated notice control. Used to return the
|
||||
* default settings while initializing the deprecated notice control.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'widget' => '', // Widgets name
|
||||
'since' => '', // Plugin version widget was deprecated
|
||||
'last' => '', // Plugin version in which the widget will be removed
|
||||
'plugin' => '', // Plugin's title
|
||||
'replacement' => '', // Widget replacement
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor dimension control.
|
||||
*
|
||||
* A base control for creating dimension control. Displays input fields for top,
|
||||
* right, bottom, left and the option to link them together.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Dimensions extends Control_Base_Units {
|
||||
|
||||
/**
|
||||
* Get dimensions control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `dimensions`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'dimensions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dimensions control default values.
|
||||
*
|
||||
* Retrieve the default value of the dimensions control. Used to return the
|
||||
* default values while initializing the dimensions control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return array_merge(
|
||||
parent::get_default_value(), [
|
||||
'top' => '',
|
||||
'right' => '',
|
||||
'bottom' => '',
|
||||
'left' => '',
|
||||
'isLinked' => true,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get dimensions control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the dimensions control. Used to return the
|
||||
* default settings while initializing the dimensions control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return array_merge(
|
||||
parent::get_default_settings(), [
|
||||
'label_block' => true,
|
||||
'allowed_dimensions' => 'all',
|
||||
'placeholder' => '',
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render dimensions control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$dimensions = [
|
||||
'top' => __( 'Top', 'elementor' ),
|
||||
'right' => __( 'Right', 'elementor' ),
|
||||
'bottom' => __( 'Bottom', 'elementor' ),
|
||||
'left' => __( 'Left', 'elementor' ),
|
||||
];
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<?php $this->print_units_template(); ?>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<ul class="elementor-control-dimensions">
|
||||
<?php
|
||||
foreach ( $dimensions as $dimension_key => $dimension_title ) :
|
||||
$control_uid = $this->get_control_uid( $dimension_key );
|
||||
?>
|
||||
<li class="elementor-control-dimension">
|
||||
<input id="<?php echo $control_uid; ?>" type="number" data-setting="<?php echo esc_attr( $dimension_key ); ?>"
|
||||
placeholder="<#
|
||||
if ( _.isObject( data.placeholder ) ) {
|
||||
if ( ! _.isUndefined( data.placeholder.<?php echo $dimension_key; ?> ) ) {
|
||||
print( data.placeholder.<?php echo $dimension_key; ?> );
|
||||
}
|
||||
} else {
|
||||
print( data.placeholder );
|
||||
} #>"
|
||||
<# if ( -1 === _.indexOf( allowed_dimensions, '<?php echo $dimension_key; ?>' ) ) { #>
|
||||
disabled
|
||||
<# } #>
|
||||
/>
|
||||
<label for="<?php echo esc_attr( $control_uid ); ?>" class="elementor-control-dimension-label"><?php echo $dimension_title; ?></label>
|
||||
</li>
|
||||
<?php endforeach; ?>
|
||||
<li>
|
||||
<button class="elementor-link-dimensions tooltip-target" data-tooltip="<?php echo esc_attr__( 'Link values together', 'elementor' ); ?>">
|
||||
<span class="elementor-linked">
|
||||
<i class="eicon-link" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Link values together', 'elementor' ); ?></span>
|
||||
</span>
|
||||
<span class="elementor-unlinked">
|
||||
<i class="eicon-chain-broken" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Unlinked values', 'elementor' ); ?></span>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor divider control.
|
||||
*
|
||||
* A base control for creating divider control. Displays horizontal line in
|
||||
* the panel.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*/
|
||||
class Control_Divider extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get divider control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `divider`.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'divider';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get divider control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the divider control. Used to
|
||||
* return the default settings while initializing the divider
|
||||
* control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'separator' => 'none',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render divider control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor exit animation control.
|
||||
*
|
||||
* A control for creating exit animation. Displays a select box
|
||||
* with the available exit animation effects @see Control_Exit_Animation::get_animations() .
|
||||
*
|
||||
* @since 2.5.0
|
||||
*/
|
||||
class Control_Exit_Animation extends Control_Animation {
|
||||
|
||||
/**
|
||||
* Get control type.
|
||||
*
|
||||
* Retrieve the animation control type.
|
||||
*
|
||||
* @since 2.5.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'exit_animation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get animations list.
|
||||
*
|
||||
* Retrieve the list of all the available animations.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Control type.
|
||||
*/
|
||||
public static function get_animations() {
|
||||
$animations = [
|
||||
'Fading' => [
|
||||
'fadeIn' => 'Fade Out',
|
||||
'fadeInDown' => 'Fade Out Up',
|
||||
'fadeInLeft' => 'Fade Out Left',
|
||||
'fadeInRight' => 'Fade Out Right',
|
||||
'fadeInUp' => 'Fade Out Down',
|
||||
],
|
||||
'Zooming' => [
|
||||
'zoomIn' => 'Zoom Out',
|
||||
'zoomInDown' => 'Zoom Out Up',
|
||||
'zoomInLeft' => 'Zoom Out Left',
|
||||
'zoomInRight' => 'Zoom Out Right',
|
||||
'zoomInUp' => 'Zoom Out Down',
|
||||
],
|
||||
'Sliding' => [
|
||||
'slideInDown' => 'Slide Out Up',
|
||||
'slideInLeft' => 'Slide Out Left',
|
||||
'slideInRight' => 'Slide Out Right',
|
||||
'slideInUp' => 'Slide Out Down',
|
||||
],
|
||||
'Rotating' => [
|
||||
'rotateIn' => 'Rotate Out',
|
||||
'rotateInDownLeft' => 'Rotate Out Up Left',
|
||||
'rotateInDownRight' => 'Rotate Out Up Right',
|
||||
'rotateInUpRight' => 'Rotate Out Down Left',
|
||||
'rotateInUpLeft' => 'Rotate Out Down Right',
|
||||
],
|
||||
'Light Speed' => [
|
||||
'lightSpeedIn' => 'Light Speed Out',
|
||||
],
|
||||
'Specials' => [
|
||||
'rollIn' => 'Roll Out',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Element appearance animations list.
|
||||
*
|
||||
* @since 2.5.0
|
||||
*
|
||||
* @param array $additional_animations Additional Animations array.
|
||||
*/
|
||||
$additional_animations = apply_filters( 'elementor/controls/exit-animations/additional_animations', [] );
|
||||
|
||||
return array_merge( $animations, $additional_animations );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor font control.
|
||||
*
|
||||
* A base control for creating font control. Displays font select box. The
|
||||
* control allows you to set a list of fonts.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Font extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get font control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `font`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'font';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get font control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the font control. Used to return the default
|
||||
* settings while initializing the font control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'groups' => Fonts::get_font_groups(),
|
||||
'options' => Fonts::get_fonts(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render font control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-5">
|
||||
<select id="<?php echo $control_uid; ?>" class="elementor-control-font-family" data-setting="{{ data.name }}">
|
||||
<option value=""><?php echo __( 'Default', 'elementor' ); ?></option>
|
||||
<# _.each( data.groups, function( group_label, group_name ) {
|
||||
var groupFonts = getFontsByGroups( group_name );
|
||||
if ( ! _.isEmpty( groupFonts ) ) { #>
|
||||
<optgroup label="{{ group_label }}">
|
||||
<# _.each( groupFonts, function( fontType, fontName ) { #>
|
||||
<option value="{{ fontName }}">{{{ fontName }}}</option>
|
||||
<# } ); #>
|
||||
</optgroup>
|
||||
<# }
|
||||
}); #>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor gallery control.
|
||||
*
|
||||
* A base control for creating gallery chooser control. Based on the WordPress
|
||||
* media library galleries. Used to select images from the WordPress media library.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Gallery extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get gallery control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `gallery`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'gallery';
|
||||
}
|
||||
|
||||
/**
|
||||
* Import gallery images.
|
||||
*
|
||||
* Used to import gallery control files from external sites while importing
|
||||
* Elementor template JSON file, and replacing the old data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $settings Control settings
|
||||
*
|
||||
* @return array Control settings.
|
||||
*/
|
||||
public function on_import( $settings ) {
|
||||
foreach ( $settings as &$attachment ) {
|
||||
if ( empty( $attachment['url'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$attachment = Plugin::$instance->templates_manager->get_import_images_instance()->import( $attachment );
|
||||
}
|
||||
|
||||
// Filter out attachments that don't exist
|
||||
$settings = array_filter( $settings );
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render gallery control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<div class="elementor-control-title">{{{ data.label }}}</div>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<div class="elementor-control-media__content elementor-control-tag-area">
|
||||
<div class="elementor-control-gallery-status elementor-control-dynamic-switcher-wrapper">
|
||||
<span class="elementor-control-gallery-status-title"></span>
|
||||
<span class="elementor-control-gallery-clear elementor-control-unit-1"><i class="eicon-trash-o" aria-hidden="true"></i></span>
|
||||
</div>
|
||||
<div class="elementor-control-gallery-content">
|
||||
<div class="elementor-control-gallery-thumbnails"></div>
|
||||
<div class="elementor-control-gallery-edit"><span><i class="eicon-pencil" aria-hidden="true"></i></span></div>
|
||||
<button class="elementor-button elementor-control-gallery-add" aria-label="<?php echo __( 'Add Images', 'elementor' ); ?>"><i class="eicon-plus-circle" aria-hidden="true"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gallery control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the gallery control. Used to return the
|
||||
* default settings while initializing the gallery control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'separator' => 'none',
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::GALLERY_CATEGORY ],
|
||||
'returnType' => 'object',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get gallery control default values.
|
||||
*
|
||||
* Retrieve the default value of the gallery control. Used to return the default
|
||||
* values while initializing the gallery control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,844 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor background control.
|
||||
*
|
||||
* A base control for creating background control. Displays input fields to define
|
||||
* the background color, background image, background gradient or background video.
|
||||
*
|
||||
* @since 1.2.2
|
||||
*/
|
||||
class Group_Control_Background extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the background control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Background control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Background Types.
|
||||
*
|
||||
* Holds all the available background types.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $background_types;
|
||||
|
||||
/**
|
||||
* Get background control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `background`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'background';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get background control types.
|
||||
*
|
||||
* Retrieve available background types.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Available background types.
|
||||
*/
|
||||
public static function get_background_types() {
|
||||
if ( null === self::$background_types ) {
|
||||
self::$background_types = self::get_default_background_types();
|
||||
}
|
||||
|
||||
return self::$background_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Default background types.
|
||||
*
|
||||
* Retrieve background control initial types.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @return array Default background types.
|
||||
*/
|
||||
private static function get_default_background_types() {
|
||||
return [
|
||||
'classic' => [
|
||||
'title' => _x( 'Classic', 'Background Control', 'elementor' ),
|
||||
'icon' => 'eicon-paint-brush',
|
||||
],
|
||||
'gradient' => [
|
||||
'title' => _x( 'Gradient', 'Background Control', 'elementor' ),
|
||||
'icon' => 'eicon-barcode',
|
||||
],
|
||||
'video' => [
|
||||
'title' => _x( 'Video', 'Background Control', 'elementor' ),
|
||||
'icon' => 'eicon-video-camera',
|
||||
],
|
||||
'slideshow' => [
|
||||
'title' => _x( 'Slideshow', 'Background Control', 'elementor' ),
|
||||
'icon' => 'eicon-slideshow',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize background control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access public
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
public function init_fields() {
|
||||
$fields = [];
|
||||
|
||||
$fields['background'] = [
|
||||
'label' => _x( 'Background Type', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::CHOOSE,
|
||||
'render_type' => 'ui',
|
||||
];
|
||||
|
||||
$fields['color'] = [
|
||||
'label' => _x( 'Color', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'default' => '',
|
||||
'title' => _x( 'Background Color', 'Background Control', 'elementor' ),
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-color: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic', 'gradient' ],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['color_stop'] = [
|
||||
'label' => _x( 'Location', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ '%' ],
|
||||
'default' => [
|
||||
'unit' => '%',
|
||||
'size' => 0,
|
||||
],
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['color_b'] = [
|
||||
'label' => _x( 'Second Color', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'default' => '#f2295b',
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['color_b_stop'] = [
|
||||
'label' => _x( 'Location', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ '%' ],
|
||||
'default' => [
|
||||
'unit' => '%',
|
||||
'size' => 100,
|
||||
],
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['gradient_type'] = [
|
||||
'label' => _x( 'Type', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => [
|
||||
'linear' => _x( 'Linear', 'Background Control', 'elementor' ),
|
||||
'radial' => _x( 'Radial', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'default' => 'linear',
|
||||
'render_type' => 'ui',
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['gradient_angle'] = [
|
||||
'label' => _x( 'Angle', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ 'deg' ],
|
||||
'default' => [
|
||||
'unit' => 'deg',
|
||||
'size' => 180,
|
||||
],
|
||||
'range' => [
|
||||
'deg' => [
|
||||
'step' => 10,
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-color: transparent; background-image: linear-gradient({{SIZE}}{{UNIT}}, {{color.VALUE}} {{color_stop.SIZE}}{{color_stop.UNIT}}, {{color_b.VALUE}} {{color_b_stop.SIZE}}{{color_b_stop.UNIT}})',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
'gradient_type' => 'linear',
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['gradient_position'] = [
|
||||
'label' => _x( 'Position', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => [
|
||||
'center center' => _x( 'Center Center', 'Background Control', 'elementor' ),
|
||||
'center left' => _x( 'Center Left', 'Background Control', 'elementor' ),
|
||||
'center right' => _x( 'Center Right', 'Background Control', 'elementor' ),
|
||||
'top center' => _x( 'Top Center', 'Background Control', 'elementor' ),
|
||||
'top left' => _x( 'Top Left', 'Background Control', 'elementor' ),
|
||||
'top right' => _x( 'Top Right', 'Background Control', 'elementor' ),
|
||||
'bottom center' => _x( 'Bottom Center', 'Background Control', 'elementor' ),
|
||||
'bottom left' => _x( 'Bottom Left', 'Background Control', 'elementor' ),
|
||||
'bottom right' => _x( 'Bottom Right', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'default' => 'center center',
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-color: transparent; background-image: radial-gradient(at {{VALUE}}, {{color.VALUE}} {{color_stop.SIZE}}{{color_stop.UNIT}}, {{color_b.VALUE}} {{color_b_stop.SIZE}}{{color_b_stop.UNIT}})',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'gradient' ],
|
||||
'gradient_type' => 'radial',
|
||||
],
|
||||
'of_type' => 'gradient',
|
||||
];
|
||||
|
||||
$fields['image'] = [
|
||||
'label' => _x( 'Image', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::MEDIA,
|
||||
'dynamic' => [
|
||||
'active' => true,
|
||||
],
|
||||
'responsive' => true,
|
||||
'title' => _x( 'Background Image', 'Background Control', 'elementor' ),
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-image: url("{{URL}}");',
|
||||
],
|
||||
'render_type' => 'template',
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['position'] = [
|
||||
'label' => _x( 'Position', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'responsive' => true,
|
||||
'options' => [
|
||||
'' => _x( 'Default', 'Background Control', 'elementor' ),
|
||||
'center center' => _x( 'Center Center', 'Background Control', 'elementor' ),
|
||||
'center left' => _x( 'Center Left', 'Background Control', 'elementor' ),
|
||||
'center right' => _x( 'Center Right', 'Background Control', 'elementor' ),
|
||||
'top center' => _x( 'Top Center', 'Background Control', 'elementor' ),
|
||||
'top left' => _x( 'Top Left', 'Background Control', 'elementor' ),
|
||||
'top right' => _x( 'Top Right', 'Background Control', 'elementor' ),
|
||||
'bottom center' => _x( 'Bottom Center', 'Background Control', 'elementor' ),
|
||||
'bottom left' => _x( 'Bottom Left', 'Background Control', 'elementor' ),
|
||||
'bottom right' => _x( 'Bottom Right', 'Background Control', 'elementor' ),
|
||||
'initial' => _x( 'Custom', 'Background Control', 'elementor' ),
|
||||
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['xpos'] = [
|
||||
'label' => _x( 'X Position', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'responsive' => true,
|
||||
'size_units' => [ 'px', 'em', '%', 'vw' ],
|
||||
'default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'tablet_default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'mobile_default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => -800,
|
||||
'max' => 800,
|
||||
],
|
||||
'em' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'%' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'vw' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{SIZE}}{{UNIT}} {{ypos.SIZE}}{{ypos.UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position' => [ 'initial' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
'required' => true,
|
||||
'device_args' => [
|
||||
Controls_Stack::RESPONSIVE_TABLET => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{SIZE}}{{UNIT}} {{ypos_tablet.SIZE}}{{ypos_tablet.UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position_tablet' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
Controls_Stack::RESPONSIVE_MOBILE => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{SIZE}}{{UNIT}} {{ypos_mobile.SIZE}}{{ypos_mobile.UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position_mobile' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['ypos'] = [
|
||||
'label' => _x( 'Y Position', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'responsive' => true,
|
||||
'size_units' => [ 'px', 'em', '%', 'vh' ],
|
||||
'default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'tablet_default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'mobile_default' => [
|
||||
'unit' => 'px',
|
||||
'size' => 0,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => -800,
|
||||
'max' => 800,
|
||||
],
|
||||
'em' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'%' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'vh' => [
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{xpos.SIZE}}{{xpos.UNIT}} {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position' => [ 'initial' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
'required' => true,
|
||||
'device_args' => [
|
||||
Controls_Stack::RESPONSIVE_TABLET => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{xpos_tablet.SIZE}}{{xpos_tablet.UNIT}} {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position_tablet' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
Controls_Stack::RESPONSIVE_MOBILE => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-position: {{xpos_mobile.SIZE}}{{xpos_mobile.UNIT}} {{SIZE}}{{UNIT}}',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'position_mobile' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['attachment'] = [
|
||||
'label' => _x( 'Attachment', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => _x( 'Default', 'Background Control', 'elementor' ),
|
||||
'scroll' => _x( 'Scroll', 'Background Control', 'elementor' ),
|
||||
'fixed' => _x( 'Fixed', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'(desktop+){{SELECTOR}}' => 'background-attachment: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['attachment_alert'] = [
|
||||
'type' => Controls_Manager::RAW_HTML,
|
||||
'content_classes' => 'elementor-control-field-description',
|
||||
'raw' => __( 'Note: Attachment Fixed works only on desktop.', 'elementor' ),
|
||||
'separator' => 'none',
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'image[url]!' => '',
|
||||
'attachment' => 'fixed',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['repeat'] = [
|
||||
'label' => _x( 'Repeat', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'responsive' => true,
|
||||
'options' => [
|
||||
'' => _x( 'Default', 'Background Control', 'elementor' ),
|
||||
'no-repeat' => _x( 'No-repeat', 'Background Control', 'elementor' ),
|
||||
'repeat' => _x( 'Repeat', 'Background Control', 'elementor' ),
|
||||
'repeat-x' => _x( 'Repeat-x', 'Background Control', 'elementor' ),
|
||||
'repeat-y' => _x( 'Repeat-y', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-repeat: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['size'] = [
|
||||
'label' => _x( 'Size', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'responsive' => true,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => _x( 'Default', 'Background Control', 'elementor' ),
|
||||
'auto' => _x( 'Auto', 'Background Control', 'elementor' ),
|
||||
'cover' => _x( 'Cover', 'Background Control', 'elementor' ),
|
||||
'contain' => _x( 'Contain', 'Background Control', 'elementor' ),
|
||||
'initial' => _x( 'Custom', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-size: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['bg_width'] = [
|
||||
'label' => _x( 'Width', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'responsive' => true,
|
||||
'size_units' => [ 'px', 'em', '%', 'vw' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 1000,
|
||||
],
|
||||
'%' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
],
|
||||
'vw' => [
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
],
|
||||
],
|
||||
'default' => [
|
||||
'size' => 100,
|
||||
'unit' => '%',
|
||||
],
|
||||
'required' => true,
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-size: {{SIZE}}{{UNIT}} auto',
|
||||
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'size' => [ 'initial' ],
|
||||
'image[url]!' => '',
|
||||
],
|
||||
'device_args' => [
|
||||
Controls_Stack::RESPONSIVE_TABLET => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-size: {{SIZE}}{{UNIT}} auto',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'size_tablet' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
Controls_Stack::RESPONSIVE_MOBILE => [
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background-size: {{SIZE}}{{UNIT}} auto',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'classic' ],
|
||||
'size_mobile' => [ 'initial' ],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['video_link'] = [
|
||||
'label' => _x( 'Video Link', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::TEXT,
|
||||
'placeholder' => 'https://www.youtube.com/watch?v=XHOmBV4js_E',
|
||||
'description' => __( 'YouTube/Vimeo link, or link to video file (mp4 is recommended).', 'elementor' ),
|
||||
'label_block' => true,
|
||||
'default' => '',
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'of_type' => 'video',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['video_start'] = [
|
||||
'label' => __( 'Start Time', 'elementor' ),
|
||||
'type' => Controls_Manager::NUMBER,
|
||||
'description' => __( 'Specify a start time (in seconds)', 'elementor' ),
|
||||
'placeholder' => 10,
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'of_type' => 'video',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['video_end'] = [
|
||||
'label' => __( 'End Time', 'elementor' ),
|
||||
'type' => Controls_Manager::NUMBER,
|
||||
'description' => __( 'Specify an end time (in seconds)', 'elementor' ),
|
||||
'placeholder' => 70,
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'of_type' => 'video',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['play_once'] = [
|
||||
'label' => __( 'Play Once', 'elementor' ),
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'of_type' => 'video',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['play_on_mobile'] = [
|
||||
'label' => __( 'Play On Mobile', 'elementor' ),
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'of_type' => 'video',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['video_fallback'] = [
|
||||
'label' => _x( 'Background Fallback', 'Background Control', 'elementor' ),
|
||||
'description' => __( 'This cover image will replace the background video in case that the video could not be loaded.', 'elementor' ),
|
||||
'type' => Controls_Manager::MEDIA,
|
||||
'condition' => [
|
||||
'background' => [ 'video' ],
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'background: url("{{URL}}") 50% 50%; background-size: cover;',
|
||||
],
|
||||
'of_type' => 'video',
|
||||
];
|
||||
|
||||
$fields['slideshow_gallery'] = [
|
||||
'label' => _x( 'Images', 'Background Control', 'elementor' ),
|
||||
'type' => Controls_Manager::GALLERY,
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'show_label' => false,
|
||||
'of_type' => 'slideshow',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_loop'] = [
|
||||
'label' => __( 'Infinite Loop', 'elementor' ),
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'default' => 'yes',
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'of_type' => 'slideshow',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_slide_duration'] = [
|
||||
'label' => __( 'Duration', 'elementor' ) . ' (ms)',
|
||||
'type' => Controls_Manager::NUMBER,
|
||||
'default' => 5000,
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_slide_transition'] = [
|
||||
'label' => __( 'Transition', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => 'fade',
|
||||
'options' => [
|
||||
'fade' => 'Fade',
|
||||
'slide_right' => 'Slide Right',
|
||||
'slide_left' => 'Slide Left',
|
||||
'slide_up' => 'Slide Up',
|
||||
'slide_down' => 'Slide Down',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'of_type' => 'slideshow',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_transition_duration'] = [
|
||||
'label' => __( 'Transition Duration', 'elementor' ) . ' (ms)',
|
||||
'type' => Controls_Manager::NUMBER,
|
||||
'default' => 500,
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_background_size'] = [
|
||||
'label' => __( 'Background Size', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'responsive' => true,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'auto' => __( 'Auto', 'elementor' ),
|
||||
'cover' => __( 'Cover', 'elementor' ),
|
||||
'contain' => __( 'Contain', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-background-slideshow__slide__image' => 'background-size: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['slideshow_background_position'] = [
|
||||
'label' => __( 'Background Position', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'responsive' => true,
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'center center' => _x( 'Center Center', 'Background Control', 'elementor' ),
|
||||
'center left' => _x( 'Center Left', 'Background Control', 'elementor' ),
|
||||
'center right' => _x( 'Center Right', 'Background Control', 'elementor' ),
|
||||
'top center' => _x( 'Top Center', 'Background Control', 'elementor' ),
|
||||
'top left' => _x( 'Top Left', 'Background Control', 'elementor' ),
|
||||
'top right' => _x( 'Top Right', 'Background Control', 'elementor' ),
|
||||
'bottom center' => _x( 'Bottom Center', 'Background Control', 'elementor' ),
|
||||
'bottom left' => _x( 'Bottom Left', 'Background Control', 'elementor' ),
|
||||
'bottom right' => _x( 'Bottom Right', 'Background Control', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{WRAPPER}} .elementor-background-slideshow__slide__image' => 'background-position: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
];
|
||||
|
||||
$fields['slideshow_ken_burns'] = [
|
||||
'label' => __( 'Ken Burns Effect', 'elementor' ),
|
||||
'type' => Controls_Manager::SWITCHER,
|
||||
'separator' => 'before',
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
],
|
||||
'of_type' => 'slideshow',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
$fields['slideshow_ken_burns_zoom_direction'] = [
|
||||
'label' => __( 'Direction', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => 'in',
|
||||
'options' => [
|
||||
'in' => __( 'In', 'elementor' ),
|
||||
'out' => __( 'Out', 'elementor' ),
|
||||
],
|
||||
'condition' => [
|
||||
'background' => [ 'slideshow' ],
|
||||
'slideshow_ken_burns!' => '',
|
||||
],
|
||||
'of_type' => 'slideshow',
|
||||
'frontend_available' => true,
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child default args.
|
||||
*
|
||||
* Retrieve the default arguments for all the child controls for a specific group
|
||||
* control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default arguments for all the child controls.
|
||||
*/
|
||||
protected function get_child_default_args() {
|
||||
return [
|
||||
'types' => [ 'classic', 'gradient' ],
|
||||
'selector' => '{{WRAPPER}}:not(.elementor-motion-effects-element-type-background), {{WRAPPER}} > .elementor-motion-effects-container > .elementor-motion-effects-layer',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter fields.
|
||||
*
|
||||
* Filter which controls to display, using `include`, `exclude`, `condition`
|
||||
* and `of_type` arguments.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function filter_fields() {
|
||||
$fields = parent::filter_fields();
|
||||
|
||||
$args = $this->get_args();
|
||||
|
||||
foreach ( $fields as &$field ) {
|
||||
if ( isset( $field['of_type'] ) && ! in_array( $field['of_type'], $args['types'] ) ) {
|
||||
unset( $field );
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare fields.
|
||||
*
|
||||
* Process background control fields before adding them to `add_control()`.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param array $fields Background control fields.
|
||||
*
|
||||
* @return array Processed fields.
|
||||
*/
|
||||
protected function prepare_fields( $fields ) {
|
||||
$args = $this->get_args();
|
||||
|
||||
$background_types = self::get_background_types();
|
||||
|
||||
$choose_types = [];
|
||||
|
||||
foreach ( $args['types'] as $type ) {
|
||||
if ( isset( $background_types[ $type ] ) ) {
|
||||
$choose_types[ $type ] = $background_types[ $type ];
|
||||
}
|
||||
}
|
||||
|
||||
$fields['background']['options'] = $choose_types;
|
||||
|
||||
return parent::prepare_fields( $fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the background control. Used to return the
|
||||
* default options while initializing the background control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default background control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,592 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor group control base.
|
||||
*
|
||||
* An abstract class for creating new group controls in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Group_Control_Base implements Group_Control_Interface {
|
||||
|
||||
/**
|
||||
* Arguments.
|
||||
*
|
||||
* Holds all the group control arguments.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array Group control arguments.
|
||||
*/
|
||||
private $args = [];
|
||||
|
||||
/**
|
||||
* Options.
|
||||
*
|
||||
* Holds all the group control options.
|
||||
*
|
||||
* Currently supports only the popover options.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array Group control options.
|
||||
*/
|
||||
private $options;
|
||||
|
||||
/**
|
||||
* Get options.
|
||||
*
|
||||
* Retrieve group control options. If options are not set, it will initialize default options.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $option Optional. Single option.
|
||||
*
|
||||
* @return mixed Group control options. If option parameter was not specified, it will
|
||||
* return an array of all the options. If single option specified, it will
|
||||
* return the option value or `null` if option does not exists.
|
||||
*/
|
||||
final public function get_options( $option = null ) {
|
||||
if ( null === $this->options ) {
|
||||
$this->init_options();
|
||||
}
|
||||
|
||||
if ( $option ) {
|
||||
if ( isset( $this->options[ $option ] ) ) {
|
||||
return $this->options[ $option ];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new controls to stack.
|
||||
*
|
||||
* Register multiple controls to allow the user to set/update data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $element The element stack.
|
||||
* @param array $user_args The control arguments defined by the user.
|
||||
* @param array $options Optional. The element options. Default is
|
||||
* an empty array.
|
||||
*/
|
||||
final public function add_controls( Controls_Stack $element, array $user_args, array $options = [] ) {
|
||||
$this->init_args( $user_args );
|
||||
|
||||
// Filter which controls to display
|
||||
$filtered_fields = $this->filter_fields();
|
||||
$filtered_fields = $this->prepare_fields( $filtered_fields );
|
||||
|
||||
// For php < 7
|
||||
reset( $filtered_fields );
|
||||
|
||||
if ( isset( $this->args['separator'] ) ) {
|
||||
$filtered_fields[ key( $filtered_fields ) ]['separator'] = $this->args['separator'];
|
||||
}
|
||||
|
||||
$has_injection = false;
|
||||
|
||||
if ( ! empty( $options['position'] ) ) {
|
||||
$has_injection = true;
|
||||
|
||||
$element->start_injection( $options['position'] );
|
||||
|
||||
unset( $options['position'] );
|
||||
}
|
||||
|
||||
if ( $this->get_options( 'popover' ) ) {
|
||||
$this->start_popover( $element );
|
||||
}
|
||||
|
||||
foreach ( $filtered_fields as $field_id => $field_args ) {
|
||||
// Add the global group args to the control
|
||||
$field_args = $this->add_group_args_to_field( $field_id, $field_args );
|
||||
|
||||
// Register the control
|
||||
$id = $this->get_controls_prefix() . $field_id;
|
||||
|
||||
if ( ! empty( $field_args['responsive'] ) ) {
|
||||
unset( $field_args['responsive'] );
|
||||
|
||||
$element->add_responsive_control( $id, $field_args, $options );
|
||||
} else {
|
||||
$element->add_control( $id, $field_args, $options );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->get_options( 'popover' ) ) {
|
||||
$element->end_popover();
|
||||
}
|
||||
|
||||
if ( $has_injection ) {
|
||||
$element->end_injection();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get arguments.
|
||||
*
|
||||
* Retrieve group control arguments.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Group control arguments.
|
||||
*/
|
||||
final public function get_args() {
|
||||
return $this->args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields.
|
||||
*
|
||||
* Retrieve group control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access public
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
final public function get_fields() {
|
||||
if ( null === static::$fields ) {
|
||||
static::$fields = $this->init_fields();
|
||||
}
|
||||
|
||||
return static::$fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controls prefix.
|
||||
*
|
||||
* Retrieve the prefix of the group control, which is `{{ControlName}}_`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control prefix.
|
||||
*/
|
||||
public function get_controls_prefix() {
|
||||
return $this->args['name'] . '_';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get group control classes.
|
||||
*
|
||||
* Retrieve the classes of the group control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Group control classes.
|
||||
*/
|
||||
public function get_base_group_classes() {
|
||||
return 'elementor-group-control-' . static::get_type() . ' elementor-group-control';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize group control fields.
|
||||
*
|
||||
* @abstract
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*/
|
||||
abstract protected function init_fields();
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the group control. Used to return the
|
||||
* default options while initializing the group control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default group control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child default arguments.
|
||||
*
|
||||
* Retrieve the default arguments for all the child controls for a specific group
|
||||
* control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default arguments for all the child controls.
|
||||
*/
|
||||
protected function get_child_default_args() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter fields.
|
||||
*
|
||||
* Filter which controls to display, using `include`, `exclude` and the
|
||||
* `condition` arguments.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function filter_fields() {
|
||||
$args = $this->get_args();
|
||||
|
||||
$fields = $this->get_fields();
|
||||
|
||||
if ( ! empty( $args['include'] ) ) {
|
||||
$fields = array_intersect_key( $fields, array_flip( $args['include'] ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $args['exclude'] ) ) {
|
||||
$fields = array_diff_key( $fields, array_flip( $args['exclude'] ) );
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add group arguments to field.
|
||||
*
|
||||
* Register field arguments to group control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param string $control_id Group control id.
|
||||
* @param array $field_args Group control field arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function add_group_args_to_field( $control_id, $field_args ) {
|
||||
$args = $this->get_args();
|
||||
|
||||
if ( ! empty( $args['tab'] ) ) {
|
||||
$field_args['tab'] = $args['tab'];
|
||||
}
|
||||
|
||||
if ( ! empty( $args['section'] ) ) {
|
||||
$field_args['section'] = $args['section'];
|
||||
}
|
||||
|
||||
$field_args['classes'] = $this->get_base_group_classes() . ' elementor-group-control-' . $control_id;
|
||||
|
||||
foreach ( [ 'condition', 'conditions' ] as $condition_type ) {
|
||||
if ( ! empty( $args[ $condition_type ] ) ) {
|
||||
if ( empty( $field_args[ $condition_type ] ) ) {
|
||||
$field_args[ $condition_type ] = [];
|
||||
}
|
||||
|
||||
$field_args[ $condition_type ] += $args[ $condition_type ];
|
||||
}
|
||||
}
|
||||
|
||||
return $field_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare fields.
|
||||
*
|
||||
* Process group control fields before adding them to `add_control()`.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param array $fields Group control fields.
|
||||
*
|
||||
* @return array Processed fields.
|
||||
*/
|
||||
protected function prepare_fields( $fields ) {
|
||||
$popover_options = $this->get_options( 'popover' );
|
||||
|
||||
$popover_name = ! $popover_options ? null : $popover_options['starter_name'];
|
||||
|
||||
foreach ( $fields as $field_key => &$field ) {
|
||||
if ( $popover_name ) {
|
||||
$field['condition'][ $popover_name . '!' ] = '';
|
||||
}
|
||||
|
||||
if ( isset( $this->args['fields_options']['__all'] ) ) {
|
||||
$field = array_merge( $field, $this->args['fields_options']['__all'] );
|
||||
}
|
||||
|
||||
if ( isset( $this->args['fields_options'][ $field_key ] ) ) {
|
||||
$field = array_merge( $field, $this->args['fields_options'][ $field_key ] );
|
||||
}
|
||||
|
||||
if ( ! empty( $field['condition'] ) ) {
|
||||
$field = $this->add_condition_prefix( $field );
|
||||
}
|
||||
|
||||
if ( ! empty( $field['conditions'] ) ) {
|
||||
$field['conditions'] = $this->add_conditions_prefix( $field['conditions'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $field['selectors'] ) ) {
|
||||
$field['selectors'] = $this->handle_selectors( $field['selectors'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $field['device_args'] ) ) {
|
||||
foreach ( $field['device_args'] as $device => $device_arg ) {
|
||||
if ( ! empty( $field['device_args'][ $device ]['condition'] ) ) {
|
||||
$field['device_args'][ $device ] = $this->add_condition_prefix( $field['device_args'][ $device ] );
|
||||
}
|
||||
|
||||
if ( ! empty( $field['device_args'][ $device ]['conditions'] ) ) {
|
||||
$field['device_args'][ $device ]['conditions'] = $this->add_conditions_prefix( $field['device_args'][ $device ]['conditions'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $device_arg['selectors'] ) ) {
|
||||
$field['device_args'][ $device ]['selectors'] = $this->handle_selectors( $device_arg['selectors'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init options.
|
||||
*
|
||||
* Initializing group control options.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access private
|
||||
*/
|
||||
private function init_options() {
|
||||
$default_options = [
|
||||
'popover' => [
|
||||
'starter_name' => 'popover_toggle',
|
||||
'starter_value' => 'custom',
|
||||
'starter_title' => '',
|
||||
],
|
||||
];
|
||||
|
||||
$this->options = array_replace_recursive( $default_options, $this->get_default_options() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init arguments.
|
||||
*
|
||||
* Initializing group control base class.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param array $args Group control settings value.
|
||||
*/
|
||||
protected function init_args( $args ) {
|
||||
$this->args = array_merge( $this->get_default_args(), $this->get_child_default_args(), $args );
|
||||
|
||||
if ( isset( $this->args['scheme'] ) ) {
|
||||
$this->args['global']['default'] = Plugin::$instance->kits_manager->convert_scheme_to_global( $this->args['scheme'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default arguments.
|
||||
*
|
||||
* Retrieve the default arguments of the group control. Used to return the
|
||||
* default arguments while initializing the group control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access private
|
||||
*
|
||||
* @return array Control default arguments.
|
||||
*/
|
||||
private function get_default_args() {
|
||||
return [
|
||||
'default' => '',
|
||||
'selector' => '{{WRAPPER}}',
|
||||
'fields_options' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add condition prefix.
|
||||
*
|
||||
* Used to add the group prefix to controls with conditions, to
|
||||
* distinguish them from other controls with the same name.
|
||||
*
|
||||
* This way Elementor can apply condition logic to a specific control in a
|
||||
* group control.
|
||||
*
|
||||
* @since 1.2.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $field Group control field.
|
||||
*
|
||||
* @return array Group control field.
|
||||
*/
|
||||
private function add_condition_prefix( $field ) {
|
||||
$controls_prefix = $this->get_controls_prefix();
|
||||
|
||||
$prefixed_condition_keys = array_map(
|
||||
function( $key ) use ( $controls_prefix ) {
|
||||
return $controls_prefix . $key;
|
||||
},
|
||||
array_keys( $field['condition'] )
|
||||
);
|
||||
|
||||
$field['condition'] = array_combine(
|
||||
$prefixed_condition_keys,
|
||||
$field['condition']
|
||||
);
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
||||
private function add_conditions_prefix( $conditions ) {
|
||||
$controls_prefix = $this->get_controls_prefix();
|
||||
|
||||
foreach ( $conditions['terms'] as & $condition ) {
|
||||
if ( isset( $condition['terms'] ) ) {
|
||||
$condition = $this->add_conditions_prefix( $condition );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$condition['name'] = $controls_prefix . $condition['name'];
|
||||
}
|
||||
|
||||
return $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle selectors.
|
||||
*
|
||||
* Used to process the CSS selector of group control fields. When using
|
||||
* group control, Elementor needs to apply the selector to different fields.
|
||||
* This method handles the process.
|
||||
*
|
||||
* In addition, it handles selector values from other fields and process the
|
||||
* css.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access private
|
||||
*
|
||||
* @param array $selectors An array of selectors to process.
|
||||
*
|
||||
* @return array Processed selectors.
|
||||
*/
|
||||
private function handle_selectors( $selectors ) {
|
||||
$args = $this->get_args();
|
||||
|
||||
$selectors = array_combine(
|
||||
array_map(
|
||||
function( $key ) use ( $args ) {
|
||||
return str_replace( '{{SELECTOR}}', $args['selector'], $key );
|
||||
}, array_keys( $selectors )
|
||||
),
|
||||
$selectors
|
||||
);
|
||||
|
||||
if ( ! $selectors ) {
|
||||
return $selectors;
|
||||
}
|
||||
|
||||
$controls_prefix = $this->get_controls_prefix();
|
||||
|
||||
foreach ( $selectors as &$selector ) {
|
||||
$selector = preg_replace_callback( '/{{\K(.*?)(?=}})/', function( $matches ) use ( $controls_prefix ) {
|
||||
$is_external_reference = false;
|
||||
|
||||
return preg_replace_callback( '/[^ ]+?(?=\.)\./', function( $sub_matches ) use ( $controls_prefix, &$is_external_reference ) {
|
||||
$placeholder = $sub_matches[0];
|
||||
|
||||
if ( 'external.' === $placeholder ) {
|
||||
$is_external_reference = true;
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $is_external_reference ) {
|
||||
$is_external_reference = false;
|
||||
|
||||
return $placeholder;
|
||||
}
|
||||
|
||||
return $controls_prefix . $placeholder;
|
||||
}, $matches[1] );
|
||||
}, $selector );
|
||||
}
|
||||
|
||||
return $selectors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start popover.
|
||||
*
|
||||
* Starts a group controls popover.
|
||||
*
|
||||
* @since 1.9.1
|
||||
* @access private
|
||||
* @param Controls_Stack $element Element.
|
||||
*/
|
||||
private function start_popover( Controls_Stack $element ) {
|
||||
$popover_options = $this->get_options( 'popover' );
|
||||
|
||||
$settings = $this->get_args();
|
||||
|
||||
if ( isset( $settings['global'] ) ) {
|
||||
if ( ! isset( $popover_options['settings']['global'] ) ) {
|
||||
$popover_options['settings']['global'] = [];
|
||||
}
|
||||
|
||||
$popover_options['settings']['global'] = array_replace_recursive( $popover_options['settings']['global'], $settings['global'] );
|
||||
}
|
||||
|
||||
if ( isset( $settings['label'] ) ) {
|
||||
$label = $settings['label'];
|
||||
} else {
|
||||
$label = $popover_options['starter_title'];
|
||||
}
|
||||
|
||||
$control_params = [
|
||||
'type' => Controls_Manager::POPOVER_TOGGLE,
|
||||
'label' => $label,
|
||||
'return_value' => $popover_options['starter_value'],
|
||||
];
|
||||
|
||||
if ( ! empty( $popover_options['settings'] ) ) {
|
||||
$control_params = array_replace_recursive( $control_params, $popover_options['settings'] );
|
||||
}
|
||||
|
||||
foreach ( [ 'condition', 'conditions' ] as $key ) {
|
||||
if ( ! empty( $settings[ $key ] ) ) {
|
||||
$control_params[ $key ] = $settings[ $key ];
|
||||
}
|
||||
}
|
||||
|
||||
$starter_name = $popover_options['starter_name'];
|
||||
|
||||
if ( isset( $this->args['fields_options'][ $starter_name ] ) ) {
|
||||
$control_params = array_merge( $control_params, $this->args['fields_options'][ $starter_name ] );
|
||||
}
|
||||
|
||||
$control_params['groupPrefix'] = $this->get_controls_prefix();
|
||||
|
||||
$element->add_control( $this->get_controls_prefix() . $starter_name, $control_params );
|
||||
|
||||
$element->start_popover();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor border control.
|
||||
*
|
||||
* A base control for creating border control. Displays input fields to define
|
||||
* border type, border width and border color.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Group_Control_Border extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the border control fields.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Border control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Get border control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `border`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'border';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize border control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$fields = [];
|
||||
|
||||
$fields['border'] = [
|
||||
'label' => _x( 'Border Type', 'Border Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => [
|
||||
'' => __( 'None', 'elementor' ),
|
||||
'solid' => _x( 'Solid', 'Border Control', 'elementor' ),
|
||||
'double' => _x( 'Double', 'Border Control', 'elementor' ),
|
||||
'dotted' => _x( 'Dotted', 'Border Control', 'elementor' ),
|
||||
'dashed' => _x( 'Dashed', 'Border Control', 'elementor' ),
|
||||
'groove' => _x( 'Groove', 'Border Control', 'elementor' ),
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'border-style: {{VALUE}};',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['width'] = [
|
||||
'label' => _x( 'Width', 'Border Control', 'elementor' ),
|
||||
'type' => Controls_Manager::DIMENSIONS,
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
|
||||
],
|
||||
'condition' => [
|
||||
'border!' => '',
|
||||
],
|
||||
'responsive' => true,
|
||||
];
|
||||
|
||||
$fields['color'] = [
|
||||
'label' => _x( 'Color', 'Border Control', 'elementor' ),
|
||||
'type' => Controls_Manager::COLOR,
|
||||
'default' => '',
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'border-color: {{VALUE}};',
|
||||
],
|
||||
'condition' => [
|
||||
'border!' => '',
|
||||
],
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the border control. Used to return the
|
||||
* default options while initializing the border control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default border control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor box shadow control.
|
||||
*
|
||||
* A base control for creating box shadow control. Displays input fields to define
|
||||
* the box shadow including the horizontal shadow, vertical shadow, shadow blur,
|
||||
* shadow spread, shadow color and the position.
|
||||
*
|
||||
* @since 1.2.2
|
||||
*/
|
||||
class Group_Control_Box_Shadow extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the box shadow control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Box shadow control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Get box shadow control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `box-shadow`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'box-shadow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize box shadow control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$controls = [];
|
||||
|
||||
$controls['box_shadow'] = [
|
||||
'label' => _x( 'Box Shadow', 'Box Shadow Control', 'elementor' ),
|
||||
'type' => Controls_Manager::BOX_SHADOW,
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'box-shadow: {{HORIZONTAL}}px {{VERTICAL}}px {{BLUR}}px {{SPREAD}}px {{COLOR}} {{box_shadow_position.VALUE}};',
|
||||
],
|
||||
];
|
||||
|
||||
$controls['box_shadow_position'] = [
|
||||
'label' => _x( 'Position', 'Box Shadow Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'options' => [
|
||||
' ' => _x( 'Outline', 'Box Shadow Control', 'elementor' ),
|
||||
'inset' => _x( 'Inset', 'Box Shadow Control', 'elementor' ),
|
||||
],
|
||||
'default' => ' ',
|
||||
'render_type' => 'ui',
|
||||
];
|
||||
|
||||
return $controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the box shadow control. Used to return the
|
||||
* default options while initializing the box shadow control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default box shadow control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => [
|
||||
'starter_title' => _x( 'Box Shadow', 'Box Shadow Control', 'elementor' ),
|
||||
'starter_name' => 'box_shadow_type',
|
||||
'starter_value' => 'yes',
|
||||
'settings' => [
|
||||
'render_type' => 'ui',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor CSS Filter control.
|
||||
*
|
||||
* A base control for applying css filters. Displays sliders to define the
|
||||
* values of different CSS filters including blur, brightens, contrast,
|
||||
* saturation and hue.
|
||||
*
|
||||
* @since 2.1.0
|
||||
*/
|
||||
class Group_Control_Css_Filter extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Prepare fields.
|
||||
*
|
||||
* Process css_filter control fields before adding them to `add_control()`.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $fields CSS filter control fields.
|
||||
*
|
||||
* @return array Processed fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Get CSS filter control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `css-filter`.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'css-filter';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize CSS filter control fields.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$controls = [];
|
||||
|
||||
$controls['blur'] = [
|
||||
'label' => _x( 'Blur', 'Filter Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'required' => 'true',
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 10,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'default' => [
|
||||
'size' => 0,
|
||||
],
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'filter: brightness( {{brightness.SIZE}}% ) contrast( {{contrast.SIZE}}% ) saturate( {{saturate.SIZE}}% ) blur( {{blur.SIZE}}px ) hue-rotate( {{hue.SIZE}}deg )',
|
||||
],
|
||||
];
|
||||
|
||||
$controls['brightness'] = [
|
||||
'label' => _x( 'Brightness', 'Filter Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'render_type' => 'ui',
|
||||
'required' => 'true',
|
||||
'default' => [
|
||||
'size' => 100,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 200,
|
||||
],
|
||||
],
|
||||
'separator' => 'none',
|
||||
];
|
||||
|
||||
$controls['contrast'] = [
|
||||
'label' => _x( 'Contrast', 'Filter Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'render_type' => 'ui',
|
||||
'required' => 'true',
|
||||
'default' => [
|
||||
'size' => 100,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 200,
|
||||
],
|
||||
],
|
||||
'separator' => 'none',
|
||||
];
|
||||
|
||||
$controls['saturate'] = [
|
||||
'label' => _x( 'Saturation', 'Filter Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'render_type' => 'ui',
|
||||
'required' => 'true',
|
||||
'default' => [
|
||||
'size' => 100,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 200,
|
||||
],
|
||||
],
|
||||
'separator' => 'none',
|
||||
];
|
||||
|
||||
$controls['hue'] = [
|
||||
'label' => _x( 'Hue', 'Filter Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'render_type' => 'ui',
|
||||
'required' => 'true',
|
||||
'default' => [
|
||||
'size' => 0,
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 0,
|
||||
'max' => 360,
|
||||
],
|
||||
],
|
||||
'separator' => 'none',
|
||||
];
|
||||
|
||||
return $controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the CSS filter control. Used to return the
|
||||
* default options while initializing the CSS filter control.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default CSS filter control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => [
|
||||
'starter_name' => 'css_filter',
|
||||
'starter_title' => _x( 'CSS Filters', 'Filter Control', 'elementor' ),
|
||||
'settings' => [
|
||||
'render_type' => 'ui',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,381 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor image size control.
|
||||
*
|
||||
* A base control for creating image size control. Displays input fields to define
|
||||
* one of the default image sizes (thumbnail, medium, medium_large, large) or custom
|
||||
* image dimensions.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Group_Control_Image_Size extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the image size control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Image size control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Get image size control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `image-size`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'image-size';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment image HTML.
|
||||
*
|
||||
* Retrieve the attachment image HTML code.
|
||||
*
|
||||
* Note that some widgets use the same key for the media control that allows
|
||||
* the image selection and for the image size control that allows the user
|
||||
* to select the image size, in this case the third parameter should be null
|
||||
* or the same as the second parameter. But when the widget uses different
|
||||
* keys for the media control and the image size control, when calling this
|
||||
* method you should pass the keys.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $settings Control settings.
|
||||
* @param string $image_size_key Optional. Settings key for image size.
|
||||
* Default is `image`.
|
||||
* @param string $image_key Optional. Settings key for image. Default
|
||||
* is null. If not defined uses image size key
|
||||
* as the image key.
|
||||
*
|
||||
* @return string Image HTML.
|
||||
*/
|
||||
public static function get_attachment_image_html( $settings, $image_size_key = 'image', $image_key = null ) {
|
||||
if ( ! $image_key ) {
|
||||
$image_key = $image_size_key;
|
||||
}
|
||||
|
||||
$image = $settings[ $image_key ];
|
||||
|
||||
// Old version of image settings.
|
||||
if ( ! isset( $settings[ $image_size_key . '_size' ] ) ) {
|
||||
$settings[ $image_size_key . '_size' ] = '';
|
||||
}
|
||||
|
||||
$size = $settings[ $image_size_key . '_size' ];
|
||||
|
||||
$image_class = ! empty( $settings['hover_animation'] ) ? 'elementor-animation-' . $settings['hover_animation'] : '';
|
||||
|
||||
$html = '';
|
||||
|
||||
// If is the new version - with image size.
|
||||
$image_sizes = get_intermediate_image_sizes();
|
||||
|
||||
$image_sizes[] = 'full';
|
||||
|
||||
if ( ! empty( $image['id'] ) && ! wp_attachment_is_image( $image['id'] ) ) {
|
||||
$image['id'] = '';
|
||||
}
|
||||
|
||||
$is_static_render_mode = Plugin::$instance->frontend->is_static_render_mode();
|
||||
|
||||
// On static mode don't use WP responsive images.
|
||||
if ( ! empty( $image['id'] ) && in_array( $size, $image_sizes ) && ! $is_static_render_mode ) {
|
||||
$image_class .= " attachment-$size size-$size";
|
||||
$image_attr = [
|
||||
'class' => trim( $image_class ),
|
||||
];
|
||||
|
||||
$html .= wp_get_attachment_image( $image['id'], $size, false, $image_attr );
|
||||
} else {
|
||||
$image_src = self::get_attachment_image_src( $image['id'], $image_size_key, $settings );
|
||||
|
||||
if ( ! $image_src && isset( $image['url'] ) ) {
|
||||
$image_src = $image['url'];
|
||||
}
|
||||
|
||||
if ( ! empty( $image_src ) ) {
|
||||
$image_class_html = ! empty( $image_class ) ? ' class="' . $image_class . '"' : '';
|
||||
|
||||
$html .= sprintf( '<img src="%s" title="%s" alt="%s"%s />', esc_attr( $image_src ), Control_Media::get_image_title( $image ), Control_Media::get_image_alt( $image ), $image_class_html );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Attachment Image HTML
|
||||
*
|
||||
* Filters the Attachment Image HTML
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @param string $html the attachment image HTML string
|
||||
* @param array $settings Control settings.
|
||||
* @param string $image_size_key Optional. Settings key for image size.
|
||||
* Default is `image`.
|
||||
* @param string $image_key Optional. Settings key for image. Default
|
||||
* is null. If not defined uses image size key
|
||||
* as the image key.
|
||||
*/
|
||||
return apply_filters( 'elementor/image_size/get_attachment_image_html', $html, $settings, $image_size_key, $image_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all image sizes.
|
||||
*
|
||||
* Retrieve available image sizes with data like `width`, `height` and `crop`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array An array of available image sizes.
|
||||
*/
|
||||
public static function get_all_image_sizes() {
|
||||
global $_wp_additional_image_sizes;
|
||||
|
||||
$default_image_sizes = [ 'thumbnail', 'medium', 'medium_large', 'large' ];
|
||||
|
||||
$image_sizes = [];
|
||||
|
||||
foreach ( $default_image_sizes as $size ) {
|
||||
$image_sizes[ $size ] = [
|
||||
'width' => (int) get_option( $size . '_size_w' ),
|
||||
'height' => (int) get_option( $size . '_size_h' ),
|
||||
'crop' => (bool) get_option( $size . '_crop' ),
|
||||
];
|
||||
}
|
||||
|
||||
if ( $_wp_additional_image_sizes ) {
|
||||
$image_sizes = array_merge( $image_sizes, $_wp_additional_image_sizes );
|
||||
}
|
||||
|
||||
/** This filter is documented in wp-admin/includes/media.php */
|
||||
return apply_filters( 'image_size_names_choose', $image_sizes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attachment image src.
|
||||
*
|
||||
* Retrieve the attachment image source URL.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $attachment_id The attachment ID.
|
||||
* @param string $image_size_key Settings key for image size.
|
||||
* @param array $settings Control settings.
|
||||
*
|
||||
* @return string Attachment image source URL.
|
||||
*/
|
||||
public static function get_attachment_image_src( $attachment_id, $image_size_key, array $settings ) {
|
||||
if ( empty( $attachment_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$size = $settings[ $image_size_key . '_size' ];
|
||||
|
||||
if ( 'custom' !== $size ) {
|
||||
$attachment_size = $size;
|
||||
} else {
|
||||
// Use BFI_Thumb script
|
||||
// TODO: Please rewrite this code.
|
||||
require_once ELEMENTOR_PATH . 'includes/libraries/bfi-thumb/bfi-thumb.php';
|
||||
|
||||
$custom_dimension = $settings[ $image_size_key . '_custom_dimension' ];
|
||||
|
||||
$attachment_size = [
|
||||
// Defaults sizes
|
||||
0 => null, // Width.
|
||||
1 => null, // Height.
|
||||
|
||||
'bfi_thumb' => true,
|
||||
'crop' => true,
|
||||
];
|
||||
|
||||
$has_custom_size = false;
|
||||
if ( ! empty( $custom_dimension['width'] ) ) {
|
||||
$has_custom_size = true;
|
||||
$attachment_size[0] = $custom_dimension['width'];
|
||||
}
|
||||
|
||||
if ( ! empty( $custom_dimension['height'] ) ) {
|
||||
$has_custom_size = true;
|
||||
$attachment_size[1] = $custom_dimension['height'];
|
||||
}
|
||||
|
||||
if ( ! $has_custom_size ) {
|
||||
$attachment_size = 'full';
|
||||
}
|
||||
}
|
||||
|
||||
$image_src = wp_get_attachment_image_src( $attachment_id, $attachment_size );
|
||||
|
||||
if ( empty( $image_src[0] ) && 'thumbnail' !== $attachment_size ) {
|
||||
$image_src = wp_get_attachment_image_src( $attachment_id );
|
||||
}
|
||||
|
||||
return ! empty( $image_src[0] ) ? $image_src[0] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get child default arguments.
|
||||
*
|
||||
* Retrieve the default arguments for all the child controls for a specific group
|
||||
* control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default arguments for all the child controls.
|
||||
*/
|
||||
protected function get_child_default_args() {
|
||||
return [
|
||||
'include' => [],
|
||||
'exclude' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize image size control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$fields = [];
|
||||
|
||||
$fields['size'] = [
|
||||
'label' => _x( 'Image Size', 'Image Size Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
];
|
||||
|
||||
$fields['custom_dimension'] = [
|
||||
'label' => _x( 'Image Dimension', 'Image Size Control', 'elementor' ),
|
||||
'type' => Controls_Manager::IMAGE_DIMENSIONS,
|
||||
'description' => __( 'You can crop the original image size to any custom size. You can also set a single value for height or width in order to keep the original size ratio.', 'elementor' ),
|
||||
'condition' => [
|
||||
'size' => 'custom',
|
||||
],
|
||||
'separator' => 'none',
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare fields.
|
||||
*
|
||||
* Process image size control fields before adding them to `add_control()`.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param array $fields Image size control fields.
|
||||
*
|
||||
* @return array Processed fields.
|
||||
*/
|
||||
protected function prepare_fields( $fields ) {
|
||||
$image_sizes = $this->get_image_sizes();
|
||||
|
||||
$args = $this->get_args();
|
||||
|
||||
if ( ! empty( $args['default'] ) && isset( $image_sizes[ $args['default'] ] ) ) {
|
||||
$default_value = $args['default'];
|
||||
} else {
|
||||
// Get the first item for default value.
|
||||
$default_value = array_keys( $image_sizes );
|
||||
$default_value = array_shift( $default_value );
|
||||
}
|
||||
|
||||
$fields['size']['options'] = $image_sizes;
|
||||
|
||||
$fields['size']['default'] = $default_value;
|
||||
|
||||
if ( ! isset( $image_sizes['custom'] ) ) {
|
||||
unset( $fields['custom_dimension'] );
|
||||
}
|
||||
|
||||
return parent::prepare_fields( $fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image sizes.
|
||||
*
|
||||
* Retrieve available image sizes after filtering `include` and `exclude` arguments.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @return array Filtered image sizes.
|
||||
*/
|
||||
private function get_image_sizes() {
|
||||
$wp_image_sizes = self::get_all_image_sizes();
|
||||
|
||||
$args = $this->get_args();
|
||||
|
||||
if ( $args['include'] ) {
|
||||
$wp_image_sizes = array_intersect_key( $wp_image_sizes, array_flip( $args['include'] ) );
|
||||
} elseif ( $args['exclude'] ) {
|
||||
$wp_image_sizes = array_diff_key( $wp_image_sizes, array_flip( $args['exclude'] ) );
|
||||
}
|
||||
|
||||
$image_sizes = [];
|
||||
|
||||
foreach ( $wp_image_sizes as $size_key => $size_attributes ) {
|
||||
$control_title = ucwords( str_replace( '_', ' ', $size_key ) );
|
||||
if ( is_array( $size_attributes ) ) {
|
||||
$control_title .= sprintf( ' - %d x %d', $size_attributes['width'], $size_attributes['height'] );
|
||||
}
|
||||
|
||||
$image_sizes[ $size_key ] = $control_title;
|
||||
}
|
||||
|
||||
$image_sizes['full'] = _x( 'Full', 'Image Size Control', 'elementor' );
|
||||
|
||||
if ( ! empty( $args['include']['custom'] ) || ! in_array( 'custom', $args['exclude'] ) ) {
|
||||
$image_sizes['custom'] = _x( 'Custom', 'Image Size Control', 'elementor' );
|
||||
}
|
||||
|
||||
return $image_sizes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the image size control. Used to return the
|
||||
* default options while initializing the image size control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default image size control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor text shadow control.
|
||||
*
|
||||
* A base control for creating text shadow control. Displays input fields to define
|
||||
* the text shadow including the horizontal shadow, vertical shadow, shadow blur and
|
||||
* shadow color.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Group_Control_Text_Shadow extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the text shadow control fields.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Text shadow control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Get text shadow control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `text-shadow`.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'text-shadow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize text shadow control fields.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$controls = [];
|
||||
|
||||
$controls['text_shadow'] = [
|
||||
'label' => _x( 'Text Shadow', 'Text Shadow Control', 'elementor' ),
|
||||
'type' => Controls_Manager::TEXT_SHADOW,
|
||||
'selectors' => [
|
||||
'{{SELECTOR}}' => 'text-shadow: {{HORIZONTAL}}px {{VERTICAL}}px {{BLUR}}px {{COLOR}};',
|
||||
],
|
||||
];
|
||||
|
||||
return $controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the text shadow control. Used to return the
|
||||
* default options while initializing the text shadow control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default text shadow control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => [
|
||||
'starter_title' => _x( 'Text Shadow', 'Text Shadow Control', 'elementor' ),
|
||||
'starter_name' => 'text_shadow_type',
|
||||
'starter_value' => 'yes',
|
||||
'settings' => [
|
||||
'render_type' => 'ui',
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Settings\Page\Manager as PageManager;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor typography control.
|
||||
*
|
||||
* A base control for creating typography control. Displays input fields to define
|
||||
* the content typography including font size, font family, font weight, text
|
||||
* transform, font style, line height and letter spacing.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Group_Control_Typography extends Group_Control_Base {
|
||||
|
||||
/**
|
||||
* Fields.
|
||||
*
|
||||
* Holds all the typography control fields.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
* @static
|
||||
*
|
||||
* @var array Typography control fields.
|
||||
*/
|
||||
protected static $fields;
|
||||
|
||||
/**
|
||||
* Scheme fields keys.
|
||||
*
|
||||
* Holds all the typography control scheme fields keys.
|
||||
* Default is an array containing `font_family` and `font_weight`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Typography control scheme fields keys.
|
||||
*/
|
||||
private static $_scheme_fields_keys = [ 'font_family', 'font_weight' ];
|
||||
|
||||
/**
|
||||
* Get scheme fields keys.
|
||||
*
|
||||
* Retrieve all the available typography control scheme fields keys.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Scheme fields keys.
|
||||
*/
|
||||
public static function get_scheme_fields_keys() {
|
||||
return self::$_scheme_fields_keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get typography control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `typography`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'typography';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init fields.
|
||||
*
|
||||
* Initialize typography control fields.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control fields.
|
||||
*/
|
||||
protected function init_fields() {
|
||||
$fields = [];
|
||||
|
||||
$kit = Plugin::$instance->kits_manager->get_active_kit_for_frontend();
|
||||
|
||||
/**
|
||||
* Retrieve the settings directly from DB, because of an open issue when a controls group is being initialized
|
||||
* from within another group
|
||||
*/
|
||||
$kit_settings = $kit->get_meta( PageManager::META_KEY );
|
||||
|
||||
$default_fonts = isset( $kit_settings['default_generic_fonts'] ) ? $kit_settings['default_generic_fonts'] : 'Sans-serif';
|
||||
|
||||
if ( $default_fonts ) {
|
||||
$default_fonts = ', ' . $default_fonts;
|
||||
}
|
||||
|
||||
$fields['font_family'] = [
|
||||
'label' => _x( 'Family', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::FONT,
|
||||
'default' => '',
|
||||
'selector_value' => 'font-family: "{{VALUE}}"' . $default_fonts . ';',
|
||||
];
|
||||
|
||||
$fields['font_size'] = [
|
||||
'label' => _x( 'Size', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'size_units' => [ 'px', 'em', 'rem', 'vw' ],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 1,
|
||||
'max' => 200,
|
||||
],
|
||||
'vw' => [
|
||||
'min' => 0.1,
|
||||
'max' => 10,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'responsive' => true,
|
||||
'selector_value' => 'font-size: {{SIZE}}{{UNIT}}',
|
||||
];
|
||||
|
||||
$typo_weight_options = [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
];
|
||||
|
||||
foreach ( array_merge( [ 'normal', 'bold' ], range( 100, 900, 100 ) ) as $weight ) {
|
||||
$typo_weight_options[ $weight ] = ucfirst( $weight );
|
||||
}
|
||||
|
||||
$fields['font_weight'] = [
|
||||
'label' => _x( 'Weight', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'options' => $typo_weight_options,
|
||||
];
|
||||
|
||||
$fields['text_transform'] = [
|
||||
'label' => _x( 'Transform', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'uppercase' => _x( 'Uppercase', 'Typography Control', 'elementor' ),
|
||||
'lowercase' => _x( 'Lowercase', 'Typography Control', 'elementor' ),
|
||||
'capitalize' => _x( 'Capitalize', 'Typography Control', 'elementor' ),
|
||||
'none' => _x( 'Normal', 'Typography Control', 'elementor' ),
|
||||
],
|
||||
];
|
||||
|
||||
$fields['font_style'] = [
|
||||
'label' => _x( 'Style', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'normal' => _x( 'Normal', 'Typography Control', 'elementor' ),
|
||||
'italic' => _x( 'Italic', 'Typography Control', 'elementor' ),
|
||||
'oblique' => _x( 'Oblique', 'Typography Control', 'elementor' ),
|
||||
],
|
||||
];
|
||||
|
||||
$fields['text_decoration'] = [
|
||||
'label' => _x( 'Decoration', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SELECT,
|
||||
'default' => '',
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'underline' => _x( 'Underline', 'Typography Control', 'elementor' ),
|
||||
'overline' => _x( 'Overline', 'Typography Control', 'elementor' ),
|
||||
'line-through' => _x( 'Line Through', 'Typography Control', 'elementor' ),
|
||||
'none' => _x( 'None', 'Typography Control', 'elementor' ),
|
||||
],
|
||||
];
|
||||
|
||||
$fields['line_height'] = [
|
||||
'label' => _x( 'Line-Height', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'desktop_default' => [
|
||||
'unit' => 'em',
|
||||
],
|
||||
'tablet_default' => [
|
||||
'unit' => 'em',
|
||||
],
|
||||
'mobile_default' => [
|
||||
'unit' => 'em',
|
||||
],
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => 1,
|
||||
],
|
||||
],
|
||||
'responsive' => true,
|
||||
'size_units' => [ 'px', 'em' ],
|
||||
'selector_value' => 'line-height: {{SIZE}}{{UNIT}}',
|
||||
];
|
||||
|
||||
$fields['letter_spacing'] = [
|
||||
'label' => _x( 'Letter Spacing', 'Typography Control', 'elementor' ),
|
||||
'type' => Controls_Manager::SLIDER,
|
||||
'range' => [
|
||||
'px' => [
|
||||
'min' => -5,
|
||||
'max' => 10,
|
||||
'step' => 0.1,
|
||||
],
|
||||
],
|
||||
'responsive' => true,
|
||||
'selector_value' => 'letter-spacing: {{SIZE}}{{UNIT}}',
|
||||
];
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare fields.
|
||||
*
|
||||
* Process typography control fields before adding them to `add_control()`.
|
||||
*
|
||||
* @since 1.2.3
|
||||
* @access protected
|
||||
*
|
||||
* @param array $fields Typography control fields.
|
||||
*
|
||||
* @return array Processed fields.
|
||||
*/
|
||||
protected function prepare_fields( $fields ) {
|
||||
array_walk(
|
||||
$fields, function( &$field, $field_name ) {
|
||||
|
||||
if ( in_array( $field_name, [ 'typography', 'popover_toggle' ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$selector_value = ! empty( $field['selector_value'] ) ? $field['selector_value'] : str_replace( '_', '-', $field_name ) . ': {{VALUE}};';
|
||||
|
||||
$field['selectors'] = [
|
||||
'{{SELECTOR}}' => $selector_value,
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
return parent::prepare_fields( $fields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add group arguments to field.
|
||||
*
|
||||
* Register field arguments to typography control.
|
||||
*
|
||||
* @since 1.2.2
|
||||
* @access protected
|
||||
*
|
||||
* @param string $control_id Typography control id.
|
||||
* @param array $field_args Typography control field arguments.
|
||||
*
|
||||
* @return array Field arguments.
|
||||
*/
|
||||
protected function add_group_args_to_field( $control_id, $field_args ) {
|
||||
$field_args = parent::add_group_args_to_field( $control_id, $field_args );
|
||||
|
||||
$field_args['groupPrefix'] = $this->get_controls_prefix();
|
||||
$field_args['groupType'] = 'typography';
|
||||
|
||||
$args = $this->get_args();
|
||||
|
||||
if ( in_array( $control_id, self::get_scheme_fields_keys() ) && ! empty( $args['scheme'] ) ) {
|
||||
$field_args['scheme'] = [
|
||||
'type' => self::get_type(),
|
||||
'value' => $args['scheme'],
|
||||
'key' => $control_id,
|
||||
];
|
||||
}
|
||||
|
||||
return $field_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default options.
|
||||
*
|
||||
* Retrieve the default options of the typography control. Used to return the
|
||||
* default options while initializing the typography control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Default typography control options.
|
||||
*/
|
||||
protected function get_default_options() {
|
||||
return [
|
||||
'popover' => [
|
||||
'starter_name' => 'typography',
|
||||
'starter_title' => _x( 'Typography', 'Typography Control', 'elementor' ),
|
||||
'settings' => [
|
||||
'render_type' => 'ui',
|
||||
'groupType' => 'typography',
|
||||
'global' => [
|
||||
'active' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor heading control.
|
||||
*
|
||||
* A base control for creating heading control. Displays a text heading between
|
||||
* controls in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Heading extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get heading control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `heading`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'heading';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get heading control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the heading control. Used to return the
|
||||
* default settings while initializing the heading control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render heading control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<h3 class="elementor-control-title">{{ data.label }}</h3>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor hidden control.
|
||||
*
|
||||
* A base control for creating hidden control. Used to save additional data in
|
||||
* the database without a visual presentation in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Hidden extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get hidden control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `hidden`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'hidden';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render hidden control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<input type="hidden" data-setting="{{{ data.name }}}" />
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor hover animation control.
|
||||
*
|
||||
* A base control for creating hover animation control. Displays a select box
|
||||
* with the available hover animation effects @see Control_Hover_Animation::get_animations()
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Hover_Animation extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Animations.
|
||||
*
|
||||
* Holds all the available hover animation effects of the control.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $_animations;
|
||||
|
||||
/**
|
||||
* Get hover animation control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `hover_animation`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'hover_animation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get animations.
|
||||
*
|
||||
* Retrieve the available hover animation effects.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Available hover animation.
|
||||
*/
|
||||
public static function get_animations() {
|
||||
if ( is_null( self::$_animations ) ) {
|
||||
self::$_animations = [
|
||||
'grow' => 'Grow',
|
||||
'shrink' => 'Shrink',
|
||||
'pulse' => 'Pulse',
|
||||
'pulse-grow' => 'Pulse Grow',
|
||||
'pulse-shrink' => 'Pulse Shrink',
|
||||
'push' => 'Push',
|
||||
'pop' => 'Pop',
|
||||
'bounce-in' => 'Bounce In',
|
||||
'bounce-out' => 'Bounce Out',
|
||||
'rotate' => 'Rotate',
|
||||
'grow-rotate' => 'Grow Rotate',
|
||||
'float' => 'Float',
|
||||
'sink' => 'Sink',
|
||||
'bob' => 'Bob',
|
||||
'hang' => 'Hang',
|
||||
'skew' => 'Skew',
|
||||
'skew-forward' => 'Skew Forward',
|
||||
'skew-backward' => 'Skew Backward',
|
||||
'wobble-vertical' => 'Wobble Vertical',
|
||||
'wobble-horizontal' => 'Wobble Horizontal',
|
||||
'wobble-to-bottom-right' => 'Wobble To Bottom Right',
|
||||
'wobble-to-top-right' => 'Wobble To Top Right',
|
||||
'wobble-top' => 'Wobble Top',
|
||||
'wobble-bottom' => 'Wobble Bottom',
|
||||
'wobble-skew' => 'Wobble Skew',
|
||||
'buzz' => 'Buzz',
|
||||
'buzz-out' => 'Buzz Out',
|
||||
];
|
||||
|
||||
$additional_animations = [];
|
||||
/**
|
||||
* Element hover animations list.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @param array $additional_animations Additional Animations array.
|
||||
*/
|
||||
$additional_animations = apply_filters( 'elementor/controls/hover_animations/additional_animations', $additional_animations );
|
||||
self::$_animations = array_merge( self::$_animations, $additional_animations );
|
||||
}
|
||||
|
||||
return self::$_animations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render hover animation control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<select id="<?php echo $control_uid; ?>" data-setting="{{ data.name }}">
|
||||
<option value=""><?php echo __( 'None', 'elementor' ); ?></option>
|
||||
<?php foreach ( self::get_animations() as $animation_name => $animation_title ) : ?>
|
||||
<option value="<?php echo $animation_name; ?>"><?php echo $animation_title; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get hover animation control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the hover animation control. Used to return
|
||||
* the default settings while initializing the hover animation control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,885 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor icon control.
|
||||
*
|
||||
* A base control for creating an icon control. Displays a font icon select box
|
||||
* field. The control accepts `include` or `exclude` arguments to set a partial
|
||||
* list of icons.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Icon extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get icon control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `icon`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'icon';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get icons.
|
||||
*
|
||||
* Retrieve all the available icons.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Available icons.
|
||||
*/
|
||||
public static function get_icons() {
|
||||
return [
|
||||
'fa fa-500px' => '500px',
|
||||
'fa fa-address-book' => 'address-book',
|
||||
'fa fa-address-book-o' => 'address-book-o',
|
||||
'fa fa-address-card' => 'address-card',
|
||||
'fa fa-address-card-o' => 'address-card-o',
|
||||
'fa fa-adjust' => 'adjust',
|
||||
'fa fa-adn' => 'adn',
|
||||
'fa fa-align-center' => 'align-center',
|
||||
'fa fa-align-justify' => 'align-justify',
|
||||
'fa fa-align-left' => 'align-left',
|
||||
'fa fa-align-right' => 'align-right',
|
||||
'fa fa-amazon' => 'amazon',
|
||||
'fa fa-ambulance' => 'ambulance',
|
||||
'fa fa-american-sign-language-interpreting' => 'american-sign-language-interpreting',
|
||||
'fa fa-anchor' => 'anchor',
|
||||
'fa fa-android' => 'android',
|
||||
'fa fa-angellist' => 'angellist',
|
||||
'fa fa-angle-double-down' => 'angle-double-down',
|
||||
'fa fa-angle-double-left' => 'angle-double-left',
|
||||
'fa fa-angle-double-right' => 'angle-double-right',
|
||||
'fa fa-angle-double-up' => 'angle-double-up',
|
||||
'fa fa-angle-down' => 'angle-down',
|
||||
'fa fa-angle-left' => 'angle-left',
|
||||
'fa fa-angle-right' => 'angle-right',
|
||||
'fa fa-angle-up' => 'angle-up',
|
||||
'fa fa-apple' => 'apple',
|
||||
'fa fa-archive' => 'archive',
|
||||
'fa fa-area-chart' => 'area-chart',
|
||||
'fa fa-arrow-circle-down' => 'arrow-circle-down',
|
||||
'fa fa-arrow-circle-left' => 'arrow-circle-left',
|
||||
'fa fa-arrow-circle-o-down' => 'arrow-circle-o-down',
|
||||
'fa fa-arrow-circle-o-left' => 'arrow-circle-o-left',
|
||||
'fa fa-arrow-circle-o-right' => 'arrow-circle-o-right',
|
||||
'fa fa-arrow-circle-o-up' => 'arrow-circle-o-up',
|
||||
'fa fa-arrow-circle-right' => 'arrow-circle-right',
|
||||
'fa fa-arrow-circle-up' => 'arrow-circle-up',
|
||||
'fa fa-arrow-down' => 'arrow-down',
|
||||
'fa fa-arrow-left' => 'arrow-left',
|
||||
'fa fa-arrow-right' => 'arrow-right',
|
||||
'fa fa-arrow-up' => 'arrow-up',
|
||||
'fa fa-arrows' => 'arrows',
|
||||
'fa fa-arrows-alt' => 'arrows-alt',
|
||||
'fa fa-arrows-h' => 'arrows-h',
|
||||
'fa fa-arrows-v' => 'arrows-v',
|
||||
'fa fa-asl-interpreting' => 'asl-interpreting',
|
||||
'fa fa-assistive-listening-systems' => 'assistive-listening-systems',
|
||||
'fa fa-asterisk' => 'asterisk',
|
||||
'fa fa-at' => 'at',
|
||||
'fa fa-audio-description' => 'audio-description',
|
||||
'fa fa-automobile' => 'automobile',
|
||||
'fa fa-backward' => 'backward',
|
||||
'fa fa-balance-scale' => 'balance-scale',
|
||||
'fa fa-ban' => 'ban',
|
||||
'fa fa-bandcamp' => 'bandcamp',
|
||||
'fa fa-bank' => 'bank',
|
||||
'fa fa-bar-chart' => 'bar-chart',
|
||||
'fa fa-bar-chart-o' => 'bar-chart-o',
|
||||
'fa fa-barcode' => 'barcode',
|
||||
'fa fa-bars' => 'bars',
|
||||
'fa fa-bath' => 'bath',
|
||||
'fa fa-bathtub' => 'bathtub',
|
||||
'fa fa-battery' => 'battery',
|
||||
'fa fa-battery-0' => 'battery-0',
|
||||
'fa fa-battery-1' => 'battery-1',
|
||||
'fa fa-battery-2' => 'battery-2',
|
||||
'fa fa-battery-3' => 'battery-3',
|
||||
'fa fa-battery-4' => 'battery-4',
|
||||
'fa fa-battery-empty' => 'battery-empty',
|
||||
'fa fa-battery-full' => 'battery-full',
|
||||
'fa fa-battery-half' => 'battery-half',
|
||||
'fa fa-battery-quarter' => 'battery-quarter',
|
||||
'fa fa-battery-three-quarters' => 'battery-three-quarters',
|
||||
'fa fa-bed' => 'bed',
|
||||
'fa fa-beer' => 'beer',
|
||||
'fa fa-behance' => 'behance',
|
||||
'fa fa-behance-square' => 'behance-square',
|
||||
'fa fa-bell' => 'bell',
|
||||
'fa fa-bell-o' => 'bell-o',
|
||||
'fa fa-bell-slash' => 'bell-slash',
|
||||
'fa fa-bell-slash-o' => 'bell-slash-o',
|
||||
'fa fa-bicycle' => 'bicycle',
|
||||
'fa fa-binoculars' => 'binoculars',
|
||||
'fa fa-birthday-cake' => 'birthday-cake',
|
||||
'fa fa-bitbucket' => 'bitbucket',
|
||||
'fa fa-bitbucket-square' => 'bitbucket-square',
|
||||
'fa fa-bitcoin' => 'bitcoin',
|
||||
'fa fa-black-tie' => 'black-tie',
|
||||
'fa fa-blind' => 'blind',
|
||||
'fa fa-bluetooth' => 'bluetooth',
|
||||
'fa fa-bluetooth-b' => 'bluetooth-b',
|
||||
'fa fa-bold' => 'bold',
|
||||
'fa fa-bolt' => 'bolt',
|
||||
'fa fa-bomb' => 'bomb',
|
||||
'fa fa-book' => 'book',
|
||||
'fa fa-bookmark' => 'bookmark',
|
||||
'fa fa-bookmark-o' => 'bookmark-o',
|
||||
'fa fa-braille' => 'braille',
|
||||
'fa fa-briefcase' => 'briefcase',
|
||||
'fa fa-btc' => 'btc',
|
||||
'fa fa-bug' => 'bug',
|
||||
'fa fa-building' => 'building',
|
||||
'fa fa-building-o' => 'building-o',
|
||||
'fa fa-bullhorn' => 'bullhorn',
|
||||
'fa fa-bullseye' => 'bullseye',
|
||||
'fa fa-bus' => 'bus',
|
||||
'fa fa-buysellads' => 'buysellads',
|
||||
'fa fa-cab' => 'cab',
|
||||
'fa fa-calculator' => 'calculator',
|
||||
'fa fa-calendar' => 'calendar',
|
||||
'fa fa-calendar-check-o' => 'calendar-check-o',
|
||||
'fa fa-calendar-minus-o' => 'calendar-minus-o',
|
||||
'fa fa-calendar-o' => 'calendar-o',
|
||||
'fa fa-calendar-plus-o' => 'calendar-plus-o',
|
||||
'fa fa-calendar-times-o' => 'calendar-times-o',
|
||||
'fa fa-camera' => 'camera',
|
||||
'fa fa-camera-retro' => 'camera-retro',
|
||||
'fa fa-car' => 'car',
|
||||
'fa fa-caret-down' => 'caret-down',
|
||||
'fa fa-caret-left' => 'caret-left',
|
||||
'fa fa-caret-right' => 'caret-right',
|
||||
'fa fa-caret-square-o-down' => 'caret-square-o-down',
|
||||
'fa fa-caret-square-o-left' => 'caret-square-o-left',
|
||||
'fa fa-caret-square-o-right' => 'caret-square-o-right',
|
||||
'fa fa-caret-square-o-up' => 'caret-square-o-up',
|
||||
'fa fa-caret-up' => 'caret-up',
|
||||
'fa fa-cart-arrow-down' => 'cart-arrow-down',
|
||||
'fa fa-cart-plus' => 'cart-plus',
|
||||
'fa fa-cc' => 'cc',
|
||||
'fa fa-cc-amex' => 'cc-amex',
|
||||
'fa fa-cc-diners-club' => 'cc-diners-club',
|
||||
'fa fa-cc-discover' => 'cc-discover',
|
||||
'fa fa-cc-jcb' => 'cc-jcb',
|
||||
'fa fa-cc-mastercard' => 'cc-mastercard',
|
||||
'fa fa-cc-paypal' => 'cc-paypal',
|
||||
'fa fa-cc-stripe' => 'cc-stripe',
|
||||
'fa fa-cc-visa' => 'cc-visa',
|
||||
'fa fa-certificate' => 'certificate',
|
||||
'fa fa-chain' => 'chain',
|
||||
'fa fa-chain-broken' => 'chain-broken',
|
||||
'fa fa-check' => 'check',
|
||||
'fa fa-check-circle' => 'check-circle',
|
||||
'fa fa-check-circle-o' => 'check-circle-o',
|
||||
'fa fa-check-square' => 'check-square',
|
||||
'fa fa-check-square-o' => 'check-square-o',
|
||||
'fa fa-chevron-circle-down' => 'chevron-circle-down',
|
||||
'fa fa-chevron-circle-left' => 'chevron-circle-left',
|
||||
'fa fa-chevron-circle-right' => 'chevron-circle-right',
|
||||
'fa fa-chevron-circle-up' => 'chevron-circle-up',
|
||||
'fa fa-chevron-down' => 'chevron-down',
|
||||
'fa fa-chevron-left' => 'chevron-left',
|
||||
'fa fa-chevron-right' => 'chevron-right',
|
||||
'fa fa-chevron-up' => 'chevron-up',
|
||||
'fa fa-child' => 'child',
|
||||
'fa fa-chrome' => 'chrome',
|
||||
'fa fa-circle' => 'circle',
|
||||
'fa fa-circle-o' => 'circle-o',
|
||||
'fa fa-circle-o-notch' => 'circle-o-notch',
|
||||
'fa fa-circle-thin' => 'circle-thin',
|
||||
'fa fa-clipboard' => 'clipboard',
|
||||
'fa fa-clock-o' => 'clock-o',
|
||||
'fa fa-clone' => 'clone',
|
||||
'fa fa-close' => 'close',
|
||||
'fa fa-cloud' => 'cloud',
|
||||
'fa fa-cloud-download' => 'cloud-download',
|
||||
'fa fa-cloud-upload' => 'cloud-upload',
|
||||
'fa fa-cny' => 'cny',
|
||||
'fa fa-code' => 'code',
|
||||
'fa fa-code-fork' => 'code-fork',
|
||||
'fa fa-codepen' => 'codepen',
|
||||
'fa fa-codiepie' => 'codiepie',
|
||||
'fa fa-coffee' => 'coffee',
|
||||
'fa fa-cog' => 'cog',
|
||||
'fa fa-cogs' => 'cogs',
|
||||
'fa fa-columns' => 'columns',
|
||||
'fa fa-comment' => 'comment',
|
||||
'fa fa-comment-o' => 'comment-o',
|
||||
'fa fa-commenting' => 'commenting',
|
||||
'fa fa-commenting-o' => 'commenting-o',
|
||||
'fa fa-comments' => 'comments',
|
||||
'fa fa-comments-o' => 'comments-o',
|
||||
'fa fa-compass' => 'compass',
|
||||
'fa fa-compress' => 'compress',
|
||||
'fa fa-connectdevelop' => 'connectdevelop',
|
||||
'fa fa-contao' => 'contao',
|
||||
'fa fa-copy' => 'copy',
|
||||
'fa fa-copyright' => 'copyright',
|
||||
'fa fa-creative-commons' => 'creative-commons',
|
||||
'fa fa-credit-card' => 'credit-card',
|
||||
'fa fa-credit-card-alt' => 'credit-card-alt',
|
||||
'fa fa-crop' => 'crop',
|
||||
'fa fa-crosshairs' => 'crosshairs',
|
||||
'fa fa-css3' => 'css3',
|
||||
'fa fa-cube' => 'cube',
|
||||
'fa fa-cubes' => 'cubes',
|
||||
'fa fa-cut' => 'cut',
|
||||
'fa fa-cutlery' => 'cutlery',
|
||||
'fa fa-dashboard' => 'dashboard',
|
||||
'fa fa-dashcube' => 'dashcube',
|
||||
'fa fa-database' => 'database',
|
||||
'fa fa-deaf' => 'deaf',
|
||||
'fa fa-deafness' => 'deafness',
|
||||
'fa fa-dedent' => 'dedent',
|
||||
'fa fa-delicious' => 'delicious',
|
||||
'fa fa-desktop' => 'desktop',
|
||||
'fa fa-deviantart' => 'deviantart',
|
||||
'fa fa-diamond' => 'diamond',
|
||||
'fa fa-digg' => 'digg',
|
||||
'fa fa-dollar' => 'dollar',
|
||||
'fa fa-dot-circle-o' => 'dot-circle-o',
|
||||
'fa fa-download' => 'download',
|
||||
'fa fa-dribbble' => 'dribbble',
|
||||
'fa fa-drivers-license' => 'drivers-license',
|
||||
'fa fa-drivers-license-o' => 'drivers-license-o',
|
||||
'fa fa-dropbox' => 'dropbox',
|
||||
'fa fa-drupal' => 'drupal',
|
||||
'fa fa-edge' => 'edge',
|
||||
'fa fa-edit' => 'edit',
|
||||
'fa fa-eercast' => 'eercast',
|
||||
'fa fa-eject' => 'eject',
|
||||
'fa fa-ellipsis-h' => 'ellipsis-h',
|
||||
'fa fa-ellipsis-v' => 'ellipsis-v',
|
||||
'fa fa-empire' => 'empire',
|
||||
'fa fa-envelope' => 'envelope',
|
||||
'fa fa-envelope-o' => 'envelope-o',
|
||||
'fa fa-envelope-open' => 'envelope-open',
|
||||
'fa fa-envelope-open-o' => 'envelope-open-o',
|
||||
'fa fa-envelope-square' => 'envelope-square',
|
||||
'fa fa-envira' => 'envira',
|
||||
'fa fa-eraser' => 'eraser',
|
||||
'fa fa-etsy' => 'etsy',
|
||||
'fa fa-eur' => 'eur',
|
||||
'fa fa-euro' => 'euro',
|
||||
'fa fa-exchange' => 'exchange',
|
||||
'fa fa-exclamation' => 'exclamation',
|
||||
'fa fa-exclamation-circle' => 'exclamation-circle',
|
||||
'fa fa-exclamation-triangle' => 'exclamation-triangle',
|
||||
'fa fa-expand' => 'expand',
|
||||
'fa fa-expeditedssl' => 'expeditedssl',
|
||||
'fa fa-external-link' => 'external-link',
|
||||
'fa fa-external-link-square' => 'external-link-square',
|
||||
'fa fa-eye' => 'eye',
|
||||
'fa fa-eye-slash' => 'eye-slash',
|
||||
'fa fa-eyedropper' => 'eyedropper',
|
||||
'fa fa-fa' => 'fa',
|
||||
'fa fa-facebook' => 'facebook',
|
||||
'fa fa-facebook-f' => 'facebook-f',
|
||||
'fa fa-facebook-official' => 'facebook-official',
|
||||
'fa fa-facebook-square' => 'facebook-square',
|
||||
'fa fa-fast-backward' => 'fast-backward',
|
||||
'fa fa-fast-forward' => 'fast-forward',
|
||||
'fa fa-fax' => 'fax',
|
||||
'fa fa-feed' => 'feed',
|
||||
'fa fa-female' => 'female',
|
||||
'fa fa-fighter-jet' => 'fighter-jet',
|
||||
'fa fa-file' => 'file',
|
||||
'fa fa-file-archive-o' => 'file-archive-o',
|
||||
'fa fa-file-audio-o' => 'file-audio-o',
|
||||
'fa fa-file-code-o' => 'file-code-o',
|
||||
'fa fa-file-excel-o' => 'file-excel-o',
|
||||
'fa fa-file-image-o' => 'file-image-o',
|
||||
'fa fa-file-movie-o' => 'file-movie-o',
|
||||
'fa fa-file-o' => 'file-o',
|
||||
'fa fa-file-pdf-o' => 'file-pdf-o',
|
||||
'fa fa-file-photo-o' => 'file-photo-o',
|
||||
'fa fa-file-picture-o' => 'file-picture-o',
|
||||
'fa fa-file-powerpoint-o' => 'file-powerpoint-o',
|
||||
'fa fa-file-sound-o' => 'file-sound-o',
|
||||
'fa fa-file-text' => 'file-text',
|
||||
'fa fa-file-text-o' => 'file-text-o',
|
||||
'fa fa-file-video-o' => 'file-video-o',
|
||||
'fa fa-file-word-o' => 'file-word-o',
|
||||
'fa fa-file-zip-o' => 'file-zip-o',
|
||||
'fa fa-files-o' => 'files-o',
|
||||
'fa fa-film' => 'film',
|
||||
'fa fa-filter' => 'filter',
|
||||
'fa fa-fire' => 'fire',
|
||||
'fa fa-fire-extinguisher' => 'fire-extinguisher',
|
||||
'fa fa-firefox' => 'firefox',
|
||||
'fa fa-first-order' => 'first-order',
|
||||
'fa fa-flag' => 'flag',
|
||||
'fa fa-flag-checkered' => 'flag-checkered',
|
||||
'fa fa-flag-o' => 'flag-o',
|
||||
'fa fa-flash' => 'flash',
|
||||
'fa fa-flask' => 'flask',
|
||||
'fa fa-flickr' => 'flickr',
|
||||
'fa fa-floppy-o' => 'floppy-o',
|
||||
'fa fa-folder' => 'folder',
|
||||
'fa fa-folder-o' => 'folder-o',
|
||||
'fa fa-folder-open' => 'folder-open',
|
||||
'fa fa-folder-open-o' => 'folder-open-o',
|
||||
'fa fa-font' => 'font',
|
||||
'fa fa-font-awesome' => 'font-awesome',
|
||||
'fa fa-fonticons' => 'fonticons',
|
||||
'fa fa-fort-awesome' => 'fort-awesome',
|
||||
'fa fa-forumbee' => 'forumbee',
|
||||
'fa fa-forward' => 'forward',
|
||||
'fa fa-foursquare' => 'foursquare',
|
||||
'fa fa-free-code-camp' => 'free-code-camp',
|
||||
'fa fa-frown-o' => 'frown-o',
|
||||
'fa fa-futbol-o' => 'futbol-o',
|
||||
'fa fa-gamepad' => 'gamepad',
|
||||
'fa fa-gavel' => 'gavel',
|
||||
'fa fa-gbp' => 'gbp',
|
||||
'fa fa-ge' => 'ge',
|
||||
'fa fa-gear' => 'gear',
|
||||
'fa fa-gears' => 'gears',
|
||||
'fa fa-genderless' => 'genderless',
|
||||
'fa fa-get-pocket' => 'get-pocket',
|
||||
'fa fa-gg' => 'gg',
|
||||
'fa fa-gg-circle' => 'gg-circle',
|
||||
'fa fa-gift' => 'gift',
|
||||
'fa fa-git' => 'git',
|
||||
'fa fa-git-square' => 'git-square',
|
||||
'fa fa-github' => 'github',
|
||||
'fa fa-github-alt' => 'github-alt',
|
||||
'fa fa-github-square' => 'github-square',
|
||||
'fa fa-gitlab' => 'gitlab',
|
||||
'fa fa-gittip' => 'gittip',
|
||||
'fa fa-glass' => 'glass',
|
||||
'fa fa-glide' => 'glide',
|
||||
'fa fa-glide-g' => 'glide-g',
|
||||
'fa fa-globe' => 'globe',
|
||||
'fa fa-google' => 'google',
|
||||
'fa fa-google-plus' => 'google-plus',
|
||||
'fa fa-google-plus-circle' => 'google-plus-circle',
|
||||
'fa fa-google-plus-official' => 'google-plus-official',
|
||||
'fa fa-google-plus-square' => 'google-plus-square',
|
||||
'fa fa-google-wallet' => 'google-wallet',
|
||||
'fa fa-graduation-cap' => 'graduation-cap',
|
||||
'fa fa-gratipay' => 'gratipay',
|
||||
'fa fa-grav' => 'grav',
|
||||
'fa fa-group' => 'group',
|
||||
'fa fa-h-square' => 'h-square',
|
||||
'fa fa-hacker-news' => 'hacker-news',
|
||||
'fa fa-hand-grab-o' => 'hand-grab-o',
|
||||
'fa fa-hand-lizard-o' => 'hand-lizard-o',
|
||||
'fa fa-hand-o-down' => 'hand-o-down',
|
||||
'fa fa-hand-o-left' => 'hand-o-left',
|
||||
'fa fa-hand-o-right' => 'hand-o-right',
|
||||
'fa fa-hand-o-up' => 'hand-o-up',
|
||||
'fa fa-hand-paper-o' => 'hand-paper-o',
|
||||
'fa fa-hand-peace-o' => 'hand-peace-o',
|
||||
'fa fa-hand-pointer-o' => 'hand-pointer-o',
|
||||
'fa fa-hand-rock-o' => 'hand-rock-o',
|
||||
'fa fa-hand-scissors-o' => 'hand-scissors-o',
|
||||
'fa fa-hand-spock-o' => 'hand-spock-o',
|
||||
'fa fa-hand-stop-o' => 'hand-stop-o',
|
||||
'fa fa-handshake-o' => 'handshake-o',
|
||||
'fa fa-hard-of-hearing' => 'hard-of-hearing',
|
||||
'fa fa-hashtag' => 'hashtag',
|
||||
'fa fa-hdd-o' => 'hdd-o',
|
||||
'fa fa-header' => 'header',
|
||||
'fa fa-headphones' => 'headphones',
|
||||
'fa fa-heart' => 'heart',
|
||||
'fa fa-heart-o' => 'heart-o',
|
||||
'fa fa-heartbeat' => 'heartbeat',
|
||||
'fa fa-history' => 'history',
|
||||
'fa fa-home' => 'home',
|
||||
'fa fa-hospital-o' => 'hospital-o',
|
||||
'fa fa-hotel' => 'hotel',
|
||||
'fa fa-hourglass' => 'hourglass',
|
||||
'fa fa-hourglass-1' => 'hourglass-1',
|
||||
'fa fa-hourglass-2' => 'hourglass-2',
|
||||
'fa fa-hourglass-3' => 'hourglass-3',
|
||||
'fa fa-hourglass-end' => 'hourglass-end',
|
||||
'fa fa-hourglass-half' => 'hourglass-half',
|
||||
'fa fa-hourglass-o' => 'hourglass-o',
|
||||
'fa fa-hourglass-start' => 'hourglass-start',
|
||||
'fa fa-houzz' => 'houzz',
|
||||
'fa fa-html5' => 'html5',
|
||||
'fa fa-i-cursor' => 'i-cursor',
|
||||
'fa fa-id-badge' => 'id-badge',
|
||||
'fa fa-id-card' => 'id-card',
|
||||
'fa fa-id-card-o' => 'id-card-o',
|
||||
'fa fa-ils' => 'ils',
|
||||
'fa fa-image' => 'image',
|
||||
'fa fa-imdb' => 'imdb',
|
||||
'fa fa-inbox' => 'inbox',
|
||||
'fa fa-indent' => 'indent',
|
||||
'fa fa-industry' => 'industry',
|
||||
'fa fa-info' => 'info',
|
||||
'fa fa-info-circle' => 'info-circle',
|
||||
'fa fa-inr' => 'inr',
|
||||
'fa fa-instagram' => 'instagram',
|
||||
'fa fa-institution' => 'institution',
|
||||
'fa fa-internet-explorer' => 'internet-explorer',
|
||||
'fa fa-intersex' => 'intersex',
|
||||
'fa fa-ioxhost' => 'ioxhost',
|
||||
'fa fa-italic' => 'italic',
|
||||
'fa fa-joomla' => 'joomla',
|
||||
'fa fa-jpy' => 'jpy',
|
||||
'fa fa-jsfiddle' => 'jsfiddle',
|
||||
'fa fa-key' => 'key',
|
||||
'fa fa-keyboard-o' => 'keyboard-o',
|
||||
'fa fa-krw' => 'krw',
|
||||
'fa fa-language' => 'language',
|
||||
'fa fa-laptop' => 'laptop',
|
||||
'fa fa-lastfm' => 'lastfm',
|
||||
'fa fa-lastfm-square' => 'lastfm-square',
|
||||
'fa fa-leaf' => 'leaf',
|
||||
'fa fa-leanpub' => 'leanpub',
|
||||
'fa fa-legal' => 'legal',
|
||||
'fa fa-lemon-o' => 'lemon-o',
|
||||
'fa fa-level-down' => 'level-down',
|
||||
'fa fa-level-up' => 'level-up',
|
||||
'fa fa-life-bouy' => 'life-bouy',
|
||||
'fa fa-life-buoy' => 'life-buoy',
|
||||
'fa fa-life-ring' => 'life-ring',
|
||||
'fa fa-life-saver' => 'life-saver',
|
||||
'fa fa-lightbulb-o' => 'lightbulb-o',
|
||||
'fa fa-line-chart' => 'line-chart',
|
||||
'fa fa-link' => 'link',
|
||||
'fa fa-linkedin' => 'linkedin',
|
||||
'fa fa-linkedin-square' => 'linkedin-square',
|
||||
'fa fa-linode' => 'linode',
|
||||
'fa fa-linux' => 'linux',
|
||||
'fa fa-list' => 'list',
|
||||
'fa fa-list-alt' => 'list-alt',
|
||||
'fa fa-list-ol' => 'list-ol',
|
||||
'fa fa-list-ul' => 'list-ul',
|
||||
'fa fa-location-arrow' => 'location-arrow',
|
||||
'fa fa-lock' => 'lock',
|
||||
'fa fa-long-arrow-down' => 'long-arrow-down',
|
||||
'fa fa-long-arrow-left' => 'long-arrow-left',
|
||||
'fa fa-long-arrow-right' => 'long-arrow-right',
|
||||
'fa fa-long-arrow-up' => 'long-arrow-up',
|
||||
'fa fa-low-vision' => 'low-vision',
|
||||
'fa fa-magic' => 'magic',
|
||||
'fa fa-magnet' => 'magnet',
|
||||
'fa fa-mail-forward' => 'mail-forward',
|
||||
'fa fa-mail-reply' => 'mail-reply',
|
||||
'fa fa-mail-reply-all' => 'mail-reply-all',
|
||||
'fa fa-male' => 'male',
|
||||
'fa fa-map' => 'map',
|
||||
'fa fa-map-marker' => 'map-marker',
|
||||
'fa fa-map-o' => 'map-o',
|
||||
'fa fa-map-pin' => 'map-pin',
|
||||
'fa fa-map-signs' => 'map-signs',
|
||||
'fa fa-mars' => 'mars',
|
||||
'fa fa-mars-double' => 'mars-double',
|
||||
'fa fa-mars-stroke' => 'mars-stroke',
|
||||
'fa fa-mars-stroke-h' => 'mars-stroke-h',
|
||||
'fa fa-mars-stroke-v' => 'mars-stroke-v',
|
||||
'fa fa-maxcdn' => 'maxcdn',
|
||||
'fa fa-meanpath' => 'meanpath',
|
||||
'fa fa-medium' => 'medium',
|
||||
'fa fa-medkit' => 'medkit',
|
||||
'fa fa-meetup' => 'meetup',
|
||||
'fa fa-meh-o' => 'meh-o',
|
||||
'fa fa-mercury' => 'mercury',
|
||||
'fa fa-microchip' => 'microchip',
|
||||
'fa fa-microphone' => 'microphone',
|
||||
'fa fa-microphone-slash' => 'microphone-slash',
|
||||
'fa fa-minus' => 'minus',
|
||||
'fa fa-minus-circle' => 'minus-circle',
|
||||
'fa fa-minus-square' => 'minus-square',
|
||||
'fa fa-minus-square-o' => 'minus-square-o',
|
||||
'fa fa-mixcloud' => 'mixcloud',
|
||||
'fa fa-mobile' => 'mobile',
|
||||
'fa fa-mobile-phone' => 'mobile-phone',
|
||||
'fa fa-modx' => 'modx',
|
||||
'fa fa-money' => 'money',
|
||||
'fa fa-moon-o' => 'moon-o',
|
||||
'fa fa-mortar-board' => 'mortar-board',
|
||||
'fa fa-motorcycle' => 'motorcycle',
|
||||
'fa fa-mouse-pointer' => 'mouse-pointer',
|
||||
'fa fa-music' => 'music',
|
||||
'fa fa-navicon' => 'navicon',
|
||||
'fa fa-neuter' => 'neuter',
|
||||
'fa fa-newspaper-o' => 'newspaper-o',
|
||||
'fa fa-object-group' => 'object-group',
|
||||
'fa fa-object-ungroup' => 'object-ungroup',
|
||||
'fa fa-odnoklassniki' => 'odnoklassniki',
|
||||
'fa fa-odnoklassniki-square' => 'odnoklassniki-square',
|
||||
'fa fa-opencart' => 'opencart',
|
||||
'fa fa-openid' => 'openid',
|
||||
'fa fa-opera' => 'opera',
|
||||
'fa fa-optin-monster' => 'optin-monster',
|
||||
'fa fa-outdent' => 'outdent',
|
||||
'fa fa-pagelines' => 'pagelines',
|
||||
'fa fa-paint-brush' => 'paint-brush',
|
||||
'fa fa-paper-plane' => 'paper-plane',
|
||||
'fa fa-paper-plane-o' => 'paper-plane-o',
|
||||
'fa fa-paperclip' => 'paperclip',
|
||||
'fa fa-paragraph' => 'paragraph',
|
||||
'fa fa-paste' => 'paste',
|
||||
'fa fa-pause' => 'pause',
|
||||
'fa fa-pause-circle' => 'pause-circle',
|
||||
'fa fa-pause-circle-o' => 'pause-circle-o',
|
||||
'fa fa-paw' => 'paw',
|
||||
'fa fa-paypal' => 'paypal',
|
||||
'fa fa-pencil' => 'pencil',
|
||||
'fa fa-pencil-square' => 'pencil-square',
|
||||
'fa fa-pencil-square-o' => 'pencil-square-o',
|
||||
'fa fa-percent' => 'percent',
|
||||
'fa fa-phone' => 'phone',
|
||||
'fa fa-phone-square' => 'phone-square',
|
||||
'fa fa-photo' => 'photo',
|
||||
'fa fa-picture-o' => 'picture-o',
|
||||
'fa fa-pie-chart' => 'pie-chart',
|
||||
'fa fa-pied-piper' => 'pied-piper',
|
||||
'fa fa-pied-piper-alt' => 'pied-piper-alt',
|
||||
'fa fa-pied-piper-pp' => 'pied-piper-pp',
|
||||
'fa fa-pinterest' => 'pinterest',
|
||||
'fa fa-pinterest-p' => 'pinterest-p',
|
||||
'fa fa-pinterest-square' => 'pinterest-square',
|
||||
'fa fa-plane' => 'plane',
|
||||
'fa fa-play' => 'play',
|
||||
'fa fa-play-circle' => 'play-circle',
|
||||
'fa fa-play-circle-o' => 'play-circle-o',
|
||||
'fa fa-plug' => 'plug',
|
||||
'fa fa-plus' => 'plus',
|
||||
'fa fa-plus-circle' => 'plus-circle',
|
||||
'fa fa-plus-square' => 'plus-square',
|
||||
'fa fa-plus-square-o' => 'plus-square-o',
|
||||
'fa fa-podcast' => 'podcast',
|
||||
'fa fa-power-off' => 'power-off',
|
||||
'fa fa-print' => 'print',
|
||||
'fa fa-product-hunt' => 'product-hunt',
|
||||
'fa fa-pull-left' => 'pull-left',
|
||||
'fa fa-pull-right' => 'pull-right',
|
||||
'fa fa-puzzle-piece' => 'puzzle-piece',
|
||||
'fa fa-qq' => 'qq',
|
||||
'fa fa-qrcode' => 'qrcode',
|
||||
'fa fa-question' => 'question',
|
||||
'fa fa-question-circle' => 'question-circle',
|
||||
'fa fa-question-circle-o' => 'question-circle-o',
|
||||
'fa fa-quora' => 'quora',
|
||||
'fa fa-quote-left' => 'quote-left',
|
||||
'fa fa-quote-right' => 'quote-right',
|
||||
'fa fa-ra' => 'ra',
|
||||
'fa fa-random' => 'random',
|
||||
'fa fa-ravelry' => 'ravelry',
|
||||
'fa fa-rebel' => 'rebel',
|
||||
'fa fa-recycle' => 'recycle',
|
||||
'fa fa-reddit' => 'reddit',
|
||||
'fa fa-reddit-alien' => 'reddit-alien',
|
||||
'fa fa-reddit-square' => 'reddit-square',
|
||||
'fa fa-refresh' => 'refresh',
|
||||
'fa fa-registered' => 'registered',
|
||||
'fa fa-remove' => 'remove',
|
||||
'fa fa-renren' => 'renren',
|
||||
'fa fa-reorder' => 'reorder',
|
||||
'fa fa-repeat' => 'repeat',
|
||||
'fa fa-reply' => 'reply',
|
||||
'fa fa-reply-all' => 'reply-all',
|
||||
'fa fa-resistance' => 'resistance',
|
||||
'fa fa-retweet' => 'retweet',
|
||||
'fa fa-rmb' => 'rmb',
|
||||
'fa fa-road' => 'road',
|
||||
'fa fa-rocket' => 'rocket',
|
||||
'fa fa-rotate-left' => 'rotate-left',
|
||||
'fa fa-rotate-right' => 'rotate-right',
|
||||
'fa fa-rouble' => 'rouble',
|
||||
'fa fa-rss' => 'rss',
|
||||
'fa fa-rss-square' => 'rss-square',
|
||||
'fa fa-rub' => 'rub',
|
||||
'fa fa-ruble' => 'ruble',
|
||||
'fa fa-rupee' => 'rupee',
|
||||
'fa fa-s15' => 's15',
|
||||
'fa fa-safari' => 'safari',
|
||||
'fa fa-save' => 'save',
|
||||
'fa fa-scissors' => 'scissors',
|
||||
'fa fa-scribd' => 'scribd',
|
||||
'fa fa-search' => 'search',
|
||||
'fa fa-search-minus' => 'search-minus',
|
||||
'fa fa-search-plus' => 'search-plus',
|
||||
'fa fa-sellsy' => 'sellsy',
|
||||
'fa fa-send' => 'send',
|
||||
'fa fa-send-o' => 'send-o',
|
||||
'fa fa-server' => 'server',
|
||||
'fa fa-share' => 'share',
|
||||
'fa fa-share-alt' => 'share-alt',
|
||||
'fa fa-share-alt-square' => 'share-alt-square',
|
||||
'fa fa-share-square' => 'share-square',
|
||||
'fa fa-share-square-o' => 'share-square-o',
|
||||
'fa fa-shekel' => 'shekel',
|
||||
'fa fa-sheqel' => 'sheqel',
|
||||
'fa fa-shield' => 'shield',
|
||||
'fa fa-ship' => 'ship',
|
||||
'fa fa-shirtsinbulk' => 'shirtsinbulk',
|
||||
'fa fa-shopping-bag' => 'shopping-bag',
|
||||
'fa fa-shopping-basket' => 'shopping-basket',
|
||||
'fa fa-shopping-cart' => 'shopping-cart',
|
||||
'fa fa-shower' => 'shower',
|
||||
'fa fa-sign-in' => 'sign-in',
|
||||
'fa fa-sign-language' => 'sign-language',
|
||||
'fa fa-sign-out' => 'sign-out',
|
||||
'fa fa-signal' => 'signal',
|
||||
'fa fa-signing' => 'signing',
|
||||
'fa fa-simplybuilt' => 'simplybuilt',
|
||||
'fa fa-sitemap' => 'sitemap',
|
||||
'fa fa-skyatlas' => 'skyatlas',
|
||||
'fa fa-skype' => 'skype',
|
||||
'fa fa-slack' => 'slack',
|
||||
'fa fa-sliders' => 'sliders',
|
||||
'fa fa-slideshare' => 'slideshare',
|
||||
'fa fa-smile-o' => 'smile-o',
|
||||
'fa fa-snapchat' => 'snapchat',
|
||||
'fa fa-snapchat-ghost' => 'snapchat-ghost',
|
||||
'fa fa-snapchat-square' => 'snapchat-square',
|
||||
'fa fa-snowflake-o' => 'snowflake-o',
|
||||
'fa fa-soccer-ball-o' => 'soccer-ball-o',
|
||||
'fa fa-sort' => 'sort',
|
||||
'fa fa-sort-alpha-asc' => 'sort-alpha-asc',
|
||||
'fa fa-sort-alpha-desc' => 'sort-alpha-desc',
|
||||
'fa fa-sort-amount-asc' => 'sort-amount-asc',
|
||||
'fa fa-sort-amount-desc' => 'sort-amount-desc',
|
||||
'fa fa-sort-asc' => 'sort-asc',
|
||||
'fa fa-sort-desc' => 'sort-desc',
|
||||
'fa fa-sort-down' => 'sort-down',
|
||||
'fa fa-sort-numeric-asc' => 'sort-numeric-asc',
|
||||
'fa fa-sort-numeric-desc' => 'sort-numeric-desc',
|
||||
'fa fa-sort-up' => 'sort-up',
|
||||
'fa fa-soundcloud' => 'soundcloud',
|
||||
'fa fa-space-shuttle' => 'space-shuttle',
|
||||
'fa fa-spinner' => 'spinner',
|
||||
'fa fa-spoon' => 'spoon',
|
||||
'fa fa-spotify' => 'spotify',
|
||||
'fa fa-square' => 'square',
|
||||
'fa fa-square-o' => 'square-o',
|
||||
'fa fa-stack-exchange' => 'stack-exchange',
|
||||
'fa fa-stack-overflow' => 'stack-overflow',
|
||||
'fa fa-star' => 'star',
|
||||
'fa fa-star-half' => 'star-half',
|
||||
'fa fa-star-half-empty' => 'star-half-empty',
|
||||
'fa fa-star-half-full' => 'star-half-full',
|
||||
'fa fa-star-half-o' => 'star-half-o',
|
||||
'fa fa-star-o' => 'star-o',
|
||||
'fa fa-steam' => 'steam',
|
||||
'fa fa-steam-square' => 'steam-square',
|
||||
'fa fa-step-backward' => 'step-backward',
|
||||
'fa fa-step-forward' => 'step-forward',
|
||||
'fa fa-stethoscope' => 'stethoscope',
|
||||
'fa fa-sticky-note' => 'sticky-note',
|
||||
'fa fa-sticky-note-o' => 'sticky-note-o',
|
||||
'fa fa-stop' => 'stop',
|
||||
'fa fa-stop-circle' => 'stop-circle',
|
||||
'fa fa-stop-circle-o' => 'stop-circle-o',
|
||||
'fa fa-street-view' => 'street-view',
|
||||
'fa fa-strikethrough' => 'strikethrough',
|
||||
'fa fa-stumbleupon' => 'stumbleupon',
|
||||
'fa fa-stumbleupon-circle' => 'stumbleupon-circle',
|
||||
'fa fa-subscript' => 'subscript',
|
||||
'fa fa-subway' => 'subway',
|
||||
'fa fa-suitcase' => 'suitcase',
|
||||
'fa fa-sun-o' => 'sun-o',
|
||||
'fa fa-superpowers' => 'superpowers',
|
||||
'fa fa-superscript' => 'superscript',
|
||||
'fa fa-support' => 'support',
|
||||
'fa fa-table' => 'table',
|
||||
'fa fa-tablet' => 'tablet',
|
||||
'fa fa-tachometer' => 'tachometer',
|
||||
'fa fa-tag' => 'tag',
|
||||
'fa fa-tags' => 'tags',
|
||||
'fa fa-tasks' => 'tasks',
|
||||
'fa fa-taxi' => 'taxi',
|
||||
'fa fa-telegram' => 'telegram',
|
||||
'fa fa-television' => 'television',
|
||||
'fa fa-tencent-weibo' => 'tencent-weibo',
|
||||
'fa fa-terminal' => 'terminal',
|
||||
'fa fa-text-height' => 'text-height',
|
||||
'fa fa-text-width' => 'text-width',
|
||||
'fa fa-th' => 'th',
|
||||
'fa fa-th-large' => 'th-large',
|
||||
'fa fa-th-list' => 'th-list',
|
||||
'fa fa-themeisle' => 'themeisle',
|
||||
'fa fa-thermometer' => 'thermometer',
|
||||
'fa fa-thermometer-0' => 'thermometer-0',
|
||||
'fa fa-thermometer-1' => 'thermometer-1',
|
||||
'fa fa-thermometer-2' => 'thermometer-2',
|
||||
'fa fa-thermometer-3' => 'thermometer-3',
|
||||
'fa fa-thermometer-4' => 'thermometer-4',
|
||||
'fa fa-thermometer-empty' => 'thermometer-empty',
|
||||
'fa fa-thermometer-full' => 'thermometer-full',
|
||||
'fa fa-thermometer-half' => 'thermometer-half',
|
||||
'fa fa-thermometer-quarter' => 'thermometer-quarter',
|
||||
'fa fa-thermometer-three-quarters' => 'thermometer-three-quarters',
|
||||
'fa fa-thumb-tack' => 'thumb-tack',
|
||||
'fa fa-thumbs-down' => 'thumbs-down',
|
||||
'fa fa-thumbs-o-down' => 'thumbs-o-down',
|
||||
'fa fa-thumbs-o-up' => 'thumbs-o-up',
|
||||
'fa fa-thumbs-up' => 'thumbs-up',
|
||||
'fa fa-ticket' => 'ticket',
|
||||
'fa fa-times' => 'times',
|
||||
'fa fa-times-circle' => 'times-circle',
|
||||
'fa fa-times-circle-o' => 'times-circle-o',
|
||||
'fa fa-times-rectangle' => 'times-rectangle',
|
||||
'fa fa-times-rectangle-o' => 'times-rectangle-o',
|
||||
'fa fa-tint' => 'tint',
|
||||
'fa fa-toggle-down' => 'toggle-down',
|
||||
'fa fa-toggle-left' => 'toggle-left',
|
||||
'fa fa-toggle-off' => 'toggle-off',
|
||||
'fa fa-toggle-on' => 'toggle-on',
|
||||
'fa fa-toggle-right' => 'toggle-right',
|
||||
'fa fa-toggle-up' => 'toggle-up',
|
||||
'fa fa-trademark' => 'trademark',
|
||||
'fa fa-train' => 'train',
|
||||
'fa fa-transgender' => 'transgender',
|
||||
'fa fa-transgender-alt' => 'transgender-alt',
|
||||
'fa fa-trash' => 'trash',
|
||||
'fa fa-trash-o' => 'trash-o',
|
||||
'fa fa-tree' => 'tree',
|
||||
'fa fa-trello' => 'trello',
|
||||
'fa fa-tripadvisor' => 'tripadvisor',
|
||||
'fa fa-trophy' => 'trophy',
|
||||
'fa fa-truck' => 'truck',
|
||||
'fa fa-try' => 'try',
|
||||
'fa fa-tty' => 'tty',
|
||||
'fa fa-tumblr' => 'tumblr',
|
||||
'fa fa-tumblr-square' => 'tumblr-square',
|
||||
'fa fa-turkish-lira' => 'turkish-lira',
|
||||
'fa fa-tv' => 'tv',
|
||||
'fa fa-twitch' => 'twitch',
|
||||
'fa fa-twitter' => 'twitter',
|
||||
'fa fa-twitter-square' => 'twitter-square',
|
||||
'fa fa-umbrella' => 'umbrella',
|
||||
'fa fa-underline' => 'underline',
|
||||
'fa fa-undo' => 'undo',
|
||||
'fa fa-universal-access' => 'universal-access',
|
||||
'fa fa-university' => 'university',
|
||||
'fa fa-unlink' => 'unlink',
|
||||
'fa fa-unlock' => 'unlock',
|
||||
'fa fa-unlock-alt' => 'unlock-alt',
|
||||
'fa fa-unsorted' => 'unsorted',
|
||||
'fa fa-upload' => 'upload',
|
||||
'fa fa-usb' => 'usb',
|
||||
'fa fa-usd' => 'usd',
|
||||
'fa fa-user' => 'user',
|
||||
'fa fa-user-circle' => 'user-circle',
|
||||
'fa fa-user-circle-o' => 'user-circle-o',
|
||||
'fa fa-user-md' => 'user-md',
|
||||
'fa fa-user-o' => 'user-o',
|
||||
'fa fa-user-plus' => 'user-plus',
|
||||
'fa fa-user-secret' => 'user-secret',
|
||||
'fa fa-user-times' => 'user-times',
|
||||
'fa fa-users' => 'users',
|
||||
'fa fa-vcard' => 'vcard',
|
||||
'fa fa-vcard-o' => 'vcard-o',
|
||||
'fa fa-venus' => 'venus',
|
||||
'fa fa-venus-double' => 'venus-double',
|
||||
'fa fa-venus-mars' => 'venus-mars',
|
||||
'fa fa-viacoin' => 'viacoin',
|
||||
'fa fa-viadeo' => 'viadeo',
|
||||
'fa fa-viadeo-square' => 'viadeo-square',
|
||||
'fa fa-video-camera' => 'video-camera',
|
||||
'fa fa-vimeo' => 'vimeo',
|
||||
'fa fa-vimeo-square' => 'vimeo-square',
|
||||
'fa fa-vine' => 'vine',
|
||||
'fa fa-vk' => 'vk',
|
||||
'fa fa-volume-control-phone' => 'volume-control-phone',
|
||||
'fa fa-volume-down' => 'volume-down',
|
||||
'fa fa-volume-off' => 'volume-off',
|
||||
'fa fa-volume-up' => 'volume-up',
|
||||
'fa fa-warning' => 'warning',
|
||||
'fa fa-wechat' => 'wechat',
|
||||
'fa fa-weibo' => 'weibo',
|
||||
'fa fa-weixin' => 'weixin',
|
||||
'fa fa-whatsapp' => 'whatsapp',
|
||||
'fa fa-wheelchair' => 'wheelchair',
|
||||
'fa fa-wheelchair-alt' => 'wheelchair-alt',
|
||||
'fa fa-wifi' => 'wifi',
|
||||
'fa fa-wikipedia-w' => 'wikipedia-w',
|
||||
'fa fa-window-close' => 'window-close',
|
||||
'fa fa-window-close-o' => 'window-close-o',
|
||||
'fa fa-window-maximize' => 'window-maximize',
|
||||
'fa fa-window-minimize' => 'window-minimize',
|
||||
'fa fa-window-restore' => 'window-restore',
|
||||
'fa fa-windows' => 'windows',
|
||||
'fa fa-won' => 'won',
|
||||
'fa fa-wordpress' => 'wordpress',
|
||||
'fa fa-wpbeginner' => 'wpbeginner',
|
||||
'fa fa-wpexplorer' => 'wpexplorer',
|
||||
'fa fa-wpforms' => 'wpforms',
|
||||
'fa fa-wrench' => 'wrench',
|
||||
'fa fa-xing' => 'xing',
|
||||
'fa fa-xing-square' => 'xing-square',
|
||||
'fa fa-y-combinator' => 'y-combinator',
|
||||
'fa fa-y-combinator-square' => 'y-combinator-square',
|
||||
'fa fa-yahoo' => 'yahoo',
|
||||
'fa fa-yc' => 'yc',
|
||||
'fa fa-yc-square' => 'yc-square',
|
||||
'fa fa-yelp' => 'yelp',
|
||||
'fa fa-yen' => 'yen',
|
||||
'fa fa-yoast' => 'yoast',
|
||||
'fa fa-youtube' => 'youtube',
|
||||
'fa fa-youtube-play' => 'youtube-play',
|
||||
'fa fa-youtube-square' => 'youtube-square',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get icons control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the icons control. Used to return the default
|
||||
* settings while initializing the icons control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'options' => self::get_icons(),
|
||||
'include' => '',
|
||||
'exclude' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render icons control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<select id="<?php echo $control_uid; ?>" class="elementor-control-icon" data-setting="{{ data.name }}" data-placeholder="<?php echo __( 'Select Icon', 'elementor' ); ?>">
|
||||
<option value=""><?php echo __( 'Select Icon', 'elementor' ); ?></option>
|
||||
<# _.each( data.options, function( option_title, option_value ) { #>
|
||||
<option value="{{ option_value }}">{{{ option_title }}}</option>
|
||||
<# } ); #>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{ data.description }}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor Icons control.
|
||||
*
|
||||
* A base control for creating a Icons chooser control.
|
||||
* Used to select an Icon.
|
||||
*
|
||||
* Usage: @see https://developers.elementor.com/elementor-controls/icons-control
|
||||
*
|
||||
* @since 2.6.0
|
||||
*/
|
||||
class Control_Icons extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get media control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `media`.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.6.0
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'icons';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Icons control default values.
|
||||
*
|
||||
* Retrieve the default value of the Icons control. Used to return the default
|
||||
* values while initializing the Icons control.
|
||||
*
|
||||
* @access public
|
||||
* @since 2.6.0
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'value' => '',
|
||||
'library' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Icons control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<# if ( 'inline' === data.skin ) { #>
|
||||
<?php $this->render_inline_skin(); ?>
|
||||
<# } else { #>
|
||||
<?php $this->render_media_skin(); ?>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function render_media_skin() {
|
||||
?>
|
||||
<div class="elementor-control-field elementor-control-media">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-aspect-ratio-219">
|
||||
<div class="elementor-control-media__content elementor-control-tag-area elementor-control-preview-area elementor-fit-aspect-ratio">
|
||||
<div class="elementor-control-media-upload-button elementor-control-media__content__upload-button elementor-fit-aspect-ratio">
|
||||
<i class="eicon-plus-circle" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-control-media-area elementor-fit-aspect-ratio">
|
||||
<div class="elementor-control-media__remove elementor-control-media__content__remove" title="<?php echo __( 'Remove', 'elementor' ); ?>">
|
||||
<i class="eicon-trash-o"></i>
|
||||
</div>
|
||||
<div class="elementor-control-media__preview elementor-fit-aspect-ratio"></div>
|
||||
</div>
|
||||
<div class="elementor-control-media__tools elementor-control-dynamic-switcher-wrapper">
|
||||
<div class="elementor-control-icon-picker elementor-control-media__tool"><?php echo __( 'Icon Library', 'elementor' ); ?></div>
|
||||
<div class="elementor-control-svg-uploader elementor-control-media__tool"><?php echo __( 'Upload SVG', 'elementor' ); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<input type="hidden" data-setting="{{ data.name }}"/>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function render_inline_skin() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field elementor-control-inline-icon">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<div class="elementor-choices">
|
||||
<input id="<?php echo $control_uid; ?>-none" type="radio" value="none">
|
||||
<label class="elementor-choices-label elementor-control-unit-1 tooltip-target elementor-control-icons--inline__none" for="<?php echo $control_uid; ?>-none" data-tooltip="<?php echo __( 'None', 'elementor' ); ?>" title="<?php echo __( 'None', 'elementor' ); ?>">
|
||||
<i class="eicon-ban" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'None', 'elementor' ); ?></span>
|
||||
</label>
|
||||
<# if ( ! data.exclude_inline_options.includes( 'svg' ) ) { #>
|
||||
<input id="<?php echo $control_uid; ?>-svg" type="radio" value="svg">
|
||||
<label class="elementor-choices-label elementor-control-unit-1 tooltip-target elementor-control-icons--inline__svg" for="<?php echo $control_uid; ?>-svg" data-tooltip="<?php echo __( 'Upload SVG', 'elementor' ); ?>" title="<?php echo __( 'Upload SVG', 'elementor' ); ?>">
|
||||
<i class="eicon-upload" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Upload SVG', 'elementor' ); ?></span>
|
||||
</label>
|
||||
<# }
|
||||
if ( ! data.exclude_inline_options.includes( 'icon' ) ) { #>
|
||||
<input id="<?php echo $control_uid; ?>-icon" type="radio" value="icon">
|
||||
<label class="elementor-choices-label elementor-control-unit-1 tooltip-target elementor-control-icons--inline__icon" for="<?php echo $control_uid; ?>-icon" data-tooltip="<?php echo __( 'Icon Library', 'elementor' ); ?>" title="<?php echo __( 'Icon Library', 'elementor' ); ?>">
|
||||
<span class="elementor-control-icons--inline__displayed-icon">
|
||||
<i class="eicon-circle" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Icon Library', 'elementor' ); ?></span>
|
||||
</label>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Icons control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the Icons control. Used to return the default
|
||||
* settings while initializing the Icons control.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::IMAGE_CATEGORY ],
|
||||
'returnType' => 'object',
|
||||
],
|
||||
'search_bar' => true,
|
||||
'recommended' => false,
|
||||
'skin' => 'media',
|
||||
'exclude_inline_options' => [],
|
||||
];
|
||||
}
|
||||
|
||||
public function support_svg_import( $mimes ) {
|
||||
$mimes['svg'] = 'image/svg+xml';
|
||||
return $mimes;
|
||||
}
|
||||
|
||||
public function on_import( $settings ) {
|
||||
if ( empty( $settings['library'] ) || 'svg' !== $settings['library'] || empty( $settings['value']['url'] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
add_filter( 'upload_mimes', [ $this, 'support_svg_import' ], 100 );
|
||||
|
||||
$imported = Plugin::$instance->templates_manager->get_import_images_instance()->import( $settings['value'] );
|
||||
|
||||
remove_filter( 'upload_mimes', [ $this, 'support_svg_import' ], 100 );
|
||||
|
||||
if ( ! $imported ) {
|
||||
$settings['value'] = '';
|
||||
$settings['library'] = '';
|
||||
} else {
|
||||
$settings['value'] = $imported;
|
||||
}
|
||||
return $settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor image dimensions control.
|
||||
*
|
||||
* A base control for creating image dimension control. Displays image width
|
||||
* input, image height input and an apply button.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Image_Dimensions extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get image dimensions control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `image_dimensions`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'image_dimensions';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image dimensions control default values.
|
||||
*
|
||||
* Retrieve the default value of the image dimensions control. Used to return the
|
||||
* default values while initializing the image dimensions control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'width' => '',
|
||||
'height' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image dimensions control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the image dimensions control. Used to return
|
||||
* the default settings while initializing the image dimensions control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'show_label' => false,
|
||||
'label_block' => true,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render image dimensions control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
if ( ! $this->is_image_editor_supports() ) : ?>
|
||||
<div class="elementor-panel-alert elementor-panel-alert-danger">
|
||||
<?php echo __( 'The server does not have ImageMagick or GD installed and/or enabled! Any of these libraries are required for WordPress to be able to resize images. Please contact your server administrator to enable this before continuing.', 'elementor' ); ?>
|
||||
</div>
|
||||
<?php
|
||||
return;
|
||||
endif;
|
||||
?>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<div class="elementor-image-dimensions-field elementor-control-unit-2">
|
||||
<?php $control_uid = $this->get_control_uid( 'width' ); ?>
|
||||
<input id="<?php echo $control_uid; ?>" type="text" data-setting="width" />
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-image-dimensions-field-description"><?php echo __( 'Width', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-image-dimensions-separator">x</div>
|
||||
<div class="elementor-image-dimensions-field elementor-control-unit-2">
|
||||
<?php $control_uid = $this->get_control_uid( 'height' ); ?>
|
||||
<input id="<?php echo $control_uid; ?>" type="text" data-setting="height" />
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-image-dimensions-field-description"><?php echo __( 'Height', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<button class="elementor-button elementor-button-success elementor-image-dimensions-apply-button"><?php echo __( 'Apply', 'elementor' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Image editor support.
|
||||
*
|
||||
* Used to determine whether the editor supports a given image mime-type.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @return bool Whether the editor supports the given mime-type.
|
||||
*/
|
||||
private function is_image_editor_supports() {
|
||||
$arg = [
|
||||
'mime_type' => 'image/jpeg',
|
||||
];
|
||||
return ( wp_image_editor_supports( $arg ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor media control.
|
||||
*
|
||||
* A base control for creating a media chooser control. Based on the WordPress
|
||||
* media library. Used to select an image from the WordPress media library.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Media extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get media control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `media`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'media';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media control default values.
|
||||
*
|
||||
* Retrieve the default value of the media control. Used to return the default
|
||||
* values while initializing the media control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'url' => '',
|
||||
'id' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Import media images.
|
||||
*
|
||||
* Used to import media control files from external sites while importing
|
||||
* Elementor template JSON file, and replacing the old data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $settings Control settings
|
||||
*
|
||||
* @return array Control settings.
|
||||
*/
|
||||
public function on_import( $settings ) {
|
||||
if ( empty( $settings['url'] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$settings = Plugin::$instance->templates_manager->get_import_images_instance()->import( $settings );
|
||||
|
||||
if ( ! $settings ) {
|
||||
$settings = [
|
||||
'id' => '',
|
||||
'url' => Utils::get_placeholder_image_src(),
|
||||
];
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue media control scripts and styles.
|
||||
*
|
||||
* Used to register and enqueue custom scripts and styles used by the media
|
||||
* control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue() {
|
||||
global $wp_version;
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
wp_enqueue_media();
|
||||
|
||||
wp_enqueue_style(
|
||||
'media',
|
||||
admin_url( '/css/media' . $suffix . '.css' ),
|
||||
[],
|
||||
$wp_version
|
||||
);
|
||||
|
||||
wp_register_script(
|
||||
'image-edit',
|
||||
'/wp-admin/js/image-edit' . $suffix . '.js',
|
||||
[
|
||||
'jquery',
|
||||
'json2',
|
||||
'imgareaselect',
|
||||
],
|
||||
$wp_version,
|
||||
true
|
||||
);
|
||||
|
||||
wp_enqueue_script( 'image-edit' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render media control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field elementor-control-media">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<# if ( 'image' === data.media_type || 'video' === data.media_type ) { #>
|
||||
<div class="elementor-control-input-wrapper elementor-aspect-ratio-219">
|
||||
<div class="elementor-control-media__content elementor-control-tag-area elementor-control-preview-area elementor-fit-aspect-ratio">
|
||||
<div class="elementor-control-media-upload-button elementor-control-media__content__upload-button elementor-fit-aspect-ratio">
|
||||
<i class="eicon-plus-circle" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-control-media-area elementor-fit-aspect-ratio">
|
||||
<div class="elementor-control-media__remove elementor-control-media__content__remove" title="<?php echo __( 'Remove', 'elementor' ); ?>">
|
||||
<i class="eicon-trash-o"></i>
|
||||
</div>
|
||||
<# if( 'image' === data.media_type ) { #>
|
||||
<div class="elementor-control-media__preview elementor-fit-aspect-ratio"></div>
|
||||
<# } else if( 'video' === data.media_type ) { #>
|
||||
<video class="elementor-control-media-video" preload="metadata"></video>
|
||||
<i class="eicon-video-camera"></i>
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="elementor-control-media__tools elementor-control-dynamic-switcher-wrapper">
|
||||
<# if( 'image' === data.media_type ) { #>
|
||||
<div class="elementor-control-media__tool elementor-control-media__replace"><?php echo __( 'Choose Image', 'elementor' ); ?></div>
|
||||
<# } else if( 'video' === data.media_type ) { #>
|
||||
<div class="elementor-control-media__tool elementor-control-media__replace"><?php echo __( 'Choose Video', 'elementor' ); ?></div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<# } else { #>
|
||||
<div class="elementor-control-media__file elementor-control-preview-area">
|
||||
<div class="elementor-control-media__file__content">
|
||||
<div class="elementor-control-media__file__content__label"><?php echo __( 'Click the media icon to upload file', 'elementor' ); ?></div>
|
||||
<div class="elementor-control-media__file__content__info">
|
||||
<div class="elementor-control-media__file__content__info__icon">
|
||||
<i class="eicon-document-file"></i>
|
||||
</div>
|
||||
<div class="elementor-control-media__file__content__info__name"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-control-media__file__controls">
|
||||
<div class="elementor-control-media__remove elementor-control-media__file__controls__remove" title="<?php echo __( 'Remove', 'elementor' ); ?>">
|
||||
<i class="eicon-trash-o"></i>
|
||||
</div>
|
||||
<div class="elementor-control-media__file__controls__upload-button elementor-control-media-upload-button" title="<?php echo __( 'Upload', 'elementor' ); ?>">
|
||||
<i class="eicon-upload"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<# } #>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<input type="hidden" data-setting="{{ data.name }}"/>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the media control. Used to return the default
|
||||
* settings while initializing the media control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'media_type' => 'image',
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::IMAGE_CATEGORY ],
|
||||
'returnType' => 'object',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media control image title.
|
||||
*
|
||||
* Retrieve the `title` of the image selected by the media control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $attachment Media attachment.
|
||||
*
|
||||
* @return string Image title.
|
||||
*/
|
||||
public static function get_image_title( $attachment ) {
|
||||
if ( empty( $attachment['id'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return get_the_title( $attachment['id'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get media control image alt.
|
||||
*
|
||||
* Retrieve the `alt` value of the image selected by the media control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $instance Media attachment.
|
||||
*
|
||||
* @return string Image alt.
|
||||
*/
|
||||
public static function get_image_alt( $instance ) {
|
||||
if ( empty( $instance['id'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$attachment_id = $instance['id'];
|
||||
if ( ! $attachment_id ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$attachment = get_post( $attachment_id );
|
||||
if ( ! $attachment ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$alt = get_post_meta( $attachment_id, '_wp_attachment_image_alt', true );
|
||||
if ( ! $alt ) {
|
||||
$alt = $attachment->post_excerpt;
|
||||
if ( ! $alt ) {
|
||||
$alt = $attachment->post_title;
|
||||
}
|
||||
}
|
||||
return trim( strip_tags( $alt ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor number control.
|
||||
*
|
||||
* A base control for creating a number control. Displays a simple number input.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Number extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get number control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `number`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'number';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get number control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the number control. Used to return the
|
||||
* default settings while initializing the number control.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'min' => '',
|
||||
'max' => '',
|
||||
'step' => '',
|
||||
'placeholder' => '',
|
||||
'title' => '',
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::NUMBER_CATEGORY ],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render number control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-dynamic-switcher-wrapper">
|
||||
<input id="<?php echo $control_uid; ?>" type="number" min="{{ data.min }}" max="{{ data.max }}" step="{{ data.step }}" class="tooltip-target elementor-control-tag-area elementor-control-unit-2" data-tooltip="{{ data.title }}" title="{{ data.title }}" data-setting="{{ data.name }}" placeholder="{{ data.placeholder }}" />
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor popover toggle control.
|
||||
*
|
||||
* A base control for creating a popover toggle control. By default displays a toggle
|
||||
* button to open and close a popover.
|
||||
*
|
||||
* @since 1.9.0
|
||||
*/
|
||||
class Control_Popover_Toggle extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get popover toggle control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `popover_toggle`.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'popover_toggle';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get popover toggle control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the popover toggle control. Used to
|
||||
* return the default settings while initializing the popover toggle
|
||||
* control.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'return_value' => 'yes',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render popover toggle control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<input id="<?php echo $control_uid; ?>-custom" class="elementor-control-popover-toggle-toggle" type="radio" name="elementor-choose-{{ data.name }}-{{ data._cid }}" value="{{ data.return_value }}">
|
||||
<label class="elementor-control-popover-toggle-toggle-label elementor-control-unit-1" for="<?php echo $control_uid; ?>-custom">
|
||||
<i class="eicon-edit" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Edit', 'elementor' ); ?></span>
|
||||
</label>
|
||||
<input id="<?php echo $control_uid; ?>-default" class="elementor-control-popover-toggle-reset" type="radio" name="elementor-choose-{{ data.name }}-{{ data._cid }}" value="">
|
||||
<label class="elementor-control-popover-toggle-reset-label tooltip-target" for="<?php echo $control_uid; ?>-default" data-tooltip="<?php echo __( 'Back to default', 'elementor' ); ?>" data-tooltip-pos="s">
|
||||
<i class="eicon-undo" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Back to default', 'elementor' ); ?></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor raw HTML control.
|
||||
*
|
||||
* A base control for creating raw HTML control. Displays HTML markup between
|
||||
* controls in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Raw_Html extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get raw html control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `raw_html`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'raw_html';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render raw html control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<# data.raw = elementor.compileTemplate( data.raw, { view } );
|
||||
if ( data.label ) { #>
|
||||
<span class="elementor-control-title">{{{ data.label }}}</span>
|
||||
<# } #>
|
||||
<div class="elementor-control-raw-html {{ data.content_classes }}">{{{ data.raw }}}</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get raw html control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the raw html control. Used to return the
|
||||
* default settings while initializing the raw html control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'raw' => '',
|
||||
'content_classes' => '',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor repeater control.
|
||||
*
|
||||
* A base control for creating repeater control. Repeater control allows you to
|
||||
* build repeatable blocks of fields. You can create, for example, a set of
|
||||
* fields that will contain a title and a WYSIWYG text - the user will then be
|
||||
* able to add "rows", and each row will contain a title and a text. The data
|
||||
* can be wrapper in custom HTML tags, designed using CSS, and interact using JS
|
||||
* or external libraries.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Repeater extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get repeater control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `repeater`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'repeater';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater control default value.
|
||||
*
|
||||
* Retrieve the default value of the data control. Used to return the default
|
||||
* values while initializing the repeater control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the repeater control. Used to return the
|
||||
* default settings while initializing the repeater control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'fields' => [],
|
||||
'title_field' => '',
|
||||
'prevent_empty' => true,
|
||||
'is_repeater' => true,
|
||||
'item_actions' => [
|
||||
'add' => true,
|
||||
'duplicate' => true,
|
||||
'remove' => true,
|
||||
'sort' => true,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater control value.
|
||||
*
|
||||
* Retrieve the value of the repeater control from a specific Controls_Stack.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $control Control
|
||||
* @param array $settings Controls_Stack settings
|
||||
*
|
||||
* @return mixed Control values.
|
||||
*/
|
||||
public function get_value( $control, $settings ) {
|
||||
$value = parent::get_value( $control, $settings );
|
||||
|
||||
if ( ! empty( $value ) ) {
|
||||
foreach ( $value as &$item ) {
|
||||
foreach ( $control['fields'] as $field ) {
|
||||
$control_obj = Plugin::$instance->controls_manager->get_control( $field['type'] );
|
||||
|
||||
// Prior to 1.5.0 the fields may contains non-data controls.
|
||||
if ( ! $control_obj instanceof Base_Data_Control ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$item[ $field['name'] ] = $control_obj->get_value( $field, $item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Import repeater.
|
||||
*
|
||||
* Used as a wrapper method for inner controls while importing Elementor
|
||||
* template JSON file, and replacing the old data.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $settings Control settings.
|
||||
* @param array $control_data Optional. Control data. Default is an empty array.
|
||||
*
|
||||
* @return array Control settings.
|
||||
*/
|
||||
public function on_import( $settings, $control_data = [] ) {
|
||||
if ( empty( $settings ) || empty( $control_data['fields'] ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$method = 'on_import';
|
||||
|
||||
foreach ( $settings as &$item ) {
|
||||
foreach ( $control_data['fields'] as $field ) {
|
||||
if ( empty( $field['name'] ) || empty( $item[ $field['name'] ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$control_obj = Plugin::$instance->controls_manager->get_control( $field['type'] );
|
||||
|
||||
if ( ! $control_obj ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( method_exists( $control_obj, $method ) ) {
|
||||
$item[ $field['name'] ] = $control_obj->{$method}( $item[ $field['name'] ], $field );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render repeater control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<label>
|
||||
<span class="elementor-control-title">{{{ data.label }}}</span>
|
||||
</label>
|
||||
<div class="elementor-repeater-fields-wrapper"></div>
|
||||
<# if ( itemActions.add ) { #>
|
||||
<div class="elementor-button-wrapper">
|
||||
<button class="elementor-button elementor-button-default elementor-repeater-add" type="button">
|
||||
<i class="eicon-plus" aria-hidden="true"></i><?php echo __( 'Add Item', 'elementor' ); ?>
|
||||
</button>
|
||||
</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor section control.
|
||||
*
|
||||
* A base control for creating section control. Displays a header that
|
||||
* functions as a toggle to show or hide a set of controls.
|
||||
*
|
||||
* Note: Do not use it directly, instead use `$widget->start_controls_section()`
|
||||
* and `$widget->end_controls_section()` to wrap a set of controls.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Section extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get section control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `section`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'section';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render section control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-panel-heading">
|
||||
<div class="elementor-panel-heading-toggle elementor-section-toggle" data-collapse_id="{{ data.name }}">
|
||||
<i class="eicon" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-panel-heading-title elementor-section-title">{{{ data.label }}}</div>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the repeater control. Used to return the
|
||||
* default settings while initializing the repeater control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'separator' => 'none',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor select control.
|
||||
*
|
||||
* A base control for creating select control. Displays a simple select box.
|
||||
* It accepts an array in which the `key` is the option value and the `value` is
|
||||
* the option name.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Select extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get select control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `select`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'select';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get select control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the select control. Used to return the
|
||||
* default settings while initializing the select control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'options' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render select control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<# if ( data.label ) {#>
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<# } #>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-5">
|
||||
<select id="<?php echo $control_uid; ?>" data-setting="{{ data.name }}">
|
||||
<#
|
||||
var printOptions = function( options ) {
|
||||
_.each( options, function( option_title, option_value ) { #>
|
||||
<option value="{{ option_value }}">{{{ option_title }}}</option>
|
||||
<# } );
|
||||
};
|
||||
|
||||
if ( data.groups ) {
|
||||
for ( var groupIndex in data.groups ) {
|
||||
var groupArgs = data.groups[ groupIndex ];
|
||||
if ( groupArgs.options ) { #>
|
||||
<optgroup label="{{ groupArgs.label }}">
|
||||
<# printOptions( groupArgs.options ) #>
|
||||
</optgroup>
|
||||
<# } else if ( _.isString( groupArgs ) ) { #>
|
||||
<option value="{{ groupIndex }}">{{{ groupArgs }}}</option>
|
||||
<# }
|
||||
}
|
||||
} else {
|
||||
printOptions( data.options );
|
||||
}
|
||||
#>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor select2 control.
|
||||
*
|
||||
* A base control for creating select2 control. Displays a select box control
|
||||
* based on select2 jQuery plugin @see https://select2.github.io/ .
|
||||
* It accepts an array in which the `key` is the value and the `value` is the
|
||||
* option name. Set `multiple` to `true` to allow multiple value selection.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Select2 extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get select2 control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `select2`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'select2';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get select2 control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the select2 control. Used to return the
|
||||
* default settings while initializing the select2 control.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'options' => [],
|
||||
'multiple' => false,
|
||||
'select2options' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render select2 control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<# if ( data.label ) {#>
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<# } #>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-5">
|
||||
<# var multiple = ( data.multiple ) ? 'multiple' : ''; #>
|
||||
<select id="<?php echo $control_uid; ?>" class="elementor-select2" type="select2" {{ multiple }} data-setting="{{ data.name }}">
|
||||
<# _.each( data.options, function( option_title, option_value ) {
|
||||
var value = data.controlValue;
|
||||
if ( typeof value == 'string' ) {
|
||||
var selected = ( option_value === value ) ? 'selected' : '';
|
||||
} else if ( null !== value ) {
|
||||
var value = _.values( value );
|
||||
var selected = ( -1 !== value.indexOf( option_value ) ) ? 'selected' : '';
|
||||
}
|
||||
#>
|
||||
<option {{ selected }} value="{{ option_value }}">{{{ option_title }}}</option>
|
||||
<# } ); #>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor slider control.
|
||||
*
|
||||
* A base control for creating slider control. Displays a draggable range slider.
|
||||
* The slider control can optionally have a number of unit types (`size_units`)
|
||||
* for the user to choose from. The control also accepts a range argument that
|
||||
* allows you to set the `min`, `max` and `step` values per unit type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Slider extends Control_Base_Units {
|
||||
|
||||
/**
|
||||
* Get slider control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `slider`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'slider';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get slider control default values.
|
||||
*
|
||||
* Retrieve the default value of the slider control. Used to return the default
|
||||
* values while initializing the slider control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return array_merge(
|
||||
parent::get_default_value(), [
|
||||
'size' => '',
|
||||
'sizes' => [],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get slider control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the slider control. Used to return the
|
||||
* default settings while initializing the slider control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return array_merge(
|
||||
parent::get_default_settings(), [
|
||||
'label_block' => true,
|
||||
'labels' => [],
|
||||
'scales' => 0,
|
||||
'handles' => 'default',
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::NUMBER_CATEGORY ],
|
||||
'property' => 'size',
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render slider control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<?php $this->print_units_template(); ?>
|
||||
<div class="elementor-control-input-wrapper elementor-control-dynamic-switcher-wrapper elementor-clearfix elementor-control-tag-area">
|
||||
<# if ( isMultiple && ( data.labels.length || data.scales ) ) { #>
|
||||
<div class="elementor-slider__extra">
|
||||
<# if ( data.labels.length ) { #>
|
||||
<div class="elementor-slider__labels">
|
||||
<# jQuery.each( data.labels, ( index, label ) => { #>
|
||||
<div class="elementor-slider__label">{{{ label }}}</div>
|
||||
<# } ); #>
|
||||
</div>
|
||||
<# } if ( data.scales ) { #>
|
||||
<div class="elementor-slider__scales">
|
||||
<# for ( var i = 0; i < data.scales; i++ ) { #>
|
||||
<div class="elementor-slider__scale"></div>
|
||||
<# } #>
|
||||
</div>
|
||||
<# } #>
|
||||
</div>
|
||||
<# } #>
|
||||
<div class="elementor-slider"></div>
|
||||
<# if ( ! isMultiple ) { #>
|
||||
<div class="elementor-slider-input">
|
||||
<input id="<?php echo $control_uid; ?>" type="number" min="{{ data.min }}" max="{{ data.max }}" step="{{ data.step }}" data-setting="size" />
|
||||
</div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor structure control.
|
||||
*
|
||||
* A base control for creating structure control. A private control for section
|
||||
* columns structure.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Structure extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get structure control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `structure`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'structure';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render structure control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$preset_control_uid = $this->get_control_uid( '{{ preset.key }}' );
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<#
|
||||
var morePresets = getMorePresets();
|
||||
|
||||
if ( morePresets.length ) { #>
|
||||
<div class="elementor-control-structure-presets">
|
||||
<# _.each( morePresets, function( preset ) { #>
|
||||
<div class="elementor-control-structure-preset-wrapper">
|
||||
<input id="<?php echo $preset_control_uid; ?>" type="radio" name="elementor-control-structure-preset-{{ data._cid }}" data-setting="structure" value="{{ preset.key }}">
|
||||
<label for="<?php echo $preset_control_uid; ?>" class="elementor-control-structure-preset">
|
||||
{{{ elementor.presetsFactory.getPresetSVG( preset.preset, 102, 42 ).outerHTML }}}
|
||||
</label>
|
||||
<div class="elementor-control-structure-preset-title">{{{ preset.preset.join( ', ' ) }}}</div>
|
||||
</div>
|
||||
<# } ); #>
|
||||
</div>
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="elementor-control-structure-reset">
|
||||
<i class="eicon-undo" aria-hidden="true"></i>
|
||||
<?php echo __( 'Reset', 'elementor' ); ?>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get structure control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the structure control. Used to return the
|
||||
* default settings while initializing the structure control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'separator' => 'none',
|
||||
'label_block' => true,
|
||||
'show_label' => false,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor switcher control.
|
||||
*
|
||||
* A base control for creating switcher control. Displays an on/off switcher,
|
||||
* basically a fancy UI representation of a checkbox.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Switcher extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get switcher control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `switcher`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'switcher';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render switcher control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<label class="elementor-switch elementor-control-unit-2">
|
||||
<input id="<?php echo $control_uid; ?>" type="checkbox" data-setting="{{ data.name }}" class="elementor-switch-input" value="{{ data.return_value }}">
|
||||
<span class="elementor-switch-label" data-on="{{ data.label_on }}" data-off="{{ data.label_off }}"></span>
|
||||
<span class="elementor-switch-handle"></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get switcher control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the switcher control. Used to return the
|
||||
* default settings while initializing the switcher control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_off' => __( 'No', 'elementor' ),
|
||||
'label_on' => __( 'Yes', 'elementor' ),
|
||||
'return_value' => 'yes',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor tab control.
|
||||
*
|
||||
* A base control for creating tab control. Displays a tab header for a set of
|
||||
* controls.
|
||||
*
|
||||
* Note: Do not use it directly, instead use: `$widget->start_controls_tab()`
|
||||
* and in the end `$widget->end_controls_tab()`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Tab extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get tab control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `tab`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'tab';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render tab control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-panel-tab-heading">
|
||||
{{{ data.label }}}
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tab control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the tab control. Used to return the
|
||||
* default settings while initializing the tab control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'separator' => 'none',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor tabs control.
|
||||
*
|
||||
* A base control for creating tabs control. Displays a tabs header for `tab`
|
||||
* controls.
|
||||
*
|
||||
* Note: Do not use it directly, instead use: `$widget->start_controls_tabs()`
|
||||
* and in the end `$widget->end_controls_tabs()`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Tabs extends Base_UI_Control {
|
||||
|
||||
/**
|
||||
* Get tabs control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `tabs`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'tabs';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render tabs control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {}
|
||||
|
||||
/**
|
||||
* Get tabs control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the tabs control. Used to return the
|
||||
* default settings while initializing the tabs control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'separator' => 'none',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor text shadow control.
|
||||
*
|
||||
* A base control for creating text shadows control. Displays input fields for
|
||||
* horizontal shadow, vertical shadow, shadow blur and shadow color.
|
||||
*
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Control_Text_Shadow extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get text shadow control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `text_shadow`.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'text_shadow';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get text shadow control default values.
|
||||
*
|
||||
* Retrieve the default value of the text shadow control. Used to return the
|
||||
* default values while initializing the text shadow control.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'horizontal' => 0,
|
||||
'vertical' => 0,
|
||||
'blur' => 10,
|
||||
'color' => 'rgba(0,0,0,0.3)',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get text shadow control sliders.
|
||||
*
|
||||
* Retrieve the sliders of the text shadow control. Sliders are used while
|
||||
* rendering the control output in the editor.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control sliders.
|
||||
*/
|
||||
public function get_sliders() {
|
||||
return [
|
||||
'blur' => [
|
||||
'label' => __( 'Blur', 'elementor' ),
|
||||
'min' => 0,
|
||||
'max' => 100,
|
||||
],
|
||||
'horizontal' => [
|
||||
'label' => __( 'Horizontal', 'elementor' ),
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
'vertical' => [
|
||||
'label' => __( 'Vertical', 'elementor' ),
|
||||
'min' => -100,
|
||||
'max' => 100,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render text shadow control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-shadow-box">
|
||||
<div class="elementor-control-field elementor-color-picker-wrapper">
|
||||
<label class="elementor-control-title"><?php echo __( 'Color', 'elementor' ); ?></label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-1">
|
||||
<div class="elementor-color-picker-placeholder"></div>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
foreach ( $this->get_sliders() as $slider_name => $slider ) :
|
||||
$control_uid = $this->get_control_uid( $slider_name );
|
||||
?>
|
||||
<div class="elementor-shadow-slider elementor-control-type-slider">
|
||||
<label for="<?php echo esc_attr( $control_uid ); ?>" class="elementor-control-title"><?php echo $slider['label']; ?></label>
|
||||
<div class="elementor-control-input-wrapper">
|
||||
<div class="elementor-slider" data-input="<?php echo esc_attr( $slider_name ); ?>"></div>
|
||||
<div class="elementor-slider-input elementor-control-unit-2">
|
||||
<input id="<?php echo esc_attr( $control_uid ); ?>" type="number" min="<?php echo esc_attr( $slider['min'] ); ?>" max="<?php echo esc_attr( $slider['max'] ); ?>" data-setting="<?php echo esc_attr( $slider_name ); ?>"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor text control.
|
||||
*
|
||||
* A base control for creating text control. Displays a simple text input.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Text extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get text control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `text`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'text';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render text control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<# if ( data.label ) {#>
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<# } #>
|
||||
<div class="elementor-control-input-wrapper elementor-control-unit-5 elementor-control-dynamic-switcher-wrapper">
|
||||
<input id="<?php echo $control_uid; ?>" type="{{ data.input_type }}" class="tooltip-target elementor-control-tag-area" data-tooltip="{{ data.title }}" title="{{ data.title }}" data-setting="{{ data.name }}" placeholder="{{ data.placeholder }}" />
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Get text control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the text control. Used to return the
|
||||
* default settings while initializing the text control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'input_type' => 'text',
|
||||
'placeholder' => '',
|
||||
'title' => '',
|
||||
'dynamic' => [
|
||||
'categories' => [
|
||||
TagsModule::TEXT_CATEGORY,
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor textarea control.
|
||||
*
|
||||
* A base control for creating textarea control. Displays a classic textarea.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Textarea extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get textarea control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `textarea`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'textarea';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get textarea control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the textarea control. Used to return the
|
||||
* default settings while initializing the textarea control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'rows' => 5,
|
||||
'placeholder' => '',
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::TEXT_CATEGORY ],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render textarea control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-dynamic-switcher-wrapper">
|
||||
<textarea id="<?php echo $control_uid; ?>" class="elementor-control-tag-area" rows="{{ data.rows }}" data-setting="{{ data.name }}" placeholder="{{ data.placeholder }}"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor URL control.
|
||||
*
|
||||
* A base control for creating url control. Displays a URL input with the
|
||||
* ability to set the target of the link to `_blank` to open in a new tab.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_URL extends Control_Base_Multiple {
|
||||
|
||||
/**
|
||||
* Get url control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `url`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'url';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url control default values.
|
||||
*
|
||||
* Retrieve the default value of the url control. Used to return the default
|
||||
* values while initializing the url control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [
|
||||
'url' => '',
|
||||
'is_external' => '',
|
||||
'nofollow' => '',
|
||||
'custom_attributes' => '',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get url control default settings.
|
||||
*
|
||||
* Retrieve the default settings of the url control. Used to return the default
|
||||
* settings while initializing the url control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'placeholder' => __( 'Paste URL or type', 'elementor' ),
|
||||
'autocomplete' => true,
|
||||
'options' => [ 'is_external', 'nofollow', 'custom_attributes' ],
|
||||
'dynamic' => [
|
||||
'categories' => [ TagsModule::URL_CATEGORY ],
|
||||
'property' => 'url',
|
||||
],
|
||||
'custom_attributes_description' => __( 'Set custom attributes for the link element. Separate attribute keys from values using the | (pipe) character. Separate key-value pairs with a comma.', 'elementor' )
|
||||
. ' <a href="https://go.elementor.com/panel-link-custom-attributes/" target="_blank">' . __( 'Learn More', 'elementor' ) . '</a>',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render url control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
$control_uid = $this->get_control_uid();
|
||||
$is_external_control_uid = $this->get_control_uid( 'is_external' );
|
||||
$nofollow_control_uid = $this->get_control_uid( 'nofollow' );
|
||||
$custom_attributes_uid = $this->get_control_uid( 'custom_attributes' );
|
||||
?>
|
||||
<div class="elementor-control-field elementor-control-url-external-{{{ ( data.options.length || data.show_external ) ? 'show' : 'hide' }}}">
|
||||
<label for="<?php echo $control_uid; ?>" class="elementor-control-title">{{{ data.label }}}</label>
|
||||
<div class="elementor-control-input-wrapper elementor-control-dynamic-switcher-wrapper">
|
||||
<i class="elementor-control-url-autocomplete-spinner eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
<input id="<?php echo $control_uid; ?>" class="elementor-control-tag-area elementor-input" data-setting="url" placeholder="{{ data.placeholder }}" />
|
||||
<input id="_ajax_linking_nonce" type="hidden" value="<?php echo wp_create_nonce( 'internal-linking' ); ?>" />
|
||||
<div class="elementor-control-url-more tooltip-target elementor-control-unit-1" data-tooltip="<?php echo __( 'Link Options', 'elementor' ); ?>">
|
||||
<i class="eicon-cog" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-control-url-more-options">
|
||||
<div class="elementor-control-url-option">
|
||||
<input id="<?php echo $is_external_control_uid; ?>" type="checkbox" class="elementor-control-url-option-input" data-setting="is_external">
|
||||
<label for="<?php echo $is_external_control_uid; ?>"><?php echo __( 'Open in new window', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-control-url-option">
|
||||
<input id="<?php echo $nofollow_control_uid; ?>" type="checkbox" class="elementor-control-url-option-input" data-setting="nofollow">
|
||||
<label for="<?php echo $nofollow_control_uid; ?>"><?php echo __( 'Add nofollow', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-control-url__custom-attributes">
|
||||
<label for="<?php echo $custom_attributes_uid; ?>" class="elementor-control-url__custom-attributes-label"><?php echo __( 'Custom Attributes', 'elementor' ); ?></label>
|
||||
<input type="text" id="<?php echo $custom_attributes_uid; ?>" class="elementor-control-unit-5" placeholder="key|value" data-setting="custom_attributes">
|
||||
</div>
|
||||
<# if ( ( data.options && -1 !== data.options.indexOf( 'custom_attributes' ) ) && data.custom_attributes_description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.custom_attributes_description }}}</div>
|
||||
<# } #>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor WordPress widget control.
|
||||
*
|
||||
* A base control for creating WordPress widget control. Displays native
|
||||
* WordPress widgets. This a private control for internal use.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_WP_Widget extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get WordPress widget control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `wp_widget`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'wp_widget';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get WordPress widget control default values.
|
||||
*
|
||||
* Retrieve the default value of the WordPress widget control. Used to return the
|
||||
* default values while initializing the WordPress widget control.
|
||||
*
|
||||
* @since 1.4.3
|
||||
* @access public
|
||||
*
|
||||
* @return array Control default value.
|
||||
*/
|
||||
public function get_default_value() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Render WordPress widget control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<form action="" method="post">
|
||||
<div class="wp-widget-form-loading">Loading..</div>
|
||||
</form>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Modules\DynamicTags\Module as TagsModule;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor WYSIWYG control.
|
||||
*
|
||||
* A base control for creating WYSIWYG control. Displays a WordPress WYSIWYG
|
||||
* (TinyMCE) editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Control_Wysiwyg extends Base_Data_Control {
|
||||
|
||||
/**
|
||||
* Get wysiwyg control type.
|
||||
*
|
||||
* Retrieve the control type, in this case `wysiwyg`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return string Control type.
|
||||
*/
|
||||
public function get_type() {
|
||||
return 'wysiwyg';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render wysiwyg control output in the editor.
|
||||
*
|
||||
* Used to generate the control HTML in the editor using Underscore JS
|
||||
* template. The variables for the class are available using `data` JS
|
||||
* object.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function content_template() {
|
||||
?>
|
||||
<div class="elementor-control-field">
|
||||
<div class="elementor-control-title">{{{ data.label }}}</div>
|
||||
<div class="elementor-control-input-wrapper elementor-control-tag-area"></div>
|
||||
</div>
|
||||
<# if ( data.description ) { #>
|
||||
<div class="elementor-control-field-description">{{{ data.description }}}</div>
|
||||
<# } #>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve textarea control default settings.
|
||||
*
|
||||
* Get the default settings of the textarea control. Used to return the
|
||||
* default settings while initializing the textarea control.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array Control default settings.
|
||||
*/
|
||||
protected function get_default_settings() {
|
||||
return [
|
||||
'label_block' => true,
|
||||
'dynamic' => [
|
||||
'active' => true,
|
||||
'categories' => [ TagsModule::TEXT_CATEGORY ],
|
||||
],
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,554 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\DynamicTags\Manager;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor database.
|
||||
*
|
||||
* Elementor database handler class is responsible for communicating with the
|
||||
* DB, save and retrieve Elementor data and meta data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class DB {
|
||||
|
||||
/**
|
||||
* Current DB version of the editor.
|
||||
*/
|
||||
const DB_VERSION = '0.4';
|
||||
|
||||
/**
|
||||
* Post publish status.
|
||||
*/
|
||||
const STATUS_PUBLISH = 'publish';
|
||||
|
||||
/**
|
||||
* Post draft status.
|
||||
*/
|
||||
const STATUS_DRAFT = 'draft';
|
||||
|
||||
/**
|
||||
* Post private status.
|
||||
*/
|
||||
const STATUS_PRIVATE = 'private';
|
||||
|
||||
/**
|
||||
* Post autosave status.
|
||||
*/
|
||||
const STATUS_AUTOSAVE = 'autosave';
|
||||
|
||||
/**
|
||||
* Post pending status.
|
||||
*/
|
||||
const STATUS_PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* Switched post data.
|
||||
*
|
||||
* Holds the switched post data.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @var array Switched post data. Default is an empty array.
|
||||
*/
|
||||
protected $switched_post_data = [];
|
||||
|
||||
/**
|
||||
* Switched data.
|
||||
*
|
||||
* Holds the switched data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @var array Switched data. Default is an empty array.
|
||||
*/
|
||||
protected $switched_data = [];
|
||||
|
||||
/**
|
||||
* Get builder.
|
||||
*
|
||||
* Retrieve editor data from the database.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $status Optional. Post status. Default is `publish`.
|
||||
*
|
||||
* @return array Editor data.
|
||||
*/
|
||||
public function get_builder( $post_id, $status = self::STATUS_PUBLISH ) {
|
||||
if ( self::STATUS_DRAFT === $status ) {
|
||||
$document = Plugin::$instance->documents->get_doc_or_auto_save( $post_id );
|
||||
} else {
|
||||
$document = Plugin::$instance->documents->get( $post_id );
|
||||
}
|
||||
|
||||
if ( $document ) {
|
||||
$editor_data = $document->get_elements_raw_data( null, true );
|
||||
} else {
|
||||
$editor_data = [];
|
||||
}
|
||||
|
||||
return $editor_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get JSON meta.
|
||||
*
|
||||
* Retrieve post meta data, and return the JSON decoded data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param string $key The meta key to retrieve.
|
||||
*
|
||||
* @return array Decoded JSON data from post meta.
|
||||
*/
|
||||
protected function _get_json_meta( $post_id, $key ) {
|
||||
$meta = get_post_meta( $post_id, $key, true );
|
||||
|
||||
if ( is_string( $meta ) && ! empty( $meta ) ) {
|
||||
$meta = json_decode( $meta, true );
|
||||
}
|
||||
|
||||
if ( empty( $meta ) ) {
|
||||
$meta = [];
|
||||
}
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get new editor from WordPress editor.
|
||||
*
|
||||
* When editing the with Elementor the first time, the current page content
|
||||
* is parsed into Text Editor Widget that contains the original data.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @deprecated 2.3.0 Use `Plugin::$instance->documents->get( $post_id )->convert_to_elementor()` instead
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*
|
||||
* @return array Content in Elementor format.
|
||||
*/
|
||||
public function get_new_editor_from_wp_editor( $post_id ) {
|
||||
_deprecated_function( __METHOD__, '2.3.0', 'Plugin::$instance->documents->get( $post_id )->convert_to_elementor()' );
|
||||
|
||||
$document = Plugin::$instance->documents->get( $post_id );
|
||||
|
||||
if ( $document ) {
|
||||
return $document->convert_to_elementor();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is using Elementor.
|
||||
*
|
||||
* Set whether the page is using Elementor or not.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param bool $is_elementor Optional. Whether the page is elementor page.
|
||||
* Default is true.
|
||||
*/
|
||||
public function set_is_elementor_page( $post_id, $is_elementor = true ) {
|
||||
if ( $is_elementor ) {
|
||||
// Use the string `builder` and not a boolean for rollback compatibility
|
||||
update_post_meta( $post_id, '_elementor_edit_mode', 'builder' );
|
||||
} else {
|
||||
delete_post_meta( $post_id, '_elementor_edit_mode' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render element plain content.
|
||||
*
|
||||
* When saving data in the editor, this method renders recursively the plain
|
||||
* content containing only the content and the HTML. No CSS data.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*
|
||||
* @param array $element_data Element data.
|
||||
*/
|
||||
private function render_element_plain_content( $element_data ) {
|
||||
if ( 'widget' === $element_data['elType'] ) {
|
||||
/** @var Widget_Base $widget */
|
||||
$widget = Plugin::$instance->elements_manager->create_element_instance( $element_data );
|
||||
|
||||
if ( $widget ) {
|
||||
$widget->render_plain_content();
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! empty( $element_data['elements'] ) ) {
|
||||
foreach ( $element_data['elements'] as $element ) {
|
||||
$this->render_element_plain_content( $element );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save plain text.
|
||||
*
|
||||
* Retrieves the raw content, removes all kind of unwanted HTML tags and saves
|
||||
* the content as the `post_content` field in the database.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*/
|
||||
public function save_plain_text( $post_id ) {
|
||||
// Switch $dynamic_tags to parsing mode = remove.
|
||||
$dynamic_tags = Plugin::$instance->dynamic_tags;
|
||||
$parsing_mode = $dynamic_tags->get_parsing_mode();
|
||||
$dynamic_tags->set_parsing_mode( Manager::MODE_REMOVE );
|
||||
|
||||
$plain_text = $this->get_plain_text( $post_id );
|
||||
|
||||
wp_update_post(
|
||||
[
|
||||
'ID' => $post_id,
|
||||
'post_content' => $plain_text,
|
||||
]
|
||||
);
|
||||
|
||||
// Restore parsing mode.
|
||||
$dynamic_tags->set_parsing_mode( $parsing_mode );
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate data.
|
||||
*
|
||||
* Accept any type of Elementor data and a callback function. The callback
|
||||
* function runs recursively for each element and his child elements.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $data_container Any type of elementor data.
|
||||
* @param callable $callback A function to iterate data by.
|
||||
* @param array $args Array of args pointers for passing parameters in & out of the callback
|
||||
*
|
||||
* @return mixed Iterated data.
|
||||
*/
|
||||
public function iterate_data( $data_container, $callback, $args = [] ) {
|
||||
if ( isset( $data_container['elType'] ) ) {
|
||||
if ( ! empty( $data_container['elements'] ) ) {
|
||||
$data_container['elements'] = $this->iterate_data( $data_container['elements'], $callback, $args );
|
||||
}
|
||||
|
||||
return call_user_func( $callback, $data_container, $args );
|
||||
}
|
||||
|
||||
foreach ( $data_container as $element_key => $element_value ) {
|
||||
$element_data = $this->iterate_data( $data_container[ $element_key ], $callback, $args );
|
||||
|
||||
if ( null === $element_data ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$data_container[ $element_key ] = $element_data;
|
||||
}
|
||||
|
||||
return $data_container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Safely copy Elementor meta.
|
||||
*
|
||||
* Make sure the original page was built with Elementor and the post is not
|
||||
* auto-save. Only then copy elementor meta from one post to another using
|
||||
* `copy_elementor_meta()`.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @param int $from_post_id Original post ID.
|
||||
* @param int $to_post_id Target post ID.
|
||||
*/
|
||||
public function safe_copy_elementor_meta( $from_post_id, $to_post_id ) {
|
||||
// It's from WP-Admin & not from Elementor.
|
||||
if ( ! did_action( 'elementor/db/before_save' ) ) {
|
||||
|
||||
if ( ! Plugin::$instance->db->is_built_with_elementor( $from_post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It's an exited Elementor auto-save
|
||||
if ( get_post_meta( $to_post_id, '_elementor_data', true ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->copy_elementor_meta( $from_post_id, $to_post_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy Elementor meta.
|
||||
*
|
||||
* Duplicate the data from one post to another.
|
||||
*
|
||||
* Consider using `safe_copy_elementor_meta()` method instead.
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $from_post_id Original post ID.
|
||||
* @param int $to_post_id Target post ID.
|
||||
*/
|
||||
public function copy_elementor_meta( $from_post_id, $to_post_id ) {
|
||||
$from_post_meta = get_post_meta( $from_post_id );
|
||||
$core_meta = [
|
||||
'_wp_page_template',
|
||||
'_thumbnail_id',
|
||||
];
|
||||
|
||||
foreach ( $from_post_meta as $meta_key => $values ) {
|
||||
// Copy only meta with the `_elementor` prefix
|
||||
if ( 0 === strpos( $meta_key, '_elementor' ) || in_array( $meta_key, $core_meta, true ) ) {
|
||||
$value = $values[0];
|
||||
|
||||
// The elementor JSON needs slashes before saving
|
||||
if ( '_elementor_data' === $meta_key ) {
|
||||
$value = wp_slash( $value );
|
||||
} else {
|
||||
$value = maybe_unserialize( $value );
|
||||
}
|
||||
|
||||
// Don't use `update_post_meta` that can't handle `revision` post type
|
||||
update_metadata( 'post', $to_post_id, $meta_key, $value );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is built with Elementor.
|
||||
*
|
||||
* Check whether the post was built with Elementor.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*
|
||||
* @return bool Whether the post was built with Elementor.
|
||||
*/
|
||||
public function is_built_with_elementor( $post_id ) {
|
||||
return ! ! get_post_meta( $post_id, '_elementor_edit_mode', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Switch to post.
|
||||
*
|
||||
* Change the global WordPress post to the requested post.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID to switch to.
|
||||
*/
|
||||
public function switch_to_post( $post_id ) {
|
||||
$post_id = absint( $post_id );
|
||||
// If is already switched, or is the same post, return.
|
||||
if ( get_the_ID() === $post_id ) {
|
||||
$this->switched_post_data[] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$this->switched_post_data[] = [
|
||||
'switched_id' => $post_id,
|
||||
'original_id' => get_the_ID(), // Note, it can be false if the global isn't set
|
||||
];
|
||||
|
||||
$GLOBALS['post'] = get_post( $post_id ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
setup_postdata( $GLOBALS['post'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore current post.
|
||||
*
|
||||
* Rollback to the previous global post, rolling back from `DB::switch_to_post()`.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function restore_current_post() {
|
||||
$data = array_pop( $this->switched_post_data );
|
||||
|
||||
// If not switched, return.
|
||||
if ( ! $data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// It was switched from an empty global post, restore this state and unset the global post
|
||||
if ( false === $data['original_id'] ) {
|
||||
unset( $GLOBALS['post'] );
|
||||
return;
|
||||
}
|
||||
|
||||
$GLOBALS['post'] = get_post( $data['original_id'] ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
setup_postdata( $GLOBALS['post'] );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Switch to query.
|
||||
*
|
||||
* Change the WordPress query to a new query with the requested
|
||||
* query variables.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $query_vars New query variables.
|
||||
* @param bool $force_global_post
|
||||
*/
|
||||
public function switch_to_query( $query_vars, $force_global_post = false ) {
|
||||
global $wp_query;
|
||||
$current_query_vars = $wp_query->query;
|
||||
|
||||
// If is already switched, or is the same query, return.
|
||||
if ( $current_query_vars === $query_vars ) {
|
||||
$this->switched_data[] = false;
|
||||
return;
|
||||
}
|
||||
|
||||
$new_query = new \WP_Query( $query_vars );
|
||||
|
||||
$switched_data = [
|
||||
'switched' => $new_query,
|
||||
'original' => $wp_query,
|
||||
];
|
||||
|
||||
if ( ! empty( $GLOBALS['post'] ) ) {
|
||||
$switched_data['post'] = $GLOBALS['post'];
|
||||
}
|
||||
|
||||
$this->switched_data[] = $switched_data;
|
||||
|
||||
$wp_query = $new_query; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
// Ensure the global post is set only if needed
|
||||
unset( $GLOBALS['post'] );
|
||||
|
||||
if ( isset( $new_query->posts[0] ) ) {
|
||||
if ( $force_global_post || $new_query->is_singular() ) {
|
||||
$GLOBALS['post'] = $new_query->posts[0]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
setup_postdata( $GLOBALS['post'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $new_query->is_author() ) {
|
||||
$GLOBALS['authordata'] = get_userdata( $new_query->get( 'author' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Restore current query.
|
||||
*
|
||||
* Rollback to the previous query, rolling back from `DB::switch_to_query()`.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function restore_current_query() {
|
||||
$data = array_pop( $this->switched_data );
|
||||
|
||||
// If not switched, return.
|
||||
if ( ! $data ) {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wp_query;
|
||||
|
||||
$wp_query = $data['original']; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
// Ensure the global post/authordata is set only if needed.
|
||||
unset( $GLOBALS['post'] );
|
||||
unset( $GLOBALS['authordata'] );
|
||||
|
||||
if ( ! empty( $data['post'] ) ) {
|
||||
$GLOBALS['post'] = $data['post']; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
setup_postdata( $GLOBALS['post'] );
|
||||
}
|
||||
|
||||
if ( $wp_query->is_author() ) {
|
||||
$GLOBALS['authordata'] = get_userdata( $wp_query->get( 'author' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plain text.
|
||||
*
|
||||
* Retrieve the post plain text.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
*
|
||||
* @return string Post plain text.
|
||||
*/
|
||||
public function get_plain_text( $post_id ) {
|
||||
$document = Plugin::$instance->documents->get( $post_id );
|
||||
$data = $document ? $document->get_elements_data() : [];
|
||||
|
||||
return $this->get_plain_text_from_data( $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get plain text from data.
|
||||
*
|
||||
* Retrieve the post plain text from any given Elementor data.
|
||||
*
|
||||
* @since 1.9.2
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Post ID.
|
||||
*
|
||||
* @return string Post plain text.
|
||||
*/
|
||||
public function get_plain_text_from_data( $data ) {
|
||||
ob_start();
|
||||
if ( $data ) {
|
||||
foreach ( $data as $element_data ) {
|
||||
$this->render_element_plain_content( $element_data );
|
||||
}
|
||||
}
|
||||
|
||||
$plain_text = ob_get_clean();
|
||||
|
||||
// Remove unnecessary tags.
|
||||
$plain_text = preg_replace( '/<\/?div[^>]*\>/i', '', $plain_text );
|
||||
$plain_text = preg_replace( '/<\/?span[^>]*\>/i', '', $plain_text );
|
||||
$plain_text = preg_replace( '#<script(.*?)>(.*?)</script>#is', '', $plain_text );
|
||||
$plain_text = preg_replace( '/<i [^>]*><\\/i[^>]*>/', '', $plain_text );
|
||||
$plain_text = preg_replace( '/ class=".*?"/', '', $plain_text );
|
||||
|
||||
// Remove empty lines.
|
||||
$plain_text = preg_replace( '/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/', "\n", $plain_text );
|
||||
|
||||
$plain_text = trim( $plain_text );
|
||||
|
||||
return $plain_text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
global $wp_version;
|
||||
|
||||
$body_classes = [
|
||||
'elementor-editor-active',
|
||||
'wp-version-' . str_replace( '.', '-', $wp_version ),
|
||||
];
|
||||
|
||||
if ( is_rtl() ) {
|
||||
$body_classes[] = 'rtl';
|
||||
}
|
||||
|
||||
if ( ! Plugin::$instance->role_manager->user_can( 'design' ) ) {
|
||||
$body_classes[] = 'elementor-editor-content-only';
|
||||
}
|
||||
|
||||
$notice = Plugin::$instance->editor->notice_bar->get_notice();
|
||||
?>
|
||||
<!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 __( 'Elementor', 'elementor' ) . ' | ' . get_the_title(); ?></title>
|
||||
<?php wp_head(); ?>
|
||||
<script>
|
||||
var ajaxurl = '<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>';
|
||||
</script>
|
||||
</head>
|
||||
<body class="<?php echo implode( ' ', $body_classes ); ?>">
|
||||
<div id="elementor-editor-wrapper">
|
||||
<div id="elementor-panel" class="elementor-panel"></div>
|
||||
<div id="elementor-preview">
|
||||
<div id="elementor-loading">
|
||||
<div class="elementor-loader-wrapper">
|
||||
<div class="elementor-loader">
|
||||
<div class="elementor-loader-boxes">
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-loading-title"><?php echo __( 'Loading', 'elementor' ); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="elementor-preview-responsive-wrapper" class="elementor-device-desktop elementor-device-rotate-portrait">
|
||||
<div id="elementor-preview-loading">
|
||||
<i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
</div>
|
||||
<?php if ( $notice ) { ?>
|
||||
<div id="elementor-notice-bar">
|
||||
<i class="eicon-elementor-square"></i>
|
||||
<div id="elementor-notice-bar__message"><?php echo sprintf( $notice['message'], $notice['action_url'] ); ?></div>
|
||||
<div id="elementor-notice-bar__action"><a href="<?php echo $notice['action_url']; ?>" target="_blank"><?php echo $notice['action_title']; ?></a></div>
|
||||
<i id="elementor-notice-bar__close" class="eicon-close"></i>
|
||||
</div>
|
||||
<?php } // IFrame will be created here by the Javascript later. ?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="elementor-navigator"></div>
|
||||
</div>
|
||||
<?php
|
||||
wp_footer();
|
||||
/** This action is documented in wp-admin/admin-footer.php */
|
||||
do_action( 'admin_print_footer_scripts' );
|
||||
?>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-empty-preview">
|
||||
<div class="elementor-first-add">
|
||||
<div class="elementor-icon eicon-plus"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-add-section">
|
||||
<div class="elementor-add-section-inner">
|
||||
<div class="elementor-add-section-close">
|
||||
<i class="eicon-close" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Close', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-add-new-section">
|
||||
<div class="elementor-add-section-area-button elementor-add-section-button" title="<?php echo __( 'Add New Section', 'elementor' ); ?>">
|
||||
<i class="eicon-plus"></i>
|
||||
</div>
|
||||
<div class="elementor-add-section-area-button elementor-add-template-button" title="<?php echo __( 'Add Template', 'elementor' ); ?>">
|
||||
<i class="eicon-folder"></i>
|
||||
</div>
|
||||
<div class="elementor-add-section-drag-title"><?php echo __( 'Drag widget here', 'elementor' ); ?></div>
|
||||
</div>
|
||||
<div class="elementor-select-preset">
|
||||
<div class="elementor-select-preset-title"><?php echo __( 'Select your Structure', 'elementor' ); ?></div>
|
||||
<ul class="elementor-select-preset-list">
|
||||
<#
|
||||
var structures = [ 10, 20, 30, 40, 21, 22, 31, 32, 33, 50, 60, 34 ];
|
||||
|
||||
_.each( structures, function( structure ) {
|
||||
var preset = elementor.presetsFactory.getPresetByStructure( structure ); #>
|
||||
|
||||
<li class="elementor-preset elementor-column elementor-col-16" data-structure="{{ structure }}">
|
||||
{{{ elementor.presetsFactory.getPresetSVG( preset.preset ).outerHTML }}}
|
||||
</li>
|
||||
<# } ); #>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-tag-controls-stack-empty">
|
||||
<?php echo __( 'This tag has no settings.', 'elementor' ); ?>
|
||||
</script>
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-hotkeys">
|
||||
<# var ctrlLabel = environment.mac ? 'Cmd' : 'Ctrl'; #>
|
||||
<div id="elementor-hotkeys__content">
|
||||
<div id="elementor-hotkeys__actions" class="elementor-hotkeys__col">
|
||||
|
||||
<div class="elementor-hotkeys__header">
|
||||
<h3><?php echo __( 'Actions', 'elementor' ); ?></h3>
|
||||
</div>
|
||||
<div class="elementor-hotkeys__list">
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Undo', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Z</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Redo', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Shift</span>
|
||||
<span>Z</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Copy', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>C</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Paste', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>V</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Paste Style', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Shift</span>
|
||||
<span>V</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Delete', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>Delete</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Duplicate', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>D</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Save', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>S</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="elementor-hotkeys__navigation" class="elementor-hotkeys__col">
|
||||
|
||||
<div class="elementor-hotkeys__header">
|
||||
<h3><?php echo __( 'Go To', 'elementor' ); ?></h3>
|
||||
</div>
|
||||
<div class="elementor-hotkeys__list">
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Finder', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>E</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Show / Hide Panel', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>P</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Responsive Mode', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Shift</span>
|
||||
<span>M</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'History', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Shift</span>
|
||||
<span>H</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Navigator', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>I</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Template Library', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>Shift</span>
|
||||
<span>L</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Keyboard Shortcuts', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>{{{ ctrlLabel }}}</span>
|
||||
<span>?</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="elementor-hotkeys__item">
|
||||
<div class="elementor-hotkeys__item--label"><?php echo __( 'Quit', 'elementor' ); ?></div>
|
||||
<div class="elementor-hotkeys__item--shortcut">
|
||||
<span>Esc</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly
|
||||
}
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-templates-modal__header">
|
||||
<div class="elementor-templates-modal__header__logo-area"></div>
|
||||
<div class="elementor-templates-modal__header__menu-area"></div>
|
||||
<div class="elementor-templates-modal__header__items-area">
|
||||
<# if ( closeType ) { #>
|
||||
<div class="elementor-templates-modal__header__close elementor-templates-modal__header__close--{{{ closeType }}} elementor-templates-modal__header__item">
|
||||
<# if ( 'skip' === closeType ) { #>
|
||||
<span><?php echo __( 'Skip', 'elementor' ); ?></span>
|
||||
<# } #>
|
||||
<i class="eicon-close" aria-hidden="true" title="<?php echo __( 'Close', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Close', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<# } #>
|
||||
<div id="elementor-template-library-header-tools"></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-templates-modal__header__logo">
|
||||
<span class="elementor-templates-modal__header__logo__icon-wrapper e-logo-wrapper">
|
||||
<i class="eicon-elementor"></i>
|
||||
</span>
|
||||
<span class="elementor-templates-modal__header__logo__title">{{{ title }}}</span>
|
||||
</script>
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-navigator">
|
||||
<div id="elementor-navigator__header">
|
||||
<i id="elementor-navigator__toggle-all" class="eicon-expand" data-elementor-action="expand"></i>
|
||||
<div id="elementor-navigator__header__title"><?php echo __( 'Navigator', 'elementor' ); ?></div>
|
||||
<i id="elementor-navigator__close" class="eicon-close"></i>
|
||||
</div>
|
||||
<div id="elementor-navigator__elements"></div>
|
||||
<div id="elementor-navigator__footer">
|
||||
<i class="eicon-ellipsis-h"></i>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-navigator__elements">
|
||||
<# if ( obj.elType ) { #>
|
||||
<div class="elementor-navigator__item">
|
||||
<div class="elementor-navigator__element__list-toggle">
|
||||
<i class="eicon-sort-down"></i>
|
||||
</div>
|
||||
<#
|
||||
if ( icon ) { #>
|
||||
<div class="elementor-navigator__element__element-type">
|
||||
<i class="{{{ icon }}}"></i>
|
||||
</div>
|
||||
<# } #>
|
||||
<div class="elementor-navigator__element__title">
|
||||
<span class="elementor-navigator__element__title__text">{{{ title }}}</span>
|
||||
</div>
|
||||
<div class="elementor-navigator__element__toggle">
|
||||
<i class="eicon-preview-medium"></i>
|
||||
</div>
|
||||
<div class="elementor-navigator__element__indicators"></div>
|
||||
</div>
|
||||
<# } #>
|
||||
<div class="elementor-navigator__elements"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-navigator__elements--empty">
|
||||
<div class="elementor-empty-view__title"><?php echo __( 'Empty', 'elementor' ); ?></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-navigator__root--empty">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/information.svg'; ?>" />
|
||||
<div class="elementor-nerd-box-title"><?php echo __( 'Easy Navigation is Here!', 'elementor' ); ?></div>
|
||||
<div class="elementor-nerd-box-message"><?php echo __( 'Once you fill your page with content, this window will give you an overview display of all the page elements. This way, you can easily move around any section, column, or widget.', 'elementor' ); ?></div>
|
||||
</script>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-panel-elements">
|
||||
<div id="elementor-panel-elements-navigation" class="elementor-panel-navigation">
|
||||
<div class="elementor-component-tab elementor-panel-navigation-tab" data-tab="categories"><?php echo __( 'Elements', 'elementor' ); ?></div>
|
||||
<div class="elementor-component-tab elementor-panel-navigation-tab" data-tab="global"><?php echo __( 'Global', 'elementor' ); ?></div>
|
||||
</div>
|
||||
<div id="elementor-panel-elements-search-area"></div>
|
||||
<div id="elementor-panel-elements-wrapper"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-categories">
|
||||
<div id="elementor-panel-categories"></div>
|
||||
|
||||
<div id="elementor-panel-get-pro-elements" class="elementor-nerd-box">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/go-pro.svg'; ?>" />
|
||||
<div class="elementor-nerd-box-message"><?php echo __( 'Get more with Elementor Pro', 'elementor' ); ?></div>
|
||||
<a class="elementor-button elementor-button-default elementor-nerd-box-link" target="_blank" href="<?php echo Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=panel-widgets&utm_campaign=gopro&utm_medium=wp-dash' ); ?>"><?php echo __( 'Go Pro', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-elements-category">
|
||||
<div class="elementor-panel-category-title">{{{ title }}}</div>
|
||||
<div class="elementor-panel-category-items"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-element-search">
|
||||
<label for="elementor-panel-elements-search-input" class="screen-reader-text"><?php echo __( 'Search Widget:', 'elementor' ); ?></label>
|
||||
<input type="search" id="elementor-panel-elements-search-input" placeholder="<?php esc_attr_e( 'Search Widget...', 'elementor' ); ?>" autocomplete="off"/>
|
||||
<i class="eicon-search-bold" aria-hidden="true"></i>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-element-library-element">
|
||||
<div class="elementor-element">
|
||||
<# if ( false === obj.editable ) { #>
|
||||
<i class="eicon-lock"></i>
|
||||
<# } #>
|
||||
<div class="icon">
|
||||
<i class="{{ icon }}" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-element-title-wrapper">
|
||||
<div class="title">{{{ title }}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-global">
|
||||
<div class="elementor-nerd-box">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/information.svg'; ?>" />
|
||||
<div class="elementor-nerd-box-title"><?php echo __( 'Meet Our Global Widget', 'elementor' ); ?></div>
|
||||
<div class="elementor-nerd-box-message"><?php echo __( 'With this feature, you can save a widget as global, then add it to multiple areas. All areas will be editable from one single place.', 'elementor' ); ?></div>
|
||||
<a class="elementor-button elementor-button-default elementor-nerd-box-link" target="_blank" href="<?php echo Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=panel-global&utm_campaign=gopro&utm_medium=wp-dash' ); ?>"><?php echo __( 'Go Pro', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Responsive\Responsive;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
$document = Plugin::$instance->documents->get( Plugin::$instance->editor->get_post_id() );
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-panel">
|
||||
<div id="elementor-mode-switcher"></div>
|
||||
<div id="elementor-panel-state-loading">
|
||||
<i class="eicon-loading eicon-animation-spin"></i>
|
||||
</div>
|
||||
<header id="elementor-panel-header-wrapper"></header>
|
||||
<main id="elementor-panel-content-wrapper"></main>
|
||||
<footer id="elementor-panel-footer">
|
||||
<div class="elementor-panel-container">
|
||||
</div>
|
||||
</footer>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-menu">
|
||||
<div id="elementor-panel-page-menu-content"></div>
|
||||
<# if ( elementor.config.document.panel.needHelpUrl ) { #>
|
||||
<div id="elementor-panel__editor__help">
|
||||
<a id="elementor-panel__editor__help__link" href="{{{ elementor.config.document.panel.needHelpUrl }}}" target="_blank">
|
||||
<?php echo __( 'Need Help', 'elementor' ); ?>
|
||||
<i class="eicon-help-o"></i>
|
||||
</a>
|
||||
</div>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-menu-group">
|
||||
<div class="elementor-panel-menu-group-title">{{{ title }}}</div>
|
||||
<div class="elementor-panel-menu-items"></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-menu-item">
|
||||
<div class="elementor-panel-menu-item-icon">
|
||||
<i class="{{ icon }}"></i>
|
||||
</div>
|
||||
<# if ( 'undefined' === typeof type || 'link' !== type ) { #>
|
||||
<div class="elementor-panel-menu-item-title">{{{ title }}}</div>
|
||||
<# } else {
|
||||
let target = ( 'undefined' !== typeof newTab && newTab ) ? '_blank' : '_self';
|
||||
#>
|
||||
<a href="{{ link }}" target="{{ target }}"><div class="elementor-panel-menu-item-title">{{{ title }}}</div></a>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-header">
|
||||
<div id="elementor-panel-header-menu-button" class="elementor-header-button">
|
||||
<i class="elementor-icon eicon-menu-bar tooltip-target" aria-hidden="true" data-tooltip="<?php esc_attr_e( 'Menu', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Menu', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-panel-header-title"></div>
|
||||
<div id="elementor-panel-header-add-button" class="elementor-header-button">
|
||||
<i class="elementor-icon eicon-apps tooltip-target" aria-hidden="true" data-tooltip="<?php esc_attr_e( 'Widgets Panel', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Widgets Panel', 'elementor' ); ?></span>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-footer-content">
|
||||
<div id="elementor-panel-footer-settings" class="elementor-panel-footer-tool elementor-leave-open tooltip-target" data-tooltip="<?php esc_attr_e( 'Settings', 'elementor' ); ?>">
|
||||
<i class="eicon-cog" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php printf( __( '%s Settings', 'elementor' ), $document::get_title() ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-navigator" class="elementor-panel-footer-tool tooltip-target" data-tooltip="<?php esc_attr_e( 'Navigator', 'elementor' ); ?>">
|
||||
<i class="eicon-navigator" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Navigator', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-history" class="elementor-panel-footer-tool elementor-leave-open tooltip-target" data-tooltip="<?php esc_attr_e( 'History', 'elementor' ); ?>">
|
||||
<i class="eicon-history" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'History', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-responsive" class="elementor-panel-footer-tool elementor-toggle-state">
|
||||
<i class="eicon-device-desktop tooltip-target" aria-hidden="true" data-tooltip="<?php esc_attr_e( 'Responsive Mode', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only">
|
||||
<?php echo __( 'Responsive Mode', 'elementor' ); ?>
|
||||
</span>
|
||||
<div class="elementor-panel-footer-sub-menu-wrapper">
|
||||
<div class="elementor-panel-footer-sub-menu">
|
||||
<div class="elementor-panel-footer-sub-menu-item" data-device-mode="desktop">
|
||||
<i class="elementor-icon eicon-device-desktop" aria-hidden="true"></i>
|
||||
<span class="elementor-title"><?php echo __( 'Desktop', 'elementor' ); ?></span>
|
||||
<span class="elementor-description"><?php echo __( 'Default Preview', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-panel-footer-sub-menu-item" data-device-mode="tablet">
|
||||
<i class="elementor-icon eicon-device-tablet" aria-hidden="true"></i>
|
||||
<span class="elementor-title"><?php echo __( 'Tablet', 'elementor' ); ?></span>
|
||||
<?php $breakpoints = Responsive::get_breakpoints(); ?>
|
||||
<span class="elementor-description"><?php echo sprintf( __( 'Preview for %s', 'elementor' ), $breakpoints['md'] . 'px' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-panel-footer-sub-menu-item" data-device-mode="mobile">
|
||||
<i class="elementor-icon eicon-device-mobile" aria-hidden="true"></i>
|
||||
<span class="elementor-title"><?php echo __( 'Mobile', 'elementor' ); ?></span>
|
||||
<span class="elementor-description"><?php echo sprintf( __( 'Preview for %s', 'elementor' ), '360px' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-saver-preview" class="elementor-panel-footer-tool tooltip-target" data-tooltip="<?php esc_attr_e( 'Preview Changes', 'elementor' ); ?>">
|
||||
<span id="elementor-panel-footer-saver-preview-label">
|
||||
<i class="eicon-preview-medium" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Preview Changes', 'elementor' ); ?></span>
|
||||
</span>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-saver-publish" class="elementor-panel-footer-tool">
|
||||
<button id="elementor-panel-saver-button-publish" class="elementor-button elementor-button-success elementor-disabled">
|
||||
<span class="elementor-state-icon">
|
||||
<i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span id="elementor-panel-saver-button-publish-label">
|
||||
<?php echo __( 'Publish', 'elementor' ); ?>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-saver-options" class="elementor-panel-footer-tool elementor-toggle-state">
|
||||
<button id="elementor-panel-saver-button-save-options" class="elementor-button elementor-button-success tooltip-target elementor-disabled" data-tooltip="<?php esc_attr_e( 'Save Options', 'elementor' ); ?>" data-tooltip-offset="7">
|
||||
<i class="eicon-caret-up" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Save Options', 'elementor' ); ?></span>
|
||||
</button>
|
||||
<div class="elementor-panel-footer-sub-menu-wrapper">
|
||||
<p class="elementor-last-edited-wrapper">
|
||||
<span class="elementor-state-icon">
|
||||
<i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
</span>
|
||||
<span class="elementor-last-edited">
|
||||
</span>
|
||||
</p>
|
||||
<div class="elementor-panel-footer-sub-menu">
|
||||
<div id="elementor-panel-footer-sub-menu-item-save-draft" class="elementor-panel-footer-sub-menu-item elementor-disabled">
|
||||
<i class="elementor-icon eicon-save" aria-hidden="true"></i>
|
||||
<span class="elementor-title"><?php echo __( 'Save Draft', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-panel-footer-sub-menu-item-save-template" class="elementor-panel-footer-sub-menu-item">
|
||||
<i class="elementor-icon eicon-folder" aria-hidden="true"></i>
|
||||
<span class="elementor-title"><?php echo __( 'Save as Template', 'elementor' ); ?></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-mode-switcher-content">
|
||||
<input id="elementor-mode-switcher-preview-input" type="checkbox">
|
||||
<label for="elementor-mode-switcher-preview-input" id="elementor-mode-switcher-preview">
|
||||
<i class="eicon" aria-hidden="true" title="<?php esc_attr_e( 'Hide Panel', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Hide Panel', 'elementor' ); ?></span>
|
||||
</label>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-editor-content">
|
||||
<div class="elementor-panel-navigation">
|
||||
<# _.each( elementData.tabs_controls, function( tabTitle, tabSlug ) {
|
||||
if ( 'content' !== tabSlug && ! elementor.userCan( 'design' ) ) {
|
||||
return;
|
||||
}
|
||||
$e.bc.ensureTab( 'panel/editor', tabSlug );
|
||||
#>
|
||||
<div class="elementor-component-tab elementor-panel-navigation-tab elementor-tab-control-{{ tabSlug }}" data-tab="{{ tabSlug }}">
|
||||
<a href="#">{{{ tabTitle }}}</a>
|
||||
</div>
|
||||
<# } ); #>
|
||||
</div>
|
||||
<# if ( elementData.reload_preview ) { #>
|
||||
<div class="elementor-update-preview">
|
||||
<div class="elementor-update-preview-title"><?php echo __( 'Update changes to page', 'elementor' ); ?></div>
|
||||
<div class="elementor-update-preview-button-wrapper">
|
||||
<button class="elementor-update-preview-button elementor-button elementor-button-success"><?php echo __( 'Apply', 'elementor' ); ?></button>
|
||||
</div>
|
||||
</div>
|
||||
<# } #>
|
||||
<div id="elementor-controls"></div>
|
||||
<# if ( elementData.help_url ) { #>
|
||||
<div id="elementor-panel__editor__help">
|
||||
<a id="elementor-panel__editor__help__link" href="{{ elementData.help_url }}" target="_blank">
|
||||
<?php echo __( 'Need Help', 'elementor' ); ?>
|
||||
<i class="eicon-help-o"></i>
|
||||
</a>
|
||||
</div>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-schemes-disabled">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/information.svg'; ?>" />
|
||||
<div class="elementor-nerd-box-title">{{{ '<?php echo __( '%s are disabled', 'elementor' ); ?>'.replace( '%s', disabledTitle ) }}}</div>
|
||||
<div class="elementor-nerd-box-message"><?php printf( __( 'You can enable it from the <a href="%s" target="_blank">Elementor settings page</a>.', 'elementor' ), Settings::get_url() ); ?></div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-scheme-color-item">
|
||||
<div class="elementor-panel-scheme-color-picker-placeholder"></div>
|
||||
<div class="elementor-panel-scheme-color-title">{{{ title }}}</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-panel-scheme-typography-item">
|
||||
<div class="elementor-panel-heading">
|
||||
<div class="elementor-panel-heading-toggle">
|
||||
<i class="eicon" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-panel-heading-title">{{{ title }}}</div>
|
||||
</div>
|
||||
<div class="elementor-panel-scheme-typography-items elementor-panel-box-content">
|
||||
<?php
|
||||
$scheme_fields_keys = Group_Control_Typography::get_scheme_fields_keys();
|
||||
|
||||
$typography_group = Plugin::$instance->controls_manager->get_control_groups( 'typography' );
|
||||
$typography_fields = $typography_group->get_fields();
|
||||
|
||||
$scheme_fields = array_intersect_key( $typography_fields, array_flip( $scheme_fields_keys ) );
|
||||
|
||||
foreach ( $scheme_fields as $option_name => $option ) :
|
||||
?>
|
||||
<div class="elementor-panel-scheme-typography-item elementor-control elementor-control-type-select">
|
||||
<div class="elementor-panel-scheme-item-title elementor-control-title"><?php echo $option['label']; ?></div>
|
||||
<div class="elementor-panel-scheme-typography-item-value elementor-control-input-wrapper">
|
||||
<?php if ( 'select' === $option['type'] ) : ?>
|
||||
<select name="<?php echo esc_attr( $option_name ); ?>" class="elementor-panel-scheme-typography-item-field">
|
||||
<?php foreach ( $option['options'] as $field_key => $field_value ) : ?>
|
||||
<option value="<?php echo esc_attr( $field_key ); ?>"><?php echo $field_value; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php elseif ( 'font' === $option['type'] ) : ?>
|
||||
<select name="<?php echo esc_attr( $option_name ); ?>" class="elementor-panel-scheme-typography-item-field">
|
||||
<option value=""><?php echo __( 'Default', 'elementor' ); ?></option>
|
||||
<?php foreach ( Fonts::get_font_groups() as $group_type => $group_label ) : ?>
|
||||
<optgroup label="<?php echo esc_attr( $group_label ); ?>">
|
||||
<?php foreach ( Fonts::get_fonts_by_groups( [ $group_type ] ) as $font_title => $font_type ) : ?>
|
||||
<option value="<?php echo esc_attr( $font_title ); ?>"><?php echo $font_title; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</optgroup>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<?php elseif ( 'text' === $option['type'] ) : ?>
|
||||
<input name="<?php echo esc_attr( $option_name ); ?>" class="elementor-panel-scheme-typography-item-field" />
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach; ?>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-control-responsive-switchers">
|
||||
<div class="elementor-control-responsive-switchers">
|
||||
<div class="elementor-control-responsive-switchers__holder">
|
||||
<#
|
||||
var devices = responsive.devices || [ 'desktop', 'tablet', 'mobile' ];
|
||||
|
||||
_.each( devices, function( device ) {
|
||||
var deviceLabel = device.charAt(0).toUpperCase() + device.slice(1),
|
||||
tooltipDir = "<?php echo is_rtl() ? 'e' : 'w'; ?>";
|
||||
#>
|
||||
<a class="elementor-responsive-switcher tooltip-target elementor-responsive-switcher-{{ device }}" data-device="{{ device }}" data-tooltip="{{ deviceLabel }}" data-tooltip-pos="{{ tooltipDir }}">
|
||||
<i class="eicon-device-{{ device }}"></i>
|
||||
</a>
|
||||
<# } );
|
||||
#>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-control-dynamic-switcher">
|
||||
<div class="elementor-control-dynamic-switcher elementor-control-unit-1" data-tooltip="<?php echo __( 'Dynamic Tags', 'elementor' ); ?>">
|
||||
<i class="eicon-database"></i>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-control-dynamic-cover">
|
||||
<div class="elementor-dynamic-cover__settings">
|
||||
<i class="eicon-{{ hasSettings ? 'wrench' : 'database' }}"></i>
|
||||
</div>
|
||||
<div class="elementor-dynamic-cover__title" title="{{{ title + ' ' + content }}}">{{{ title + ' ' + content }}}</div>
|
||||
<# if ( isRemovable ) { #>
|
||||
<div class="elementor-dynamic-cover__remove">
|
||||
<i class="eicon-close-circle"></i>
|
||||
</div>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-dynamic-tags-promo">
|
||||
<div class="elementor-tags-list__teaser">
|
||||
<div class="elementor-tags-list__group-title elementor-tags-list__teaser-title">
|
||||
<i class="eicon-info-circle"></i><?php echo __( 'Elementor Dynamic Content', 'elementor' ); ?>
|
||||
</div>
|
||||
<div class="elementor-tags-list__teaser-text">
|
||||
<?php echo __( 'You’re missing out!', 'elementor' ); ?><br />
|
||||
<?php echo __( 'Get more dynamic capabilities by incorporating dozens of Elementor\'s native dynamic tags.', 'elementor' ); ?>
|
||||
<a href="{{{ elementor.config.dynamicPromotionURL }}}" class="elementor-tags-list__teaser-link" target="_blank">
|
||||
<?php echo __( 'See it in action', 'elementor' ); ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-repeater-row">
|
||||
<div class="elementor-repeater-row-tools">
|
||||
<# if ( itemActions.drag_n_drop ) { #>
|
||||
<div class="elementor-repeater-row-handle-sortable">
|
||||
<i class="eicon-ellipsis-v" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Drag & Drop', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<# } #>
|
||||
<div class="elementor-repeater-row-item-title"></div>
|
||||
<# if ( itemActions.duplicate ) { #>
|
||||
<div class="elementor-repeater-row-tool elementor-repeater-tool-duplicate">
|
||||
<i class="eicon-copy" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Duplicate', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<# }
|
||||
if ( itemActions.remove ) { #>
|
||||
<div class="elementor-repeater-row-tool elementor-repeater-tool-remove">
|
||||
<i class="eicon-close" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Remove', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<# } #>
|
||||
</div>
|
||||
<div class="elementor-repeater-row-controls"></div>
|
||||
</script>
|
||||
@@ -0,0 +1,286 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
?>
|
||||
<script type="text/template" id="tmpl-elementor-template-library-header-actions">
|
||||
<div id="elementor-template-library-header-import" class="elementor-templates-modal__header__item">
|
||||
<i class="eicon-upload-circle-o" aria-hidden="true" title="<?php esc_attr_e( 'Import Template', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Import Template', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-template-library-header-sync" class="elementor-templates-modal__header__item">
|
||||
<i class="eicon-sync" aria-hidden="true" title="<?php esc_attr_e( 'Sync Library', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Sync Library', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div id="elementor-template-library-header-save" class="elementor-templates-modal__header__item">
|
||||
<i class="eicon-save-o" aria-hidden="true" title="<?php esc_attr_e( 'Save', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Save', 'elementor' ); ?></span>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-header-menu">
|
||||
<# jQuery.each( tabs, ( tab, args ) => { #>
|
||||
<div class="elementor-component-tab elementor-template-library-menu-item" data-tab="{{{ tab }}}">{{{ args.title }}}</div>
|
||||
<# } ); #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-header-preview">
|
||||
<div id="elementor-template-library-header-preview-insert-wrapper" class="elementor-templates-modal__header__item">
|
||||
{{{ elementor.templates.layout.getTemplateActionButton( obj ) }}}
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-header-back">
|
||||
<i class="eicon-" aria-hidden="true"></i>
|
||||
<span><?php echo __( 'Back to Library', 'elementor' ); ?></span>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-loading">
|
||||
<div class="elementor-loader-wrapper">
|
||||
<div class="elementor-loader">
|
||||
<div class="elementor-loader-boxes">
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
<div class="elementor-loader-box"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-loading-title"><?php echo __( 'Loading', 'elementor' ); ?></div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-templates">
|
||||
<#
|
||||
var activeSource = elementor.templates.getFilter('source');
|
||||
#>
|
||||
<div id="elementor-template-library-toolbar">
|
||||
<# if ( 'remote' === activeSource ) {
|
||||
var activeType = elementor.templates.getFilter('type');
|
||||
#>
|
||||
<div id="elementor-template-library-filter-toolbar-remote" class="elementor-template-library-filter-toolbar">
|
||||
<# if ( 'page' === activeType ) { #>
|
||||
<div id="elementor-template-library-order">
|
||||
<input type="radio" id="elementor-template-library-order-new" class="elementor-template-library-order-input" name="elementor-template-library-order" value="date">
|
||||
<label for="elementor-template-library-order-new" class="elementor-template-library-order-label"><?php echo __( 'New', 'elementor' ); ?></label>
|
||||
<input type="radio" id="elementor-template-library-order-trend" class="elementor-template-library-order-input" name="elementor-template-library-order" value="trendIndex">
|
||||
<label for="elementor-template-library-order-trend" class="elementor-template-library-order-label"><?php echo __( 'Trend', 'elementor' ); ?></label>
|
||||
<input type="radio" id="elementor-template-library-order-popular" class="elementor-template-library-order-input" name="elementor-template-library-order" value="popularityIndex">
|
||||
<label for="elementor-template-library-order-popular" class="elementor-template-library-order-label"><?php echo __( 'Popular', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<# } else {
|
||||
var config = elementor.templates.getConfig( activeType );
|
||||
if ( config.categories ) { #>
|
||||
<div id="elementor-template-library-filter">
|
||||
<select id="elementor-template-library-filter-subtype" class="elementor-template-library-filter-select" data-elementor-filter="subtype">
|
||||
<option></option>
|
||||
<# config.categories.forEach( function( category ) {
|
||||
var selected = category === elementor.templates.getFilter( 'subtype' ) ? ' selected' : '';
|
||||
#>
|
||||
<option value="{{ category }}"{{{ selected }}}>{{{ category }}}</option>
|
||||
<# } ); #>
|
||||
</select>
|
||||
</div>
|
||||
<# }
|
||||
} #>
|
||||
<div id="elementor-template-library-my-favorites">
|
||||
<# var checked = elementor.templates.getFilter( 'favorite' ) ? ' checked' : ''; #>
|
||||
<input id="elementor-template-library-filter-my-favorites" type="checkbox"{{{ checked }}}>
|
||||
<label id="elementor-template-library-filter-my-favorites-label" for="elementor-template-library-filter-my-favorites">
|
||||
<i class="eicon" aria-hidden="true"></i>
|
||||
<?php echo __( 'My Favorites', 'elementor' ); ?>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<# } else { #>
|
||||
<div id="elementor-template-library-filter-toolbar-local" class="elementor-template-library-filter-toolbar"></div>
|
||||
<# } #>
|
||||
<div id="elementor-template-library-filter-text-wrapper">
|
||||
<label for="elementor-template-library-filter-text" class="elementor-screen-only"><?php echo __( 'Search Templates:', 'elementor' ); ?></label>
|
||||
<input id="elementor-template-library-filter-text" placeholder="<?php echo esc_attr__( 'Search', 'elementor' ); ?>">
|
||||
<i class="eicon-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
<# if ( 'local' === activeSource ) { #>
|
||||
<div id="elementor-template-library-order-toolbar-local">
|
||||
<div class="elementor-template-library-local-column-1">
|
||||
<input type="radio" id="elementor-template-library-order-local-title" class="elementor-template-library-order-input" name="elementor-template-library-order-local" value="title" data-default-ordering-direction="asc">
|
||||
<label for="elementor-template-library-order-local-title" class="elementor-template-library-order-label"><?php echo __( 'Name', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-template-library-local-column-2">
|
||||
<input type="radio" id="elementor-template-library-order-local-type" class="elementor-template-library-order-input" name="elementor-template-library-order-local" value="type" data-default-ordering-direction="asc">
|
||||
<label for="elementor-template-library-order-local-type" class="elementor-template-library-order-label"><?php echo __( 'Type', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-template-library-local-column-3">
|
||||
<input type="radio" id="elementor-template-library-order-local-author" class="elementor-template-library-order-input" name="elementor-template-library-order-local" value="author" data-default-ordering-direction="asc">
|
||||
<label for="elementor-template-library-order-local-author" class="elementor-template-library-order-label"><?php echo __( 'Created By', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-template-library-local-column-4">
|
||||
<input type="radio" id="elementor-template-library-order-local-date" class="elementor-template-library-order-input" name="elementor-template-library-order-local" value="date">
|
||||
<label for="elementor-template-library-order-local-date" class="elementor-template-library-order-label"><?php echo __( 'Creation Date', 'elementor' ); ?></label>
|
||||
</div>
|
||||
<div class="elementor-template-library-local-column-5">
|
||||
<div class="elementor-template-library-order-label"><?php echo __( 'Actions', 'elementor' ); ?></div>
|
||||
</div>
|
||||
</div>
|
||||
<# } #>
|
||||
<div id="elementor-template-library-templates-container"></div>
|
||||
<# if ( 'remote' === activeSource ) { #>
|
||||
<div id="elementor-template-library-footer-banner">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/information.svg'; ?>" />
|
||||
<div class="elementor-excerpt"><?php echo __( 'Stay tuned! More awesome templates coming real soon.', 'elementor' ); ?></div>
|
||||
</div>
|
||||
<# } #>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-template-remote">
|
||||
<div class="elementor-template-library-template-body">
|
||||
<# if ( 'page' === type ) { #>
|
||||
<div class="elementor-template-library-template-screenshot" style="background-image: url({{ thumbnail }});"></div>
|
||||
<# } else { #>
|
||||
<img src="{{ thumbnail }}">
|
||||
<# } #>
|
||||
<div class="elementor-template-library-template-preview">
|
||||
<i class="eicon-zoom-in-bold" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="elementor-template-library-template-footer">
|
||||
{{{ elementor.templates.layout.getTemplateActionButton( obj ) }}}
|
||||
<div class="elementor-template-library-template-name">{{{ title }}} - {{{ type }}}</div>
|
||||
<div class="elementor-template-library-favorite">
|
||||
<input id="elementor-template-library-template-{{ template_id }}-favorite-input" class="elementor-template-library-template-favorite-input" type="checkbox"{{ favorite ? " checked" : "" }}>
|
||||
<label for="elementor-template-library-template-{{ template_id }}-favorite-input" class="elementor-template-library-template-favorite-label">
|
||||
<i class="eicon-heart-o" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Favorite', 'elementor' ); ?></span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-template-local">
|
||||
<div class="elementor-template-library-template-name elementor-template-library-local-column-1">{{{ title }}}</div>
|
||||
<div class="elementor-template-library-template-meta elementor-template-library-template-type elementor-template-library-local-column-2">{{{ elementor.translate( type ) }}}</div>
|
||||
<div class="elementor-template-library-template-meta elementor-template-library-template-author elementor-template-library-local-column-3">{{{ author }}}</div>
|
||||
<div class="elementor-template-library-template-meta elementor-template-library-template-date elementor-template-library-local-column-4">{{{ human_date }}}</div>
|
||||
<div class="elementor-template-library-template-controls elementor-template-library-local-column-5">
|
||||
<div class="elementor-template-library-template-preview">
|
||||
<i class="eicon-preview-medium" aria-hidden="true"></i>
|
||||
<span class="elementor-template-library-template-control-title"><?php echo __( 'Preview', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<button class="elementor-template-library-template-action elementor-template-library-template-insert elementor-button elementor-button-success">
|
||||
<i class="eicon-file-download" aria-hidden="true"></i>
|
||||
<span class="elementor-button-title"><?php echo __( 'Insert', 'elementor' ); ?></span>
|
||||
</button>
|
||||
<div class="elementor-template-library-template-more-toggle">
|
||||
<i class="eicon-ellipsis-h" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'More actions', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-template-library-template-more">
|
||||
<div class="elementor-template-library-template-delete">
|
||||
<i class="eicon-trash-o" aria-hidden="true"></i>
|
||||
<span class="elementor-template-library-template-control-title"><?php echo __( 'Delete', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-template-library-template-export">
|
||||
<a href="{{ export_link }}">
|
||||
<i class="eicon-sign-out" aria-hidden="true"></i>
|
||||
<span class="elementor-template-library-template-control-title"><?php echo __( 'Export', 'elementor' ); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-insert-button">
|
||||
<a class="elementor-template-library-template-action elementor-template-library-template-insert elementor-button">
|
||||
<i class="eicon-file-download" aria-hidden="true"></i>
|
||||
<span class="elementor-button-title"><?php echo __( 'Insert', 'elementor' ); ?></span>
|
||||
</a>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-get-pro-button">
|
||||
<a class="elementor-template-library-template-action elementor-button elementor-go-pro" href="<?php echo Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=panel-library&utm_campaign=gopro&utm_medium=wp-dash' ); ?>" target="_blank">
|
||||
<i class="eicon-external-link-square" aria-hidden="true"></i>
|
||||
<span class="elementor-button-title"><?php echo __( 'Go Pro', 'elementor' ); ?></span>
|
||||
</a>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-save-template">
|
||||
<div class="elementor-template-library-blank-icon">
|
||||
<i class="eicon-library-save" aria-hidden="true"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Save', 'elementor' ); ?></span>
|
||||
</div>
|
||||
<div class="elementor-template-library-blank-title">{{{ title }}}</div>
|
||||
<div class="elementor-template-library-blank-message">{{{ description }}}</div>
|
||||
<form id="elementor-template-library-save-template-form">
|
||||
<input type="hidden" name="post_id" value="<?php echo get_the_ID(); ?>">
|
||||
<input id="elementor-template-library-save-template-name" name="title" placeholder="<?php echo esc_attr__( 'Enter Template Name', 'elementor' ); ?>" required>
|
||||
<button id="elementor-template-library-save-template-submit" class="elementor-button elementor-button-success">
|
||||
<span class="elementor-state-icon">
|
||||
<i class="eicon-loading eicon-animation-spin" aria-hidden="true"></i>
|
||||
</span>
|
||||
<?php echo __( 'Save', 'elementor' ); ?>
|
||||
</button>
|
||||
</form>
|
||||
<div class="elementor-template-library-blank-footer">
|
||||
<?php echo __( 'Want to learn more about the Elementor library?', 'elementor' ); ?>
|
||||
<a class="elementor-template-library-blank-footer-link" href="https://go.elementor.com/docs-library/" target="_blank"><?php echo __( 'Click here', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-import">
|
||||
<form id="elementor-template-library-import-form">
|
||||
<div class="elementor-template-library-blank-icon">
|
||||
<i class="eicon-library-upload" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-template-library-blank-title"><?php echo __( 'Import Template to Your Library', 'elementor' ); ?></div>
|
||||
<div class="elementor-template-library-blank-message"><?php echo __( 'Drag & drop your .JSON or .zip template file', 'elementor' ); ?></div>
|
||||
<div id="elementor-template-library-import-form-or"><?php echo __( 'or', 'elementor' ); ?></div>
|
||||
<label for="elementor-template-library-import-form-input" id="elementor-template-library-import-form-label" class="elementor-button elementor-button-success"><?php echo __( 'Select File', 'elementor' ); ?></label>
|
||||
<input id="elementor-template-library-import-form-input" type="file" name="file" accept=".json,.zip" required/>
|
||||
<div class="elementor-template-library-blank-footer">
|
||||
<?php echo __( 'Want to learn more about the Elementor library?', 'elementor' ); ?>
|
||||
<a class="elementor-template-library-blank-footer-link" href="https://go.elementor.com/docs-library/" target="_blank"><?php echo __( 'Click here', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</form>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-templates-empty">
|
||||
<div class="elementor-template-library-blank-icon">
|
||||
<img src="<?php echo ELEMENTOR_ASSETS_URL . 'images/no-search-results.svg'; ?>" class="elementor-template-library-no-results" />
|
||||
</div>
|
||||
<div class="elementor-template-library-blank-title"></div>
|
||||
<div class="elementor-template-library-blank-message"></div>
|
||||
<div class="elementor-template-library-blank-footer">
|
||||
<?php echo __( 'Want to learn more about the Elementor library?', 'elementor' ); ?>
|
||||
<a class="elementor-template-library-blank-footer-link" href="https://go.elementor.com/docs-library/" target="_blank"><?php echo __( 'Click here', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-preview">
|
||||
<iframe></iframe>
|
||||
</script>
|
||||
|
||||
<script type="text/template" id="tmpl-elementor-template-library-connect">
|
||||
<div id="elementor-template-library-connect-logo" class="e-logo-wrapper">
|
||||
<i class="eicon-elementor" aria-hidden="true"></i>
|
||||
</div>
|
||||
<div class="elementor-template-library-blank-title">
|
||||
{{{ title }}}
|
||||
</div>
|
||||
<div class="elementor-template-library-blank-message">
|
||||
{{{ message }}}
|
||||
</div>
|
||||
<?php $url = Plugin::$instance->common->get_component( 'connect' )->get_app( 'library' )->get_admin_url( 'authorize' ); ?>
|
||||
<a id="elementor-template-library-connect__button" class="elementor-button elementor-button-success" href="<?php echo esc_attr( $url ); ?>">
|
||||
{{{ button }}}
|
||||
</a>
|
||||
<?php
|
||||
$base_images_url = $this->get_assets_base_url() . '/assets/images/library-connect/';
|
||||
|
||||
$images = [ 'left-1', 'left-2', 'right-1', 'right-2' ];
|
||||
|
||||
foreach ( $images as $image ) : ?>
|
||||
<img id="elementor-template-library-connect__background-image-<?php echo $image; ?>" class="elementor-template-library-connect__background-image" src="<?php echo $base_images_url . $image; ?>.png" draggable="false"/>
|
||||
<?php endforeach; ?>
|
||||
</script>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,149 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor repeater element.
|
||||
*
|
||||
* Elementor repeater handler class is responsible for initializing the repeater.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Repeater extends Element_Base {
|
||||
|
||||
/**
|
||||
* Repeater counter.
|
||||
*
|
||||
* Holds the Repeater counter data. Default is `0`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var int Repeater counter.
|
||||
*/
|
||||
private static $counter = 0;
|
||||
|
||||
/**
|
||||
* Repeater constructor.
|
||||
*
|
||||
* Initializing Elementor repeater element.
|
||||
*
|
||||
* @since 1.0.7
|
||||
* @access public
|
||||
*
|
||||
* @param array $data Optional. Element data. Default is an empty array.
|
||||
* @param array|null $args Optional. Element default arguments. Default is null.
|
||||
*
|
||||
*/
|
||||
public function __construct( array $data = [], array $args = null ) {
|
||||
self::$counter++;
|
||||
|
||||
parent::__construct( $data, $args );
|
||||
|
||||
$this->add_control(
|
||||
'_id',
|
||||
[
|
||||
'type' => Controls_Manager::HIDDEN,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater name.
|
||||
*
|
||||
* Retrieve the repeater name.
|
||||
*
|
||||
* @since 1.0.7
|
||||
* @access public
|
||||
*
|
||||
* @return string Repeater name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return 'repeater-' . self::$counter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater type.
|
||||
*
|
||||
* Retrieve the repeater type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Repeater type.
|
||||
*/
|
||||
public static function get_type() {
|
||||
return 'repeater';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add new repeater control to stack.
|
||||
*
|
||||
* Register a repeater control to allow the user to set/update data.
|
||||
*
|
||||
* This method should be used inside `_register_controls()`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Repeater control ID.
|
||||
* @param array $args Repeater control arguments.
|
||||
* @param array $options Optional. Repeater control options. Default is an
|
||||
* empty array.
|
||||
*
|
||||
* @return bool True if repeater control added, False otherwise.
|
||||
*/
|
||||
public function add_control( $id, array $args, $options = [] ) {
|
||||
$current_tab = $this->get_current_tab();
|
||||
|
||||
if ( null !== $current_tab ) {
|
||||
$args = array_merge( $args, $current_tab );
|
||||
}
|
||||
|
||||
return parent::add_control( $id, $args, $options );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get repeater fields.
|
||||
*
|
||||
* Retrieve the fields from the current repeater control.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @deprecated 2.1.0 Use `Repeater::get_controls()` instead.
|
||||
* @access public
|
||||
*
|
||||
* @return array Repeater fields.
|
||||
*/
|
||||
public function get_fields() {
|
||||
_deprecated_function( __METHOD__, '2.1.0', __CLASS__ . '::get_controls()' );
|
||||
|
||||
return array_values( $this->get_controls() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default child type.
|
||||
*
|
||||
* Retrieve the repeater child type based on element data.
|
||||
*
|
||||
* Note that repeater does not support children, therefore it returns false.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access protected
|
||||
*
|
||||
* @param array $element_data Element ID.
|
||||
*
|
||||
* @return false Repeater default child type or False if type not found.
|
||||
*/
|
||||
protected function _get_default_child_type( array $element_data ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected function handle_control_position( array $args, $control_id, $overwrite ) {
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,259 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor embed.
|
||||
*
|
||||
* Elementor embed handler class is responsible for Elementor embed functionality.
|
||||
* The class holds the supported providers with their embed patters, and handles
|
||||
* their custom properties to create custom HTML with the embeded content.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class Embed {
|
||||
|
||||
/**
|
||||
* Provider match masks.
|
||||
*
|
||||
* Holds a list of supported providers with their URL structure in a regex format.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Provider URL structure regex.
|
||||
*/
|
||||
private static $provider_match_masks = [
|
||||
'youtube' => '/^.*(?:youtu\.be\/|youtube(?:-nocookie)?\.com\/(?:(?:watch)?\?(?:.*&)?vi?=|(?:embed|v|vi|user)\/))([^\?&\"\'>]+)/',
|
||||
'vimeo' => '/^.*vimeo\.com\/(?:[a-z]*\/)*([0-9]{6,11})[?]?.*/',
|
||||
'dailymotion' => '/^.*dailymotion.com\/(?:video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/',
|
||||
];
|
||||
|
||||
/**
|
||||
* Embed patterns.
|
||||
*
|
||||
* Holds a list of supported providers with their embed patters.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array Embed patters.
|
||||
*/
|
||||
private static $embed_patterns = [
|
||||
'youtube' => 'https://www.youtube{NO_COOKIE}.com/embed/{VIDEO_ID}?feature=oembed',
|
||||
'vimeo' => 'https://player.vimeo.com/video/{VIDEO_ID}#t={TIME}',
|
||||
'dailymotion' => 'https://dailymotion.com/embed/video/{VIDEO_ID}',
|
||||
];
|
||||
|
||||
/**
|
||||
* Get video properties.
|
||||
*
|
||||
* Retrieve the video properties for a given video URL.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $video_url Video URL.
|
||||
*
|
||||
* @return null|array The video properties, or null.
|
||||
*/
|
||||
public static function get_video_properties( $video_url ) {
|
||||
foreach ( self::$provider_match_masks as $provider => $match_mask ) {
|
||||
preg_match( $match_mask, $video_url, $matches );
|
||||
|
||||
if ( $matches ) {
|
||||
return [
|
||||
'provider' => $provider,
|
||||
'video_id' => $matches[1],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embed URL.
|
||||
*
|
||||
* Retrieve the embed URL for a given video.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $video_url Video URL.
|
||||
* @param array $embed_url_params Optional. Embed parameters. Default is an
|
||||
* empty array.
|
||||
* @param array $options Optional. Embed options. Default is an
|
||||
* empty array.
|
||||
*
|
||||
* @return null|array The video properties, or null.
|
||||
*/
|
||||
public static function get_embed_url( $video_url, array $embed_url_params = [], array $options = [] ) {
|
||||
$video_properties = self::get_video_properties( $video_url );
|
||||
|
||||
if ( ! $video_properties ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$embed_pattern = self::$embed_patterns[ $video_properties['provider'] ];
|
||||
|
||||
$replacements = [
|
||||
'{VIDEO_ID}' => $video_properties['video_id'],
|
||||
];
|
||||
|
||||
if ( 'youtube' === $video_properties['provider'] ) {
|
||||
$replacements['{NO_COOKIE}'] = ! empty( $options['privacy'] ) ? '-nocookie' : '';
|
||||
} elseif ( 'vimeo' === $video_properties['provider'] ) {
|
||||
$time_text = '';
|
||||
|
||||
if ( ! empty( $options['start'] ) ) {
|
||||
$time_text = date( 'H\hi\ms\s', $options['start'] ); // PHPCS:Ignore WordPress.DateTime.RestrictedFunctions.date_date
|
||||
}
|
||||
|
||||
$replacements['{TIME}'] = $time_text;
|
||||
}
|
||||
|
||||
$embed_pattern = str_replace( array_keys( $replacements ), $replacements, $embed_pattern );
|
||||
|
||||
return add_query_arg( $embed_url_params, $embed_pattern );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get embed HTML.
|
||||
*
|
||||
* Retrieve the final HTML of the embedded URL.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $video_url Video URL.
|
||||
* @param array $embed_url_params Optional. Embed parameters. Default is an
|
||||
* empty array.
|
||||
* @param array $options Optional. Embed options. Default is an
|
||||
* empty array.
|
||||
* @param array $frame_attributes Optional. IFrame attributes. Default is an
|
||||
* empty array.
|
||||
*
|
||||
* @return string The embed HTML.
|
||||
*/
|
||||
public static function get_embed_html( $video_url, array $embed_url_params = [], array $options = [], array $frame_attributes = [] ) {
|
||||
$video_properties = self::get_video_properties( $video_url );
|
||||
|
||||
$default_frame_attributes = [
|
||||
'class' => 'elementor-video-iframe',
|
||||
'allowfullscreen',
|
||||
'title' => sprintf(
|
||||
/* translators: %s: Video provider */
|
||||
__( '%s Video Player', 'elementor' ),
|
||||
$video_properties['provider']
|
||||
),
|
||||
];
|
||||
|
||||
$video_embed_url = self::get_embed_url( $video_url, $embed_url_params, $options );
|
||||
if ( ! $video_embed_url ) {
|
||||
return null;
|
||||
}
|
||||
if ( ! $options['lazy_load'] ) {
|
||||
$default_frame_attributes['src'] = $video_embed_url;
|
||||
} else {
|
||||
$default_frame_attributes['data-lazy-load'] = $video_embed_url;
|
||||
}
|
||||
|
||||
$frame_attributes = array_merge( $default_frame_attributes, $frame_attributes );
|
||||
|
||||
$attributes_for_print = [];
|
||||
|
||||
foreach ( $frame_attributes as $attribute_key => $attribute_value ) {
|
||||
$attribute_value = esc_attr( $attribute_value );
|
||||
|
||||
if ( is_numeric( $attribute_key ) ) {
|
||||
$attributes_for_print[] = $attribute_value;
|
||||
} else {
|
||||
$attributes_for_print[] = sprintf( '%1$s="%2$s"', $attribute_key, $attribute_value );
|
||||
}
|
||||
}
|
||||
|
||||
$attributes_for_print = implode( ' ', $attributes_for_print );
|
||||
|
||||
$iframe_html = "<iframe $attributes_for_print></iframe>";
|
||||
|
||||
/** This filter is documented in wp-includes/class-oembed.php */
|
||||
return apply_filters( 'oembed_result', $iframe_html, $video_url, $frame_attributes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get oembed data from the cache.
|
||||
* if not exists in the cache it will fetch from provider and then save to the cache.
|
||||
*
|
||||
* @param $oembed_url
|
||||
* @param $cached_post_id
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function get_oembed_data( $oembed_url, $cached_post_id ) {
|
||||
$cached_oembed_data = json_decode( get_post_meta( $cached_post_id, '_elementor_oembed_cache', true ), true );
|
||||
|
||||
if ( isset( $cached_oembed_data[ $oembed_url ] ) ) {
|
||||
return $cached_oembed_data[ $oembed_url ];
|
||||
}
|
||||
|
||||
$normalize_oembed_data = self::fetch_oembed_data( $oembed_url );
|
||||
|
||||
if ( ! $cached_oembed_data ) {
|
||||
$cached_oembed_data = [];
|
||||
}
|
||||
|
||||
update_post_meta( $cached_post_id, '_elementor_oembed_cache', wp_json_encode( array_merge(
|
||||
$cached_oembed_data,
|
||||
[
|
||||
$oembed_url => $normalize_oembed_data,
|
||||
]
|
||||
) ) );
|
||||
|
||||
return $normalize_oembed_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch oembed data from oembed provider.
|
||||
*
|
||||
* @param $oembed_url
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public static function fetch_oembed_data( $oembed_url ) {
|
||||
$oembed_data = _wp_oembed_get_object()->get_data( $oembed_url );
|
||||
|
||||
if ( ! $oembed_data ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [
|
||||
'thumbnail_url' => $oembed_data->thumbnail_url,
|
||||
'title' => $oembed_data->title,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $oembed_url
|
||||
* @param null|string|int $cached_post_id
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function get_embed_thumbnail_html( $oembed_url, $cached_post_id = null ) {
|
||||
$oembed_data = self::get_oembed_data( $oembed_url, $cached_post_id );
|
||||
|
||||
if ( ! $oembed_data ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return '<div class="elementor-image">' . sprintf( '<img src="%1$s" alt="%2$s" title="%2$s" width="%3$s" />', $oembed_data['thumbnail_url'], esc_attr( $oembed_data['title'] ), '100%' ) . '</div>';
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor heartbeat.
|
||||
*
|
||||
* Elementor heartbeat handler class is responsible for initializing Elementor
|
||||
* heartbeat. The class communicates with WordPress Heartbeat API while working
|
||||
* with Elementor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Heartbeat {
|
||||
|
||||
/**
|
||||
* Heartbeat received.
|
||||
*
|
||||
* Locks the Heartbeat response received when editing with Elementor.
|
||||
*
|
||||
* Fired by `heartbeat_received` filter.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $response The Heartbeat response.
|
||||
* @param array $data The `$_POST` data sent.
|
||||
*
|
||||
* @return array Heartbeat response received.
|
||||
*/
|
||||
public function heartbeat_received( $response, $data ) {
|
||||
if ( isset( $data['elementor_post_lock']['post_ID'] ) ) {
|
||||
$post_id = $data['elementor_post_lock']['post_ID'];
|
||||
$locked_user = Plugin::$instance->editor->get_locked_user( $post_id );
|
||||
|
||||
if ( ! $locked_user || ! empty( $data['elementor_force_post_lock'] ) ) {
|
||||
Plugin::$instance->editor->lock_post( $post_id );
|
||||
} else {
|
||||
$response['locked_user'] = $locked_user->display_name;
|
||||
}
|
||||
|
||||
/** @var Core\Common\Modules\Ajax\Module $ajax */
|
||||
$ajax = Plugin::$instance->common->get_component( 'ajax' );
|
||||
|
||||
$response['elementorNonce'] = $ajax->create_nonce();
|
||||
}
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh nonces.
|
||||
*
|
||||
* Filter the nonces to send to the editor when editing with Elementor. Used
|
||||
* to refresh the nonce when the nonce expires while editing. This way the
|
||||
* user doesn't need to log-in again as Elementor fetches the new nonce from
|
||||
* the server using ajax.
|
||||
*
|
||||
* Fired by `wp_refresh_nonces` filter.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $response The no-priv Heartbeat response object or array.
|
||||
* @param array $data The `$_POST` data sent.
|
||||
*
|
||||
* @return array Refreshed nonces.
|
||||
*/
|
||||
public function refresh_nonces( $response, $data ) {
|
||||
if ( isset( $data['elementor_post_lock']['post_ID'] ) ) {
|
||||
/** @var Core\Common\Modules\Ajax\Module $ajax */
|
||||
$ajax = Plugin::$instance->common->get_component( 'ajax' );
|
||||
|
||||
$response['elementor-refresh-nonces'] = [
|
||||
'elementorNonce' => $ajax->create_nonce(),
|
||||
'heartbeatNonce' => wp_create_nonce( 'heartbeat-nonce' ),
|
||||
];
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Heartbeat constructor.
|
||||
*
|
||||
* Initializing Elementor heartbeat.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
add_filter( 'heartbeat_received', [ $this, 'heartbeat_received' ], 10, 2 );
|
||||
add_filter( 'wp_refresh_nonces', [ $this, 'refresh_nonces' ], 30, 2 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Group control interface.
|
||||
*
|
||||
* An interface for Elementor group control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
interface Group_Control_Interface {
|
||||
|
||||
/**
|
||||
* Get group control type.
|
||||
*
|
||||
* Retrieve the group control type.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function get_type();
|
||||
}
|
||||
@@ -0,0 +1,799 @@
|
||||
<?php
|
||||
/*
|
||||
* bfi_thumb - WP Image Resizer v1.3
|
||||
*
|
||||
* (c) 2013 Benjamin F. Intal / Gambit
|
||||
*
|
||||
* This program 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
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** Uses WP's Image Editor Class to resize and filter images
|
||||
*
|
||||
* @param $url string the local image URL to manipulate
|
||||
* @param $params array the options to perform on the image. Keys and values supported:
|
||||
* 'width' int pixels
|
||||
* 'height' int pixels
|
||||
* 'opacity' int 0-100
|
||||
* 'color' string hex-color #000000-#ffffff
|
||||
* 'grayscale' bool
|
||||
* 'negate' bool
|
||||
* 'crop' bool
|
||||
* 'crop_only' bool
|
||||
* 'crop_x' bool string
|
||||
* 'crop_y' bool string
|
||||
* 'crop_width' bool string
|
||||
* 'crop_height' bool string
|
||||
* 'quality' int 1-100
|
||||
* @param $single boolean, if false then an array of data will be returned
|
||||
*
|
||||
* @return string|array containing the url of the resized modified image
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly.
|
||||
|
||||
if ( ! defined( 'BFITHUMB_UPLOAD_DIR' ) ) {
|
||||
define( 'BFITHUMB_UPLOAD_DIR', 'elementor/thumbs' );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'bfi_thumb' ) ) {
|
||||
|
||||
function bfi_thumb( $url, $params = array(), $single = true ) {
|
||||
$class = BFI_Class_Factory::getNewestVersion( 'BFI_Thumb' );
|
||||
|
||||
return call_user_func( array( $class, 'thumb' ), $url, $params, $single );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Class factory, this is to make sure that when multiple bfi_thumb scripts
|
||||
* are used (e.g. a plugin and a theme both use it), we always use the
|
||||
* latest version.
|
||||
*/
|
||||
if ( ! class_exists( 'BFI_Class_Factory' ) ) {
|
||||
|
||||
class BFI_Class_Factory {
|
||||
|
||||
public static $versions = array();
|
||||
public static $latestClass = array();
|
||||
|
||||
public static function addClassVersion( $baseClassName, $className, $version ) {
|
||||
if ( empty( self::$versions[ $baseClassName ] ) ) {
|
||||
self::$versions[ $baseClassName ] = array();
|
||||
}
|
||||
self::$versions[ $baseClassName ][] = array(
|
||||
'class' => $className,
|
||||
'version' => $version,
|
||||
);
|
||||
}
|
||||
|
||||
public static function getNewestVersion( $baseClassName ) {
|
||||
if ( empty( self::$latestClass[ $baseClassName ] ) ) {
|
||||
usort( self::$versions[ $baseClassName ], array( __CLASS__, "versionCompare" ) );
|
||||
self::$latestClass[ $baseClassName ] = self::$versions[ $baseClassName ][0]['class'];
|
||||
unset( self::$versions[ $baseClassName ] );
|
||||
}
|
||||
|
||||
return self::$latestClass[ $baseClassName ];
|
||||
}
|
||||
|
||||
public static function versionCompare( $a, $b ) {
|
||||
return version_compare( $a['version'], $b['version'] ) == 1 ? -1 : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Change the default image editors
|
||||
*/
|
||||
add_filter( 'wp_image_editors', 'bfi_wp_image_editor' );
|
||||
|
||||
// Instead of using the default image editors, use our extended ones
|
||||
if ( ! function_exists( 'bfi_wp_image_editor' ) ) {
|
||||
|
||||
function bfi_wp_image_editor( $editorArray ) {
|
||||
// Make sure that we use the latest versions
|
||||
return array(
|
||||
BFI_Class_Factory::getNewestVersion( 'BFI_Image_Editor_GD' ),
|
||||
BFI_Class_Factory::getNewestVersion( 'BFI_Image_Editor_Imagick' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Include the WP Image classes
|
||||
*/
|
||||
|
||||
require_once ABSPATH . WPINC . '/class-wp-image-editor.php';
|
||||
require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
|
||||
require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
|
||||
|
||||
|
||||
/*
|
||||
* Enhanced Imagemagick Image Editor
|
||||
*/
|
||||
|
||||
|
||||
if ( ! class_exists( 'BFI_Image_Editor_Imagick_1_3' ) ) {
|
||||
|
||||
BFI_Class_Factory::addClassVersion( 'BFI_Image_Editor_Imagick', 'BFI_Image_Editor_Imagick_1_3', '1.3' );
|
||||
|
||||
class BFI_Image_Editor_Imagick_1_3 extends WP_Image_Editor_Imagick {
|
||||
|
||||
/** Changes the opacity of the image
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @param float $opacity (0.0-1.0)
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function opacity( $opacity ) {
|
||||
$opacity /= 100;
|
||||
|
||||
try {
|
||||
// From: http://stackoverflow.com/questions/3538851/php-imagick-setimageopacity-destroys-transparency-and-does-nothing
|
||||
// preserves transparency
|
||||
//$this->image->setImageOpacity($opacity);
|
||||
return $this->image->evaluateImage( Imagick::EVALUATE_MULTIPLY, $opacity, Imagick::CHANNEL_ALPHA );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'image_opacity_error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/** Tints the image a different color
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @param string hex color e.g. #ff00ff
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function colorize( $hexColor ) {
|
||||
try {
|
||||
return $this->image->colorizeImage( $hexColor, 1.0 );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'image_colorize_error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/** Makes the image grayscale
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function grayscale() {
|
||||
try {
|
||||
return $this->image->modulateImage( 100, 0, 100 );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'image_grayscale_error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/** Negates the image
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function negate() {
|
||||
try {
|
||||
return $this->image->negateImage( false );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 'image_negate_error', $e->getMessage() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enhanced GD Image Editor
|
||||
*/
|
||||
|
||||
|
||||
if ( ! class_exists( 'BFI_Image_Editor_GD_1_3' ) ) {
|
||||
|
||||
BFI_Class_Factory::addClassVersion( 'BFI_Image_Editor_GD', 'BFI_Image_Editor_GD_1_3', '1.3' );
|
||||
|
||||
class BFI_Image_Editor_GD_1_3 extends WP_Image_Editor_GD {
|
||||
|
||||
/** Rotates current image counter-clockwise by $angle.
|
||||
* Ported from image-edit.php
|
||||
* Added presevation of alpha channels
|
||||
*
|
||||
* @since 3.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param float $angle
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function rotate( $angle ) {
|
||||
if ( function_exists( 'imagerotate' ) ) {
|
||||
$rotated = imagerotate( $this->image, $angle, 0 );
|
||||
|
||||
// Add alpha blending
|
||||
imagealphablending( $rotated, true );
|
||||
imagesavealpha( $rotated, true );
|
||||
|
||||
if ( is_resource( $rotated ) ) {
|
||||
imagedestroy( $this->image );
|
||||
$this->image = $rotated;
|
||||
$this->update_size();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return new WP_Error( 'image_rotate_error', 'Image rotate failed.', $this->file );
|
||||
}
|
||||
|
||||
/** Changes the opacity of the image
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @param float $opacity (0.0-1.0)
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function opacity( $opacity ) {
|
||||
$opacity /= 100;
|
||||
|
||||
$filtered = $this->_opacity( $this->image, $opacity );
|
||||
|
||||
if ( is_resource( $filtered ) ) {
|
||||
// imagedestroy($this->image);
|
||||
$this->image = $filtered;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return new WP_Error( 'image_opacity_error', 'Image opacity change failed.', $this->file );
|
||||
}
|
||||
|
||||
|
||||
// from: http://php.net/manual/en/function.imagefilter.php
|
||||
// params: image resource id, opacity (eg. 0.0-1.0)
|
||||
protected function _opacity( $image, $opacity ) {
|
||||
if ( ! function_exists( 'imagealphablending' ) || ! function_exists( 'imagecolorat' ) || ! function_exists( 'imagecolorallocatealpha' ) || ! function_exists( 'imagesetpixel' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// get image width and height
|
||||
$w = imagesx( $image );
|
||||
$h = imagesy( $image );
|
||||
|
||||
// turn alpha blending off
|
||||
imagealphablending( $image, false );
|
||||
|
||||
// find the most opaque pixel in the image (the one with the smallest alpha value)
|
||||
$minalpha = 127;
|
||||
for ( $x = 0; $x < $w; $x++ ) {
|
||||
for ( $y = 0; $y < $h; $y++ ) {
|
||||
$alpha = ( imagecolorat( $image, $x, $y ) >> 24 ) & 0xFF;
|
||||
if ( $alpha < $minalpha ) {
|
||||
$minalpha = $alpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// loop through image pixels and modify alpha for each
|
||||
for ( $x = 0; $x < $w; $x++ ) {
|
||||
for ( $y = 0; $y < $h; $y++ ) {
|
||||
|
||||
// get current alpha value (represents the TANSPARENCY!)
|
||||
$colorxy = imagecolorat( $image, $x, $y );
|
||||
$alpha = ( $colorxy >> 24 ) & 0xFF;
|
||||
|
||||
// calculate new alpha
|
||||
if ( $minalpha !== 127 ) {
|
||||
$alpha = 127 + 127 * $opacity * ( $alpha - 127 ) / ( 127 - $minalpha );
|
||||
} else {
|
||||
$alpha += 127 * $opacity;
|
||||
}
|
||||
|
||||
// get the color index with new alpha
|
||||
$alphacolorxy = imagecolorallocatealpha( $image, ( $colorxy >> 16 ) & 0xFF, ( $colorxy >> 8 ) & 0xFF, $colorxy & 0xFF, $alpha );
|
||||
|
||||
// set pixel with the new color + opacity
|
||||
if ( ! imagesetpixel( $image, $x, $y, $alphacolorxy ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
imagesavealpha( $image, true );
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/** Tints the image a different color
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @param string hex color e.g. #ff00ff
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function colorize( $hexColor ) {
|
||||
if ( function_exists( 'imagefilter' ) && function_exists( 'imagesavealpha' ) && function_exists( 'imagealphablending' ) ) {
|
||||
|
||||
$hexColor = preg_replace( '#^\##', '', $hexColor );
|
||||
$r = hexdec( substr( $hexColor, 0, 2 ) );
|
||||
$g = hexdec( substr( $hexColor, 2, 2 ) );
|
||||
$b = hexdec( substr( $hexColor, 2, 2 ) );
|
||||
|
||||
imagealphablending( $this->image, false );
|
||||
if ( imagefilter( $this->image, IMG_FILTER_COLORIZE, $r, $g, $b, 0 ) ) {
|
||||
imagesavealpha( $this->image, true );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return new WP_Error( 'image_colorize_error', 'Image color change failed.', $this->file );
|
||||
}
|
||||
|
||||
/** Makes the image grayscale
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function grayscale() {
|
||||
if ( function_exists( 'imagefilter' ) ) {
|
||||
if ( imagefilter( $this->image, IMG_FILTER_GRAYSCALE ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return new WP_Error( 'image_grayscale_error', 'Image grayscale failed.', $this->file );
|
||||
}
|
||||
|
||||
/** Negates the image
|
||||
*
|
||||
* @supports 3.5.1
|
||||
* @access public
|
||||
*
|
||||
* @return boolean|WP_Error
|
||||
*/
|
||||
public function negate() {
|
||||
if ( function_exists( 'imagefilter' ) ) {
|
||||
if ( imagefilter( $this->image, IMG_FILTER_NEGATE ) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return new WP_Error( 'image_negate_error', 'Image negate failed.', $this->file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Main Class
|
||||
*/
|
||||
if ( ! class_exists( 'BFI_Thumb_1_3' ) ) {
|
||||
|
||||
BFI_Class_Factory::addClassVersion( 'BFI_Thumb', 'BFI_Thumb_1_3', '1.3' );
|
||||
|
||||
class BFI_Thumb_1_3 {
|
||||
|
||||
/** Uses WP's Image Editor Class to resize and filter images
|
||||
* Inspired by: https://github.com/sy4mil/Aqua-Resizer/blob/master/aq_resizer.php
|
||||
*
|
||||
* @param $url string the local image URL to manipulate
|
||||
* @param $params array the options to perform on the image. Keys and values supported:
|
||||
* 'width' int pixels
|
||||
* 'height' int pixels
|
||||
* 'opacity' int 0-100
|
||||
* 'color' string hex-color #000000-#ffffff
|
||||
* 'grayscale' bool
|
||||
* 'crop' bool
|
||||
* 'negate' bool
|
||||
* 'crop_only' bool
|
||||
* 'crop_x' bool string
|
||||
* 'crop_y' bool string
|
||||
* 'crop_width' bool string
|
||||
* 'crop_height' bool string
|
||||
* 'quality' int 1-100
|
||||
* @param $single boolean, if false then an array of data will be returned
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
public static function thumb( $url, $params = array(), $single = true ) {
|
||||
extract( $params );
|
||||
|
||||
//validate inputs
|
||||
if ( ! $url ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$crop_only = isset( $crop_only ) ? $crop_only : false;
|
||||
|
||||
//define upload path & dir
|
||||
$upload_info = wp_upload_dir();
|
||||
$upload_dir = $upload_info['basedir'];
|
||||
$upload_url = $upload_info['baseurl'];
|
||||
$theme_url = get_template_directory_uri();
|
||||
$theme_dir = get_template_directory();
|
||||
|
||||
// find the path of the image. Perform 2 checks:
|
||||
// #1 check if the image is in the uploads folder
|
||||
if ( strpos( $url, $upload_url ) !== false ) {
|
||||
$rel_path = str_replace( $upload_url, '', $url );
|
||||
$img_path = $upload_dir . $rel_path;
|
||||
// #2 check if the image is in the current theme folder
|
||||
} else if ( strpos( $url, $theme_url ) !== false ) {
|
||||
$rel_path = str_replace( $theme_url, '', $url );
|
||||
$img_path = $theme_dir . $rel_path;
|
||||
}
|
||||
|
||||
// Fail if we can't find the image in our WP local directory
|
||||
if ( empty( $img_path ) ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// check if img path exists, and is an image indeed
|
||||
if ( ! @file_exists( $img_path ) || ! getimagesize( $img_path ) ) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
// This is the filename
|
||||
$basename = basename( $img_path );
|
||||
|
||||
//get image info
|
||||
$info = pathinfo( $img_path );
|
||||
$ext = $info['extension'];
|
||||
list( $orig_w, $orig_h ) = getimagesize( $img_path );
|
||||
|
||||
// support percentage dimensions. compute percentage based on
|
||||
// the original dimensions
|
||||
if ( isset( $width ) ) {
|
||||
if ( stripos( $width, '%' ) !== false ) {
|
||||
$width = (int) ( (float) str_replace( '%', '', $width ) / 100 * $orig_w );
|
||||
}
|
||||
}
|
||||
if ( isset( $height ) ) {
|
||||
if ( stripos( $height, '%' ) !== false ) {
|
||||
$height = (int) ( (float) str_replace( '%', '', $height ) / 100 * $orig_h );
|
||||
}
|
||||
}
|
||||
|
||||
// The only purpose of this is to determine the final width and height
|
||||
// without performing any actual image manipulation, which will be used
|
||||
// to check whether a resize was previously done.
|
||||
if ( isset( $width ) && $crop_only === false ) {
|
||||
//get image size after cropping
|
||||
$dims = image_resize_dimensions( $orig_w, $orig_h, $width, isset( $height ) ? $height : null, isset( $crop ) ? $crop : false );
|
||||
$dst_w = isset( $dims[4] ) ? $dims[4] : null;
|
||||
$dst_h = isset( $dims[5] ) ? $dims[5] : null;
|
||||
} else if ( $crop_only === true ) {
|
||||
// we don't want a resize,
|
||||
// but only a crop in the image
|
||||
|
||||
// get x position to start croping
|
||||
$src_x = ( isset( $crop_x ) ) ? $crop_x : 0;
|
||||
|
||||
// get y position to start croping
|
||||
$src_y = ( isset( $crop_y ) ) ? $crop_y : 0;
|
||||
|
||||
// width of the crop
|
||||
if ( isset( $crop_width ) ) {
|
||||
$src_w = $crop_width;
|
||||
} else if ( isset( $width ) ) {
|
||||
$src_w = $width;
|
||||
} else {
|
||||
$src_w = $orig_w;
|
||||
}
|
||||
|
||||
// height of the crop
|
||||
if ( isset( $crop_height ) ) {
|
||||
$src_h = $crop_height;
|
||||
} else if ( isset( $height ) ) {
|
||||
$src_h = $height;
|
||||
} else {
|
||||
$src_h = $orig_h;
|
||||
}
|
||||
|
||||
// set the width resize with the crop
|
||||
if ( isset( $crop_width ) && isset( $width ) ) {
|
||||
$dst_w = $width;
|
||||
} else {
|
||||
$dst_w = null;
|
||||
}
|
||||
|
||||
// set the height resize with the crop
|
||||
if ( isset( $crop_height ) && isset( $height ) ) {
|
||||
$dst_h = $height;
|
||||
} else {
|
||||
$dst_h = null;
|
||||
}
|
||||
|
||||
// allow percentages
|
||||
if ( isset( $dst_w ) ) {
|
||||
if ( stripos( $dst_w, '%' ) !== false ) {
|
||||
$dst_w = (int) ( (float) str_replace( '%', '', $dst_w ) / 100 * $orig_w );
|
||||
}
|
||||
}
|
||||
if ( isset( $dst_h ) ) {
|
||||
if ( stripos( $dst_h, '%' ) !== false ) {
|
||||
$dst_h = (int) ( (float) str_replace( '%', '', $dst_h ) / 100 * $orig_h );
|
||||
}
|
||||
}
|
||||
|
||||
$dims = image_resize_dimensions( $src_w, $src_h, $dst_w, $dst_h, false );
|
||||
$dst_w = $dims[4];
|
||||
$dst_h = $dims[5];
|
||||
|
||||
// Make the pos x and pos y work with percentages
|
||||
if ( stripos( $src_x, '%' ) !== false ) {
|
||||
$src_x = (int) ( (float) str_replace( '%', '', $width ) / 100 * $orig_w );
|
||||
}
|
||||
if ( stripos( $src_y, '%' ) !== false ) {
|
||||
$src_y = (int) ( (float) str_replace( '%', '', $height ) / 100 * $orig_h );
|
||||
}
|
||||
|
||||
// allow center to position crop start
|
||||
if ( $src_x === 'center' ) {
|
||||
$src_x = ( $orig_w - $src_w ) / 2;
|
||||
}
|
||||
if ( $src_y === 'center' ) {
|
||||
$src_y = ( $orig_h - $src_h ) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
// create the suffix for the saved file
|
||||
// we can use this to check whether we need to create a new file or just use an existing one.
|
||||
$suffix = (string) filemtime( $img_path ) . ( isset( $width ) ? str_pad( (string) $width, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $height ) ? str_pad( (string) $height, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $opacity ) ? str_pad( (string) $opacity, 3, '0', STR_PAD_LEFT ) : '100' ) . ( isset( $color ) ? str_pad( preg_replace( '#^\##', '', $color ), 8, '0', STR_PAD_LEFT ) : '00000000' ) . ( isset( $grayscale ) ? ( $grayscale ? '1' : '0' ) : '0' ) . ( isset( $crop ) ? ( $crop ? '1' : '0' ) : '0' ) . ( isset( $negate ) ? ( $negate ? '1' : '0' ) : '0' ) . ( isset( $crop_only ) ? ( $crop_only ? '1' : '0' ) : '0' ) . ( isset( $src_x ) ? str_pad( (string) $src_x, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $src_y ) ? str_pad( (string) $src_y, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $src_w ) ? str_pad( (string) $src_w, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $src_h ) ? str_pad( (string) $src_h, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $dst_w ) ? str_pad( (string) $dst_w, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( isset( $dst_h ) ? str_pad( (string) $dst_h, 5, '0', STR_PAD_LEFT ) : '00000' ) . ( ( isset ( $quality ) && $quality > 0 && $quality <= 100 ) ? ( $quality ? (string) $quality : '0' ) : '0' );
|
||||
$suffix = self::base_convert_arbitrary( $suffix, 10, 36 );
|
||||
|
||||
// use this to check if cropped image already exists, so we can return that instead
|
||||
$dst_rel_path = str_replace( '.' . $ext, '', basename( $img_path ) );
|
||||
|
||||
// If opacity is set, change the image type to png
|
||||
if ( isset( $opacity ) ) {
|
||||
$ext = 'png';
|
||||
}
|
||||
|
||||
|
||||
// Create the upload subdirectory, this is where
|
||||
// we store all our generated images
|
||||
if ( defined( 'BFITHUMB_UPLOAD_DIR' ) ) {
|
||||
$upload_dir .= "/" . BFITHUMB_UPLOAD_DIR;
|
||||
$upload_url .= "/" . BFITHUMB_UPLOAD_DIR;
|
||||
} else {
|
||||
$upload_dir .= "/bfi_thumb";
|
||||
$upload_url .= "/bfi_thumb";
|
||||
}
|
||||
if ( ! is_dir( $upload_dir ) ) {
|
||||
wp_mkdir_p( $upload_dir );
|
||||
}
|
||||
|
||||
|
||||
// desination paths and urls
|
||||
$destfilename = "{$upload_dir}/{$dst_rel_path}-{$suffix}.{$ext}";
|
||||
|
||||
// The urls generated have lower case extensions regardless of the original case
|
||||
$ext = strtolower( $ext );
|
||||
$img_url = "{$upload_url}/{$dst_rel_path}-{$suffix}.{$ext}";
|
||||
|
||||
// if file exists, just return it
|
||||
if ( @file_exists( $destfilename ) && getimagesize( $destfilename ) ) {
|
||||
} else {
|
||||
// perform resizing and other filters
|
||||
$editor = wp_get_image_editor( $img_path );
|
||||
|
||||
if ( is_wp_error( $editor ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform image manipulations
|
||||
*/
|
||||
if ( $crop_only === false ) {
|
||||
if ( ( isset( $width ) && $width ) || ( isset( $height ) && $height ) ) {
|
||||
if ( is_wp_error( $editor->resize( isset( $width ) ? $width : null, isset( $height ) ? $height : null, isset( $crop ) ? $crop : false ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( is_wp_error( $editor->crop( $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $negate ) ) {
|
||||
if ( $negate ) {
|
||||
if ( is_wp_error( $editor->negate() ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $opacity ) ) {
|
||||
if ( is_wp_error( $editor->opacity( $opacity ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $grayscale ) ) {
|
||||
if ( $grayscale ) {
|
||||
if ( is_wp_error( $editor->grayscale() ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $color ) ) {
|
||||
if ( is_wp_error( $editor->colorize( $color ) ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set the image quality (1-100) to save this image at
|
||||
if ( isset( $quality ) && $quality > 0 && $quality <= 100 && $ext != 'png' ) {
|
||||
$editor->set_quality( $quality );
|
||||
}
|
||||
|
||||
// save our new image
|
||||
$mime_type = isset( $opacity ) ? 'image/png' : null;
|
||||
$resized_file = $editor->save( $destfilename, $mime_type );
|
||||
}
|
||||
|
||||
//return the output
|
||||
if ( $single ) {
|
||||
$image = $img_url;
|
||||
} else {
|
||||
//array return
|
||||
$image = array(
|
||||
0 => $img_url,
|
||||
1 => isset( $dst_w ) ? $dst_w : $orig_w,
|
||||
2 => isset( $dst_h ) ? $dst_h : $orig_h,
|
||||
);
|
||||
}
|
||||
|
||||
return $image;
|
||||
}
|
||||
|
||||
/** Shortens a number into a base 36 string
|
||||
*
|
||||
* @param $number string a string of numbers to convert
|
||||
* @param $fromBase starting base
|
||||
* @param $toBase base to convert the number to
|
||||
*
|
||||
* @return string base converted characters
|
||||
*/
|
||||
protected static function base_convert_arbitrary( $number, $fromBase, $toBase ) {
|
||||
$digits = '0123456789abcdefghijklmnopqrstuvwxyz';
|
||||
$length = strlen( $number );
|
||||
$result = '';
|
||||
|
||||
$nibbles = array();
|
||||
for ( $i = 0; $i < $length; ++$i ) {
|
||||
$nibbles[ $i ] = strpos( $digits, $number[ $i ] );
|
||||
}
|
||||
|
||||
do {
|
||||
$value = 0;
|
||||
$newlen = 0;
|
||||
|
||||
for ( $i = 0; $i < $length; ++$i ) {
|
||||
|
||||
$value = $value * $fromBase + $nibbles[ $i ];
|
||||
|
||||
if ( $value >= $toBase ) {
|
||||
$nibbles[ $newlen++ ] = (int) ( $value / $toBase );
|
||||
$value %= $toBase;
|
||||
} else if ( $newlen > 0 ) {
|
||||
$nibbles[ $newlen++ ] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
$length = $newlen;
|
||||
$result = $digits[ $value ] . $result;
|
||||
} while ( $newlen != 0 );
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// don't use the default resizer since we want to allow resizing to larger sizes (than the original one)
|
||||
// Parts are copied from media.php
|
||||
// Crop is always applied (just like timthumb)
|
||||
// Don't use this inside the admin since sometimes images in the media library get resized
|
||||
if ( ! is_admin() ) {
|
||||
add_filter( 'image_resize_dimensions', 'bfi_image_resize_dimensions', 10, 5 );
|
||||
}
|
||||
|
||||
if ( ! function_exists( 'bfi_image_resize_dimensions' ) ) {
|
||||
function bfi_image_resize_dimensions( $payload, $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {
|
||||
$aspect_ratio = $orig_w / $orig_h;
|
||||
|
||||
$new_w = $dest_w;
|
||||
$new_h = $dest_h;
|
||||
|
||||
if ( empty( $new_w ) || $new_w < 0 ) {
|
||||
$new_w = intval( $new_h * $aspect_ratio );
|
||||
}
|
||||
|
||||
if ( empty( $new_h ) || $new_h < 0 ) {
|
||||
$new_h = intval( $new_w / $aspect_ratio );
|
||||
}
|
||||
|
||||
$size_ratio = max( $new_w / $orig_w, $new_h / $orig_h );
|
||||
|
||||
$crop_w = round( $new_w / $size_ratio );
|
||||
$crop_h = round( $new_h / $size_ratio );
|
||||
$s_x = floor( ( $orig_w - $crop_w ) / 2 );
|
||||
$s_y = floor( ( $orig_h - $crop_h ) / 2 );
|
||||
|
||||
// Safe guard against super large or zero images which might cause 500 errors
|
||||
if ( $new_w > 5000 || $new_h > 5000 || $new_w <= 0 || $new_h <= 0 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// the return array matches the parameters to imagecopyresampled()
|
||||
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
|
||||
return array( 0, 0, (int) $s_x, (int) $s_y, (int) $new_w, (int) $new_h, (int) $crop_w, (int) $crop_h );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This function allows us to latch on WP image functions such as
|
||||
// the_post_thumbnail, get_image_tag and wp_get_attachment_image_src
|
||||
// so that you won't have to use the function bfi_thumb in order to do resizing.
|
||||
// To make this work, in the WP image functions, when specifying an
|
||||
// array for the image dimensions, add a 'bfi_thumb' => true to
|
||||
// the array, then add your normal $params arguments.
|
||||
//
|
||||
// e.g. the_post_thumbnail( array( 1024, 400, 'bfi_thumb' => true, 'grayscale' => true ) );
|
||||
add_filter( 'image_downsize', 'bfi_image_downsize', 1, 3 );
|
||||
|
||||
if ( ! function_exists( 'bfi_image_downsize' ) ) {
|
||||
function bfi_image_downsize( $out, $id, $size ) {
|
||||
if ( ! is_array( $size ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( ! array_key_exists( 'bfi_thumb', $size ) ) {
|
||||
return false;
|
||||
}
|
||||
if ( empty( $size['bfi_thumb'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$img_url = wp_get_attachment_url( $id );
|
||||
|
||||
$params = $size;
|
||||
$params['width'] = $size[0];
|
||||
$params['height'] = $size[1];
|
||||
|
||||
$resized_img_url = bfi_thumb( $img_url, $params );
|
||||
|
||||
return array( $resized_img_url, $size[0], $size[1], false );
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// TODO: _deprecated_file( __FILE__, '3.0.7', '\Elementor\Core\Base\BackgroundProcess\WP_Async_Request' );
|
||||
|
||||
if ( ! class_exists( 'WP_Async_Request' ) ) {
|
||||
abstract class WP_Async_Request extends \Elementor\Core\Base\BackgroundProcess\WP_Async_Request {
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
// TODO: _deprecated_file( __FILE__, '3.0.7', '\Elementor\Core\Base\BackgroundProcess\WP_Background_Process' );
|
||||
|
||||
if ( ! class_exists( 'WP_Background_Process' ) ) {
|
||||
abstract class WP_Background_Process extends \Elementor\Core\Base\BackgroundProcess\WP_Background_Process {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\TemplateLibrary\Source_Local;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor maintenance mode.
|
||||
*
|
||||
* Elementor maintenance mode handler class is responsible for the Elementor
|
||||
* "Maintenance Mode" and the "Coming Soon" features.
|
||||
*
|
||||
* @since 1.4.0
|
||||
*/
|
||||
class Maintenance_Mode {
|
||||
|
||||
/**
|
||||
* The options prefix.
|
||||
*/
|
||||
const OPTION_PREFIX = 'elementor_maintenance_mode_';
|
||||
|
||||
/**
|
||||
* The maintenance mode.
|
||||
*/
|
||||
const MODE_MAINTENANCE = 'maintenance';
|
||||
|
||||
/**
|
||||
* The coming soon mode.
|
||||
*/
|
||||
const MODE_COMING_SOON = 'coming_soon';
|
||||
|
||||
/**
|
||||
* Get elementor option.
|
||||
*
|
||||
* Retrieve elementor option from the database.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $option Option name. Expected to not be SQL-escaped.
|
||||
* @param mixed $default Optional. Default value to return if the option
|
||||
* does not exist. Default is false.
|
||||
*
|
||||
* @return bool False if value was not updated and true if value was updated.
|
||||
*/
|
||||
public static function get( $option, $default = false ) {
|
||||
return get_option( self::OPTION_PREFIX . $option, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set elementor option.
|
||||
*
|
||||
* Update elementor option in the database.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $option Option name. Expected to not be SQL-escaped.
|
||||
* @param mixed $value Option value. Must be serializable if non-scalar.
|
||||
* Expected to not be SQL-escaped.
|
||||
*
|
||||
* @return bool False if value was not updated and true if value was updated.
|
||||
*/
|
||||
public static function set( $option, $value ) {
|
||||
return update_option( self::OPTION_PREFIX . $option, $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* Body class.
|
||||
*
|
||||
* Add "Maintenance Mode" CSS classes to the body tag.
|
||||
*
|
||||
* Fired by `body_class` filter.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $classes An array of body classes.
|
||||
*
|
||||
* @return array An array of body classes.
|
||||
*/
|
||||
public function body_class( $classes ) {
|
||||
$classes[] = 'elementor-maintenance-mode';
|
||||
|
||||
return $classes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Template redirect.
|
||||
*
|
||||
* Redirect to the "Maintenance Mode" template.
|
||||
*
|
||||
* Fired by `template_redirect` action.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*/
|
||||
public function template_redirect() {
|
||||
if ( Plugin::$instance->preview->is_preview_mode() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$user = wp_get_current_user();
|
||||
|
||||
$exclude_mode = self::get( 'exclude_mode', [] );
|
||||
|
||||
$is_login_page = apply_filters( 'elementor/maintenance_mode/is_login_page', false );
|
||||
|
||||
if ( $is_login_page ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'logged_in' === $exclude_mode && is_user_logged_in() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'custom' === $exclude_mode ) {
|
||||
$exclude_roles = self::get( 'exclude_roles', [] );
|
||||
$user_roles = $user->roles;
|
||||
|
||||
if ( is_multisite() && is_super_admin() ) {
|
||||
$user_roles[] = 'super_admin';
|
||||
}
|
||||
|
||||
$compare_roles = array_intersect( $user_roles, $exclude_roles );
|
||||
|
||||
if ( ! empty( $compare_roles ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
add_filter( 'body_class', [ $this, 'body_class' ] );
|
||||
|
||||
if ( 'maintenance' === self::get( 'mode' ) ) {
|
||||
$protocol = wp_get_server_protocol();
|
||||
header( "$protocol 503 Service Unavailable", true, 503 );
|
||||
header( 'Content-Type: text/html; charset=utf-8' );
|
||||
header( 'Retry-After: 600' );
|
||||
}
|
||||
|
||||
// Setup global post for Elementor\frontend so `_has_elementor_in_page = true`.
|
||||
$GLOBALS['post'] = get_post( self::get( 'template_id' ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
// Set the template as `$wp_query->current_object` for `wp_title` and etc.
|
||||
query_posts( [
|
||||
'p' => self::get( 'template_id' ),
|
||||
'post_type' => Source_Local::CPT,
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings fields.
|
||||
*
|
||||
* Adds new "Maintenance Mode" settings fields to Elementor admin page.
|
||||
*
|
||||
* The method need to receive the an instance of the Tools settings page
|
||||
* to add the new maintenance mode functionality.
|
||||
*
|
||||
* Fired by `elementor/admin/after_create_settings/{$page_id}` action.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param Tools $tools An instance of the Tools settings page.
|
||||
*/
|
||||
public function register_settings_fields( Tools $tools ) {
|
||||
$templates = Plugin::$instance->templates_manager->get_source( 'local' )->get_items( [
|
||||
'type' => 'page',
|
||||
] );
|
||||
|
||||
$templates_options = [];
|
||||
|
||||
foreach ( $templates as $template ) {
|
||||
$templates_options[ $template['template_id'] ] = esc_html( $template['title'] );
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
$this->print_template_description();
|
||||
|
||||
$template_description = ob_get_clean();
|
||||
|
||||
$tools->add_tab(
|
||||
'maintenance_mode', [
|
||||
'label' => __( 'Maintenance Mode', 'elementor' ),
|
||||
'sections' => [
|
||||
'maintenance_mode' => [
|
||||
'callback' => function() {
|
||||
echo '<h2>' . esc_html__( 'Maintenance Mode', 'elementor' ) . '</h2>';
|
||||
echo '<div>' . __( 'Set your entire website as MAINTENANCE MODE, meaning the site is offline temporarily for maintenance, or set it as COMING SOON mode, meaning the site is offline until it is ready to be launched.', 'elementor' ) . '</div>';
|
||||
},
|
||||
'fields' => [
|
||||
'maintenance_mode_mode' => [
|
||||
'label' => __( 'Choose Mode', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'' => __( 'Disabled', 'elementor' ),
|
||||
self::MODE_COMING_SOON => __( 'Coming Soon', 'elementor' ),
|
||||
self::MODE_MAINTENANCE => __( 'Maintenance', 'elementor' ),
|
||||
],
|
||||
'desc' => '<div class="elementor-maintenance-mode-description" data-value="" style="display: none">' .
|
||||
__( 'Choose between Coming Soon mode (returning HTTP 200 code) or Maintenance Mode (returning HTTP 503 code).', 'elementor' ) .
|
||||
'</div>' .
|
||||
'<div class="elementor-maintenance-mode-description" data-value="maintenance" style="display: none">' .
|
||||
__( 'Maintenance Mode returns HTTP 503 code, so search engines know to come back a short time later. It is not recommended to use this mode for more than a couple of days.', 'elementor' ) .
|
||||
'</div>' .
|
||||
'<div class="elementor-maintenance-mode-description" data-value="coming_soon" style="display: none">' .
|
||||
__( 'Coming Soon returns HTTP 200 code, meaning the site is ready to be indexed.', 'elementor' ) .
|
||||
'</div>',
|
||||
],
|
||||
],
|
||||
'maintenance_mode_exclude_mode' => [
|
||||
'label' => __( 'Who Can Access', 'elementor' ),
|
||||
'field_args' => [
|
||||
'class' => 'elementor-default-hide',
|
||||
'type' => 'select',
|
||||
'std' => 'logged_in',
|
||||
'options' => [
|
||||
'logged_in' => __( 'Logged In', 'elementor' ),
|
||||
'custom' => __( 'Custom', 'elementor' ),
|
||||
],
|
||||
],
|
||||
],
|
||||
'maintenance_mode_exclude_roles' => [
|
||||
'label' => __( 'Roles', 'elementor' ),
|
||||
'field_args' => [
|
||||
'class' => 'elementor-default-hide',
|
||||
'type' => 'checkbox_list_roles',
|
||||
],
|
||||
'setting_args' => [ __NAMESPACE__ . '\Settings_Validations', 'checkbox_list' ],
|
||||
],
|
||||
'maintenance_mode_template_id' => [
|
||||
'label' => __( 'Choose Template', 'elementor' ),
|
||||
'field_args' => [
|
||||
'class' => 'elementor-default-hide',
|
||||
'type' => 'select',
|
||||
'show_select' => true,
|
||||
'options' => $templates_options,
|
||||
'desc' => $template_description,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add menu in admin bar.
|
||||
*
|
||||
* Adds "Maintenance Mode" items to the WordPress admin bar.
|
||||
*
|
||||
* Fired by `admin_bar_menu` filter.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*
|
||||
* @param \WP_Admin_Bar $wp_admin_bar WP_Admin_Bar instance, passed by reference.
|
||||
*/
|
||||
public function add_menu_in_admin_bar( \WP_Admin_Bar $wp_admin_bar ) {
|
||||
$wp_admin_bar->add_node( [
|
||||
'id' => 'elementor-maintenance-on',
|
||||
'title' => __( 'Maintenance Mode ON', 'elementor' ),
|
||||
'href' => Tools::get_url() . '#tab-maintenance_mode',
|
||||
] );
|
||||
|
||||
$document = Plugin::$instance->documents->get( self::get( 'template_id' ) );
|
||||
|
||||
$wp_admin_bar->add_node( [
|
||||
'id' => 'elementor-maintenance-edit',
|
||||
'parent' => 'elementor-maintenance-on',
|
||||
'title' => __( 'Edit Template', 'elementor' ),
|
||||
'href' => $document ? $document->get_edit_url() : '',
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print style.
|
||||
*
|
||||
* Adds custom CSS to the HEAD html tag. The CSS that emphasise the maintenance
|
||||
* mode with red colors.
|
||||
*
|
||||
* Fired by `admin_head` and `wp_head` filters.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*/
|
||||
public function print_style() {
|
||||
?>
|
||||
<style>#wp-admin-bar-elementor-maintenance-on > a { background-color: #dc3232; }
|
||||
#wp-admin-bar-elementor-maintenance-on > .ab-item:before { content: "\f160"; top: 2px; }</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
public function on_update_mode( $old_value, $value ) {
|
||||
if ( $old_value !== $value ) {
|
||||
do_action( 'elementor/maintenance_mode/mode_changed', $old_value, $value );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maintenance mode constructor.
|
||||
*
|
||||
* Initializing Elementor maintenance mode.
|
||||
*
|
||||
* @since 1.4.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'update_option_elementor_maintenance_mode_mode', [ $this, 'on_update_mode' ], 10, 2 );
|
||||
|
||||
$is_enabled = (bool) self::get( 'mode' ) && (bool) self::get( 'template_id' );
|
||||
|
||||
if ( is_admin() ) {
|
||||
$page_id = Tools::PAGE_ID;
|
||||
add_action( "elementor/admin/after_create_settings/{$page_id}", [ $this, 'register_settings_fields' ] );
|
||||
}
|
||||
|
||||
if ( ! $is_enabled ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'admin_bar_menu', [ $this, 'add_menu_in_admin_bar' ], 300 );
|
||||
add_action( 'admin_head', [ $this, 'print_style' ] );
|
||||
add_action( 'wp_head', [ $this, 'print_style' ] );
|
||||
|
||||
// Priority = 11 that is *after* WP default filter `redirect_canonical` in order to avoid redirection loop.
|
||||
add_action( 'template_redirect', [ $this, 'template_redirect' ], 11 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Print Template Description
|
||||
*
|
||||
* Prints the template description
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function print_template_description() {
|
||||
$template_id = self::get( 'template_id' );
|
||||
|
||||
$edit_url = '';
|
||||
|
||||
if ( $template_id && get_post( $template_id ) ) {
|
||||
$edit_url = Plugin::$instance->documents->get( $template_id )->get_edit_url();
|
||||
}
|
||||
|
||||
?>
|
||||
<a target="_blank" class="elementor-edit-template" style="display: none" href="<?php echo $edit_url; ?>"><?php echo __( 'Edit Template', 'elementor' ); ?></a>
|
||||
<div class="elementor-maintenance-mode-error"><?php echo __( 'To enable maintenance mode you have to set a template for the maintenance mode page.', 'elementor' ); ?></div>
|
||||
<div class="elementor-maintenance-mode-error"><?php echo sprintf( __( 'Select one or go ahead and <a target="_blank" href="%s">create one</a> now.', 'elementor' ), admin_url( 'post-new.php?post_type=' . Source_Local::CPT ) ); ?></div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor maintenance.
|
||||
*
|
||||
* Elementor maintenance handler class is responsible for setting up Elementor
|
||||
* activation and uninstallation hooks.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Maintenance {
|
||||
|
||||
/**
|
||||
* Activate Elementor.
|
||||
*
|
||||
* Set Elementor activation hook.
|
||||
*
|
||||
* Fired by `register_activation_hook` when the plugin is activated.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function activation( $network_wide ) {
|
||||
wp_clear_scheduled_hook( 'elementor/tracker/send_event' );
|
||||
|
||||
wp_schedule_event( time(), 'daily', 'elementor/tracker/send_event' );
|
||||
flush_rewrite_rules();
|
||||
|
||||
if ( is_multisite() && $network_wide ) {
|
||||
return;
|
||||
}
|
||||
|
||||
set_transient( 'elementor_activation_redirect', true, MINUTE_IN_SECONDS );
|
||||
}
|
||||
|
||||
/**
|
||||
* Uninstall Elementor.
|
||||
*
|
||||
* Set Elementor uninstallation hook.
|
||||
*
|
||||
* Fired by `register_uninstall_hook` when the plugin is uninstalled.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function uninstall() {
|
||||
wp_clear_scheduled_hook( 'elementor/tracker/send_event' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor Maintenance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
public static function init() {
|
||||
register_activation_hook( ELEMENTOR_PLUGIN_BASE, [ __CLASS__, 'activation' ] );
|
||||
register_uninstall_hook( ELEMENTOR_PLUGIN_BASE, [ __CLASS__, 'uninstall' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,976 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor controls manager.
|
||||
*
|
||||
* Elementor controls manager handler class is responsible for registering and
|
||||
* initializing all the supported controls, both regular controls and the group
|
||||
* controls.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Controls_Manager {
|
||||
|
||||
/**
|
||||
* Content tab.
|
||||
*/
|
||||
const TAB_CONTENT = 'content';
|
||||
|
||||
/**
|
||||
* Style tab.
|
||||
*/
|
||||
const TAB_STYLE = 'style';
|
||||
|
||||
/**
|
||||
* Advanced tab.
|
||||
*/
|
||||
const TAB_ADVANCED = 'advanced';
|
||||
|
||||
/**
|
||||
* Responsive tab.
|
||||
*/
|
||||
const TAB_RESPONSIVE = 'responsive';
|
||||
|
||||
/**
|
||||
* Layout tab.
|
||||
*/
|
||||
const TAB_LAYOUT = 'layout';
|
||||
|
||||
/**
|
||||
* Settings tab.
|
||||
*/
|
||||
const TAB_SETTINGS = 'settings';
|
||||
|
||||
/**
|
||||
* Text control.
|
||||
*/
|
||||
const TEXT = 'text';
|
||||
|
||||
/**
|
||||
* Number control.
|
||||
*/
|
||||
const NUMBER = 'number';
|
||||
|
||||
/**
|
||||
* Textarea control.
|
||||
*/
|
||||
const TEXTAREA = 'textarea';
|
||||
|
||||
/**
|
||||
* Select control.
|
||||
*/
|
||||
const SELECT = 'select';
|
||||
|
||||
/**
|
||||
* Switcher control.
|
||||
*/
|
||||
const SWITCHER = 'switcher';
|
||||
|
||||
/**
|
||||
* Button control.
|
||||
*/
|
||||
const BUTTON = 'button';
|
||||
|
||||
/**
|
||||
* Hidden control.
|
||||
*/
|
||||
const HIDDEN = 'hidden';
|
||||
|
||||
/**
|
||||
* Heading control.
|
||||
*/
|
||||
const HEADING = 'heading';
|
||||
|
||||
/**
|
||||
* Raw HTML control.
|
||||
*/
|
||||
const RAW_HTML = 'raw_html';
|
||||
|
||||
/**
|
||||
* Deprecated Notice control.
|
||||
*/
|
||||
const DEPRECATED_NOTICE = 'deprecated_notice';
|
||||
|
||||
/**
|
||||
* Popover Toggle control.
|
||||
*/
|
||||
const POPOVER_TOGGLE = 'popover_toggle';
|
||||
|
||||
/**
|
||||
* Section control.
|
||||
*/
|
||||
const SECTION = 'section';
|
||||
|
||||
/**
|
||||
* Tab control.
|
||||
*/
|
||||
const TAB = 'tab';
|
||||
|
||||
/**
|
||||
* Tabs control.
|
||||
*/
|
||||
const TABS = 'tabs';
|
||||
|
||||
/**
|
||||
* Divider control.
|
||||
*/
|
||||
const DIVIDER = 'divider';
|
||||
|
||||
/**
|
||||
* Color control.
|
||||
*/
|
||||
const COLOR = 'color';
|
||||
|
||||
/**
|
||||
* Media control.
|
||||
*/
|
||||
const MEDIA = 'media';
|
||||
|
||||
/**
|
||||
* Slider control.
|
||||
*/
|
||||
const SLIDER = 'slider';
|
||||
|
||||
/**
|
||||
* Dimensions control.
|
||||
*/
|
||||
const DIMENSIONS = 'dimensions';
|
||||
|
||||
/**
|
||||
* Choose control.
|
||||
*/
|
||||
const CHOOSE = 'choose';
|
||||
|
||||
/**
|
||||
* WYSIWYG control.
|
||||
*/
|
||||
const WYSIWYG = 'wysiwyg';
|
||||
|
||||
/**
|
||||
* Code control.
|
||||
*/
|
||||
const CODE = 'code';
|
||||
|
||||
/**
|
||||
* Font control.
|
||||
*/
|
||||
const FONT = 'font';
|
||||
|
||||
/**
|
||||
* Image dimensions control.
|
||||
*/
|
||||
const IMAGE_DIMENSIONS = 'image_dimensions';
|
||||
|
||||
/**
|
||||
* WordPress widget control.
|
||||
*/
|
||||
const WP_WIDGET = 'wp_widget';
|
||||
|
||||
/**
|
||||
* URL control.
|
||||
*/
|
||||
const URL = 'url';
|
||||
|
||||
/**
|
||||
* Repeater control.
|
||||
*/
|
||||
const REPEATER = 'repeater';
|
||||
|
||||
/**
|
||||
* Icon control.
|
||||
*/
|
||||
const ICON = 'icon';
|
||||
|
||||
/**
|
||||
* Icons control.
|
||||
*/
|
||||
const ICONS = 'icons';
|
||||
|
||||
/**
|
||||
* Gallery control.
|
||||
*/
|
||||
const GALLERY = 'gallery';
|
||||
|
||||
/**
|
||||
* Structure control.
|
||||
*/
|
||||
const STRUCTURE = 'structure';
|
||||
|
||||
/**
|
||||
* Select2 control.
|
||||
*/
|
||||
const SELECT2 = 'select2';
|
||||
|
||||
/**
|
||||
* Date/Time control.
|
||||
*/
|
||||
const DATE_TIME = 'date_time';
|
||||
|
||||
/**
|
||||
* Box shadow control.
|
||||
*/
|
||||
const BOX_SHADOW = 'box_shadow';
|
||||
|
||||
/**
|
||||
* Text shadow control.
|
||||
*/
|
||||
const TEXT_SHADOW = 'text_shadow';
|
||||
|
||||
/**
|
||||
* Entrance animation control.
|
||||
*/
|
||||
const ANIMATION = 'animation';
|
||||
|
||||
/**
|
||||
* Hover animation control.
|
||||
*/
|
||||
const HOVER_ANIMATION = 'hover_animation';
|
||||
|
||||
/**
|
||||
* Exit animation control.
|
||||
*/
|
||||
const EXIT_ANIMATION = 'exit_animation';
|
||||
|
||||
/**
|
||||
* Controls.
|
||||
*
|
||||
* Holds the list of all the controls. Default is `null`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var Base_Control[]
|
||||
*/
|
||||
private $controls = null;
|
||||
|
||||
/**
|
||||
* Control groups.
|
||||
*
|
||||
* Holds the list of all the control groups. Default is an empty array.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var Group_Control_Base[]
|
||||
*/
|
||||
private $control_groups = [];
|
||||
|
||||
/**
|
||||
* Control stacks.
|
||||
*
|
||||
* Holds the list of all the control stacks. Default is an empty array.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $stacks = [];
|
||||
|
||||
/**
|
||||
* Tabs.
|
||||
*
|
||||
* Holds the list of all the tabs.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $tabs;
|
||||
|
||||
/**
|
||||
* Init tabs.
|
||||
*
|
||||
* Initialize control tabs.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
private static function init_tabs() {
|
||||
self::$tabs = [
|
||||
self::TAB_CONTENT => __( 'Content', 'elementor' ),
|
||||
self::TAB_STYLE => __( 'Style', 'elementor' ),
|
||||
self::TAB_ADVANCED => __( 'Advanced', 'elementor' ),
|
||||
self::TAB_RESPONSIVE => __( 'Responsive', 'elementor' ),
|
||||
self::TAB_LAYOUT => __( 'Layout', 'elementor' ),
|
||||
self::TAB_SETTINGS => __( 'Settings', 'elementor' ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabs.
|
||||
*
|
||||
* Retrieve the tabs of the current control.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return array Control tabs.
|
||||
*/
|
||||
public static function get_tabs() {
|
||||
if ( ! self::$tabs ) {
|
||||
self::init_tabs();
|
||||
}
|
||||
|
||||
return self::$tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tab.
|
||||
*
|
||||
* This method adds a new tab to the current control.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param string $tab_name Tab name.
|
||||
* @param string $tab_label Tab label.
|
||||
*/
|
||||
public static function add_tab( $tab_name, $tab_label = '' ) {
|
||||
if ( ! self::$tabs ) {
|
||||
self::init_tabs();
|
||||
}
|
||||
|
||||
if ( isset( self::$tabs[ $tab_name ] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$tabs[ $tab_name ] = $tab_label;
|
||||
}
|
||||
|
||||
public static function get_groups_names() {
|
||||
// Group name must use "-" instead of "_"
|
||||
return [
|
||||
'background',
|
||||
'border',
|
||||
'typography',
|
||||
'image-size',
|
||||
'box-shadow',
|
||||
'css-filter',
|
||||
'text-shadow',
|
||||
];
|
||||
}
|
||||
|
||||
public static function get_controls_names() {
|
||||
return [
|
||||
self::TEXT,
|
||||
self::NUMBER,
|
||||
self::TEXTAREA,
|
||||
self::SELECT,
|
||||
self::SWITCHER,
|
||||
|
||||
self::BUTTON,
|
||||
self::HIDDEN,
|
||||
self::HEADING,
|
||||
self::RAW_HTML,
|
||||
self::POPOVER_TOGGLE,
|
||||
self::SECTION,
|
||||
self::TAB,
|
||||
self::TABS,
|
||||
self::DIVIDER,
|
||||
self::DEPRECATED_NOTICE,
|
||||
|
||||
self::COLOR,
|
||||
self::MEDIA,
|
||||
self::SLIDER,
|
||||
self::DIMENSIONS,
|
||||
self::CHOOSE,
|
||||
self::WYSIWYG,
|
||||
self::CODE,
|
||||
self::FONT,
|
||||
self::IMAGE_DIMENSIONS,
|
||||
|
||||
self::WP_WIDGET,
|
||||
|
||||
self::URL,
|
||||
self::REPEATER,
|
||||
self::ICON,
|
||||
self::ICONS,
|
||||
self::GALLERY,
|
||||
self::STRUCTURE,
|
||||
self::SELECT2,
|
||||
self::DATE_TIME,
|
||||
self::BOX_SHADOW,
|
||||
self::TEXT_SHADOW,
|
||||
self::ANIMATION,
|
||||
self::HOVER_ANIMATION,
|
||||
self::EXIT_ANIMATION,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Register controls.
|
||||
*
|
||||
* This method creates a list of all the supported controls by requiring the
|
||||
* control files and initializing each one of them.
|
||||
*
|
||||
* The list of supported controls includes the regular controls and the group
|
||||
* controls.
|
||||
*
|
||||
* External developers can register new controls by hooking to the
|
||||
* `elementor/controls/controls_registered` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function register_controls() {
|
||||
$this->controls = [];
|
||||
|
||||
foreach ( self::get_controls_names() as $control_id ) {
|
||||
$control_class_id = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $control_id ) ) );
|
||||
$class_name = __NAMESPACE__ . '\Control_' . $control_class_id;
|
||||
|
||||
$this->register_control( $control_id, new $class_name() );
|
||||
}
|
||||
|
||||
// Group Controls
|
||||
foreach ( self::get_groups_names() as $group_name ) {
|
||||
$group_class_id = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $group_name ) ) );
|
||||
$class_name = __NAMESPACE__ . '\Group_Control_' . $group_class_id;
|
||||
|
||||
$this->control_groups[ $group_name ] = new $class_name();
|
||||
}
|
||||
|
||||
/**
|
||||
* After controls registered.
|
||||
*
|
||||
* Fires after Elementor controls are registered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Controls_Manager $this The controls manager.
|
||||
*/
|
||||
do_action( 'elementor/controls/controls_registered', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register control.
|
||||
*
|
||||
* This method adds a new control to the controls list. It adds any given
|
||||
* control to any given control instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $control_id Control ID.
|
||||
* @param Base_Control $control_instance Control instance, usually the
|
||||
* current instance.
|
||||
*/
|
||||
public function register_control( $control_id, Base_Control $control_instance ) {
|
||||
$this->controls[ $control_id ] = $control_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister control.
|
||||
*
|
||||
* This method removes control from the controls list.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $control_id Control ID.
|
||||
*
|
||||
* @return bool True if the control was removed, False otherwise.
|
||||
*/
|
||||
public function unregister_control( $control_id ) {
|
||||
if ( ! isset( $this->controls[ $control_id ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset( $this->controls[ $control_id ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controls.
|
||||
*
|
||||
* Retrieve the controls list from the current instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return Base_Control[] Controls list.
|
||||
*/
|
||||
public function get_controls() {
|
||||
if ( null === $this->controls ) {
|
||||
$this->register_controls();
|
||||
}
|
||||
|
||||
return $this->controls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control.
|
||||
*
|
||||
* Retrieve a specific control from the current controls instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $control_id Control ID.
|
||||
*
|
||||
* @return bool|Base_Control Control instance, or False otherwise.
|
||||
*/
|
||||
public function get_control( $control_id ) {
|
||||
$controls = $this->get_controls();
|
||||
|
||||
return isset( $controls[ $control_id ] ) ? $controls[ $control_id ] : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get controls data.
|
||||
*
|
||||
* Retrieve all the registered controls and all the data for each control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array {
|
||||
* Control data.
|
||||
*
|
||||
* @type array $name Control data.
|
||||
* }
|
||||
*/
|
||||
public function get_controls_data() {
|
||||
$controls_data = [];
|
||||
|
||||
foreach ( $this->get_controls() as $name => $control ) {
|
||||
$controls_data[ $name ] = $control->get_settings();
|
||||
}
|
||||
|
||||
return $controls_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render controls.
|
||||
*
|
||||
* Generate the final HTML for all the registered controls using the element
|
||||
* template.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render_controls() {
|
||||
foreach ( $this->get_controls() as $control ) {
|
||||
$control->print_template();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control groups.
|
||||
*
|
||||
* Retrieve a specific group for a given ID, or a list of all the control
|
||||
* groups.
|
||||
*
|
||||
* If the given group ID is wrong, it will return `null`. When the ID valid,
|
||||
* it will return the group control instance. When no ID was given, it will
|
||||
* return all the control groups.
|
||||
*
|
||||
* @since 1.0.10
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Optional. Group ID. Default is null.
|
||||
*
|
||||
* @return null|Group_Control_Base|Group_Control_Base[]
|
||||
*/
|
||||
public function get_control_groups( $id = null ) {
|
||||
if ( $id ) {
|
||||
return isset( $this->control_groups[ $id ] ) ? $this->control_groups[ $id ] : null;
|
||||
}
|
||||
|
||||
return $this->control_groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add group control.
|
||||
*
|
||||
* This method adds a new group control to the control groups list. It adds
|
||||
* any given group control to any given group control instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Group control ID.
|
||||
* @param Group_Control_Base $instance Group control instance, usually the
|
||||
* current instance.
|
||||
*
|
||||
* @return Group_Control_Base Group control instance.
|
||||
*/
|
||||
public function add_group_control( $id, $instance ) {
|
||||
$this->control_groups[ $id ] = $instance;
|
||||
|
||||
return $instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue control scripts and styles.
|
||||
*
|
||||
* Used to register and enqueue custom scripts and styles used by the control.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue_control_scripts() {
|
||||
foreach ( $this->get_controls() as $control ) {
|
||||
$control->enqueue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Open new stack.
|
||||
*
|
||||
* This method adds a new stack to the control stacks list. It adds any
|
||||
* given stack to the current control instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $controls_stack Controls stack.
|
||||
*/
|
||||
public function open_stack( Controls_Stack $controls_stack ) {
|
||||
$stack_id = $controls_stack->get_unique_name();
|
||||
|
||||
$this->stacks[ $stack_id ] = [
|
||||
'tabs' => [],
|
||||
'controls' => [],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add control to stack.
|
||||
*
|
||||
* This method adds a new control to the stack.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $element Element stack.
|
||||
* @param string $control_id Control ID.
|
||||
* @param array $control_data Control data.
|
||||
* @param array $options Optional. Control additional options.
|
||||
* Default is an empty array.
|
||||
*
|
||||
* @return bool True if control added, False otherwise.
|
||||
*/
|
||||
public function add_control_to_stack( Controls_Stack $element, $control_id, $control_data, $options = [] ) {
|
||||
$default_options = [
|
||||
'overwrite' => false,
|
||||
'index' => null,
|
||||
];
|
||||
|
||||
$options = array_merge( $default_options, $options );
|
||||
|
||||
$default_args = [
|
||||
'type' => self::TEXT,
|
||||
'tab' => self::TAB_CONTENT,
|
||||
];
|
||||
|
||||
$control_data['name'] = $control_id;
|
||||
|
||||
$control_data = array_merge( $default_args, $control_data );
|
||||
|
||||
$control_type_instance = $this->get_control( $control_data['type'] );
|
||||
|
||||
if ( ! $control_type_instance ) {
|
||||
_doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Control type "%s" not found.', $control_data['type'] ), '1.0.0' );
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $control_type_instance instanceof Base_Data_Control ) {
|
||||
$control_default_value = $control_type_instance->get_default_value();
|
||||
|
||||
if ( is_array( $control_default_value ) ) {
|
||||
$control_data['default'] = isset( $control_data['default'] ) ? array_merge( $control_default_value, $control_data['default'] ) : $control_default_value;
|
||||
} else {
|
||||
$control_data['default'] = isset( $control_data['default'] ) ? $control_data['default'] : $control_default_value;
|
||||
}
|
||||
}
|
||||
|
||||
$stack_id = $element->get_unique_name();
|
||||
|
||||
if ( ! $options['overwrite'] && isset( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
|
||||
_doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Cannot redeclare control with same name "%s".', $control_id ), '1.0.0' );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$tabs = self::get_tabs();
|
||||
|
||||
if ( ! isset( $tabs[ $control_data['tab'] ] ) ) {
|
||||
$control_data['tab'] = $default_args['tab'];
|
||||
}
|
||||
|
||||
$this->stacks[ $stack_id ]['tabs'][ $control_data['tab'] ] = $tabs[ $control_data['tab'] ];
|
||||
|
||||
$this->stacks[ $stack_id ]['controls'][ $control_id ] = $control_data;
|
||||
|
||||
if ( null !== $options['index'] ) {
|
||||
$controls = $this->stacks[ $stack_id ]['controls'];
|
||||
|
||||
$controls_keys = array_keys( $controls );
|
||||
|
||||
array_splice( $controls_keys, $options['index'], 0, $control_id );
|
||||
|
||||
$this->stacks[ $stack_id ]['controls'] = array_merge( array_flip( $controls_keys ), $controls );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove control from stack.
|
||||
*
|
||||
* This method removes a control a the stack.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $stack_id Stack ID.
|
||||
* @param array|string $control_id The ID of the control to remove.
|
||||
*
|
||||
* @return bool|\WP_Error True if the stack was removed, False otherwise.
|
||||
*/
|
||||
public function remove_control_from_stack( $stack_id, $control_id ) {
|
||||
if ( is_array( $control_id ) ) {
|
||||
foreach ( $control_id as $id ) {
|
||||
$this->remove_control_from_stack( $stack_id, $id );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( empty( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
|
||||
return new \WP_Error( 'Cannot remove not-exists control.' );
|
||||
}
|
||||
|
||||
unset( $this->stacks[ $stack_id ]['controls'][ $control_id ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get control from stack.
|
||||
*
|
||||
* Retrieve a specific control for a given a specific stack.
|
||||
*
|
||||
* If the given control does not exist in the stack, or the stack does not
|
||||
* exist, it will return `WP_Error`. Otherwise, it will retrieve the control
|
||||
* from the stack.
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $stack_id Stack ID.
|
||||
* @param string $control_id Control ID.
|
||||
*
|
||||
* @return array|\WP_Error The control, or an error.
|
||||
*/
|
||||
public function get_control_from_stack( $stack_id, $control_id ) {
|
||||
if ( empty( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
|
||||
return new \WP_Error( 'Cannot get a not-exists control.' );
|
||||
}
|
||||
|
||||
return $this->stacks[ $stack_id ]['controls'][ $control_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Update control in stack.
|
||||
*
|
||||
* This method updates the control data for a given stack.
|
||||
*
|
||||
* @since 1.1.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $element Element stack.
|
||||
* @param string $control_id Control ID.
|
||||
* @param array $control_data Control data.
|
||||
* @param array $options Optional. Control additional options.
|
||||
* Default is an empty array.
|
||||
*
|
||||
* @return bool True if control updated, False otherwise.
|
||||
*/
|
||||
public function update_control_in_stack( Controls_Stack $element, $control_id, $control_data, array $options = [] ) {
|
||||
$old_control_data = $this->get_control_from_stack( $element->get_unique_name(), $control_id );
|
||||
|
||||
if ( is_wp_error( $old_control_data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! empty( $options['recursive'] ) ) {
|
||||
$control_data = array_replace_recursive( $old_control_data, $control_data );
|
||||
} else {
|
||||
$control_data = array_merge( $old_control_data, $control_data );
|
||||
}
|
||||
|
||||
return $this->add_control_to_stack( $element, $control_id, $control_data, [
|
||||
'overwrite' => true,
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stacks.
|
||||
*
|
||||
* Retrieve a specific stack for the list of stacks.
|
||||
*
|
||||
* If the given stack is wrong, it will return `null`. When the stack valid,
|
||||
* it will return the the specific stack. When no stack was given, it will
|
||||
* return all the stacks.
|
||||
*
|
||||
* @since 1.7.1
|
||||
* @access public
|
||||
*
|
||||
* @param string $stack_id Optional. stack ID. Default is null.
|
||||
*
|
||||
* @return null|array A list of stacks.
|
||||
*/
|
||||
public function get_stacks( $stack_id = null ) {
|
||||
if ( $stack_id ) {
|
||||
if ( isset( $this->stacks[ $stack_id ] ) ) {
|
||||
return $this->stacks[ $stack_id ];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->stacks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element stack.
|
||||
*
|
||||
* Retrieve a specific stack for the list of stacks from the current instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $controls_stack Controls stack.
|
||||
*
|
||||
* @return null|array Stack data if it exist, `null` otherwise.
|
||||
*/
|
||||
public function get_element_stack( Controls_Stack $controls_stack ) {
|
||||
$stack_id = $controls_stack->get_unique_name();
|
||||
|
||||
if ( ! isset( $this->stacks[ $stack_id ] ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->stacks[ $stack_id ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom CSS controls.
|
||||
*
|
||||
* This method adds a new control for the "Custom CSS" feature. The free
|
||||
* version of elementor uses this method to display an upgrade message to
|
||||
* Elementor Pro.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $controls_stack .
|
||||
* @param string $tab
|
||||
* @param array $additional_messages
|
||||
*
|
||||
*/
|
||||
public function add_custom_css_controls( Controls_Stack $controls_stack, $tab = self::TAB_ADVANCED, $additional_messages = [] ) {
|
||||
$controls_stack->start_controls_section(
|
||||
'section_custom_css_pro',
|
||||
[
|
||||
'label' => __( 'Custom CSS', 'elementor' ),
|
||||
'tab' => $tab,
|
||||
]
|
||||
);
|
||||
|
||||
$messages = [
|
||||
__( 'Custom CSS lets you add CSS code to any widget, and see it render live right in the editor.', 'elementor' ),
|
||||
];
|
||||
|
||||
if ( $additional_messages ) {
|
||||
$messages = array_merge( $messages, $additional_messages );
|
||||
}
|
||||
|
||||
$controls_stack->add_control(
|
||||
'custom_css_pro',
|
||||
[
|
||||
'type' => self::RAW_HTML,
|
||||
'raw' => $this->get_teaser_template( [
|
||||
'title' => __( 'Meet Our Custom CSS', 'elementor' ),
|
||||
'messages' => $messages,
|
||||
'link' => 'https://elementor.com/pro/?utm_source=panel-custom-css&utm_campaign=gopro&utm_medium=wp-dash',
|
||||
] ),
|
||||
]
|
||||
);
|
||||
|
||||
$controls_stack->end_controls_section();
|
||||
}
|
||||
|
||||
public function get_teaser_template( $texts ) {
|
||||
ob_start();
|
||||
?>
|
||||
<div class="elementor-nerd-box">
|
||||
<img class="elementor-nerd-box-icon" src="<?php echo ELEMENTOR_ASSETS_URL . 'images/go-pro.svg'; ?>" />
|
||||
<div class="elementor-nerd-box-title"><?php echo $texts['title']; ?></div>
|
||||
<?php foreach ( $texts['messages'] as $message ) { ?>
|
||||
<div class="elementor-nerd-box-message"><?php echo $message; ?></div>
|
||||
<?php }
|
||||
|
||||
if ( $texts['link'] ) { ?>
|
||||
<a class="elementor-nerd-box-link elementor-button elementor-button-default elementor-button-go-pro" href="<?php echo Utils::get_pro_link( $texts['link'] ); ?>" target="_blank">
|
||||
<?php echo __( 'Go Pro', 'elementor' ); ?>
|
||||
</a>
|
||||
<?php } ?>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom attributes controls.
|
||||
*
|
||||
* This method adds a new control for the "Custom Attributes" feature. The free
|
||||
* version of elementor uses this method to display an upgrade message to
|
||||
* Elementor Pro.
|
||||
*
|
||||
* @since 2.8.3
|
||||
* @access public
|
||||
*
|
||||
* @param Controls_Stack $controls_stack.
|
||||
*/
|
||||
public function add_custom_attributes_controls( Controls_Stack $controls_stack ) {
|
||||
$controls_stack->start_controls_section(
|
||||
'section_custom_attributes_pro',
|
||||
[
|
||||
'label' => __( 'Attributes', 'elementor' ),
|
||||
'tab' => self::TAB_ADVANCED,
|
||||
]
|
||||
);
|
||||
|
||||
$controls_stack->add_control(
|
||||
'custom_attributes_pro',
|
||||
[
|
||||
'type' => self::RAW_HTML,
|
||||
'raw' => $this->get_teaser_template( [
|
||||
'title' => __( 'Meet Our Attributes', 'elementor' ),
|
||||
'messages' => [
|
||||
__( 'Attributes lets you add custom HTML attributes to any element.', 'elementor' ),
|
||||
],
|
||||
'link' => 'https://elementor.com/pro/?utm_source=panel-custom-attributes&utm_campaign=gopro&utm_medium=wp-dash',
|
||||
] ),
|
||||
]
|
||||
);
|
||||
|
||||
$controls_stack->end_controls_section();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor elements manager.
|
||||
*
|
||||
* Elementor elements manager handler class is responsible for registering and
|
||||
* initializing all the supported elements.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Elements_Manager {
|
||||
|
||||
/**
|
||||
* Element types.
|
||||
*
|
||||
* Holds the list of all the element types.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var Element_Base[]
|
||||
*/
|
||||
private $_element_types;
|
||||
|
||||
/**
|
||||
* Element categories.
|
||||
*
|
||||
* Holds the list of all the element categories.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var
|
||||
*/
|
||||
private $categories;
|
||||
|
||||
/**
|
||||
* Elements constructor.
|
||||
*
|
||||
* Initializing Elementor elements manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->require_files();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create element instance.
|
||||
*
|
||||
* This method creates a new element instance for any given element.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $element_data Element data.
|
||||
* @param array $element_args Optional. Element arguments. Default is
|
||||
* an empty array.
|
||||
* @param Element_Base $element_type Optional. Element type. Default is null.
|
||||
*
|
||||
* @return Element_Base|null Element instance if element created, or null
|
||||
* otherwise.
|
||||
*/
|
||||
public function create_element_instance( array $element_data, array $element_args = [], Element_Base $element_type = null ) {
|
||||
if ( null === $element_type ) {
|
||||
if ( 'widget' === $element_data['elType'] ) {
|
||||
$element_type = Plugin::$instance->widgets_manager->get_widget_types( $element_data['widgetType'] );
|
||||
} else {
|
||||
$element_type = $this->get_element_types( $element_data['elType'] );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $element_type ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$args = array_merge( $element_type->get_default_args(), $element_args );
|
||||
|
||||
$element_class = $element_type->get_class_name();
|
||||
|
||||
try {
|
||||
$element = new $element_class( $element_data, $args );
|
||||
} catch ( \Exception $e ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element categories.
|
||||
*
|
||||
* Retrieve the list of categories the element belongs to.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Element categories.
|
||||
*/
|
||||
public function get_categories() {
|
||||
if ( null === $this->categories ) {
|
||||
$this->init_categories();
|
||||
}
|
||||
|
||||
return $this->categories;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add element category.
|
||||
*
|
||||
* Register new category for the element.
|
||||
*
|
||||
* @since 1.7.12
|
||||
* @access public
|
||||
*
|
||||
* @param string $category_name Category name.
|
||||
* @param array $category_properties Category properties.
|
||||
*/
|
||||
public function add_category( $category_name, $category_properties ) {
|
||||
if ( null === $this->categories ) {
|
||||
$this->get_categories();
|
||||
}
|
||||
|
||||
if ( ! isset( $this->categories[ $category_name ] ) ) {
|
||||
$this->categories[ $category_name ] = $category_properties;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register element type.
|
||||
*
|
||||
* Add new type to the list of registered types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Element_Base $element Element instance.
|
||||
*
|
||||
* @return bool Whether the element type was registered.
|
||||
*/
|
||||
public function register_element_type( Element_Base $element ) {
|
||||
$this->_element_types[ $element->get_name() ] = $element;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister element type.
|
||||
*
|
||||
* Remove element type from the list of registered types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Element name.
|
||||
*
|
||||
* @return bool Whether the element type was unregister, or not.
|
||||
*/
|
||||
public function unregister_element_type( $name ) {
|
||||
if ( ! isset( $this->_element_types[ $name ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset( $this->_element_types[ $name ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element types.
|
||||
*
|
||||
* Retrieve the list of all the element types, or if a specific element name
|
||||
* was provided retrieve his element types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $element_name Optional. Element name. Default is null.
|
||||
*
|
||||
* @return null|Element_Base|Element_Base[] Element types, or a list of all the element
|
||||
* types, or null if element does not exist.
|
||||
*/
|
||||
public function get_element_types( $element_name = null ) {
|
||||
if ( is_null( $this->_element_types ) ) {
|
||||
$this->init_elements();
|
||||
}
|
||||
|
||||
if ( null !== $element_name ) {
|
||||
return isset( $this->_element_types[ $element_name ] ) ? $this->_element_types[ $element_name ] : null;
|
||||
}
|
||||
|
||||
return $this->_element_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element types config.
|
||||
*
|
||||
* Retrieve the config of all the element types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Element types config.
|
||||
*/
|
||||
public function get_element_types_config() {
|
||||
$config = [];
|
||||
|
||||
foreach ( $this->get_element_types() as $element ) {
|
||||
$config[ $element->get_name() ] = $element->get_config();
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render elements content.
|
||||
*
|
||||
* Used to generate the elements templates on the editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render_elements_content() {
|
||||
foreach ( $this->get_element_types() as $element_type ) {
|
||||
$element_type->print_template();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init elements.
|
||||
*
|
||||
* Initialize Elementor elements by registering the supported elements.
|
||||
* Elementor supports by default `section` element and `column` element.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function init_elements() {
|
||||
$this->_element_types = [];
|
||||
|
||||
foreach ( [ 'section', 'column' ] as $element_name ) {
|
||||
$class_name = __NAMESPACE__ . '\Element_' . $element_name;
|
||||
|
||||
$this->register_element_type( new $class_name() );
|
||||
}
|
||||
|
||||
/**
|
||||
* After elements registered.
|
||||
*
|
||||
* Fires after Elementor elements are registered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
do_action( 'elementor/elements/elements_registered' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Init categories.
|
||||
*
|
||||
* Initialize the element categories.
|
||||
*
|
||||
* @since 1.7.12
|
||||
* @access private
|
||||
*/
|
||||
private function init_categories() {
|
||||
$this->categories = [
|
||||
'basic' => [
|
||||
'title' => __( 'Basic', 'elementor' ),
|
||||
'icon' => 'eicon-font',
|
||||
],
|
||||
'pro-elements' => [
|
||||
'title' => __( 'Pro', 'elementor' ),
|
||||
],
|
||||
'general' => [
|
||||
'title' => __( 'General', 'elementor' ),
|
||||
'icon' => 'eicon-font',
|
||||
],
|
||||
'theme-elements' => [
|
||||
'title' => __( 'Site', 'elementor' ),
|
||||
'active' => false,
|
||||
],
|
||||
'woocommerce-elements' => [
|
||||
'title' => __( 'WooCommerce', 'elementor' ),
|
||||
'active' => false,
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* When categories are registered.
|
||||
*
|
||||
* Fires after basic categories are registered, before WordPress
|
||||
* category have been registered.
|
||||
*
|
||||
* This is where categories registered by external developers are
|
||||
* added.
|
||||
*
|
||||
* @since 2.0.0
|
||||
*
|
||||
* @param Elements_Manager $this Elements manager instance.
|
||||
*/
|
||||
do_action( 'elementor/elements/categories_registered', $this );
|
||||
|
||||
$this->categories['pojo'] = [
|
||||
'title' => __( 'Pojo Themes', 'elementor' ),
|
||||
'icon' => 'eicon-pojome',
|
||||
];
|
||||
|
||||
$this->categories['wordpress'] = [
|
||||
'title' => __( 'WordPress', 'elementor' ),
|
||||
'icon' => 'eicon-wordpress',
|
||||
'active' => false,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Require files.
|
||||
*
|
||||
* Require Elementor element base class and column, section and repeater
|
||||
* elements.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function require_files() {
|
||||
require_once ELEMENTOR_PATH . 'includes/base/element-base.php';
|
||||
|
||||
require ELEMENTOR_PATH . 'includes/elements/column.php';
|
||||
require ELEMENTOR_PATH . 'includes/elements/section.php';
|
||||
require ELEMENTOR_PATH . 'includes/elements/repeater.php';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Files\Assets\Svg\Svg_Handler;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor icons manager.
|
||||
*
|
||||
* Elementor icons manager handler class
|
||||
*
|
||||
* @since 2.4.0
|
||||
*/
|
||||
class Icons_Manager {
|
||||
|
||||
const NEEDS_UPDATE_OPTION = 'icon_manager_needs_update';
|
||||
/**
|
||||
* Tabs.
|
||||
*
|
||||
* Holds the list of all the tabs.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @since 2.4.0
|
||||
* @var array
|
||||
*/
|
||||
private static $tabs;
|
||||
|
||||
private static function get_needs_upgrade_option() {
|
||||
return get_option( 'elementor_' . self::NEEDS_UPDATE_OPTION, null );
|
||||
}
|
||||
|
||||
/**
|
||||
* register styles
|
||||
*
|
||||
* Used to register all icon types stylesheets so they could be enqueued later by widgets
|
||||
*/
|
||||
public function register_styles() {
|
||||
$config = self::get_icon_manager_tabs_config();
|
||||
|
||||
$shared_styles = [];
|
||||
|
||||
foreach ( $config as $type => $icon_type ) {
|
||||
if ( ! isset( $icon_type['url'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$dependencies = [];
|
||||
if ( ! empty( $icon_type['enqueue'] ) ) {
|
||||
foreach ( (array) $icon_type['enqueue'] as $font_css_url ) {
|
||||
if ( ! in_array( $font_css_url, array_keys( $shared_styles ) ) ) {
|
||||
$style_handle = 'elementor-icons-shared-' . count( $shared_styles );
|
||||
wp_register_style(
|
||||
$style_handle,
|
||||
$font_css_url,
|
||||
[],
|
||||
$icon_type['ver']
|
||||
);
|
||||
$shared_styles[ $font_css_url ] = $style_handle;
|
||||
}
|
||||
$dependencies[] = $shared_styles[ $font_css_url ];
|
||||
}
|
||||
}
|
||||
wp_register_style(
|
||||
'elementor-icons-' . $icon_type['name'],
|
||||
$icon_type['url'],
|
||||
$dependencies,
|
||||
$icon_type['ver']
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Tabs
|
||||
*
|
||||
* Initiate Icon Manager Tabs.
|
||||
*
|
||||
* @access private
|
||||
* @static
|
||||
* @since 2.4.0
|
||||
*/
|
||||
private static function init_tabs() {
|
||||
self::$tabs = apply_filters( 'elementor/icons_manager/native', [
|
||||
'fa-regular' => [
|
||||
'name' => 'fa-regular',
|
||||
'label' => __( 'Font Awesome - Regular', 'elementor' ),
|
||||
'url' => self::get_fa_asset_url( 'regular' ),
|
||||
'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ],
|
||||
'prefix' => 'fa-',
|
||||
'displayPrefix' => 'far',
|
||||
'labelIcon' => 'fab fa-font-awesome-alt',
|
||||
'ver' => '5.12.0',
|
||||
'fetchJson' => self::get_fa_asset_url( 'regular', 'js', false ),
|
||||
'native' => true,
|
||||
],
|
||||
'fa-solid' => [
|
||||
'name' => 'fa-solid',
|
||||
'label' => __( 'Font Awesome - Solid', 'elementor' ),
|
||||
'url' => self::get_fa_asset_url( 'solid' ),
|
||||
'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ],
|
||||
'prefix' => 'fa-',
|
||||
'displayPrefix' => 'fas',
|
||||
'labelIcon' => 'fab fa-font-awesome',
|
||||
'ver' => '5.12.0',
|
||||
'fetchJson' => self::get_fa_asset_url( 'solid', 'js', false ),
|
||||
'native' => true,
|
||||
],
|
||||
'fa-brands' => [
|
||||
'name' => 'fa-brands',
|
||||
'label' => __( 'Font Awesome - Brands', 'elementor' ),
|
||||
'url' => self::get_fa_asset_url( 'brands' ),
|
||||
'enqueue' => [ self::get_fa_asset_url( 'fontawesome' ) ],
|
||||
'prefix' => 'fa-',
|
||||
'displayPrefix' => 'fab',
|
||||
'labelIcon' => 'fab fa-font-awesome-flag',
|
||||
'ver' => '5.12.0',
|
||||
'fetchJson' => self::get_fa_asset_url( 'brands', 'js', false ),
|
||||
'native' => true,
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Icon Manager Tabs
|
||||
* @return array
|
||||
*/
|
||||
public static function get_icon_manager_tabs() {
|
||||
if ( ! self::$tabs ) {
|
||||
self::init_tabs();
|
||||
}
|
||||
$additional_tabs = apply_filters( 'elementor/icons_manager/additional_tabs', [] );
|
||||
return array_merge( self::$tabs, $additional_tabs );
|
||||
}
|
||||
|
||||
public static function enqueue_shim() {
|
||||
wp_enqueue_script(
|
||||
'font-awesome-4-shim',
|
||||
self::get_fa_asset_url( 'v4-shims', 'js' ),
|
||||
[],
|
||||
ELEMENTOR_VERSION
|
||||
);
|
||||
// Make sure that the CSS in the 'all' file does not override FA Pro's CSS
|
||||
if ( ! wp_script_is( 'font-awesome-pro' ) ) {
|
||||
wp_enqueue_style(
|
||||
'font-awesome-5-all',
|
||||
self::get_fa_asset_url( 'all' ),
|
||||
[],
|
||||
ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
wp_enqueue_style(
|
||||
'font-awesome-4-shim',
|
||||
self::get_fa_asset_url( 'v4-shims' ),
|
||||
[],
|
||||
ELEMENTOR_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
private static function get_fa_asset_url( $filename, $ext_type = 'css', $add_suffix = true ) {
|
||||
static $is_test_mode = null;
|
||||
if ( null === $is_test_mode ) {
|
||||
$is_test_mode = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG || defined( 'ELEMENTOR_TESTS' ) && ELEMENTOR_TESTS;
|
||||
}
|
||||
$url = ELEMENTOR_ASSETS_URL . 'lib/font-awesome/' . $ext_type . '/' . $filename;
|
||||
if ( ! $is_test_mode && $add_suffix ) {
|
||||
$url .= '.min';
|
||||
}
|
||||
return $url . '.' . $ext_type;
|
||||
}
|
||||
|
||||
public static function get_icon_manager_tabs_config() {
|
||||
$tabs = [
|
||||
'all' => [
|
||||
'name' => 'all',
|
||||
'label' => __( 'All Icons', 'elementor' ),
|
||||
'labelIcon' => 'eicon-filter',
|
||||
'native' => true,
|
||||
],
|
||||
];
|
||||
|
||||
return array_values( array_merge( $tabs, self::get_icon_manager_tabs() ) );
|
||||
}
|
||||
|
||||
private static function render_svg_icon( $value ) {
|
||||
if ( ! isset( $value['id'] ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return Svg_Handler::get_inline_svg( $value['id'] );
|
||||
}
|
||||
|
||||
private static function render_icon_html( $icon, $attributes = [], $tag = 'i' ) {
|
||||
$icon_types = self::get_icon_manager_tabs();
|
||||
if ( isset( $icon_types[ $icon['library'] ]['render_callback'] ) && is_callable( $icon_types[ $icon['library'] ]['render_callback'] ) ) {
|
||||
return call_user_func_array( $icon_types[ $icon['library'] ]['render_callback'], [ $icon, $attributes, $tag ] );
|
||||
}
|
||||
|
||||
if ( empty( $attributes['class'] ) ) {
|
||||
$attributes['class'] = $icon['value'];
|
||||
} else {
|
||||
if ( is_array( $attributes['class'] ) ) {
|
||||
$attributes['class'][] = $icon['value'];
|
||||
} else {
|
||||
$attributes['class'] .= ' ' . $icon['value'];
|
||||
}
|
||||
}
|
||||
return '<' . $tag . ' ' . Utils::render_html_attributes( $attributes ) . '></' . $tag . '>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Icon
|
||||
*
|
||||
* Used to render Icon for \Elementor\Controls_Manager::ICONS
|
||||
* @param array $icon Icon Type, Icon value
|
||||
* @param array $attributes Icon HTML Attributes
|
||||
* @param string $tag Icon HTML tag, defaults to <i>
|
||||
*
|
||||
* @return mixed|string
|
||||
*/
|
||||
public static function render_icon( $icon, $attributes = [], $tag = 'i' ) {
|
||||
if ( empty( $icon['library'] ) ) {
|
||||
return false;
|
||||
}
|
||||
$output = '';
|
||||
// handler SVG Icon
|
||||
if ( 'svg' === $icon['library'] ) {
|
||||
$output = self::render_svg_icon( $icon['value'] );
|
||||
} else {
|
||||
$output = self::render_icon_html( $icon, $attributes, $tag );
|
||||
}
|
||||
|
||||
echo $output;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Font Awesome 4 to font Awesome 5 Value Migration
|
||||
*
|
||||
* used to convert string value of Icon control to array value of Icons control
|
||||
* ex: 'fa fa-star' => [ 'value' => 'fas fa-star', 'library' => 'fa-solid' ]
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function fa4_to_fa5_value_migration( $value ) {
|
||||
static $migration_dictionary = false;
|
||||
if ( '' === $value ) {
|
||||
return [
|
||||
'value' => '',
|
||||
'library' => '',
|
||||
];
|
||||
}
|
||||
if ( false === $migration_dictionary ) {
|
||||
$migration_dictionary = json_decode( file_get_contents( ELEMENTOR_ASSETS_PATH . 'lib/font-awesome/migration/mapping.js' ), true );
|
||||
}
|
||||
if ( isset( $migration_dictionary[ $value ] ) ) {
|
||||
return $migration_dictionary[ $value ];
|
||||
}
|
||||
|
||||
return [
|
||||
'value' => 'fas ' . str_replace( 'fa ', '', $value ),
|
||||
'library' => 'fa-solid',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* on_import_migration
|
||||
* @param array $element settings array
|
||||
* @param string $old_control old control id
|
||||
* @param string $new_control new control id
|
||||
* @param bool $remove_old boolean weather to remove old control or not
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function on_import_migration( array $element, $old_control = '', $new_control = '', $remove_old = false ) {
|
||||
|
||||
if ( ! isset( $element['settings'][ $old_control ] ) || isset( $element['settings'][ $new_control ] ) ) {
|
||||
return $element;
|
||||
}
|
||||
|
||||
// Case when old value is saved as empty string
|
||||
$new_value = [
|
||||
'value' => '',
|
||||
'library' => '',
|
||||
];
|
||||
|
||||
// Case when old value needs migration
|
||||
if ( ! empty( $element['settings'][ $old_control ] ) && ! self::is_migration_allowed() ) {
|
||||
$new_value = self::fa4_to_fa5_value_migration( $element['settings'][ $old_control ] );
|
||||
}
|
||||
|
||||
$element['settings'][ $new_control ] = $new_value;
|
||||
|
||||
//remove old value
|
||||
if ( $remove_old ) {
|
||||
unset( $element['settings'][ $old_control ] );
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
/**
|
||||
* is_migration_allowed
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_migration_allowed() {
|
||||
static $migration_allowed = false;
|
||||
if ( false === $migration_allowed ) {
|
||||
$migration_allowed = null === self::get_needs_upgrade_option();
|
||||
|
||||
/**
|
||||
* allowed to filter migration allowed
|
||||
*/
|
||||
$migration_allowed = apply_filters( 'elementor/icons_manager/migration_allowed', $migration_allowed );
|
||||
}
|
||||
return $migration_allowed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register_Admin Settings
|
||||
*
|
||||
* adds Font Awesome migration / update admin settings
|
||||
* @param Settings $settings
|
||||
*/
|
||||
public function register_admin_settings( Settings $settings ) {
|
||||
$settings->add_field(
|
||||
Settings::TAB_ADVANCED,
|
||||
Settings::TAB_ADVANCED,
|
||||
'load_fa4_shim',
|
||||
[
|
||||
'label' => __( 'Load Font Awesome 4 Support', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'select',
|
||||
'std' => 1,
|
||||
'options' => [
|
||||
'' => __( 'No', 'elementor' ),
|
||||
'yes' => __( 'Yes', 'elementor' ),
|
||||
],
|
||||
'desc' => __( 'Font Awesome 4 support script (shim.js) is a script that makes sure all previously selected Font Awesome 4 icons are displayed correctly while using Font Awesome 5 library.', 'elementor' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
public function register_admin_tools_settings( Tools $settings ) {
|
||||
$settings->add_tab( 'fontawesome4_migration', [ 'label' => __( 'Font Awesome Upgrade', 'elementor' ) ] );
|
||||
|
||||
$settings->add_section( 'fontawesome4_migration', 'fontawesome4_migration', [
|
||||
'callback' => function() {
|
||||
echo '<h2>' . esc_html__( 'Font Awesome Upgrade', 'elementor' ) . '</h2>';
|
||||
echo '<p>' .
|
||||
__( 'Access 1,500+ amazing Font Awesome 5 icons and enjoy faster performance and design flexibility.', 'elementor' ) . '<br>' .
|
||||
__( 'By upgrading, whenever you edit a page containing a Font Awesome 4 icon, Elementor will convert it to the new Font Awesome 5 icon.', 'elementor' ) .
|
||||
'</p><p><strong>' .
|
||||
__( 'Please note that the upgrade process may cause some of the previously used Font Awesome 4 icons to look a bit different due to minor design changes made by Font Awesome.', 'elementor' ) .
|
||||
'</strong></p><p>' .
|
||||
__( 'The upgrade process includes a database update', 'elementor' ) . ' - ' .
|
||||
__( 'We highly recommend backing up your database before performing this upgrade.', 'elementor' ) .
|
||||
'</p>' .
|
||||
__( 'This action is not reversible and cannot be undone by rolling back to previous versions.', 'elementor' ) .
|
||||
'</p>';
|
||||
},
|
||||
'fields' => [
|
||||
[
|
||||
'label' => __( 'Font Awesome Upgrade', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'raw_html',
|
||||
'html' => sprintf( '<span data-action="%s" data-_nonce="%s" class="button" id="elementor_upgrade_fa_button">%s</span>',
|
||||
self::NEEDS_UPDATE_OPTION . '_upgrade',
|
||||
wp_create_nonce( self::NEEDS_UPDATE_OPTION ),
|
||||
__( 'Upgrade To Font Awesome 5', 'elementor' )
|
||||
),
|
||||
],
|
||||
],
|
||||
],
|
||||
] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax Upgrade to FontAwesome 5
|
||||
*/
|
||||
public function ajax_upgrade_to_fa5() {
|
||||
check_ajax_referer( self::NEEDS_UPDATE_OPTION, '_nonce' );
|
||||
|
||||
delete_option( 'elementor_' . self::NEEDS_UPDATE_OPTION );
|
||||
|
||||
wp_send_json_success( [ 'message' => '<p>' . __( 'Hurray! The upgrade process to Font Awesome 5 was completed successfully.', 'elementor' ) . '</p>' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add Update Needed Flag
|
||||
* @param array $settings
|
||||
*
|
||||
* @return array;
|
||||
*/
|
||||
public function add_update_needed_flag( $settings ) {
|
||||
$settings['icons_update_needed'] = true;
|
||||
return $settings;
|
||||
}
|
||||
|
||||
public function enqueue_fontawesome_css() {
|
||||
if ( ! self::is_migration_allowed() ) {
|
||||
wp_enqueue_style( 'font-awesome' );
|
||||
} else {
|
||||
$current_filter = current_filter();
|
||||
$load_shim = get_option( 'elementor_load_fa4_shim', false );
|
||||
if ( 'elementor/editor/after_enqueue_styles' === $current_filter ) {
|
||||
self::enqueue_shim();
|
||||
} else if ( 'yes' === $load_shim ) {
|
||||
self::enqueue_shim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function add_admin_strings( $settings ) {
|
||||
$settings['i18n']['confirm_fa_migration_admin_modal_body'] = __( 'I understand that by upgrading to Font Awesome 5,', 'elementor' ) . '<br>' . __( 'I acknowledge that some changes may affect my website and that this action cannot be undone.', 'elementor' );
|
||||
$settings['i18n']['confirm_fa_migration_admin_modal_head'] = __( 'Font Awesome 5 Migration', 'elementor' );
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
public function register_ajax_actions() {
|
||||
_deprecated_function( __METHOD__, '3.0.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 3.0.0.
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
public function ajax_enable_svg_uploads() {
|
||||
_deprecated_function( __METHOD__, '3.0.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Icons Manager constructor
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( is_admin() ) {
|
||||
// @todo: remove once we deprecate fa4
|
||||
add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_settings' ], 100 );
|
||||
add_action( 'elementor/admin/localize_settings', [ $this, 'add_admin_strings' ] );
|
||||
}
|
||||
|
||||
add_action( 'elementor/editor/after_enqueue_styles', [ $this, 'enqueue_fontawesome_css' ] );
|
||||
add_action( 'elementor/frontend/after_enqueue_styles', [ $this, 'enqueue_fontawesome_css' ] );
|
||||
|
||||
add_action( 'elementor/frontend/after_register_styles', [ $this, 'register_styles' ] );
|
||||
|
||||
if ( ! self::is_migration_allowed() ) {
|
||||
add_filter( 'elementor/editor/localize_settings', [ $this, 'add_update_needed_flag' ] );
|
||||
add_action( 'elementor/admin/after_create_settings/' . Tools::PAGE_ID, [ $this, 'register_admin_tools_settings' ], 100 );
|
||||
|
||||
if ( ! empty( $_POST ) ) { // phpcs:ignore -- nonce validation done in callback
|
||||
add_action( 'wp_ajax_' . self::NEEDS_UPDATE_OPTION . '_upgrade', [ $this, 'ajax_upgrade_to_fa5' ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor images manager.
|
||||
*
|
||||
* Elementor images manager handler class is responsible for retrieving image
|
||||
* details.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Images_Manager {
|
||||
|
||||
/**
|
||||
* Get images details.
|
||||
*
|
||||
* Retrieve details for all the images.
|
||||
*
|
||||
* Fired by `wp_ajax_elementor_get_images_details` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function get_images_details() {
|
||||
$items = $_POST['items'];
|
||||
$urls = [];
|
||||
|
||||
foreach ( $items as $item ) {
|
||||
$urls[ $item['id'] ] = $this->get_details( $item['id'], $item['size'], $item['is_first_time'] );
|
||||
}
|
||||
|
||||
wp_send_json_success( $urls );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get image details.
|
||||
*
|
||||
* Retrieve single image details.
|
||||
*
|
||||
* Fired by `wp_ajax_elementor_get_image_details` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $id Image attachment ID.
|
||||
* @param string|array $size Image size. Accepts any valid image
|
||||
* size, or an array of width and height
|
||||
* values in pixels (in that order).
|
||||
* @param string $is_first_time Set 'true' string to force reloading
|
||||
* all image sizes.
|
||||
*
|
||||
* @return array URLs with different image sizes.
|
||||
*/
|
||||
public function get_details( $id, $size, $is_first_time ) {
|
||||
if ( ! class_exists( 'Group_Control_Image_Size' ) ) {
|
||||
require_once ELEMENTOR_PATH . '/includes/controls/groups/image-size.php';
|
||||
}
|
||||
|
||||
if ( 'true' === $is_first_time ) {
|
||||
$sizes = get_intermediate_image_sizes();
|
||||
$sizes[] = 'full';
|
||||
} else {
|
||||
$sizes = [];
|
||||
}
|
||||
|
||||
$sizes[] = $size;
|
||||
$urls = [];
|
||||
foreach ( $sizes as $size ) {
|
||||
if ( 0 === strpos( $size, 'custom_' ) ) {
|
||||
preg_match( '/custom_(\d*)x(\d*)/', $size, $matches );
|
||||
|
||||
$instance = [
|
||||
'image_size' => 'custom',
|
||||
'image_custom_dimension' => [
|
||||
'width' => $matches[1],
|
||||
'height' => $matches[2],
|
||||
],
|
||||
];
|
||||
|
||||
$urls[ $size ] = Group_Control_Image_Size::get_attachment_image_src( $id, 'image', $instance );
|
||||
} else {
|
||||
$urls[ $size ] = wp_get_attachment_image_src( $id, $size )[0];
|
||||
}
|
||||
}
|
||||
|
||||
return $urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Light-Box Image Attributes
|
||||
*
|
||||
* Used to retrieve an array of image attributes to be used for displaying an image in Elementor's Light Box module.
|
||||
*
|
||||
* @param int $id The ID of the image
|
||||
*
|
||||
* @return array An array of image attributes including `title` and `description`.
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*/
|
||||
|
||||
public function get_lightbox_image_attributes( $id ) {
|
||||
$attributes = [];
|
||||
$kit = Plugin::$instance->kits_manager->get_active_kit();
|
||||
$lightbox_title_src = $kit->get_settings( 'lightbox_title_src' );
|
||||
$lightbox_description_src = $kit->get_settings( 'lightbox_description_src' );
|
||||
$attachment = get_post( $id );
|
||||
$image_data = [
|
||||
'alt' => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
|
||||
'caption' => $attachment->post_excerpt,
|
||||
'description' => $attachment->post_content,
|
||||
'title' => $attachment->post_title,
|
||||
];
|
||||
|
||||
if ( $lightbox_title_src && $image_data[ $lightbox_title_src ] ) {
|
||||
$attributes['title'] = $image_data[ $lightbox_title_src ];
|
||||
}
|
||||
|
||||
if ( $lightbox_description_src && $image_data[ $lightbox_description_src ] ) {
|
||||
$attributes['description'] = $image_data[ $lightbox_description_src ];
|
||||
}
|
||||
|
||||
return $attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Images manager constructor.
|
||||
*
|
||||
* Initializing Elementor images manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'wp_ajax_elementor_get_images_details', [ $this, 'get_images_details' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor skins manager.
|
||||
*
|
||||
* Elementor skins manager handler class is responsible for registering and
|
||||
* initializing all the supported skins.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Skins_Manager {
|
||||
|
||||
/**
|
||||
* Registered Skins.
|
||||
*
|
||||
* Holds the list of all the registered skins for all the widgets.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var array Registered skins.
|
||||
*/
|
||||
private $_skins = [];
|
||||
|
||||
/**
|
||||
* Add new skin.
|
||||
*
|
||||
* Register a single new skin for a widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Widget_Base $widget Elementor widget.
|
||||
* @param Skin_Base $skin Elementor skin.
|
||||
*
|
||||
* @return true True if skin added.
|
||||
*/
|
||||
public function add_skin( Widget_Base $widget, Skin_Base $skin ) {
|
||||
$widget_name = $widget->get_name();
|
||||
|
||||
if ( ! isset( $this->_skins[ $widget_name ] ) ) {
|
||||
$this->_skins[ $widget_name ] = [];
|
||||
}
|
||||
|
||||
$this->_skins[ $widget_name ][ $skin->get_id() ] = $skin;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a skin.
|
||||
*
|
||||
* Unregister an existing skin from a widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Widget_Base $widget Elementor widget.
|
||||
* @param string $skin_id Elementor skin ID.
|
||||
*
|
||||
* @return true|\WP_Error True if skin removed, `WP_Error` otherwise.
|
||||
*/
|
||||
public function remove_skin( Widget_Base $widget, $skin_id ) {
|
||||
$widget_name = $widget->get_name();
|
||||
|
||||
if ( ! isset( $this->_skins[ $widget_name ][ $skin_id ] ) ) {
|
||||
return new \WP_Error( 'Cannot remove not-exists skin.' );
|
||||
}
|
||||
|
||||
unset( $this->_skins[ $widget_name ][ $skin_id ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get skins.
|
||||
*
|
||||
* Retrieve all the skins assigned for a specific widget.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Widget_Base $widget Elementor widget.
|
||||
*
|
||||
* @return false|array Skins if the widget has skins, False otherwise.
|
||||
*/
|
||||
public function get_skins( Widget_Base $widget ) {
|
||||
$widget_name = $widget->get_name();
|
||||
|
||||
if ( ! isset( $this->_skins[ $widget_name ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $this->_skins[ $widget_name ];
|
||||
}
|
||||
|
||||
/**
|
||||
* Skins manager constructor.
|
||||
*
|
||||
* Initializing Elementor skins manager by requiring the skin base class.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
require ELEMENTOR_PATH . 'includes/base/skin-base.php';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,526 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
|
||||
use Elementor\Core\Utils\Exceptions;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor widgets manager.
|
||||
*
|
||||
* Elementor widgets manager handler class is responsible for registering and
|
||||
* initializing all the supported Elementor widgets.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Widgets_Manager {
|
||||
|
||||
/**
|
||||
* Widget types.
|
||||
*
|
||||
* Holds the list of all the widget types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var Widget_Base[]
|
||||
*/
|
||||
private $_widget_types = null;
|
||||
|
||||
/**
|
||||
* Init widgets.
|
||||
*
|
||||
* Initialize Elementor widgets manager. Include all the the widgets files
|
||||
* and register each Elementor and WordPress widget.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function init_widgets() {
|
||||
$build_widgets_filename = [
|
||||
'common',
|
||||
'heading',
|
||||
'image',
|
||||
'text-editor',
|
||||
'video',
|
||||
'button',
|
||||
'divider',
|
||||
'spacer',
|
||||
'image-box',
|
||||
'google-maps',
|
||||
'icon',
|
||||
'icon-box',
|
||||
'star-rating',
|
||||
'image-carousel',
|
||||
'image-gallery',
|
||||
'icon-list',
|
||||
'counter',
|
||||
'progress',
|
||||
'testimonial',
|
||||
'tabs',
|
||||
'accordion',
|
||||
'toggle',
|
||||
'social-icons',
|
||||
'alert',
|
||||
'audio',
|
||||
'shortcode',
|
||||
'html',
|
||||
'menu-anchor',
|
||||
'sidebar',
|
||||
'read-more',
|
||||
];
|
||||
|
||||
$this->_widget_types = [];
|
||||
|
||||
foreach ( $build_widgets_filename as $widget_filename ) {
|
||||
include( ELEMENTOR_PATH . 'includes/widgets/' . $widget_filename . '.php' );
|
||||
|
||||
$class_name = str_replace( '-', '_', $widget_filename );
|
||||
|
||||
$class_name = __NAMESPACE__ . '\Widget_' . $class_name;
|
||||
|
||||
$this->register_widget_type( new $class_name() );
|
||||
}
|
||||
|
||||
$this->register_wp_widgets();
|
||||
|
||||
/**
|
||||
* After widgets registered.
|
||||
*
|
||||
* Fires after Elementor widgets are registered.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Widgets_Manager $this The widgets manager.
|
||||
*/
|
||||
do_action( 'elementor/widgets/widgets_registered', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register WordPress widgets.
|
||||
*
|
||||
* Add native WordPress widget to the list of registered widget types.
|
||||
*
|
||||
* Exclude the widgets that are in Elementor widgets black list. Theme and
|
||||
* plugin authors can filter the black list.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function register_wp_widgets() {
|
||||
global $wp_widget_factory;
|
||||
|
||||
// Skip Pojo widgets.
|
||||
$pojo_allowed_widgets = [
|
||||
'Pojo_Widget_Recent_Posts',
|
||||
'Pojo_Widget_Posts_Group',
|
||||
'Pojo_Widget_Gallery',
|
||||
'Pojo_Widget_Recent_Galleries',
|
||||
'Pojo_Slideshow_Widget',
|
||||
'Pojo_Forms_Widget',
|
||||
'Pojo_Widget_News_Ticker',
|
||||
|
||||
'Pojo_Widget_WC_Products',
|
||||
'Pojo_Widget_WC_Products_Category',
|
||||
'Pojo_Widget_WC_Product_Categories',
|
||||
];
|
||||
|
||||
// Allow themes/plugins to filter out their widgets.
|
||||
$black_list = [];
|
||||
|
||||
/**
|
||||
* Elementor widgets black list.
|
||||
*
|
||||
* Filters the widgets black list that won't be displayed in the panel.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param array $black_list A black list of widgets. Default is an empty array.
|
||||
*/
|
||||
$black_list = apply_filters( 'elementor/widgets/black_list', $black_list );
|
||||
|
||||
foreach ( $wp_widget_factory->widgets as $widget_class => $widget_obj ) {
|
||||
|
||||
if ( in_array( $widget_class, $black_list ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $widget_obj instanceof \Pojo_Widget_Base && ! in_array( $widget_class, $pojo_allowed_widgets ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$elementor_widget_class = __NAMESPACE__ . '\Widget_WordPress';
|
||||
|
||||
$this->register_widget_type(
|
||||
new $elementor_widget_class( [], [
|
||||
'widget_name' => $widget_class,
|
||||
] )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Require files.
|
||||
*
|
||||
* Require Elementor widget base class.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function require_files() {
|
||||
require ELEMENTOR_PATH . 'includes/base/widget-base.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Register widget type.
|
||||
*
|
||||
* Add a new widget type to the list of registered widget types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Widget_Base $widget Elementor widget.
|
||||
*
|
||||
* @return true True if the widget was registered.
|
||||
*/
|
||||
public function register_widget_type( Widget_Base $widget ) {
|
||||
if ( is_null( $this->_widget_types ) ) {
|
||||
$this->init_widgets();
|
||||
}
|
||||
|
||||
$this->_widget_types[ $widget->get_name() ] = $widget;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister widget type.
|
||||
*
|
||||
* Removes widget type from the list of registered widget types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $name Widget name.
|
||||
*
|
||||
* @return true True if the widget was unregistered, False otherwise.
|
||||
*/
|
||||
public function unregister_widget_type( $name ) {
|
||||
if ( ! isset( $this->_widget_types[ $name ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
unset( $this->_widget_types[ $name ] );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget types.
|
||||
*
|
||||
* Retrieve the registered widget types list.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $widget_name Optional. Widget name. Default is null.
|
||||
*
|
||||
* @return Widget_Base|Widget_Base[]|null Registered widget types.
|
||||
*/
|
||||
public function get_widget_types( $widget_name = null ) {
|
||||
if ( is_null( $this->_widget_types ) ) {
|
||||
$this->init_widgets();
|
||||
}
|
||||
|
||||
if ( null !== $widget_name ) {
|
||||
return isset( $this->_widget_types[ $widget_name ] ) ? $this->_widget_types[ $widget_name ] : null;
|
||||
}
|
||||
|
||||
return $this->_widget_types;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widget types config.
|
||||
*
|
||||
* Retrieve all the registered widgets with config for each widgets.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Registered widget types with each widget config.
|
||||
*/
|
||||
public function get_widget_types_config() {
|
||||
$config = [];
|
||||
|
||||
foreach ( $this->get_widget_types() as $widget_key => $widget ) {
|
||||
$config[ $widget_key ] = $widget->get_config();
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
public function ajax_get_widget_types_controls_config( array $data ) {
|
||||
$config = [];
|
||||
|
||||
foreach ( $this->get_widget_types() as $widget_key => $widget ) {
|
||||
if ( isset( $data['exclude'][ $widget_key ] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$config[ $widget_key ] = [
|
||||
'controls' => $widget->get_stack( false )['controls'],
|
||||
'tabs_controls' => $widget->get_tabs_controls(),
|
||||
];
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax render widget.
|
||||
*
|
||||
* Ajax handler for Elementor render_widget.
|
||||
*
|
||||
* Fired by `wp_ajax_elementor_render_widget` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @throws \Exception If current user don't have permissions to edit the post.
|
||||
*
|
||||
* @param array $request Ajax request.
|
||||
*
|
||||
* @return array {
|
||||
* Rendered widget.
|
||||
*
|
||||
* @type string $render The rendered HTML.
|
||||
* }
|
||||
*/
|
||||
public function ajax_render_widget( $request ) {
|
||||
$document = Plugin::$instance->documents->get( $request['editor_post_id'] );
|
||||
|
||||
if ( ! $document->is_editable_by_current_user() ) {
|
||||
throw new \Exception( 'Access denied.', Exceptions::FORBIDDEN );
|
||||
}
|
||||
|
||||
// Override the global $post for the render.
|
||||
query_posts(
|
||||
[
|
||||
'p' => $request['editor_post_id'],
|
||||
'post_type' => 'any',
|
||||
]
|
||||
);
|
||||
|
||||
$editor = Plugin::$instance->editor;
|
||||
$is_edit_mode = $editor->is_edit_mode();
|
||||
$editor->set_edit_mode( true );
|
||||
|
||||
Plugin::$instance->documents->switch_to_document( $document );
|
||||
|
||||
$render_html = $document->render_element( $request['data'] );
|
||||
|
||||
$editor->set_edit_mode( $is_edit_mode );
|
||||
|
||||
return [
|
||||
'render' => $render_html,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajax get WordPress widget form.
|
||||
*
|
||||
* Ajax handler for Elementor editor get_wp_widget_form.
|
||||
*
|
||||
* Fired by `wp_ajax_elementor_editor_get_wp_widget_form` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $request Ajax request.
|
||||
*
|
||||
* @return bool|string Rendered widget form.
|
||||
*/
|
||||
public function ajax_get_wp_widget_form( $request ) {
|
||||
if ( empty( $request['widget_type'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $request['data'] ) ) {
|
||||
$request['data'] = [];
|
||||
}
|
||||
|
||||
$element_data = [
|
||||
'id' => $request['id'],
|
||||
'elType' => 'widget',
|
||||
'widgetType' => $request['widget_type'],
|
||||
'settings' => $request['data'],
|
||||
];
|
||||
|
||||
/**
|
||||
* @var $widget_obj Widget_WordPress
|
||||
*/
|
||||
$widget_obj = Plugin::$instance->elements_manager->create_element_instance( $element_data );
|
||||
|
||||
if ( ! $widget_obj ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $widget_obj->get_form();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render widgets content.
|
||||
*
|
||||
* Used to generate the widget templates on the editor using Underscore JS
|
||||
* template, for all the registered widget types.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function render_widgets_content() {
|
||||
foreach ( $this->get_widget_types() as $widget ) {
|
||||
$widget->print_template();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get widgets frontend settings keys.
|
||||
*
|
||||
* Retrieve frontend controls settings keys for all the registered widget
|
||||
* types.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Registered widget types with settings keys for each widget.
|
||||
*/
|
||||
public function get_widgets_frontend_settings_keys() {
|
||||
$keys = [];
|
||||
|
||||
foreach ( $this->get_widget_types() as $widget_type_name => $widget_type ) {
|
||||
$widget_type_keys = $widget_type->get_frontend_settings_keys();
|
||||
|
||||
if ( $widget_type_keys ) {
|
||||
$keys[ $widget_type_name ] = $widget_type_keys;
|
||||
}
|
||||
}
|
||||
|
||||
return $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue widgets scripts.
|
||||
*
|
||||
* Enqueue all the scripts defined as a dependency for each widget.
|
||||
*
|
||||
* @since 1.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue_widgets_scripts() {
|
||||
foreach ( $this->get_widget_types() as $widget ) {
|
||||
$widget->enqueue_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue widgets styles
|
||||
*
|
||||
* Enqueue all the styles defined as a dependency for each widget
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public function enqueue_widgets_styles() {
|
||||
foreach ( $this->get_widget_types() as $widget ) {
|
||||
$widget->enqueue_styles();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve inline editing configuration.
|
||||
*
|
||||
* Returns general inline editing configurations like toolbar types etc.
|
||||
*
|
||||
* @access public
|
||||
* @since 1.8.0
|
||||
*
|
||||
* @return array {
|
||||
* Inline editing configuration.
|
||||
*
|
||||
* @type array $toolbar {
|
||||
* Toolbar types and the actions each toolbar includes.
|
||||
* Note: Wysiwyg controls uses the advanced toolbar, textarea controls
|
||||
* uses the basic toolbar and text controls has no toolbar.
|
||||
*
|
||||
* @type array $basic Basic actions included in the edit tool.
|
||||
* @type array $advanced Advanced actions included in the edit tool.
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
public function get_inline_editing_config() {
|
||||
$basic_tools = [
|
||||
'bold',
|
||||
'underline',
|
||||
'italic',
|
||||
];
|
||||
|
||||
$advanced_tools = array_merge( $basic_tools, [
|
||||
'createlink',
|
||||
'unlink',
|
||||
'h1' => [
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'p',
|
||||
'blockquote',
|
||||
'pre',
|
||||
],
|
||||
'list' => [
|
||||
'insertOrderedList',
|
||||
'insertUnorderedList',
|
||||
],
|
||||
] );
|
||||
|
||||
return [
|
||||
'toolbar' => [
|
||||
'basic' => $basic_tools,
|
||||
'advanced' => $advanced_tools,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Widgets manager constructor.
|
||||
*
|
||||
* Initializing Elementor widgets manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->require_files();
|
||||
|
||||
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register ajax actions.
|
||||
*
|
||||
* Add new actions to handle data after an ajax requests returned.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param Ajax $ajax_manager
|
||||
*/
|
||||
public function register_ajax_actions( Ajax $ajax_manager ) {
|
||||
$ajax_manager->register_ajax_action( 'render_widget', [ $this, 'ajax_render_widget' ] );
|
||||
$ajax_manager->register_ajax_action( 'editor_get_wp_widget_form', [ $this, 'ajax_get_wp_widget_form' ] );
|
||||
$ajax_manager->register_ajax_action( 'get_widgets_config', [ $this, 'ajax_get_widget_types_controls_config' ] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor WordPress widgets manager.
|
||||
*
|
||||
* Elementor WordPress widgets manager handler class is responsible for
|
||||
* registering and initializing all the supported controls, both regular
|
||||
* controls and the group controls.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class WordPress_Widgets_Manager {
|
||||
|
||||
/**
|
||||
* WordPress widgets manager constructor.
|
||||
*
|
||||
* Initializing the WordPress widgets manager in Elementor editor.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( version_compare( get_bloginfo( 'version' ), '4.8', '<' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'before_enqueue_scripts' ] );
|
||||
add_action( 'elementor/editor/footer', [ $this, 'footer' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Before enqueue scripts.
|
||||
*
|
||||
* Prints custom scripts required to run WordPress widgets in Elementor
|
||||
* editor.
|
||||
*
|
||||
* Fired by `elementor/editor/before_enqueue_scripts` action.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function before_enqueue_scripts() {
|
||||
global $wp_scripts;
|
||||
|
||||
$suffix = Utils::is_script_debug() ? '' : '.min';
|
||||
|
||||
// TODO: after WP >= 4.9 - it's no needed, Keep for Backward compatibility.
|
||||
$wp_scripts->add( 'media-widgets', "/wp-admin/js/widgets/media-widgets$suffix.js", array( 'jquery', 'media-models', 'media-views' ) );
|
||||
$wp_scripts->add_inline_script( 'media-widgets', 'wp.mediaWidgets.init();', 'after' );
|
||||
|
||||
$wp_scripts->add( 'media-audio-widget', "/wp-admin/js/widgets/media-audio-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) );
|
||||
$wp_scripts->add( 'media-image-widget', "/wp-admin/js/widgets/media-image-widget$suffix.js", array( 'media-widgets' ) );
|
||||
$wp_scripts->add( 'media-video-widget', "/wp-admin/js/widgets/media-video-widget$suffix.js", array( 'media-widgets', 'media-audiovideo' ) );
|
||||
$wp_scripts->add( 'text-widgets', "/wp-admin/js/widgets/text-widgets$suffix.js", array( 'jquery', 'editor', 'wp-util' ) );
|
||||
$wp_scripts->add_inline_script( 'text-widgets', 'wp.textWidgets.init();', 'after' );
|
||||
|
||||
wp_enqueue_style( 'widgets' );
|
||||
wp_enqueue_style( 'media-views' );
|
||||
// End TODO.
|
||||
|
||||
// Don't enqueue `code-editor` for WP Custom HTML widget.
|
||||
wp_get_current_user()->syntax_highlighting = 'false';
|
||||
|
||||
/** This action is documented in wp-admin/admin-header.php */
|
||||
do_action( 'admin_print_scripts-widgets.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
* WordPress widgets footer.
|
||||
*
|
||||
* Prints WordPress widgets scripts in Elementor editor footer.
|
||||
*
|
||||
* Fired by `elementor/editor/footer` action.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function footer() {
|
||||
/** This action is documented in wp-admin/admin-footer.php */
|
||||
do_action( 'admin_footer-widgets.php' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,726 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Admin\Admin;
|
||||
use Elementor\Core\Common\Modules\Ajax\Module as Ajax;
|
||||
use Elementor\Core\Common\App as CommonApp;
|
||||
use Elementor\Core\Debug\Inspector;
|
||||
use Elementor\Core\Documents_Manager;
|
||||
use Elementor\Core\Kits\Manager as Kits_Manager;
|
||||
use Elementor\Core\Editor\Editor;
|
||||
use Elementor\Core\Files\Manager as Files_Manager;
|
||||
use Elementor\Core\Files\Assets\Manager as Assets_Manager;
|
||||
use Elementor\Core\Modules_Manager;
|
||||
use Elementor\Core\Schemes\Manager as Schemes_Manager;
|
||||
use Elementor\Core\Settings\Manager as Settings_Manager;
|
||||
use Elementor\Core\Settings\Page\Manager as Page_Settings_Manager;
|
||||
use Elementor\Core\Upgrade\Elementor_3_Re_Migrate_Globals;
|
||||
use Elementor\Core\Upgrade\Manager as Upgrades_Manager;
|
||||
use Elementor\Modules\History\Revisions_Manager;
|
||||
use Elementor\Core\DynamicTags\Manager as Dynamic_Tags_Manager;
|
||||
use Elementor\Core\Logger\Manager as Log_Manager;
|
||||
use Elementor\Modules\System_Info\Module as System_Info_Module;
|
||||
use Elementor\Data\Manager as Data_Manager;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor plugin.
|
||||
*
|
||||
* The main plugin handler class is responsible for initializing Elementor. The
|
||||
* class registers and all the components required to run the plugin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Plugin {
|
||||
|
||||
/**
|
||||
* Instance.
|
||||
*
|
||||
* Holds the plugin instance.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @var Plugin
|
||||
*/
|
||||
public static $instance = null;
|
||||
|
||||
/**
|
||||
* Database.
|
||||
*
|
||||
* Holds the plugin database.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var DB
|
||||
*/
|
||||
public $db;
|
||||
|
||||
/**
|
||||
* Ajax Manager.
|
||||
*
|
||||
* Holds the plugin ajax manager.
|
||||
*
|
||||
* @since 1.9.0
|
||||
* @deprecated 2.3.0 Use `Plugin::$instance->common->get_component( 'ajax' )` instead
|
||||
* @access public
|
||||
*
|
||||
* @var Ajax
|
||||
*/
|
||||
public $ajax;
|
||||
|
||||
/**
|
||||
* Controls manager.
|
||||
*
|
||||
* Holds the plugin controls manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Controls_Manager
|
||||
*/
|
||||
public $controls_manager;
|
||||
|
||||
/**
|
||||
* Documents manager.
|
||||
*
|
||||
* Holds the documents manager.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Documents_Manager
|
||||
*/
|
||||
public $documents;
|
||||
|
||||
/**
|
||||
* Schemes manager.
|
||||
*
|
||||
* Holds the plugin schemes manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Schemes_Manager
|
||||
*/
|
||||
public $schemes_manager;
|
||||
|
||||
/**
|
||||
* Elements manager.
|
||||
*
|
||||
* Holds the plugin elements manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Elements_Manager
|
||||
*/
|
||||
public $elements_manager;
|
||||
|
||||
/**
|
||||
* Widgets manager.
|
||||
*
|
||||
* Holds the plugin widgets manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Widgets_Manager
|
||||
*/
|
||||
public $widgets_manager;
|
||||
|
||||
/**
|
||||
* Revisions manager.
|
||||
*
|
||||
* Holds the plugin revisions manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Revisions_Manager
|
||||
*/
|
||||
public $revisions_manager;
|
||||
|
||||
/**
|
||||
* Images manager.
|
||||
*
|
||||
* Holds the plugin images manager.
|
||||
*
|
||||
* @since 2.9.0
|
||||
* @access public
|
||||
*
|
||||
* @var Images_Manager
|
||||
*/
|
||||
public $images_manager;
|
||||
|
||||
/**
|
||||
* Maintenance mode.
|
||||
*
|
||||
* Holds the plugin maintenance mode.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Maintenance_Mode
|
||||
*/
|
||||
public $maintenance_mode;
|
||||
|
||||
/**
|
||||
* Page settings manager.
|
||||
*
|
||||
* Holds the page settings manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Page_Settings_Manager
|
||||
*/
|
||||
public $page_settings_manager;
|
||||
|
||||
/**
|
||||
* Dynamic tags manager.
|
||||
*
|
||||
* Holds the dynamic tags manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Dynamic_Tags_Manager
|
||||
*/
|
||||
public $dynamic_tags;
|
||||
|
||||
/**
|
||||
* Settings.
|
||||
*
|
||||
* Holds the plugin settings.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Settings
|
||||
*/
|
||||
public $settings;
|
||||
|
||||
/**
|
||||
* Role Manager.
|
||||
*
|
||||
* Holds the plugin Role Manager
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var \Elementor\Core\RoleManager\Role_Manager
|
||||
*/
|
||||
public $role_manager;
|
||||
|
||||
/**
|
||||
* Admin.
|
||||
*
|
||||
* Holds the plugin admin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Admin
|
||||
*/
|
||||
public $admin;
|
||||
|
||||
/**
|
||||
* Tools.
|
||||
*
|
||||
* Holds the plugin tools.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Tools
|
||||
*/
|
||||
public $tools;
|
||||
|
||||
/**
|
||||
* Preview.
|
||||
*
|
||||
* Holds the plugin preview.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Preview
|
||||
*/
|
||||
public $preview;
|
||||
|
||||
/**
|
||||
* Editor.
|
||||
*
|
||||
* Holds the plugin editor.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Editor
|
||||
*/
|
||||
public $editor;
|
||||
|
||||
/**
|
||||
* Frontend.
|
||||
*
|
||||
* Holds the plugin frontend.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Frontend
|
||||
*/
|
||||
public $frontend;
|
||||
|
||||
/**
|
||||
* Heartbeat.
|
||||
*
|
||||
* Holds the plugin heartbeat.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Heartbeat
|
||||
*/
|
||||
public $heartbeat;
|
||||
|
||||
/**
|
||||
* System info.
|
||||
*
|
||||
* Holds the system info data.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var System_Info\Main
|
||||
*/
|
||||
public $system_info;
|
||||
|
||||
/**
|
||||
* Template library manager.
|
||||
*
|
||||
* Holds the template library manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var TemplateLibrary\Manager
|
||||
*/
|
||||
public $templates_manager;
|
||||
|
||||
/**
|
||||
* Skins manager.
|
||||
*
|
||||
* Holds the skins manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Skins_Manager
|
||||
*/
|
||||
public $skins_manager;
|
||||
|
||||
/**
|
||||
* Files Manager.
|
||||
*
|
||||
* Holds the files manager.
|
||||
*
|
||||
* @since 2.1.0
|
||||
* @access public
|
||||
*
|
||||
* @var Files_Manager
|
||||
*/
|
||||
public $files_manager;
|
||||
|
||||
/**
|
||||
* Assets Manager.
|
||||
*
|
||||
* Holds the Assets manager.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
*
|
||||
* @var Assets_Manager
|
||||
*/
|
||||
public $assets_manager;
|
||||
|
||||
/**
|
||||
* Files Manager.
|
||||
*
|
||||
* Holds the files manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @deprecated 2.1.0 Use `Plugin::$files_manager` instead
|
||||
*
|
||||
* @var Files_Manager
|
||||
*/
|
||||
public $posts_css_manager;
|
||||
|
||||
/**
|
||||
* WordPress widgets manager.
|
||||
*
|
||||
* Holds the WordPress widgets manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var WordPress_Widgets_Manager
|
||||
*/
|
||||
public $wordpress_widgets_manager;
|
||||
|
||||
/**
|
||||
* Modules manager.
|
||||
*
|
||||
* Holds the modules manager.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Modules_Manager
|
||||
*/
|
||||
public $modules_manager;
|
||||
|
||||
/**
|
||||
* Beta testers.
|
||||
*
|
||||
* Holds the plugin beta testers.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @var Beta_Testers
|
||||
*/
|
||||
public $beta_testers;
|
||||
|
||||
/**
|
||||
* @var Inspector
|
||||
* @deprecated 2.1.2 Use $inspector.
|
||||
*/
|
||||
public $debugger;
|
||||
|
||||
/**
|
||||
* @var Inspector
|
||||
*/
|
||||
public $inspector;
|
||||
|
||||
/**
|
||||
* @var CommonApp
|
||||
*/
|
||||
public $common;
|
||||
|
||||
/**
|
||||
* @var Log_Manager
|
||||
*/
|
||||
public $logger;
|
||||
|
||||
/**
|
||||
* @var Core\Upgrade\Manager
|
||||
*/
|
||||
public $upgrade;
|
||||
|
||||
/**
|
||||
* @var Core\Kits\Manager
|
||||
*/
|
||||
public $kits_manager;
|
||||
|
||||
/**
|
||||
* @var \Core\Data\Manager
|
||||
*/
|
||||
public $data_manager;
|
||||
|
||||
public $legacy_mode;
|
||||
|
||||
/**
|
||||
* @var Core\App\App
|
||||
*/
|
||||
public $app;
|
||||
|
||||
/**
|
||||
* Clone.
|
||||
*
|
||||
* Disable class cloning and throw an error on object clone.
|
||||
*
|
||||
* The whole idea of the singleton design pattern is that there is a single
|
||||
* object. Therefore, we don't want the object to be cloned.
|
||||
*
|
||||
* @access public
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function __clone() {
|
||||
// Cloning instances of the class is forbidden.
|
||||
_doing_it_wrong( __FUNCTION__, esc_html__( 'Something went wrong.', 'elementor' ), '1.0.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Wakeup.
|
||||
*
|
||||
* Disable unserializing of the class.
|
||||
*
|
||||
* @access public
|
||||
* @since 1.0.0
|
||||
*/
|
||||
public function __wakeup() {
|
||||
// Unserializing instances of the class is forbidden.
|
||||
_doing_it_wrong( __FUNCTION__, esc_html__( 'Something went wrong.', 'elementor' ), '1.0.0' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Instance.
|
||||
*
|
||||
* Ensures only one instance of the plugin class is loaded or can be loaded.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return Plugin An instance of the class.
|
||||
*/
|
||||
public static function instance() {
|
||||
if ( is_null( self::$instance ) ) {
|
||||
self::$instance = new self();
|
||||
|
||||
/**
|
||||
* Elementor loaded.
|
||||
*
|
||||
* Fires when Elementor was fully loaded and instantiated.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
do_action( 'elementor/loaded' );
|
||||
}
|
||||
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor Plugin. Register Elementor support for all the
|
||||
* supported post types and initialize Elementor components.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
$this->add_cpt_support();
|
||||
|
||||
$this->init_components();
|
||||
|
||||
/**
|
||||
* Elementor init.
|
||||
*
|
||||
* Fires on Elementor init, after Elementor has finished loading but
|
||||
* before any headers are sent.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
do_action( 'elementor/init' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get install time.
|
||||
*
|
||||
* Retrieve the time when Elementor was installed.
|
||||
*
|
||||
* @since 2.6.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return int Unix timestamp when Elementor was installed.
|
||||
*/
|
||||
public function get_install_time() {
|
||||
$installed_time = get_option( '_elementor_installed_time' );
|
||||
|
||||
if ( ! $installed_time ) {
|
||||
$installed_time = time();
|
||||
|
||||
update_option( '_elementor_installed_time', $installed_time );
|
||||
}
|
||||
|
||||
return $installed_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function on_rest_api_init() {
|
||||
// On admin/frontend sometimes the rest API is initialized after the common is initialized.
|
||||
if ( ! $this->common ) {
|
||||
$this->init_common();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init components.
|
||||
*
|
||||
* Initialize Elementor components. Register actions, run setting manager,
|
||||
* initialize all the components that run elementor, and if in admin page
|
||||
* initialize admin components.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function init_components() {
|
||||
$this->inspector = new Inspector();
|
||||
$this->debugger = $this->inspector;
|
||||
|
||||
Settings_Manager::run();
|
||||
|
||||
$this->db = new DB();
|
||||
$this->controls_manager = new Controls_Manager();
|
||||
$this->documents = new Documents_Manager();
|
||||
$this->kits_manager = new Kits_Manager();
|
||||
$this->schemes_manager = new Schemes_Manager();
|
||||
$this->elements_manager = new Elements_Manager();
|
||||
$this->widgets_manager = new Widgets_Manager();
|
||||
$this->skins_manager = new Skins_Manager();
|
||||
$this->files_manager = new Files_Manager();
|
||||
$this->assets_manager = new Assets_Manager();
|
||||
$this->icons_manager = new Icons_Manager();
|
||||
/*
|
||||
* @TODO: Remove deprecated alias
|
||||
*/
|
||||
$this->posts_css_manager = $this->files_manager;
|
||||
$this->settings = new Settings();
|
||||
$this->tools = new Tools();
|
||||
$this->editor = new Editor();
|
||||
$this->preview = new Preview();
|
||||
$this->frontend = new Frontend();
|
||||
$this->templates_manager = new TemplateLibrary\Manager();
|
||||
$this->maintenance_mode = new Maintenance_Mode();
|
||||
$this->dynamic_tags = new Dynamic_Tags_Manager();
|
||||
$this->modules_manager = new Modules_Manager();
|
||||
$this->role_manager = new Core\RoleManager\Role_Manager();
|
||||
$this->system_info = new System_Info_Module();
|
||||
$this->revisions_manager = new Revisions_Manager();
|
||||
$this->images_manager = new Images_Manager();
|
||||
|
||||
User::init();
|
||||
Api::init();
|
||||
Tracker::init();
|
||||
|
||||
$this->upgrade = new Core\Upgrade\Manager();
|
||||
|
||||
$this->app = new Core\App\App();
|
||||
|
||||
if ( is_admin() ) {
|
||||
$this->heartbeat = new Heartbeat();
|
||||
$this->wordpress_widgets_manager = new WordPress_Widgets_Manager();
|
||||
$this->admin = new Admin();
|
||||
$this->beta_testers = new Beta_Testers();
|
||||
new Elementor_3_Re_Migrate_Globals();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.3.0
|
||||
* @access public
|
||||
*/
|
||||
public function init_common() {
|
||||
$this->common = new CommonApp();
|
||||
|
||||
$this->common->init_components();
|
||||
|
||||
$this->ajax = $this->common->get_component( 'ajax' );
|
||||
}
|
||||
|
||||
public function get_legacy_mode( $mode_name = null ) {
|
||||
if ( ! $this->legacy_mode ) {
|
||||
$optimized_dom_output = get_option( 'elementor_optimized_dom_output' );
|
||||
|
||||
if ( $optimized_dom_output ) {
|
||||
$element_wrappers_legacy_mode = 'disabled' === $optimized_dom_output;
|
||||
} else {
|
||||
$element_wrappers_legacy_mode = true;
|
||||
}
|
||||
|
||||
$this->legacy_mode = [
|
||||
'elementWrappers' => $element_wrappers_legacy_mode,
|
||||
];
|
||||
}
|
||||
|
||||
if ( ! $mode_name ) {
|
||||
return $this->legacy_mode;
|
||||
}
|
||||
|
||||
if ( isset( $this->legacy_mode[ $mode_name ] ) ) {
|
||||
return $this->legacy_mode[ $mode_name ];
|
||||
}
|
||||
|
||||
// If there is no legacy mode with the given mode name;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add custom post type support.
|
||||
*
|
||||
* Register Elementor support for all the supported post types defined by
|
||||
* the user in the admin screen and saved as `elementor_cpt_support` option
|
||||
* in WordPress `$wpdb->options` table.
|
||||
*
|
||||
* If no custom post type selected, usually in new installs, this method
|
||||
* will return the two default post types: `page` and `post`.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function add_cpt_support() {
|
||||
$cpt_support = get_option( 'elementor_cpt_support', [ 'page', 'post' ] );
|
||||
|
||||
foreach ( $cpt_support as $cpt_slug ) {
|
||||
add_post_type_support( $cpt_slug, 'elementor' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register autoloader.
|
||||
*
|
||||
* Elementor autoloader loads all the classes needed to run the plugin.
|
||||
*
|
||||
* @since 1.6.0
|
||||
* @access private
|
||||
*/
|
||||
private function register_autoloader() {
|
||||
require_once ELEMENTOR_PATH . '/includes/autoloader.php';
|
||||
|
||||
Autoloader::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Plugin constructor.
|
||||
*
|
||||
* Initializing Elementor plugin.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function __construct() {
|
||||
$this->register_autoloader();
|
||||
|
||||
$this->logger = Log_Manager::instance();
|
||||
$this->data_manager = Data_Manager::instance();
|
||||
|
||||
Maintenance::init();
|
||||
Compatibility::register_actions();
|
||||
|
||||
add_action( 'init', [ $this, 'init' ], 0 );
|
||||
add_action( 'rest_api_init', [ $this, 'on_rest_api_init' ] );
|
||||
}
|
||||
|
||||
final public static function get_title() {
|
||||
return __( 'Elementor', 'elementor' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! defined( 'ELEMENTOR_TESTS' ) ) {
|
||||
// In tests we run the instance manually.
|
||||
Plugin::instance();
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Base\App;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor preview.
|
||||
*
|
||||
* Elementor preview handler class is responsible for initializing Elementor in
|
||||
* preview mode.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Preview extends App {
|
||||
|
||||
/**
|
||||
* Is Preview.
|
||||
*
|
||||
* Holds a flag if current request is a preview.
|
||||
* The flag is not related to a specific post or edit permissions.
|
||||
*
|
||||
* @since 2.9.5
|
||||
* @access private
|
||||
*
|
||||
* @var bool Is Preview.
|
||||
*/
|
||||
|
||||
private $is_preview;
|
||||
|
||||
/**
|
||||
* Post ID.
|
||||
*
|
||||
* Holds the ID of the current post being previewed.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*
|
||||
* @var int Post ID.
|
||||
*/
|
||||
private $post_id;
|
||||
|
||||
/**
|
||||
* Get module name.
|
||||
*
|
||||
* Retrieve the module name.
|
||||
*
|
||||
* @since 3.0.0
|
||||
* @access public
|
||||
* @abstract
|
||||
*
|
||||
* @return string Module name.
|
||||
*/
|
||||
public function get_name() {
|
||||
return 'preview';
|
||||
}
|
||||
|
||||
/**
|
||||
* Init.
|
||||
*
|
||||
* Initialize Elementor preview mode.
|
||||
*
|
||||
* Fired by `template_redirect` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function init() {
|
||||
if ( is_admin() || ! $this->is_preview_mode() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( isset( $_GET['preview-debug'] ) ) {
|
||||
register_shutdown_function( function () {
|
||||
$e = error_get_last();
|
||||
if ( $e ) {
|
||||
echo '<div id="elementor-preview-debug-error"><pre>';
|
||||
echo $e['message'];
|
||||
echo '</pre></div>';
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
$this->post_id = get_the_ID();
|
||||
$this->is_preview = true;
|
||||
|
||||
// Don't redirect to permalink.
|
||||
remove_action( 'template_redirect', 'redirect_canonical' );
|
||||
|
||||
// Compatibility with Yoast SEO plugin when 'Removes unneeded query variables from the URL' enabled.
|
||||
// TODO: Move this code to `includes/compatibility.php`.
|
||||
if ( class_exists( 'WPSEO_Frontend' ) ) {
|
||||
remove_action( 'template_redirect', [ \WPSEO_Frontend::get_instance(), 'clean_permalink' ], 1 );
|
||||
}
|
||||
|
||||
// Disable the WP admin bar in preview mode.
|
||||
add_filter( 'show_admin_bar', '__return_false' );
|
||||
|
||||
add_action( 'wp_enqueue_scripts', function() {
|
||||
$this->enqueue_styles();
|
||||
$this->enqueue_scripts();
|
||||
} );
|
||||
|
||||
add_filter( 'the_content', [ $this, 'builder_wrapper' ], 999999 );
|
||||
|
||||
add_action( 'wp_footer', [ $this, 'wp_footer' ] );
|
||||
|
||||
// Avoid Cloudflare's Rocket Loader lazy load the editor iframe
|
||||
add_filter( 'script_loader_tag', [ $this, 'rocket_loader_filter' ], 10, 3 );
|
||||
|
||||
// Tell to WP Cache plugins do not cache this request.
|
||||
Utils::do_not_cache();
|
||||
|
||||
/**
|
||||
* Preview init.
|
||||
*
|
||||
* Fires on Elementor preview init, after Elementor preview has finished
|
||||
* loading but before any headers are sent.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Preview $this The current preview.
|
||||
*/
|
||||
do_action( 'elementor/preview/init', $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve post ID.
|
||||
*
|
||||
* Get the ID of the current post.
|
||||
*
|
||||
* @since 1.8.0
|
||||
* @access public
|
||||
*
|
||||
* @return int Post ID.
|
||||
*/
|
||||
public function get_post_id() {
|
||||
return $this->post_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Preview.
|
||||
*
|
||||
* Whether current request is the elementor preview iframe.
|
||||
* The flag is not related to a specific post or edit permissions.
|
||||
*
|
||||
* @since 2.9.5
|
||||
* @access public
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_preview() {
|
||||
return $this->is_preview;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether preview mode is active.
|
||||
*
|
||||
* Used to determine whether we are in the preview mode (iframe).
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param int $post_id Optional. Post ID. Default is `0`.
|
||||
*
|
||||
* @return bool Whether preview mode is active.
|
||||
*/
|
||||
public function is_preview_mode( $post_id = 0 ) {
|
||||
if ( ! isset( $_GET['elementor-preview'] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( empty( $post_id ) ) {
|
||||
$post_id = get_the_ID();
|
||||
}
|
||||
|
||||
if ( ! User::is_current_user_can_edit( $post_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $post_id !== (int) $_GET['elementor-preview'] ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder wrapper.
|
||||
*
|
||||
* Used to add an empty HTML wrapper for the builder, the javascript will add
|
||||
* the content later.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $content The content of the builder.
|
||||
*
|
||||
* @return string HTML wrapper for the builder.
|
||||
*/
|
||||
public function builder_wrapper( $content ) {
|
||||
if ( get_the_ID() === $this->post_id ) {
|
||||
$document = Plugin::$instance->documents->get( $this->post_id );
|
||||
|
||||
$attributes = $document->get_container_attributes();
|
||||
|
||||
$content = '<div ' . Utils::render_html_attributes( $attributes ) . '></div>';
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue preview styles.
|
||||
*
|
||||
* Registers all the preview styles and enqueues them.
|
||||
*
|
||||
* Fired by `wp_enqueue_scripts` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access private
|
||||
*/
|
||||
private function enqueue_styles() {
|
||||
// Hold-on all jQuery plugins after all HTML markup render.
|
||||
wp_add_inline_script( 'jquery-migrate', 'jQuery.holdReady( true );' );
|
||||
|
||||
Plugin::$instance->frontend->enqueue_styles();
|
||||
|
||||
Plugin::$instance->widgets_manager->enqueue_widgets_styles();
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
$direction_suffix = is_rtl() ? '-rtl' : '';
|
||||
|
||||
wp_register_style(
|
||||
'elementor-select2',
|
||||
ELEMENTOR_ASSETS_URL . 'lib/e-select2/css/e-select2' . $suffix . '.css',
|
||||
[],
|
||||
'4.0.6-rc.1'
|
||||
);
|
||||
|
||||
wp_register_style(
|
||||
'editor-preview',
|
||||
ELEMENTOR_ASSETS_URL . 'css/editor-preview' . $direction_suffix . $suffix . '.css',
|
||||
[
|
||||
'elementor-select2',
|
||||
],
|
||||
ELEMENTOR_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_style( 'editor-preview' );
|
||||
|
||||
if ( Plugin::instance()->get_legacy_mode( 'elementWrappers' ) ) {
|
||||
wp_register_style(
|
||||
'editor-preview-legacy',
|
||||
ELEMENTOR_ASSETS_URL . 'css/editor-preview-legacy' . $direction_suffix . $suffix . '.css',
|
||||
[],
|
||||
ELEMENTOR_VERSION
|
||||
);
|
||||
|
||||
wp_enqueue_style( 'editor-preview-legacy' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview enqueue styles.
|
||||
*
|
||||
* Fires after Elementor preview styles are enqueued.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
do_action( 'elementor/preview/enqueue_styles' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue preview scripts.
|
||||
*
|
||||
* Registers all the preview scripts and enqueues them.
|
||||
*
|
||||
* Fired by `wp_enqueue_scripts` action.
|
||||
*
|
||||
* @since 1.5.4
|
||||
* @access private
|
||||
*/
|
||||
private function enqueue_scripts() {
|
||||
Plugin::$instance->frontend->register_scripts();
|
||||
|
||||
Plugin::$instance->widgets_manager->enqueue_widgets_scripts();
|
||||
|
||||
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
|
||||
|
||||
wp_enqueue_script(
|
||||
'elementor-inline-editor',
|
||||
ELEMENTOR_ASSETS_URL . 'lib/inline-editor/js/inline-editor' . $suffix . '.js',
|
||||
[],
|
||||
ELEMENTOR_VERSION,
|
||||
true
|
||||
);
|
||||
|
||||
/**
|
||||
* Preview enqueue scripts.
|
||||
*
|
||||
* Fires after Elementor preview scripts are enqueued.
|
||||
*
|
||||
* @since 1.5.4
|
||||
*/
|
||||
do_action( 'elementor/preview/enqueue_scripts' );
|
||||
}
|
||||
|
||||
public function rocket_loader_filter( $tag, $handle, $src ) {
|
||||
return str_replace( '<script', '<script data-cfasync="false"', $tag );
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor Preview footer scripts and styles.
|
||||
*
|
||||
* Handle styles and scripts from frontend.
|
||||
*
|
||||
* Fired by `wp_footer` action.
|
||||
*
|
||||
* @since 2.0.9
|
||||
* @access public
|
||||
*/
|
||||
public function wp_footer() {
|
||||
$frontend = Plugin::$instance->frontend;
|
||||
if ( $frontend->has_elementor_in_page() ) {
|
||||
// Has header/footer/widget-template - enqueue all style/scripts/fonts.
|
||||
$frontend->wp_footer();
|
||||
} else {
|
||||
// Enqueue only scripts.
|
||||
$frontend->enqueue_scripts();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preview constructor.
|
||||
*
|
||||
* Initializing Elementor preview.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'template_redirect', [ $this, 'init' ], 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor rollback.
|
||||
*
|
||||
* Elementor rollback handler class is responsible for rolling back Elementor to
|
||||
* previous version.
|
||||
*
|
||||
* @since 1.5.0
|
||||
*/
|
||||
class Rollback {
|
||||
|
||||
/**
|
||||
* Package URL.
|
||||
*
|
||||
* Holds the package URL.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @var string Package URL.
|
||||
*/
|
||||
protected $package_url;
|
||||
|
||||
/**
|
||||
* Version.
|
||||
*
|
||||
* Holds the version.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @var string Package URL.
|
||||
*/
|
||||
protected $version;
|
||||
|
||||
/**
|
||||
* Plugin name.
|
||||
*
|
||||
* Holds the plugin name.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @var string Plugin name.
|
||||
*/
|
||||
protected $plugin_name;
|
||||
|
||||
/**
|
||||
* Plugin slug.
|
||||
*
|
||||
* Holds the plugin slug.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @var string Plugin slug.
|
||||
*/
|
||||
protected $plugin_slug;
|
||||
|
||||
/**
|
||||
* Rollback constructor.
|
||||
*
|
||||
* Initializing Elementor rollback.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param array $args Optional. Rollback arguments. Default is an empty array.
|
||||
*/
|
||||
public function __construct( $args = [] ) {
|
||||
foreach ( $args as $key => $value ) {
|
||||
$this->{$key} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print inline style.
|
||||
*
|
||||
* Add an inline CSS to the rollback page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
*/
|
||||
private function print_inline_style() {
|
||||
?>
|
||||
<style>
|
||||
.wrap {
|
||||
overflow: hidden;
|
||||
max-width: 850px;
|
||||
margin: auto;
|
||||
font-family: Courier, monospace;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background: #D30C5C;
|
||||
text-align: center;
|
||||
color: #fff !important;
|
||||
padding: 70px !important;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
|
||||
h1 img {
|
||||
max-width: 300px;
|
||||
display: block;
|
||||
margin: auto auto 50px;
|
||||
}
|
||||
</style>
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply package.
|
||||
*
|
||||
* Change the plugin data when WordPress checks for updates. This method
|
||||
* modifies package data to update the plugin from a specific URL containing
|
||||
* the version package.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function apply_package() {
|
||||
$update_plugins = get_site_transient( 'update_plugins' );
|
||||
if ( ! is_object( $update_plugins ) ) {
|
||||
$update_plugins = new \stdClass();
|
||||
}
|
||||
|
||||
$plugin_info = new \stdClass();
|
||||
$plugin_info->new_version = $this->version;
|
||||
$plugin_info->slug = $this->plugin_slug;
|
||||
$plugin_info->package = $this->package_url;
|
||||
$plugin_info->url = 'https://elementor.com/';
|
||||
|
||||
$update_plugins->response[ $this->plugin_name ] = $plugin_info;
|
||||
|
||||
// Remove handle beta testers.
|
||||
remove_filter( 'pre_set_site_transient_update_plugins', [ Plugin::instance()->beta_testers, 'check_version' ] );
|
||||
|
||||
set_site_transient( 'update_plugins', $update_plugins );
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade.
|
||||
*
|
||||
* Run WordPress upgrade to rollback Elementor to previous version.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*/
|
||||
protected function upgrade() {
|
||||
require_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
|
||||
|
||||
$logo_url = ELEMENTOR_ASSETS_URL . 'images/logo-panel.svg';
|
||||
|
||||
$upgrader_args = [
|
||||
'url' => 'update.php?action=upgrade-plugin&plugin=' . rawurlencode( $this->plugin_name ),
|
||||
'plugin' => $this->plugin_name,
|
||||
'nonce' => 'upgrade-plugin_' . $this->plugin_name,
|
||||
'title' => '<img src="' . $logo_url . '" alt="Elementor">' . __( 'Rollback to Previous Version', 'elementor' ),
|
||||
];
|
||||
|
||||
$this->print_inline_style();
|
||||
|
||||
$upgrader = new \Plugin_Upgrader( new \Plugin_Upgrader_Skin( $upgrader_args ) );
|
||||
$upgrader->upgrade( $this->plugin_name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run.
|
||||
*
|
||||
* Rollback Elementor to previous versions.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function run() {
|
||||
$this->apply_package();
|
||||
$this->upgrade();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,283 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor settings controls.
|
||||
*
|
||||
* Elementor settings controls handler class responsible for creating the final
|
||||
* HTML for various input field types used in Elementor settings pages.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Settings_Controls {
|
||||
|
||||
/**
|
||||
* Render settings control.
|
||||
*
|
||||
* Generates the final HTML on the frontend for any given field based on
|
||||
* the field type (text, select, checkbox, raw HTML, etc.).
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @param array $field Optional. Field data. Default is an empty array.
|
||||
*/
|
||||
public static function render( $field = [] ) {
|
||||
if ( empty( $field ) || empty( $field['id'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$defaults = [
|
||||
'type' => '',
|
||||
'attributes' => [],
|
||||
'std' => '',
|
||||
'desc' => '',
|
||||
];
|
||||
|
||||
$field = array_merge( $defaults, $field );
|
||||
|
||||
$method_name = $field['type'];
|
||||
|
||||
if ( ! method_exists( __CLASS__, $method_name ) ) {
|
||||
$method_name = 'text';
|
||||
}
|
||||
|
||||
self::$method_name( $field );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render text control.
|
||||
*
|
||||
* Generates the final HTML for text controls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function text( array $field ) {
|
||||
if ( empty( $field['attributes']['class'] ) ) {
|
||||
$field['attributes']['class'] = 'regular-text';
|
||||
}
|
||||
|
||||
$attributes = Utils::render_html_attributes( $field['attributes'] );
|
||||
?>
|
||||
<input type="<?php echo esc_attr( $field['type'] ); ?>" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['id'] ); ?>" value="<?php echo esc_attr( get_option( $field['id'], $field['std'] ) ); ?>" <?php echo $attributes; ?>/>
|
||||
<?php
|
||||
if ( ! empty( $field['sub_desc'] ) ) :
|
||||
echo $field['sub_desc'];
|
||||
endif;
|
||||
?>
|
||||
<?php if ( ! empty( $field['desc'] ) ) : ?>
|
||||
<p class="description"><?php echo $field['desc']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render checkbox control.
|
||||
*
|
||||
* Generates the final HTML for checkbox controls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function checkbox( array $field ) {
|
||||
?>
|
||||
<label>
|
||||
<input type="<?php echo esc_attr( $field['type'] ); ?>" id="<?php echo esc_attr( $field['id'] ); ?>" name="<?php echo esc_attr( $field['id'] ); ?>" value="<?php echo $field['value']; ?>"<?php checked( $field['value'], get_option( $field['id'], $field['std'] ) ); ?> />
|
||||
<?php
|
||||
if ( ! empty( $field['sub_desc'] ) ) :
|
||||
echo $field['sub_desc'];
|
||||
endif;
|
||||
?>
|
||||
</label>
|
||||
<?php if ( ! empty( $field['desc'] ) ) : ?>
|
||||
<p class="description"><?php echo $field['desc']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render checkbox list control.
|
||||
*
|
||||
* Generates the final HTML for checkbox list controls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function checkbox_list( array $field ) {
|
||||
$old_value = get_option( $field['id'], $field['std'] );
|
||||
if ( ! is_array( $old_value ) ) {
|
||||
$old_value = [];
|
||||
}
|
||||
|
||||
foreach ( $field['options'] as $option_key => $option_value ) :
|
||||
?>
|
||||
<label>
|
||||
<input type="checkbox" name="<?php echo esc_attr( $field['id'] ); ?>[]" value="<?php echo esc_attr( $option_key ); ?>"<?php checked( in_array( $option_key, $old_value ), true ); ?> />
|
||||
<?php echo $option_value; ?>
|
||||
</label><br />
|
||||
<?php endforeach; ?>
|
||||
<?php if ( ! empty( $field['desc'] ) ) : ?>
|
||||
<p class="description"><?php echo $field['desc']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render select control.
|
||||
*
|
||||
* Generates the final HTML for select controls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function select( array $field ) {
|
||||
$old_value = get_option( $field['id'], $field['std'] );
|
||||
?>
|
||||
<select name="<?php echo esc_attr( $field['id'] ); ?>">
|
||||
<?php if ( ! empty( $field['show_select'] ) ) : ?>
|
||||
<option value="">— <?php echo __( 'Select', 'elementor' ); ?> —</option>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php foreach ( $field['options'] as $value => $label ) : ?>
|
||||
<option value="<?php echo esc_attr( $value ); ?>"<?php selected( $value, $old_value ); ?>><?php echo $label; ?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
|
||||
<?php if ( ! empty( $field['desc'] ) ) : ?>
|
||||
<p class="description"><?php echo $field['desc']; ?></p>
|
||||
<?php
|
||||
endif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render checkbox list control for CPT.
|
||||
*
|
||||
* Generates the final HTML for checkbox list controls populated with Custom Post Types.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function checkbox_list_cpt( array $field ) {
|
||||
$defaults = [
|
||||
'exclude' => [],
|
||||
];
|
||||
$field = array_merge( $defaults, $field );
|
||||
|
||||
$post_types_objects = get_post_types(
|
||||
[
|
||||
'public' => true,
|
||||
], 'objects'
|
||||
);
|
||||
|
||||
/**
|
||||
* Filters the list of post type objects used by Elementor.
|
||||
*
|
||||
* @since 2.8.0
|
||||
*
|
||||
* @param array $post_types_objects List of post type objects used by Elementor.
|
||||
*/
|
||||
$post_types_objects = apply_filters( 'elementor/settings/controls/checkbox_list_cpt/post_type_objects', $post_types_objects );
|
||||
|
||||
$field['options'] = [];
|
||||
foreach ( $post_types_objects as $cpt_slug => $post_type ) {
|
||||
if ( in_array( $cpt_slug, $field['exclude'], true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field['options'][ $cpt_slug ] = $post_type->labels->name;
|
||||
}
|
||||
|
||||
self::checkbox_list( $field );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render checkbox list control for user roles.
|
||||
*
|
||||
* Generates the final HTML for checkbox list controls populated with user roles.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function checkbox_list_roles( array $field ) {
|
||||
$defaults = [
|
||||
'exclude' => [],
|
||||
];
|
||||
$field = array_merge( $defaults, $field );
|
||||
|
||||
$field['options'] = [];
|
||||
$roles = get_editable_roles();
|
||||
|
||||
if ( is_multisite() ) {
|
||||
$roles = [
|
||||
'super_admin' => [
|
||||
'name' => __( 'Super Admin', 'elementor' ),
|
||||
],
|
||||
] + $roles;
|
||||
}
|
||||
|
||||
foreach ( $roles as $role_slug => $role_data ) {
|
||||
if ( in_array( $role_slug, $field['exclude'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$field['options'][ $role_slug ] = $role_data['name'];
|
||||
}
|
||||
|
||||
self::checkbox_list( $field );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render raw HTML control.
|
||||
*
|
||||
* Generates the final HTML for raw HTML controls.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access private
|
||||
* @static
|
||||
*
|
||||
* @param array $field Field data.
|
||||
*/
|
||||
private static function raw_html( array $field ) {
|
||||
if ( empty( $field['html'] ) ) {
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<div id="<?php echo $field['id']; ?>">
|
||||
|
||||
<div><?php echo $field['html']; ?></div>
|
||||
<?php
|
||||
if ( ! empty( $field['sub_desc'] ) ) :
|
||||
echo $field['sub_desc'];
|
||||
endif;
|
||||
?>
|
||||
<?php if ( ! empty( $field['desc'] ) ) : ?>
|
||||
<p class="description"><?php echo $field['desc']; ?></p>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,383 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor settings page.
|
||||
*
|
||||
* An abstract class that provides the needed properties and methods to handle
|
||||
* WordPress dashboard settings pages in inheriting classes.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @abstract
|
||||
*/
|
||||
abstract class Settings_Page {
|
||||
|
||||
/**
|
||||
* Settings page ID.
|
||||
*/
|
||||
const PAGE_ID = '';
|
||||
|
||||
/**
|
||||
* Tabs.
|
||||
*
|
||||
* Holds the settings page tabs, sections and fields.
|
||||
*
|
||||
* @access private
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $tabs;
|
||||
|
||||
/**
|
||||
* Create tabs.
|
||||
*
|
||||
* Return the settings page tabs, sections and fields.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function create_tabs();
|
||||
|
||||
/**
|
||||
* Get settings page title.
|
||||
*
|
||||
* Retrieve the title for the settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
* @abstract
|
||||
*/
|
||||
abstract protected function get_page_title();
|
||||
|
||||
/**
|
||||
* Get settings page URL.
|
||||
*
|
||||
* Retrieve the URL of the settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
* @static
|
||||
*
|
||||
* @return string Settings page URL.
|
||||
*/
|
||||
final public static function get_url() {
|
||||
return admin_url( 'admin.php?page=' . static::PAGE_ID );
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings page constructor.
|
||||
*
|
||||
* Initializing Elementor settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( ! empty( $_POST['option_page'] ) && static::PAGE_ID === $_POST['option_page'] ) {
|
||||
add_action( 'admin_init', [ $this, 'register_settings_fields' ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabs.
|
||||
*
|
||||
* Retrieve the settings page tabs, sections and fields.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @return array Settings page tabs, sections and fields.
|
||||
*/
|
||||
final public function get_tabs() {
|
||||
$this->ensure_tabs();
|
||||
|
||||
return $this->tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add tab.
|
||||
*
|
||||
* Register a new tab to a settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tab_id Tab ID.
|
||||
* @param array $tab_args Optional. Tab arguments. Default is an empty array.
|
||||
*/
|
||||
final public function add_tab( $tab_id, array $tab_args = [] ) {
|
||||
$this->ensure_tabs();
|
||||
|
||||
if ( isset( $this->tabs[ $tab_id ] ) ) {
|
||||
// Don't override an existing tab
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $tab_args['sections'] ) ) {
|
||||
$tab_args['sections'] = [];
|
||||
}
|
||||
|
||||
$this->tabs[ $tab_id ] = $tab_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add section.
|
||||
*
|
||||
* Register a new section to a tab.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tab_id Tab ID.
|
||||
* @param string $section_id Section ID.
|
||||
* @param array $section_args Optional. Section arguments. Default is an
|
||||
* empty array.
|
||||
*/
|
||||
final public function add_section( $tab_id, $section_id, array $section_args = [] ) {
|
||||
$this->ensure_tabs();
|
||||
|
||||
if ( ! isset( $this->tabs[ $tab_id ] ) ) {
|
||||
// If the requested tab doesn't exists, use the first tab
|
||||
$tab_id = key( $this->tabs );
|
||||
}
|
||||
|
||||
if ( isset( $this->tabs[ $tab_id ]['sections'][ $section_id ] ) ) {
|
||||
// Don't override an existing section
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! isset( $section_args['fields'] ) ) {
|
||||
$section_args['fields'] = [];
|
||||
}
|
||||
|
||||
$this->tabs[ $tab_id ]['sections'][ $section_id ] = $section_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add field.
|
||||
*
|
||||
* Register a new field to a section.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tab_id Tab ID.
|
||||
* @param string $section_id Section ID.
|
||||
* @param string $field_id Field ID.
|
||||
* @param array $field_args Field arguments.
|
||||
*/
|
||||
final public function add_field( $tab_id, $section_id, $field_id, array $field_args ) {
|
||||
$this->ensure_tabs();
|
||||
|
||||
if ( ! isset( $this->tabs[ $tab_id ] ) ) {
|
||||
// If the requested tab doesn't exists, use the first tab
|
||||
$tab_id = key( $this->tabs );
|
||||
}
|
||||
|
||||
if ( ! isset( $this->tabs[ $tab_id ]['sections'][ $section_id ] ) ) {
|
||||
// If the requested section doesn't exists, use the first section
|
||||
$section_id = key( $this->tabs[ $tab_id ]['sections'] );
|
||||
}
|
||||
|
||||
if ( isset( $this->tabs[ $tab_id ]['sections'][ $section_id ]['fields'][ $field_id ] ) ) {
|
||||
// Don't override an existing field
|
||||
return;
|
||||
}
|
||||
|
||||
$this->tabs[ $tab_id ]['sections'][ $section_id ]['fields'][ $field_id ] = $field_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add fields.
|
||||
*
|
||||
* Register multiple fields to a section.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*
|
||||
* @param string $tab_id Tab ID.
|
||||
* @param string $section_id Section ID.
|
||||
* @param array $fields {
|
||||
* An array of fields.
|
||||
*
|
||||
* @type string $field_id Field ID.
|
||||
* @type array $field_args Field arguments.
|
||||
* }
|
||||
*/
|
||||
final public function add_fields( $tab_id, $section_id, array $fields ) {
|
||||
foreach ( $fields as $field_id => $field_args ) {
|
||||
$this->add_field( $tab_id, $section_id, $field_id, $field_args );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register settings fields.
|
||||
*
|
||||
* In each tab register his inner sections, and in each section register his
|
||||
* inner fields.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
final public function register_settings_fields() {
|
||||
$controls_class_name = __NAMESPACE__ . '\Settings_Controls';
|
||||
|
||||
$tabs = $this->get_tabs();
|
||||
|
||||
foreach ( $tabs as $tab_id => $tab ) {
|
||||
|
||||
foreach ( $tab['sections'] as $section_id => $section ) {
|
||||
$full_section_id = 'elementor_' . $section_id . '_section';
|
||||
|
||||
$label = isset( $section['label'] ) ? $section['label'] : '';
|
||||
|
||||
$section_callback = isset( $section['callback'] ) ? $section['callback'] : '__return_empty_string';
|
||||
|
||||
add_settings_section( $full_section_id, $label, $section_callback, static::PAGE_ID );
|
||||
|
||||
foreach ( $section['fields'] as $field_id => $field ) {
|
||||
$full_field_id = ! empty( $field['full_field_id'] ) ? $field['full_field_id'] : 'elementor_' . $field_id;
|
||||
|
||||
$field['field_args']['id'] = $full_field_id;
|
||||
|
||||
$field_classes = [ $full_field_id ];
|
||||
|
||||
if ( ! empty( $field['class'] ) ) {
|
||||
$field_classes[] = $field['field_args']['class'];
|
||||
}
|
||||
|
||||
$field['field_args']['class'] = implode( ' ', $field_classes );
|
||||
|
||||
add_settings_field(
|
||||
$full_field_id,
|
||||
isset( $field['label'] ) ? $field['label'] : '',
|
||||
[ $controls_class_name, 'render' ],
|
||||
static::PAGE_ID,
|
||||
$full_section_id,
|
||||
$field['field_args']
|
||||
);
|
||||
|
||||
$setting_args = [];
|
||||
|
||||
if ( ! empty( $field['setting_args'] ) ) {
|
||||
$setting_args = $field['setting_args'];
|
||||
}
|
||||
|
||||
register_setting( static::PAGE_ID, $full_field_id, $setting_args );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display settings page.
|
||||
*
|
||||
* Output the content for the settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access public
|
||||
*/
|
||||
public function display_settings_page() {
|
||||
$this->register_settings_fields();
|
||||
|
||||
$tabs = $this->get_tabs();
|
||||
?>
|
||||
<div class="wrap">
|
||||
<h1><?php echo $this->get_page_title(); ?></h1>
|
||||
<div id="elementor-settings-tabs-wrapper" class="nav-tab-wrapper">
|
||||
<?php
|
||||
foreach ( $tabs as $tab_id => $tab ) {
|
||||
if ( empty( $tab['sections'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$active_class = '';
|
||||
|
||||
if ( 'general' === $tab_id ) {
|
||||
$active_class = ' nav-tab-active';
|
||||
}
|
||||
|
||||
echo "<a id='elementor-settings-tab-{$tab_id}' class='nav-tab{$active_class}' href='#tab-{$tab_id}'>{$tab['label']}</a>";
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<form id="elementor-settings-form" method="post" action="options.php">
|
||||
<?php
|
||||
settings_fields( static::PAGE_ID );
|
||||
|
||||
foreach ( $tabs as $tab_id => $tab ) {
|
||||
if ( empty( $tab['sections'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$active_class = '';
|
||||
|
||||
if ( 'general' === $tab_id ) {
|
||||
$active_class = ' elementor-active';
|
||||
}
|
||||
|
||||
echo "<div id='tab-{$tab_id}' class='elementor-settings-form-page{$active_class}'>";
|
||||
|
||||
foreach ( $tab['sections'] as $section_id => $section ) {
|
||||
$full_section_id = 'elementor_' . $section_id . '_section';
|
||||
|
||||
if ( ! empty( $section['label'] ) ) {
|
||||
echo "<h2>{$section['label']}</h2>";
|
||||
}
|
||||
|
||||
if ( ! empty( $section['callback'] ) ) {
|
||||
$section['callback']();
|
||||
}
|
||||
|
||||
echo '<table class="form-table">';
|
||||
|
||||
do_settings_fields( static::PAGE_ID, $full_section_id );
|
||||
|
||||
echo '</table>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
}
|
||||
|
||||
submit_button();
|
||||
?>
|
||||
</form>
|
||||
</div><!-- /.wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure tabs.
|
||||
*
|
||||
* Make sure the settings page has tabs before inserting any new sections or
|
||||
* fields.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access private
|
||||
*/
|
||||
private function ensure_tabs() {
|
||||
if ( null === $this->tabs ) {
|
||||
$this->tabs = $this->create_tabs();
|
||||
|
||||
$page_id = static::PAGE_ID;
|
||||
|
||||
/**
|
||||
* After create settings.
|
||||
*
|
||||
* Fires after the settings are created in Elementor admin page.
|
||||
*
|
||||
* The dynamic portion of the hook name, `$page_id`, refers to the current page ID.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*
|
||||
* @param Settings_Page $this The settings page.
|
||||
*/
|
||||
do_action( "elementor/admin/after_create_settings/{$page_id}", $this );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
<?php
|
||||
namespace Elementor;
|
||||
|
||||
use Elementor\Core\Upgrade\Manager as Upgrades_Manager;
|
||||
use Elementor\TemplateLibrary\Source_Local;
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit; // Exit if accessed directly.
|
||||
}
|
||||
|
||||
/**
|
||||
* Elementor "Settings" page in WordPress Dashboard.
|
||||
*
|
||||
* Elementor settings page handler class responsible for creating and displaying
|
||||
* Elementor "Settings" page in WordPress dashboard.
|
||||
*
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Settings extends Settings_Page {
|
||||
|
||||
/**
|
||||
* Settings page ID for Elementor settings.
|
||||
*/
|
||||
const PAGE_ID = 'elementor';
|
||||
|
||||
/**
|
||||
* Go Pro menu priority.
|
||||
*/
|
||||
const MENU_PRIORITY_GO_PRO = 502;
|
||||
|
||||
/**
|
||||
* Settings page field for update time.
|
||||
*/
|
||||
const UPDATE_TIME_FIELD = '_elementor_settings_update_time';
|
||||
|
||||
/**
|
||||
* Settings page general tab slug.
|
||||
*/
|
||||
const TAB_GENERAL = 'general';
|
||||
|
||||
/**
|
||||
* Settings page style tab slug.
|
||||
*/
|
||||
const TAB_STYLE = 'style';
|
||||
|
||||
/**
|
||||
* Settings page integrations tab slug.
|
||||
*/
|
||||
const TAB_INTEGRATIONS = 'integrations';
|
||||
|
||||
/**
|
||||
* Settings page advanced tab slug.
|
||||
*/
|
||||
const TAB_ADVANCED = 'advanced';
|
||||
|
||||
/**
|
||||
* Register admin menu.
|
||||
*
|
||||
* Add new Elementor Settings admin menu.
|
||||
*
|
||||
* Fired by `admin_menu` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function register_admin_menu() {
|
||||
global $menu;
|
||||
|
||||
$menu[] = [ '', 'read', 'separator-elementor', '', 'wp-menu-separator elementor' ]; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
add_menu_page(
|
||||
__( 'Elementor', 'elementor' ),
|
||||
__( 'Elementor', 'elementor' ),
|
||||
'manage_options',
|
||||
self::PAGE_ID,
|
||||
[ $this, 'display_settings_page' ],
|
||||
'',
|
||||
'58.5'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reorder the Elementor menu items in admin.
|
||||
* Based on WC.
|
||||
*
|
||||
* @since 2.4.0
|
||||
*
|
||||
* @param array $menu_order Menu order.
|
||||
* @return array
|
||||
*/
|
||||
public function menu_order( $menu_order ) {
|
||||
// Initialize our custom order array.
|
||||
$elementor_menu_order = [];
|
||||
|
||||
// Get the index of our custom separator.
|
||||
$elementor_separator = array_search( 'separator-elementor', $menu_order, true );
|
||||
|
||||
// Get index of library menu.
|
||||
$elementor_library = array_search( Source_Local::ADMIN_MENU_SLUG, $menu_order, true );
|
||||
|
||||
// Loop through menu order and do some rearranging.
|
||||
foreach ( $menu_order as $index => $item ) {
|
||||
if ( 'elementor' === $item ) {
|
||||
$elementor_menu_order[] = 'separator-elementor';
|
||||
$elementor_menu_order[] = $item;
|
||||
$elementor_menu_order[] = Source_Local::ADMIN_MENU_SLUG;
|
||||
|
||||
unset( $menu_order[ $elementor_separator ] );
|
||||
unset( $menu_order[ $elementor_library ] );
|
||||
} elseif ( ! in_array( $item, [ 'separator-elementor' ], true ) ) {
|
||||
$elementor_menu_order[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
// Return order.
|
||||
return $elementor_menu_order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Elementor Pro sub-menu.
|
||||
*
|
||||
* Add new Elementor Pro sub-menu under the main Elementor menu.
|
||||
*
|
||||
* Fired by `admin_menu` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function register_pro_menu() {
|
||||
add_submenu_page(
|
||||
self::PAGE_ID,
|
||||
__( 'Custom Fonts', 'elementor' ),
|
||||
__( 'Custom Fonts', 'elementor' ),
|
||||
'manage_options',
|
||||
'elementor_custom_fonts',
|
||||
[ $this, 'elementor_custom_fonts' ]
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
self::PAGE_ID,
|
||||
__( 'Custom Icons', 'elementor' ),
|
||||
__( 'Custom Icons', 'elementor' ),
|
||||
'manage_options',
|
||||
'elementor_custom_icons',
|
||||
[ $this, 'elementor_custom_icons' ]
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
self::PAGE_ID,
|
||||
'',
|
||||
'<span class="dashicons dashicons-star-filled" style="font-size: 17px"></span> ' . __( 'Go Pro', 'elementor' ),
|
||||
'manage_options',
|
||||
'go_elementor_pro',
|
||||
[ $this, 'handle_external_redirects' ]
|
||||
);
|
||||
|
||||
add_submenu_page( Source_Local::ADMIN_MENU_SLUG, __( 'Popups', 'elementor' ), __( 'Popups', 'elementor' ), 'manage_options', 'popup_templates', [ $this, 'elementor_popups' ] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register Elementor knowledge base sub-menu.
|
||||
*
|
||||
* Add new Elementor knowledge base sub-menu under the main Elementor menu.
|
||||
*
|
||||
* Fired by `admin_menu` action.
|
||||
*
|
||||
* @since 2.0.3
|
||||
* @access public
|
||||
*/
|
||||
public function register_knowledge_base_menu() {
|
||||
add_submenu_page(
|
||||
self::PAGE_ID,
|
||||
'',
|
||||
__( 'Getting Started', 'elementor' ),
|
||||
'manage_options',
|
||||
'elementor-getting-started',
|
||||
[ $this, 'elementor_getting_started' ]
|
||||
);
|
||||
|
||||
add_submenu_page(
|
||||
self::PAGE_ID,
|
||||
'',
|
||||
__( 'Get Help', 'elementor' ),
|
||||
'manage_options',
|
||||
'go_knowledge_base_site',
|
||||
[ $this, 'handle_external_redirects' ]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Go Elementor Pro.
|
||||
*
|
||||
* Redirect the Elementor Pro page the clicking the Elementor Pro menu link.
|
||||
*
|
||||
* Fired by `admin_init` action.
|
||||
*
|
||||
* @since 2.0.3
|
||||
* @access public
|
||||
*/
|
||||
public function handle_external_redirects() {
|
||||
if ( empty( $_GET['page'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( 'go_elementor_pro' === $_GET['page'] ) {
|
||||
wp_redirect( Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-menu&utm_campaign=gopro&utm_medium=wp-dash' ) );
|
||||
die;
|
||||
}
|
||||
|
||||
if ( 'go_knowledge_base_site' === $_GET['page'] ) {
|
||||
wp_redirect( 'https://go.elementor.com/docs-admin-menu/' );
|
||||
die;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display settings page.
|
||||
*
|
||||
* Output the content for the getting started page.
|
||||
*
|
||||
* @since 2.2.0
|
||||
* @access public
|
||||
*/
|
||||
public function elementor_getting_started() {
|
||||
if ( User::is_current_user_can_edit_post_type( 'page' ) ) {
|
||||
$create_new_label = __( 'Create Your First Page', 'elementor' );
|
||||
$create_new_cpt = 'page';
|
||||
} elseif ( User::is_current_user_can_edit_post_type( 'post' ) ) {
|
||||
$create_new_label = __( 'Create Your First Post', 'elementor' );
|
||||
$create_new_cpt = 'post';
|
||||
}
|
||||
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="e-getting-started">
|
||||
<div class="e-getting-started__box postbox">
|
||||
<div class="e-getting-started__header">
|
||||
<div class="e-getting-started__title">
|
||||
<div class="e-logo-wrapper">
|
||||
<i class="eicon-elementor"></i>
|
||||
</div>
|
||||
<?php echo __( 'Getting Started', 'elementor' ); ?>
|
||||
</div>
|
||||
<a class="e-getting-started__skip" href="<?php echo esc_url( admin_url() ); ?>">
|
||||
<i class="eicon-close" aria-hidden="true" title="<?php esc_attr_e( 'Skip', 'elementor' ); ?>"></i>
|
||||
<span class="elementor-screen-only"><?php echo __( 'Skip', 'elementor' ); ?></span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="e-getting-started__content">
|
||||
<div class="e-getting-started__content--narrow">
|
||||
<h2><?php echo __( 'Welcome to Elementor', 'elementor' ); ?></h2>
|
||||
<p><?php echo __( 'Get introduced to Elementor by watching our "Getting Started" video series. It will guide you through the steps needed to create your website. Then click to create your first page.', 'elementor' ); ?></p>
|
||||
</div>
|
||||
|
||||
<div class="e-getting-started__video">
|
||||
<iframe width="620" height="350" src="https://www.youtube-nocookie.com/embed/videoseries?list=PLZyp9H25CboH8b_wsNyOmstckiOE8aUBg&controls=1&modestbranding=1" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<div class="e-getting-started__actions e-getting-started__content--narrow">
|
||||
<?php if ( ! empty( $create_new_cpt ) ) : ?>
|
||||
<a href="<?php echo esc_url( Utils::get_create_new_post_url( $create_new_cpt ) ); ?>" class="button button-primary button-hero"><?php echo esc_html( $create_new_label ); ?></a>
|
||||
<?php endif; ?>
|
||||
|
||||
<a href="https://go.elementor.com/getting-started/" target="_blank" class="button button-secondary button-hero"><?php echo __( 'Watch the Full Guide', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /.wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display settings page.
|
||||
*
|
||||
* Output the content for the custom fonts page.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function elementor_custom_fonts() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="elementor-blank_state">
|
||||
<img src="<?php echo ELEMENTOR_ASSETS_URL . 'images/go-pro-wp-dashboard.svg'; ?>" />
|
||||
<h2><?php echo __( 'Add Your Custom Fonts', 'elementor' ); ?></h2>
|
||||
<p><?php echo __( 'Custom Fonts allows you to add your self-hosted fonts and use them on your Elementor projects to create a unique brand language.', 'elementor' ); ?></p>
|
||||
<a class="elementor-button elementor-button-default elementor-button-go-pro" target="_blank" href="<?php echo Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-custom-fonts&utm_campaign=gopro&utm_medium=wp-dash' ); ?>"><?php echo __( 'Go Pro', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</div><!-- /.wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display settings page.
|
||||
*
|
||||
* Output the content for the custom icons page.
|
||||
*
|
||||
* @since 2.8.0
|
||||
* @access public
|
||||
*/
|
||||
public function elementor_custom_icons() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="elementor-blank_state">
|
||||
<img src="<?php echo ELEMENTOR_ASSETS_URL . 'images/go-pro-wp-dashboard.svg'; ?>" />
|
||||
<h2><?php echo __( 'Add Your Custom Icons', 'elementor' ); ?></h2>
|
||||
<p><?php echo __( 'Don\'t rely solely on the FontAwesome icons everyone else is using! Differentiate your website and your style with custom icons you can upload from your favorite icons source.', 'elementor' ); ?></p>
|
||||
<a class="elementor-button elementor-button-default elementor-button-go-pro" target="_blank" href="<?php echo Utils::get_pro_link( 'https://elementor.com/pro/?utm_source=wp-custom-icons&utm_campaign=gopro&utm_medium=wp-dash' ); ?>"><?php echo __( 'Go Pro', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</div><!-- /.wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* Display settings page.
|
||||
*
|
||||
* Output the content for the Popups page.
|
||||
*
|
||||
* @since 2.4.0
|
||||
* @access public
|
||||
*/
|
||||
public function elementor_popups() {
|
||||
?>
|
||||
<div class="wrap">
|
||||
<div class="elementor-blank_state">
|
||||
<i class="eicon-nerd-chuckle"></i>
|
||||
<h2><?php echo __( 'Get Popup Builder', 'elementor' ); ?></h2>
|
||||
<p><?php echo __( 'Popup Builder lets you take advantage of all the amazing features in Elementor, so you can build beautiful & highly converting popups. Go pro and start designing your popups today.', 'elementor' ); ?></p>
|
||||
<a class="elementor-button elementor-button-default elementor-button-go-pro" target="_blank" href="<?php echo Utils::get_pro_link( 'https://elementor.com/popup-builder/?utm_source=popup-templates&utm_campaign=gopro&utm_medium=wp-dash' ); ?>"><?php echo __( 'Go Pro', 'elementor' ); ?></a>
|
||||
</div>
|
||||
</div><!-- /.wrap -->
|
||||
<?php
|
||||
}
|
||||
|
||||
/**
|
||||
* On admin init.
|
||||
*
|
||||
* Preform actions on WordPress admin initialization.
|
||||
*
|
||||
* Fired by `admin_init` action.
|
||||
*
|
||||
* @since 2.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function on_admin_init() {
|
||||
$this->handle_external_redirects();
|
||||
|
||||
$this->maybe_remove_all_admin_notices();
|
||||
}
|
||||
|
||||
/**
|
||||
* Change "Settings" menu name.
|
||||
*
|
||||
* Update the name of the Settings admin menu from "Elementor" to "Settings".
|
||||
*
|
||||
* Fired by `admin_menu` action.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function admin_menu_change_name() {
|
||||
global $submenu;
|
||||
|
||||
if ( isset( $submenu['elementor'] ) ) {
|
||||
// @codingStandardsIgnoreStart
|
||||
$submenu['elementor'][0][0] = __( 'Settings', 'elementor' );
|
||||
// @codingStandardsIgnoreEnd
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update CSS print method.
|
||||
*
|
||||
* Clear post CSS cache.
|
||||
*
|
||||
* Fired by `add_option_elementor_css_print_method` and
|
||||
* `update_option_elementor_css_print_method` actions.
|
||||
*
|
||||
* @since 1.7.5
|
||||
* @access public
|
||||
* @deprecated 3.0.0
|
||||
*/
|
||||
public function update_css_print_method() {
|
||||
Plugin::$instance->files_manager->clear_cache();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create tabs.
|
||||
*
|
||||
* Return the settings page tabs, sections and fields.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @return array An array with the settings page tabs, sections and fields.
|
||||
*/
|
||||
protected function create_tabs() {
|
||||
$validations_class_name = __NAMESPACE__ . '\Settings_Validations';
|
||||
|
||||
return [
|
||||
self::TAB_GENERAL => [
|
||||
'label' => __( 'General', 'elementor' ),
|
||||
'sections' => [
|
||||
'general' => [
|
||||
'fields' => [
|
||||
self::UPDATE_TIME_FIELD => [
|
||||
'full_field_id' => self::UPDATE_TIME_FIELD,
|
||||
'field_args' => [
|
||||
'type' => 'hidden',
|
||||
],
|
||||
'setting_args' => [ $validations_class_name, 'current_time' ],
|
||||
],
|
||||
'cpt_support' => [
|
||||
'label' => __( 'Post Types', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'checkbox_list_cpt',
|
||||
'std' => [ 'page', 'post' ],
|
||||
'exclude' => [ 'attachment', 'elementor_library' ],
|
||||
],
|
||||
'setting_args' => [ $validations_class_name, 'checkbox_list' ],
|
||||
],
|
||||
'disable_color_schemes' => [
|
||||
'label' => __( 'Disable Default Colors', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'checkbox',
|
||||
'value' => 'yes',
|
||||
'sub_desc' => __( 'Checking this box will disable Elementor\'s Default Colors, and make Elementor inherit the colors from your theme.', 'elementor' ),
|
||||
],
|
||||
],
|
||||
'disable_typography_schemes' => [
|
||||
'label' => __( 'Disable Default Fonts', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'checkbox',
|
||||
'value' => 'yes',
|
||||
'sub_desc' => __( 'Checking this box will disable Elementor\'s Default Fonts, and make Elementor inherit the fonts from your theme.', 'elementor' ),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
'usage' => [
|
||||
'label' => __( 'Improve Elementor', 'elementor' ),
|
||||
'fields' => [
|
||||
'allow_tracking' => [
|
||||
'label' => __( 'Usage Data Sharing', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'checkbox',
|
||||
'value' => 'yes',
|
||||
'default' => '',
|
||||
'sub_desc' => __( 'Become a super contributor by opting in to share non-sensitive plugin data and to receive periodic email updates from us.', 'elementor' ) . sprintf( ' <a href="%1$s" target="_blank">%2$s</a>', 'https://go.elementor.com/usage-data-tracking/', __( 'Learn more.', 'elementor' ) ),
|
||||
],
|
||||
'setting_args' => [ __NAMESPACE__ . '\Tracker', 'check_for_settings_optin' ],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
self::TAB_STYLE => [
|
||||
'label' => __( 'Style', 'elementor' ),
|
||||
'sections' => [
|
||||
'style' => [
|
||||
'fields' => [
|
||||
'notice' => [
|
||||
'label' => __( 'Looking for the Style settings?', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'raw_html',
|
||||
'html' => __( 'The Style settings changed its location and can now be found within Elementor Editor\'s <b>Settings Panel > Hamburger Menu > Site Settings</b>.<br>You can use the Global Manager to make changes and see them live!', 'elementor' ) . sprintf( ' <a target="_blank" href="http://go.elementor.com/panel-layout-settings">%s</a>', __( 'Learn More', 'elementor' ) ),
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
self::TAB_INTEGRATIONS => [
|
||||
'label' => __( 'Integrations', 'elementor' ),
|
||||
'sections' => [],
|
||||
],
|
||||
self::TAB_ADVANCED => [
|
||||
'label' => __( 'Advanced', 'elementor' ),
|
||||
'sections' => [
|
||||
'advanced' => [
|
||||
'fields' => [
|
||||
'css_print_method' => [
|
||||
'label' => __( 'CSS Print Method', 'elementor' ),
|
||||
'field_args' => [
|
||||
'class' => 'elementor_css_print_method',
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'external' => __( 'External File', 'elementor' ),
|
||||
'internal' => __( 'Internal Embedding', 'elementor' ),
|
||||
],
|
||||
'desc' => '<div class="elementor-css-print-method-description" data-value="external" style="display: none">' . __( 'Use external CSS files for all generated stylesheets. Choose this setting for better performance (recommended).', 'elementor' ) . '</div><div class="elementor-css-print-method-description" data-value="internal" style="display: none">' . __( 'Use internal CSS that is embedded in the head of the page. For troubleshooting server configuration conflicts and managing development environments.', 'elementor' ) . '</div>',
|
||||
],
|
||||
],
|
||||
'editor_break_lines' => [
|
||||
'label' => __( 'Switch Editor Loader Method', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'' => __( 'Disable', 'elementor' ),
|
||||
1 => __( 'Enable', 'elementor' ),
|
||||
],
|
||||
'desc' => __( 'For troubleshooting server configuration conflicts.', 'elementor' ),
|
||||
],
|
||||
],
|
||||
'unfiltered_files_upload' => [
|
||||
'label' => __( 'Enable Unfiltered File Uploads', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'select',
|
||||
'std' => '',
|
||||
'options' => [
|
||||
'' => __( 'Disable', 'elementor' ),
|
||||
1 => __( 'Enable', 'elementor' ),
|
||||
],
|
||||
'desc' => __( 'Please note! Allowing uploads of any files (SVG & JSON included) is a potential security risk.', 'elementor' ) . '<br>' . __( 'Elementor will try to sanitize the unfiltered files, removing potential malicious code and scripts.', 'elementor' ) . '<br>' . __( 'We recommend you only enable this feature if you understand the security risks involved.', 'elementor' ),
|
||||
],
|
||||
],
|
||||
'optimized_dom_output' => [
|
||||
'label' => __( 'Optimized DOM Output', 'elementor' ),
|
||||
'field_args' => [
|
||||
'type' => 'select',
|
||||
'options' => [
|
||||
'' => __( 'Default', 'elementor' ),
|
||||
'enabled' => __( 'Enable', 'elementor' ),
|
||||
'disabled' => __( 'Disable', 'elementor' ),
|
||||
],
|
||||
'desc' => __( 'Developers, Please Note! If you\'ve used custom code in Elementor, you might have experienced a snippet of code not running. Legacy DOM Output allows you to keep prior Elementor markup output settings, and have that lovely code running again.', 'elementor' )
|
||||
. '<a href="https://go.elementor.com/wp-dash-legacy-optimized-dom" target="_blank"> ' . __( 'Learn More', 'elementor' ) . '</a>',
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get settings page title.
|
||||
*
|
||||
* Retrieve the title for the settings page.
|
||||
*
|
||||
* @since 1.5.0
|
||||
* @access protected
|
||||
*
|
||||
* @return string Settings page title.
|
||||
*/
|
||||
protected function get_page_title() {
|
||||
return __( 'Elementor', 'elementor' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @since 2.2.0
|
||||
* @access private
|
||||
*/
|
||||
private function maybe_remove_all_admin_notices() {
|
||||
$elementor_pages = [
|
||||
'elementor-getting-started',
|
||||
'elementor_custom_fonts',
|
||||
'elementor_custom_icons',
|
||||
'elementor-license',
|
||||
'popup_templates',
|
||||
];
|
||||
|
||||
if ( empty( $_GET['page'] ) || ! in_array( $_GET['page'], $elementor_pages, true ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
remove_all_actions( 'admin_notices' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Settings page constructor.
|
||||
*
|
||||
* Initializing Elementor "Settings" page.
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
|
||||
add_action( 'admin_init', [ $this, 'on_admin_init' ] );
|
||||
add_action( 'admin_menu', [ $this, 'register_admin_menu' ], 20 );
|
||||
add_action( 'admin_menu', [ $this, 'admin_menu_change_name' ], 200 );
|
||||
add_action( 'admin_menu', [ $this, 'register_pro_menu' ], self::MENU_PRIORITY_GO_PRO );
|
||||
add_action( 'admin_menu', [ $this, 'register_knowledge_base_menu' ], 501 );
|
||||
|
||||
$clear_cache_callback = [ Plugin::$instance->files_manager, 'clear_cache' ];
|
||||
|
||||
// Clear CSS Meta after change css related methods.
|
||||
$css_settings = [
|
||||
'elementor_disable_color_schemes',
|
||||
'elementor_disable_typography_schemes',
|
||||
'elementor_css_print_method',
|
||||
'elementor_optimized_dom_output',
|
||||
];
|
||||
|
||||
foreach ( $css_settings as $option_name ) {
|
||||
add_action( "add_option_{$option_name}", $clear_cache_callback );
|
||||
add_action( "update_option_{$option_name}", $clear_cache_callback );
|
||||
}
|
||||
|
||||
add_filter( 'custom_menu_order', '__return_true' );
|
||||
add_filter( 'menu_order', [ $this, 'menu_order' ] );
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user