8889841cassets-manager/module.php 0000644 00000002131 15043204017 0011445 0 ustar 00 asset_managers[ $name ] = $instance;
}
public function get_assets_manager( $id = null ) {
if ( $id ) {
if ( ! isset( $this->asset_managers[ $id ] ) ) {
return null;
}
return $this->asset_managers[ $id ];
}
return $this->asset_managers;
}
/**
* @deprecated 3.1.0
*/
public function localize_settings() {
Plugin::elementor()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0' );
return [];
}
public function __construct() {
parent::__construct();
$this->add_asset_manager( 'font', new AssetTypes\Fonts_Manager() );
$this->add_asset_manager( 'icon', new AssetTypes\Icons_Manager() );
}
}
assets-manager/classes/assets-base.php 0000644 00000030306 15043204017 0014034 0 ustar 00
get_metabox_field_html( $field, $field['saved'] ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
endforeach;
?>
get_html_field( $field );
return $html;
break;
case 'html_tag':
$html = $this->get_html_tag( $field );
return $html;
break;
case 'toolbar':
$html = $this->get_repeater_tools( $field );
break;
case 'input':
$html = $this->get_input_field( $field );
break;
case 'select':
$html = $this->get_select_field( $field, $saved );
break;
case 'textarea':
$html = $this->get_textarea_field( $field, $saved );
break;
case 'file':
$html = $this->get_file_field( $field, $saved );
break;
case 'repeater':
$html = $this->get_repeater_field( $field, $saved );
break;
case 'dropzone':
$html = $this->get_dropzone_field( $field, $saved );
break;
case 'checkbox':
return $this->get_checkbox_field( $field, $saved );
default:
$method = 'get_' . $field['field_type'] . 'field';
if ( method_exists( $this, $method ) ) {
$html = call_user_func( [ $this, $method ], $field, $saved );
}
break;
}
return $this->get_field_row( $field, $html );
}
public function get_field_label( $field ) {
if ( ! isset( $field['label'] ) || false === $field['label'] ) {
return '';
}
$id = $field['id'];
if ( 'file' === $field['field_type'] ) {
$id .= $field['field_type'];
}
return '' . $field['label'] . '
';
}
public function get_input_field( $attributes ) {
if ( isset( $attributes['input_type'] ) ) {
$attributes['type'] = $attributes['input_type'];
unset( $attributes['input_type'] );
}
$input = ' get_attribute_string( $attributes ) . '>';
return $input;
}
public function get_attribute_string( $attributes, $field = [] ) {
if ( isset( $field['extra_attributes'] ) && is_array( $field['extra_attributes'] ) ) {
$attributes = array_merge( $attributes, $field['extra_attributes'] );
}
$attributes_array = [];
foreach ( $attributes as $name => $value ) {
$attributes_array[] = sprintf( '%s="%s"', $name, esc_attr( $value ) );
}
return implode( ' ', $attributes_array );
}
public function get_select_field( $field, $selected = '' ) {
$input = 'get_attribute_string( [
'name' => $field['id'],
'id' => $field['id'],
], $field );
$input .= '>' . "\n";
foreach ( $field['options'] as $value => $label ) {
$input .= '' . esc_attr( $label ) . ' ' . PHP_EOL;
}
return $input . ' ';
}
public function get_textarea_field( $field, $html ) {
$input = '';
return $input;
}
public function get_file_field( $field, $saved ) {
$value = [
'id' => '',
'url' => '',
];
if ( isset( $saved['id'] ) && isset( $saved['url'] ) ) {
$value = $saved;
}
$html = '';
$html .= $this->get_input_field(
[
'type' => 'hidden',
'name' => $field['id'] . '[id]',
'value' => $value['id'],
]
);
$html .= $this->get_input_field(
[
'type' => 'text',
'name' => $field['id'] . '[url]',
'value' => $value['url'],
'placeholder' => $field['description'],
'class' => 'elementor-field-input',
]
);
$html .= $this->get_input_field(
[
'type' => 'button',
'class' => 'button elementor-button elementor-upload-btn',
'name' => $field['id'],
'id' => $field['id'],
'value' => '',
'data-preview_anchor' => isset( $field['preview_anchor'] ) ? $field['preview_anchor'] : 'none',
'data-mime_type' => isset( $field['mine'] ) ? $field['mine'] : '',
'data-ext' => isset( $field['ext'] ) ? $field['ext'] : '',
'data-upload_text' => esc_html__( 'Upload', 'elementor-pro' ),
'data-remove_text' => esc_html__( 'Delete', 'elementor-pro' ),
'data-box_title' => isset( $field['box_title'] ) ? $field['box_title'] : '',
'data-box_action' => isset( $field['box_action'] ) ? $field['box_action'] : '',
]
);
return $html;
}
public function get_html_field( $field ) {
return $field['raw_html'];
}
public function get_dropzone_field( $field ) {
ob_start();
$input_attributes = [
'type' => 'file',
'name' => $field['id'],
'id' => $field['id'],
'accept' => $field['accept'],
'class' => 'box__file',
];
if ( ! empty( $field['multiple'] ) ) {
$input_attributes['multiple'] = true;
}
$input_html = $this->get_input_field( $input_attributes );
$field['label'] = '' . esc_html__( 'Drag & Drop to Upload', 'elementor-pro' ) . ' ';
if ( ! empty( $field['sub-label'] ) ) {
$field['label'] .= '' . $field['sub-label'] . ' ';
}
?>
'row_label_' . $js_id,
'class' => 'repeater-title hidden',
];
if ( is_array( $row_label ) ) {
$label = $row_label['default'];
$row_label_html_args['data-default'] = $row_label['default'];
$row_label_html_args['data-selector'] = $row_label['selector'];
} else {
$label = $row_label;
$row_label_html_args['data-default'] = $row_label;
}
$row_label_html = 'get_attribute_string( $row_label_html_args ) . '>' . $label . ' ';
ob_start();
?>
get_attribute_string( $row_label_html_args ) . '>' . $label . '';
if ( is_array( $saved ) && count( $saved ) > 0 ) {
foreach ( (array) $saved as $key => $item ) {
echo '';
echo $row_label_html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo $this->get_repeater_tools( $field ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
echo '
';
foreach ( $field['fields'] as $sub_field ) {
$default = isset( $sub_field['default'] ) ? $sub_field['default'] : '';
$item_meta = isset( $item[ $sub_field['id'] ] ) ? $item[ $sub_field['id'] ] : $default;
$sub_field['real_id'] = $sub_field['id'];
$sub_field['id'] = $id . '[' . $counter . '][' . $sub_field['id'] . ']';
echo $this->get_metabox_field_html( $sub_field, $item_meta ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
echo '
'; // end table
echo '
';
$counter++;
}
}
echo ' ';
return ob_get_clean();
}
public function get_checkbox_field( $field, $saved ) {
Utils::print_unescaped_internal_string( $this->get_field_row( $field, '' ) );
echo '';
foreach ( $field['options'] as $checkbox_key => $label ) {
$name = $field['id'] . '_' . $checkbox_key;
$checked = ! empty( $saved ) && in_array( $checkbox_key, $saved, true ) ? 'checked' : '';
echo '' . esc_html( $label ) . ' ';
}
echo '
';
}
private function get_html_tag( $field ) {
$tag = isset( $field['tag'] ) ? $field['tag'] : 'div';
if ( isset( $field['close'] ) && true === $field['close'] ) {
return '' . $tag . '>';
}
return '<' . $tag . ' ' . $this->get_attribute_string( $field['attributes'] ) . '>';
}
private function get_repeater_tools( $field ) {
$confirm = isset( $field['confirm'] ) ? $field['confirm'] : esc_html__( 'Are you sure?', 'elementor-pro' );
$remove_title = isset( $field['remove_title'] ) ? $field['remove_title'] : esc_html__( 'Delete', 'elementor-pro' );
$toggle_title = isset( $field['toggle_title'] ) ? $field['toggle_title'] : esc_html__( 'Edit', 'elementor-pro' );
$close_title = isset( $field['close_title'] ) ? $field['close_title'] : esc_html__( 'Close', 'elementor-pro' );
return '
' . $close_title . '
' . $toggle_title . '
' . $remove_title . '
';
}
public function get_field_row( $field, $field_html ) {
$description = '';
$css_id = isset( $field['id'] ) ? ' ' . $field['id'] : '';
if ( isset( $field['real_id'] ) ) {
$css_id = ' ' . $field['real_id'];
}
$css_id .= ' elementor-field-' . $field['field_type'];
return '' . $this->get_field_label( $field ) . $field_html . $description . '
';
}
public function sanitize_text_field_recursive( $data ) {
if ( is_array( $data ) ) {
foreach ( $data as $key => $value ) {
$data[ $key ] = $this->sanitize_text_field_recursive( $value );
}
return $data;
}
return sanitize_text_field( $data );
}
public function __construct() {
$this->actions();
}
}
assets-manager/classes/font-base.php 0000644 00000002040 15043204017 0013472 0 ustar 00 font_preview_phrase = esc_html__( 'Elementor Is Making the Web Beautiful!!!', 'elementor-pro' );
}
public function get_name() {
return '';
}
public function get_type() {
return '';
}
public function handle_panel_request( array $data ) {
return [];
}
public function get_fonts( $force = false ) {}
public function enqueue_font( $font_family, $font_data, $post_css ) {}
public function get_font_family_type( $post_id, $post_title ) {}
public function get_font_data( $post_id, $post_title ) {}
public function render_preview_column( $post_id ) {}
public function get_font_variations_count( $post_id ) {}
public function save_meta( $post_id, $data ) {}
}
assets-manager/asset-types/icons-manager.php 0000644 00000016723 15043204017 0015200 0 ustar 00 icon_types;
}
if ( isset( $this->icon_types[ $type ] ) ) {
return $this->icon_types[ $type ];
}
return false;
}
/**
* Add a font type to the font manager
*
* @param string $icon_type
* @param Classes\Assets_Base $instance
*/
public function add_icon_type( $icon_type, $instance ) {
$this->icon_types[ $icon_type ] = $instance;
}
/**
* Register elementor icon set custom post type
*/
public function register_post_type() {
$labels = [
'name' => _x( 'Custom Icons', 'CPT Name', 'elementor-pro' ),
'singular_name' => _x( 'Icon Set', 'CPT Singular Name', 'elementor-pro' ),
'add_new' => esc_html__( 'Add New', 'elementor-pro' ),
'add_new_item' => esc_html__( 'Add New Icon Set', 'elementor-pro' ),
'edit_item' => esc_html__( 'Edit Icon Set', 'elementor-pro' ),
'new_item' => esc_html__( 'New Icon Set', 'elementor-pro' ),
'all_items' => esc_html__( 'All Icons', 'elementor-pro' ),
'view_item' => esc_html__( 'View Icon', 'elementor-pro' ),
'search_items' => esc_html__( 'Search Icon Set', 'elementor-pro' ),
'not_found' => esc_html__( 'No icons found', 'elementor-pro' ),
'not_found_in_trash' => esc_html__( 'No icons found in trash', 'elementor-pro' ),
'parent_item_colon' => '',
'menu_name' => _x( 'Custom Icons', 'CPT Menu Name', 'elementor-pro' ),
];
$args = [
'labels' => $labels,
'public' => false,
'rewrite' => false,
'show_ui' => true,
'show_in_menu' => false,
'show_in_nav_menus' => false,
'exclude_from_search' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => [ 'title' ],
];
$this->post_type_object = register_post_type( self::CPT, $args );
}
public function post_updated_messages( $messages ) {
$messages[ self::CPT ] = [
0 => '', // Unused. Messages start at index 1.
1 => esc_html__( 'Icon Set updated.', 'elementor-pro' ),
2 => esc_html__( 'Custom field updated.', 'elementor-pro' ),
3 => esc_html__( 'Custom field deleted.', 'elementor-pro' ),
4 => esc_html__( 'Icon Set updated.', 'elementor-pro' ),
/* translators: %s: Date and time of the revision. */
5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Icon Set restored to revision from %s', 'elementor-pro' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
6 => esc_html__( 'Icon Set saved.', 'elementor-pro' ),
7 => esc_html__( 'Icon Set saved.', 'elementor-pro' ),
8 => esc_html__( 'Icon Set submitted.', 'elementor-pro' ),
9 => esc_html__( 'Icon Set updated.', 'elementor-pro' ),
10 => esc_html__( 'Icon Set draft updated.', 'elementor-pro' ),
];
return $messages;
}
/**
* Add Font manager link to admin menu
*/
private function register_admin_menu( Admin_Menu_Manager $admin_menu_manager ) {
if ( $this->can_use_custom_icons() ) {
$admin_menu_manager->register( static::MENU_SLUG, new Custom_Icons_Menu_Item() );
} else {
$admin_menu_manager->register( static::PROMOTION_MENU_SLUG, new Custom_Icons_Promotion_Menu_Item() );
}
}
private function can_use_custom_icons() {
return ( API::is_license_active() || $this->has_icons() );
}
private function has_icons() {
if ( null !== $this->has_icons ) {
return $this->has_icons;
}
$existing_icons = new \WP_Query( [
'post_type' => static::CPT,
'posts_per_page' => 1,
] );
$this->has_icons = $existing_icons->post_count > 0;
return $this->has_icons;
}
public function redirect_admin_old_page_to_new() {
if ( ! empty( $_GET['page'] ) && 'elementor_custom_icons' === $_GET['page'] ) {
wp_safe_redirect( admin_url( static::MENU_SLUG ) );
die;
}
}
/**
* Clean up admin Font manager admin listing
*/
public function clean_admin_listing_page() {
global $typenow;
if ( self::CPT !== $typenow ) {
return;
}
add_filter( 'months_dropdown_results', '__return_empty_array' );
add_filter( 'screen_options_show_screen', '__return_false' );
}
public function post_row_actions( $actions, $post ) {
if ( self::CPT !== $post->post_type ) {
return $actions;
}
unset( $actions['inline hide-if-no-js'] );
return $actions;
}
public function add_finder_item( array $categories ) {
$categories['settings']['items']['custom-icons'] = [
'title' => esc_html__( 'Custom Icons', 'elementor-pro' ),
'icon' => 'favorite',
'url' => admin_url( static::MENU_SLUG ),
'keywords' => [ 'custom', 'icons', 'elementor' ],
];
if ( ! $this->can_use_custom_icons() ) {
$lock = new Feature_Lock( [ 'type' => 'custom-icon' ] );
$categories['settings']['items']['custom-icons']['lock'] = $lock->get_config();
}
return $categories;
}
/**
* Register Font Manager action and filter hooks
*/
protected function actions() {
add_action( 'init', [ $this, 'register_post_type' ] );
if ( is_admin() ) {
add_action( 'init', [ $this, 'redirect_admin_old_page_to_new' ] );
add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu_manager ) {
$this->register_admin_menu( $admin_menu_manager );
} );
// TODO: BC - Remove after `Admin_Menu_Manager` will be the standard.
add_action( 'admin_menu', function () {
if ( did_action( 'elementor/admin/menu/register' ) ) {
return;
}
$menu_title = _x( 'Custom Icons', 'Elementor Font', 'elementor-pro' );
add_submenu_page(
Settings::PAGE_ID,
$menu_title,
$menu_title,
self::CAPABILITY,
static::MENU_SLUG
);
}, 50 );
add_action( 'admin_head', [ $this, 'clean_admin_listing_page' ] );
}
// TODO: Maybe just ignore all of those when the user can't use custom icons?
add_filter( 'post_updated_messages', [ $this, 'post_updated_messages' ] );
add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 );
add_filter( 'elementor/finder/categories', [ $this, 'add_finder_item' ] );
/**
* Elementor icons manager loaded.
*
* Fires after the icons manager was fully loaded and instantiated.
*
* @since 2.0.0
*
* @param Fonts_Manager $this An instance of icons manager.
*/
do_action( 'elementor_pro/icons_manager_loaded', $this );
}
/**
* Fonts_Manager constructor.
*/
public function __construct() {
$this->actions();
$this->add_icon_type( 'custom', new Icons\Custom_Icons() );
$this->add_icon_type( 'font-awesome-pro', new Icons\Font_Awesome_Pro() );
}
}
assets-manager/asset-types/icons/icon-sets/fontello.php 0000644 00000004123 15043204017 0017305 0 ustar 00 remove_fontello_styling();
$this->dir_name = $this->get_unique_name();
}
public function get_type() {
return esc_html__( 'Fontello', 'elementor-pro' );
}
public function is_valid() {
if ( ! file_exists( $this->directory . $this->data_file ) ) {
return false; // missing data file
}
return true;
}
private function remove_fontello_styling() {
$filename = $this->directory . 'css/' . $this->get_name() . '.css';
$stylesheet = Utils::_unstable_file_get_contents( $filename );
$stylesheet = str_replace( [ 'margin-left: .2em;', 'margin-right: .2em;' ], [ '', '' ], $stylesheet );
file_put_contents( $filename, $stylesheet );
}
private function get_json() {
return json_decode( Utils::_unstable_file_get_contents( $this->directory . $this->data_file ) );
}
protected function extract_icon_list() {
$config = $this->get_json();
if ( ! isset( $config->glyphs ) ) {
return false; // missing icons list
}
$icons = [];
foreach ( $config->glyphs as $icon ) {
$icons[] = $icon->css;
}
return $icons;
}
protected function get_prefix() {
$config = $this->get_json();
if ( ! isset( $config->css_prefix_text ) ) {
return false; // missing css_prefix_text
}
return $config->css_prefix_text;
}
public function get_name() {
$config = $this->get_json();
if ( ! isset( $config->name ) ) {
return false; // missing name
}
return $config->name;
}
protected function get_stylesheet() {
$name = $this->get_name();
if ( ! $name ) {
return false; // missing name
}
return $this->get_url() . '/css/' . $name . '.css';
}
}
assets-manager/asset-types/icons/icon-sets/fontastic.php 0000644 00000003762 15043204017 0017465 0 ustar 00 data = Utils::_unstable_file_get_contents( $this->directory . $this->stylesheet_file );
$this->dir_name = $this->get_unique_name();
}
public function get_type() {
return esc_html__( 'Fontastic', 'elementor-pro' );
}
public function is_valid() {
if ( ! file_exists( $this->directory . $this->data_file ) ) {
return false; // missing data file
}
return true;
}
protected function extract_icon_list() {
$pattern = '/\.' . $this->get_prefix() . '(.*)\:before\s\{/';
preg_match_all( $pattern, $this->data, $icons_matches );
if ( empty( $icons_matches[1] ) ) {
return false; // missing icons list
}
$icons = [];
foreach ( $icons_matches[1] as $icon ) {
$icons[] = $icon;
}
return $icons;
}
protected function get_prefix() {
static $set_prefix = null;
if ( null === $set_prefix ) {
$pattern = '/class\^="(.*)?"/';
preg_match_all( $pattern, $this->data, $prefix );
if ( ! isset( $prefix[1][0] ) ) {
return false; // missing css_prefix_text
}
$set_prefix = $prefix[1][0];
}
return $set_prefix;
}
public function get_name() {
static $set_name = null;
if ( null === $set_name ) {
$pattern = '/font-family: "(.*)"/';
preg_match_all( $pattern, $this->data, $name );
if ( ! isset( $name[1][0] ) ) {
return false; // missing name
}
$set_name = $name[1][0];
}
return $set_name;
}
protected function get_stylesheet( $unique_name = '' ) {
return $this->get_url() . '/' . $this->stylesheet_file;
}
}
assets-manager/asset-types/icons/icon-sets/icomoon.php 0000644 00000003744 15043204017 0017136 0 ustar 00 dir_name = $this->get_unique_name();
return [];
}
public function get_type() {
return esc_html__( 'Icomoon', 'elementor-pro' );
}
public function is_valid() {
if ( ! file_exists( $this->directory . $this->data_file ) ) {
return false; // missing data file
}
return true;
}
private function get_json() {
return json_decode( Utils::_unstable_file_get_contents( $this->directory . $this->data_file ) );
}
protected function extract_icon_list() {
$config = $this->get_json();
if ( ! isset( $config->icons ) ) {
return false; // missing icons list
}
$icons = [];
foreach ( $config->icons as $icon ) {
$icons[] = $icon->properties->name;
}
return $icons;
}
protected function get_prefix() {
$config = $this->get_json();
if ( ! isset( $config->preferences->fontPref->prefix ) ) {
return false; // missing css_prefix_text
}
return $config->preferences->fontPref->prefix;
}
protected function get_display_prefix() {
$config = $this->get_json();
if ( ! isset( $config->preferences->fontPref->classSelector ) ) {
return false; // missing css_prefix_text
}
return str_replace( '.', '', $config->preferences->fontPref->classSelector );
}
public function get_name() {
$config = $this->get_json();
if ( ! isset( $config->metadata->name ) ) {
return false; // missing name
}
return $config->metadata->name;
}
protected function get_stylesheet() {
return $this->get_url( '/' . $this->stylesheet_file );
}
}
assets-manager/asset-types/icons/icon-sets/icon-set-base.php 0000644 00000015034 15043204017 0020117 0 ustar 00 directory . $path_name;
if ( ! file_exists( $check ) ) {
return false;
}
if ( $this->is_path_dir( $path_name ) ) {
return is_dir( $check );
}
return true;
}
/**
* is icon set
*
* validate that the current uploaded zip is in this icon set format
* @return bool
*/
public function is_icon_set() {
foreach ( $this->allowed_zipped_files as $file ) {
if ( ! $this->is_file_allowed( $file ) ) {
return false;
}
}
return true;
}
public function is_valid() {
return false;
}
protected function get_display_prefix() {
return '';
}
protected function get_prefix() {
return '';
}
public function handle_new_icon_set() {
return $this->prepare();
}
/**
* cleanup_temp_files
* @param \WP_Filesystem_Base $wp_filesystem
*/
protected function cleanup_temp_files( $wp_filesystem ) {
$wp_filesystem->rmdir( $this->directory, true );
}
/**
* Gets the URL to uploaded file.
*
* @param $file_name
*
* @return string
*/
protected function get_file_url( $file_name ) {
$wp_upload_dir = wp_upload_dir();
$url = $wp_upload_dir['baseurl'] . '/elementor/custom-icons/' . $file_name;
/**
* Upload file URL.
*
* Filters the URL to a file uploaded using custom icons.
*
* By default URL to a file uploaded is set to `/elementor/custom-icons/{file_name}`
* inside the WordPress uploads folder. This hook allows developers to change this URL.
*
* @since 1.0.0
*
* @param string $url File URL.
* @param string $file_name File name.
*/
$url = apply_filters( 'elementor_pro/icons_manager/custom_icons/url', $url, $file_name );
return $url;
}
protected function get_icon_sets_dir() {
$wp_upload_dir = wp_upload_dir();
$path = $wp_upload_dir['basedir'] . '/elementor/custom-icons';
/**
* Upload file path.
*
* Filters the path to a folder uploaded using custom icons.
*
* By default the folder path to custom icon files is set to `/elementor/custom-icons`
* inside the WordPress uploads folder. This hook allows developers to change this path.
*
* @param string $path Path to custom icons uploads directory.
*/
$path = apply_filters( 'elementor_pro/icons_manager/custom_icons/dir', $path );
Utils::get_ensure_upload_dir( $path );
return $path;
}
protected function get_ensure_upload_dir( $dir = '' ) {
$path = $this->get_icon_sets_dir();
if ( ! empty( $dir ) ) {
$path .= '/' . $dir;
}
return Utils::get_ensure_upload_dir( $path );
}
public function move_files( $post_id ) {
// @todo: save only needed files
$wp_filesystem = Custom_Icons::get_wp_filesystem();
$to = $this->get_ensure_upload_dir( $this->dir_name ) . '/';
foreach ( $wp_filesystem->dirlist( $this->directory, false, true ) as $file ) {
$full_path = $this->directory . $file['name'];
if ( $wp_filesystem->is_dir( $full_path ) ) {
$wp_filesystem->mkdir( $to . $file['name'] );
foreach ( $file['files'] as $filename => $sub_file ) {
$new_path = $to . $file['name'] . DIRECTORY_SEPARATOR . $filename;
$wp_filesystem->move( $full_path . DIRECTORY_SEPARATOR . $filename, $new_path );
$this->insert_attachment( $this->get_url() . '/' . $file['name'] . '/' . $filename, $new_path, $post_id );
}
} else {
$new_path = $to . $file['name'];
$wp_filesystem->move( $full_path, $new_path );
$this->insert_attachment( $this->get_url() . '/' . $file['name'], $new_path, $post_id );
}
}
$this->cleanup_temp_files( $wp_filesystem );
update_post_meta( $post_id, '_elementor_icon_set_path', $to );
$this->directory = $to;
}
private function insert_attachment( $file_url, $filename, $post_id = 0 ) {
$attachment = [
'file' => $filename,
'guid' => $file_url,
'post_parent' => $post_id,
'post_type' => 'attachment',
];
$id = wp_insert_attachment( $attachment );
return $id;
}
public function get_unique_name() {
$name = $this->get_name();
$basename = $name;
$counter = 1;
while ( ! $this->is_name_unique( $name ) ) {
$name = $basename . '-' . $counter;
$counter++;
}
return $name;
}
private function is_name_unique( $name ) {
return ! is_dir( $this->get_icon_sets_dir() . '/' . $name );
}
protected function get_url( $filename = '' ) {
return $this->get_file_url( $this->dir_name . $filename );
}
protected function get_stylesheet() {
return '';
}
protected function get_version() {
return '1.0.0';
}
protected function get_enqueue() {
return false;
}
public function build_config() {
$icon_set_config = [
'name' => $this->dir_name,
'label' => ucwords( str_replace( [ '-', '_' ], ' ', $this->dir_name ) ),
'url' => $this->get_stylesheet(),
'enqueue' => $this->get_enqueue(),
'prefix' => $this->get_prefix(),
'displayPrefix' => $this->get_display_prefix(),
'labelIcon' => 'eicon eicon-folder',
'ver' => $this->get_version(),
'custom_icon_type' => $this->get_type(),
];
$icons = $this->extract_icon_list();
$icon_set_config['count'] = count( $icons );
$icon_set_config['icons'] = $icons;
if ( 25 < $icon_set_config['count'] ) {
$icon_set_config['fetchJson'] = $this->store_icon_list_json( $icons );
}
return $icon_set_config;
}
private function store_icon_list_json( $icons ) {
$wp_filesystem = Custom_Icons::get_wp_filesystem();
$json_file = $this->get_ensure_upload_dir( $this->dir_name ) . '/e_icons.js';
$wp_filesystem->put_contents( $json_file, json_encode( [ 'icons' => $icons ] ) );
return $this->get_url() . '/e_icons.js';
}
/**
* Icon Set Base constructor.
*
* @param $directory
*/
public function __construct( $directory ) {
$this->directory = $directory;
return $this->is_icon_set() ? $this : false;
}
}
assets-manager/asset-types/icons/font-awesome-pro.php 0000644 00000011630 15043204017 0016762 0 ustar 00 'fa-regular',
'label' => esc_html__( 'Font Awesome - Regular Pro', 'elementor-pro' ),
'url' => false,
'enqueue' => false,
'prefix' => 'fa-',
'displayPrefix' => 'far',
'labelIcon' => 'fab fa-font-awesome-alt',
'ver' => '5.15.1-pro',
'fetchJson' => sprintf( $json_url, 'regular' ),
'native' => true,
];
$icons['fa-solid'] = [
'name' => 'fa-solid',
'label' => esc_html__( 'Font Awesome - Solid Pro', 'elementor-pro' ),
'url' => false,
'enqueue' => false,
'prefix' => 'fa-',
'displayPrefix' => 'fas',
'labelIcon' => 'fab fa-font-awesome',
'ver' => '5.15.1-pro',
'fetchJson' => sprintf( $json_url, 'solid' ),
'native' => true,
];
$icons['fa-brands'] = [
'name' => 'fa-brands',
'label' => esc_html__( 'Font Awesome - Brands Pro', 'elementor-pro' ),
'url' => false,
'enqueue' => false,
'prefix' => 'fa-',
'displayPrefix' => 'fab',
'labelIcon' => 'fab fa-font-awesome-flag',
'ver' => '5.15.1-pro',
'fetchJson' => sprintf( $json_url, 'brands' ),
'native' => true,
];
$icons['fa-light'] = [
'name' => 'fa-light',
'label' => esc_html__( 'Font Awesome - Light Pro', 'elementor-pro' ),
'url' => false,
'enqueue' => false,
'prefix' => 'fa-',
'displayPrefix' => 'fal',
'labelIcon' => 'fal fa-flag',
'ver' => '5.15.1-pro',
'fetchJson' => sprintf( $json_url, 'light' ),
'native' => true,
];
$icons['fa-duotone'] = [
'name' => 'fa-duotone',
'label' => esc_html__( 'Font Awesome - Duotone Pro', 'elementor-pro' ),
'url' => false,
'enqueue' => false,
'prefix' => 'fa-',
'displayPrefix' => 'fad',
'labelIcon' => 'fad fa-flag',
'ver' => '5.15.1-pro',
'fetchJson' => sprintf( $json_url, 'duotone' ),
'native' => true,
];
// remove Free
unset(
$settings['fa-solid'],
$settings['fa-regular'],
$settings['fa-brands']
);
return array_merge( $icons, $settings );
}
public function register_admin_fields( Settings $settings ) {
$settings->add_section( Settings::TAB_INTEGRATIONS, 'font_awesome_pro', [
'callback' => function() {
echo '' . esc_html__( 'Font Awesome Pro', 'elementor-pro' ) . ' ';
esc_html_e( 'Font Awesome, the web\'s most popular icon set and toolkit, Pro Integration', 'elementor-pro' );
},
'fields' => [
self::FA_KIT_ID_OPTION_NAME => [
'label' => esc_html__( 'Kit ID', 'elementor-pro' ),
'field_args' => [
'type' => 'text',
'desc' => sprintf(
/* translators: 1: Link opening tag, 2: Link closing tag. */
esc_html__( 'Enter Your %1$sFont Awesome Pro Kit ID%2$s.', 'elementor-pro' ),
'',
' '
),
],
'setting_args' => [
'sanitize_callback' => [ $this, 'sanitize_kit_id_settings' ],
],
],
'validate_api_data' => [
'field_args' => [
'type' => 'raw_html',
'html' => sprintf( '%s
',
self::FA_KIT_ID_OPTION_NAME . '_fetch',
wp_create_nonce( self::FA_KIT_ID_OPTION_NAME ),
__( 'Validate Kit ID', 'elementor-pro' )
),
],
],
],
] );
}
public function enqueue_kit_js() {
wp_enqueue_script( 'font-awesome-pro', sprintf( self::FA_KIT_SCRIPT_LINK, $this->get_kit_id() ), [], ELEMENTOR_PRO_VERSION );
}
public function sanitize_kit_id_settings( $input ) {
if ( empty( $input ) ) {
delete_option( 'elementor_' . self::FA_KIT_ID_OPTION_NAME );
}
return $input;
}
protected function actions() {
parent::actions();
if ( is_admin() ) {
add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 100 );
}
if ( $this->get_kit_id() ) {
add_filter( 'elementor/icons_manager/native', [ $this, 'replace_font_awesome_pro' ] );
add_action( 'elementor/editor/after_enqueue_scripts', [ $this, 'enqueue_kit_js' ] );
add_action( 'elementor/frontend/after_enqueue_scripts', [ $this, 'enqueue_kit_js' ] );
}
}
}
assets-manager/asset-types/icons/templates.php 0000644 00000002506 15043204017 0015560 0 ustar 00
assets-manager/asset-types/icons/custom-icons.php 0000644 00000034662 15043204017 0016215 0 ustar 00 ID );
$fields = [
[
'id' => 'open_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'attributes' => [
'class' => 'elementor-custom-icons-metabox',
],
],
[
'id' => 'zip_upload',
'field_type' => 'dropzone',
'accept' => 'zip,application/octet-stream,application/zip,application/x-zip,application/x-zip-compressed',
'label' => false,
'sub-label' => esc_html__( 'Your Fontello, IcoMoon or Fontastic .zip file', 'elementor-pro' ),
],
[
'id' => 'close_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'close' => true,
],
[
'id' => self::META_KEY,
'name' => self::META_KEY,
'field_type' => 'input',
'input_type' => 'hidden',
'label' => false,
'value' => $save_data,
'saved' => $save_data,
],
[
'id' => Icons_Manager::CPT . '_nonce',
'name' => Icons_Manager::CPT . '_nonce',
'field_type' => 'input',
'input_type' => 'hidden',
'label' => false,
'value' => wp_create_nonce( Icons_Manager::CPT ),
],
];
foreach ( $fields as $field ) {
$field['saved'] = isset( $field['saved'] ) ? $field['saved'] : '';
}
$this->print_metabox( $fields );
}
public function save_post_meta( $post_id, $post, $update ) {
// If this is an autosave, our form has not been submitted,
// so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
// Check if our nonce is set.
if ( ! isset( $_POST[ Icons_Manager::CPT . '_nonce' ] ) ) {
return $post_id;
}
// Verify that the nonce is valid.
if ( ! wp_verify_nonce(
Utils::_unstable_get_super_global_value( $_POST, Icons_Manager::CPT . '_nonce' ),
Icons_Manager::CPT
) ) {
return $post_id;
}
if ( ! isset( $_POST[ self::META_KEY ] ) ) {
return delete_post_meta( $post_id, self::META_KEY );
}
// PHPCS - It will be sanitized in the next line.
$json = json_decode( stripslashes_deep( $_POST[ self::META_KEY ] ), true ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
foreach ( $json as $property => $value ) {
$json[ $property ] = $this->sanitize_text_field_recursive( $value );
}
// All good save the files array
update_post_meta( $post_id, self::META_KEY, json_encode( $json ) );
// Force refresh of list in Options Table
self::clear_icon_list_option();
}
public static function get_supported_icon_sets() {
$icon_sets = [
'fontastic' => __NAMESPACE__ . '\IconSets\Fontastic',
'fontello' => __NAMESPACE__ . '\IconSets\Fontello',
'icomoon' => __NAMESPACE__ . '\IconSets\Icomoon',
];
$additional_icon_sets = [];
/**
* Additional icon sets.
*
* Filters the icon types supported by Elementor Pro.
*
* By default Elementor Pro supports 'fontastic', 'fontello' and 'icomoon'.
* This hook allows developers to add additional icon sets.
*
* @param array $additional_icon_sets Additional icon sets.
*/
$additional_icon_sets = apply_filters( 'elementor_pro/icons_manager/custom_icons/additional_supported_types', $additional_icon_sets );
return array_merge( $additional_icon_sets, $icon_sets );
}
private function get_active_icon_sets() {
$icons = new \WP_Query( [
'post_type' => Icons_Manager::CPT,
'posts_per_page' => -1,
] );
$custom_icon_sets = [];
foreach ( $icons->posts as $icon_set ) {
$set_config = json_decode( self::get_icon_set_config( $icon_set->ID ), true );
$set_config['custom_icon_post_id'] = $icon_set->ID;
$set_config['label'] = $icon_set->post_title;
$custom_icon_sets[ $set_config['name'] ] = $set_config;
}
return $custom_icon_sets;
}
/**
* get_wp_filesystem
* @return \WP_Filesystem_Base
*/
public static function get_wp_filesystem() {
global $wp_filesystem;
if ( empty( $wp_filesystem ) ) {
require_once ABSPATH . '/wp-admin/includes/file.php';
WP_Filesystem();
}
return $wp_filesystem;
}
private function upload() {
$file = Utils::_unstable_get_super_global_value( $_FILES, 'zip_upload' );
$filename = $file['name'];
$ext = pathinfo( $filename, PATHINFO_EXTENSION );
if ( 'zip' !== $ext ) {
unlink( $filename );
return new \WP_Error( 'unsupported_file', esc_html__( 'Only zip files are allowed', 'elementor-pro' ) );
}
if ( ! function_exists( 'wp_handle_upload' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
// Handler upload archive file.
$upload_result = wp_handle_upload( $file, [ 'test_form' => false ] );
if ( isset( $upload_result['error'] ) ) {
unlink( $filename );
return new \WP_Error( 'upload_error', $upload_result['error'] );
}
return $upload_result['file'];
}
private function extract_zip( $file, $to ) {
// TODO: Move to core as a util.
$valid_field_types = [
'css',
'eot',
'html',
'json',
'otf',
'svg',
'ttf',
'txt',
'woff',
'woff2',
];
$zip = new \ZipArchive();
$zip->open( $file );
$valid_entries = [];
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
for ( $i = 0; $i < $zip->numFiles; $i++ ) {
$zipped_file_name = $zip->getNameIndex( $i );
$dirname = pathinfo( $zipped_file_name, PATHINFO_DIRNAME );
// Skip the OS X-created __MACOSX directory.
if ( '__MACOSX/' === substr( $dirname, 0, 9 ) ) {
continue;
}
$zipped_extension = pathinfo( $zipped_file_name, PATHINFO_EXTENSION );
// Skip files with transversal paths.
if ( strpos( $zipped_file_name, '..' ) !== false ) {
continue;
}
if ( in_array( $zipped_extension, $valid_field_types, true ) ) {
$valid_entries[] = $zipped_file_name;
}
}
$unzip_result = false;
if ( ! empty( $valid_entries ) ) {
$unzip_result = $zip->extractTo( $to, $valid_entries );
}
if ( ! $unzip_result ) {
$unzip_result = new \WP_Error( 'error', esc_html__( 'Could not unzip or empty archive.', 'elementor-pro' ) );
}
@unlink( $file );
return $unzip_result; // TRUE | WP_Error instance.
}
private function upload_and_extract_zip() {
$zip_file = $this->upload();
if ( is_wp_error( $zip_file ) ) {
return $zip_file;
}
$filesystem = self::get_wp_filesystem();
$extract_to = trailingslashit( get_temp_dir() . pathinfo( $zip_file, PATHINFO_FILENAME ) );
$unzipped = $this->extract_zip( $zip_file, $extract_to );
if ( is_wp_error( $unzipped ) ) {
return $unzipped;
}
// Find the right folder.
$source_files = array_keys( $filesystem->dirlist( $extract_to ) );
if ( count( $source_files ) === 0 ) {
return new \WP_Error( 'incompatible_archive', esc_html__( 'Incompatible archive', 'elementor-pro' ) );
}
if ( 1 === count( $source_files ) && $filesystem->is_dir( $extract_to . $source_files[0] ) ) {
$directory = $extract_to . trailingslashit( $source_files[0] );
} else {
$directory = $extract_to;
}
return [
'directory' => $directory,
'extracted_to' => $extract_to,
];
}
public function custom_icons_upload_handler( $data ) {
if ( ! current_user_can( Icons_Manager::CAPABILITY ) ) {
return new \WP_Error( Exceptions::FORBIDDEN, 'Access denied.' );
}
$this->current_post_id = $data['post_id'];
$results = $this->upload_and_extract_zip();
if ( is_wp_error( $results ) ) {
return $results;
}
$supported_icon_sets = self::get_supported_icon_sets();
foreach ( $supported_icon_sets as $key => $handler ) {
/**
* @var IconSets\Icon_Set_Base $icon_set_handler
*/
$icon_set_handler = new $handler( $results['directory'] );
if ( ! $icon_set_handler ) {
continue;
}
if ( ! $icon_set_handler->is_valid() ) {
continue;
}
$icon_set_handler->handle_new_icon_set();
$icon_set_handler->move_files( $this->current_post_id );
$config = $icon_set_handler->build_config();
// Notify about duplicate prefix
if ( self::icon_set_prefix_exists( $config['prefix'] ) ) {
$config['duplicate_prefix'] = true;
}
return [
'config' => $config,
];
}
return new \WP_Error( 'unsupported_zip_format', esc_html__( 'The zip file provided is not supported!', 'elementor-pro' ) );
}
public function handle_delete_icon_set( $post_id ) {
if ( Icons_Manager::CPT !== get_post_type( $post_id ) ) {
return;
}
// remove all assets related to this icon set
$attachments = get_attached_media( '', $post_id );
foreach ( $attachments as $attachment ) {
wp_delete_attachment( $attachment->ID, 'true' );
}
// remove icon set assets directory
$icon_set_dir = get_post_meta( $post_id, '_elementor_icon_set_path', true );
if ( ! empty( $icon_set_dir ) && is_dir( $icon_set_dir ) ) {
$this::get_wp_filesystem()->rmdir( $icon_set_dir, true );
}
// Force refresh of list in Options Table
self::clear_icon_list_option();
}
public static function clear_icon_list_option() {
delete_option( self::OPTION_NAME );
}
public function display_post_states( $post_states, $post ) {
if ( 'publish' !== $post->post_status || Icons_Manager::CPT !== $post->post_type ) {
return $post_states;
}
$data = json_decode( self::get_icon_set_config( $post->ID ) );
if ( ! empty( $data->count ) ) {
echo sprintf( '%d ', esc_html( $data->count ) );
}
return $post_states;
}
/**
* Render preview column in font manager admin listing
*
* @param $column
* @param $post_id
*/
public function render_columns( $column, $post_id ) {
if ( 'icons_prefix' === $column ) {
$data = json_decode( self::get_icon_set_config( $post_id ) );
if ( ! empty( $data->prefix ) ) {
echo '' . esc_html( '.' . $data->prefix ) . ' ';
}
}
}
/**
* Define which columns to display in font manager admin listing
*
* @param $columns
*
* @return array
*/
public function manage_columns( $columns ) {
return [
'cb' => ' ',
'title' => esc_html__( 'Icon Set', 'elementor-pro' ),
'icons_prefix' => esc_html__( 'CSS Prefix', 'elementor-pro' ),
];
}
public function update_enter_title_here( $title, $post ) {
if ( isset( $post->post_type ) && Icons_Manager::CPT === $post->post_type ) {
return esc_html__( 'Enter Icon Set Name', 'elementor-pro' );
}
return $title;
}
public function register_ajax_actions( Ajax $ajax ) {
$ajax->register_ajax_action( 'pro_assets_manager_custom_icon_upload', [ $this, 'custom_icons_upload_handler' ] );
}
public function register_icon_libraries_control( $additional_sets ) {
return array_replace( $additional_sets, self::get_custom_icons_config() );
}
public function add_custom_icon_templates( $current_screen ) {
if ( 'elementor_icons' !== $current_screen->id || 'post' !== $current_screen->base ) {
return;
}
Plugin::elementor()->common->add_template( __DIR__ . '/templates.php' );
}
public function add_custom_icons_url( $config ) {
$config['customIconsURL'] = admin_url( 'edit.php?post_type=' . Icons_Manager::CPT );
return $config;
}
public static function get_custom_icons_config() {
$config = get_option( self::OPTION_NAME, false );
if ( false === $config ) {
$icons = new \WP_Query( [
'post_type' => Icons_Manager::CPT,
'posts_per_page' => -1,
'post_status' => 'publish',
] );
$config = [];
foreach ( $icons->posts as $icon_set ) {
$set_config = json_decode( self::get_icon_set_config( $icon_set->ID ), true );
$set_config['custom_icon_post_id'] = $icon_set->ID;
$set_config['label'] = $icon_set->post_title;
if ( isset( $set_config['fetchJson'] ) ) {
unset( $set_config['icons'] );
}
$config[ $set_config['name'] ] = $set_config;
}
update_option( self::OPTION_NAME, $config );
}
return $config;
}
public static function icon_set_prefix_exists( $prefix ) {
$config = self::get_custom_icons_config();
if ( empty( $config ) ) {
return false;
}
foreach ( $config as $icon_set_name => $icon_config ) {
if ( $prefix === $icon_config['prefix'] ) {
return true;
}
}
return false;
}
public function transition_post_status( $new_status, $old_status, $post ) {
if ( Icons_Manager::CPT !== $post->post_type ) {
return;
}
if ( 'publish' === $old_status && 'publish' !== $new_status ) {
$this->clear_icon_list_option();
}
}
protected function actions() {
parent::actions();
if ( is_admin() ) {
add_action( 'add_meta_boxes_' . Icons_Manager::CPT, [ $this, 'add_meta_box' ] );
add_action( 'save_post_' . Icons_Manager::CPT, [ $this, 'save_post_meta' ], 10, 3 );
add_filter( 'display_post_states', [ $this, 'display_post_states' ], 10, 2 );
add_action( 'manage_' . Icons_Manager::CPT . '_posts_custom_column', [ $this, 'render_columns' ], 10, 2 );
add_filter( 'enter_title_here', [ $this, 'update_enter_title_here' ], 10, 2 );
add_filter( 'manage_' . Icons_Manager::CPT . '_posts_columns', [ $this, 'manage_columns' ], 100 );
add_action( 'current_screen', [ $this, 'add_custom_icon_templates' ] );
}
add_action( 'transition_post_status', [ $this, 'transition_post_status' ], 10, 3 );
add_action( 'before_delete_post', [ $this, 'handle_delete_icon_set' ] );
add_filter( 'elementor/icons_manager/additional_tabs', [ $this, 'register_icon_libraries_control' ] );
add_filter( 'elementor/editor/localize_settings', [ $this, 'add_custom_icons_url' ] );
// Ajax.
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
}
}
assets-manager/asset-types/admin-menu-items/custom-fonts-menu-item.php 0000644 00000001314 15043204017 0022153 0 ustar 00 license_admin->get_connect_url( [
'utm_source' => 'wp-custom-fonts',
'utm_medium' => 'wp-dash',
'utm_campaign' => 'connect-and-activate-license',
] );
$renew_url = 'https://go.elementor.com/renew-custom-fonts/';
return API::is_license_expired()
? $renew_url
: $connect_url;
}
public function get_cta_text() {
return API::is_license_expired()
? esc_html__( 'Renew now', 'elementor-pro' )
: esc_html__( 'Connect & Activate', 'elementor-pro' );
}
public function get_label() {
return esc_html__( 'Custom Fonts', 'elementor-pro' );
}
public function get_page_title() {
return esc_html__( 'Custom Fonts', 'elementor-pro' );
}
public function get_promotion_title() {
return esc_html__( 'Add Your Custom Fonts', 'elementor-pro' );
}
public function render_promotion_description() {
echo esc_html__(
'Custom Fonts allows you to add your self-hosted fonts and use them on your Elementor projects to create a unique brand language.',
'elementor-pro'
);
}
}
assets-manager/asset-types/admin-menu-items/custom-icons-menu-item.php 0000644 00000001314 15043204017 0022135 0 ustar 00 license_admin->get_connect_url( [
'utm_source' => 'wp-custom-icons',
'utm_medium' => 'wp-dash',
'utm_campaign' => 'connect-and-activate-license',
] );
$renew_url = 'https://go.elementor.com/renew-custom-icons/';
return API::is_license_expired()
? $renew_url
: $connect_url;
}
public function get_position() {
return null;
}
public function get_cta_text() {
return API::is_license_expired()
? esc_html__( 'Renew now', 'elementor-pro' )
: esc_html__( 'Connect & Activate', 'elementor-pro' );
}
public function get_label() {
return esc_html__( 'Custom Icons', 'elementor-pro' );
}
public function get_page_title() {
return esc_html__( 'Custom Icons', 'elementor-pro' );
}
public function get_promotion_title() {
return esc_html__( 'Add Your Custom Icons', 'elementor-pro' );
}
public function render_promotion_description() {
echo esc_html__(
'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-pro'
);
}
}
assets-manager/asset-types/fonts-manager.php 0000644 00000043022 15043204017 0015206 0 ustar 00 font_types;
}
if ( isset( $this->font_types[ $type ] ) ) {
return $this->font_types[ $type ];
}
return false;
}
/**
* Add a font type to the font manager
*
* @param string $font_type
* @param Classes\Font_Base $instance
*/
public function add_font_type( $font_type, $instance ) {
$this->font_types[ $font_type ] = $instance;
}
/**
* Register elementor font custom post type and elementor font type custom taxonomy
*/
public function register_post_type_and_tax() {
$labels = [
'name' => _x( 'Custom Fonts', 'CPT Name', 'elementor-pro' ),
'singular_name' => _x( 'Font', 'CPT Singular Name', 'elementor-pro' ),
'add_new' => esc_html__( 'Add New', 'elementor-pro' ),
'add_new_item' => esc_html__( 'Add New Font', 'elementor-pro' ),
'edit_item' => esc_html__( 'Edit Font', 'elementor-pro' ),
'new_item' => esc_html__( 'New Font', 'elementor-pro' ),
'all_items' => esc_html__( 'All Fonts', 'elementor-pro' ),
'view_item' => esc_html__( 'View Font', 'elementor-pro' ),
'search_items' => esc_html__( 'Search Font', 'elementor-pro' ),
'not_found' => esc_html__( 'No fonts found', 'elementor-pro' ),
'not_found_in_trash' => esc_html__( 'No fonts found in trash', 'elementor-pro' ),
'parent_item_colon' => '',
'menu_name' => _x( 'Custom Fonts', 'CPT Menu Name', 'elementor-pro' ),
];
$args = [
'labels' => $labels,
'public' => false,
'rewrite' => false,
'show_ui' => true,
'show_in_menu' => false,
'show_in_nav_menus' => false,
'exclude_from_search' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => [ 'title' ],
];
$this->post_type_object = register_post_type( self::CPT, $args );
$taxonomy_labels = [
'name' => _x( 'Font Types', 'Font type taxonomy general name', 'elementor-pro' ),
'singular_name' => _x( 'Font Type', 'Font type singular name', 'elementor-pro' ),
'search_items' => esc_html__( 'Search Font Types', 'elementor-pro' ),
'popular_items' => esc_html__( 'Popular Font Types', 'elementor-pro' ),
'all_items' => esc_html__( 'All Font Types', 'elementor-pro' ),
'edit_item' => esc_html__( 'Edit Font Type', 'elementor-pro' ),
'update_item' => esc_html__( 'Update Font Type', 'elementor-pro' ),
'add_new_item' => esc_html__( 'Add New Font Type', 'elementor-pro' ),
'new_item_name' => esc_html__( 'New Font Type Name', 'elementor-pro' ),
'separate_items_with_commas' => esc_html__( 'Separate Font Types with commas', 'elementor-pro' ),
'add_or_remove_items' => esc_html__( 'Add or remove Font Types', 'elementor-pro' ),
'choose_from_most_used' => esc_html__( 'Choose from the most used Font Types', 'elementor-pro' ),
'not_found' => esc_html__( 'No Font Types found.', 'elementor-pro' ),
'menu_name' => esc_html__( 'Font Types', 'elementor-pro' ),
];
$taxonomy_args = [
'labels' => $taxonomy_labels,
'hierarchical' => false,
'show_ui' => true,
'show_in_nav_menus' => false,
'query_var' => is_admin(),
'rewrite' => false,
'public' => false,
'meta_box_cb' => [ $this, 'print_taxonomy_metabox' ],
];
$this->taxonomy_object = register_taxonomy( self::TAXONOMY, self::CPT, $taxonomy_args );
}
public function post_updated_messages( $messages ) {
$messages[ self::CPT ] = [
0 => '', // Unused. Messages start at index 1.
1 => esc_html__( 'Font updated.', 'elementor-pro' ),
2 => esc_html__( 'Custom field updated.', 'elementor-pro' ),
3 => esc_html__( 'Custom field deleted.', 'elementor-pro' ),
4 => esc_html__( 'Font updated.', 'elementor-pro' ),
/* translators: %s: Date and time of the revision. */
5 => isset( $_GET['revision'] ) ? sprintf( esc_html__( 'Font restored to revision from %s', 'elementor-pro' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
6 => esc_html__( 'Font saved.', 'elementor-pro' ),
7 => esc_html__( 'Font saved.', 'elementor-pro' ),
8 => esc_html__( 'Font submitted.', 'elementor-pro' ),
9 => esc_html__( 'Font updated.', 'elementor-pro' ),
10 => esc_html__( 'Font draft updated.', 'elementor-pro' ),
];
return $messages;
}
/**
* Print Font Type metabox
*
* @param $post
* @param $box
*/
public function print_taxonomy_metabox( $post, $box ) {
wp_nonce_field( self::CPT, self::CPT . '_nonce' );
$name = self::TAXONOMY;
?>
ID, $name );
$slug = false;
if ( is_array( $term_obj ) && isset( $term_obj[0] ) ) {
$slug = $term_obj[0]->slug;
}
$options = '';
foreach ( $this->font_types as $type => $instance ) {
$options .= sprintf( '%s ' . "\n", $type, selected( $slug, $type, false ), $instance->get_name() );
}
?>
can_use_custom_fonts() ) {
$admin_menu_manager->register( static::MENU_SLUG, new Custom_Fonts_Menu_Item() );
} else {
$admin_menu_manager->register( static::PROMOTION_MENU_SLUG, new Custom_Fonts_Promotion_Menu_Item() );
}
}
private function can_use_custom_fonts() {
return ( API::is_license_active() || $this->has_fonts() );
}
private function has_fonts() {
if ( null !== $this->has_fonts ) {
return $this->has_fonts;
}
$existing_fonts = new \WP_Query( [
'post_type' => static::CPT,
'posts_per_page' => 1,
] );
$this->has_fonts = $existing_fonts->post_count > 0;
return $this->has_fonts;
}
public function redirect_admin_old_page_to_new() {
if ( ! empty( $_GET['page'] ) && 'elementor_custom_fonts' === $_GET['page'] ) {
wp_safe_redirect( admin_url( static::MENU_SLUG ) );
die;
}
}
/**
* Render preview column in font manager admin listing
*
* @param $column
* @param $post_id
*/
public function render_columns( $column, $post_id ) {
if ( 'font_preview' === $column ) {
$font_type = $this->get_font_type_by_post_id( $post_id, true );
if ( false === $font_type ) {
return;
}
$font_type->render_preview_column( $post_id );
}
}
/**
* Handle editor request to embed/link font CSS per font type
*
* @param array $data
*
* @return array
* @throws \Exception
*/
public function assets_manager_panel_action_data( array $data ) {
$document = Pro_Utils::_unstable_get_document_for_edit( $data['editor_post_id'] );
if ( empty( $data['type'] ) ) {
throw new \Exception( 'Font type is required.' );
}
if ( empty( $data['font'] ) ) {
throw new \Exception( 'Font is required.' );
}
$asset = $this->get_font_type_object( $data['type'] );
if ( ! $asset ) {
throw new \Exception( 'Font type not found.' );
}
try {
return $asset->handle_panel_request( $data );
} catch ( \Exception $exception ) {
throw $exception;
}
}
/**
* Clean up admin Font manager admin listing
*/
public function clean_admin_listing_page() {
global $typenow;
if ( self::CPT !== $typenow ) {
return;
}
add_filter( 'months_dropdown_results', '__return_empty_array' );
add_action( 'manage_' . self::CPT . '_posts_custom_column', [ $this, 'render_columns' ], 10, 2 );
add_filter( 'display_post_states', [ $this, 'display_post_states' ], 10, 2 );
add_filter( 'screen_options_show_screen', '__return_false' );
}
public function update_enter_title_here( $title, $post ) {
if ( isset( $post->post_type ) && self::CPT === $post->post_type ) {
return esc_html__( 'Enter Font Family', 'elementor-pro' );
}
return $title;
}
public function post_row_actions( $actions, $post ) {
if ( self::CPT !== $post->post_type ) {
return $actions;
}
unset( $actions['inline hide-if-no-js'] );
return $actions;
}
public function display_post_states( $post_states, $post ) {
$font_type = $this->get_font_type_by_post_id( $post->ID, true );
if ( false !== $font_type ) {
$font_type->get_font_variations_count( $post->ID );
}
return $post_states;
}
/**
* Define which columns to display in font manager admin listing
*
* @param $columns
*
* @return array
*/
public function manage_columns( $columns ) {
return [
'cb' => ' ',
'title' => esc_html__( 'Font Family', 'elementor-pro' ),
'font_preview' => esc_html__( 'Preview', 'elementor-pro' ),
];
}
public function register_fonts_in_control( $fonts ) {
$custom_fonts = $this->get_font_types();
if ( empty( $custom_fonts ) ) {
$this->generate_fonts_list();
$custom_fonts = $this->get_font_types();
}
return array_replace( $custom_fonts, $fonts );
}
public function register_fonts_groups( $font_groups ) {
$new_groups = [];
foreach ( $this->get_font_type_object() as $type => $instance ) {
$new_groups[ $type ] = $instance->get_name();
}
return array_replace( $new_groups, $font_groups );
}
/**
* Gets a Font type for any given post id
*
* @param $post_id
* @param bool $return_object
*
* @return array|bool|Classes\Font_Base
*/
private function get_font_type_by_post_id( $post_id, $return_object = false ) {
$term_obj = get_the_terms( $post_id, self::TAXONOMY );
if ( is_array( $term_obj ) ) {
$type_obj = array_shift( $term_obj );
if ( false === $return_object ) {
return $type_obj->slug;
}
return $this->get_font_type_object( $type_obj->slug );
}
return false;
}
/**
* Get font manager fonts as font family => font type array
* @return array
*/
private function get_font_types() {
static $font_types = false;
if ( ! $font_types ) {
$font_types = get_option( self::FONTS_NAME_TYPE_OPTION_NAME, [] );
}
return $font_types;
}
/**
* Generates a list of all Font Manager fonts and stores it in the options table
* @return array
*/
private function generate_fonts_list() {
$fonts = new \WP_Query( [
'post_type' => self::CPT,
'posts_per_page' => -1,
] );
$new_fonts = [];
$font_types = [];
foreach ( $fonts->posts as $font ) {
$font_type = $this->get_font_type_by_post_id( $font->ID, true );
if ( false === $font_type ) {
continue;
}
$font_types = array_replace( $font_types, $font_type->get_font_family_type( $font->ID, $font->post_title ) );
$new_fonts = array_replace( $new_fonts, $font_type->get_font_data( $font->ID, $font->post_title ) );
}
update_option( self::FONTS_NAME_TYPE_OPTION_NAME, $font_types );
update_option( self::FONTS_OPTION_NAME, $new_fonts );
return $new_fonts;
}
/**
* runs on Elementor font post save and calls the font type handler save meta method
*
* @param int $post_id
* @param \WP_Post $post
* @param bool $update
*
* @return mixed
*/
public function save_post_meta( $post_id, $post, $update ) {
// If this is an autosave, our form has not been submitted,
// so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
// Check if our nonce is set.
if ( ! isset( $_POST[ self::CPT . '_nonce' ] ) ) {
return $post_id;
}
// Verify that the nonce is valid.
if ( ! wp_verify_nonce(
Pro_Utils::_unstable_get_super_global_value( $_POST, self::CPT . '_nonce' ),
self::CPT
) ) {
return $post_id;
}
// Save font type
// only custom for now
$custom_font = $this->get_font_type_object( 'custom' );
wp_set_object_terms( $post_id, $custom_font->get_type(), self::TAXONOMY );
// Let Font type handle saving
// Sanitize the whole $_POST array
$custom_font->save_meta( $post_id, Pro_Utils::_unstable_get_super_global_value( [ 'data' => $_POST ], 'data' ) );
}
/**
* Helper to clean font list on save/update
*/
public function clear_fonts_list() {
delete_option( self::FONTS_OPTION_NAME );
delete_option( self::FONTS_NAME_TYPE_OPTION_NAME );
}
/**
* Get fonts array form the database or generate a new list if $force is set to true
*
* @param bool $force
*
* @return array|bool|mixed
*/
public function get_fonts() {
static $fonts = false;
if ( false !== $fonts ) {
return $fonts;
}
$fonts = $this->generate_fonts_list();
$fonts = get_option( self::FONTS_OPTION_NAME, false );
return $fonts;
}
/**
* Enqueue fonts css
*
* @param $post_css
*/
public function enqueue_fonts( $post_css ) {
$used_fonts = $post_css->get_fonts();
$font_manager_fonts = $this->get_fonts();
$font_types = $this->get_font_types();
foreach ( $used_fonts as $font_family ) {
if ( ! isset( $font_types[ $font_family ] ) || in_array( $font_family, $this->enqueued_fonts ) ) {
continue;
}
$font_type = $this->get_font_type_object( $font_types[ $font_family ] );
if ( ! $font_type ) {
continue;
}
$font_data = [];
if ( isset( $font_manager_fonts[ $font_family ] ) ) {
$font_data = $font_manager_fonts[ $font_family ];
}
$font_type->enqueue_font( $font_family, $font_data, $post_css );
$this->enqueued_fonts[] = $font_family;
}
}
public function register_ajax_actions( Ajax $ajax ) {
$ajax->register_ajax_action( 'pro_assets_manager_panel_action_data', [ $this, 'assets_manager_panel_action_data' ] );
}
public function add_finder_item( array $categories ) {
$categories['settings']['items']['custom-fonts'] = [
'title' => esc_html__( 'Custom Fonts', 'elementor-pro' ),
'icon' => 'typography',
'url' => admin_url( static::MENU_SLUG ),
'keywords' => [ 'custom', 'fonts', 'elementor' ],
];
if ( ! $this->can_use_custom_fonts() ) {
$lock = new Feature_Lock( [ 'type' => 'custom-font' ] );
$categories['settings']['items']['custom-fonts']['lock'] = $lock->get_config();
}
return $categories;
}
/**
* Register Font Manager action and filter hooks
*/
protected function actions() {
add_action( 'init', [ $this, 'register_post_type_and_tax' ] );
if ( is_admin() ) {
add_action( 'init', [ $this, 'redirect_admin_old_page_to_new' ] );
add_action( 'elementor/admin/menu/register', function ( Admin_Menu_Manager $admin_menu_manager ) {
$this->register_admin_menu( $admin_menu_manager );
} );
// TODO: BC - Remove after `Admin_Menu_Manager` will be the standard.
add_action( 'admin_menu', function () {
if ( did_action( 'elementor/admin/menu/register' ) ) {
return;
}
$menu_title = _x( 'Custom Fonts', 'Elementor Font', 'elementor-pro' );
add_submenu_page(
Settings::PAGE_ID,
$menu_title,
$menu_title,
self::CAPABILITY,
static::MENU_SLUG
);
}, 50 );
add_action( 'admin_head', [ $this, 'clean_admin_listing_page' ] );
}
// TODO: Maybe just ignore all of those when the user can't use custom fonts?
add_filter( 'post_row_actions', [ $this, 'post_row_actions' ], 10, 2 );
add_filter( 'manage_' . self::CPT . '_posts_columns', [ $this, 'manage_columns' ], 100 );
add_action( 'save_post_' . self::CPT, [ $this, 'save_post_meta' ], 10, 3 );
add_action( 'save_post_' . self::CPT, [ $this, 'clear_fonts_list' ], 100 );
add_filter( 'elementor/fonts/groups', [ $this, 'register_fonts_groups' ] );
add_filter( 'elementor/fonts/additional_fonts', [ $this, 'register_fonts_in_control' ] );
add_filter( 'elementor/finder/categories', [ $this, 'add_finder_item' ] );
add_action( 'elementor/css-file/post/parse', [ $this, 'enqueue_fonts' ] );
add_action( 'elementor/css-file/global/parse', [ $this, 'enqueue_fonts' ] );
add_filter( 'post_updated_messages', [ $this, 'post_updated_messages' ] );
add_filter( 'enter_title_here', [ $this, 'update_enter_title_here' ], 10, 2 );
// Ajax.
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
/**
* Elementor fonts manager loaded.
*
* Fires after the fonts manager was fully loaded and instantiated.
*
* @since 2.0.0
*
* @param Fonts_Manager $this An instance of fonts manager.
*/
do_action( 'elementor_pro/fonts_manager_loaded', $this );
}
/**
* Fonts_Manager constructor.
*/
public function __construct() {
$this->actions();
$this->add_font_type( 'custom', new Fonts\Custom_Fonts() );
$this->add_font_type( 'typekit', new Fonts\Typekit_Fonts() );
}
}
assets-manager/asset-types/fonts/typekit-fonts.php 0000644 00000017374 15043204017 0016431 0 ustar 00 get_typekit_kit_id();
if ( ! $kit_id ) {
return false;
}
$response = wp_remote_get( $this->api_base . '/' . $kit_id . '/published' );
// Response is a WP_Error object
if ( is_wp_error( $response ) ) {
return false;
}
// Response code is not success
$response_code = (int) wp_remote_retrieve_response_code( $response );
$response_body = json_decode( wp_remote_retrieve_body( $response ) );
if ( 200 !== $response_code ) {
switch ( $response_code ) {
case 404:
$this->error = esc_html__( 'Project not found.', 'elementor-pro' );
break;
default:
$this->error = $response_code;
if ( isset( $response_body->errors ) ) {
$this->error .= ': ' . implode( ', ', $response_body->errors );
}
break;
}
return false;
}
if ( ! $response_body ) {
$this->error = esc_html__( 'No project data was returned.', 'elementor-pro' );
return false;
}
/*
* Expected Json response example
* {
* "kit": {
* "id": "nmm7qvq",
* "families": [
* {
* "id": "hmqz",
* "name": "Adobe Caslon Pro",
* "slug": "adobe-caslon-pro",
* "css_names": [
* "adobe-caslon-pro"
* ],
* "css_stack": "\"adobe-caslon-pro\",serif",
* "variations": [ "n6","i6","i7" ]
* }
* ]
* }
* }
*/
if ( ! is_object( $response_body ) || ! isset( $response_body->kit ) || ! isset( $response_body->kit->families ) || ! is_array( $response_body->kit->families ) ) {
return false;
}
$families = [];
foreach ( $response_body->kit->families as $font_family ) {
$font_css = isset( $font_family->css_names[0] ) ? $font_family->css_names[0] : $font_family->slug;
$families[ $font_css ] = $this->get_type();
}
update_option( self::TYPEKIT_FONTS_OPTION_NAME, $families );
return $families;
}
private function get_kit_fonts() {
$typekit_fonts = $this->get_typekit_fonts();
if ( ! $typekit_fonts ) {
$typekit_fonts = $this->fetch_typekit_data();
}
return $typekit_fonts;
}
/**
* @param array $data
*
* @return array
* @throws \Exception
*/
public function handle_panel_request( array $data ) {
$font_family = sanitize_text_field( $data['font'] );
$typekit_fonts = $this->get_kit_fonts();
if ( ! $typekit_fonts || ! is_array( $typekit_fonts ) ) {
throw new \Exception( 'Error with TypeKit fonts.' );
}
if ( ! in_array( $font_family, array_keys( $typekit_fonts ) ) ) {
throw new \Exception( 'Font missing in Project.' );
}
$kit_id = $this->get_typekit_kit_id();
return [ 'font_url' => sprintf( self::TYPEKIT_FONTS_LINK, $kit_id ) ];
}
public function sanitize_kit_id_settings( $input ) {
if ( empty( $input ) ) {
delete_option( self::TYPEKIT_FONTS_OPTION_NAME );
}
return $input;
}
public function register_admin_fields( Settings $settings ) {
$fonts = $this->get_typekit_fonts();
$button_label = esc_html__( 'Get Project ID', 'elementor-pro' );
$found_label = '{{count}} ' . esc_html__( 'Fonts Families Found in project. Please note that typekit takes a few minutes to sync once you publish or update a project.', 'elementor-pro' );
if ( $fonts && is_array( $fonts ) ) {
$button_label = esc_html__( 'Sync Project', 'elementor-pro' );
}
$settings->add_section( Settings::TAB_INTEGRATIONS, 'typekit', [
'callback' => function() {
echo '' . esc_html__( 'Adobe Fonts (TypeKit)', 'elementor-pro' ) . ' ';
esc_html_e( 'TypeKit partners with the world’s leading type foundries to bring thousands of beautiful fonts to designers every day.', 'elementor-pro' );
},
'fields' => [
self::TYPEKIT_KIT_ID_OPTION_NAME => [
'label' => esc_html__( 'Project ID', 'elementor-pro' ),
'field_args' => [
'type' => 'text',
'desc' => sprintf(
/* translators: 1: Link opening tag, 2: Link closing tag. */
esc_html__( 'Enter Your %1$sTypeKit Project ID%2$s.', 'elementor-pro' ),
'',
' '
),
],
'setting_args' => [
'sanitize_callback' => [ $this, 'sanitize_kit_id_settings' ],
],
],
'validate_api_data' => [
'field_args' => [
'type' => 'raw_html',
'html' => sprintf( '%s
',
esc_html( $found_label ),
self::TYPEKIT_KIT_ID_OPTION_NAME . '_fetch',
wp_create_nonce( self::TYPEKIT_KIT_ID_OPTION_NAME ),
$button_label
),
],
],
],
] );
}
public function register_fonts_in_control( $fonts ) {
$typekit_fonts = $this->get_kit_fonts();
if ( $typekit_fonts ) {
return array_merge( $typekit_fonts, $fonts );
}
return $fonts;
}
public function print_font_link( $font ) {
if ( $this->kit_enqueued ) {
return;
}
if ( $this->is_font_in_kit( $font ) ) {
$kit_url = sprintf( self::TYPEKIT_FONTS_LINK, $this->get_typekit_kit_id() );
echo ' ';
$this->kit_enqueued = true;
}
}
private function is_font_in_kit( $font ) {
$kit_fonts = $this->get_kit_fonts();
if ( ! $kit_fonts || ! is_array( $kit_fonts ) ) {
return false;
}
return in_array( $font, array_keys( $kit_fonts ) );
}
public function integrations_admin_ajax_handler() {
check_ajax_referer( self::TYPEKIT_KIT_ID_OPTION_NAME, '_nonce' );
if ( ! current_user_can( Fonts_Manager::CAPABILITY ) ) {
wp_send_json_error( 'Permission denied' );
}
$kit_id = Utils::_unstable_get_super_global_value( $_POST, 'kit_id' );
if ( ! $kit_id ) {
wp_send_json_error();
}
$fonts = [];
try {
update_option( 'elementor_' . self::TYPEKIT_KIT_ID_OPTION_NAME, sanitize_text_field( $kit_id ) );
$fonts = $this->fetch_typekit_data();
} catch ( \Exception $exception ) {
wp_send_json_error();
}
wp_send_json_success( [
'fonts' => $fonts,
'count' => count( $fonts ),
] );
}
protected function actions() {
parent::actions();
if ( is_admin() ) {
add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 100 );
}
add_filter( 'elementor/fonts/additional_fonts', [ $this, 'register_fonts_in_control' ] );
add_action( 'elementor/fonts/print_font_links/' . $this->get_type(), [ $this, 'print_font_link' ] );
add_action( 'wp_ajax_elementor_pro_admin_fetch_fonts', [ $this, 'integrations_admin_ajax_handler' ] );
}
}
assets-manager/asset-types/fonts/custom-fonts.php 0000644 00000033203 15043204017 0016237 0 ustar 00 'font/woff|application/font-woff|application/x-font-woff|application/octet-stream',
'woff2' => 'font/woff2|application/octet-stream|font/x-woff2',
'ttf' => 'application/x-font-ttf|application/octet-stream|font/ttf',
'svg' => 'image/svg+xml|application/octet-stream|image/x-svg+xml',
'eot' => 'application/vnd.ms-fontobject|application/octet-stream|application/x-vnd.ms-fontobject',
];
}
public function add_meta_box() {
add_meta_box(
'elementor-font-' . $this->get_type() . 'metabox',
__( 'Manage Your Font Files', 'elementor-pro' ),
[ $this, 'render_metabox' ],
Fonts_Manager::CPT,
'normal',
'default'
);
}
public function render_metabox( $post ) {
wp_enqueue_media();
$fields = [
[
'id' => 'open_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'attributes' => [
'class' => 'repeater-content-top',
],
],
[
'id' => 'font_weight',
'field_type' => 'select',
'label' => esc_html__( 'Weight', 'elementor-pro' ) . ':',
'extra_attributes' => [
'class' => 'font_weight',
],
'options' => $this->get_font_weight_options(),
],
[
'id' => 'font_style',
'field_type' => 'select',
'label' => esc_html__( 'Style', 'elementor-pro' ) . ':',
'extra_attributes' => [
'class' => 'font_style',
],
'options' => $this->get_font_style_options(),
],
[
'id' => 'preview_label',
'field_type' => 'html',
'label' => false,
'raw_html' => sprintf( '%s
', esc_html__( 'Elementor Is Making the Web Beautiful!!!', 'elementor-pro' ) ),
],
[
'id' => 'toolbar',
'field_type' => 'toolbar',
'label' => false,
],
[
'id' => 'close_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'close' => true,
],
[
'id' => 'open_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'attributes' => [
'class' => 'repeater-content-bottom',
],
],
];
foreach ( $this->get_file_types() as $type => $mine ) {
$fields[] = [
'id' => $type,
'field_type' => 'file',
'mine' => str_replace( '|', ',', $mine ),
'ext' => $type,
/* translators: %s: Font file format. */
'label' => sprintf( esc_html__( '%s File', 'elementor-pro' ), strtoupper( $type ) ),
/* translators: %s: Font file format. */
'box_title' => sprintf( esc_html__( 'Upload font .%s file', 'elementor-pro' ), $type ),
/* translators: %s: Font file format. */
'box_action' => sprintf( esc_html__( 'Select .%s file', 'elementor-pro' ), $type ),
'preview_anchor' => 'none',
'description' => $this->get_file_type_description( $type ),
];
}
$fields[] = [
'id' => 'close_div',
'field_type' => 'html_tag',
'label' => false,
'tag' => 'div',
'close' => true,
];
$font_data = get_post_meta( $post->ID, self::FONT_META_KEY, true );
$repeater = [
'fields' => $fields,
'id' => 'font_face',
'label' => false,
'add_label' => esc_html__( 'Add Font Variation', 'elementor-pro' ),
'toggle_title' => esc_html__( 'Edit', 'elementor-pro' ),
'remove_title' => esc_html__( 'Delete', 'elementor-pro' ),
'field_type' => 'repeater',
'row_label' => [
'default' => 'Settings',
'selector' => '.font_weight',
],
'saved' => $font_data,
];
$this->print_metabox( [ $repeater ] );
// PHPCS - Dedicated for CSS.
printf( '', get_post_meta( $post->ID, self::FONT_FACE_META_KEY, true ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
public function save_meta( $post_id, $data ) {
if ( ! isset( $data['font_face'] ) || ! is_array( $data['font_face'] ) ) {
return;
}
// Sanitize a little
$font_face = [];
foreach ( $data['font_face'] as $font_data ) {
$font_face[] = $this->sanitize_text_field_recursive( $font_data );
}
// All good save the files array
update_post_meta( $post_id, self::FONT_META_KEY, $font_face );
// Save font face
update_post_meta( $post_id, self::FONT_FACE_META_KEY, $this->generate_font_face( $post_id ) );
}
public function upload_mimes( $mine_types ) {
if ( current_user_can( Fonts_Manager::CAPABILITY ) && $this->is_elementor_font_upload() ) {
foreach ( $this->get_file_types() as $type => $mine ) {
if ( ! isset( $mine_types[ $type ] ) ) {
$mine_types[ $type ] = $mine;
}
}
}
return $mine_types;
}
public function wp_handle_upload_prefilter( $file ) {
if ( ! $this->is_elementor_font_upload() ) {
return $file;
}
$ext = pathinfo( $file['name'], PATHINFO_EXTENSION );
if ( 'svg' !== $ext ) {
return $file;
}
/**
* @var \Elementor\Core\Files\Assets\Svg\Svg_Handler $svg_handler;
*/
$svg_handler = Plugin::elementor()->assets_manager->get_asset( 'svg-handler' );
if ( Files_Upload_Handler::file_sanitizer_can_run() && ! $svg_handler->sanitize_svg( $file['tmp_name'] ) ) {
$file['error'] = esc_html__( 'Invalid SVG Format, file not uploaded for security reasons', 'elementor-pro' );
}
return $file;
}
private function is_elementor_font_upload() {
return isset( $_POST['uploadTypeCaller'] ) && 'elementor-admin-font-upload' === $_POST['uploadTypeCaller']; // phpcs:ignore
}
/**
* A workaround for upload validation which relies on a PHP extension (fileinfo) with inconsistent reporting behaviour.
* ref: https://core.trac.wordpress.org/ticket/39550
* ref: https://core.trac.wordpress.org/ticket/40175
*/
public function filter_fix_wp_check_filetype_and_ext( $data, $file, $filename, $mimes ) {
if ( ! empty( $data['ext'] ) && ! empty( $data['type'] ) ) {
return $data;
}
$registered_file_types = $this->get_file_types();
$filetype = wp_check_filetype( $filename, $mimes );
if ( ! isset( $registered_file_types[ $filetype['ext'] ] ) ) {
return $data;
}
// Fix incorrect file mime type
$filetype['type'] = explode( '|', $filetype['type'] )[0];
return [
'ext' => $filetype['ext'],
'type' => $filetype['type'],
'proper_filename' => $data['proper_filename'],
];
}
public function generate_font_face( $post_id ) {
$saved = get_post_meta( $post_id, self::FONT_META_KEY, true );
if ( ! is_array( $saved ) ) {
return false;
}
$font_family = get_the_title( $post_id );
$font_face = '';
foreach ( $saved as $font_data ) {
$font_face .= $this->get_font_face_from_data( $font_family, $font_data ) . PHP_EOL;
}
return $font_face;
}
public function get_font_face_from_data( $font_family, $data ) {
$src = [];
foreach ( [ 'eot', 'woff2', 'woff', 'ttf', 'svg' ] as $type ) {
if ( ! isset( $data[ $type ] ) || ! isset( $data[ $type ]['url'] ) || empty( $data[ $type ]['url'] ) ) {
continue;
}
if ( 'svg' === $type ) {
$data[ $type ]['url'] .= '#' . str_replace( ' ', '', $font_family );
}
$src[] = $this->get_font_src_per_type( $type, $data[ $type ]['url'] );
}
$font_face = '@font-face {' . PHP_EOL;
$font_face .= "\tfont-family: '" . $font_family . "';" . PHP_EOL;
$font_face .= "\tfont-style: " . $data['font_style'] . ';' . PHP_EOL;
$font_face .= "\tfont-weight: " . $data['font_weight'] . ';' . PHP_EOL;
$font_face .= "\tfont-display: " . apply_filters( 'elementor_pro/custom_fonts/font_display', 'auto', $font_family, $data ) . ';' . PHP_EOL;
if ( isset( $data['eot'] ) && isset( $data['eot']['url'] ) && ! empty( $data['eot']['url'] ) ) {
$font_face .= "\tsrc: url('" . esc_attr( $data['eot']['url'] ) . "');" . PHP_EOL;
}
$font_face .= "\tsrc: " . implode( ',' . PHP_EOL . "\t\t", $src ) . ';' . PHP_EOL . '}';
return $font_face;
}
private function get_font_src_per_type( $type, $url ) {
$src = 'url(\'' . esc_attr( $url ) . '\') ';
switch ( $type ) {
case 'woff':
case 'woff2':
case 'svg':
$src .= 'format(\'' . $type . '\')';
break;
case 'ttf':
$src .= 'format(\'truetype\')';
break;
case 'eot':
$src = 'url(\'' . esc_attr( $url ) . '?#iefix\') format(\'embedded-opentype\')';
break;
}
return $src;
}
public function get_fonts( $force = false ) {
$fonts = get_option( self::FONTS_OPTION_NAME, false );
if ( $fonts && ! $force ) {
return $fonts;
}
add_filter( 'posts_fields', [ $this, 'posts_fields' ] );
$fonts = new \WP_Query( [
'post_type' => Fonts_Manager::CPT,
'posts_per_page' => -1,
] );
remove_filter( 'posts_fields', [ $this, 'posts_fields' ] );
$new_fonts = [];
foreach ( $fonts->posts as $font ) {
$new_fonts[ $font->post_title ] = 'custom';
}
update_option( self::FONTS_OPTION_NAME, $new_fonts );
return $new_fonts;
}
private function get_font_face_by_font_family( $font_family ) {
global $wpdb;
$id = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = %s LIMIT 1", $font_family, Fonts_Manager::CPT ) );
if ( $id ) {
return get_post_meta( $id, self::FONT_FACE_META_KEY, true );
}
return '';
}
public function render_preview_column( $post_id ) {
$font_face = get_post_meta( $post_id, self::FONT_FACE_META_KEY, true );
if ( ! $font_face ) {
return;
}
// PHPCS - the variable $font_face is CSS. the property $this->font_preview_phrase is safe.
printf( '%s ', $font_face, esc_html( get_the_title( $post_id ) ), $this->font_preview_phrase ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
public function get_font_family_type( $post_id, $post_title ) {
return [
$post_title => $this->get_type(),
];
}
public function get_font_data( $post_id, $post_title ) {
return [
$post_title => [
'font_face' => $this->generate_font_face( $post_id ),
'post_id' => $post_id,
],
];
}
public function get_font_variations_count( $post_id ) {
$data = get_post_meta( $post_id, self::FONT_META_KEY, true );
if ( ! empty( $data ) && count( $data ) > 0 ) {
echo sprintf( '%d ', count( $data ) );
}
}
/**
* @param string $font_family
* @param array $font_data
* @param Base $post_css
*/
public function enqueue_font( $font_family, $font_data, $post_css ) {
$font_faces = isset( $font_data['font_face'] ) ? $font_data['font_face'] : $this->get_font_face_by_font_family( $font_family );
// Add a css comment
$custom_css = '/* Start Custom Fonts CSS */' . $font_faces . '/* End Custom Fonts CSS */';
$post_css->get_stylesheet()->add_raw_css( $custom_css );
}
/**
* @param array $data
*
* @return array
* @throws \Exception
*/
public function handle_panel_request( array $data ) {
$font_family = sanitize_text_field( $data['font'] );
$font_face = $this->get_font_face_by_font_family( $font_family );
if ( empty( $font_face ) ) {
/* translators: %s: Font family. */
$error_message = sprintf( esc_html__( 'Font %s was not found.', 'elementor-pro' ), $font_family );
throw new \Exception( $error_message );
}
return [
'font_face' => $font_face,
];
}
private function get_font_style_options() {
return [
'normal' => esc_html__( 'Normal', 'elementor-pro' ),
'italic' => esc_html__( 'Italic', 'elementor-pro' ),
'oblique' => esc_html__( 'Oblique', 'elementor-pro' ),
];
}
private function get_font_weight_options() {
return [
'normal' => esc_html__( 'Normal', 'elementor-pro' ),
'bold' => esc_html__( 'Bold', 'elementor-pro' ),
'100' => '100',
'200' => '200',
'300' => '300',
'400' => '400',
'500' => '500',
'600' => '600',
'700' => '700',
'800' => '800',
'900' => '900',
];
}
private function get_file_type_description( $file_type ) {
$descriptions = [
'eot' => esc_html__( 'Embedded OpenType, Used by IE6-IE9 Browsers', 'elementor-pro' ),
'woff2' => esc_html__( 'The Web Open Font Format 2, Used by Super Modern Browsers', 'elementor-pro' ),
'woff' => esc_html__( 'The Web Open Font Format, Used by Modern Browsers', 'elementor-pro' ),
'ttf' => esc_html__( 'TrueType Fonts, Used for better supporting Safari, Android, iOS', 'elementor-pro' ),
'svg' => esc_html__( 'SVG fonts allow SVG to be used as glyphs when displaying text, Used by Legacy iOS', 'elementor-pro' ),
];
return isset( $descriptions[ $file_type ] ) ? $descriptions[ $file_type ] : '';
}
private function replace_urls( $rows_affected, $from, $to ) {
global $wpdb;
$rows_affected = $wpdb->query(
"UPDATE {$wpdb->postmeta} " .
$wpdb->prepare( 'SET `meta_value` = REPLACE(`meta_value`, %s, %s) ', $from, $to ) .
'WHERE `meta_key` = \'' . self::FONT_FACE_META_KEY . '\''
);
return $rows_affected;
}
protected function actions() {
parent::actions();
add_filter( 'elementor/tools/replace-urls', function( $rows_affected, $from, $to ) {
return $this->replace_urls( $rows_affected, $from, $to );
}, 10, 3 );
add_filter( 'wp_check_filetype_and_ext', [ $this, 'filter_fix_wp_check_filetype_and_ext' ], 10, 4 );
add_filter( 'wp_handle_upload_prefilter', [ $this, 'wp_handle_upload_prefilter' ] );
add_filter( 'upload_mimes', [ $this, 'upload_mimes' ] );
add_action( 'add_meta_boxes_' . Fonts_Manager::CPT, [ $this, 'add_meta_box' ] );
}
}
blockquote/module.php 0000644 00000000501 15043204017 0010702 0 ustar 00 start_controls_section(
'section_blockquote_content',
[
'label' => esc_html__( 'Blockquote', 'elementor-pro' ),
]
);
$this->add_control(
'blockquote_skin',
[
'label' => esc_html__( 'Skin', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'border' => esc_html__( 'Border', 'elementor-pro' ),
'quotation' => esc_html__( 'Quotation', 'elementor-pro' ),
'boxed' => esc_html__( 'Boxed', 'elementor-pro' ),
'clean' => esc_html__( 'Clean', 'elementor-pro' ),
],
'default' => 'border',
'prefix_class' => 'elementor-blockquote--skin-',
]
);
$this->add_control(
'alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'prefix_class' => 'elementor-blockquote--align-',
'condition' => [
'blockquote_skin!' => 'border',
],
'separator' => 'after',
]
);
$this->add_control(
'blockquote_content',
[
'label' => esc_html__( 'Content', 'elementor-pro' ),
'type' => Controls_Manager::TEXTAREA,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.', 'elementor-pro' ) . esc_html__( 'Lorem ipsum dolor sit amet consectetur adipiscing elit dolor', 'elementor-pro' ),
'placeholder' => esc_html__( 'Enter your quote', 'elementor-pro' ),
'rows' => 10,
]
);
$this->add_control(
'author_name',
[
'label' => esc_html__( 'Author', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'John Doe', 'elementor-pro' ),
'separator' => 'after',
]
);
$this->add_control(
'tweet_button',
[
'label' => esc_html__( 'Tweet Button', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'On', 'elementor-pro' ),
'label_off' => esc_html__( 'Off', 'elementor-pro' ),
'default' => 'yes',
]
);
$this->add_control(
'tweet_button_view',
[
'label' => esc_html__( 'View', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'icon-text' => 'Icon & Text',
'icon' => 'Icon',
'text' => 'Text',
],
'prefix_class' => 'elementor-blockquote--button-view-',
'default' => 'icon-text',
'render_type' => 'template',
'condition' => [
'tweet_button' => 'yes',
],
]
);
$this->add_control(
'tweet_button_skin',
[
'label' => esc_html__( 'Skin', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'classic' => 'Classic',
'bubble' => 'Bubble',
'link' => 'Link',
],
'default' => 'classic',
'prefix_class' => 'elementor-blockquote--button-skin-',
'condition' => [
'tweet_button' => 'yes',
],
]
);
$this->add_control(
'tweet_button_label',
[
'label' => esc_html__( 'Label', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Tweet', 'elementor-pro' ),
'condition' => [
'tweet_button' => 'yes',
'tweet_button_view!' => 'icon',
],
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'user_name',
[
'label' => esc_html__( 'Username', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => '@username',
'condition' => [
'tweet_button' => 'yes',
],
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'url_type',
[
'label' => esc_html__( 'Target URL', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'current_page' => esc_html__( 'Current Page', 'elementor-pro' ),
'none' => esc_html__( 'None', 'elementor-pro' ),
'custom' => esc_html__( 'Custom', 'elementor-pro' ),
],
'default' => 'current_page',
'condition' => [
'tweet_button' => 'yes',
],
]
);
$this->add_control(
'url',
[
'label' => esc_html__( 'Link', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'input_type' => 'url',
'dynamic' => [
'active' => true,
'categories' => [
TagsModule::POST_META_CATEGORY,
TagsModule::URL_CATEGORY,
],
],
'placeholder' => esc_html__( 'https://your-link.com', 'elementor-pro' ),
'label_block' => true,
'condition' => [
'url_type' => 'custom',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_content_style',
[
'label' => esc_html__( 'Content', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'content_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__content' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'content_typography',
'selector' => '{{WRAPPER}} .elementor-blockquote__content',
]
);
$this->add_responsive_control(
'content_gap',
[
'label' => esc_html__( 'Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__content +.e-q-footer' => 'margin-top: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'heading_author_style',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Author', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'author_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_SECONDARY,
],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__author' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'author_typography',
'selector' => '{{WRAPPER}} .elementor-blockquote__author',
]
);
$this->add_responsive_control(
'author_gap',
[
'label' => esc_html__( 'Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'default' => [
'size' => 20,
],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__author' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
'condition' => [
'alignment' => 'center',
'tweet_button' => 'yes',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_button_style',
[
'label' => esc_html__( 'Button', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'button_size',
[
'label' => esc_html__( 'Size', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0.5,
'max' => 2,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button' => 'font-size: calc({{SIZE}}{{UNIT}} * 10);',
],
]
);
$this->add_control(
'button_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button' => 'border-radius: {{SIZE}}{{UNIT}}',
],
'range' => [
'em' => [
'min' => 0,
'max' => 5,
'step' => 0.1,
],
'rem' => [
'min' => 0,
'max' => 5,
'step' => 0.1,
],
'px' => [
'min' => 0,
'max' => 50,
'step' => 1,
],
'%' => [
'min' => 0,
'max' => 100,
'step' => 1,
],
],
]
);
$this->add_control(
'button_color_source',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'official' => esc_html__( 'Official', 'elementor-pro' ),
'custom' => esc_html__( 'Custom', 'elementor-pro' ),
],
'default' => 'official',
'prefix_class' => 'elementor-blockquote--button-color-',
]
);
$this->start_controls_tabs( 'tabs_button_style' );
$this->start_controls_tab(
'tab_button_normal',
[
'label' => esc_html__( 'Normal', 'elementor-pro' ),
'condition' => [
'button_color_source' => 'custom',
],
]
);
$this->add_control(
'button_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button' => 'background-color: {{VALUE}}',
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-left .elementor-blockquote__tweet-button:before' => 'border-right-color: {{VALUE}}; border-left-color: transparent',
'body.rtl {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-right .elementor-blockquote__tweet-button:before' => 'border-left-color: {{VALUE}}; border-right-color: transparent',
],
'condition' => [
'button_color_source' => 'custom',
'tweet_button_skin!' => 'link',
],
]
);
$this->add_control(
'button_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button' => 'color: {{VALUE}}',
'{{WRAPPER}} .elementor-blockquote__tweet-button svg' => 'fill: {{VALUE}}',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'tab_button_hover',
[
'label' => esc_html__( 'Hover', 'elementor-pro' ),
'condition' => [
'button_color_source' => 'custom',
],
]
);
$this->add_control(
'button_background_color_hover',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button:hover' => 'background-color: {{VALUE}}',
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote__tweet-button:hover:before, body {{WRAPPER}}.elementor-blockquote--align-left .elementor-blockquote__tweet-button:hover:before' => 'border-right-color: {{VALUE}}; border-left-color: transparent',
'body.rtl {{WRAPPER}} .elementor-blockquote__tweet-button:before, body {{WRAPPER}}.elementor-blockquote--align-right .elementor-blockquote__tweet-button:hover:before' => 'border-left-color: {{VALUE}}; border-right-color: transparent',
],
'condition' => [
'button_color_source' => 'custom',
'tweet_button_skin!' => 'link',
],
]
);
$this->add_control(
'button_text_color_hover',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button:hover' => 'color: {{VALUE}}',
'{{WRAPPER}} .elementor-blockquote__tweet-button:hover svg' => 'fill: {{VALUE}}',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$default_fonts = Plugin::elementor()->kits_manager->get_current_settings( 'default_generic_fonts' );
if ( $default_fonts ) {
$default_fonts = ', ' . $default_fonts;
}
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'button_typography',
'selector' => '{{WRAPPER}} .elementor-blockquote__tweet-button span, {{WRAPPER}} .elementor-blockquote__tweet-button i',
'separator' => 'before',
'fields_options' => [
'font_family' => [
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__tweet-button' => 'font-family: "{{VALUE}}"' . $default_fonts . ';',
],
],
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_border_style',
[
'label' => esc_html__( 'Border', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'blockquote_skin' => 'border',
],
]
);
$this->start_controls_tabs( 'tabs_border_style' );
$this->start_controls_tab(
'tab_border_normal',
[
'label' => esc_html__( 'Normal', 'elementor-pro' ),
]
);
$this->add_control(
'border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote' => 'border-color: {{VALUE}}',
],
]
);
$this->add_responsive_control(
'border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote' => 'border-left-width: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}} .elementor-blockquote' => 'border-right-width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'border_gap',
[
'label' => esc_html__( 'Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote' => 'padding-left: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}} .elementor-blockquote' => 'padding-right: {{SIZE}}{{UNIT}}',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'tab_border_hover',
[
'label' => esc_html__( 'Hover', 'elementor-pro' ),
]
);
$this->add_control(
'border_color_hover',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote:hover' => 'border-color: {{VALUE}}',
],
]
);
$this->add_responsive_control(
'border_width_hover',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote:hover' => 'border-left-width: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}} .elementor-blockquote:hover' => 'border-right-width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'border_gap_hover',
[
'label' => esc_html__( 'Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'body:not(.rtl) {{WRAPPER}} .elementor-blockquote:hover' => 'padding-left: {{SIZE}}{{UNIT}}',
'body.rtl {{WRAPPER}} .elementor-blockquote:hover' => 'padding-right: {{SIZE}}{{UNIT}}',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_responsive_control(
'border_vertical_padding',
[
'label' => esc_html__( 'Vertical Padding', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote' => 'padding-top: {{SIZE}}{{UNIT}}; padding-bottom: {{SIZE}}{{UNIT}}',
],
'separator' => 'before',
'condition' => [
'blockquote_skin' => 'border',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_box_style',
[
'label' => esc_html__( 'Box', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'blockquote_skin' => 'boxed',
],
]
);
$this->add_responsive_control(
'box_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote' => 'padding: {{SIZE}}{{UNIT}}',
],
]
);
$this->start_controls_tabs( 'tabs_box_style' );
$this->start_controls_tab(
'tab_box_normal',
[
'label' => esc_html__( 'Normal', 'elementor-pro' ),
]
);
$this->add_control(
'box_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote' => 'background-color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'box_border',
'selector' => '{{WRAPPER}} .elementor-blockquote',
]
);
$this->add_responsive_control(
'box_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote' => 'border-radius: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'box_box_shadow',
'exclude' => [
'box_shadow_position',
],
'selector' => '{{WRAPPER}} .elementor-blockquote',
]
);
$this->end_controls_tab();
$this->start_controls_tab(
'tab_box_hover',
[
'label' => esc_html__( 'Hover', 'elementor-pro' ),
]
);
$this->add_control(
'box_background_color_hover',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote:hover' => 'background-color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'box_border_hover',
'selector' => '{{WRAPPER}} .elementor-blockquote:hover',
]
);
$this->add_responsive_control(
'box_border_radius_hover',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote:hover' => 'border-radius: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'box_box_shadow_hover',
'exclude' => [
'box_shadow_position',
],
'selector' => '{{WRAPPER}} .elementor-blockquote:hover',
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'section_quote_style',
[
'label' => esc_html__( 'Quote', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'blockquote_skin' => 'quotation',
],
]
);
$this->add_control(
'quote_text_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .elementor-blockquote:before' => 'color: {{VALUE}}',
],
]
);
$this->add_responsive_control(
'quote_size',
[
'label' => esc_html__( 'Size', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'range' => [
'px' => [
'min' => 0.5,
'max' => 2,
'step' => 0.1,
],
],
'default' => [
'size' => 1,
],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote:before' => 'font-size: calc({{SIZE}}{{UNIT}} * 100)',
],
]
);
$this->add_responsive_control(
'quote_gap',
[
'label' => esc_html__( 'Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .elementor-blockquote__content' => 'margin-top: {{SIZE}}{{UNIT}}',
],
]
);
$this->end_controls_section();
}
protected function render() {
$settings = $this->get_settings_for_display();
$tweet_button_view = $settings['tweet_button_view'];
$share_link = 'https://twitter.com/intent/tweet';
$text = rawurlencode( $settings['blockquote_content'] );
if ( ! empty( $settings['author_name'] ) ) {
$text .= ' — ' . $settings['author_name'];
}
$share_link = add_query_arg( 'text', $text, $share_link );
if ( 'current_page' === $settings['url_type'] ) {
$share_link = add_query_arg( 'url', rawurlencode( home_url() . add_query_arg( false, false ) ), $share_link );
} elseif ( 'custom' === $settings['url_type'] ) {
$share_link = add_query_arg( 'url', rawurlencode( $settings['url'] ), $share_link );
}
if ( ! empty( $settings['user_name'] ) ) {
$user_name = $settings['user_name'];
if ( '@' === substr( $user_name, 0, 1 ) ) {
$user_name = substr( $user_name, 1 );
}
$share_link = add_query_arg( 'via', rawurlencode( $user_name ), $share_link );
}
$this->add_render_attribute( [
'blockquote_content' => [ 'class' => 'elementor-blockquote__content' ],
'author_name' => [ 'class' => 'elementor-blockquote__author' ],
'tweet_button_label' => [ 'class' => 'elementor-blockquote__tweet-label' ],
] );
$this->add_inline_editing_attributes( 'blockquote_content' );
$this->add_inline_editing_attributes( 'author_name', 'none' );
$this->add_inline_editing_attributes( 'tweet_button_label', 'none' );
?>
print_render_attribute_string( 'blockquote_content' ); ?>>
print_unescaped_setting( 'blockquote_content' ); ?>
<#
var tweetButtonView = settings.tweet_button_view;
#>
{{{ settings.blockquote_content }}}
<# if ( 'yes' === settings.tweet_button || settings.author_name ) { #>
<# } #>
add_control( 'field', [
'label' => esc_html__( 'Format', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'average_rating' => esc_html__( 'Average Rating', 'elementor-pro' ),
'rating_count' => esc_html__( 'Rating Count', 'elementor-pro' ),
'review_count' => esc_html__( 'Review Count', 'elementor-pro' ),
],
'default' => 'average_rating',
] );
$this->add_product_id_control();
}
public function render() {
$settings = $this->get_settings_for_display();
$product = $this->get_product( $settings['product_id'] );
if ( ! $product ) {
return '';
}
$field = $settings['field'];
$value = '';
switch ( $field ) {
case 'average_rating':
$value = $product->get_average_rating();
break;
case 'rating_count':
$value = $product->get_rating_count();
break;
case 'review_count':
$value = $product->get_review_count();
break;
}
// PHPCS - Safe WC data
echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
woocommerce/tags/base-data-tag.php 0000644 00000001013 15043204017 0013113 0 ustar 00 get_settings_for_display();
$product = $this->get_product( $settings['product_id'] );
if ( ! $product ) {
return;
}
if ( 'yes' === $settings['show_text'] ) {
$value = wc_get_stock_html( $product );
} else {
$value = (int) $product->get_stock_quantity();
}
// PHPCS - `wc_get_stock_html` is safe, and `get_stock_quantity` protected with (int).
echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
protected function register_controls() {
$this->add_control(
'show_text',
[
'label' => esc_html__( 'Show Text', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => 'yes',
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
]
);
$this->add_product_id_control();
}
}
woocommerce/tags/product-short-description.php 0000644 00000001215 15043204017 0015663 0 ustar 00 add_product_id_control();
}
public function render() {
$product = $this->get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return;
}
echo wp_kses_post( $product->get_short_description() );
}
}
woocommerce/tags/product-sku.php 0000644 00000001231 15043204017 0013003 0 ustar 00 add_product_id_control();
}
public function render() {
$product = $this->get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return;
}
$value = '';
if ( $product->get_sku() ) {
$value = $product->get_sku();
}
echo esc_html( $value );
}
}
woocommerce/tags/category-image.php 0000644 00000002273 15043204017 0013427 0 ustar 00 get_category_ids();
if ( ! empty( $category_ids ) ) {
$category_id = $category_ids[0];
}
}
}
if ( $category_id ) {
$image_id = get_term_meta( $category_id, 'thumbnail_id', true );
}
if ( empty( $image_id ) ) {
return [];
}
$src = wp_get_attachment_image_src( $image_id, 'full' );
return [
'id' => $image_id,
'url' => $src[0],
];
}
}
woocommerce/tags/base-tag.php 0000644 00000001147 15043204017 0012214 0 ustar 00 update_control(
'before',
[
'default' => esc_html__( 'Categories', 'elementor-pro' ) . ': ',
]
);
}
protected function register_controls() {
$taxonomy_filter_args = [
'show_in_nav_menus' => true,
'object_type' => [ 'product' ],
];
$taxonomies = get_taxonomies( $taxonomy_filter_args, 'objects' );
$options = [];
foreach ( $taxonomies as $taxonomy => $object ) {
$options[ $taxonomy ] = $object->label;
}
$this->add_control(
'taxonomy',
[
'label' => esc_html__( 'Taxonomy', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $options,
'default' => 'product_cat',
]
);
$this->add_control(
'separator',
[
'label' => esc_html__( 'Separator', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => ', ',
]
);
$this->add_product_id_control();
}
public function render() {
$settings = $this->get_settings_for_display();
$product = $this->get_product( $settings['product_id'] );
if ( ! $product ) {
return;
}
$value = get_the_term_list( $product->get_id(), $settings['taxonomy'], '', $settings['separator'] );
echo wp_kses_post( $value );
}
}
woocommerce/tags/product-gallery.php 0000644 00000001651 15043204017 0013646 0 ustar 00 get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return [];
}
$value = [];
$attachment_ids = $product->get_gallery_image_ids();
foreach ( $attachment_ids as $attachment_id ) {
$value[] = [
'id' => $attachment_id,
];
}
return $value;
}
}
woocommerce/tags/product-content.php 0000644 00000001151 15043204017 0013654 0 ustar 00 add_product_id_control();
}
public function render() {
$product = $this->get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return;
}
echo wp_kses_post( $product->get_description() );
}
}
woocommerce/tags/traits/tag-product-id.php 0000644 00000001503 15043204017 0014656 0 ustar 00 add_control(
'product_id',
[
'label' => esc_html__( 'Product', 'elementor-pro' ),
'type' => QueryControlModule::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'autocomplete' => [
'object' => QueryControlModule::QUERY_OBJECT_POST,
'query' => [
'post_type' => [ 'product' ],
],
],
// Since we're using the `wc_get_product` method to retrieve products, when no product selected manually
// by the dynamic tag - the default should be `false` so the method will use the product id given in the
// http request instead.
'default' => false,
]
);
}
}
woocommerce/tags/product-sale.php 0000644 00000001642 15043204017 0013133 0 ustar 00 add_control( 'text', [
'label' => esc_html__( 'Text', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Sale!', 'elementor-pro' ),
] );
$this->add_product_id_control();
}
public function render() {
$settings = $this->get_settings_for_display();
$product = $this->get_product( $settings['product_id'] );
if ( ! $product ) {
return;
}
$value = '';
if ( $product->is_on_sale() ) {
$value = $settings['text'];
}
echo wp_kses_post( $value );
}
}
woocommerce/tags/woocommerce-add-to-cart.php 0000644 00000004025 15043204017 0015143 0 ustar 00 add_control(
'product_id',
[
'label' => esc_html__( 'Product', 'elementor-pro' ),
'type' => QueryModule::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'autocomplete' => [
'object' => QueryModule::QUERY_OBJECT_POST,
'query' => [
'post_type' => [ 'product' ],
'tax_query' => [
[
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => 'simple',
],
],
],
],
]
);
$this->add_control(
'quantity',
[
'label' => esc_html__( 'Quantity', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'ai' => [
'active' => false,
],
'default' => 1,
]
);
}
public function get_value( array $options = [] ) {
$settings = $this->get_settings_for_display();
if ( ! $settings['product_id'] ) {
global $product;
$product = wc_get_product();
if ( empty( $product ) ) {
return;
}
$product_id = $product->get_id();
} else {
$product_id = absint( $settings['product_id'] );
}
$quantity = absint( $settings['quantity'] );
$url = 'yes' === get_option( 'woocommerce_cart_redirect_after_add' )
? wc_get_cart_url()
: get_permalink( $product_id );
return home_url() . '?add-to-cart=' . $product_id . '&quantity=' . $quantity . '&e-redirect=' . $url;
}
}
woocommerce/tags/product-price.php 0000644 00000002724 15043204017 0013313 0 ustar 00 add_control( 'format', [
'label' => esc_html__( 'Format', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'both' => esc_html__( 'Both', 'elementor-pro' ),
'original' => esc_html__( 'Original', 'elementor-pro' ),
'sale' => esc_html__( 'Sale', 'elementor-pro' ),
],
'default' => 'both',
] );
$this->add_product_id_control();
}
public function render() {
$settings = $this->get_settings();
$product = $this->get_product( $settings['product_id'] );
if ( ! $product ) {
return '';
}
$format = $settings['format'];
$value = '';
switch ( $format ) {
case 'both':
$value = $product->get_price_html();
break;
case 'original':
$value = wc_price( $product->get_regular_price() ) . $product->get_price_suffix();
break;
case 'sale' && $product->is_on_sale():
$value = wc_price( $product->get_sale_price() ) . $product->get_price_suffix();
break;
}
// PHPCS - Just passing WC price as is
echo $value; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
woocommerce/tags/product-image.php 0000644 00000002247 15043204017 0013273 0 ustar 00 add_product_id_control();
}
public function get_group() {
return Module::WOOCOMMERCE_GROUP;
}
public function get_categories() {
return [ \Elementor\Modules\DynamicTags\Module::IMAGE_CATEGORY ];
}
public function get_value( array $options = [] ) {
$product = $this->get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return [];
}
$image_id = $product->get_image_id();
if ( ! $image_id ) {
return [];
}
$src = wp_get_attachment_image_src( $image_id, 'full' );
return [
'id' => $image_id,
'url' => $src[0],
];
}
}
woocommerce/tags/product-title.php 0000644 00000001341 15043204017 0013324 0 ustar 00 add_product_id_control();
}
public function render() {
$product = $this->get_product( $this->get_settings( 'product_id' ) );
if ( ! $product ) {
return;
}
if ( 'variation' === $product->get_type() ) {
$title = $product->get_name();
} else {
$title = get_the_title( $product->get_id() );
}
echo wp_kses_post( $title );
}
}
woocommerce/conditions/product-archive.php 0000644 00000002736 15043204017 0015050 0 ustar 00 post_type, 'objects' );
$this->post_taxonomies = wp_filter_object_list( $taxonomies, [
'public' => true,
'show_in_nav_menus' => true,
] );
parent::__construct( $data );
}
public static function get_type() {
return 'archive';
}
public function get_name() {
return 'product_archive';
}
public static function get_priority() {
return 40;
}
public function get_label() {
return esc_html__( 'Product Archive', 'elementor-pro' );
}
public function get_all_label() {
return esc_html__( 'All Product Archives', 'elementor-pro' );
}
public function register_sub_conditions() {
$this->register_sub_condition( new Shop_page() );
$this->register_sub_condition( new Product_Search() );
foreach ( $this->post_taxonomies as $slug => $object ) {
$condition = new ThemeBuilder\Conditions\Taxonomy( [
'object' => $object,
] );
$this->register_sub_condition( $condition );
}
}
public function check( $args ) {
return is_shop() || is_product_taxonomy() || Module::is_product_search();
}
}
woocommerce/conditions/shop-page.php 0000644 00000001102 15043204017 0013616 0 ustar 00 'product',
] );
$this->register_sub_condition( $product_archive );
$this->register_sub_condition( $product_single );
}
public function check( $args ) {
return is_woocommerce() || Module::is_product_search();
}
}
woocommerce/conditions/product-search.php 0000644 00000001217 15043204017 0014665 0 ustar 00 parent = $widget;
$this->add_control(
'columns',
[
'label' => esc_html__( 'Columns', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'1' => '1',
'2' => '2',
'3' => '3',
'4' => '4',
'5' => '5',
'6' => '6',
],
'default' => '4',
]
);
}
public function render() {
$this->parent->query_posts();
/** @var \WP_Query $query */
$query = $this->parent->get_query();
if ( ! $query->have_posts() ) {
return;
}
global $woocommerce_loop;
$woocommerce_loop['columns'] = (int) $this->get_instance_value( 'columns' );
Module::instance()->add_products_post_class_filter();
echo '';
woocommerce_product_loop_start();
while ( $query->have_posts() ) {
$query->the_post();
wc_get_template_part( 'content', 'product' );
}
woocommerce_product_loop_end();
woocommerce_reset_loop();
wp_reset_postdata();
echo '
';
Module::instance()->remove_products_post_class_filter();
}
}
woocommerce/skins/skin-loop-product.php 0000644 00000002406 15043204017 0014312 0 ustar 00 parent->add_render_attribute( '_wrapper', 'class', 'woocommerce' );
parent::render();
}
/**
* Register Query Controls
*
* Registers the controls for the query used by the Loop.
*
* @since 3.8.0
*/
public function register_query_controls( Loop_Widget_Base $widget ) {
$this->parent = $widget;
$this->add_query_controls( Loop_Module::QUERY_ID );
}
protected function render_post() {
global $product;
$product = wc_get_product( get_the_ID() );
parent::render_post();
}
}
woocommerce/wc-templates/cart/mini-cart.php 0000644 00000011617 15043204017 0015017 0 ustar 00 exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) );
if ( ! $is_product_visible ) {
return;
}
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
$product_permalink = apply_filters( 'woocommerce_cart_item_permalink', $_product->is_visible() ? $_product->get_permalink( $cart_item ) : '', $cart_item, $cart_item_key );
?>
cart->get_cart();
if ( empty( $cart_items ) ) { ?>
woocommerce/traits/product-id-trait.php 0000644 00000001055 15043204017 0014272 0 ustar 00 get_product_variation( $product_id );
}
$product = wc_get_product( $product_id );
if ( ! $product ) {
$product = wc_get_product();
}
return $product;
}
public function get_product_variation( $product_id = false ) {
return wc_get_product( get_the_ID() );
}
}
woocommerce/traits/products-trait.php 0000644 00000013165 15043204017 0014070 0 ustar 00 [
'default' => 'product',
'options' => [
'current_query' => esc_html__( 'Current Query', 'elementor-pro' ),
'product' => esc_html__( 'Latest Products', 'elementor-pro' ),
'sale' => esc_html__( 'Sale', 'elementor-pro' ),
'featured' => esc_html__( 'Featured', 'elementor-pro' ),
'by_id' => _x( 'Manual Selection', 'Posts Query Control', 'elementor-pro' ),
'related_products' => esc_html__( 'Related Products', 'elementor-pro' ),
'upsells' => esc_html__( 'Upsells', 'elementor-pro' ),
'cross_sells' => esc_html__( 'Cross-Sells', 'elementor-pro' ),
],
],
'orderby' => [
'default' => 'date',
'options' => [
'date' => esc_html__( 'Date', 'elementor-pro' ),
'title' => esc_html__( 'Title', 'elementor-pro' ),
'price' => esc_html__( 'Price', 'elementor-pro' ),
'popularity' => esc_html__( 'Popularity', 'elementor-pro' ),
'rating' => esc_html__( 'Rating', 'elementor-pro' ),
'rand' => esc_html__( 'Random', 'elementor-pro' ),
'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ),
],
],
'exclude' => [
'options' => [
'current_post' => esc_html__( 'Current Post', 'elementor-pro' ),
'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ),
'terms' => esc_html__( 'Term', 'elementor-pro' ),
],
],
'include' => [
'options' => [
'terms' => esc_html__( 'Term', 'elementor-pro' ),
],
],
];
}
private function init_query_settings( $name ) {
$this->product_query_group_control_name = $name;
$this->product_query_control_args = $this->get_query_control_args();
$this->product_query_post_type_control_id = $this->get_query_post_type_control_id();
}
/**
* @return array
*/
private function get_query_control_args() {
$args = [
'name' => $this->product_query_group_control_name,
'post_type' => 'product',
'presets' => [ 'include', 'exclude', 'order' ],
'fields_options' => $this->get_query_fields_options(),
'exclude' => [
'posts_per_page',
'exclude_authors',
'authors',
'offset',
'related_fallback',
'related_ids',
'query_id',
'avoid_duplicates',
'ignore_sticky_posts',
],
];
$args['fields_options'] = array_merge( $args['fields_options'], $this->get_query_exclude_conditions() );
return $args;
}
private function get_query_exclude_conditions() {
$fields = [];
foreach ( $this->product_query_controls_to_hide as $control_name ) {
$fields = $this->add_query_not_supported_types( $control_name, $fields );
}
return $fields;
}
private function add_query_not_supported_types( $control_name, $fields ) {
foreach ( $this->product_query_types as $query_type ) {
$fields[ $control_name ]['condition']['post_type!'][] = $query_type;
}
return $fields;
}
/**
* @return string
*/
private function get_query_post_type_control_id() {
$control_id = $this->product_query_control_args['name'] . '_post_type';
// Check if the trait is currently being used by a widget or skin. Group controls add
// the post_type as a prefix when added by a skin.
if ( method_exists( $this, 'get_control_id' ) ) {
$control_id = $this->product_query_control_args['post_type'] . '_' . $control_id;
}
return $control_id;
}
private function add_query_controls( $name ) {
$this->init_query_settings( $name );
$this->add_group_control(
Group_Control_Query::get_type(),
$this->product_query_control_args
);
$this->add_control(
'related_products_note',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'Note: The Related Products Query is available when creating a Single Product template', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
'condition' => [
$this->product_query_post_type_control_id => 'related_products',
],
]
);
$this->add_control(
'upsells_products_note',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'Note: The Upsells Query is available when creating a Single Product template', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
'condition' => [
$this->product_query_post_type_control_id => 'upsells',
],
]
);
$this->add_control(
'cross_sells_products_note',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'Note: The Cross-Sells Query is available when creating a Cart page', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
'condition' => [
$this->product_query_post_type_control_id => 'cross_sells',
],
]
);
}
}
woocommerce/module.php 0000644 00000146451 15043204017 0011070 0 ustar 00 'eicons',
'value' => 'eicon-' . $icon,
] );
}
}
/**
* @param $settings
* @return void
*/
private static function render_custom_menu_icon( $settings ) {
if ( empty( $settings['menu_icon_svg'] ) ) {
echo ' '; // Default Custom icon.
} else {
Icons_Manager::render_icon( $settings['menu_icon_svg'], [
'class' => 'e-toggle-cart-custom-icon',
'aria-hidden' => 'true',
] );
}
}
public function get_name() {
return 'woocommerce';
}
public function get_widgets() {
return [
'Archive_Products',
'Archive_Products_Deprecated',
'Archive_Description',
'Products',
'Products_Deprecated',
'Breadcrumb',
'Add_To_Cart',
'Elements',
'Single_Elements',
'Categories',
'Menu_Cart',
'Product_Title',
'Product_Images',
'Product_Price',
'Product_Add_To_Cart',
'Product_Rating',
'Product_Stock',
'Product_Meta',
'Product_Short_Description',
'Product_Content',
'Product_Data_Tabs',
'Product_Additional_Information',
'Product_Related',
'Product_Upsell',
'Purchase_Summary',
'Checkout',
'Cart',
'My_Account',
'Notices',
];
}
const RECOMMENDED_POSTS_WIDGET_NAMES = [
'theme-post-featured-image',
'woocommerce-product-title',
'woocommerce-product-add-to-cart',
'woocommerce-product-price',
'woocommerce-product-rating',
'woocommerce-product-stock',
'woocommerce-product-meta',
'woocommerce-product-short-description',
'woocommerce-product-content',
'woocommerce-product-data-tabs',
'woocommerce-product-additional-information',
];
// 'WC page name' => 'Elementor widget name'
const WC_STATUS_PAGES_MAPPED_TO_WIDGETS = [
'Cart' => 'woocommerce-cart',
'Checkout' => 'woocommerce-checkout-page',
'My account' => 'woocommerce-my-account',
];
public function add_product_post_class( $classes ) {
$classes[] = 'product';
return $classes;
}
public function add_products_post_class_filter() {
add_filter( 'post_class', [ $this, 'add_product_post_class' ] );
}
public function remove_products_post_class_filter() {
remove_filter( 'post_class', [ $this, 'add_product_post_class' ] );
}
public function register_tags() {
$tags = [
'Product_Gallery',
'Product_Image',
'Product_Price',
'Product_Rating',
'Product_Sale',
'Product_Content',
'Product_Short_Description',
'Product_SKU',
'Product_Stock',
'Product_Terms',
'Product_Title',
'Category_Image',
'Woocommerce_Add_To_Cart',
];
/** @var \Elementor\Core\DynamicTags\Manager $module */
$module = Plugin::elementor()->dynamic_tags;
$module->register_group( self::WOOCOMMERCE_GROUP, [
'title' => esc_html__( 'WooCommerce', 'elementor-pro' ),
] );
foreach ( $tags as $tag ) {
$tag = 'ElementorPro\\Modules\\Woocommerce\\tags\\' . $tag;
$module->register( new $tag() );
}
}
public function register_wc_hooks() {
wc()->frontend_includes();
}
/**
* @param Conditions_Manager $conditions_manager
*/
public function register_conditions( $conditions_manager ) {
$woocommerce_condition = new Woocommerce();
$conditions_manager->get_condition( 'general' )->register_sub_condition( $woocommerce_condition );
}
/**
* @param Documents_Manager $documents_manager
*/
public function register_documents( $documents_manager ) {
$this->docs_types = [
'product-post' => Product_Post::get_class_full_name(),
'product' => Product::get_class_full_name(),
'product-archive' => Product_Archive::get_class_full_name(),
];
foreach ( $this->docs_types as $type => $class_name ) {
$documents_manager->register_document_type( $type, $class_name );
}
}
public static function render_menu_cart_toggle_button( $settings ) {
if ( null === WC()->cart ) {
return;
}
$product_count = WC()->cart->get_cart_contents_count();
$sub_total = WC()->cart->get_cart_subtotal();
$icon = ! empty( $settings['icon'] ) ? $settings['icon'] : 'cart-medium';
?>
cart ) {
return;
}
$widget_cart_is_hidden = apply_filters( 'woocommerce_widget_cart_is_hidden', false );
$is_edit_mode = Plugin::elementor()->editor->is_edit_mode();
?>
'e-close-cart-custom-icon',
'aria-hidden' => 'true',
] );
}
?>
editor->set_edit_mode( true );
}
foreach ( $templates as $id ) {
$this->get_all_fragments( $id, $all_fragments );
}
wp_send_json( [ 'fragments' => $all_fragments ] );
}
/**
* Get All Fragments.
*
* @since 3.7.0
*
* @param $id
* @param $all_fragments
* @return void
*/
public function get_all_fragments( $id, &$all_fragments ) {
$fragments_in_document = $this->get_fragments_in_document( $id );
if ( $fragments_in_document ) {
$all_fragments += $fragments_in_document;
}
}
/**
* Get Fragments In Document.
*
* A general function that will return any needed fragments for a Post.
*
* @since 3.7.0
* @access public
*
* @param int $id
*
* @return mixed $fragments
*/
public function get_fragments_in_document( $id ) {
$document = Plugin::elementor()->documents->get( $id );
if ( ! is_object( $document ) ) {
return false;
}
$fragments = [];
$data = $document->get_elements_data();
Plugin::elementor()->db->iterate_data(
$data,
$this->get_fragments_handler( $fragments )
);
return ! empty( $fragments ) ? $fragments : false;
}
/**
* Get Fragments Handler.
*
* @since 3.7.0
*
* @param array $fragments
* @return void
*/
public function get_fragments_handler( array &$fragments ) {
return function ( $element ) use ( &$fragments ) {
if ( ! isset( $element['widgetType'] ) ) {
return;
}
$fragment_data = $this->get_fragment_data( $element );
$total_fragments = count( $fragment_data ) / 2;
for ( $i = 0; $i < $total_fragments; $i++ ) {
$fragments[ $fragment_data['selector'][ $i ] ] = $fragment_data['html'][ $i ];
}
};
}
/**
* Empty Cart Fragments
*
* When the Cart is emptied, the selected 'Empty Cart Template' needs to be added as an item
* in the WooCommerce `$fragments` array, so that WC will push the custom Template content into the DOM.
* This is done to prevent the need for a page refresh after the cart is cleared.
*
* @since 3.7.0
*
* @param array $fragments
* @return array
*/
public function empty_cart_fragments( $fragments ) {
// Only do this when the cart is empty.
if ( WC()->cart->get_cart_contents_count() !== 0 ) {
return $fragments;
}
$document = Plugin::elementor()->documents->get( url_to_postid( wp_get_referer() ) );
if ( is_object( $document ) ) {
$data = $document->get_elements_data();
Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$fragments ) {
if (
isset( $element['widgetType'] )
&& 'woocommerce-cart' === $element['widgetType']
&& ( isset( $element['settings']['additional_template_switch'] ) && 'active' === $element['settings']['additional_template_switch'] )
&& ( isset( $element['settings']['additional_template_select'] ) && 0 < $element['settings']['additional_template_select'] )
) {
$fragments[ 'div.elementor-element-' . $element['id'] . ' .elementor-widget-container' ] = '' . do_shortcode( '[elementor-template id="' . $element['settings']['additional_template_select'] . '"]' ) . '
';
}
} );
}
return $fragments;
}
public function maybe_init_cart() {
$has_cart = is_a( WC()->cart, 'WC_Cart' );
if ( ! $has_cart ) {
$session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' );
WC()->session = new $session_class();
WC()->session->init();
WC()->cart = new \WC_Cart();
WC()->customer = new \WC_Customer( get_current_user_id(), true );
}
}
public function localized_settings_frontend( $settings ) {
$has_cart = is_a( WC()->cart, 'WC_Cart' );
if ( $has_cart ) {
$settings['woocommerce']['menu_cart'] = [
'cart_page_url' => wc_get_cart_url(),
'checkout_page_url' => wc_get_checkout_url(),
'fragments_nonce' => wp_create_nonce( self::MENU_CART_FRAGMENTS_ACTION ),
];
}
return $settings;
}
public function theme_template_include( $need_override_location, $location ) {
if ( is_product() && 'single' === $location ) {
$need_override_location = true;
}
return $need_override_location;
}
public function add_loop_recommended_widgets( $config, $post_id ) {
if ( ! $this->is_source_set_to_products( $post_id ) ) {
return $config;
}
$config = $this->add_woocommerce_widgets_to_recommended( $config );
return $this->hide_woocommerce_widgets_in_loop_document( $config );
}
/**
* Add plugin path to wc template search path.
* Based on: https://www.skyverge.com/blog/override-woocommerce-template-file-within-a-plugin/
* @param $template
* @param $template_name
* @param $template_path
*
* @return string
*/
public function woocommerce_locate_template( $template, $template_name, $template_path ) {
if ( self::TEMPLATE_MINI_CART !== $template_name ) {
return $template;
}
if ( ! $this->use_mini_cart_template ) {
return $template;
}
$plugin_path = plugin_dir_path( __DIR__ ) . 'woocommerce/wc-templates/';
if ( file_exists( $plugin_path . $template_name ) ) {
$template = $plugin_path . $template_name;
}
return $template;
}
/**
* WooCommerce/WordPress widget(s), some of the widgets have css classes that used by final selectors.
* before this filter, all those widgets were warped by `.elementor-widget-container` without chain original widget
* classes, now they will be warped by div with the original css classes.
*
* @param array $default_widget_args
* @param \Elementor\Widget_WordPress $widget
*
* @return array $default_widget_args
*/
public function woocommerce_wordpress_widget_css_class( $default_widget_args, $widget ) {
$widget_instance = $widget->get_widget_instance();
if ( ! empty( $widget_instance->widget_cssclass ) ) {
$default_widget_args['before_widget'] .= '';
$default_widget_args['after_widget'] .= '
';
}
return $default_widget_args;
}
public function register_admin_fields( Settings $settings ) {
$settings->add_section( Settings::TAB_INTEGRATIONS, 'woocommerce', [
'callback' => function() {
echo '' . esc_html__( 'WooCommerce', 'elementor-pro' ) . ' ';
},
'fields' => [
self::OPTION_NAME_USE_MINI_CART => [
'label' => esc_html__( 'Mini Cart Template', 'elementor-pro' ),
'field_args' => [
'type' => 'select',
'std' => 'initial',
'options' => [
'initial' => '', // Relevant until either menu-cart widget is used or option is explicitly set to 'no'.
'no' => esc_html__( 'Disable', 'elementor-pro' ),
'yes' => esc_html__( 'Enable', 'elementor-pro' ),
],
'desc' => esc_html__( 'Set to `Disable` in order to use your Theme\'s or WooCommerce\'s mini-cart template instead of Elementor\'s.', 'elementor-pro' ),
],
],
],
] );
}
/**
* Load Widget Before WooCommerce Ajax.
*
* When outputting the complex WooCommerce shortcodes (which we use in our widgets) e.g. Checkout, Cart, etc. WC
* immediately does more ajax calls and retrieves updated html fragments based on the data in the forms that may
* be autofilled by the current user's browser e.g. the Payment section holding the "Place order" button.
*
* This function runs before these ajax calls. Using the `elementorPageId` and `elementorWidgetId` querystring
* appended to the forms `_wp_http_referer` url field, or the referer page ID, it loads the relevant Elementor widget.
* The rendered Elementor widget replaces the default WooCommerce template used to refresh WooCommerce elements in the page.
*
* This is necessary for example in the Checkout Payment section where we modify the Terms & Conditions text
* using settings from the widget or when updating shipping methods on the Cart.
*
* @since 3.5.0
*/
public function load_widget_before_wc_ajax() {
// Make sure is a WooCommerce ajax call.
$wc_ajax = ProUtils::_unstable_get_super_global_value( $_GET, 'wc-ajax' );
if ( ! $wc_ajax ) {
return;
}
// Only handle relevant WC AJAX calls
if ( ! in_array( $wc_ajax, [ 'update_order_review', 'update_shipping_method' ], true ) ) {
return;
}
// Security checks.
switch ( $wc_ajax ) {
case 'update_order_review':
check_ajax_referer( 'update-order-review', 'security' );
break;
case 'update_shipping_method':
check_ajax_referer( 'update-shipping-method', 'security' );
break;
}
$page_id = false;
$widget_id = false;
// Try to get the `$page_id` and `$widget_id` we added as a query string to `_wp_http_referer` in `post_data`.
// This is only available when a form is submitted.
$raw_post_data = ProUtils::_unstable_get_super_global_value( $_POST, 'post_data' );
if ( $raw_post_data ) {
$raw_post_data = html_entity_decode( $raw_post_data );
parse_str( $raw_post_data, $post_data );
if ( isset( $post_data['_wp_http_referer'] ) ) {
$wp_http_referer = wp_unslash( $post_data['_wp_http_referer'] );
$wp_http_referer_query_string = wp_parse_url( $wp_http_referer, PHP_URL_QUERY );
parse_str( $wp_http_referer_query_string, $wp_http_referer_query_string );
if ( isset( $wp_http_referer_query_string['elementorPageId'] ) ) {
$page_id = $wp_http_referer_query_string['elementorPageId'];
}
if ( isset( $wp_http_referer_query_string['elementorWidgetId'] ) ) {
$widget_id = $wp_http_referer_query_string['elementorWidgetId'];
}
}
}
if ( ! $page_id ) {
$page_id = url_to_postid( wp_get_referer() );
}
// Bail if no `$page_id`.
if ( ! $page_id ) {
return;
}
// Get Elementor document from `$page_id`.
$document = Plugin::elementor()->documents->get_doc_for_frontend( $page_id );
// Bail if not Elementor page.
if ( ! $document ) {
return;
}
// Setup $page_id as the WP global $post, so is available to our widgets.
$post = get_post( $page_id, OBJECT );
setup_postdata( $post );
$widget_data = false;
if ( $widget_id ) {
// If we did manage to pass `$widget_id` to this ajax call we get the widget data by its ID.
$widget_data = Utils::find_element_recursive( $document->get_elements_data(), $widget_id );
} else {
// If we didn't manage to pass `$widget_id` to this ajax call we use this alternate method and get the first
// of the type of widget used on the WC endpoint pages responsible for these ajax calls - cart or checkout widget.
$woocommerce_widgets = [ 'woocommerce-cart', 'woocommerce-checkout-page' ];
$document_data = $document->get_elements_data();
Plugin::elementor()->db->iterate_data( $document_data, function( $element ) use ( $woocommerce_widgets, &$widget_data ) {
if ( $widget_data && ( ! isset( $element['widgetType'] ) || ! in_array( $element['widgetType'], $woocommerce_widgets, true ) ) ) {
return;
}
$widget_data = $element;
} );
}
// If we found a widget then run `add_render_hooks()` widget method.
if ( $widget_data ) {
$widget_instance = Plugin::elementor()->elements_manager->create_element_instance( $widget_data );
if ( method_exists( $widget_instance, 'add_render_hooks' ) ) {
$widget_instance->add_render_hooks();
}
}
}
/**
* Elementor Woocommerce Checkout Login User
*
* Handle the Ajax call for the custom login form on the Checkout Widget
*
* @since 3.5.0
*/
public function elementor_woocommerce_checkout_login_user() {
if ( is_user_logged_in() ) {
wp_logout();
}
$error = false;
$error_message = '';
if ( ! wp_verify_nonce( ProUtils::_unstable_get_super_global_value( $_POST, 'nonce' ), 'woocommerce-login' ) ) {
$error = true;
$error_message = sprintf(
/* translators: 1: Bold text opening tag, 2: Bold text closing tag. */
esc_html__( '%1$sError:%2$s The nonce security check didn’t pass. Please reload the page and try again. You may want to try clearing your browser cache as a last attempt.', 'elementor-pro' ),
'',
' '
);
} else {
$info = [
'user_login' => trim( ProUtils::_unstable_get_super_global_value( $_POST, 'username' ) ),
'user_password' => $_POST['password'] ?? '', // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized, WordPress.Security.ValidatedSanitizedInput.MissingUnslash, A password should not be sanitized.
'remember' => ProUtils::_unstable_get_super_global_value( $_POST, 'remember' ),
];
$user_signon = wp_signon( $info, false );
if ( is_wp_error( $user_signon ) ) {
$error = true;
$error_message = $user_signon->get_error_message();
}
}
if ( $error ) {
wc_add_notice(
$error_message,
'error'
);
$response = [
'logged_in' => false,
'message' => wc_print_notices( true ),
];
} else {
$response = [ 'logged_in' => true ];
}
echo wp_json_encode( $response );
wp_die();
}
/**
* Register Ajax Actions.
*
* Registers ajax action used by the Editor js.
*
* @since 3.5.0
*
* @param Ajax $ajax
*/
public function register_ajax_actions( Ajax $ajax ) {
// `woocommerce_update_page_option` is called in the editor save-show-modal.js.
$ajax->register_ajax_action( 'pro_woocommerce_update_page_option', [ $this, 'update_page_option' ] );
$ajax->register_ajax_action( 'pro_woocommerce_mock_notices', [ $this, 'woocommerce_mock_notices' ] );
}
/**
* @throws \Exception
*/
public function woocommerce_mock_notices( $data ) {
$document = ProUtils::_unstable_get_document_for_edit( $data['editor_post_id'] );
if ( in_array( 'wc_error', $data['notice_elements'], true ) ) {
$notice_message = sprintf(
'%1$s %2$s ',
esc_html__( 'This is how an error notice would look.', 'elementor-pro' ),
esc_html__( 'Here\'s a link', 'elementor-pro' )
);
wc_add_notice( $notice_message, 'error' );
}
if ( in_array( 'wc_message', $data['notice_elements'], true ) ) {
$notice_message = sprintf(
'%1$s %2$s %3$s ',
esc_html__( 'Button', 'elementor-pro' ),
esc_html__( 'This is what a WooCommerce message notice looks like.', 'elementor-pro' ),
esc_html__( 'Here\'s a link', 'elementor-pro' )
);
wc_add_notice( $notice_message, 'success' );
}
if ( in_array( 'wc_info', $data['notice_elements'], true ) ) {
$notice_message = sprintf(
'%1$s %2$s',
esc_html__( 'Button', 'elementor-pro' ),
esc_html__( 'This is how WooCommerce provides an info notice.', 'elementor-pro' )
);
wc_add_notice( $notice_message, 'notice' );
}
return '' . wc_print_notices( true ) . '
';
}
/**
* Update Page Option.
*
* Ajax action can be used to update any WooCommerce option.
*
* @since 3.5.0
*
* @param array $data
*/
public function update_page_option( $data ) {
$is_admin = current_user_can( 'manage_options' );
$is_shop_manager = current_user_can( 'manage_woocommerce' );
$is_allowed = $is_admin || $is_shop_manager;
if ( ! $is_allowed ) {
return new \WP_Error( 401 );
}
$allowed_options = [
'woocommerce_checkout_page_id',
'woocommerce_cart_page_id',
'woocommerce_myaccount_page_id',
'elementor_woocommerce_purchase_summary_page_id',
];
$option_name = $data['option_name'];
$post_id = absint( $data['editor_post_id'] );
if ( ! in_array( $option_name, $allowed_options, true ) ) {
return new \WP_Error( 400 );
}
update_option( $option_name, $post_id );
}
public function init_site_settings( \Elementor\Core\Kits\Documents\Kit $kit ) {
$kit->register_tab( 'settings-woocommerce', \ElementorPro\Modules\Woocommerce\Settings\Settings_Woocommerce::class );
}
public function add_products_type_to_template_popup( $form ) {
$this->add_products_to_options( $form, '_elementor_source' );
}
public function add_products_type_to_loop_settings_query( $form ) {
$this->add_products_to_options( $form, 'source' );
}
public function e_cart_count_fragments( $fragments ) {
$product_count = WC()->cart->get_cart_contents_count();
$fragments['.elementor-menu-cart__toggle_button span.elementor-button-text'] = '' . WC()->cart->get_cart_subtotal() . ' ';
$fragments['.elementor-menu-cart__toggle_button span.elementor-button-icon-qty'] = '' . $product_count . ' ';
return $fragments;
}
/**
* @param $form
* @param $control_name
* @return void
*/
protected function add_products_to_options( $form, $control_name ) {
if ( empty( $form ) ) {
return;
}
$controls = $form->get_controls( $control_name );
if ( ! $controls || ! isset( $controls['options'] ) ) {
return;
}
$options = $controls['options'];
$options[ self::LOOP_PRODUCT_SKIN_ID ] = esc_html__( 'Products', 'elementor-pro' );
$form->update_control($control_name, [
'options' => $options,
]);
}
/**
* Add Update Kit Settings Hooks
*
* Add hooks that update the corresponding kit setting when the WooCommerce option is updated.
*/
public function add_update_kit_settings_hooks() {
add_action( 'update_option_woocommerce_cart_page_id', function( $old_value, $value ) {
Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_cart_page_id', $value );
}, 10, 2 );
add_action( 'update_option_woocommerce_checkout_page_id', function( $old_value, $value ) {
Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_checkout_page_id', $value );
}, 10, 2 );
add_action( 'update_option_woocommerce_myaccount_page_id', function( $old_value, $value ) {
Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_myaccount_page_id', $value );
}, 10, 2 );
add_action( 'update_option_woocommerce_terms_page_id', function( $old_value, $value ) {
Plugin::elementor()->kits_manager->update_kit_settings_based_on_option( 'woocommerce_terms_page_id', $value );
}, 10, 2 );
}
/**
* Elementor WC My Account Logout
*
* Programatically log out if $_REQUEST['elementor_wc_logout'] is set.
* The $_REQUEST variables we have generated a custom logout URL for in the My Account menu.
*
* @since 3.5.0
*/
public function elementor_wc_my_account_logout() {
$elementor_wc_logout = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor_wc_logout' );
$nonce = ProUtils::_unstable_get_super_global_value( $_REQUEST, '_wpnonce' );
if ( $elementor_wc_logout && $nonce && wp_verify_nonce( $nonce, 'customer-logout' ) ) {
wp_logout(); // Log the user out Programatically.
wp_safe_redirect( esc_url( ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor_my_account_redirect' ) ) ); // Redirect back to the widget page.
exit;
}
}
/**
* Add Localize Data
*
* Makes `woocommercePages` available with the page name and the associated post ID for use with the various
* widgets site settings modal.
*
* @param $settings
* @return array
*/
public function add_localize_data( $settings ) {
$settings['woocommerce']['woocommercePages'] = [
'checkout' => wc_get_page_id( 'checkout' ),
'cart' => wc_get_page_id( 'cart' ),
'myaccount' => wc_get_page_id( 'myaccount' ),
'purchase_summary' => get_option( 'elementor_woocommerce_purchase_summary_page_id' ),
];
return $settings;
}
/**
* Localize Added To Cart On Product Single
*
* WooCommerce doesn't trigger `added_to_cart` event on its products single page which is required for us to
* automatically open our Menu Cart if the settings is chosen. We make the `productAddedToCart` setting
* available that we can use in the Menu Cart js to check if a product has just been added.
*
* @since 3.5.0
*/
public function localize_added_to_cart_on_product_single() {
add_filter( 'elementor_pro/frontend/localize_settings', function ( $settings ) {
$settings['woocommerce']['productAddedToCart'] = true;
return $settings;
} );
}
public function e_notices_body_classes( $classes ) {
if ( $this->should_load_wc_notices_styles() ) {
foreach ( $this->woocommerce_notices_elements as $notice_element ) {
$classes[] = 'e-' . str_replace( '_', '-', $notice_element ) . '-notice';
}
}
return $classes;
}
public function e_notices_css( $classes ) {
if ( $this->should_load_wc_notices_styles() ) {
wp_enqueue_style(
'e-woocommerce-notices',
ELEMENTOR_PRO_URL . 'assets/css/woocommerce-notices.min.css',
[],
ELEMENTOR_PRO_VERSION
);
}
}
public function get_order_received_endpoint_url( $url, $endpoint, $value ) {
$order_received_endpoint = get_option( 'woocommerce_checkout_order_received_endpoint', 'order-received' );
if ( $order_received_endpoint === $endpoint ) {
$woocommerce_purchase_summary_page_id = get_option( 'elementor_woocommerce_purchase_summary_page_id' );
$order = wc_get_order( $value );
if ( $woocommerce_purchase_summary_page_id && $order ) {
$url = trailingslashit( trailingslashit( trailingslashit( get_permalink( $woocommerce_purchase_summary_page_id ) ) . $order_received_endpoint ) . $order->get_id() );
}
}
return $url;
}
public function maybe_define_woocommerce_checkout() {
$woocommerce_purchase_summary_page_id = get_option( 'elementor_woocommerce_purchase_summary_page_id' );
if ( $woocommerce_purchase_summary_page_id && intval( $woocommerce_purchase_summary_page_id ) === get_queried_object_id() ) {
if ( ! defined( 'WOOCOMMERCE_CHECKOUT' ) ) {
define( 'WOOCOMMERCE_CHECKOUT', true );
}
}
}
/**
* Products Query Sources Fragments.
*
* Since we introduced additional query sources to the Products Widget,
* some of these query sources can now be used outside of the Single Product template.
*
* For example the Related Products and Cross-Sells.
*
* But now we'll need to make those sections also update when the Cart is updated. So
* we'll do this by creating fragments for each of these.
*
* @since 3.7.0
*
* @param array $fragments
*
* @return array
*/
public function products_query_sources_fragments( $fragments ) {
if ( WC()->cart->get_cart_contents_count() !== 0 ) {
$document = Plugin::elementor()->documents->get( url_to_postid( wp_get_referer() ) );
if ( is_object( $document ) ) {
$data = $document->get_elements_data();
Plugin::elementor()->db->iterate_data( $data, function( $element ) use ( &$fragments ) {
if (
isset( $element['widgetType'] )
&& 'woocommerce-products' === $element['widgetType']
) {
$settings = $element['settings'];
if ( isset( $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ] ) ) {
$query_type = $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ];
$query_types_to_check = [ 'related_products', 'upsells', 'cross_sells' ];
if ( in_array( $query_type, $query_types_to_check, true ) ) {
switch ( $query_type ) {
case 'related_products':
$content = self::get_products_related_content( $settings );
break;
case 'upsells':
$content = self::get_upsells_content( $settings );
break;
case 'cross_sells':
$content = self::get_cross_sells_content( $settings );
break;
default:
$content = null;
}
if ( $content ) {
$fragments[ 'div.elementor-element-' . $element['id'] . ' div.elementor-widget-container' ] = '' . $content . '
';
}
}
}
}
} );
}
} else {
$fragments['div.elementor-widget-container .woocommerce .cross-sells'] = '
';
$fragments['div.elementor-widget-container .woocommerce section.up-sells'] = '';
}
return $fragments;
}
/**
* Get Products Related Content.
*
* A function to return content for the 'related' products query type in the Products widget.
* This function is declared in the Module file so it can be accessed during a WC fragment refresh
* and also be used in the Product widget's render method.
*
* @since 3.7.0
* @access public
*
* @param array $settings
*
* @return mixed The content or false
*/
public static function get_products_related_content( $settings ) {
global $product;
$product = wc_get_product();
if ( ! $product ) {
return;
}
return self::get_product_widget_content(
$settings,
'related_products',
'woocommerce_product_related_products_heading',
'products_related_title_text'
);
}
/**
* Get Upsells Content.
*
* A function to return content for the 'upsell' query type in the Products widget.
* This function is declared in the Module file so it can be accessed during a WC fragment refresh
* and also be used in the Product widget's render method.
*
* @since 3.7.0
* @access public
*
* @param array $settings
*
* @return mixed The content or false
*/
public static function get_upsells_content( $settings ) {
return self::get_product_widget_content(
$settings,
'upsells',
'woocommerce_product_upsells_products_heading',
'products_upsells_title_text'
);
}
/**
* Get Cross Sells Content.
*
* A function to return content for the 'cross_sells' query type in the Products widget.
* This function is declared in the Module file so it can be accessed during a WC fragment refresh
* and also be used in the Product widget's render method.
*
* @since 3.7.0
* @access public
*
* @param array $settings
*
* @return mixed The content or false
*/
public static function get_cross_sells_content( $settings ) {
return self::get_product_widget_content(
$settings,
'cross_sells',
'woocommerce_product_cross_sells_products_heading',
'products_cross_sells_title_text'
);
}
/**
* Print Woocommerce Shipping Message
*
* Format the shipping messages that will be displayed on the Cart and Checkout Widgets.
* This will add extra classes to those messages so that we can target certain messages
* with certain style controls.
*
* @since 3.5.0
*
* @param string $html the original HTML from WC
* @param string $classes the classes we will surround $html with
* @return string the final formatted HTML that will be rendered
*/
private function print_woocommerce_shipping_message( $html, $classes ) {
return '' . $html . ' ';
}
/**
* Should load WC Notices Styles
*
* Determine if we should load the WooCommerce notices CSS.
* It should only load:
* - When we are in the Editor, regardless if any notices have been activated.
* - If WooCoomerce is active.
* - When we are on the front end, if at least one notice is activated.
*
* It should not load in WP Admin.
*
* @return boolean
*/
private function should_load_wc_notices_styles() {
$woocommerce_active = in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) );
$is_editor = ProUtils::_unstable_get_super_global_value( $_GET, 'elementor-preview' );
// Editor checks.
if ( $woocommerce_active && $is_editor ) {
return true;
}
$kit = Plugin::elementor()->kits_manager->get_active_kit_for_frontend();
$this->woocommerce_notices_elements = is_array( $kit->get_settings_for_display( 'woocommerce_notices_elements' ) ) ? $kit->get_settings_for_display( 'woocommerce_notices_elements' ) : [];
// Front end checks.
if (
0 < count( $this->woocommerce_notices_elements ) // At least one notice has been activated.
&& $woocommerce_active // WooCommerce is active.
&& ( ! is_admin() || $is_editor ) // We are not in WP Admin.
) {
return true;
}
return false;
}
/**
* Get Product Widget Content.
*
* A general function to create markup for the new query types in the Products widget.
*
* @since 3.7.0
* @access private
*
* @param array $settings The widget settings.
* @param string $type The query type to create content for.
* @param string $title_hook The hook name to filter in the widget title.
* @param string $title_key The control ID for the section title.
*
* @return mixed The content or false
*/
private static function get_product_widget_content( $settings, $type, $title_hook, $title_key = '' ) {
add_filter( $title_hook, function ( $heading ) use ( $settings, $title_key ) {
$title_text = isset( $settings[ $title_key ] ) ? $settings[ $title_key ] : '';
if ( ! empty( $title_text ) ) {
return $title_text;
}
return $heading;
}, 10, 1 );
ob_start();
$args = self::parse_product_widget_args( $settings, $type );
if ( 'related_products' === $type ) {
woocommerce_related_products( $args );
} elseif ( 'upsells' === $type ) {
woocommerce_upsell_display( $args['limit'], $args['columns'], $args['orderby'], $args['order'] );
} else {
/**
* We need to wrap this content in the 'woocommerce' class for the layout to have the correct styling.
* Because this will only be used as a separate widget on the Cart page,
* the normal 'woocommerce' div from the cart widget will be closed before this content.
*/
echo '';
woocommerce_cross_sell_display( $args['limit'], $args['columns'], $args['orderby'], $args['order'] );
echo '
';
}
$products_html = ob_get_clean();
remove_filter( $title_hook, function(){}, 10 );
if ( $products_html ) {
$products_html = str_replace( ' '-1',
'columns' => ! empty( $settings['columns'] ) ? $settings['columns'] : 4,
'orderby' => ! empty( $settings[ "{$query_name}_orderby" ] ) ? $settings[ "{$query_name}_orderby" ] : 'rand',
'order' => ! empty( $settings[ "{$query_name}_order" ] ) ? $settings[ "{$query_name}_order" ] : 'desc',
];
if ( ! empty( $settings['rows'] ) ) {
$args[ $limit_key ] = $args['columns'] * $settings['rows'];
}
return $args;
}
/**
* Get Fragment Data.
*
* A function that will return the selector and HTML for WC fragments.
*
* @since 3.7.0
* @access private
*
* @param array $element
*
* @return array $fragment_data
*/
private function get_fragment_data( $element ) {
$fragment_data = [];
if ( 'woocommerce-menu-cart' === $element['widgetType'] ) {
ob_start();
self::render_menu_cart_toggle_button( $element['settings'] );
$fragment_data['html'][] = ob_get_clean();
$fragment_data['selector'][] = 'div.elementor-element-' . $element['id'] . ' div.elementor-menu-cart__toggle';
}
return $fragment_data;
}
/**
* Is Preview
*
* Helper to check if we are doing either:
* - Viewing the WP Preview page - also used as the Elementor preview page when clicking "Preview Changes" in the editor
* - Viewing the page in the editor, but not the active page being edited e.g. if you click Edit Header while editing a page
*
* @since 3.7.0
*
* @return bool
*/
public static function is_preview() {
return Plugin::elementor()->preview->is_preview_mode() || is_preview();
}
public function __construct() {
parent::__construct();
add_action( 'elementor/kit/register_tabs', [ $this, 'init_site_settings' ], 1, 40 );
$this->add_update_kit_settings_hooks();
add_action( 'elementor/template-library/create_new_dialog_fields', [ $this, 'add_products_type_to_template_popup' ], 11 );
add_action( 'elementor-pro/modules/loop-builder/documents/loop/query_settings', [ $this, 'add_products_type_to_loop_settings_query' ], 11 );
$this->use_mini_cart_template = 'yes' === get_option( 'elementor_' . self::OPTION_NAME_USE_MINI_CART, 'no' );
if ( is_admin() ) {
add_action( 'elementor/admin/after_create_settings/' . Settings::PAGE_ID, [ $this, 'register_admin_fields' ], 15 );
}
add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'maybe_init_cart' ] );
add_action( 'elementor/dynamic_tags/register', [ $this, 'register_tags' ] );
add_action( 'elementor/documents/register', [ $this, 'register_documents' ] );
add_action( 'elementor/theme/register_conditions', [ $this, 'register_conditions' ] );
add_action( 'wp_ajax_elementor_woocommerce_checkout_login_user', [ $this, 'elementor_woocommerce_checkout_login_user' ] );
add_action( 'wp_ajax_nopriv_elementor_woocommerce_checkout_login_user', [ $this, 'elementor_woocommerce_checkout_login_user' ] );
add_action( 'wp_ajax_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] );
add_action( 'wp_ajax_nopriv_elementor_menu_cart_fragments', [ $this, 'menu_cart_fragments' ] );
add_filter( 'woocommerce_add_to_cart_fragments', [ $this, 'e_cart_count_fragments' ] );
add_filter( 'elementor/theme/need_override_location', [ $this, 'theme_template_include' ], 10, 2 );
add_filter( 'elementor/document/config', [ $this, 'add_loop_recommended_widgets' ], 11, 2 );
add_filter( 'elementor_pro/frontend/localize_settings', [ $this, 'localized_settings_frontend' ] );
// Load our widget Before WooCommerce Ajax. See the variable's PHPDoc for details.
add_action( 'woocommerce_checkout_update_order_review', [ $this, 'load_widget_before_wc_ajax' ] );
add_action( 'woocommerce_before_calculate_totals', [ $this, 'load_widget_before_wc_ajax' ] );
// On Editor - Register WooCommerce frontend hooks before the Editor init.
// Priority = 5, in order to allow plugins remove/add their wc hooks on init.
$action = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'action' );
if ( 'elementor' === $action && is_admin() ) {
add_action( 'init', [ $this, 'register_wc_hooks' ], 5 );
}
// Allow viewing of Checkout page in the Editor with an empty cart.
if (
( 'elementor' === $action && is_admin() ) // Elementor Editor
|| 'elementor_ajax' === $action // Elementor Editor Preview - Ajax Render Widget
|| ProUtils::_unstable_get_super_global_value( $_REQUEST, 'elementor-preview' ) // Elementor Editor Preview
) {
add_filter( 'woocommerce_checkout_redirect_empty_cart', '__return_false', 5 );
}
if ( $this->use_mini_cart_template ) {
add_filter( 'woocommerce_locate_template', [ $this, 'woocommerce_locate_template' ], 10, 3 );
}
$wc_ajax = ProUtils::_unstable_get_super_global_value( $_REQUEST, 'wc-ajax' );
if ( 'get_refreshed_fragments' === $wc_ajax ) {
add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'products_query_sources_fragments' ] );
// Render the Empty Cart Template on WC fragment refresh
add_action( 'woocommerce_add_to_cart_fragments', [ $this, 'empty_cart_fragments' ] );
}
add_filter( 'elementor/widgets/wordpress/widget_args', [ $this, 'woocommerce_wordpress_widget_css_class' ], 10, 2 );
add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
// Make the Logout redirect go to our my account widget page instead of the set My Account Page.
add_action( 'init', [ $this, 'elementor_wc_my_account_logout' ], 5 );
add_filter( 'elementor_pro/editor/localize_settings', [ $this, 'add_localize_data' ] );
add_action( 'wp', [ $this, 'maybe_define_woocommerce_checkout' ] );
add_filter( 'woocommerce_get_endpoint_url', [ $this, 'get_order_received_endpoint_url' ], 10, 3 );
// Filters for messages on the Shipping calculator
add_filter( 'woocommerce_shipping_may_be_available_html', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-may-be-available-html e-checkout-message e-cart-content' );
}, 10, 1 );
add_filter( 'woocommerce_shipping_not_enabled_on_cart_html', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-not_enabled-on-cart-html e-checkout-message e-cart-content' );
}, 10, 1 );
add_filter( 'woocommerce_shipping_estimate_html', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-shipping-estimate-html e-checkout-message e-cart-content' );
}, 10, 1 );
add_filter( 'woocommerce_cart_no_shipping_available_html', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-cart-no-shipping-available-html e-checkout-message e-cart-content' );
}, 10, 1 );
add_filter( 'woocommerce_no_available_payment_methods_message', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-available-payment-methods-message e-description' );
}, 10, 1 );
add_filter( 'woocommerce_no_shipping_available_html', function ( $html ) {
return $this->print_woocommerce_shipping_message( $html, 'woocommerce-no-shipping-available-html e-checkout-message' );
}, 10, 1 );
add_action( 'woocommerce_add_to_cart', [ $this, 'localize_added_to_cart_on_product_single' ] );
foreach ( LoopBuilderModule::LOOP_WIDGETS as $widget_type ) {
add_action( 'elementor/widget/' . $widget_type . '/skins_init', function( Widget_Base $widget ) {
$widget->add_skin( new Skin_Loop_Product( $widget ) );
} );
}
// WooCommerce Notice Site Settings
add_filter( 'body_class', [ $this, 'e_notices_body_classes' ] );
add_filter( 'wp_enqueue_scripts', [ $this, 'e_notices_css' ] );
add_filter( 'elementor/query/query_args', function( $query_args, $widget ) {
return $this->loop_query( $query_args, $widget );
}, 10, 2 );
add_filter( 'woocommerce_rest_prepare_system_status', function( $response, $system_status, $request ) {
return $this->add_system_status_data( $response, $system_status, $request );
}, 10, 3 );
add_filter( 'elementor/editor/localize_settings', function ( $config ) {
return $this->populate_persistent_settings( $config );
});
}
public function add_system_status_data( $response, $system_status, $request ) {
foreach ( $response->data['pages'] as $index => $wc_page ) {
$this->modify_response_if_widget_exists_in_page( $wc_page, $response, $index );
}
return $response;
}
private function modify_response_if_widget_exists_in_page( $wc_page, &$response, $index ) {
if ( empty( $wc_page['page_name'] ) || empty( $wc_page['page_id'] ) || ! array_key_exists( $wc_page['page_name'], static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS ) ) {
return;
}
if ( isset( $wc_page['shortcode_present'] ) && false !== $wc_page['shortcode_present'] ) {
return;
}
$document = Plugin::elementor()->documents->get( $wc_page['page_id'] );
if ( ! $document || ! $document->is_built_with_elementor() ) {
return;
}
$elementor_data = get_post_meta( $wc_page['page_id'], '_elementor_data', true );
$widget_name = static::WC_STATUS_PAGES_MAPPED_TO_WIDGETS[ $wc_page['page_name'] ];
$widget_exists_in_page = false !== strpos( $elementor_data, $widget_name );
if ( $widget_exists_in_page ) {
$response->data['pages'][ $index ]['shortcode_present'] = true;
}
}
public function loop_query( $query_args, $widget ) {
if ( ! $this->is_product_query( $widget ) ) {
return $query_args;
}
return $this->parse_loop_query_args( $widget, $query_args );
}
private function is_product_query( $widget ) {
$widget_config = $widget->get_config();
return ( ! empty( $widget_config['is_loop'] ) && 'product' === $widget->get_current_skin_id() );
}
private function parse_loop_query_args( $widget, $query_args ) {
$settings = $this->adjust_setting_for_product_renderer( $widget );
// For Products_Renderer.
if ( ! isset( $GLOBALS['post'] ) ) {
$GLOBALS['post'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
$shortcode = Products_Widget::get_shortcode_object( $settings );
$parsed_query_args = $shortcode->parse_query_args();
unset( $parsed_query_args['fields'] );
$override_various_query_args = array_filter( $query_args, function( $key ) {
return in_array( $key, [ 'posts_per_page', 'offset', 'paged' ], true );
}, ARRAY_FILTER_USE_KEY );
return wp_parse_args( $override_various_query_args, $parsed_query_args );
}
private function adjust_setting_for_product_renderer( $widget ) {
$settings = $widget->get_settings_for_display();
$query_name = $widget->get_query_name();
$unique_query_settings = array_filter( $settings, function( $key ) use ( $query_name ) {
return 0 === strpos( $key, $query_name );
}, ARRAY_FILTER_USE_KEY );
$query_settings = [];
foreach ( $unique_query_settings as $key => $value ) {
$query_settings[ 'query' . str_replace( $query_name, '', $key ) ] = $value;
}
$settings = array_merge( $settings, $query_settings );
if ( isset( $settings['posts_per_page'] ) && isset( $settings['columns'] ) ) {
$settings['rows'] = ceil( $settings['posts_per_page'] / $settings['columns'] );
}
$settings['paginate'] = 'yes';
$settings['allow_order'] = 'no';
$settings['show_result_count'] = 'no';
$settings['query_fields'] = false;
return $settings;
}
/**
* @param $post_id
* @return bool
*/
private function is_source_set_to_products( $post_id ) {
return 'product' === get_post_meta( $post_id, '_elementor_source', true );
}
/**
* @param array $config
* @return array
*/
private function add_woocommerce_widgets_to_recommended( array $config ) {
foreach ( static::RECOMMENDED_POSTS_WIDGET_NAMES as $recommended_posts_widget_name ) {
$config['panel']['widgets_settings'][ $recommended_posts_widget_name ] = [
'categories' => [ 'recommended' ],
'show_in_panel' => true,
];
}
return $config;
}
private function hide_woocommerce_widgets_in_loop_document( array $config ) {
$config['panel']['widgets_settings']['woocommerce-product-images'] = [
'show_in_panel' => false,
];
return $config;
}
private function populate_persistent_settings( array $config ) {
$config['persistent_keys'] = array_key_exists( 'persistent_keys', $config ) ?
array_merge( $config['persistent_keys'], self::WC_PERSISTENT_SITE_SETTINGS ) :
self::WC_PERSISTENT_SITE_SETTINGS;
return $config;
}
}
woocommerce/widgets/product-rating.php 0000644 00000010566 15043204017 0014210 0 ustar 00 start_controls_section(
'section_product_rating_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_control(
'star_color',
[
'label' => esc_html__( 'Star Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .star-rating' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'empty_star_color',
[
'label' => esc_html__( 'Empty Star Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .star-rating::before' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'link_color',
[
'label' => esc_html__( 'Link Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .woocommerce-review-link' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '.woocommerce {{WRAPPER}} .woocommerce-review-link',
]
);
$this->add_control(
'star_size',
[
'label' => esc_html__( 'Star Size', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'default' => [
'unit' => 'em',
],
'range' => [
'em' => [
'min' => 0,
'max' => 4,
'step' => 0.1,
],
],
'selectors' => [
'.woocommerce {{WRAPPER}} .star-rating' => 'font-size: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'space_between',
[
'label' => esc_html__( 'Space Between', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'default' => [
'unit' => 'em',
],
'range' => [
'em' => [
'min' => 0,
'max' => 4,
'step' => 0.1,
],
'px' => [
'min' => 0,
'max' => 50,
'step' => 1,
],
],
'selectors' => [
'.woocommerce:not(.rtl) {{WRAPPER}} .star-rating' => 'margin-right: {{SIZE}}{{UNIT}}',
'.woocommerce.rtl {{WRAPPER}} .star-rating' => 'margin-left: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justified', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'prefix_class' => 'elementor-product-rating--align-',
]
);
$this->end_controls_section();
}
protected function render() {
if ( ! post_type_supports( 'product', 'comments' ) ) {
return;
}
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
wc_get_template( 'single-product/rating.php' );
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-stock.php 0000644 00000004003 15043204017 0014034 0 ustar 00 start_controls_section(
'section_product_stock_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .stock' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '.woocommerce {{WRAPPER}} .stock',
]
);
$this->end_controls_section();
}
protected function render() {
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
// PHPCS - the method wc_get_stock_html is safe.
echo wc_get_stock_html( $product ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/products.php 0000644 00000023563 15043204017 0013112 0 ustar 00 start_controls_section(
'section_query',
[
'label' => esc_html__( 'Query', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_query_controls( Products_Renderer::QUERY_CONTROL_NAME );
$this->end_controls_section();
}
protected function register_controls() {
$this->start_controls_section(
'section_content',
[
'label' => esc_html__( 'Content', 'elementor-pro' ),
]
);
$this->add_columns_responsive_control();
$this->add_control(
'rows',
[
'label' => esc_html__( 'Rows', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => Products_Renderer::DEFAULT_COLUMNS_AND_ROWS,
'render_type' => 'template',
'range' => [
'px' => [
'max' => 20,
],
],
]
);
$this->add_control(
'paginate',
[
'label' => esc_html__( 'Pagination', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'condition' => [
Products_Renderer::QUERY_CONTROL_NAME . '_post_type!' => [
'related_products',
'upsells',
'cross_sells',
],
],
]
);
$this->add_control(
'allow_order',
[
'label' => esc_html__( 'Allow Order', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'condition' => [
'paginate' => 'yes',
],
]
);
$this->add_control(
'wc_notice_frontpage',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'Ordering is not available if this widget is placed in your front page. Visible on frontend only.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
'condition' => [
'paginate' => 'yes',
'allow_order' => 'yes',
],
]
);
$this->add_control(
'show_result_count',
[
'label' => esc_html__( 'Show Result Count', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'condition' => [
'paginate' => 'yes',
],
]
);
$this->end_controls_section();
$this->register_query_section();
$this->start_controls_section(
'section_products_title',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'conditions' => [
'relation' => 'or',
'terms' => [
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'related_products',
],
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'upsells',
],
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'cross_sells',
],
],
],
]
);
$this->add_control(
'products_title_show',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'default' => '',
'return_value' => 'show',
'prefix_class' => 'products-heading-',
]
);
$query_type_strings = [
'related_products' => esc_html__( 'Related Products', 'elementor-pro' ),
'upsells' => esc_html__( 'You may also like...', 'elementor-pro' ),
'cross_sells' => esc_html__( 'You may be interested in...', 'elementor-pro' ),
];
foreach ( $query_type_strings as $query_type => $string ) {
$this->add_control(
'products_' . $query_type . '_title_text',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'label_block' => true,
'placeholder' => $string,
'default' => $string,
'dynamic' => [
'active' => true,
],
'condition' => [
'products_title_show!' => '',
Products_Renderer::QUERY_CONTROL_NAME . '_post_type' => $query_type,
],
]
);
}
$this->add_responsive_control(
'products_title_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--products-title-alignment: {{VALUE}};',
],
'condition' => [
'products_title_show!' => '',
],
]
);
$this->end_controls_section();
parent::register_controls();
$this->start_injection( [
'type' => 'section',
'at' => 'start',
'of' => 'section_design_box',
] );
$this->start_controls_section(
'products_title_style',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'products_title_show!' => '',
],
'conditions' => [
'relation' => 'or',
'terms' => [
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'related_products',
],
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'upsells',
],
[
'name' => Products_Renderer::QUERY_CONTROL_NAME . '_post_type',
'operator' => '=',
'value' => 'cross_sells',
],
],
],
]
);
$this->add_control(
'products_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'{{WRAPPER}}' => '--products-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'products_title_typography',
'selector' => '{{WRAPPER}}.products-heading-show .related-products > h2, {{WRAPPER}}.products-heading-show .upsells > h2, {{WRAPPER}}.products-heading-show .cross-sells > h2',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
]
);
$this->add_responsive_control(
'products_title_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--products-title-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->end_injection();
}
public static function get_shortcode_object( $settings ) {
if ( 'current_query' === $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ] ) {
return new Current_Query_Renderer( $settings, 'current_query' );
}
return new Products_Renderer( $settings, 'products' );
}
protected function render() {
if ( WC()->session ) {
wc_print_notices();
}
$settings = $this->get_settings_for_display();
$post_type_setting = $settings[ Products_Renderer::QUERY_CONTROL_NAME . '_post_type' ];
// Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected.
if ( 'yes' === $settings['automatically_align_buttons'] ) {
add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 );
}
if ( 'related_products' === $post_type_setting ) {
$content = Module::get_products_related_content( $settings );
} elseif ( 'upsells' === $post_type_setting ) {
$content = Module::get_upsells_content( $settings );
} elseif ( 'cross_sells' === $post_type_setting ) {
$content = Module::get_cross_sells_content( $settings );
} else {
// For Products_Renderer.
if ( ! isset( $GLOBALS['post'] ) ) {
$GLOBALS['post'] = null; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
}
$shortcode = static::get_shortcode_object( $settings );
$content = $shortcode->get_content();
}
if ( $content ) {
$content = str_replace( 'get_settings_for_display( 'nothing_found_message' ) ) {
echo '' . esc_html( $this->get_settings_for_display( 'nothing_found_message' ) ) . '
';
}
if ( 'yes' === $settings['automatically_align_buttons'] ) {
remove_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ] );
}
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-short-description.php 0000644 00000005450 15043204017 0016400 0 ustar 00 start_controls_section(
'section_product_description_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_responsive_control(
'text_align',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justified', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}}',
],
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .woocommerce-product-details__short-description' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '.woocommerce {{WRAPPER}} .woocommerce-product-details__short-description',
]
);
$this->end_controls_section();
}
protected function render() {
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
wc_get_template( 'single-product/short-description.php' );
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-images.php 0000644 00000013421 15043204017 0014162 0 ustar 00 start_controls_section(
'section_product_gallery_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_control(
'sale_flash',
[
'label' => esc_html__( 'Sale Flash', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'render_type' => 'template',
'return_value' => 'yes',
'default' => 'yes',
'prefix_class' => '',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'image_border',
'selector' => '.woocommerce {{WRAPPER}} .woocommerce-product-gallery__trigger + .woocommerce-product-gallery__wrapper,
.woocommerce {{WRAPPER}} .flex-viewport, .woocommerce {{WRAPPER}} .flex-control-thumbs img',
'separator' => 'before',
]
);
$this->add_responsive_control(
'image_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} .woocommerce-product-gallery__trigger + .woocommerce-product-gallery__wrapper,
.woocommerce {{WRAPPER}} .flex-viewport' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}',
],
]
);
$this->add_control(
'spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} .flex-viewport:not(:last-child)' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'heading_thumbs_style',
[
'label' => esc_html__( 'Thumbnails', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'thumbs_border',
'selector' => '.woocommerce {{WRAPPER}} .flex-control-thumbs img',
]
);
$this->add_responsive_control(
'thumbs_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} .flex-control-thumbs img' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}',
],
]
);
$this->add_control(
'spacing_thumbs',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} .flex-control-thumbs li' => 'padding-right: calc({{SIZE}}{{UNIT}} / 2); padding-left: calc({{SIZE}}{{UNIT}} / 2); padding-bottom: {{SIZE}}{{UNIT}}',
'.woocommerce {{WRAPPER}} .flex-control-thumbs' => 'margin-right: calc(-{{SIZE}}{{UNIT}} / 2); margin-left: calc(-{{SIZE}}{{UNIT}} / 2)',
],
]
);
$this->end_controls_section();
}
public function render() {
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
$settings = $this->get_settings_for_display();
$is_library_preview = Utils::_unstable_get_super_global_value( $_GET, 'elementor_library' )
&& Utils::_unstable_get_super_global_value( $_GET, 'preview_id' );
if ( $is_library_preview ) {
// We need to enqueue these scripts manually on the Library preview.
$this->load_assets_dependencies();
}
if ( 'yes' === $settings['sale_flash'] ) {
wc_get_template( 'loop/sale-flash.php' );
}
wc_get_template( 'single-product/product-image.php' );
// On render widget from Editor - trigger the init manually.
if ( Plugin::elementor()->editor->is_edit_mode() ) {
?>
start_controls_section(
'section_product_description_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_responsive_control(
'text_align',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justified', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}}' => 'text-align: {{VALUE}}',
],
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} .term-description' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '.woocommerce {{WRAPPER}} .term-description',
]
);
$this->end_controls_section();
}
protected function render() {
do_action( 'woocommerce_archive_description' );
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-meta.php 0000644 00000031225 15043204017 0013645 0 ustar 00 start_controls_section(
'section_product_meta_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_control(
'view',
[
'label' => esc_html__( 'View', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'inline',
'options' => [
'table' => esc_html__( 'Table', 'elementor-pro' ),
'stacked' => esc_html__( 'Stacked', 'elementor-pro' ),
'inline' => esc_html__( 'Inline', 'elementor-pro' ),
],
'prefix_class' => 'elementor-woo-meta--view-',
]
);
$this->add_responsive_control(
'space_between',
[
'label' => esc_html__( 'Space Between', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'max' => 50,
],
],
'selectors' => [
'{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child)' => 'padding-bottom: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:first-child)' => 'margin-top: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container' => 'margin-right: calc({{SIZE}}{{UNIT}}/2); margin-left: calc({{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta' => 'margin-right: calc(-{{SIZE}}{{UNIT}}/2); margin-left: calc(-{{SIZE}}{{UNIT}}/2)',
'body:not(.rtl) {{WRAPPER}}.elementor-woo-meta--view-inline .detail-container:after' => 'right: calc( (-{{SIZE}}{{UNIT}}/2) + (-{{divider_weight.SIZE}}px/2) )',
'body:not.rtl {{WRAPPER}}.elementor-woo-meta--view-inline .detail-container:after' => 'left: calc( (-{{SIZE}}{{UNIT}}/2) - ({{divider_weight.SIZE}}px/2) )',
],
]
);
$this->add_control(
'divider',
[
'label' => esc_html__( 'Divider', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => esc_html__( 'Off', 'elementor-pro' ),
'label_on' => esc_html__( 'On', 'elementor-pro' ),
'selectors' => [
'{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'content: ""',
],
'return_value' => 'yes',
'separator' => 'before',
]
);
$this->add_control(
'divider_style',
[
'label' => esc_html__( 'Style', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'solid' => esc_html__( 'Solid', 'elementor-pro' ),
'double' => esc_html__( 'Double', 'elementor-pro' ),
'dotted' => esc_html__( 'Dotted', 'elementor-pro' ),
'dashed' => esc_html__( 'Dashed', 'elementor-pro' ),
],
'default' => 'solid',
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child):after' => 'border-top-style: {{VALUE}}',
'{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container:not(:last-child):after' => 'border-left-style: {{VALUE}}',
],
]
);
$this->add_control(
'divider_weight',
[
'label' => esc_html__( 'Weight', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'default' => [
'size' => 1,
],
'range' => [
'px' => [
'min' => 1,
'max' => 20,
],
],
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}}:not(.elementor-woo-meta--view-inline) .product_meta .detail-container:not(:last-child):after' => 'border-top-width: {{SIZE}}{{UNIT}}; margin-bottom: calc(-{{SIZE}}{{UNIT}}/2)',
'{{WRAPPER}}.elementor-woo-meta--view-inline .product_meta .detail-container:not(:last-child):after' => 'border-left-width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_responsive_control(
'divider_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'default' => [
'unit' => '%',
],
'condition' => [
'divider' => 'yes',
'view!' => 'inline',
],
'selectors' => [
'{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'divider_height',
[
'label' => esc_html__( 'Height', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vh', 'custom' ],
'default' => [
'unit' => '%',
],
'range' => [
'px' => [
'min' => 1,
'max' => 100,
],
'%' => [
'min' => 1,
'max' => 100,
],
],
'condition' => [
'divider' => 'yes',
'view' => 'inline',
],
'selectors' => [
'{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'height: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'divider_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'default' => '#ddd',
'global' => [
'default' => Global_Colors::COLOR_TEXT,
],
'condition' => [
'divider' => 'yes',
],
'selectors' => [
'{{WRAPPER}} .product_meta .detail-container:not(:last-child):after' => 'border-color: {{VALUE}}',
],
]
);
$this->add_control(
'heading_text_style',
[
'label' => esc_html__( 'Text', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'text_typography',
'selector' => '{{WRAPPER}}',
]
);
$this->add_control(
'text_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'heading_link_style',
[
'label' => esc_html__( 'Link', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'link_typography',
'selector' => '{{WRAPPER}} a',
]
);
$this->add_control(
'link_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} a' => 'color: {{VALUE}}',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_product_meta_captions',
[
'label' => esc_html__( 'Captions', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'heading_category_caption',
[
'label' => esc_html__( 'Category', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
]
);
$this->add_control(
'category_caption_single',
[
'label' => esc_html__( 'Singular', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Category', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'category_caption_plural',
[
'label' => esc_html__( 'Plural', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Categories', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'heading_tag_caption',
[
'label' => esc_html__( 'Tag', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'tag_caption_single',
[
'label' => esc_html__( 'Singular', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Tag', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'tag_caption_plural',
[
'label' => esc_html__( 'Plural', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Tags', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'heading_sku_caption',
[
'label' => esc_html__( 'SKU', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'sku_caption',
[
'label' => esc_html__( 'SKU', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'SKU', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'sku_missing_caption',
[
'label' => esc_html__( 'Missing', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'N/A', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->end_controls_section();
}
private function get_plural_or_single( $single, $plural, $count ) {
return 1 === $count ? $single : $plural;
}
protected function render() {
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
$sku = esc_html( $product->get_sku() );
$settings = $this->get_settings_for_display();
$sku_caption = ! empty( $settings['sku_caption'] ) ? esc_html( $settings['sku_caption'] ) : esc_html__( 'SKU', 'elementor-pro' );
$sku_missing = ! empty( $settings['sku_missing_caption'] ) ? esc_html( $settings['sku_missing_caption'] ) : esc_html__( 'N/A', 'elementor-pro' );
$category_caption_single = ! empty( $settings['category_caption_single'] ) ? $settings['category_caption_single'] : esc_html__( 'Category', 'elementor-pro' );
$category_caption_plural = ! empty( $settings['category_caption_plural'] ) ? $settings['category_caption_plural'] : esc_html__( 'Categories', 'elementor-pro' );
$tag_caption_single = ! empty( $settings['tag_caption_single'] ) ? $settings['tag_caption_single'] : esc_html__( 'Tag', 'elementor-pro' );
$tag_caption_plural = ! empty( $settings['tag_caption_plural'] ) ? $settings['tag_caption_plural'] : esc_html__( 'Tags', 'elementor-pro' );
?>
is_type( 'variable' ) ) ) : ?>
get_category_ids() ) ) : ?>
get_plural_or_single( $category_caption_single, $category_caption_plural, count( $product->get_category_ids() ) ) ); ?> get_id(), 'product_cat', '', ', ' ); ?>
get_tag_ids() ) ) : ?>
get_plural_or_single( $tag_caption_single, $tag_caption_plural, count( $product->get_tag_ids() ) ) ); ?> get_id(), 'product_tag', '', ', ' ); ?>
'image',
'is_core_dependency' => true,
],
];
}
protected function register_controls() {
parent::register_controls();
$this->update_control(
'image',
[
'dynamic' => [
'default' => Plugin::elementor()->dynamic_tags->tag_data_to_tag_text( null, 'woocommerce-category-image-tag' ),
],
],
[
'recursive' => true,
]
);
}
protected function get_html_wrapper_class() {
return parent::get_html_wrapper_class() . ' elementor-widget-' . parent::get_name();
}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/add-to-cart.php 0000644 00000017273 15043204017 0013347 0 ustar 00 start_controls_section(
'section_product',
[
'label' => esc_html__( 'Product', 'elementor-pro' ),
]
);
$this->add_control(
'product_id',
[
'label' => esc_html__( 'Product', 'elementor-pro' ),
'type' => Module::QUERY_CONTROL_ID,
'options' => [],
'label_block' => true,
'autocomplete' => [
'object' => Module::QUERY_OBJECT_POST,
'query' => [
'post_type' => [ 'product' ],
],
],
]
);
$this->add_control(
'show_quantity',
[
'label' => esc_html__( 'Show Quantity', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'description' => esc_html__( 'Please note that switching on this option will disable some of the design controls.', 'elementor-pro' ),
]
);
$this->add_control(
'quantity',
[
'label' => esc_html__( 'Quantity', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => 1,
'condition' => [
'show_quantity' => '',
],
]
);
$this->end_controls_section();
parent::register_controls();
$this->start_controls_section(
'section_layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => esc_html__( 'Inline', 'elementor-pro' ),
'stacked' => esc_html__( 'Stacked', 'elementor-pro' ),
'auto' => esc_html__( 'Auto', 'elementor-pro' ),
],
'prefix_class' => 'elementor-add-to-cart--layout-',
'render_type' => 'template',
]
);
$this->end_controls_section();
$this->update_control(
'link',
[
'type' => Controls_Manager::HIDDEN,
'default' => [
'url' => '',
],
]
);
$this->update_control(
'text',
[
'default' => esc_html__( 'Add to Cart', 'elementor-pro' ),
'placeholder' => esc_html__( 'Add to Cart', 'elementor-pro' ),
]
);
$this->update_responsive_control(
'align',
[
'prefix_class' => 'elementor-add-to-cart%s--align-',
]
);
$this->update_control(
'selected_icon',
[
'default' => [
'value' => 'fas fa-shopping-cart',
'library' => 'fa-solid',
],
]
);
$this->update_control(
'size',
[
'condition' => [
'show_quantity' => '',
],
]
);
}
protected function render() {
$settings = $this->get_settings_for_display();
if ( ! empty( $settings['product_id'] ) ) {
$product_id = $settings['product_id'];
} elseif ( wp_doing_ajax() && ! empty( $settings['product_id'] ) ) {
// PHPCS - No nonce is required.
// phpcs:ignore WordPress.Security.NonceVerification.Missing
$product_id = (int) Utils::_unstable_get_super_global_value( $_POST, 'post_id' );
} else {
$product_id = get_queried_object_id();
}
global $product;
$product = $this->get_product( $product_id );
$settings = $this->get_settings_for_display();
if ( in_array( $settings['layout'], [ 'auto', 'stacked' ], true ) ) {
add_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 );
add_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 );
}
if ( 'yes' === $settings['show_quantity'] ) {
$this->render_form_button( $product );
} else {
$this->render_ajax_button( $product );
}
if ( in_array( $settings['layout'], [ 'auto', 'stacked' ], true ) ) {
remove_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 );
remove_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 );
}
}
/**
* Before Add to Cart Quantity
*
* Added wrapper tag around the quantity input and "Add to Cart" button
* used to more solidly accommodate the layout when additional elements
* are added by 3rd party plugins.
*
* @since 3.6.0
*/
public function before_add_to_cart_quantity() {
?>
get_settings_for_display();
if ( $product ) {
if ( version_compare( WC()->version, '3.0.0', '>=' ) ) {
$product_type = $product->get_type();
} else {
$product_type = $product->product_type;
}
$class = implode( ' ', array_filter( [
'product_type_' . $product_type,
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
] ) );
$this->add_render_attribute( 'button',
[
'rel' => 'nofollow',
'href' => $product->add_to_cart_url(),
'data-quantity' => ( isset( $settings['quantity'] ) ? $settings['quantity'] : 1 ),
'data-product_id' => $product->get_id(),
'class' => $class,
]
);
} elseif ( current_user_can( 'manage_options' ) ) {
$settings['text'] = esc_html__( 'Please set a valid product', 'elementor-pro' );
$this->set_settings( $settings );
}
parent::render();
}
private function render_form_button( $product ) {
if ( ! $product && current_user_can( 'manage_options' ) ) {
echo esc_html__( 'Please set a valid product', 'elementor-pro' );
return;
}
$text_callback = function() {
ob_start();
$this->render_text();
return ob_get_clean();
};
add_filter( 'woocommerce_get_stock_html', '__return_empty_string' );
add_filter( 'woocommerce_product_single_add_to_cart_text', $text_callback );
add_filter( 'esc_html', [ $this, 'unescape_html' ], 10, 2 );
ob_start();
woocommerce_template_single_add_to_cart();
$form = ob_get_clean();
$form = str_replace( 'single_add_to_cart_button', 'single_add_to_cart_button elementor-button', $form );
// PHPCS - The HTML from 'woocommerce_template_single_add_to_cart' is safe.
echo $form; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
remove_filter( 'woocommerce_product_single_add_to_cart_text', $text_callback );
remove_filter( 'woocommerce_get_stock_html', '__return_empty_string' );
remove_filter( 'esc_html', [ $this, 'unescape_html' ] );
}
/**
* Written as a Backbone JavaScript template and used to generate the live preview.
*
* @since 2.9.0
* @access protected
*/
// Force remote render
protected function content_template() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/products-deprecated.php 0000644 00000015273 15043204017 0015207 0 ustar 00 query;
}
protected function register_skins() {
$this->add_skin( new Skins\Skin_Classic( $this ) );
}
protected function register_controls() {
$this->deprecated_notice( Plugin::get_title(), '2.0.10', '', esc_html__( 'Products', 'elementor-pro' ) );
$this->start_controls_section(
'section_layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_control(
'posts_per_page',
[
'label' => esc_html__( 'Products Count', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => '4',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_filter',
[
'label' => esc_html__( 'Query', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_CONTENT,
]
);
$this->add_group_control(
Group_Control_Posts::get_type(),
[
'name' => 'posts',
'post_type' => 'product',
]
);
$this->add_control(
'advanced',
[
'label' => esc_html__( 'Advanced', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
]
);
$this->add_control(
'filter_by',
[
'label' => esc_html__( 'Filter By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => '',
'options' => [
'' => esc_html__( 'None', 'elementor-pro' ),
'featured' => esc_html__( 'Featured', 'elementor-pro' ),
'sale' => esc_html__( 'Sale', 'elementor-pro' ),
],
]
);
$this->add_control(
'orderby',
[
'label' => esc_html__( 'Order By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'date',
'options' => [
'date' => esc_html__( 'Date', 'elementor-pro' ),
'title' => esc_html__( 'Title', 'elementor-pro' ),
'price' => esc_html__( 'Price', 'elementor-pro' ),
'popularity' => esc_html__( 'Popularity', 'elementor-pro' ),
'rating' => esc_html__( 'Rating', 'elementor-pro' ),
'rand' => esc_html__( 'Random', 'elementor-pro' ),
'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ),
],
]
);
$this->add_control(
'order',
[
'label' => esc_html__( 'Order', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'desc',
'options' => [
'asc' => esc_html__( 'ASC', 'elementor-pro' ),
'desc' => esc_html__( 'DESC', 'elementor-pro' ),
],
]
);
$this->add_control(
'exclude',
[
'label' => esc_html__( 'Exclude', 'elementor-pro' ),
'type' => Controls_Manager::SELECT2,
'multiple' => true,
'options' => [
'current_post' => esc_html__( 'Current Post', 'elementor-pro' ),
'manual_selection' => esc_html__( 'Manual Selection', 'elementor-pro' ),
],
'label_block' => true,
]
);
$this->add_control(
'exclude_ids',
[
'label' => esc_html__( 'Search & Select', 'elementor-pro' ),
'type' => Module::QUERY_CONTROL_ID,
'autocomplete' => [
'object' => Module::QUERY_OBJECT_POST,
],
'options' => [],
'label_block' => true,
'multiple' => true,
'condition' => [
'exclude' => 'manual_selection',
],
]
);
$this->add_control(
'avoid_duplicates',
[
'label' => esc_html__( 'Avoid Duplicates', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'default' => '',
'description' => esc_html__( 'Set to Yes to avoid duplicate posts from showing up on the page. This only affects the frontend.', 'elementor-pro' ),
]
);
$this->end_controls_section();
parent::register_controls();
}
public function query_posts() {
$settings = $this->get_settings();
/** @var Module $query_module */
$query_module = Module::instance();
$query_args = $query_module->get_query_args( 'posts', $settings );
// Default ordering args
$ordering_args = WC()->query->get_catalog_ordering_args( $settings['orderby'], $settings['order'] );
$query_args['orderby'] = $ordering_args['orderby'];
$query_args['order'] = $ordering_args['order'];
if ( ! empty( $ordering_args['meta_key'] ) ) {
$query_args['meta_key'] = $ordering_args['meta_key'];
}
if ( 'sale' === $settings['filter_by'] ) {
// From WooCommerce `sale_products` shortcode
$query_args['post__in'] = array_merge( [ 0 ], wc_get_product_ids_on_sale() );
}
if ( version_compare( WC()->version, '3.0.0', '>=' ) ) {
$query_args = $this->get_wc_visibility_parse_query( $query_args );
} else {
$query_args = $this->get_wc_legacy_visibility_parse_query( $query_args );
}
$this->query = new \WP_Query( $query_args );
}
private function get_wc_visibility_parse_query( $query_args ) {
$settings = $this->get_settings();
$product_visibility_term_ids = wc_get_product_visibility_term_ids();
if ( 'featured' === $settings['filter_by'] ) {
$query_args['tax_query'][] = [
'taxonomy' => 'product_visibility',
'field' => 'term_taxonomy_id',
'terms' => $product_visibility_term_ids['featured'],
];
}
return $query_args;
}
private function get_wc_legacy_visibility_parse_query( $query_args ) {
$settings = $this->get_settings();
$query_args['meta_query'] = [
[
'key' => '_visibility',
'value' => [ 'catalog', 'visible' ],
'compare' => 'IN',
],
];
if ( 'featured' === $settings['filter_by'] ) {
// From WooCommerce `featured_products` shortcode
$query_args['meta_query'][] = [
'key' => '_featured',
'value' => 'yes',
];
}
return $query_args;
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/checkout.php 0000644 00000360460 15043204017 0013054 0 ustar 00 start_controls_section(
'section_content',
[
'label' => esc_html__( 'General', 'elementor-pro' ),
]
);
$this->add_control(
'checkout_layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'two-column' => esc_html__( 'Two columns', 'elementor-pro' ),
'one-column' => esc_html__( 'One column', 'elementor-pro' ),
],
'default' => 'two-column',
'prefix_class' => 'e-checkout-layout-',
]
);
$this->add_control(
'sticky_right_column',
[
'label' => esc_html__( 'Sticky Right Column', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Yes', 'elementor-pro' ),
'label_off' => esc_html__( 'No', 'elementor-pro' ),
'return_value' => 'yes',
'description' => esc_html__( 'The Order Summary and Payment sections will remain in place while scrolling.', 'elementor-pro' ),
'frontend_available' => true,
'render_type' => 'none',
'condition' => [
'checkout_layout' => 'two-column',
],
]
);
$this->add_control(
'sticky_right_column_offset',
[
'label' => esc_html__( 'Offset', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'frontend_available' => true,
'conditions' => [
'relation' => 'and',
'terms' => [
[
'name' => 'sticky_right_column',
'operator' => '!==',
'value' => '',
],
[
'name' => 'checkout_layout',
'operator' => '=',
'value' => 'two-column',
],
],
],
]
);
$this->end_controls_section();
if ( $this->is_wc_feature_active( 'checkout_login_reminder' ) ) {
$this->add_checkout_login_reminder_controls();
}
$this->start_controls_section(
'billing_details_section',
[
'label' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ),
]
);
$this->add_control(
'billing_details_section_title',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ),
'default' => $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ? esc_html__( 'Billing and Shipping Details', 'elementor-pro' ) : esc_html__( 'Billing Details', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_responsive_control(
'billing_details_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--billing-details-title-alignment: {{VALUE}};',
],
]
);
$repeater = new Repeater();
$repeater->start_controls_tabs( 'tabs', [
'condition' => [
'repeater_state' => '',
],
] );
$repeater->start_controls_tab( 'content_tab', [
'label' => esc_html__( 'Content', 'elementor-pro' ),
] );
$repeater->add_control(
'label',
[
'label' => esc_html__( 'Label', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
]
);
$repeater->add_control(
'placeholder',
[
'label' => esc_html__( 'Placeholder', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
]
);
$repeater->end_controls_tab();
$repeater->start_controls_tab( 'advanced_tab', [
'label' => esc_html__( 'Advanced', 'elementor-pro' ),
] );
$repeater->add_control(
'default',
[
'label' => esc_html__( 'Default Value', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
]
);
$repeater->end_controls_tab();
$repeater->end_controls_tabs();
$repeater->add_control(
'repeater_state',
[
'label' => esc_html__( 'Repeater State - hidden', 'elementor-pro' ),
'type' => Controls_Manager::HIDDEN,
]
);
$repeater->add_control(
'locale_notice',
[
'raw' => __( 'Note: This content cannot be changed due to local regulations.', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'repeater_state' => 'locale',
],
]
);
$repeater->add_control(
'from_billing_notice',
[
'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'repeater_state' => 'from_billing',
],
]
);
$this->add_control(
'billing_details_form_fields',
[
'label' => esc_html__( 'Form Items', 'elementor-pro' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'item_actions' => [
'add' => false,
'duplicate' => false,
'remove' => false,
'sort' => false,
],
'default' => $this->get_billing_field_defaults(),
'title_field' => '{{{ label }}}',
]
);
$this->end_controls_section();
if ( $this->is_wc_feature_active( 'shipping' ) && ! $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ) {
$this->add_shipping_controls();
}
$this->start_controls_section(
'additional_information_section',
[
'label' => esc_html__( 'Additional Information', 'elementor-pro' ),
]
);
$this->add_control(
'additional_information_active',
[
'label' => esc_html__( 'Additional Information', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'default' => 'yes',
'selectors' => [
'{{WRAPPER}}' => '--additional-information-display: block;',
],
]
);
if ( $this->is_wc_feature_active( 'ship_to_billing_address_only' ) ) {
$this->add_control(
'additional_information_section_title',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'placeholder' => esc_html__( 'Additional Information', 'elementor-pro' ),
'default' => esc_html__( 'Additional Information', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
'condition' => [
'additional_information_active!' => '',
],
]
);
$this->add_responsive_control(
'additional_information_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--additional-fields-title-alignment: {{VALUE}};',
],
'condition' => [
'additional_information_active!' => '',
],
]
);
}
$repeater = new Repeater();
$repeater->start_controls_tabs( 'additional_information_form_fields_tabs' );
$repeater->start_controls_tab( 'additional_information_form_fields_content_tab', [
'label' => esc_html__( 'Content', 'elementor-pro' ),
] );
$repeater->add_control(
'label',
[
'label' => esc_html__( 'Label', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
]
);
$repeater->add_control(
'placeholder',
[
'label' => esc_html__( 'Placeholder', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
]
);
$repeater->end_controls_tab();
$repeater->start_controls_tab( 'additional_information_form_fields_advanced_tab', [
'label' => esc_html__( 'Advanced', 'elementor-pro' ),
] );
$repeater->add_control(
'default',
[
'label' => esc_html__( 'Default Value', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
]
);
$repeater->end_controls_tab();
$repeater->end_controls_tabs();
$this->add_control(
'additional_information_form_fields',
[
'label' => esc_html__( 'Items', 'elementor-pro' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'item_actions' => [
'add' => false,
'duplicate' => false,
'remove' => false,
'sort' => false,
],
'default' => [
[
'field_key' => 'order_comments',
'field_label' => esc_html__( 'Order Notes', 'elementor-pro' ),
'label' => esc_html__( 'Order Notes', 'elementor-pro' ),
'placeholder' => esc_html__( 'Notes about your order, e.g. special notes for delivery.', 'elementor-pro' ),
],
],
'title_field' => '{{{ label }}}',
'condition' => [
'additional_information_active!' => '',
],
]
);
$this->end_controls_section();
if ( $this->is_wc_feature_active( 'signup_and_login_from_checkout' ) ) {
$this->add_signup_and_login_from_checkout_controls();
}
$this->start_controls_section(
'order_summary_section',
[
'label' => esc_html__( 'Your Order', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_section_title',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Your Order', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_responsive_control(
'order_summary_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--order-review-title-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
if ( $this->is_wc_feature_active( 'coupons' ) ) {
$this->add_coupon_controls();
}
$this->start_controls_section(
'payment_section',
[
'label' => esc_html__( 'Payment', 'elementor-pro' ),
]
);
$this->add_control(
'terms_conditions_heading',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Terms & Conditions', 'elementor-pro' ),
]
);
$this->add_control(
'terms_conditions_message_text',
[
'label' => esc_html__( 'Message', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'label_block' => true,
'default' => esc_html__( 'I have read and agree to the website', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'terms_conditions_link_text',
[
'label' => esc_html__( 'Link Text', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'label_block' => true,
'default' => esc_html__( 'terms and conditions', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'purchase_buttom_heading',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Purchase Button', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'purchase_button_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justify', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout' => '{{VALUE}}',
],
'selectors_dictionary' => [
'start' => '--place-order-title-alignment: flex-start; --purchase-button-width: fit-content;',
'center' => '--place-order-title-alignment: center; --purchase-button-width: fit-content;',
'end' => '--place-order-title-alignment: flex-end; --purchase-button-width: fit-content;',
'justify' => '--place-order-title-alignment: stretch; --purchase-button-width: 100%;',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_style',
[
'label' => esc_html__( 'Sections', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'sections_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'section_normal_box_shadow',
'selector' => $this->get_main_woocommerce_sections_selectors(),
]
);
$this->add_control(
'sections_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'sections_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
$this->get_main_woocommerce_sections_selectors() => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'sections_border_type!' => 'none',
],
]
);
$this->add_control(
'sections_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'sections_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'sections_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'sections_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
// move the 'Ship to a different address?' checkbox
'{{WRAPPER}} .woocommerce-shipping-fields' => '--shipping-heading-padding-start: {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'sections_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_typography',
[
'label' => esc_html__( 'Typography', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'sections_typography',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles', 'elementor-pro' ),
]
);
$this->add_control(
'sections_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_titles_typography',
'selector' => $this->get_main_woocommerce_sections_title_selectors(),
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'sections_titles_text_shadow',
'selector' => $this->get_main_woocommerce_sections_title_selectors(),
]
);
$this->add_responsive_control(
'sections_title_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--sections-title-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'sections_secondary_typography',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Secondary Titles', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'sections_secondary_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-secondary-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_secondary_titles_typography',
'selector' => '{{WRAPPER}} .e-checkout-secondary-title',
]
);
$this->add_responsive_control(
'sections_secondary_title_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--sections-secondary-title-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'sections_descriptions_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Descriptions', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'sections_descriptions_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-descriptions-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_descriptions_typography',
'selector' => '{{WRAPPER}} .e-description',
]
);
$this->add_responsive_control(
'sections_descriptions_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--sections-descriptions-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'sections_messages_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Messages', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'sections_messages_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-messages-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_messages_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_box, {{WRAPPER}} .woocommerce-privacy-policy-text p, {{WRAPPER}} .e-checkout-message',
]
);
$this->add_control(
'sections_checkboxes_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Checkboxes', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'sections_checkboxes_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-checkboxes-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_checkboxes_typography',
'selector' => '{{WRAPPER}} .woocommerce-form__label-for-checkbox span',
]
);
$this->add_control(
'sections_radio_buttons_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Radio Buttons', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'sections_radio_buttons_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-radio-buttons-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'sections_radio_buttons_typography',
'selector' => '{{WRAPPER}} .wc_payment_method label, {{WRAPPER}} #shipping_method li label',
]
);
// Links
$this->add_control(
'sections_links_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Links', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->start_controls_tabs( 'links_colors' );
$this->start_controls_tab( 'links_normal_colors', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'links_normal_color',
[
'label' => esc_html__( 'Link Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--links-normal-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'links_hover_colors', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'links_hover_color',
[
'label' => esc_html__( 'Link Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--links-hover-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_forms',
[
'label' => esc_html__( 'Forms', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'forms_columns_gap',
[
'label' => esc_html__( 'Columns Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--forms-columns-gap-padding: calc( {{SIZE}}{{UNIT}}/2 ); --forms-columns-gap-margin: calc( -{{SIZE}}{{UNIT}}/2 );',
],
]
);
$this->add_responsive_control(
'forms_rows_gap',
[
'label' => esc_html__( 'Rows Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 60,
],
],
'selectors' => [
'{{WRAPPER}}' => '--forms-rows-gap: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'forms_label_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Labels', 'elementor-pro' ),
]
);
$this->add_control(
'forms_label_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--forms-labels-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'forms_label_typography',
'selector' => '{{WRAPPER}} .woocommerce-billing-fields .form-row label, {{WRAPPER}} .woocommerce-shipping-fields .form-row label, {{WRAPPER}} .woocommerce-additional-fields .form-row label, {{WRAPPER}} .e-woocommerce-login-anchor .form-row label, {{WRAPPER}} .e-coupon-anchor-description',
]
);
$this->add_responsive_control(
'forms_label_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 60,
],
],
'selectors' => [
'{{WRAPPER}}' => '--forms-label-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'forms_field_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Fields', 'elementor-pro' ),
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'forms_field_typography',
'selector' => '{{WRAPPER}} #customer_details .input-text, {{WRAPPER}} #customer_details .form-row textarea, {{WRAPPER}} #customer_details .form-row select, {{WRAPPER}} .e-woocommerce-login-anchor .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} ::placeholder, {{WRAPPER}} .select2-container--default .select2-selection--single, .select2-results__option',
]
);
$this->start_controls_tabs( 'forms_fields_styles' );
$this->start_controls_tab( 'forms_fields_normal_styles', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'forms_fields_normal_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--forms-fields-normal-color: {{VALUE}};',
'.e-woo-select2-wrapper .select2-results__option' => 'color: {{VALUE}};',
// style select2 arrow
'{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow b' => 'border-color: {{VALUE}} transparent transparent transparent;',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'forms_fields_normal_background',
'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text, {{WRAPPER}} .woocommerce #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single, {{WRAPPER}} .woocommerce-checkout #payment .payment_methods .payment_box',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'forms_fields_normal_box_shadow',
'selector' => '{{WRAPPER}} #customer_details .input-text, {{WRAPPER}} #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .e-woocommerce-login-anchor .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'forms_fields_focus_styles', [
'label' => esc_html__( 'Focus', 'elementor-pro' ),
] );
$this->add_control(
'forms_fields_focus_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--forms-fields-focus-color: {{VALUE}}',
'.e-woo-select2-wrapper .select2-results__option:focus' => 'color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'forms_fields_focus_background',
'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text:focus, {{WRAPPER}} .woocommerce #customer_details .form-row textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'forms_fields_focus_box_shadow',
'selector' => '{{WRAPPER}} #customer_details .input-text:focus, {{WRAPPER}} #customer_details textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .e-woocommerce-login-anchor .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus',
]
);
$this->add_control(
'forms_fields_focus_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce #customer_details .form-row .input-text:focus, {{WRAPPER}} .woocommerce #customer_details .form-row textarea:focus, {{WRAPPER}} #customer_details select:focus, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text:focus, {{WRAPPER}} #coupon_code:focus, {{WRAPPER}} .select2-container--default .select2-selection--single:focus' => 'border-color: {{VALUE}}',
],
'condition' => [
'forms_fields_border_border!' => '',
],
]
);
$this->add_control(
'forms_fields_focus_transition_duration',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)',
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}}' => '--forms-fields-focus-transition-duration: {{SIZE}}ms',
],
'range' => [
'px' => [
'min' => 0,
'max' => 3000,
],
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'forms_fields_border',
'selector' => '{{WRAPPER}} .woocommerce #customer_details .form-row .input-text, {{WRAPPER}} .woocommerce #customer_details .form-row textarea, {{WRAPPER}} .woocommerce form #customer_details select, {{WRAPPER}} .woocommerce .e-woocommerce-login-anchor .form-row .input-text, {{WRAPPER}} #coupon_code, {{WRAPPER}} .select2-container--default .select2-selection--single',
'separator' => 'before',
]
);
$this->add_responsive_control(
'forms_fields_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--forms-fields-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'forms_fields_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--forms-fields-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
// style select2
'{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__rendered' => 'line-height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); padding-left: {{LEFT}}{{UNIT}}; padding-right: {{RIGHT}}{{UNIT}};',
'{{WRAPPER}} .select2-container--default .select2-selection--single .select2-selection__arrow' => 'height: calc( ({{TOP}}{{UNIT}}*2) + 16px ); right: {{RIGHT}}{{UNIT}};',
'{{WRAPPER}} .select2-container--default .select2-selection--single' => 'height: auto;',
],
'separator' => 'after',
]
);
$this->add_control(
'forms_button_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Button', 'elementor-pro' ),
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'forms_button_typography',
'selector' => '{{WRAPPER}} .woocommerce-button',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'forms_button_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-button',
]
);
$this->start_controls_tabs( 'forms_buttons_styles' );
$this->start_controls_tab( 'forms_buttons_normal_styles', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'forms_buttons_normal_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--forms-buttons-normal-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'forms_buttons_normal_background',
'selector' => '{{WRAPPER}} .woocommerce-button',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'forms_buttons_normal_box_shadow',
'selector' => '{{WRAPPER}} .woocommerce-button',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'forms_buttons_hover_styles', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'forms_buttons_hover_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--forms-buttons-hover-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'forms_buttons_hover_background',
'selector' => '{{WRAPPER}} .woocommerce-button:hover',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'forms_buttons_focus_box_shadow',
'selector' => '{{WRAPPER}} .woocommerce-button:hover',
]
);
$this->add_control(
'forms_buttons_hover_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-apply-coupon:hover, {{WRAPPER}} .woocommerce-form-login__submit:hover' => 'border-color: {{VALUE}}',
],
'condition' => [
'forms_buttons_border_type!' => 'none',
],
]
);
$this->add_control(
'forms_buttons_hover_transition_duration',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)',
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}}' => '--forms-buttons-hover-transition-duration: {{SIZE}}ms',
],
'range' => [
'px' => [
'min' => 0,
'max' => 3000,
],
],
]
);
$this->add_control(
'forms_buttons_hover_animation',
[
'label' => esc_html__( 'Hover Animation', 'elementor-pro' ),
'type' => Controls_Manager::HOVER_ANIMATION,
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_control(
'forms_buttons_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--forms-buttons-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'forms_buttons_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-apply-coupon, {{WRAPPER}} .woocommerce-form-login__submit' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'forms_buttons_border_type!' => 'none',
],
]
);
$this->add_control(
'forms_buttons_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} ' => '--forms-buttons-border-color: {{VALUE}};',
],
'condition' => [
'forms_buttons_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'forms_buttons_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--forms-buttons-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'forms_buttons_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; width: auto;',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_order_summary',
[
'label' => esc_html__( 'Order Summary', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'order_summary_rows_gap',
[
'label' => esc_html__( 'Rows Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 60,
],
],
'selectors' => [
'{{WRAPPER}}' => '--order-summary-rows-gap-top: calc( {{SIZE}}{{UNIT}}/2 ); --order-summary-rows-gap-bottom: calc( {{SIZE}}{{UNIT}}/2 );',
],
]
);
$this->add_control(
'order_summary_items_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Items', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_items_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-summary-items-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_items_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout-review-order-table .cart_item td',
]
);
$this->add_control(
'order_summary_variations_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Variations', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_variations_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-summary-variations-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_variations_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_TEXT,
],
'selector' => '{{WRAPPER}} .product-name .variation',
]
);
$this->add_control(
'order_summary_items_divider_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Dividers', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_items_divider_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-summary-items-divider-color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'order_summary_items_divider_weight',
[
'label' => esc_html__( 'Weight', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--order-summary-items-divider-weight: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'order_summary_totals_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_totals_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-summary-totals-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_totals_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout-review-order-table thead tr th, {{WRAPPER}} .woocommerce-checkout-review-order-table tfoot tr th, {{WRAPPER}} .woocommerce-checkout-review-order-table tfoot tr td',
]
);
$this->add_control(
'order_summary_dividers_total_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Divider Total', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_totals_divider_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-summary-totals-divider-color: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'order_summary_totals_divider_weight',
[
'label' => esc_html__( 'Weight', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--order-summary-totals-divider-weight: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_purchase_button',
[
'label' => esc_html__( 'Purchase Button', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'purchase_button_typography',
'selector' => '{{WRAPPER}} .woocommerce #payment #place_order',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'purchase_button_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce #payment #place_order',
]
);
$this->start_controls_tabs( 'purchase_button_styles' );
$this->start_controls_tab( 'purchase_button_normal_styles', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'purchase_button_normal_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-normal-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'purchase_button_normal_background',
'selector' => '{{WRAPPER}} #payment #place_order',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'purchase_button_normal_box_shadow',
'selector' => '{{WRAPPER}} #place_order',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'purchase_button_hover_styles', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'purchase_button_hover_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-hover-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'purchase_button_hover_background',
'selector' => '{{WRAPPER}} #payment #place_order:hover',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'purchase_button_hover_box_shadow',
'selector' => '{{WRAPPER}} #place_order:hover',
]
);
$this->add_control(
'purchase_button_hover_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-hover-border-color: {{VALUE}}',
],
'condition' => [
'purchase_button_border_border!' => '',
],
]
);
$this->add_control(
'purchase_button_hover_transition_duration',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)',
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-hover-transition-duration: {{SIZE}}ms',
],
'range' => [
'px' => [
'min' => 0,
'max' => 3000,
],
],
]
);
$this->add_control(
'purchase_button_hover_animation',
[
'label' => esc_html__( 'Hover Animation', 'elementor-pro' ),
'type' => Controls_Manager::HOVER_ANIMATION,
'frontend_available' => true,
'render_type' => 'template',
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'purchase_button_border',
'selector' => '{{WRAPPER}} #place_order',
'separator' => 'before',
]
);
$this->add_responsive_control(
'purchase_button_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'purchase_button_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--purchase-button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}}; --purchase-button-width: fit-content;',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_customize',
[
'label' => esc_html__( 'Customize', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$customize_options = [];
if ( $this->is_wc_feature_active( 'checkout_login_reminder' ) ) {
$customize_options += [
'customize_returning_customer' => esc_html__( 'Returning Customer', 'elementor-pro' ),
];
}
$customize_options += [
'customize_billing_details' => esc_html__( 'Billing Details', 'elementor-pro' ),
'customize_additional_info' => esc_html__( 'Additional Information', 'elementor-pro' ),
];
if ( $this->is_wc_feature_active( 'shipping' ) ) {
$customize_options += [
'customize_shipping_address' => esc_html__( 'Shipping Address', 'elementor-pro' ),
];
}
$customize_options += [
'customize_order_summary' => esc_html__( 'Order Summary', 'elementor-pro' ),
];
if ( $this->is_wc_feature_active( 'coupons' ) ) {
$customize_options += [
'customize_coupon' => esc_html__( 'Coupon', 'elementor-pro' ),
];
}
$customize_options += [
'customize_payment' => esc_html__( 'Payment', 'elementor-pro' ),
];
$this->add_control(
'section_checkout_show_customize_elements',
[
'label' => esc_html__( 'Select sections of the checkout to customize:', 'elementor-pro' ),
'type' => Controls_Manager::SELECT2,
'multiple' => true,
'options' => $customize_options,
'render_type' => 'ui',
'label_block' => true,
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_customize_returning_customer',
[
'label' => esc_html__( 'Customize: Returning Customer', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_returning_customer',
],
]
);
$this->add_control(
'returning_customers_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_returning_customer_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'returning_customers_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .e-woocommerce-login-section',
]
);
$this->add_control(
'returning_customers_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'returning_customers_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'returning_customers_border_type!' => 'none',
],
]
);
$this->add_control(
'returning_customers_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'returning_customers_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'returning_customers_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'returning_customers_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'returning_customers_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'returning_customers_secondary_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Secondary Title', 'elementor-pro' ),
]
);
$this->add_control(
'returning_customers_secondary_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-form-login-toggle' => '--sections-secondary-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'returning_customers_content_typography',
'selector' => '{{WRAPPER}} .woocommerce-form-login-toggle',
]
);
$this->add_control(
'returning_customers_description_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Description', 'elementor-pro' ),
]
);
$this->add_control(
'returning_customers_description_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-nudge' => '--sections-descriptions-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'returning_customers_description_typography',
'selector' => '{{WRAPPER}} .e-woocommerce-login-nudge.e-description',
]
);
$this->add_control(
'returning_customers_checkboxes_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Checkbox', 'elementor-pro' ),
]
);
$this->add_control(
'returning_customers_checkboxes_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--sections-checkboxes-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'returning_customers_checkboxes_typography',
'selector' => '{{WRAPPER}} .e-woocommerce-login-section .woocommerce-form__label-for-checkbox span',
]
);
$this->add_control(
'returning_customers_link_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Link', 'elementor-pro' ),
]
);
$this->start_controls_tabs( 'returning_customers_links' );
$this->start_controls_tab( 'returning_customers_normal_links', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'returning_customers_normal_links_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--links-normal-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'returning_customers_hover_links', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'returning_customers_hover_links_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-login-section' => '--links-hover-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_customize_billing_details',
[
'label' => esc_html__( 'Customize: Billing Details', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_billing_details',
],
]
);
$this->add_control(
'customize_billing_details_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_billing_details_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'billing_details_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .e-checkout__column-start .col2-set .col-1',
]
);
$this->add_control(
'billing_details_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'billing_details_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-checkout__column-start #customer_details .col-1' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'billing_details_border_type!' => 'none',
],
]
);
$this->add_control(
'billing_details_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-border-color: {{VALUE}}',
],
'condition' => [
'billing_details_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'billing_details_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'billing_details_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'billing_details_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'billing_details_titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Title', 'elementor-pro' ),
]
);
$this->add_control(
'billing_details_titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'billing_details_titles_typography',
'selector' => '{{WRAPPER}} .woocommerce-billing-fields h3',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'billing_details_titles_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-billing-fields h3',
]
);
$this->add_control(
'billing_details_checkboxes_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Checkbox', 'elementor-pro' ),
]
);
$this->add_control(
'billing_details_checkboxes_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .col2-set .col-1' => '--sections-checkboxes-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'billing_details_checkboxes_typography',
'selector' => '{{WRAPPER}} .col2-set .col-1 .woocommerce-form__label-for-checkbox span',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_customize_additional_info',
[
'label' => esc_html__( 'Customize: Additional Information', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_additional_info',
],
]
);
$this->add_control(
'customize_additional_information_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_additional_information_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'additional_information_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .woocommerce-additional-fields',
]
);
$this->add_control(
'additional_information_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'additional_information_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'additional_information_border_type!' => 'none',
],
]
);
$this->add_control(
'additional_information_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'additional_information_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'additional_information_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'additional_information_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'additional_information_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
'{{WRAPPER}}.e-checkout-layout-one-column .e-checkout__container' => 'grid-row-gap: {{BOTTOM}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'additional_information_titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Title', 'elementor-pro' ),
]
);
$this->add_control(
'additional_information_titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-additional-fields' => '--sections-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'additional_information_titles_typography',
'selector' => '{{WRAPPER}} .woocommerce-additional-fields h3',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'additional_information_titles_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-additional-fields h3',
]
);
$this->end_controls_section();
if ( $this->is_wc_feature_active( 'shipping' ) ) {
$this->add_shipping_style_controls();
}
if ( $this->is_wc_feature_active( 'coupons' ) ) {
$this->add_coupons_style_controls();
}
$this->start_controls_section(
'section_checkout_tabs_customize_order_summary',
[
'label' => esc_html__( 'Customize: Order Summary', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_order_summary',
],
]
);
$this->add_control(
'customize_order_summary_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_order_summary_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'order_summary_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .e-checkout__order_review',
]
);
$this->add_control(
'order_summary_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'order_summary_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'order_summary_border_type!' => 'none',
],
]
);
$this->add_control(
'order_summary_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-border-color: {{VALUE}}',
],
'condition' => [
'order_summary_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'order_summary_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'order_summary_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'order_summary_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'order_summary_titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Title', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_titles_typography',
'selector' => '{{WRAPPER}} h3#order_review_heading',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'order_summary_titles_text_shadow',
'selector' => '{{WRAPPER}} h3#order_review_heading',
]
);
$this->add_control(
'order_summary_descriptions_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Message', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_descriptions_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-descriptions-color: {{VALUE}}; --sections-messages-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_descriptions_typography',
'selector' => '{{WRAPPER}} .woocommerce-no-shipping-available-html.e-description, {{WRAPPER}} .woocommerce-no-shipping-available-html.e-checkout-message',
]
);
$this->add_control(
'order_summary_radios_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Radio Button', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_radios_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-checkout__order_review' => '--sections-radio-buttons-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_summary_radio_typography',
'selector' => '{{WRAPPER}} .woocommerce .e-checkout__order_review ul#shipping_method li label',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_checkout_tabs_customize_payment',
[
'label' => esc_html__( 'Customize: Payment', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_payment',
],
]
);
$this->add_control(
'customize_payment_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_payment_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'payment_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .woocommerce-checkout #payment',
]
);
$this->add_control(
'payment_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'payment_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'payment_border_type!' => 'none',
],
]
);
$this->add_control(
'payment_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'payment_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'payment_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'payment_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'payment_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout #payment' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'payment_info_box_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Info Box', 'elementor-pro' ),
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'payment_info_box_title_background',
'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_methods .payment_box',
]
);
$this->add_control(
'payment_description_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Description', 'elementor-pro' ),
]
);
$this->add_control(
'payment_description_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-descriptions-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_description_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout-payment .e-description',
]
);
$this->add_control(
'payment_messages_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Message', 'elementor-pro' ),
]
);
$this->add_control(
'payment_messages_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-messages-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_messages_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout #payment .payment_box, {{WRAPPER}} .woocommerce-privacy-policy-text p',
]
);
$this->add_control(
'payment_checkboxes_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Checkbox', 'elementor-pro' ),
]
);
$this->add_control(
'payment_checkboxes_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-terms-and-conditions-wrapper' => '--sections-checkboxes-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_checkboxes_typography',
'selector' => '{{WRAPPER}} .woocommerce-terms-and-conditions-wrapper .woocommerce-form__label-for-checkbox span',
]
);
$this->add_control(
'payment_radio_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Radio Button', 'elementor-pro' ),
]
);
$this->add_control(
'payment_radio_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout-payment' => '--sections-radio-buttons-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_radio_typography',
'selector' => '{{WRAPPER}} .woocommerce-checkout-payment .wc_payment_method label',
]
);
$this->add_control(
'payment_links_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Links', 'elementor-pro' ),
]
);
$this->start_controls_tabs( 'payment_colors' );
$this->start_controls_tab( 'payment_normal_colors', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'payment_normal_color',
[
'label' => esc_html__( 'Link Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout-payment' => '--links-normal-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'payment_hover_colors', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'payment_hover_color',
[
'label' => esc_html__( 'Link Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-checkout-payment' => '--links-hover-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
}
private function add_checkout_login_reminder_controls() {
$this->start_controls_section(
'returning_customer_heading',
[
'label' => esc_html__( 'Returning Customer', 'elementor-pro' ),
]
);
$this->add_control(
'returning_customer_section_title',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Returning customer?', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_control(
'returning_customer_link_text',
[
'label' => esc_html__( 'Link Text', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Click here to login', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->add_responsive_control(
'returning_customer_title_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--login-title-alignment: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'login_button_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Login Button', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_responsive_control(
'login_button_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justify', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}} .e-login-wrap' => '{{VALUE}}',
],
'selectors_dictionary' => [
'start' => '--login-button-alignment: start; --login-button-width: 35%;',
'center' => '--login-button-alignment: center; --login-button-width: 35%;',
'end' => '--login-button-alignment: end; --login-button-width: 35%;',
'justify' => '--login-button-alignment: center; --login-button-width: 100%;',
],
]
);
$this->add_control(
'login_button_alignment_note',
[
'raw' => esc_html__( 'Note: This control will only affect screen sizes Tablet and below', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
]
);
$this->end_controls_section();
}
private function add_shipping_controls() {
$this->start_controls_section(
'shipping_details_section',
[
'label' => esc_html__( 'Shipping Details', 'elementor-pro' ),
]
);
$this->add_control(
'shipping_details_section_title',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Ship to a different address?', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$repeater = new Repeater();
$repeater->add_control(
'repeater_state',
[
'label' => esc_html__( 'Repeater State - hidden', 'elementor-pro' ),
'type' => Controls_Manager::HIDDEN,
]
);
$repeater->add_control(
'label_placeholder_notification',
[
'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'repeater_state' => 'from_billing',
],
]
);
$repeater->start_controls_tabs( 'tabs', [
'condition' => [
'repeater_state' => '',
],
] );
$repeater->start_controls_tab( 'content_tab', [
'label' => esc_html__( 'Content', 'elementor-pro' ),
] );
$repeater->add_control(
'label',
[
'label' => esc_html__( 'Label', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
]
);
$repeater->add_control(
'placeholder',
[
'label' => esc_html__( 'Placeholder', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
]
);
$repeater->end_controls_tab();
$repeater->start_controls_tab( 'advanced_tab', [
'label' => esc_html__( 'Advanced', 'elementor-pro' ),
] );
$repeater->add_control(
'default',
[
'label' => esc_html__( 'Default Value', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
]
);
$repeater->end_controls_tab();
$repeater->end_controls_tabs();
$repeater->add_control(
'locale_notice',
[
'raw' => __( 'Note: This content cannot be changed due to local regulations.', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'repeater_state' => 'locale',
],
]
);
$repeater->add_control(
'from_billing_notice',
[
'raw' => __( 'Note: This label and placeholder are taken from the Billing section. You can change it there.', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'repeater_state' => 'from_billing',
],
]
);
$this->add_control(
'shipping_details_form_fields',
[
'label' => esc_html__( 'Form Items', 'elementor-pro' ),
'type' => Controls_Manager::REPEATER,
'fields' => $repeater->get_controls(),
'item_actions' => [
'add' => false,
'duplicate' => false,
'remove' => false,
'sort' => false,
],
'default' => $this->get_shipping_field_defaults(),
'title_field' => '{{{ label }}}',
]
);
$this->end_controls_section();
}
private function add_signup_and_login_from_checkout_controls() {
$this->start_controls_section(
'create_account_section',
[
'label' => esc_html__( 'Create an Account', 'elementor-pro' ),
]
);
$this->add_control(
'create_account_text',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Create an account?', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
]
);
$this->end_controls_section();
}
private function add_coupon_controls() {
$this->start_controls_section(
'coupon_section',
[
'label' => esc_html__( 'Coupon', 'elementor-pro' ),
]
);
$this->add_control(
'coupon_section_display',
[
'label' => esc_html__( 'Coupon', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'default' => 'yes',
]
);
$this->add_control(
'coupon_section_title_text',
[
'label' => esc_html__( 'Section Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Have a coupon?', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->add_control(
'coupon_section_title_link_text',
[
'label' => esc_html__( 'Link Text', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'default' => esc_html__( 'Click here to enter your coupon code', 'elementor-pro' ),
'dynamic' => [
'active' => true,
],
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->add_responsive_control(
'coupon_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--coupon-title-alignment: {{VALUE}};',
],
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->add_responsive_control(
'coupon_button_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Apply Button', 'elementor-pro' ),
'separator' => 'before',
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->add_responsive_control(
'coupon_button_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justify', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'selectors' => [
'{{WRAPPER}} .coupon-container-grid' => '{{VALUE}}',
],
'selectors_dictionary' => [
'start' => '--coupon-button-alignment: start;',
'center' => '--coupon-button-alignment: center;',
'end' => '--coupon-button-alignment: end;',
'justify' => '--coupon-button-alignment: justify; --coupon-button-width: 100%;',
],
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->add_control(
'coupon_button_alignment_note',
[
'raw' => esc_html__( 'Note: This control will only affect screen sizes Tablet and below', 'elementor-pro' ),
'type' => Controls_Manager::RAW_HTML,
'content_classes' => 'elementor-descriptor',
'condition' => [
'coupon_section_display' => 'yes',
],
]
);
$this->end_controls_section();
}
private function add_shipping_style_controls() {
$this->start_controls_section(
'section_checkout_tabs_customize_shipping_address',
[
'label' => esc_html__( 'Customize: Shipping Address', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_shipping_address',
],
]
);
$this->add_control(
'shipping_address_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_shipping_address_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'shipping_address_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .woocommerce-shipping-fields .shipping_address',
]
);
$this->add_control(
'shipping_address_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'shipping_address_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'shipping_address_border_type!' => 'none',
],
]
);
$this->add_control(
'shipping_address_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-color: {{VALUE}}',
],
'condition' => [
'shipping_address_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'shipping_address_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'shipping_address_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'shipping_address_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields .shipping_address' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'shipping_address_checkboxes_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Checkboxes', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'shipping_address_checkboxes_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .woocommerce-shipping-fields' => '--sections-checkboxes-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'shipping_address_checkboxes_typography',
'selector' => '{{WRAPPER}} .woocommerce-shipping-fields .woocommerce-form__label-for-checkbox span',
]
);
$this->end_controls_section();
}
private function add_coupons_style_controls() {
$this->start_controls_section(
'section_checkout_tabs_customize_coupon',
[
'label' => esc_html__( 'Customize: Coupon', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
'condition' => [
'section_checkout_show_customize_elements' => 'customize_coupon',
],
]
);
$this->add_control(
'customize_coupon_section_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Section', 'elementor-pro' ),
]
);
$this->add_control(
'customize_coupon_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'coupon_section_normal_box_shadow',
'selector' => '{{WRAPPER}} .e-coupon-box',
]
);
$this->add_control(
'coupon_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'coupon_border_width',
[
'label' => esc_html__( 'Border Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'coupon_border_type!' => 'none',
],
]
);
$this->add_control(
'coupon_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'coupon_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'coupon_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'coupon_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'coupon_margin',
[
'label' => esc_html__( 'Margin', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--sections-margin: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'coupon_secondary_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Secondary Title', 'elementor-pro' ),
]
);
$this->add_control(
'coupon_secondary_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-woocommerce-coupon-nudge' => '--sections-secondary-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'coupon_content_typography',
'selector' => '{{WRAPPER}} .e-woocommerce-coupon-nudge.e-checkout-secondary-title',
]
);
$this->add_control(
'coupon_link_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Link', 'elementor-pro' ),
]
);
$this->start_controls_tabs( 'coupon_links' );
$this->start_controls_tab( 'coupon_normal_links', [
'label' => esc_html__( 'Normal', 'elementor-pro' ),
] );
$this->add_control(
'coupon_normal_links_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--links-normal-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'coupon_hover_links', [
'label' => esc_html__( 'Hover', 'elementor-pro' ),
] );
$this->add_control(
'coupon_hover_links_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .e-coupon-box' => '--links-hover-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
}
/**
* Get Billing Field Defaults
*
* Get defaults used for the billing details repeater control.
*
* @since 3.5.0
*
* @return array
*/
private function get_billing_field_defaults() {
$fields = [
'billing_first_name' => [
'label' => esc_html__( 'First Name', 'elementor-pro' ),
'repeater_state' => '',
],
'billing_last_name' => [
'label' => esc_html__( 'Last Name', 'elementor-pro' ),
'repeater_state' => '',
],
'billing_company' => [
'label' => esc_html__( 'Company Name', 'elementor-pro' ),
'repeater_state' => '',
],
'billing_country' => [
'label' => esc_html__( 'Country / Region', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'billing_address_1' => [
'label' => esc_html__( 'Street Address', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'billing_postcode' => [
'label' => esc_html__( 'Post Code', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'billing_city' => [
'label' => esc_html__( 'Town / City', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'billing_state' => [
'label' => esc_html__( 'State', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'billing_phone' => [
'label' => esc_html__( 'Phone', 'elementor-pro' ),
'repeater_state' => '',
],
'billing_email' => [
'label' => esc_html__( 'Email Address', 'elementor-pro' ),
'repeater_state' => '',
],
];
return $this->reformat_address_field_defaults( $fields );
}
/**
* Get Shipping Field Defaults
*
* Get defaults used for the shipping details repeater control.
*
* @since 3.5.0
*
* @return array
*/
private function get_shipping_field_defaults() {
$fields = [
'shipping_first_name' => [
'label' => esc_html__( 'First Name', 'elementor-pro' ),
'repeater_state' => '',
],
'shipping_last_name' => [
'label' => esc_html__( 'Last Name', 'elementor-pro' ),
'repeater_state' => '',
],
'shipping_company' => [
'label' => esc_html__( 'Company Name', 'elementor-pro' ),
'repeater_state' => '',
],
'shipping_country' => [
'label' => esc_html__( 'Country / Region', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'shipping_address_1' => [
'label' => esc_html__( 'Street Address', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'shipping_postcode' => [
'label' => esc_html__( 'Post Code', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'shipping_city' => [
'label' => esc_html__( 'Town / City', 'elementor-pro' ),
'repeater_state' => 'locale',
],
'shipping_state' => [
'label' => esc_html__( 'State', 'elementor-pro' ),
'repeater_state' => 'locale',
],
];
return $this->reformat_address_field_defaults( $fields );
}
/**
* Reformat Address Field Defaults
*
* Used with the `get_..._field_defaults()` methods.
* Takes the address array and converts it into the format expected by the repeater controls.
*
* @since 3.5.0
*
* @param $address
* @return array
*/
private function reformat_address_field_defaults( $address ) {
$defaults = [];
foreach ( $address as $key => $value ) {
$defaults[] = [
'field_key' => $key,
'field_label' => $value['label'],
'label' => $value['label'],
'placeholder' => $value['label'],
'repeater_state' => $value['repeater_state'],
];
}
return $defaults;
}
/**
* Get Main Woocommerce Sections Selectors
*
* Get all the 'Sections' selectors. There are numerous controls that need these selectors so it was easier
* to consolidate them into one function. Especially when updates need to be made.
*
* @since 3.5.0
*
* @return string
*/
private function get_main_woocommerce_sections_selectors() {
$selector = '{{WRAPPER}} .e-woocommerce-login-section, {{WRAPPER}} .woocommerce-checkout #customer_details .col-1, {{WRAPPER}} .woocommerce-additional-fields, {{WRAPPER}} .e-checkout__order_review, {{WRAPPER}} .e-coupon-box, {{WRAPPER}} .woocommerce-checkout #payment';
if ( $this->is_wc_feature_active( 'shipping' ) ) {
$selector .= ', {{WRAPPER}} .woocommerce-shipping-fields .shipping_address';
}
return $selector;
}
/**
* Get Main Woocommerce Sections Title Selectors
*
* Get all the 'Title' selectors. There are numerous controls that need these selectors so it was easier to
* consolidate them into one function. Especially when updates need to be made.
*
* @since 3.5.0
*
* @return string
*/
private function get_main_woocommerce_sections_title_selectors() {
return '{{WRAPPER}} h3#order_review_heading, {{WRAPPER}} .woocommerce-billing-fields h3, {{WRAPPER}} .woocommerce-additional-fields h3';
}
/**
* Init Gettext Modifications
*
* Sets the `$gettext_modifications` property used with the `filter_gettext()` in the extended Base_Widget.
*
* @since 3.5.0
*/
protected function init_gettext_modifications() {
$instance = $this->get_settings_for_display();
$this->gettext_modifications = [
'Billing details' => isset( $instance['billing_details_section_title'] ) ? $instance['billing_details_section_title'] : '',
'Billing & Shipping' => isset( $instance['billing_details_section_title'] ) ? $instance['billing_details_section_title'] : '',
'Ship to a different address?' => isset( $instance['shipping_details_section_title'] ) ? $instance['shipping_details_section_title'] : '',
'Additional information' => isset( $instance['additional_information_section_title'] ) ? $instance['additional_information_section_title'] : '',
'Your order' => isset( $instance['order_summary_section_title'] ) ? $instance['order_summary_section_title'] : '',
'Have a coupon?' => isset( $instance['coupon_section_title_text'] ) ? $instance['coupon_section_title_text'] : '',
'Click here to enter your coupon code' => isset( $instance['coupon_section_title_link_text'] ) ? $instance['coupon_section_title_link_text'] : '',
'Returning customer?' => isset( $instance['returning_customer_section_title'] ) ? $instance['returning_customer_section_title'] : '',
'Click here to login' => isset( $instance['returning_customer_link_text'] ) ? $instance['returning_customer_link_text'] : '',
'Create an account?' => isset( $instance['create_account_text'] ) ? $instance['create_account_text'] : '',
];
}
/**
* WooCommerce Terms and Conditions Checkbox Text.
*
* WooCommerce filter is used to apply widget settings to Checkout Terms & Conditions text and link text.
*
* @since 3.5.0
*
* @param string $text
* @return string
*/
public function woocommerce_terms_and_conditions_checkbox_text( $text ) {
$instance = $this->get_settings_for_display();
if ( ! isset( $instance['terms_conditions_message_text'] ) || ! isset( $instance['terms_conditions_link_text'] ) ) {
return $text;
}
$message = $instance['terms_conditions_message_text'];
$link = $instance['terms_conditions_link_text'];
$terms_page_id = wc_terms_and_conditions_page_id();
if ( $terms_page_id ) {
$message .= ' ' . $link . ' ';
}
return $message;
}
/**
* Modify Form Field.
*
* WooCommerce filter is used to apply widget settings to the Checkout forms address fields
* from the Billing and Shipping Details widget sections, e.g. label, placeholder, default.
*
* @since 3.5.0
*
* @param array $args
* @param string $key
* @param string $value
* @return array
*/
public function modify_form_field( $args, $key, $value ) {
$reformatted_form_fields = $this->get_reformatted_form_fields();
// Check if we need to modify the args of this form field.
if ( isset( $reformatted_form_fields[ $key ] ) ) {
$apply_fields = [
'label',
'placeholder',
'default',
];
foreach ( $apply_fields as $field ) {
if ( ! empty( $reformatted_form_fields[ $key ][ $field ] ) ) {
$args[ $field ] = $reformatted_form_fields[ $key ][ $field ];
}
}
}
return $args;
}
/**
* Get Reformatted Form Fields.
*
* Combines the 3 relevant repeater settings arrays into a one level deep associative array
* with the keys that match those that WooCommerce uses for its form fields.
*
* The result is cached so the conversion only ever happens once.
*
* @since 3.5.0
*
* @return array
*/
private function get_reformatted_form_fields() {
if ( ! isset( $this->reformatted_form_fields ) ) {
$instance = $this->get_settings_for_display();
// Reformat form repeater field into one usable array.
$repeater_fields = [
'billing_details_form_fields',
'shipping_details_form_fields',
'additional_information_form_fields',
];
$this->reformatted_form_fields = [];
// Apply other modifications to inputs.
foreach ( $repeater_fields as $repeater_field ) {
if ( isset( $instance[ $repeater_field ] ) ) {
foreach ( $instance[ $repeater_field ] as $item ) {
if ( ! isset( $item['field_key'] ) ) {
continue;
}
$this->reformatted_form_fields[ $item['field_key'] ] = $item;
}
}
}
}
return $this->reformatted_form_fields;
}
/**
* Render Woocommerce Checkout Login Form
*
* A custom function to render a login form on the Checkout widget. The default WC Login form
* was removed in this file's render() method with:
* remove_action( 'woocommerce_before_checkout_form', 'woocommerce_checkout_login_form' );
*
* And then we are adding this form into the widget at the
* 'woocommerce_checkout_before_customer_details' hook.
*
* We are doing this in order to match the placement of the Login form to the provided design.
* WC places these forms ABOVE the checkout form section where as we needed to place them inside the
* checkout form section. So we removed the default login form and added our own form.
*
* @since 3.5.0
*/
private function render_woocommerce_checkout_login_form() {
$settings = $this->get_settings_for_display();
$button_classes = [ 'woocommerce-button', 'button', 'woocommerce-form-login__submit', 'e-woocommerce-form-login-submit' ];
if ( $settings['forms_buttons_hover_animation'] ) {
$button_classes[] = 'elementor-animation-' . $settings['forms_buttons_hover_animation'];
}
$this->add_render_attribute(
'button_login', [
'class' => $button_classes,
'name' => 'login',
'type' => 'submit',
]
);
?>
' . esc_html__( 'Click here to login', 'elementor-pro' ) . ''; ?>
print_render_attribute_string( 'button_login' ); ?> value="">
get_settings_for_display();
$button_classes = [ 'woocommerce-button', 'button', 'e-apply-coupon' ];
if ( $settings['forms_buttons_hover_animation'] ) {
$button_classes[] = 'elementor-animation-' . $settings['forms_buttons_hover_animation'];
}
$this->add_render_attribute(
'button_coupon', [
'class' => $button_classes,
'name' => 'apply_coupon',
'type' => 'submit',
]
);
?>
editor->is_edit_mode() );
}
/**
* Should Render Coupon
*
* Decide if the coupon form should be rendered.
* The coupon form should be rendered if:
* 1) The WooCommerce setting is enabled
* 2) And the Coupon Display toggle hasn't been set to 'no'
* 3) AND: a payment is needed, OR the Editor is open
*
* @since 3.5.0
*
* @return boolean
*/
private function should_render_coupon() {
$settings = $this->get_settings_for_display();
$coupon_display_control = true;
if ( '' === $settings['coupon_section_display'] ) {
$coupon_display_control = false;
}
return ( WC()->cart->needs_payment() || Plugin::elementor()->editor->is_edit_mode() ) && wc_coupons_enabled() && $coupon_display_control;
}
/**
* WooCommerce Checkout Before Customer Details
*
* Callback function for the woocommerce_checkout_before_customer_details hook that outputs elements
*
* This eliminates the need for template overrides.
*
* @since 3.5.0
*/
public function woocommerce_checkout_before_customer_details() {
?>
should_render_login() ) {
$this->render_woocommerce_checkout_login_form();
}
}
/**
* Woocommerce Checkout After Customer Details
*
* Output containing elements. Callback function for the woocommerce_checkout_after_customer_details hook.
*
* This eliminates the need for template overrides.
*
* @since 3.5.0
*/
public function woocommerce_checkout_after_customer_details() {
?>
should_render_coupon() ) {
$this->render_woocommerce_checkout_coupon_form();
}
?>
editor->is_edit_mode();
// Simulate a logged out user so that all WooCommerce sections will render in the Editor
if ( $is_editor ) {
$store_current_user = wp_get_current_user()->ID;
wp_set_current_user( 0 );
}
// Add actions & filters before displaying our Widget.
$this->add_render_hooks();
// Display our Widget.
echo do_shortcode( '[woocommerce_checkout]' );
// Remove actions & filters after displaying our Widget.
$this->remove_render_hooks();
// Return to existing logged-in user after widget is rendered.
if ( $is_editor ) {
wp_set_current_user( $store_current_user );
}
}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/base-widget.php 0000644 00000010575 15043204017 0013441 0 ustar 00 $breakpoint_config ) {
$devices_required[ $breakpoint_name ] = [
'required' => false,
];
}
return $devices_required;
}
protected function add_columns_responsive_control() {
$this->add_responsive_control(
'columns',
[
'label' => esc_html__( 'Columns', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'prefix_class' => 'elementor-grid%s-',
'min' => 1,
'max' => 12,
'default' => Products_Renderer::DEFAULT_COLUMNS_AND_ROWS,
'tablet_default' => '3',
'mobile_default' => '2',
'required' => true,
'device_args' => $this->get_devices_default_args(),
'min_affected_device' => [
Controls_Stack::RESPONSIVE_DESKTOP => Controls_Stack::RESPONSIVE_TABLET,
Controls_Stack::RESPONSIVE_TABLET => Controls_Stack::RESPONSIVE_TABLET,
],
]
);
}
/**
* Is WooCommerce Feature Active.
*
* Checks whether a specific WooCommerce feature is active. These checks can sometimes look at multiple WooCommerce
* settings at once so this simplifies and centralizes the checking.
*
* @since 3.5.0
*
* @param string $feature
* @return bool
*/
protected function is_wc_feature_active( $feature ) {
switch ( $feature ) {
case 'checkout_login_reminder':
return 'yes' === get_option( 'woocommerce_enable_checkout_login_reminder' );
case 'shipping':
if ( class_exists( 'WC_Shipping_Zones' ) ) {
$all_zones = \WC_Shipping_Zones::get_zones();
if ( count( $all_zones ) > 0 ) {
return true;
}
}
break;
case 'coupons':
return function_exists( 'wc_coupons_enabled' ) && wc_coupons_enabled();
case 'signup_and_login_from_checkout':
return 'yes' === get_option( 'woocommerce_enable_signup_and_login_from_checkout' );
case 'ship_to_billing_address_only':
return wc_ship_to_billing_address_only();
}
return false;
}
/**
* Get Custom Border Type Options
*
* Return a set of border options to be used in different WooCommerce widgets.
*
* This will be used in cases where the Group Border Control could not be used.
*
* @since 3.5.0
*
* @return array
*/
public static function get_custom_border_type_options() {
return [
'none' => esc_html__( 'None', 'elementor-pro' ),
'solid' => esc_html__( 'Solid', 'elementor-pro' ),
'double' => esc_html__( 'Double', 'elementor-pro' ),
'dotted' => esc_html__( 'Dotted', 'elementor-pro' ),
'dashed' => esc_html__( 'Dashed', 'elementor-pro' ),
'groove' => esc_html__( 'Groove', 'elementor-pro' ),
];
}
/**
* Init Gettext Modifications
*
* Should be overridden by a method in the Widget class.
*
* @since 3.5.0
*/
protected function init_gettext_modifications() {
$this->gettext_modifications = [];
}
/**
* Filter Gettext.
*
* Filter runs when text is output to the page using the translation functions (`_e()`, `__()`, etc.)
* used to apply text changes from the widget settings.
*
* This allows us to make text changes without having to ovveride WooCommerce templates, which would
* lead to dev tax to keep all the templates up to date with each future WC release.
*
* @since 3.5.0
*
* @param string $translation
* @param string $text
* @param string $domain
* @return string
*/
public function filter_gettext( $translation, $text, $domain ) {
if ( 'woocommerce' !== $domain && 'elementor-pro' !== $domain ) {
return $translation;
}
if ( ! isset( $this->gettext_modifications ) ) {
$this->init_gettext_modifications();
}
return array_key_exists( $text, $this->gettext_modifications ) ? $this->gettext_modifications[ $text ] : $translation;
}
}
woocommerce/widgets/purchase-summary.php 0000644 00000121626 15043204017 0014553 0 ustar 00 start_controls_section(
'confirmation_message',
[
'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ),
]
);
$this->add_control(
'confirmation_message_active',
[
'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'default' => 'yes',
'selectors' => [
'{{WRAPPER}}' => '--confirmation-message-display: block;',
],
]
);
$this->add_control(
'confirmation_message_text',
[
'label' => esc_html__( 'Message', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Thank You. Your order has been received.', 'elementor-pro' ),
'label_block' => true,
'condition' => [
'confirmation_message_active!' => '',
],
]
);
$this->add_responsive_control(
'confirmation_message_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'condition' => [
'confirmation_message_active!' => '',
],
'selectors' => [
'{{WRAPPER}}' => '--confirmation-message-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'payment_details',
[
'label' => esc_html__( 'Payment Details', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_number',
[
'label' => esc_html__( 'Number', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Order Number:', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_date',
[
'label' => esc_html__( 'Date:', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Order Date:', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_email',
[
'label' => esc_html__( 'Email', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Order Email:', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_total',
[
'label' => esc_html__( 'Total', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Order Total:', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_payment',
[
'label' => esc_html__( 'Payment', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Payment Method:', 'elementor-pro' ),
]
);
$this->end_controls_section();
$this->start_controls_section(
'bank_details',
[
'label' => esc_html__( 'Bank Details', 'elementor-pro' ),
]
);
$this->add_control(
'bank_details_text',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Our Bank Details', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'bank_details_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--bank-details-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'downloads',
[
'label' => esc_html__( 'Downloads', 'elementor-pro' ),
]
);
$this->add_control(
'downloads_text',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Downloads', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'downloads_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--downloads-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'order_summary',
[
'label' => esc_html__( 'Purchase Summary', 'elementor-pro' ),
]
);
$this->add_control(
'order_summary_text',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Order Details', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'order_summary_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--order-summary-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'billing_details',
[
'label' => esc_html__( 'Billing Details', 'elementor-pro' ),
]
);
$this->add_control(
'billing_details_text',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Billing Details', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'billing_details_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--billing-details-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'shipping_details',
[
'label' => esc_html__( 'Shipping Address', 'elementor-pro' ),
]
);
$this->add_control(
'shipping_details_text',
[
'label' => esc_html__( 'Title', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'dynamic' => [
'active' => true,
],
'default' => esc_html__( 'Shipping Details', 'elementor-pro' ),
]
);
$this->add_responsive_control(
'shipping_details_alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'start' => [
'title' => esc_html__( 'Start', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'end' => [
'title' => esc_html__( 'End', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'{{WRAPPER}}' => '--shipping-details-alignment: {{VALUE}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'preview_order',
[
'label' => esc_html__( 'Preview Settings', 'elementor-pro' ),
]
);
$this->add_control(
'preview_order_type',
[
'label' => esc_html__( 'Preview order with', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => 'Latest Order',
'custom-order' => 'Order ID',
],
]
);
$this->add_control(
'preview_order_custom',
[
'label' => esc_html__( 'Order ID', 'elementor-pro' ),
'type' => Controls_Manager::TEXT,
'condition' => [
'preview_order_type' => 'custom-order',
],
'render_type' => 'template',
'description' => esc_html__( 'Note: To find an order ID, go to the WP dashboard: WooCommerce > Orders', 'elementor-pro' ),
]
);
$this->end_controls_section();
$this->start_controls_section(
'sections_tabs_style',
[
'label' => esc_html__( 'Sections', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'sections_background_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-background-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'sections_box_shadow',
'selector' => '{{WRAPPER}} .shop_table, {{WRAPPER}} address',
]
);
$this->add_control(
'sections_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--sections-border-type: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'sections_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .shop_table, {{WRAPPER}} address' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'sections_border_type!' => 'none',
],
]
);
$this->add_control(
'sections_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--sections-border-color: {{VALUE}};',
],
'condition' => [
'sections_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'sections_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--sections-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'sections_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--sections-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'sections_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--sections-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'typography_title',
[
'label' => esc_html__( 'Typography', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'confirmation_message_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Confirmation Message', 'elementor-pro' ),
]
);
$this->add_control(
'confirmation_message_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--confirmation-message-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'confirmation_message_typography',
'selector' => '{{WRAPPER}} .woocommerce-thankyou-order-received',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'confirmation_message_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-thankyou-order-received',
]
);
$this->add_control(
'titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles', 'elementor-pro' ),
]
);
$this->add_control(
'titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--titles-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'titles_typography',
'selector' => '{{WRAPPER}} h2',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'titles_text_shadow',
'selector' => '{{WRAPPER}} h2',
]
);
$this->add_responsive_control(
'titles_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--titles-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'general_text_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'General Text', 'elementor-pro' ),
]
);
$this->add_control(
'general_text_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--general-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'general_text_typography',
'selector' => '{{WRAPPER}} address, {{WRAPPER}} .product-purchase-note, {{WRAPPER}} .woocommerce-thankyou-order-details + p',
]
);
$this->end_controls_section();
$this->start_controls_section(
'payment_details_title',
[
'label' => esc_html__( 'Payment Details', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'payment_details_space_between',
[
'label' => esc_html__( 'Space Between', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 75,
],
],
'selectors' => [
'{{WRAPPER}}' => '--payment-details-space-between: {{SIZE}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'payment_details_titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--payment-details-titles-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_details_titles_typography',
'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li',
'exclude' => [
'text_decoration',
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'payment_details_titles_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li',
]
);
$this->add_responsive_control(
'payment_details_titles_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--payment-details-titles-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'payment_details_items_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Items', 'elementor-pro' ),
]
);
$this->add_control(
'payment_details_items_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--payment-details-items-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'payment_details_items_typography',
'selector' => '{{WRAPPER}} .woocommerce-order-overview.order_details li strong',
'exclude' => [
'text_decoration',
],
]
);
$this->add_control(
'payment_details_dividers_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Dividers', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'payment_details_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--payment-details-border-type: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'payment_details_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--payment-details-border-width: {{SIZE}}{{UNIT}};',
],
'condition' => [
'payment_details_border_type!' => 'none',
],
]
);
$this->add_control(
'payment_details_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--payment-details-border-color: {{VALUE}};',
],
'condition' => [
'payment_details_border_type!' => 'none',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'bank_details_title',
[
'label' => esc_html__( 'Bank Details', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'bank_details_space_between',
[
'label' => esc_html__( 'Space Between', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 75,
],
],
'selectors' => [
'{{WRAPPER}}' => '--bank-details-space-between: {{SIZE}}{{UNIT}};',
],
'separator' => 'after',
]
);
$this->add_control(
'bank_details_account_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Account Title', 'elementor-pro' ),
]
);
$this->add_control(
'account_title_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--account-title-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'account_title_typography',
'selector' => '{{WRAPPER}} .wc-bacs-bank-details-account-name',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'account_title_text_shadow',
'selector' => '{{WRAPPER}} .wc-bacs-bank-details-account-name',
]
);
$this->add_responsive_control(
'account_title_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--account-title-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'bank_details_titles_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles', 'elementor-pro' ),
]
);
$this->add_control(
'bank_details_titles_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--bank-details-titles-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'bank_details_titles_typography',
'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li',
'exclude' => [
'text_decoration',
],
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'bank_details_titles_text_shadow',
'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li',
]
);
$this->add_responsive_control(
'bank_details_titles_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--bank-details-titles-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'bank_details_items_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Items', 'elementor-pro' ),
]
);
$this->add_control(
'bank_details_items_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--bank-details-items-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'bank_details_items_typography',
'selector' => '{{WRAPPER}} .woocommerce-bacs-bank-details .wc-bacs-bank-details li strong',
'exclude' => [
'text_decoration',
],
]
);
$this->add_control(
'bank_details_dividers_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Dividers', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'bank_details_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--bank-details-border-type: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'bank_details_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--bank-details-border-width: {{SIZE}}{{UNIT}};',
],
'condition' => [
'bank_details_border_type!' => 'none',
],
]
);
$this->add_control(
'bank_details_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--bank-details-border-color: {{VALUE}};',
],
'condition' => [
'bank_details_border_type!' => 'none',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'order_details_title',
[
'label' => esc_html__( 'Order Details', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_responsive_control(
'order_details_rows_gap',
[
'label' => esc_html__( 'Rows Gap', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 60,
],
],
'selectors' => [
'{{WRAPPER}}' => '--order-details-rows-gap: {{SIZE}}{{UNIT}};',
],
]
);
$this->add_control(
'order_details_titles_totals',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Titles & Totals', 'elementor-pro' ),
]
);
$this->add_control(
'order_details_titles_totals_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-details-titles-totals-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_details_titles_totals_typography',
'selector' => '{{WRAPPER}} .shop_table thead tr th, {{WRAPPER}} .shop_table tfoot th, {{WRAPPER}} .shop_table tfoot tr td, {{WRAPPER}} .shop_table tfoot tr td span, {{WRAPPER}} .woocommerce-table--order-downloads tr td:before',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'order_details_titles_totals_text_shadow',
'selector' => '{{WRAPPER}} .shop_table thead tr th, {{WRAPPER}} .shop_table tfoot th, {{WRAPPER}} .shop_table tfoot tr td, {{WRAPPER}} .shop_table tfoot tr td span, {{WRAPPER}} .woocommerce-table--order-downloads tr td:before',
]
);
$this->add_control(
'order_details_items_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Items', 'elementor-pro' ),
]
);
$this->add_control(
'order_details_items_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-details-items-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_details_items_typography',
'selector' => '{{WRAPPER}} .product-quantity, {{WRAPPER}} .woocommerce-table--order-details td a, {{WRAPPER}} td.product-total, {{WRAPPER}} td.download-product, {{WRAPPER}} td.download-remaining, {{WRAPPER}} td.download-expires, {{WRAPPER}} td.download-file',
]
);
$this->add_control(
'order_details_variations_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Variations', 'elementor-pro' ),
]
);
$this->add_control(
'order_details_variations_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-details-variations-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_details_variations_typography',
'selector' => '{{WRAPPER}} .product-name .wc-item-meta .wc-item-meta-label, {{WRAPPER}} .wc-item-meta li p',
]
);
$this->add_control(
'order_details_product_links_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Product Link', 'elementor-pro' ),
]
);
$this->start_controls_tabs( 'order_details_product_links_colors' );
$this->start_controls_tab( 'order_details_product_links_normal_colors', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] );
$this->add_control(
'order_details_product_links_normal_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-details-product-links-normal-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'order_details_product_links_hover_colors', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] );
$this->add_control(
'order_details_product_links_hover_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--order-details-product-links-hover-color: {{VALUE}};',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_control(
'order_details_dividers_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Dividers', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_control(
'order_details_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--tables-divider-border-type: {{VALUE}};',
],
]
);
$this->add_responsive_control(
'order_details_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 100,
],
],
'selectors' => [
'{{WRAPPER}}' => '--tables-divider-border-width: {{SIZE}}{{UNIT}};',
],
'condition' => [
'order_details_border_type!' => 'none',
],
]
);
$this->add_control(
'order_details_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--tables-divider-border-color: {{VALUE}};',
],
'condition' => [
'order_details_border_type!' => 'none',
],
]
);
$this->add_control(
'order_details_button_title',
[
'type' => Controls_Manager::HEADING,
'label' => esc_html__( 'Buttons', 'elementor-pro' ),
'separator' => 'before',
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'order_details_button_typography',
'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button',
]
);
$this->add_group_control(
Group_Control_Text_Shadow::get_type(),
[
'name' => 'order_details_button_text_shadow',
'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button',
]
);
$this->start_controls_tabs( 'order_details_button_styles' );
$this->start_controls_tab( 'order_details_button_styles_normal', [ 'label' => esc_html__( 'Normal', 'elementor-pro' ) ] );
$this->add_control(
'order_details_button_normal_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--button-normal-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'order_details_button_normal_background',
'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'order_details_button_normal_box_shadow',
'selector' => '{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button',
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'order_details_button_styles_hover', [ 'label' => esc_html__( 'Hover', 'elementor-pro' ) ] );
$this->add_control(
'order_details_button_hover_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}}' => '--button-hover-text-color: {{VALUE}};',
],
]
);
$this->add_group_control(
Group_Control_Background::get_type(),
[
'name' => 'order_details_button_hover_background',
'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover',
]
);
$this->add_group_control(
Group_Control_Box_Shadow::get_type(),
[
'name' => 'order_details_button_hover_box_shadow',
'selector' => '{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover',
]
);
$this->add_control(
'order_details_button_hover_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .shop_table .button:hover, {{WRAPPER}} .order-again .button:hover' => 'border-color: {{VALUE}}',
],
'condition' => [
'order_details_button_border_type!' => 'none',
],
]
);
$this->add_control(
'order_details_button_hover_transition_duration',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ) . ' (ms)',
'type' => Controls_Manager::SLIDER,
'selectors' => [
'{{WRAPPER}}' => '--button-hover-transition-duration: {{SIZE}}ms',
],
'range' => [
'px' => [
'min' => 0,
'max' => 3000,
],
],
]
);
$this->add_control(
'order_details_button_hover_animation',
[
'label' => esc_html__( 'Hover Animation', 'elementor-pro' ),
'type' => Controls_Manager::HOVER_ANIMATION,
'frontend_available' => true,
'render_type' => 'template',
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_control(
'order_details_button_border_type',
[
'label' => esc_html__( 'Border Type', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => $this->get_custom_border_type_options(),
'selectors' => [
'{{WRAPPER}}' => '--buttons-border-type: {{VALUE}};',
],
'separator' => 'before',
]
);
$this->add_responsive_control(
'order_details_button_border_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .shop_table .button, {{WRAPPER}} .order-again .button, {{WRAPPER}} .woocommerce-pagination .button' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'order_details_button_border_type!' => 'none',
],
]
);
$this->add_control(
'order_details_button_border_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} ' => '--buttons-border-color: {{VALUE}};',
],
'condition' => [
'order_details_button_border_type!' => 'none',
],
]
);
$this->add_responsive_control(
'order_details_button_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--button-border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_responsive_control(
'order_details_button_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--button-padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->end_controls_section();
}
/**
* Init Gettext Modifications
*
* Sets the `$gettext_modifications` property used with the `filter_gettext()` in the extended Base_Widget.
*
* @since 3.5.0
*/
protected function init_gettext_modifications() {
$instance = $this->get_settings_for_display();
$this->gettext_modifications = [
'Order number:' => isset( $instance['payment_details_number'] ) ? $instance['payment_details_number'] : '',
'Date:' => isset( $instance['payment_details_date'] ) ? $instance['payment_details_date'] : '',
'Email:' => isset( $instance['payment_details_email'] ) ? $instance['payment_details_email'] : '',
'Total:' => isset( $instance['payment_details_total'] ) ? $instance['payment_details_total'] : '',
'Payment method:' => isset( $instance['payment_details_payment'] ) ? $instance['payment_details_payment'] : '',
'Our bank details' => isset( $instance['bank_details_text'] ) ? $instance['bank_details_text'] : '',
'Order details' => isset( $instance['order_summary_text'] ) ? $instance['order_summary_text'] : '',
'Billing address' => isset( $instance['billing_details_text'] ) ? $instance['billing_details_text'] : '',
'Shipping address' => isset( $instance['shipping_details_text'] ) ? $instance['shipping_details_text'] : '',
'Downloads' => isset( $instance['downloads_text'] ) ? $instance['downloads_text'] : '',
];
}
/**
* Modify Order Received Text.
*
* @since 3.5.0
*
* @param $text
* @return string
*/
public function modify_order_received_text( $text ) {
$instance = $this->get_settings_for_display();
if ( isset( $instance['confirmation_message_text'] ) ) {
$text = $instance['confirmation_message_text'];
}
return $text;
}
public function get_modified_order_id() {
return $this->order_id;
}
public function get_modified_order_key() {
return $this->order_key;
}
protected function render() {
$is_editor = Plugin::elementor()->editor->is_edit_mode();
$is_preview = Module::is_preview();
if ( $is_editor || $is_preview ) {
$this->set_preview_order();
add_filter( 'woocommerce_thankyou_order_id', [ $this, 'get_modified_order_id' ] );
add_filter( 'woocommerce_thankyou_order_key', [ $this, 'get_modified_order_key' ] );
/**
* The action `template_redirect` is not run during the re-loading of the Widget and as a result the
* `wc_template_redirect` function is not run which is responsible for loading the following, so we
* must load them ourselves.
*/
WC()->payment_gateways();
WC()->shipping();
}
/*
* Add actions & filters before displaying our Widget.
*/
add_filter( 'gettext', [ $this, 'filter_gettext' ], 20, 3 );
add_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'modify_order_received_text' ] );
/**
* Display our Widget.
*/
global $wp;
if ( isset( $wp->query_vars['order-received'] ) && wc_get_order( intval( $wp->query_vars['order-received'] ) ) ) {
echo do_shortcode( '[woocommerce_checkout]' );
} elseif ( $is_editor || $is_preview ) {
$this->no_order_notice();
}
/*
* Remove actions & filters after displaying our Widget.
*/
remove_filter( 'gettext', [ $this, 'filter_gettext' ], 20 );
remove_filter( 'woocommerce_thankyou_order_received_text', [ $this, 'modify_order_received_text' ] );
if ( $is_editor || $is_preview ) {
remove_filter( 'woocommerce_thankyou_order_id', [ $this, 'get_modified_order_id' ] );
remove_filter( 'woocommerce_thankyou_order_key', [ $this, 'get_modified_order_key' ] );
}
}
public function no_order_notice() {
?>
get_settings_for_display();
$order = false;
if ( 'custom-order' === $instance['preview_order_type'] ) {
$order = wc_get_order( $instance['preview_order_custom'] );
}
if ( ! $order ) {
$latest_order = wc_get_orders( [
'limit' => 1,
'orderby' => 'date',
'order' => 'DESC',
'return' => 'ids',
] );
if ( isset( $latest_order[0] ) ) {
$order = wc_get_order( $latest_order[0] );
}
}
if ( $order ) {
global $wp;
$wp->set_query_var( 'order-received', $order->get_id() );
$this->order_id = $order->get_id();
$this->order_key = $order->get_order_key();
}
}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-content.php 0000644 00000001173 15043204017 0014370 0 ustar 00 start_controls_section(
'section',
[
'label' => esc_html__( 'WooCommerce Notices', 'elementor-pro' ),
]
);
$this->add_control(
'where_to_appear_notice',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'Drop this widget anywhere on the page or template where you want notices to appear.', 'elementor-pro' ),
'content_classes' => 'elementor-descriptor',
]
);
$this->add_control(
'site_settings_notice',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf(
/* translators: 1: Link opening tag, 2: Link closing tag. */
esc_html__( 'To change the design of your notices, go to your %1$sWooCommerce Settings%2$s', 'elementor-pro' ),
'',
' '
),
'content_classes' => 'elementor-descriptor elementor-descriptor-subtle',
]
);
$this->add_control(
'one_per_page_notice',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => sprintf(
/* translators: 1: Bold text opening tag, 2: Bold text closing tag. */
esc_html__( '%1$sNote:%2$s You can only add the Notices widget once per page.', 'elementor-pro' ),
'',
' '
),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->end_controls_section();
}
private function hide_woocommerce_notices() {
?>
editor->is_edit_mode() || Plugin::elementor()->preview->is_preview_mode() ) {
?>
hide_woocommerce_notices();
?>
get_product();
if ( ! $product ) {
return;
}
add_action( 'woocommerce_before_add_to_cart_quantity', [ $this, 'before_add_to_cart_quantity' ], 95 );
add_action( 'woocommerce_before_add_to_cart_button', [ $this, 'before_add_to_cart_quantity' ], 5 );
add_action( 'woocommerce_after_add_to_cart_button', [ $this, 'after_add_to_cart_button' ], 5 );
?>
is_loop_item() ) {
$this->render_loop_add_to_cart();
} else {
woocommerce_template_single_add_to_cart();
} ?>
get_loop_quantity_args();
$button_args = [ 'quantity' => $quantity_args['min_value'] ];
?>
get_type()
&& 'yes' === $this->get_settings_for_display( 'show_quantity' )
) {
woocommerce_quantity_input( $quantity_args );
}
}
private function get_loop_quantity_args() {
global $product;
$quantity_args = [
'min_value' => apply_filters( 'woocommerce_quantity_input_min', $product->get_min_purchase_quantity(), $product ),
'max_value' => apply_filters( 'woocommerce_quantity_input_max', $product->get_max_purchase_quantity(), $product ),
'input_value' => $product->get_min_purchase_quantity(),
'classes' => [ 'input-text', 'qty', 'text' ],
];
if ( 'no' === get_option( 'woocommerce_enable_ajax_add_to_cart' ) ) {
$quantity_args['min_value'] = $product->get_min_purchase_quantity();
$quantity_args['input_value'] = $product->get_min_purchase_quantity();
$quantity_args['classes'][] = 'disabled';
}
return $quantity_args;
}
private function is_loop_item() {
return 'loop-item' === Plugin::elementor()->documents->get_current()->get_type();
}
private function is_loop_item_template_edit() {
return ( Plugin::elementor()->editor->is_edit_mode() && $this->is_loop_item() );
}
public function should_add_container() {
global $product;
if ( ! in_array( $this->get_settings_for_display( 'layout' ), [ 'auto', 'stacked' ], true ) ) {
return false;
}
switch ( current_action() ) {
case 'woocommerce_before_add_to_cart_quantity':
return in_array( $product->get_type(), [ 'simple', 'variable' ], true );
case 'woocommerce_before_add_to_cart_button':
return in_array( $product->get_type(), [ 'grouped', 'external' ], true );
case 'woocommerce_after_add_to_cart_button':
default:
return true;
}
}
/**
* Before Add to Cart Quantity
*
* Added wrapper tag around the quantity input and "Add to Cart" button
* used to more solidly accommodate the layout when additional elements
* are added by 3rd party plugins.
*
* @since 3.6.0
*/
public function before_add_to_cart_quantity() {
if ( ! $this->should_add_container() ) {
return;
}
?>
should_add_container() ) {
return;
}
?>
start_controls_section(
'section_layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'layout',
[
'label' => esc_html__( 'Layout', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'options' => [
'' => esc_html__( 'Inline', 'elementor-pro' ),
'stacked' => esc_html__( 'Stacked', 'elementor-pro' ),
'auto' => esc_html__( 'Auto', 'elementor-pro' ),
],
'prefix_class' => 'elementor-add-to-cart--layout-',
'render_type' => 'template',
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_atc_button_style',
[
'label' => esc_html__( 'Button', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'wc_style_warning',
[
'type' => Controls_Manager::RAW_HTML,
'raw' => esc_html__( 'The style of this widget is often affected by your theme and plugins. If you experience any such issue, try to switch to a basic theme and deactivate related plugins.', 'elementor-pro' ),
'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
]
);
$this->add_responsive_control(
'alignment',
[
'label' => esc_html__( 'Alignment', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
'justify' => [
'title' => esc_html__( 'Justified', 'elementor-pro' ),
'icon' => 'eicon-text-align-justify',
],
],
'prefix_class' => 'elementor-add-to-cart%s--align-',
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'button_typography',
'selector' => '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button',
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'button_border',
'selector' => '{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button',
'exclude' => [ 'color' ],
]
);
$this->add_control(
'button_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->add_control(
'button_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
]
);
$this->start_controls_tabs( 'button_style_tabs' );
$this->start_controls_tab( 'button_style_normal',
[
'label' => esc_html__( 'Normal', 'elementor-pro' ),
]
);
$this->add_control(
'button_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'button_bg_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'button_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'border-color: {{VALUE}}',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'button_style_hover',
[
'label' => esc_html__( 'Hover', 'elementor-pro' ),
]
);
$this->add_control(
'button_text_color_hover',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'button_bg_color_hover',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'button_border_color_hover',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .cart button:hover, {{WRAPPER}} .cart .button:hover' => 'border-color: {{VALUE}}',
],
]
);
$this->add_control(
'button_transition',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 0.2,
],
'range' => [
'px' => [
'max' => 2,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} .cart button, {{WRAPPER}} .cart .button' => 'transition: all {{SIZE}}s',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->add_control(
'heading_view_cart_style',
[
'label' => esc_html__( 'View Cart', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'view_cart_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .added_to_cart' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'view_cart_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_ACCENT,
],
'selector' => '{{WRAPPER}} .added_to_cart',
]
);
$this->add_responsive_control(
'view_cart_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'range' => [
'px' => [
'min' => 0,
'max' => 50,
'step' => 1,
],
'em' => [
'min' => 0,
'max' => 3.5,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}}' => '--view-cart-spacing: {{SIZE}}{{UNIT}};',
],
]
);
$this->end_controls_section();
$this->start_controls_section(
'section_atc_quantity_style',
[
'label' => esc_html__( 'Quantity', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'show_quantity',
[
'label' => esc_html__( 'Quantity', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'return_value' => 'yes',
'default' => 'yes',
'prefix_class' => 'e-add-to-cart--show-quantity-',
'render_type' => 'template',
]
);
$this->add_responsive_control(
'spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}}' => '--button-spacing: {{SIZE}}{{UNIT}};',
],
'condition' => [
'show_quantity!' => '',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'quantity_typography',
'selector' => '{{WRAPPER}} .quantity .qty',
'condition' => [
'show_quantity!' => '',
],
]
);
$this->add_group_control(
Group_Control_Border::get_type(),
[
'name' => 'quantity_border',
'selector' => '{{WRAPPER}} .quantity .qty',
'exclude' => [ 'color' ],
'condition' => [
'show_quantity!' => '',
],
]
);
$this->add_control(
'quantity_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'show_quantity!' => '',
],
]
);
$this->add_control(
'quantity_padding',
[
'label' => esc_html__( 'Padding', 'elementor-pro' ),
'type' => Controls_Manager::DIMENSIONS,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
],
'condition' => [
'show_quantity!' => '',
],
]
);
$this->start_controls_tabs( 'quantity_style_tabs',
[
'condition' => [
'show_quantity!' => '',
],
]
);
$this->start_controls_tab( 'quantity_style_normal',
[
'label' => esc_html__( 'Normal', 'elementor-pro' ),
]
);
$this->add_control(
'quantity_text_color',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'quantity_bg_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'quantity_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'border-color: {{VALUE}}',
],
]
);
$this->end_controls_tab();
$this->start_controls_tab( 'quantity_style_focus',
[
'label' => esc_html__( 'Focus', 'elementor-pro' ),
]
);
$this->add_control(
'quantity_text_color_focus',
[
'label' => esc_html__( 'Text Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty:focus' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'quantity_bg_color_focus',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty:focus' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'quantity_border_color_focus',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'{{WRAPPER}} .quantity .qty:focus' => 'border-color: {{VALUE}}',
],
]
);
$this->add_control(
'quantity_transition',
[
'label' => esc_html__( 'Transition Duration', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'default' => [
'size' => 0.2,
],
'range' => [
'px' => [
'max' => 2,
'step' => 0.1,
],
],
'selectors' => [
'{{WRAPPER}} .quantity .qty' => 'transition: all {{SIZE}}s',
],
]
);
$this->end_controls_tab();
$this->end_controls_tabs();
$this->end_controls_section();
$this->start_controls_section(
'section_atc_variations_style',
[
'label' => esc_html__( 'Variations', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'variations_width',
[
'label' => esc_html__( 'Width', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'vw', 'custom' ],
'default' => [
'unit' => '%',
],
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart .variations' => 'width: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'variations_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart .variations' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
]
);
$this->add_control(
'variations_space_between',
[
'label' => esc_html__( 'Space Between', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations tr th, .woocommerce {{WRAPPER}} form.cart table.variations tr td' => 'padding-top: calc( {{SIZE}}{{UNIT}}/2 ); padding-bottom: calc( {{SIZE}}{{UNIT}}/2 );',
],
]
);
$this->add_control(
'heading_variations_label_style',
[
'label' => esc_html__( 'Label', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'variations_label_color_focus',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations label' => 'color: {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'variations_label_typography',
'selector' => '.woocommerce {{WRAPPER}} form.cart table.variations label',
]
);
$this->add_control(
'heading_variations_select_style',
[
'label' => esc_html__( 'Select field', 'elementor-pro' ),
'type' => Controls_Manager::HEADING,
'separator' => 'before',
]
);
$this->add_control(
'variations_select_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations td.value select' => 'color: {{VALUE}}',
],
]
);
$this->add_control(
'variations_select_bg_color',
[
'label' => esc_html__( 'Background Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'background-color: {{VALUE}}',
],
]
);
$this->add_control(
'variations_select_border_color',
[
'label' => esc_html__( 'Border Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'border: 1px solid {{VALUE}}',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'variations_select_typography',
'selector' => '.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce div.product.elementor{{WRAPPER}} form.cart table.variations td.value:before',
]
);
$this->add_control(
'variations_select_border_radius',
[
'label' => esc_html__( 'Border Radius', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}} form.cart table.variations td.value select, .woocommerce {{WRAPPER}} form.cart table.variations td.value:before' => 'border-radius: {{SIZE}}{{UNIT}}',
],
]
);
$this->end_controls_section();
}
public function render_plain_content() {}
public function get_group_name() {
return 'woocommerce';
}
}
woocommerce/widgets/product-related.php 0000644 00000015262 15043204017 0014342 0 ustar 00 start_controls_section(
'section_related_products_content',
[
'label' => esc_html__( 'Related Products', 'elementor-pro' ),
]
);
$this->add_control(
'posts_per_page',
[
'label' => esc_html__( 'Products Per Page', 'elementor-pro' ),
'type' => Controls_Manager::NUMBER,
'default' => 4,
'range' => [
'px' => [
'max' => 20,
],
],
]
);
$this->add_columns_responsive_control();
$this->add_control(
'orderby',
[
'label' => esc_html__( 'Order By', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'date',
'options' => [
'date' => esc_html__( 'Date', 'elementor-pro' ),
'title' => esc_html__( 'Title', 'elementor-pro' ),
'price' => esc_html__( 'Price', 'elementor-pro' ),
'popularity' => esc_html__( 'Popularity', 'elementor-pro' ),
'rating' => esc_html__( 'Rating', 'elementor-pro' ),
'rand' => esc_html__( 'Random', 'elementor-pro' ),
'menu_order' => esc_html__( 'Menu Order', 'elementor-pro' ),
],
]
);
$this->add_control(
'order',
[
'label' => esc_html__( 'Order', 'elementor-pro' ),
'type' => Controls_Manager::SELECT,
'default' => 'desc',
'options' => [
'asc' => esc_html__( 'ASC', 'elementor-pro' ),
'desc' => esc_html__( 'DESC', 'elementor-pro' ),
],
]
);
$this->end_controls_section();
parent::register_controls();
$this->start_injection( [
'at' => 'before',
'of' => 'section_design_box',
] );
$this->start_controls_section(
'section_heading_style',
[
'label' => esc_html__( 'Heading', 'elementor-pro' ),
'tab' => Controls_Manager::TAB_STYLE,
]
);
$this->add_control(
'show_heading',
[
'label' => esc_html__( 'Heading', 'elementor-pro' ),
'type' => Controls_Manager::SWITCHER,
'label_off' => esc_html__( 'Hide', 'elementor-pro' ),
'label_on' => esc_html__( 'Show', 'elementor-pro' ),
'default' => 'yes',
'return_value' => 'yes',
'prefix_class' => 'show-heading-',
]
);
$this->add_control(
'heading_color',
[
'label' => esc_html__( 'Color', 'elementor-pro' ),
'type' => Controls_Manager::COLOR,
'global' => [
'default' => Global_Colors::COLOR_PRIMARY,
],
'selectors' => [
'.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'color: {{VALUE}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_group_control(
Group_Control_Typography::get_type(),
[
'name' => 'heading_typography',
'global' => [
'default' => Global_Typography::TYPOGRAPHY_PRIMARY,
],
'selector' => '.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2',
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_responsive_control(
'heading_text_align',
[
'label' => esc_html__( 'Text Align', 'elementor-pro' ),
'type' => Controls_Manager::CHOOSE,
'options' => [
'left' => [
'title' => esc_html__( 'Left', 'elementor-pro' ),
'icon' => 'eicon-text-align-left',
],
'center' => [
'title' => esc_html__( 'Center', 'elementor-pro' ),
'icon' => 'eicon-text-align-center',
],
'right' => [
'title' => esc_html__( 'Right', 'elementor-pro' ),
'icon' => 'eicon-text-align-right',
],
],
'selectors' => [
'.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'text-align: {{VALUE}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->add_responsive_control(
'heading_spacing',
[
'label' => esc_html__( 'Spacing', 'elementor-pro' ),
'type' => Controls_Manager::SLIDER,
'size_units' => [ 'px', 'em', 'rem', 'custom' ],
'selectors' => [
'.woocommerce {{WRAPPER}}.elementor-wc-products .products > h2' => 'margin-bottom: {{SIZE}}{{UNIT}}',
],
'condition' => [
'show_heading!' => '',
],
]
);
$this->end_controls_section();
$this->end_injection();
}
protected function render() {
global $product;
$product = $this->get_product();
if ( ! $product ) {
return;
}
$settings = $this->get_settings_for_display();
// Add a wrapper class to the Add to Cart & View Items elements if the automically_align_buttons switch has been selected.
if ( 'yes' === $settings['automatically_align_buttons'] ) {
add_filter( 'woocommerce_loop_add_to_cart_link', [ $this, 'add_to_cart_wrapper' ], 10, 1 );
}
$args = [
'posts_per_page' => 4,
'columns' => 4,
'orderby' => $settings['orderby'],
'order' => $settings['order'],
];
if ( ! empty( $settings['posts_per_page'] ) ) {
$args['posts_per_page'] = $settings['posts_per_page'];
}
if ( ! empty( $settings['columns'] ) ) {
$args['columns'] = $settings['columns'];
}
$args = array_map( 'sanitize_text_field', $args );
// Get visible related products then sort them at random.
$args['related_products'] = array_filter( array_map( 'wc_get_product', wc_get_related_products( $product->get_id(), $args['posts_per_page'], $product->get_upsell_ids() ) ), 'wc_products_array_filter_visible' );
// Handle orderby.
$args['related_products'] = wc_products_array_orderby( $args['related_products'], $args['orderby'], $args['order'] );
ob_start();
wc_get_template( 'single-product/related.php', $args );
$related_products_html = ob_get_clean();
if ( $related_products_html ) {
$related_products_html = str_replace( '