version 4.13.0
This commit is contained in:
585
includes/builder/module/woocommerce/AddToCart.php
Normal file
585
includes/builder/module/woocommerce/AddToCart.php
Normal file
@ -0,0 +1,585 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Add_To_Cart class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Add_To_Cart Class is responsible for rendering the
|
||||
* Add To Cart markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Add to cart component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Add_To_Cart extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Add To Cart', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Add To Cart', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_add_to_cart';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
'elements' => et_builder_i18n( 'Elements' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'text' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
),
|
||||
'header' => array(
|
||||
'title' => esc_html__( 'Heading Text', 'et_builder' ),
|
||||
'priority' => 49,
|
||||
'tabbed_subtoggles' => true,
|
||||
'sub_toggles' => array(
|
||||
'h1' => array(
|
||||
'name' => 'H1',
|
||||
'icon' => 'text-h1',
|
||||
),
|
||||
'h2' => array(
|
||||
'name' => 'H2',
|
||||
'icon' => 'text-h2',
|
||||
),
|
||||
'h3' => array(
|
||||
'name' => 'H3',
|
||||
'icon' => 'text-h3',
|
||||
),
|
||||
'h4' => array(
|
||||
'name' => 'H4',
|
||||
'icon' => 'text-h4',
|
||||
),
|
||||
'h5' => array(
|
||||
'name' => 'H5',
|
||||
'icon' => 'text-h5',
|
||||
),
|
||||
'h6' => array(
|
||||
'name' => 'H6',
|
||||
'icon' => 'text-h6',
|
||||
),
|
||||
),
|
||||
),
|
||||
'width' => array(
|
||||
'title' => et_builder_i18n( 'Sizing' ),
|
||||
'priority' => 80,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%, %%order_class%% a, %%order_class%% label, %%order_class%%.et_pb_module .et_pb_module_inner .stock',
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.3em',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'toggle_slug' => 'text',
|
||||
'font' => array(
|
||||
'default' => '|700|||||||',
|
||||
),
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_background_layout' => true,
|
||||
'options' => array(
|
||||
'text_orientation' => array(
|
||||
'default' => 'left',
|
||||
),
|
||||
'background_layout' => array(
|
||||
'default' => 'light',
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => array(
|
||||
'button' => array(
|
||||
'label' => et_builder_i18n( 'Button' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .button',
|
||||
'limited_main' => '%%order_class%% .button',
|
||||
'alignment' => '%%order_class%% .et_pb_module_inner > form',
|
||||
// Setting to TRUE since it only checks for the value's existence.
|
||||
'important' => 'all',
|
||||
),
|
||||
|
||||
/*
|
||||
* Button inside add to cart module is rendered from WooCommerce's default
|
||||
* template which makes its positioning isn't flexible. Thus button alignment
|
||||
* is removed.
|
||||
*/
|
||||
'use_alignment' => false,
|
||||
'box_shadow' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .button',
|
||||
'important' => true,
|
||||
),
|
||||
),
|
||||
'use_icon' => false,
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'form_field' => array(
|
||||
'fields' => array(
|
||||
'label' => esc_html__( 'Fields', 'et_builder' ),
|
||||
'toggle_priority' => 67,
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% input, %%order_class%% .quantity input.qty',
|
||||
'background_color' => '%%order_class%% input, %%order_class%% .quantity input.qty',
|
||||
'background_color_hover' => '%%order_class%% input:hover, %%order_class%% .quantity input.qty:hover',
|
||||
'focus_background_color' => '%%order_class%% input:focus, %%order_class%% select:focus, %%order_class%% .quantity input.qty:focus',
|
||||
'form_text_color' => '%%order_class%% input, %%order_class%% select, %%order_class%% .quantity input.qty',
|
||||
'form_text_color_hover' => '%%order_class%% input[type="text"]:hover, %%order_class%% select:hover, %%order_class%% .quantity input.qty:hover',
|
||||
'focus_text_color' => '%%order_class%% input:focus, %%order_class%% .quantity input.qty:focus',
|
||||
'placeholder_focus' => '%%order_class%% input:focus::-webkit-input-placeholder, %%order_class%% input:focus::-moz-placeholder, %%order_class%% input:focus:-ms-input-placeholder, %%order_class%% textarea:focus::-webkit-input-placeholder, %%order_class%% textarea:focus::-moz-placeholder, %%order_class%% textarea:focus:-ms-input-placeholder',
|
||||
'padding' => '%%order_class%% input',
|
||||
'margin' => '%%order_class%%',
|
||||
'important' => array(
|
||||
'background_color',
|
||||
'background_color_hover',
|
||||
'focus_background_color',
|
||||
'form_text_color',
|
||||
'form_text_color_hover',
|
||||
'text_color',
|
||||
'focus_text_color',
|
||||
'padding',
|
||||
'margin',
|
||||
),
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'name' => 'fields',
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% input',
|
||||
),
|
||||
'default_on_fronts' => array(
|
||||
'color' => '',
|
||||
'position' => '',
|
||||
),
|
||||
),
|
||||
'border_styles' => array(
|
||||
'fields' => array(
|
||||
'name' => 'fields',
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%% input, %%order_class%% .quantity input.qty',
|
||||
'border_styles' => '%%order_class%% input, %%order_class%% .quantity input.qty',
|
||||
'defaults' => array(
|
||||
'border_radii' => 'on|3px|3px|3px|3px',
|
||||
'border_styles' => array(
|
||||
'width' => '0px',
|
||||
'style' => 'none',
|
||||
),
|
||||
),
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'label_prefix' => esc_html__( 'Fields', 'et_builder' ),
|
||||
),
|
||||
'fields_focus' => array(
|
||||
'name' => 'fields_focus',
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%% input:focus, %%order_class%% .quantity input.qty:focus',
|
||||
'border_styles' => '%%order_class%% input:focus, %%order_class%% .quantity input.qty:focus',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'label_prefix' => esc_html__( 'Fields Focus', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
'font_field' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'%%order_class%% input, %%order_class%% .quantity input.qty',
|
||||
),
|
||||
'hover' => array(
|
||||
'%%order_class%% input:hover',
|
||||
'%%order_class%% input:hover::-webkit-input-placeholder',
|
||||
'%%order_class%% input:hover::-moz-placeholder',
|
||||
'%%order_class%% input:hover:-ms-input-placeholder',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '20px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations tr',
|
||||
'important' => array( 'custom_padding' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'dropdown_menus' => array(
|
||||
'label' => esc_html__( 'Dropdown Menus', 'et_builder' ),
|
||||
'toggle_priority' => 67,
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
'background_color' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
'background_color_hover' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select:hover',
|
||||
'focus_background_color' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select:focus',
|
||||
'form_text_color' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
'form_text_color_hover' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select + label:hover, %%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select:hover',
|
||||
'focus_text_color' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select option:focus, %%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select + label',
|
||||
'placeholder_focus' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select:focus, %%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select + label:focus',
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% select',
|
||||
'important' => array( 'all' ),
|
||||
),
|
||||
),
|
||||
'important' => array(
|
||||
'text_color',
|
||||
'form_text_color',
|
||||
'margin_padding',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'use_padding' => false,
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'name' => 'dropdown_menus',
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
),
|
||||
),
|
||||
'border_styles' => array(
|
||||
'dropdown_menus' => array(
|
||||
'name' => 'dropdown_menus',
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_styles' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
'border_radii' => '%%order_class%%.et_pb_module .et_pb_module_inner form.cart .variations td select',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'label_prefix' => esc_html__( 'Dropdown Menus', 'et_builder' ),
|
||||
'use_radius' => false,
|
||||
),
|
||||
),
|
||||
'font_field' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'%%order_class%% select',
|
||||
),
|
||||
'hover' => array(
|
||||
'%%order_class%% select:hover',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '12px',
|
||||
),
|
||||
'hide_line_height' => true,
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'fields' => array(
|
||||
'label' => esc_html__( 'Fields', 'et_builder' ),
|
||||
'selector' => 'input',
|
||||
),
|
||||
'dropdown_menus' => array(
|
||||
'label' => esc_html__( 'Dropdown Menus', 'et_builder' ),
|
||||
'selector' => 'select',
|
||||
),
|
||||
'buttons' => array(
|
||||
'label' => esc_html__( 'Buttons', 'et_builder' ),
|
||||
'selector' => '.button',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__add_to_cart',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__add_to_cart',
|
||||
),
|
||||
)
|
||||
),
|
||||
'show_quantity' => array(
|
||||
'label' => esc_html__( 'Show Quantity Field', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the quantity field should be added before the Add to Cart button.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'show_stock' => array(
|
||||
'label' => esc_html__( 'Show Stock', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the stock (displayed when product inventory is managed) should be visible or not', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'__add_to_cart' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Add_To_Cart',
|
||||
'get_add_to_cart',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get add to cart markup as string
|
||||
*
|
||||
* @since 4.4.0 Fixed compatibility w/ WooCommerce Product Add-ons
|
||||
* @see https://github.com/elegantthemes/Divi/issues/19116
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_add_to_cart( $args = array() ) {
|
||||
return et_builder_wc_render_module_template(
|
||||
'woocommerce_template_single_add_to_cart',
|
||||
$args,
|
||||
array( 'product', 'post' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Button classname.
|
||||
*
|
||||
* @used-by ET_Builder_Module_Helper_Woocommerce_Modules::add_custom_button_icons()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_button_classname() {
|
||||
return 'single_add_to_cart_button';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Breadcrumb markup, we inject Multi view
|
||||
* attributes on to the Outer wrapper.
|
||||
*
|
||||
* @param array $outer_wrapper_attrs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $outer_wrapper_attrs ) {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'classes' => array(
|
||||
'et_pb_hide_input_quantity' => array(
|
||||
'show_quantity' => 'off',
|
||||
),
|
||||
'et_pb_hide_stock' => array(
|
||||
'show_stock' => 'off',
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$outer_wrapper_attrs = array_merge( $outer_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $outer_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates any required additional CSS.
|
||||
*
|
||||
* Dropdown menu's Bottom & Left margin affects the Dropdown arrow placement.
|
||||
* This is handled using additional CSS.
|
||||
*
|
||||
* @param array $attrs
|
||||
* @param string $render_slug
|
||||
*
|
||||
* @since 4.3.4
|
||||
*/
|
||||
public function add_additional_css( $attrs, $render_slug ) {
|
||||
if ( ! is_array( $attrs ) || empty( $attrs ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$prop = 'dropdown_menus_custom_margin';
|
||||
|
||||
$values = et_pb_responsive_options()->get_property_values( $attrs, $prop );
|
||||
$hover_value = et_pb_hover_options()->get_value( $prop, $attrs, '' );
|
||||
$processed_values = array();
|
||||
|
||||
foreach ( $values as $device => $value ) {
|
||||
if ( empty( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$processed_values[ $device ] = $this->calculate_dropdown_arrow_margin( $value );
|
||||
}
|
||||
|
||||
// Generate style for desktop, tablet, and phone.
|
||||
et_pb_responsive_options()->declare_responsive_css(
|
||||
$processed_values,
|
||||
'%%order_class%% form.cart .variations td.value span:after',
|
||||
$render_slug
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates Dropdown's arrow margin values.
|
||||
*
|
||||
* The Dropdown's arrow margin values depend on the actual
|
||||
* Dropdown margin values.
|
||||
*
|
||||
* @since 4.3.4
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function calculate_dropdown_arrow_margin( $value ) {
|
||||
$dropdown_margin = explode( '|', $value );
|
||||
$dropdown_bottom_margin = empty( $dropdown_margin[2] ) ? '0px' : $dropdown_margin[2];
|
||||
$dropdown_left_margin = empty( $dropdown_margin[3] ) ? '0px' : $dropdown_margin[3];
|
||||
|
||||
$declarations = array(
|
||||
sprintf( 'margin-top: calc( 3px - %s )', $dropdown_bottom_margin ),
|
||||
sprintf( 'right: calc( 10px - %s )', $dropdown_left_margin ),
|
||||
);
|
||||
|
||||
// The last declaration wouldn't have the `;`. So appending manually.
|
||||
return implode( ';', $declarations ) . ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
$use_focus_border_color = $this->props['use_focus_border_color'];
|
||||
|
||||
// Module classnames.
|
||||
if ( 'on' !== $multi_view->get_value( 'show_quantity' ) ) {
|
||||
$this->add_classname( 'et_pb_hide_input_quantity' );
|
||||
}
|
||||
|
||||
if ( 'on' !== $multi_view->get_value( 'show_stock' ) ) {
|
||||
$this->add_classname( 'et_pb_hide_stock' );
|
||||
}
|
||||
|
||||
if ( 'on' === $use_focus_border_color ) {
|
||||
$this->add_classname( 'et_pb_with_focus_border' );
|
||||
}
|
||||
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_custom_button_icons( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$this->add_additional_css( $this->props, $render_slug );
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_outer_wrapper_attrs", array( $this, 'add_multi_view_attrs' ) );
|
||||
|
||||
$output = self::get_add_to_cart( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Add_To_Cart();
|
346
includes/builder/module/woocommerce/AdditionalInfo.php
Normal file
346
includes/builder/module/woocommerce/AdditionalInfo.php
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Additional_Info class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Additional_Info Class is responsible for rendering the
|
||||
* Additional markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Additional Info component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Additional_Info extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @since 4.0.6 Implemented Attribute Row, Title and Body Custom CSS fields.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Additional Info', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Additional Info', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_additional_info';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
'elements' => et_builder_i18n( 'Elements' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'text' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
'tabbed_subtoggles' => true,
|
||||
'bb_icons_support' => true,
|
||||
'sub_toggles' => array(
|
||||
'p' => array(
|
||||
'name' => 'P',
|
||||
'icon' => 'text-left',
|
||||
),
|
||||
'a' => array(
|
||||
'name' => 'A',
|
||||
'icon' => 'text-link',
|
||||
),
|
||||
),
|
||||
),
|
||||
'header' => array(
|
||||
'title' => esc_html__( 'Title Text', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% td',
|
||||
'important' => array( 'line-height' ),
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.5em',
|
||||
),
|
||||
'toggle_slug' => 'text',
|
||||
'sub_toggle' => 'p',
|
||||
'font' => array(
|
||||
'default' => '||on||||||',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'link' => array(
|
||||
'label' => et_builder_i18n( 'Link' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% a',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.5em',
|
||||
),
|
||||
'toggle_slug' => 'text',
|
||||
'sub_toggle' => 'a',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'header' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h2',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
),
|
||||
'attribute' => array(
|
||||
'label' => esc_html__( 'Attribute', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% th',
|
||||
'important' => 'all',
|
||||
'text_align' => '%%order_class%% th, %%order_class%% td',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.5em',
|
||||
),
|
||||
'font' => array(
|
||||
'default' => '|700|||||||',
|
||||
),
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'css' => array(
|
||||
'text_orientation' => '%%order_class%%',
|
||||
),
|
||||
'use_background_layout' => true,
|
||||
'sub_toggle' => 'p',
|
||||
'options' => array(
|
||||
'text_orientation' => array(
|
||||
'default' => 'left',
|
||||
),
|
||||
'background_layout' => array(
|
||||
'default' => 'light',
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'title_text' => array(
|
||||
'label' => esc_html__( 'Title Text', 'et_builder' ),
|
||||
'selector' => 'h2',
|
||||
),
|
||||
'content_area' => array(
|
||||
'label' => esc_html__( 'Content Area', 'et_builder' ),
|
||||
'selector' => '.shop_attributes',
|
||||
),
|
||||
'attribute_row' => array(
|
||||
'label' => esc_html__( 'Attribute Row', 'et_builder' ),
|
||||
'selector' => '.shop_attributes .woocommerce-product-attributes-item',
|
||||
),
|
||||
'attribute_title' => array(
|
||||
'label' => esc_html__( 'Attribute Title', 'et_builder' ),
|
||||
'selector' => '.shop_attributes .woocommerce-product-attributes-item__label',
|
||||
),
|
||||
'attribute_text' => array(
|
||||
'label' => esc_html__( 'Attribute Body', 'et_builder' ),
|
||||
'selector' => '.shop_attributes .woocommerce-product-attributes-item__value',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__additional_info',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__additional_info',
|
||||
),
|
||||
)
|
||||
),
|
||||
'show_title' => array(
|
||||
'label' => esc_html__( 'Show Title', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose to display the title.', 'et_builder' ),
|
||||
'computed_affects' => array(
|
||||
'__additional_info',
|
||||
),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'__additional_info' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Additional_Info',
|
||||
'get_additional_info',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'show_title',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
'show_title',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get additional information
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_additional_info( $args = array() ) {
|
||||
$defaults = array(
|
||||
'show_title' => 'on',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
$display_title = 'on' === $args['show_title'];
|
||||
|
||||
/*
|
||||
* WooCommerce's default additional information template conditionally display heading
|
||||
* markup based on filterable value which can be plugged and unplugged here.
|
||||
*/
|
||||
if ( ! $display_title ) {
|
||||
add_filter( 'woocommerce_product_additional_information_heading', '__return_false' );
|
||||
}
|
||||
|
||||
$additional_info = et_builder_wc_render_module_template(
|
||||
'woocommerce_product_additional_information_tab',
|
||||
$args
|
||||
);
|
||||
|
||||
if ( ! $display_title ) {
|
||||
remove_filter( 'woocommerce_product_additional_information_heading', '__return_false' );
|
||||
}
|
||||
|
||||
return $additional_info;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Additional Info markup, we inject Multi
|
||||
* view attributes on to the Outer wrapper.
|
||||
*
|
||||
* @param array $outer_wrapper_attrs
|
||||
* @param ET_Builder_Module_Woocommerce_Additional_Info $this_class
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $outer_wrapper_attrs, $this_class ) {
|
||||
$multi_view = et_pb_multi_view_options( $this_class );
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'classes' => array(
|
||||
'et_pb_hide_title' => array(
|
||||
'show_title' => 'off',
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$outer_wrapper_attrs = array_merge( $outer_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $outer_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_outer_wrapper_attrs", array( $this, 'add_multi_view_attrs' ), 10, 2 );
|
||||
|
||||
$output = self::get_additional_info( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Additional_Info();
|
365
includes/builder/module/woocommerce/Breadcrumb.php
Normal file
365
includes/builder/module/woocommerce/Breadcrumb.php
Normal file
@ -0,0 +1,365 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Breadcrumb class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Breadcrumb Class is responsible for rendering the
|
||||
* Breadcrumb markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Breadcrumb component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Breadcrumb extends ET_Builder_Module {
|
||||
/**
|
||||
* Home URL.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $home_url;
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Breadcrumb', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Breadcrumbs', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_breadcrumb';
|
||||
$this->vb_support = 'on';
|
||||
$this->main_css_element = '%%order_class%% .woocommerce-breadcrumb';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => array(
|
||||
'title' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'text' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
'tabbed_subtoggles' => true,
|
||||
'bb_icons_support' => true,
|
||||
'sub_toggles' => array(
|
||||
'p' => array(
|
||||
'name' => 'P',
|
||||
'icon' => 'text-left',
|
||||
),
|
||||
'a' => array(
|
||||
'name' => 'A',
|
||||
'icon' => 'text-link',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%, %%order_class%% .et_pb_module_inner, %%order_class%% .woocommerce-breadcrumb, %%order_class%% .woocommerce-breadcrumb a',
|
||||
'text_align' => '%%order_class%%',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '13px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'toggle_slug' => 'text',
|
||||
'sub_toggle' => 'p',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'link' => array(
|
||||
'label' => et_builder_i18n( 'Link' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%.et_pb_wc_breadcrumb a, %%order_class%%.et_pb_wc_breadcrumb .woocommerce-breadcrumb a',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'toggle_slug' => 'text',
|
||||
'sub_toggle' => 'a',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'margin' => '%%order_class%% .woocommerce-breadcrumb',
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_background_layout' => false,
|
||||
'sub_toggle' => 'p',
|
||||
'options' => array(
|
||||
'text_orientation' => array(
|
||||
'default' => 'left',
|
||||
),
|
||||
'background_layout' => array(
|
||||
'default' => 'light',
|
||||
),
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Includes any Module specific fields.
|
||||
*
|
||||
* Fields from Parent module that may be not needed are also removed.
|
||||
*
|
||||
* @since 4.0 Removed Hover options from Breadcrumb URL.
|
||||
*
|
||||
* @return array Parent's fields w/ module specific fields.
|
||||
*/
|
||||
public function get_fields() {
|
||||
// Content Toggle.
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__breadcrumb',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__breadcrumb',
|
||||
),
|
||||
)
|
||||
),
|
||||
'breadcrumb_home_text' => array(
|
||||
'label' => esc_html__( 'Home Text', 'et_builder' ),
|
||||
'type' => 'text',
|
||||
'option_category' => 'basic_option',
|
||||
'description' => esc_html__( 'Here you can create the breadcrumb text for the Home page.', 'et_builder' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'default' => __( 'Home', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
'dynamic_content' => 'text',
|
||||
),
|
||||
'breadcrumb_home_url' => array(
|
||||
'label' => esc_html__( 'Home Link', 'et_builder' ),
|
||||
'type' => 'text',
|
||||
'option_category' => 'basic_option',
|
||||
'description' => esc_html__( 'Here you can create the link for the Home page.', 'et_builder' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'default' => get_home_url(),
|
||||
'mobile_options' => true,
|
||||
'dynamic_content' => 'url',
|
||||
),
|
||||
'breadcrumb_separator' => array(
|
||||
'label' => esc_html__( 'Separator', 'et_builder' ),
|
||||
'type' => 'text',
|
||||
'option_category' => 'basic_option',
|
||||
'description' => esc_html__( 'Here you can set the Breadcrumb separator.', 'et_builder' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'default' => ' / ',
|
||||
'dynamic_content' => 'text',
|
||||
),
|
||||
'__breadcrumb' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Breadcrumb',
|
||||
'get_breadcrumb',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get breadcrumb
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_breadcrumb( $args = array() ) {
|
||||
global $post, $product, $wp_query;
|
||||
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
'breadcrumb_home_text' => __( 'Home', 'et_builder' ),
|
||||
'breadcrumb_home_url' => get_home_url(),
|
||||
'breadcrumb_separator' => '/',
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$args['breadcrumb_separator'] = esc_html( $args['breadcrumb_separator'] );
|
||||
|
||||
/*
|
||||
* Replace update-able string in visual builder with text placeholder which can be
|
||||
* easily replaced by builder for quick interaction on field change
|
||||
*
|
||||
* The `et_fb_is_resolve_post_content_callback_ajax()` check is added to enable
|
||||
* Product Breadcrumb dynamic content field.
|
||||
*
|
||||
* Breadcrumb customization is not required when resolving dynamic content field.
|
||||
* Hence we exclude customizations if the AJAX request is to resolve dynamic content fields.
|
||||
*/
|
||||
$main_query_post_id = ET_Post_Stack::get_main_post_id();
|
||||
$layout_post_id = ET_Builder_Element::get_layout_id();
|
||||
$is_fb = et_core_is_fb_enabled() && $main_query_post_id === $layout_post_id;
|
||||
|
||||
if ( ! et_fb_is_resolve_post_content_callback_ajax() && ( $is_fb || et_fb_is_builder_ajax() || et_fb_is_computed_callback_ajax() ) ) {
|
||||
$args = wp_parse_args(
|
||||
array(
|
||||
'breadcrumb_home_text' => '%HOME_TEXT%',
|
||||
'breadcrumb_home_url' => '%HOME_URL%',
|
||||
'breadcrumb_separator' => '%SEPARATOR%',
|
||||
),
|
||||
$args
|
||||
);
|
||||
}
|
||||
|
||||
// Update home URL which is rendered inside breadcrumb function and pluggable via filter.
|
||||
self::$home_url = $args['breadcrumb_home_url'];
|
||||
add_filter(
|
||||
'woocommerce_breadcrumb_home_url',
|
||||
array( 'ET_Builder_Module_Woocommerce_Breadcrumb', 'modify_home_url' )
|
||||
);
|
||||
|
||||
$breadcrumb = et_builder_wc_render_module_template(
|
||||
'woocommerce_breadcrumb',
|
||||
$args,
|
||||
array(
|
||||
'product',
|
||||
'post',
|
||||
'wp_query',
|
||||
)
|
||||
);
|
||||
|
||||
// Reset home URL.
|
||||
self::$home_url = get_home_url();
|
||||
remove_filter(
|
||||
'woocommerce_breadcrumb_home_url',
|
||||
array( 'ET_Builder_Module_Woocommerce_Breadcrumb', 'modify_home_url' )
|
||||
);
|
||||
|
||||
return $breadcrumb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify home url
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function modify_home_url() {
|
||||
return self::$home_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Inner wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Breadcrumb markup, we inject Multi view
|
||||
* attributes on to the Inner wrapper.
|
||||
*
|
||||
* Inner wrapper is selected to inject the Multi view attributes because, there is already
|
||||
* a lot going on w/ the Outer wrapper.
|
||||
*
|
||||
* @param array $inner_wrapper_attrs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $inner_wrapper_attrs ) {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
|
||||
/*
|
||||
* Breadcrumb separator cannot have Multi-view options as it is not enclosed in a HTML tag.
|
||||
* Element being enclose in a tag is essential for the Multi-view options to work.
|
||||
*/
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'content' => '{{breadcrumb_home_text}}',
|
||||
'attrs' => array(
|
||||
'href' => '{{breadcrumb_home_url}}',
|
||||
'data-breadcrumb-separator' => '{{breadcrumb_separator}}',
|
||||
),
|
||||
'target' => '%%order_class%% .woocommerce-breadcrumb a:first-child',
|
||||
),
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$inner_wrapper_attrs = array_merge( $inner_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $inner_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$output = self::get_breadcrumb( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_inner_wrapper_attrs", array( $this, 'add_multi_view_attrs' ) );
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Breadcrumb();
|
319
includes/builder/module/woocommerce/CartNotice.php
Normal file
319
includes/builder/module/woocommerce/CartNotice.php
Normal file
@ -0,0 +1,319 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Cart_Notice class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Cart_Notice Class is responsible for rendering the
|
||||
* Cart Notice markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Cart Notice component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Cart_Notice extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Cart Notice', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Cart Notices', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_cart_notice';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'text' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->main_css_element = '%%order_class%% .woocommerce-message';
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .woocommerce-message',
|
||||
// CPT style uses `!important` so outputting important is inevitable.
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '18px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'toggle_slug' => 'text',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
),
|
||||
'max_width' => array(
|
||||
'css' => array(
|
||||
'module_alignment' => '%%order_class%%.et_pb_module',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'padding' => '%%order_class%% .woocommerce-message',
|
||||
'important' => 'all',
|
||||
),
|
||||
'custom_padding' => array(
|
||||
'default' => '15px|15px|15px|15px|false|false',
|
||||
),
|
||||
'custom_margin' => array(
|
||||
'default' => '0em|0em|2em|0em|false|false',
|
||||
),
|
||||
),
|
||||
'button' => array(
|
||||
'button' => array(
|
||||
'label' => et_builder_i18n( 'Button' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .wc-forward',
|
||||
'important' => true,
|
||||
),
|
||||
'use_alignment' => false,
|
||||
'border_width' => array(
|
||||
'default' => '0px',
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .wc-forward',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_background_layout' => true,
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%',
|
||||
'text_shadow' => '%%order_class%%',
|
||||
),
|
||||
'options' => array(
|
||||
'text_orientation' => array(
|
||||
'default' => 'left',
|
||||
),
|
||||
'background_layout' => array(
|
||||
'default' => 'dark',
|
||||
),
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'background' => array(
|
||||
'css' => array(
|
||||
// Defined explicitly to solve
|
||||
// @see https://github.com/elegantthemes/Divi/issues/17200#issuecomment-542140907
|
||||
'main' => '%%order_class%% .woocommerce-message',
|
||||
// Important is required to override
|
||||
// Appearance ⟶ Customize ⟶ Color schemes styles.
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'border' => array(
|
||||
'css' => array(
|
||||
'important' => true,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'text' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'selector' => '.woocommerce-message',
|
||||
),
|
||||
'button' => array(
|
||||
'label' => et_builder_i18n( 'Button' ),
|
||||
'selector' => '.wc-forward',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
* Disable default cart notice if needed. Priority need to be set at 100 to
|
||||
* that the callback is being called after modules are being loaded.
|
||||
*
|
||||
* See: et_builder_load_framework()
|
||||
*/
|
||||
add_action(
|
||||
'wp',
|
||||
array(
|
||||
'ET_Builder_Module_Woocommerce_Cart_Notice',
|
||||
'disable_default_notice',
|
||||
),
|
||||
100
|
||||
);
|
||||
|
||||
// Clear notices array which was modified during render.
|
||||
add_action( 'wp_footer', array( 'ET_Builder_Module_Woocommerce_Cart_Notice', 'clear_notices' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__cart_notice',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__cart_notice',
|
||||
),
|
||||
)
|
||||
),
|
||||
'__cart_notice' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Cart_Notice',
|
||||
'get_cart_notice',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minumum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable default WooCommerce notice if current page's main query post content contains
|
||||
* Cart Notice module to prevent duplicate cart notices being rendered AND to make Cart Notice
|
||||
* module can render the notices correctly (notices are cleared once they are rendered)
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public static function disable_default_notice() {
|
||||
global $post;
|
||||
|
||||
$remove_default_notices = false;
|
||||
$tb_layouts = et_theme_builder_get_template_layouts();
|
||||
$tb_layout_types = et_theme_builder_get_layout_post_types();
|
||||
|
||||
// Check if a TB layout outputs the notices.
|
||||
foreach ( $tb_layout_types as $post_type ) {
|
||||
$id = et_()->array_get( $tb_layouts, array( $post_type, 'id' ), 0 );
|
||||
$enabled = et_()->array_get( $tb_layouts, array( $post_type, 'enabled' ), 0 );
|
||||
|
||||
if ( ! $id || ! $enabled ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$content = get_post_field( 'post_content', $id );
|
||||
|
||||
if ( has_shortcode( $content, 'et_pb_wc_cart_notice' ) ) {
|
||||
$remove_default_notices = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the product itself outputs the notices.
|
||||
if ( isset( $post->post_content ) && has_shortcode( $post->post_content, 'et_pb_wc_cart_notice' ) ) {
|
||||
$remove_default_notices = true;
|
||||
}
|
||||
|
||||
if ( $remove_default_notices ) {
|
||||
remove_action( 'woocommerce_before_single_product', 'woocommerce_output_all_notices', 10 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* We update Woo Notices array during modules render and need to cleat it
|
||||
* after Woo Product is fully rendered to avoid duplicated notifications on
|
||||
* subsequent page loads.
|
||||
*/
|
||||
public static function clear_notices() {
|
||||
if ( ! empty( WC()->session ) ) {
|
||||
WC()->session->set( 'wc_notices', null );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Cart notice markup.
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_cart_notice( $args = array() ) {
|
||||
if ( et_fb_enabled() || et_fb_is_builder_ajax() || et_fb_is_computed_callback_ajax() ) {
|
||||
return et_builder_wc_render_module_template( 'wc_print_notice', $args );
|
||||
}
|
||||
|
||||
return et_builder_wc_render_module_template( 'wc_print_notices', $args );
|
||||
}
|
||||
|
||||
function get_button_classname() {
|
||||
return 'wc-forward';
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
/*
|
||||
* In front end, do not print cart notice module if there is no notices exist.
|
||||
*
|
||||
* There is no custom style rendered below (to make sure that styles are correctly cached
|
||||
* nevertheless), thus it is fine to exit early;
|
||||
*/
|
||||
if ( ! empty( WC()->session ) && empty( WC()->session->get( 'wc_notices', array() ) ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_custom_button_icons( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$output = self::get_cart_notice( $this->props );
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Cart_Notice();
|
540
includes/builder/module/woocommerce/Description.php
Normal file
540
includes/builder/module/woocommerce/Description.php
Normal file
@ -0,0 +1,540 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Description class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Description Class is responsible for rendering the
|
||||
* Description markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Description component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Description extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @since 4.0.6 Updated `toggle_slug` to avoid empty Tabs in Text OG.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Description', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Descriptions', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_description';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'body' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
'tabbed_subtoggles' => true,
|
||||
'bb_icons_support' => true,
|
||||
'sub_toggles' => array(
|
||||
'p' => array(
|
||||
'name' => 'P',
|
||||
'icon' => 'text-left',
|
||||
),
|
||||
'a' => array(
|
||||
'name' => 'A',
|
||||
'icon' => 'text-link',
|
||||
),
|
||||
'ul' => array(
|
||||
'name' => 'UL',
|
||||
'icon' => 'list',
|
||||
),
|
||||
'ol' => array(
|
||||
'name' => 'OL',
|
||||
'icon' => 'numbered-list',
|
||||
),
|
||||
'quote' => array(
|
||||
'name' => 'QUOTE',
|
||||
'icon' => 'text-quote',
|
||||
),
|
||||
),
|
||||
),
|
||||
'header' => array(
|
||||
'title' => esc_html__( 'Heading Text', 'et_builder' ),
|
||||
'priority' => 49,
|
||||
'tabbed_subtoggles' => true,
|
||||
'sub_toggles' => array(
|
||||
'h1' => array(
|
||||
'name' => 'H1',
|
||||
'icon' => 'text-h1',
|
||||
),
|
||||
'h2' => array(
|
||||
'name' => 'H2',
|
||||
'icon' => 'text-h2',
|
||||
),
|
||||
'h3' => array(
|
||||
'name' => 'H3',
|
||||
'icon' => 'text-h3',
|
||||
),
|
||||
'h4' => array(
|
||||
'name' => 'H4',
|
||||
'icon' => 'text-h4',
|
||||
),
|
||||
'h5' => array(
|
||||
'name' => 'H5',
|
||||
'icon' => 'text-h5',
|
||||
),
|
||||
'h6' => array(
|
||||
'name' => 'H6',
|
||||
'icon' => 'text-h6',
|
||||
),
|
||||
),
|
||||
),
|
||||
'width' => array(
|
||||
'title' => et_builder_i18n( 'Sizing' ),
|
||||
'priority' => 65,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'line_height' => '%%order_class%% p',
|
||||
'color' => '%%order_class%%.et_pb_wc_description',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'p',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'link' => array(
|
||||
'label' => et_builder_i18n( 'Link' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% a',
|
||||
'color' => '%%order_class%%.et_pb_wc_description a',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => absint( et_get_option( 'body_font_size', '14' ) ) . 'px',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'a',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'ul' => array(
|
||||
'label' => esc_html__( 'Unordered List', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% ul',
|
||||
'color' => '%%order_class%%.et_pb_wc_description ul',
|
||||
'line_height' => '%%order_class%% ul li',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'ul',
|
||||
),
|
||||
'ol' => array(
|
||||
'label' => esc_html__( 'Ordered List', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% ol',
|
||||
'color' => '%%order_class%%.et_pb_wc_description ol',
|
||||
'line_height' => '%%order_class%% ol li',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'ol',
|
||||
),
|
||||
'quote' => array(
|
||||
'label' => esc_html__( 'Blockquote', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% blockquote',
|
||||
'color' => '%%order_class%%.et_pb_wc_description blockquote',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'quote',
|
||||
),
|
||||
'header' => array(
|
||||
'label' => esc_html__( 'Heading', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h1',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => absint( et_get_option( 'body_header_size', '30' ) ) . 'px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h1',
|
||||
),
|
||||
'header_2' => array(
|
||||
'label' => esc_html__( 'Heading 2', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h2',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h2',
|
||||
),
|
||||
'header_3' => array(
|
||||
'label' => esc_html__( 'Heading 3', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h3',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '22px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h3',
|
||||
),
|
||||
'header_4' => array(
|
||||
'label' => esc_html__( 'Heading 4', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h4',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '18px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h4',
|
||||
),
|
||||
'header_5' => array(
|
||||
'label' => esc_html__( 'Heading 5', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h5',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '16px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h5',
|
||||
),
|
||||
'header_6' => array(
|
||||
'label' => esc_html__( 'Heading 6', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h6',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
'sub_toggle' => 'h6',
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_background_layout' => true,
|
||||
'sub_toggle' => 'p',
|
||||
'toggle_slug' => 'body',
|
||||
'options' => array(
|
||||
'text_orientation' => array(
|
||||
'default' => 'left',
|
||||
),
|
||||
'background_layout' => array(
|
||||
'default' => 'light',
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__description',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__description',
|
||||
),
|
||||
)
|
||||
),
|
||||
'description_type' => array(
|
||||
'label' => esc_html__( 'Description Type', 'et_builder' ),
|
||||
'type' => 'select',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'description' => esc_html__( 'Description', 'et_builder' ),
|
||||
'short_description' => esc_html__( 'Short Description', 'et_builder' ),
|
||||
),
|
||||
'toggle_slug' => 'main_content',
|
||||
'description' => esc_html__( 'Here you can choose between Description and short description to display.', 'et_builder' ),
|
||||
'default_on_front' => 'short_description',
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
'computed_affects' => array(
|
||||
'__description',
|
||||
),
|
||||
),
|
||||
'__description' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Description',
|
||||
'get_description',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'description_type',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Description
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_description( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
'description_type' => 'short_description',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// Theme builder's description placeholder; short-circuit is cleaner and more efficient than
|
||||
// global object element being modified. NOTE: $conditional_tags element value is string
|
||||
if ( et_builder_tb_enabled() || 'true' === et_()->array_get( $conditional_tags, 'is_tb', false ) ) {
|
||||
$placeholders = et_theme_builder_wc_placeholders();
|
||||
|
||||
$description = 'short_description' === $args['description_type'] ?
|
||||
$placeholders['short_description'] :
|
||||
$placeholders['description'];
|
||||
|
||||
// Description comes from Post Content or Excerpt or Custom Field which is processed by WP and should be properly escaped during save.
|
||||
return et_core_intentionally_unescaped( $description, 'html' );
|
||||
}
|
||||
|
||||
$post_id = ET_Builder_Module_Helper_Woocommerce_Modules::get_product_id( $args['product'] );
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( ! ( $post instanceof WP_Post ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( 'description' === $args['description_type'] ) {
|
||||
// If builder is not used on given post, display post content.
|
||||
if ( ! et_pb_is_pagebuilder_used( $post_id ) ) {
|
||||
/** This filter is documented in wp-includes/post-template.php */
|
||||
$description = apply_filters( 'the_content', $post->post_content );
|
||||
} else {
|
||||
$description = get_post_meta( $post->ID, ET_BUILDER_WC_PRODUCT_LONG_DESC_META_KEY, true );
|
||||
|
||||
// Cannot use `the_content` filter since it adds content wrapper.
|
||||
// Content wrapper added at
|
||||
// `includes/builder/core.php`::et_builder_add_builder_content_wrapper()
|
||||
// This filter is documented at
|
||||
// includes/builder/feature/woocommerce-modules.php
|
||||
$description = apply_filters( 'et_builder_wc_description', $description );
|
||||
}
|
||||
} else {
|
||||
$description = apply_filters( 'woocommerce_short_description', $post->post_excerpt );
|
||||
}
|
||||
|
||||
// Description comes from Post Content or Excerpt or Custom Field which is processed by WP and should be properly escaped during save.
|
||||
return et_core_intentionally_unescaped( $description, 'html' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Breadcrumb markup, we inject Multi view
|
||||
* attributes on to the Outer wrapper.
|
||||
*
|
||||
* @param array $outer_wrapper_attrs
|
||||
* @param ET_Builder_Module_Woocommerce_Description $this_class
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $outer_wrapper_attrs, $this_class ) {
|
||||
$multi_view = et_pb_multi_view_options( $this_class );
|
||||
|
||||
$contexts = array(
|
||||
'content' => '{{description_type}}',
|
||||
'target' => '%%order_class%% .et_pb_module_inner',
|
||||
);
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs( $contexts, false, null, true );
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$outer_wrapper_attrs = array_merge( $outer_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $outer_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter multi view value.
|
||||
*
|
||||
* @see ET_Builder_Module_Helper_MultiViewOptions::filter_value
|
||||
*
|
||||
* @param mixed $raw_value Props raw value.
|
||||
* @param array $args {
|
||||
* Context data.
|
||||
*
|
||||
* @type string $context Context param: content,
|
||||
* attrs, visibility, classes.
|
||||
* @type string $name Module options props name.
|
||||
* @type string $mode Current data mode: desktop,
|
||||
* hover, tablet, phone.
|
||||
* @type string $attr_key Attribute key for attrs
|
||||
* context data. Example: src, class, etc.
|
||||
* @type string $attr_sub_key Attribute sub key that
|
||||
* availabe when passing attrs value as array such as styes. Example: padding-top,
|
||||
* margin-botton, etc.
|
||||
* }
|
||||
*
|
||||
* @param ET_Builder_Module_Helper_MultiViewOptions $multi_view Multiview object instance.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function multi_view_filter_value( $raw_value, $args, $multi_view ) {
|
||||
if ( empty( $multi_view->get_module_props() ) ) {
|
||||
return $raw_value;
|
||||
}
|
||||
|
||||
$maybe_product = et_()->array_get( $multi_view->get_module_props(), 'product', '0' );
|
||||
$product = ET_Builder_Module_Helper_Woocommerce_Modules::get_product( $maybe_product );
|
||||
|
||||
if ( ! $product ) {
|
||||
return $raw_value;
|
||||
}
|
||||
|
||||
$name = et_()->array_get( $args, 'name', '' );
|
||||
$mode = et_()->array_get( $args, 'mode', '' );
|
||||
$post = get_post( $product->get_id() );
|
||||
|
||||
// Validating $post validates $post_id. No separate $post_id validation is required.
|
||||
if ( 'description_type' !== $name || ! $post ) {
|
||||
return $raw_value;
|
||||
}
|
||||
|
||||
if ( 'description' === $multi_view->get_inherit_value( $name, $mode ) ) {
|
||||
if ( ! et_pb_is_pagebuilder_used( $product->get_id() ) ) {
|
||||
$raw_value = $post->post_content;
|
||||
} else {
|
||||
$raw_value = get_post_meta( $post->ID, ET_BUILDER_WC_PRODUCT_LONG_DESC_META_KEY, true );
|
||||
}
|
||||
} else {
|
||||
$raw_value = $post->post_excerpt;
|
||||
}
|
||||
|
||||
return $raw_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_outer_wrapper_attrs", array( $this, 'add_multi_view_attrs' ), 10, 2 );
|
||||
|
||||
$output = self::get_description( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Description();
|
293
includes/builder/module/woocommerce/Gallery.php
Normal file
293
includes/builder/module/woocommerce/Gallery.php
Normal file
@ -0,0 +1,293 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Description class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Description Class is responsible for rendering the
|
||||
* Description markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'ET_Builder_Module_Gallery' ) ) {
|
||||
require_once ET_BUILDER_DIR_RESOLVED_PATH . '/module/Gallery.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Gallery component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Gallery extends ET_Builder_Module_Gallery {
|
||||
/**
|
||||
* Modify properties defined on base module's (gallery) init()
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
$this->name = esc_html__( 'Woo Gallery', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Galleries', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_gallery';
|
||||
$this->main_css_element = '%%order_class%%';
|
||||
|
||||
// Intentionally removing inherited options group.
|
||||
unset( $this->settings_modal_toggles['general']['toggles']['main_content'] );
|
||||
|
||||
// Rename Elements Option group to Content.
|
||||
$this->settings_modal_toggles['general']['toggles']['elements'] = et_builder_i18n( 'Content' );
|
||||
|
||||
// Intentionally removing inherited advanced options group.
|
||||
$this->advanced_fields['link_options'] = false;
|
||||
|
||||
$this->advanced_fields['fonts']['title']['font_size'] = array(
|
||||
'default' => '18px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['title']['line_height'] = array(
|
||||
'default' => '1em',
|
||||
);
|
||||
$this->advanced_fields['fonts']['pagination']['font_size'] = array(
|
||||
'default' => '16px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['pagination']['line_height'] = array(
|
||||
'default' => '16px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['caption']['font_size'] = array(
|
||||
'default' => '14px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['caption']['line_height'] = array(
|
||||
'default' => '1em',
|
||||
);
|
||||
$this->advanced_fields['position_fields'] = array(
|
||||
'default' => 'relative',
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'gallery_item' => array(
|
||||
'label' => esc_html__( 'Gallery Item', 'et_builder' ),
|
||||
'selector' => '.et_pb_gallery_item',
|
||||
),
|
||||
'gallery_pagination' => array(
|
||||
'label' => esc_html__( 'Gallery Pagination', 'et_builder' ),
|
||||
'selector' => '.et-pb-controllers a',
|
||||
),
|
||||
'gallery_pagination_active' => array(
|
||||
'label' => esc_html__( 'Pagination Active Page', 'et_builder' ),
|
||||
'selector' => '.et-pb-controllers a.et-pb-active-control',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
|
||||
// Insert classname to module wrapper.
|
||||
add_filter(
|
||||
'et_builder_wc_gallery_classes',
|
||||
array(
|
||||
$this,
|
||||
'add_wc_gallery_classname',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Woo Galleries specific fields and modify fields inherited from base module (gallery)
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_fields() {
|
||||
/*
|
||||
* Woo Galleries fields that need to be prepended before fields inherited from gallery
|
||||
* module.
|
||||
*/
|
||||
$product_default = ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default();
|
||||
$wc_gallery_fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => $product_default,
|
||||
'toggle_slug' => 'elements',
|
||||
'computed_affects' => array(
|
||||
'__gallery',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'toggle_slug' => 'elements',
|
||||
'computed_affects' => array(
|
||||
'__gallery',
|
||||
),
|
||||
)
|
||||
),
|
||||
);
|
||||
|
||||
// Base module (gallery) fields.
|
||||
$fields = parent::get_fields();
|
||||
|
||||
// Set the default Layout as Slider.
|
||||
if ( array_key_exists( 'fullwidth', $fields ) ) {
|
||||
$fields['fullwidth']['default_on_front'] = 'on';
|
||||
}
|
||||
|
||||
// Prepending WC images field to fields inherited from gallery module (base module).
|
||||
$fields = array_merge( $wc_gallery_fields, $fields );
|
||||
|
||||
// Hide gallery upload image field because module images are set from "Product" field.
|
||||
$fields['gallery_ids']['type'] = 'hidden';
|
||||
|
||||
/*
|
||||
* Modify `__gallery`'s `computed_callback` attribute so Woo Gallery can insert additional
|
||||
* arguments to computed callback result.
|
||||
*/
|
||||
$fields['__gallery'] = array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Gallery',
|
||||
'get_wc_gallery',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
// Field is hidden because its control is take over by `product` field.
|
||||
'gallery_ids',
|
||||
|
||||
/*
|
||||
* Fields exist but not being rendered because their options group is hidden
|
||||
* based on the spec.
|
||||
*/
|
||||
'gallery_orderby',
|
||||
'gallery_captions',
|
||||
|
||||
// Exising and visible fields.
|
||||
'fullwidth',
|
||||
'orientation',
|
||||
'show_pagination',
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Placeholder ID as Gallery IDs when in TB mode.
|
||||
*
|
||||
* @see https://github.com/elegantthemes/Divi/issues/18768
|
||||
*
|
||||
* @since 4.10.8
|
||||
*
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
*
|
||||
* @return array Array containing placeholder Id when in TB mode. Empty array otherwise.
|
||||
*/
|
||||
public static function get_gallery_ids( $conditional_tags ) {
|
||||
if ( ! is_array( $conditional_tags ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$is_tb = et_()->array_get( $conditional_tags, 'is_tb', false );
|
||||
|
||||
if ( ! $is_tb || ! function_exists( 'wc_placeholder_img_src' ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$placeholder_src = wc_placeholder_img_src( 'full' );
|
||||
$placeholder_id = attachment_url_to_postid( $placeholder_src );
|
||||
|
||||
if ( 0 === absint( $placeholder_id ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
return array( $placeholder_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed callback's callback method which adjusted arguments passed to original computed
|
||||
* callback's callback so the result is suitable for Woo Gallery module
|
||||
*
|
||||
* @since 4.10.8 Load Placeholder Image when in TB mode.
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Arguments from Computed Prop AJAX call.
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
* @param array $current_page Current page args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_wc_gallery( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
if ( 'current' === $args['product'] && 'true' === et_()->array_get( $conditional_tags, 'is_tb', false ) ) {
|
||||
et_theme_builder_wc_set_global_objects( $conditional_tags );
|
||||
|
||||
global $product;
|
||||
} else {
|
||||
// Generate valid `gallery_ids` value based `product` attribute.
|
||||
$product = ET_Builder_Module_Helper_Woocommerce_Modules::get_product( $args['product'] );
|
||||
}
|
||||
|
||||
$attachment_ids = array();
|
||||
|
||||
if ( $product ) {
|
||||
$featured_image_id = intval( $product->get_image_id() );
|
||||
$attachment_ids = $product->get_gallery_image_ids();
|
||||
}
|
||||
|
||||
// Load placeholder Image when in TB.
|
||||
if ( is_array( $attachment_ids ) && empty( $attachment_ids ) ) {
|
||||
$attachment_ids = self::get_gallery_ids( $conditional_tags );
|
||||
}
|
||||
|
||||
// Modify `gallery_ids` value.
|
||||
$args['gallery_ids'] = $attachment_ids;
|
||||
|
||||
// Don't display Placeholder when no Gallery image is available.
|
||||
// @see https://github.com/elegantthemes/submodule-builder/pull/6706#issuecomment-542275647
|
||||
if ( 0 === count( $attachment_ids ) ) {
|
||||
$args['attachment_id'] = -1;
|
||||
}
|
||||
|
||||
return ET_Builder_Module_Gallery::get_gallery( $args, $conditional_tags, $current_page );
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify module wrapper's classname
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $classname List of class names.
|
||||
* @param int $render_count Count of times the module is rendered.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_wc_gallery_classname( $classname, $render_count ) {
|
||||
// For gallery to be properly rendered, it needs `et_pb_gallery` classname.
|
||||
$classname[] = 'et_pb_gallery';
|
||||
|
||||
return $classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use ET_Builder_Module_Woocommerce_Gallery::get_wc_gallery() instead of base module's
|
||||
* ET_Builder_Module_Gallery::get_gallery() method for defining attachment value in
|
||||
* frontend's `render()` and visual builder's computed callback result
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_attachments( $args = array() ) {
|
||||
$args['product'] = $this->props['product'];
|
||||
|
||||
return self::get_wc_gallery( $args );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Gallery();
|
342
includes/builder/module/woocommerce/Images.php
Normal file
342
includes/builder/module/woocommerce/Images.php
Normal file
@ -0,0 +1,342 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Images class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Images Class is responsible for rendering the
|
||||
* Image markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Images component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Images extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Images', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_images';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
'elements' => et_builder_i18n( 'Elements' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'image' => et_builder_i18n( 'Image' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'borders' => array(
|
||||
'default' => array(),
|
||||
'image' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%% div.images ol.flex-control-thumbs.flex-control-nav li, %%order_class%% .flex-viewport, %%order_class%% .woocommerce-product-gallery--without-images .woocommerce-product-gallery__wrapper, %%order_class%% .woocommerce-product-gallery > div:not(.flex-viewport) .woocommerce-product-gallery__image, %%order_class%% .woocommerce-product-gallery > .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image, %%order_class%% .woocommerce-product-gallery .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image',
|
||||
'border_styles' => '%%order_class%% div.images ol.flex-control-thumbs.flex-control-nav li, %%order_class%% .flex-viewport, %%order_class%% .woocommerce-product-gallery--without-images .woocommerce-product-gallery__wrapper, %%order_class%% .woocommerce-product-gallery > div:not(.flex-viewport) .woocommerce-product-gallery__image, %%order_class%% .woocommerce-product-gallery > .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image',
|
||||
),
|
||||
),
|
||||
'label_prefix' => et_builder_i18n( 'Image' ),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
),
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'default' => array(),
|
||||
'image' => array(
|
||||
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
|
||||
'option_category' => 'layout',
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% div.images ol.flex-control-thumbs.flex-control-nav li, %%order_class%% .flex-viewport, %%order_class%% .woocommerce-product-gallery--without-images .woocommerce-product-gallery__wrapper, %%order_class%% .woocommerce-product-gallery > div:not(.flex-viewport) .woocommerce-product-gallery__image, %%order_class%% .woocommerce-product-gallery > .woocommerce-product-gallery__wrapper .woocommerce-product-gallery__image',
|
||||
'overlay' => 'inset',
|
||||
'important' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
'background' => array(),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text_shadow' => array(),
|
||||
'text' => false,
|
||||
'fonts' => array(
|
||||
'sale_badge' => array(
|
||||
'label' => esc_html__( 'Sale Badge', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_pb_module_inner span.onsale',
|
||||
'important' => 'all',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '20px',
|
||||
),
|
||||
'letter_spacing' => array(
|
||||
'default' => '0px',
|
||||
),
|
||||
),
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__images',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__images',
|
||||
),
|
||||
)
|
||||
),
|
||||
'show_product_image' => array(
|
||||
'label' => esc_html__( 'Show Featured Image', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether product image should be displayed or not.', 'et_builder' ),
|
||||
'computed_affects' => array(
|
||||
'__images',
|
||||
),
|
||||
),
|
||||
'show_product_gallery' => array(
|
||||
'label' => esc_html__( 'Show Gallery Images', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether product gallery should be displayed or not.', 'et_builder' ),
|
||||
'computed_affects' => array(
|
||||
'__images',
|
||||
),
|
||||
),
|
||||
'show_sale_badge' => array(
|
||||
'label' => esc_html__( 'Show Sale Badge', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether Sale Badge should be displayed or not.', 'et_builder' ),
|
||||
'computed_affects' => array(
|
||||
'__images',
|
||||
),
|
||||
),
|
||||
'sale_badge_color' => array(
|
||||
'label' => esc_html__( 'Sale Badge Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Pick a color to use for the sales bade that appears on products that are on sale.', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'sale_badge',
|
||||
'hover' => 'tabs',
|
||||
'sticky' => true,
|
||||
'mobile_options' => true,
|
||||
),
|
||||
'__images' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Images',
|
||||
'get_images',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'show_product_image',
|
||||
'show_product_gallery',
|
||||
'show_sale_badge',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
'force_fullwidth' => array(
|
||||
'label' => esc_html__( 'Force Fullwidth', 'et_builder' ),
|
||||
'description' => esc_html__( "When enabled, this will force your image to extend 100% of the width of the column it's in.", 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'layout',
|
||||
'options' => array(
|
||||
'off' => et_builder_i18n( 'No' ),
|
||||
'on' => et_builder_i18n( 'Yes' ),
|
||||
),
|
||||
'default' => 'off',
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
'affects' => array(
|
||||
'max_width',
|
||||
'width',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get images output
|
||||
*
|
||||
* @since 4.12.0 Set $defaults['overwrite'] to array( 'product', 'post' )
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_images( $args = array() ) {
|
||||
/*
|
||||
* YITH Badge Management plugin executes only when
|
||||
* did_action( 'woocommerce_product_thumbnails' ) returns FALSE.
|
||||
*
|
||||
* The above wouldn't be the case when multiple Woo Images modules
|
||||
* are placed on the same page.
|
||||
* Hence the workaround is to reset the 'woocommerce_product_thumbnails' action.
|
||||
*
|
||||
* @link https://github.com/elegantthemes/Divi/issues/18530
|
||||
*/
|
||||
global $wp_actions;
|
||||
|
||||
$tag = 'woocommerce_product_thumbnails';
|
||||
$reset = false;
|
||||
$value = 0;
|
||||
|
||||
if ( isset( $wp_actions[ $tag ] ) ) {
|
||||
$value = $wp_actions[ $tag ];
|
||||
$reset = true;
|
||||
unset( $wp_actions[ $tag ] );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
'show_product_image' => 'on',
|
||||
'show_product_gallery' => 'on',
|
||||
'show_sale_badge' => 'on',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
$images = et_builder_wc_render_module_template(
|
||||
'woocommerce_show_product_images',
|
||||
$args,
|
||||
array( 'product', 'post' )
|
||||
);
|
||||
|
||||
/*
|
||||
* Reset changes made for YITH Badge Management plugin.
|
||||
*
|
||||
* That way we won't bleed creating new issues.
|
||||
*
|
||||
* @link https://github.com/elegantthemes/Divi/issues/18530
|
||||
*/
|
||||
if ( $reset && ! isset( $wp_actions[ $tag ] ) ) {
|
||||
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Fix compatibility.
|
||||
$wp_actions[ $tag ] = $value;
|
||||
}
|
||||
|
||||
return $images;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$sale_badge_color_hover = $this->get_hover_value( 'sale_badge_color' );
|
||||
$sale_badge_color_values = et_pb_responsive_options()->get_property_values( $this->props, 'sale_badge_color' );
|
||||
$force_fullwidth = et_()->array_get( $this->props, 'force_fullwidth', 'off' );
|
||||
$show_product_image = et_()->array_get( $this->props, 'show_product_image', 'off' );
|
||||
|
||||
// Sale Badge Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'base_attr_name' => 'sale_badge_color',
|
||||
'selector' => '%%order_class%% span.onsale',
|
||||
'css_property' => 'background-color',
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Image force fullwidth.
|
||||
if ( 'on' === $force_fullwidth ) {
|
||||
ET_Builder_Element::set_style(
|
||||
$render_slug,
|
||||
array(
|
||||
'selector' => '%%order_class%% .woocommerce-product-gallery__image img',
|
||||
'declaration' => 'width: 100%;',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Toggle featured image.
|
||||
if ( 'off' === $show_product_image ) {
|
||||
ET_Builder_Element::set_style(
|
||||
$render_slug,
|
||||
array(
|
||||
'selector' => '%%order_class%% .woocommerce-product-gallery__image--placeholder img[src*="woocommerce-placeholder"]',
|
||||
'declaration' => 'visibility: hidden;',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$output = self::get_images( $this->props );
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Images();
|
399
includes/builder/module/woocommerce/Meta.php
Normal file
399
includes/builder/module/woocommerce/Meta.php
Normal file
@ -0,0 +1,399 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Meta class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Meta Class is responsible for rendering the
|
||||
* Meta markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Meta component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Meta extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Meta', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Metas', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_meta';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
'elements' => et_builder_i18n( 'Elements' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'layout' => et_builder_i18n( 'Layout' ),
|
||||
'body' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
'tabbed_subtoggles' => true,
|
||||
'bb_icons_support' => true,
|
||||
'sub_toggles' => array(
|
||||
'p' => array(
|
||||
'name' => 'P',
|
||||
'icon' => 'text-left',
|
||||
),
|
||||
'a' => array(
|
||||
'name' => 'A',
|
||||
'icon' => 'text-link',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => esc_html__( 'Meta', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product_meta, %%order_class%% .product_meta a',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'sub_toggle' => 'p',
|
||||
'toggle_slug' => 'body',
|
||||
),
|
||||
'link' => array(
|
||||
'label' => et_builder_i18n( 'Link' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% div.product_meta a',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'toggle_slug' => 'body',
|
||||
'sub_toggle' => 'a',
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product_meta',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product_meta',
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_text_orientation' => false,
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product_meta',
|
||||
),
|
||||
),
|
||||
),
|
||||
'button' => false,
|
||||
|
||||
'borders' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%% .product_meta',
|
||||
'border_styles' => '%%order_class%% .product_meta',
|
||||
),
|
||||
),
|
||||
'defaults' => array(
|
||||
'border_radii' => 'on||||',
|
||||
'border_styles' => array(
|
||||
'width' => '0px',
|
||||
'color' => '#dadada',
|
||||
'style' => 'solid',
|
||||
),
|
||||
'composite' => array(
|
||||
'border_top' => array(
|
||||
'border_width_top' => '1px',
|
||||
'border_color_top' => '#dadada',
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
'height' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product_meta',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'meta_text' => array(
|
||||
'label' => esc_html__( 'Meta Text', 'et_builder' ),
|
||||
'selector' => '.product_meta, .product_meta a',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__meta',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__meta',
|
||||
),
|
||||
)
|
||||
),
|
||||
'separator' => array(
|
||||
'label' => esc_html__( 'Separator', 'et_builder' ),
|
||||
'type' => 'text',
|
||||
'option_category' => 'basic_option',
|
||||
'description' => esc_html__( 'Here you can set the separator.', 'et_builder' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'default' => '/',
|
||||
'show_if' => array(
|
||||
'meta_layout' => 'inline',
|
||||
),
|
||||
),
|
||||
'show_sku' => array(
|
||||
'label' => esc_html__( 'Show SKU', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the SKU should be added.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'show_categories' => array(
|
||||
'label' => esc_html__( 'Show Categories', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the Categories should be added.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'show_tags' => array(
|
||||
'label' => esc_html__( 'Show Tags', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the Tags should be added.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'meta_layout' => array(
|
||||
'label' => esc_html__( 'Meta Layout', 'et_builder' ),
|
||||
'type' => 'select',
|
||||
'option_category' => 'layout',
|
||||
'options' => array(
|
||||
'inline' => esc_html__( 'Inline', 'et_builder' ),
|
||||
'stacked' => esc_html__( 'Stacked', 'et_builder' ),
|
||||
),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'layout',
|
||||
'description' => esc_html__( 'Here you can choose how to position the product meta.', 'et_builder' ),
|
||||
'default_on_front' => 'inline',
|
||||
'affects' => array(
|
||||
'separator',
|
||||
),
|
||||
),
|
||||
'__meta' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Meta',
|
||||
'get_meta',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get meta output
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_meta( $args = array() ) {
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
$meta = et_builder_wc_render_module_template(
|
||||
'woocommerce_template_single_meta',
|
||||
$args
|
||||
);
|
||||
|
||||
return $meta;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Breadcrumb markup, we inject Multi view
|
||||
* attributes on to the Outer wrapper.
|
||||
*
|
||||
* @param array $outer_wrapper_attrs
|
||||
* @param ET_Builder_Module_Woocommerce_Meta $this_class
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $outer_wrapper_attrs, $this_class ) {
|
||||
$multi_view = et_pb_multi_view_options( $this_class );
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'classes' => array(
|
||||
'et_pb_wc_no_sku' => array(
|
||||
'show_sku' => 'off',
|
||||
),
|
||||
'et_pb_wc_no_categories' => array(
|
||||
'show_categories' => 'off',
|
||||
),
|
||||
'et_pb_wc_no_tags' => array(
|
||||
'show_tags' => 'off',
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$outer_wrapper_attrs = array_merge( $outer_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $outer_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
// Module classnames.
|
||||
if ( 'on' !== $multi_view->get_value( 'show_sku' ) ) {
|
||||
$this->add_classname( 'et_pb_wc_no_sku' );
|
||||
}
|
||||
|
||||
if ( 'on' !== $multi_view->get_value( 'show_categories' ) ) {
|
||||
$this->add_classname( 'et_pb_wc_no_categories' );
|
||||
}
|
||||
|
||||
if ( 'on' !== $multi_view->get_value( 'show_tags' ) ) {
|
||||
$this->add_classname( 'et_pb_wc_no_tags' );
|
||||
}
|
||||
|
||||
$this->add_classname( esc_attr( 'et_pb_wc_meta_layout_' . $this->props['meta_layout'] ) );
|
||||
|
||||
/*
|
||||
* Append separator via css pseudo selector so meta module can reuse default WooCommerce
|
||||
* template (default WooCommerce meta template has no separator option)
|
||||
*/
|
||||
ET_Builder_Element::set_style(
|
||||
$render_slug,
|
||||
array(
|
||||
'selector' => array(
|
||||
'%%order_class%%:not(.et_pb_wc_no_categories).et_pb_wc_meta_layout_inline .sku_wrapper:after',
|
||||
'%%order_class%%:not(.et_pb_wc_no_tags).et_pb_wc_meta_layout_inline .sku_wrapper:after',
|
||||
'%%order_class%%:not(.et_pb_wc_no_tags).et_pb_wc_meta_layout_inline .posted_in:after',
|
||||
),
|
||||
'declaration' => 'content: " ' . esc_html(
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::escape_special_chars(
|
||||
$this->props['separator']
|
||||
)
|
||||
) . ' "',
|
||||
)
|
||||
);
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_outer_wrapper_attrs", array( $this, 'add_multi_view_attrs' ), 10, 2 );
|
||||
|
||||
$output = self::get_meta( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Meta();
|
236
includes/builder/module/woocommerce/Price.php
Normal file
236
includes/builder/module/woocommerce/Price.php
Normal file
@ -0,0 +1,236 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Price class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Price Class is responsible for rendering the
|
||||
* Price markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Price component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Price extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Price', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Prices', 'et_builder' );
|
||||
|
||||
// Use `et_pb_wc_{module}` for all WooCommerce modules.
|
||||
$this->slug = 'et_pb_wc_price';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
|
||||
/*
|
||||
* Manually define `text` to avoid `Text Text` toggle defined by advanced
|
||||
* field font which automatically append ` Text` by default.
|
||||
*/
|
||||
'text' => array(
|
||||
'title' => esc_html__( 'Price Text', 'et_builder' ),
|
||||
'priority' => 45,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'body' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .price',
|
||||
'important' => array( 'size' ),
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'before_sale_price' => array(
|
||||
'label' => esc_html__( 'Sale Old Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .price del',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
'sale_price' => array(
|
||||
'label' => esc_html__( 'Sale New Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .price ins',
|
||||
'important' => array( 'font' ),
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
'font' => array(
|
||||
'default' => '|700|||||||',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
|
||||
/*
|
||||
* Module has default margin-bottom which adapts to column it currently in
|
||||
* thus, stronger selector needed for module's custom styling to overwrite it.
|
||||
*/
|
||||
'margin' => '.et_pb_row .et_pb_column div%%order_class%%',
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'css' => array(
|
||||
'text_shadow' => '%%order_class%%',
|
||||
),
|
||||
'options' => array(
|
||||
'background_layout' => array(
|
||||
'default' => 'light',
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
),
|
||||
|
||||
// Assign to main font advanced field (body), keeping things simplified
|
||||
'toggle_slug' => 'body',
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'text' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'selector' => '.price',
|
||||
),
|
||||
'before_sale_price' => array(
|
||||
'label' => esc_html__( 'Sale Old Price', 'et_builder' ),
|
||||
'selector' => '.price del',
|
||||
),
|
||||
'sale_price' => array(
|
||||
'label' => esc_html__( 'Sale New Price', 'et_builder' ),
|
||||
'selector' => '.price ins',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__price',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__price',
|
||||
),
|
||||
)
|
||||
),
|
||||
'__price' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Price',
|
||||
'get_price',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minumum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get price data
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Arguments from Computed Prop AJAX call.
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
* @param array $current_page Current page args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_price( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
return et_builder_wc_render_module_template( 'woocommerce_template_single_price', $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$output = self::get_price( $this->props );
|
||||
|
||||
// Render empty string if no output or no price value are generated
|
||||
// to avoid unwanted vertical space.
|
||||
if ( '' === trim( $output ) || '<p class="price"></p>' === trim( $output ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Price();
|
346
includes/builder/module/woocommerce/Rating.php
Normal file
346
includes/builder/module/woocommerce/Rating.php
Normal file
@ -0,0 +1,346 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Rating class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Rating Class is responsible for rendering the
|
||||
* Rating markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Rating component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Rating extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @since 3.29.2 Added custom margin default.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Rating', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Ratings', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_rating';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
'elements' => et_builder_i18n( 'Elements' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'layout' => et_builder_i18n( 'Layout' ),
|
||||
// Avoid Text suffix by manually defining the `text` toggle slug.
|
||||
'text' => array(
|
||||
'title' => et_builder_i18n( 'Text' ),
|
||||
'priority' => 45,
|
||||
),
|
||||
// Avoid Text suffix by manually defining the `star` toggle slug.
|
||||
'star' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'rating' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .woocommerce-product-rating .star-rating',
|
||||
'color' => '%%order_class%% .woocommerce-product-rating .star-rating > span:before',
|
||||
'text_align' => '%%order_class%% .woocommerce-product-rating',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'hide_font' => true,
|
||||
'hide_line_height' => true,
|
||||
'hide_text_shadow' => true,
|
||||
'text_align' => array(
|
||||
'label' => esc_html__( 'Star Rating Alignment', 'et_builder' ),
|
||||
),
|
||||
'font_size' => array(
|
||||
'label' => esc_html__( 'Star Rating Size', 'et_builder' ),
|
||||
),
|
||||
'text_color' => array(
|
||||
'label' => esc_html__( 'Star Rating Color', 'et_builder' ),
|
||||
),
|
||||
'toggle_slug' => 'star',
|
||||
),
|
||||
'body' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% a.woocommerce-review-link',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
|
||||
/*
|
||||
* Manually assign `text` toggle to avoid `Text Text` toggle defined by advanced
|
||||
* field font which automatically append ` Text` by default.
|
||||
*/
|
||||
'toggle_slug' => 'text',
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
'custom_margin' => array(
|
||||
'default' => '0em|0em|1.618em|0em|false|false',
|
||||
),
|
||||
),
|
||||
'text' => array(),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'text' => array(
|
||||
'label' => et_builder_i18n( 'Text' ),
|
||||
'selector' => 'a.woocommerce-review-link',
|
||||
),
|
||||
'star_rating_text' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'selector' => '.woocommerce-product-rating .star-rating',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__rating',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__rating',
|
||||
),
|
||||
)
|
||||
),
|
||||
'show_rating' => array(
|
||||
'label' => esc_html__( 'Show Star Rating', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the star rating should be added.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'show_reviews_link' => array(
|
||||
'label' => esc_html__( 'Show Customer Reviews Count', 'et_builder' ),
|
||||
'type' => 'yes_no_button',
|
||||
'option_category' => 'configuration',
|
||||
'options' => array(
|
||||
'on' => et_builder_i18n( 'On' ),
|
||||
'off' => et_builder_i18n( 'Off' ),
|
||||
),
|
||||
'default_on_front' => 'on',
|
||||
'toggle_slug' => 'elements',
|
||||
'description' => esc_html__( 'Here you can choose whether the custom reviews link should be added.', 'et_builder' ),
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
'layout' => array(
|
||||
'label' => esc_html__( 'Rating Layout', 'et_builder' ),
|
||||
'type' => 'select',
|
||||
'option_category' => 'layout',
|
||||
'options' => array(
|
||||
'inline' => esc_html__( 'Inline', 'et_builder' ),
|
||||
'stacked' => esc_html__( 'Stacked', 'et_builder' ),
|
||||
),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'layout',
|
||||
'description' => esc_html__( 'Here you can choose where to place the reviews link.', 'et_builder' ),
|
||||
'default_on_front' => 'inline',
|
||||
),
|
||||
'__rating' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Rating',
|
||||
'get_rating',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_transition_fields_css_props() {
|
||||
$fields = parent::get_transition_fields_css_props();
|
||||
|
||||
$fields['rating_letter_spacing'] = array(
|
||||
'width' => '%%order_class%% .star-rating',
|
||||
'letter-spacing' => '%%order_class%% .star-rating',
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rating output
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_rating( $args = array() ) {
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
if ( 'current' !== $args['product'] ) {
|
||||
// Enable comments via filter to render the reviews link.
|
||||
add_filter( 'comments_open', '__return_true' );
|
||||
}
|
||||
|
||||
$rating = et_builder_wc_render_module_template(
|
||||
'woocommerce_template_single_rating',
|
||||
$args,
|
||||
array( 'product', 'wp_query' )
|
||||
);
|
||||
|
||||
if ( 'current' !== $args['product'] ) {
|
||||
// Remove filter after module is rendered.
|
||||
remove_filter( 'comments_open', '__return_true' );
|
||||
}
|
||||
|
||||
return $rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Rating markup, we inject Multi view
|
||||
* attributes on to the Outer wrapper.
|
||||
*
|
||||
* @param array $outer_wrapper_attrs
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_multi_view_attrs( $outer_wrapper_attrs ) {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'classes' => array(
|
||||
'et_pb_wc_rating_no_rating' => array(
|
||||
'show_rating' => 'off',
|
||||
),
|
||||
'et_pb_wc_rating_no_reviews' => array(
|
||||
'show_reviews_link' => 'off',
|
||||
),
|
||||
),
|
||||
),
|
||||
false,
|
||||
null,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $multi_view_attrs && is_array( $multi_view_attrs ) ) {
|
||||
$outer_wrapper_attrs = array_merge( $outer_wrapper_attrs, $multi_view_attrs );
|
||||
}
|
||||
|
||||
return $outer_wrapper_attrs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::add_star_rating_style(
|
||||
$render_slug,
|
||||
$this->props,
|
||||
'%%order_class%% .star-rating',
|
||||
'%%order_class%%:hover .star-rating',
|
||||
array( 'rating_letter_spacing' )
|
||||
);
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
// Add classes to hide disabled elements.
|
||||
if ( 'on' !== $this->props['show_rating'] ) {
|
||||
$this->add_classname( 'et_pb_wc_rating_no_rating' );
|
||||
}
|
||||
|
||||
if ( 'on' !== $this->props['show_reviews_link'] ) {
|
||||
$this->add_classname( 'et_pb_wc_rating_no_reviews' );
|
||||
}
|
||||
|
||||
if ( ! empty( $this->props['layout'] ) ) {
|
||||
$this->add_classname( "et_pb_wc_rating_layout_{$this->props['layout']}" );
|
||||
}
|
||||
|
||||
add_filter( "et_builder_module_{$render_slug}_outer_wrapper_attrs", array( $this, 'add_multi_view_attrs' ) );
|
||||
|
||||
$output = self::get_rating( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Rating();
|
704
includes/builder/module/woocommerce/RelatedProducts.php
Normal file
704
includes/builder/module/woocommerce/RelatedProducts.php
Normal file
@ -0,0 +1,704 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Related_Products class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Related_Products Class is responsible for rendering the
|
||||
* Related Products markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Related Products component.
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Related_Products extends ET_Builder_Module {
|
||||
/**
|
||||
* Holds Prop values across static methods.
|
||||
*
|
||||
* @var array
|
||||
*
|
||||
* @used-by ET_Builder_Module_Woocommerce_Related_Products::get_related_products()
|
||||
* @used-by ET_Builder_Module_Woocommerce_Related_Products::get_selected_related_product_args()
|
||||
*/
|
||||
public static $static_props;
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*
|
||||
* @since 4.0.7 Introduced Product title toggle slug to allow Copy/Paste
|
||||
* @see {https://github.com/elegantthemes/Divi/issues/17436}
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Related Product', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Related Products', 'et_builder' );
|
||||
|
||||
// Use `et_pb_wc_{module}` for all WooCommerce modules.
|
||||
$this->slug = 'et_pb_wc_related_products';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->main_css_element = '%%order_class%%';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'overlay' => et_builder_i18n( 'Overlay' ),
|
||||
'image' => et_builder_i18n( 'Image' ),
|
||||
// Avoid Text suffix by manually defining the `star` toggle slug.
|
||||
'star' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'title' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% section.products > h1, %%order_class%% section.products > h2, %%order_class%% section.products > h3, %%order_class%% section.products > h4, %%order_class%% section.products > h5, %%order_class%% section.products > h6',
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1',
|
||||
),
|
||||
),
|
||||
'rating' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% ul.products li.product .star-rating',
|
||||
'color' => '%%order_class%% li.product .star-rating > span:before',
|
||||
'letter_spacing_hover' => '%%order_class%% ul.products li.product:hover .star-rating',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => 14,
|
||||
),
|
||||
'hide_font' => true,
|
||||
'hide_line_height' => true,
|
||||
'hide_text_shadow' => true,
|
||||
'use_original_label' => true,
|
||||
'text_align' => array(
|
||||
'label' => esc_html__( 'Star Rating Alignment', 'et_builder' ),
|
||||
),
|
||||
'font_size' => array(
|
||||
'label' => esc_html__( 'Star Rating Size', 'et_builder' ),
|
||||
),
|
||||
'text_color' => array(
|
||||
'label' => esc_html__( 'Star Rating Color', 'et_builder' ),
|
||||
),
|
||||
'toggle_slug' => 'star',
|
||||
),
|
||||
'product_title' => array(
|
||||
'label' => esc_html__( 'Product Title', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product h3, {$this->main_css_element} ul.products li.product h1, {$this->main_css_element} ul.products li.product h2, {$this->main_css_element} ul.products li.product h4, {$this->main_css_element} ul.products li.product h5, {$this->main_css_element} ul.products li.product h6",
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1',
|
||||
),
|
||||
),
|
||||
'price' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .price, {$this->main_css_element} ul.products li.product .price .amount",
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'range_settings' => array(
|
||||
'min' => '1',
|
||||
'max' => '100',
|
||||
'step' => '1',
|
||||
),
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
),
|
||||
'sale_badge' => array(
|
||||
'label' => esc_html__( 'Sale Badge', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .onsale",
|
||||
'important' => array( 'line-height', 'font', 'text-shadow' ),
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '20px',
|
||||
),
|
||||
'letter_spacing' => array(
|
||||
'default' => '0px',
|
||||
),
|
||||
),
|
||||
'sale_price' => array(
|
||||
'label' => esc_html__( 'Sale Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .price ins .amount",
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'font' => array(
|
||||
'default' => '|700|||||||',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'range_settings' => array(
|
||||
'min' => '1',
|
||||
'max' => '100',
|
||||
'step' => '1',
|
||||
),
|
||||
'default' => '1.7em',
|
||||
),
|
||||
),
|
||||
),
|
||||
'borders' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%%.et_pb_wc_related_products .product',
|
||||
'border_styles' => '%%order_class%%.et_pb_wc_related_products .product',
|
||||
),
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%%.et_pb_module .et_shop_image',
|
||||
'border_styles' => '%%order_class%%.et_pb_module .et_shop_image',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'label_prefix' => et_builder_i18n( 'Image' ),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
),
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product',
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
|
||||
'option_category' => 'layout',
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_shop_image',
|
||||
'overlay' => 'inset',
|
||||
),
|
||||
'default_on_fronts' => array(
|
||||
'color' => '',
|
||||
'position' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%',
|
||||
|
||||
// Needed to overwrite last module margin-bottom styling.
|
||||
'important' => array( 'custom_margin' ),
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'css' => array(
|
||||
'text_shadow' => implode(
|
||||
', ',
|
||||
array(
|
||||
// Title.
|
||||
"{$this->main_css_element} ul.products h3",
|
||||
"{$this->main_css_element} ul.products h1",
|
||||
"{$this->main_css_element} ul.products h2",
|
||||
"{$this->main_css_element} ul.products h4",
|
||||
"{$this->main_css_element} ul.products h5",
|
||||
"{$this->main_css_element} ul.products h6",
|
||||
// Price.
|
||||
"{$this->main_css_element} ul.products .price",
|
||||
"{$this->main_css_element} ul.products .price .amount",
|
||||
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
'filters' => array(
|
||||
'child_filters_target' => array(
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_shop_image',
|
||||
),
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'product' => array(
|
||||
'label' => esc_html__( 'Product', 'et_builder' ),
|
||||
'selector' => 'li.product',
|
||||
),
|
||||
'onsale' => array(
|
||||
'label' => esc_html__( 'Onsale', 'et_builder' ),
|
||||
'selector' => 'li.product .onsale',
|
||||
),
|
||||
'image' => array(
|
||||
'label' => et_builder_i18n( 'Image' ),
|
||||
'selector' => '.et_shop_image',
|
||||
),
|
||||
'overlay' => array(
|
||||
'label' => et_builder_i18n( 'Overlay' ),
|
||||
'selector' => '.et_overlay',
|
||||
),
|
||||
'title' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'selector' => ET_Builder_Module_Helper_Woocommerce_Modules::get_title_selector(),
|
||||
),
|
||||
'rating' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'selector' => '.star-rating',
|
||||
),
|
||||
'price' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'selector' => 'li.product .price',
|
||||
),
|
||||
'price_old' => array(
|
||||
'label' => esc_html__( 'Old Price', 'et_builder' ),
|
||||
'selector' => 'li.product .price del span.amount',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__related_products',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__related_products',
|
||||
),
|
||||
)
|
||||
),
|
||||
'posts_number' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'posts_number',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default(),
|
||||
'computed_affects' => array(
|
||||
'__related_products',
|
||||
),
|
||||
)
|
||||
),
|
||||
'columns_number' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'columns_number',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default(),
|
||||
'computed_affects' => array(
|
||||
'__related_products',
|
||||
),
|
||||
)
|
||||
),
|
||||
'orderby' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'orderby',
|
||||
array(
|
||||
'options' => array(
|
||||
'default' => esc_html__( 'Random Order', 'et_builder' ),
|
||||
'menu_order' => esc_html__( 'Sort by Menu Order', 'et_builder' ),
|
||||
'popularity' => esc_html__( 'Sort By Popularity', 'et_builder' ),
|
||||
'date' => esc_html__( 'Sort By Date: Oldest To Newest', 'et_builder' ),
|
||||
'date-desc' => esc_html__( 'Sort By Date: Newest To Oldest', 'et_builder' ),
|
||||
'price' => esc_html__( 'Sort By Price: Low To High', 'et_builder' ),
|
||||
'price-desc' => esc_html__( 'Sort By Price: High To Low', 'et_builder' ),
|
||||
),
|
||||
'computed_affects' => array(
|
||||
'__related_products',
|
||||
),
|
||||
)
|
||||
),
|
||||
'sale_badge_color' => array(
|
||||
'label' => esc_html__( 'Sale Badge Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Pick a color to use for the sales bade that appears on products that are on sale.', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'sale_badge',
|
||||
'hover' => 'tabs',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'icon_hover_color' => array(
|
||||
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Pick a color to use for the icon that appears when hovering over a product.', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'hover_overlay_color' => array(
|
||||
'label' => esc_html__( 'Overlay Background Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'hover_icon' => array(
|
||||
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
|
||||
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
|
||||
'type' => 'select_icon',
|
||||
'option_category' => 'configuration',
|
||||
'class' => array( 'et-pb-font-icon' ),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'__related_products' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Related_Products',
|
||||
'get_related_products',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'posts_number',
|
||||
'columns_number',
|
||||
'orderby',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_transition_fields_css_props() {
|
||||
$fields = parent::get_transition_fields_css_props();
|
||||
|
||||
$fields['rating_letter_spacing'] = array(
|
||||
'width' => '%%order_class%% .star-rating',
|
||||
'letter-spacing' => '%%order_class%% .star-rating',
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the related Products.
|
||||
*
|
||||
* Used as a callback to the __related_products computed prop.
|
||||
*
|
||||
* @param array $args Arguments from Computed Prop AJAX call.
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
* @param array $current_page Current page args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_related_products( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
/*
|
||||
* User selected Posts per page, Columns and Order by values are propagated to WooCommerce
|
||||
* using the `woocommerce_output_related_products_args` filter.
|
||||
*
|
||||
* Since we cannot directly pass the `$args` as argument to the filter,
|
||||
* we pass them via a static variable.
|
||||
*/
|
||||
self::$static_props = $args;
|
||||
|
||||
// Force set product's class to ET_Theme_Builder_Woocommerce_Product_Variable_Placeholder
|
||||
// in TB so related product can outputs visible content based on pre-filled value in TB
|
||||
if ( 'true' === et_()->array_get( $conditional_tags, 'is_tb', false ) ) {
|
||||
add_filter( 'woocommerce_product_class', 'et_theme_builder_wc_product_class' );
|
||||
}
|
||||
|
||||
add_filter(
|
||||
'woocommerce_output_related_products_args',
|
||||
array(
|
||||
'ET_Builder_Module_Woocommerce_Related_Products',
|
||||
'set_related_products_args',
|
||||
)
|
||||
);
|
||||
|
||||
$output = et_builder_wc_render_module_template( 'woocommerce_output_related_products', $args );
|
||||
|
||||
remove_filter(
|
||||
'woocommerce_output_related_products_args',
|
||||
array(
|
||||
'ET_Builder_Module_Woocommerce_Related_Products',
|
||||
'set_related_products_args',
|
||||
)
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the User selected Posts per page, columns and Order by values to WooCommerce.
|
||||
*
|
||||
* @param array $args Documented at
|
||||
* {@see woocommerce_output_related_products()}.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function set_related_products_args( $args ) {
|
||||
$selected_args = self::get_selected_related_product_args();
|
||||
|
||||
return wp_parse_args( $selected_args, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the User set Posts per page, columns and Order by values.
|
||||
*
|
||||
* The static variable used in this method is set by
|
||||
*
|
||||
* @see ET_Builder_Module_Woocommerce_Related_Products::get_related_products()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_selected_related_product_args() {
|
||||
$selected_args = array();
|
||||
$selected_args['posts_per_page'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'posts_number',
|
||||
''
|
||||
);
|
||||
$selected_args['columns'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'columns_number',
|
||||
''
|
||||
);
|
||||
$selected_args['orderby'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'orderby',
|
||||
''
|
||||
);
|
||||
|
||||
// Set default values when parameters are empty.
|
||||
$default = ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default_value();
|
||||
if ( empty( $selected_args['posts_per_page'] ) ) {
|
||||
$selected_args['posts_per_page'] = $default;
|
||||
}
|
||||
if ( empty( $selected_args['columns'] ) ) {
|
||||
$selected_args['columns'] = $default;
|
||||
}
|
||||
|
||||
$selected_args = array_filter( $selected_args, 'strlen' );
|
||||
|
||||
if ( isset( $selected_args['orderby'] ) ) {
|
||||
$orderby = $selected_args['orderby'];
|
||||
|
||||
if ( in_array( $orderby, array( 'price-desc', 'date-desc' ), true ) ) {
|
||||
/*
|
||||
* For the list of all allowed Orderby values, refer
|
||||
*
|
||||
* @see wc_products_array_orderby
|
||||
*/
|
||||
$selected_args['orderby'] = str_replace( '-desc', '', $orderby );
|
||||
} else {
|
||||
/*
|
||||
* Implicitly specify when ascending is required since `desc` is the default value.
|
||||
*
|
||||
* @see woocommerce_related_products()
|
||||
*/
|
||||
$selected_args['order'] = 'asc';
|
||||
}
|
||||
}
|
||||
|
||||
return $selected_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @since 4.1.0 Show only Products irrespective of Customizer Product Catalog setting on Shop page.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::add_star_rating_style(
|
||||
$render_slug,
|
||||
$this->props,
|
||||
'%%order_class%% ul.products li.product .star-rating',
|
||||
'%%order_class%% ul.products li.product:hover .star-rating'
|
||||
);
|
||||
|
||||
// Sale Badge Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'base_attr_name' => 'sale_badge_color',
|
||||
'selector' => '%%order_class%% span.onsale',
|
||||
'css_property' => 'background-color',
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Icon Hover Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'hover' => false,
|
||||
'base_attr_name' => 'icon_hover_color',
|
||||
'selector' => '%%order_class%% .et_overlay:before, %%order_class%% .et_pb_extra_overlay:before',
|
||||
'css_property' => 'color',
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Hover Overlay Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'hover' => false,
|
||||
'base_attr_name' => 'hover_overlay_color',
|
||||
'selector' => '%%order_class%% .et_overlay, %%order_class%% .et_pb_extra_overlay',
|
||||
'css_property' => array( 'background-color', 'border-color' ),
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Overlay Icon Styles.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'hover' => false,
|
||||
'utility_arg' => 'icon_font_family',
|
||||
'render_slug' => $render_slug,
|
||||
'base_attr_name' => 'hover_icon',
|
||||
'important' => true,
|
||||
'selector' => '%%order_class%% .et_overlay:before',
|
||||
'processor' => array(
|
||||
'ET_Builder_Module_Helper_Style_Processor',
|
||||
'process_extended_icon',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Images: Add CSS Filters and Mix Blend Mode rules (if set).
|
||||
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
|
||||
$this->add_classname(
|
||||
$this->generate_css_filters(
|
||||
$render_slug,
|
||||
'child_',
|
||||
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$is_shop = function_exists( 'is_shop' ) && is_shop();
|
||||
$is_wc_loop_prop_get_set_exists = function_exists( 'wc_get_loop_prop' ) && function_exists( 'wc_set_loop_prop' );
|
||||
$is_product_category = function_exists( 'is_product_category' ) && is_product_category();
|
||||
|
||||
if ( $is_shop ) {
|
||||
$display_type = ET_Builder_Module_Helper_Woocommerce_Modules::set_display_type_to_render_only_products( 'woocommerce_shop_page_display' );
|
||||
} elseif ( $is_product_category ) {
|
||||
$display_type = ET_Builder_Module_Helper_Woocommerce_Modules::set_display_type_to_render_only_products( 'woocommerce_category_archive_display' );
|
||||
}
|
||||
|
||||
// Required to handle Customizer preview pane.
|
||||
// Refer: https://github.com/elegantthemes/Divi/issues/17998#issuecomment-565955422
|
||||
if ( $is_wc_loop_prop_get_set_exists && is_customize_preview() ) {
|
||||
$is_filtered = wc_get_loop_prop( 'is_filtered' );
|
||||
wc_set_loop_prop( 'is_filtered', true );
|
||||
}
|
||||
|
||||
$output = self::get_related_products( $this->props );
|
||||
|
||||
// Required to handle Customizer preview pane.
|
||||
// Refer: https://github.com/elegantthemes/Divi/issues/17998#issuecomment-565955422
|
||||
if ( $is_wc_loop_prop_get_set_exists && is_customize_preview() && isset( $is_filtered ) ) {
|
||||
wc_set_loop_prop( 'is_filtered', $is_filtered );
|
||||
}
|
||||
|
||||
if ( $is_shop && isset( $display_type ) ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::reset_display_type( 'woocommerce_shop_page_display', $display_type );
|
||||
} elseif ( $is_product_category && isset( $display_type ) ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::reset_display_type( 'woocommerce_category_archive_display', $display_type );
|
||||
}
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
add_filter(
|
||||
"et_builder_module_{$render_slug}_outer_wrapper_attrs",
|
||||
array(
|
||||
'ET_Builder_Module_Helper_Woocommerce_Modules',
|
||||
'output_data_icon_attrs',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
$output = $this->_render_module_wrapper( $output, $render_slug );
|
||||
|
||||
remove_filter(
|
||||
"et_builder_module_{$render_slug}_outer_wrapper_attrs",
|
||||
array(
|
||||
'ET_Builder_Module_Helper_Woocommerce_Modules',
|
||||
'output_data_icon_attrs',
|
||||
),
|
||||
10
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Related_Products();
|
490
includes/builder/module/woocommerce/Reviews.php
Normal file
490
includes/builder/module/woocommerce/Reviews.php
Normal file
@ -0,0 +1,490 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Reviews class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Reviews Class is responsible for rendering the
|
||||
* Reviews markup.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
if ( ! class_exists( 'ET_Builder_Module_Gallery' ) ) {
|
||||
require_once ET_BUILDER_DIR_RESOLVED_PATH . '/module/Comments.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Reviews component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Reviews extends ET_Builder_Module_Comments {
|
||||
/**
|
||||
* Modify properties defined on base module's (comment) init()
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public function init() {
|
||||
parent::init();
|
||||
|
||||
// Define basic module information.
|
||||
$this->name = esc_html__( 'Woo Reviews', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Reviews', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_reviews';
|
||||
|
||||
// Modify toggle settings.
|
||||
$this->settings_modal_toggles['general']['toggles']['main_content'] = array(
|
||||
'title' => et_builder_i18n( 'Content' ),
|
||||
'priority' => 1,
|
||||
);
|
||||
|
||||
$this->settings_modal_toggles['advanced']['toggles']['rating'] = array(
|
||||
'title' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'priority' => 60,
|
||||
);
|
||||
|
||||
$this->settings_modal_toggles['advanced']['toggles']['image'] = array(
|
||||
'title' => et_builder_i18n( 'Image' ),
|
||||
'priority' => 30,
|
||||
);
|
||||
|
||||
// Modify advanced field settings.
|
||||
$this->advanced_fields['fonts']['header']['label'] = esc_html__( 'Review Count', 'et_builder' );
|
||||
$this->advanced_fields['fonts']['header']['header_level']['default'] = 'h2';
|
||||
$this->advanced_fields['fonts']['header']['header_level']['computed_affects'] = array(
|
||||
'__reviews',
|
||||
);
|
||||
$this->advanced_fields['fonts']['header']['font_size'] = array(
|
||||
'default' => '26px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['header']['line_height'] = array(
|
||||
'default' => '1em',
|
||||
);
|
||||
$this->advanced_fields['fonts']['title']['font_size'] = array(
|
||||
'default' => '14px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['title']['line_height'] = array(
|
||||
'default' => '1.7em',
|
||||
);
|
||||
$this->advanced_fields['fonts']['header']['css']['main'] = "{$this->main_css_element} h1.woocommerce-Reviews-title, {$this->main_css_element} h2.woocommerce-Reviews-title, {$this->main_css_element} h3.woocommerce-Reviews-title, {$this->main_css_element} h4.woocommerce-Reviews-title, {$this->main_css_element} h5.woocommerce-Reviews-title, {$this->main_css_element} h6.woocommerce-Reviews-title";
|
||||
$this->advanced_fields['fonts']['meta']['css']['main'] = "{$this->main_css_element} #reviews #comments ol.commentlist li .comment-text p.meta, %%order_class%% .comment-form-rating label";
|
||||
$this->advanced_fields['fonts']['meta']['hide_text_align'] = true;
|
||||
$this->advanced_fields['fonts']['body']['css']['main'] = "{$this->main_css_element} .comment-text .description";
|
||||
$this->advanced_fields['fonts']['rating'] = array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars a',
|
||||
'letter_spacing' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars',
|
||||
'letter_spacing_hover' => '%%order_class%% .star-rating:hover, %%order_class%% .comment-form-rating p.stars:hover',
|
||||
'color' => '%%order_class%% .star-rating > span:before, %%order_class%% .comment-form-rating p.stars a',
|
||||
'color_hover' => '%%order_class%% .star-rating:hover > span:before, %%order_class%% .comment-form-rating p.stars:hover a',
|
||||
'main' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars a',
|
||||
'text_align' => '%%order_class%% .comment-form-rating p.stars',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => 14,
|
||||
),
|
||||
'hide_font' => true,
|
||||
'hide_line_height' => true,
|
||||
'hide_text_shadow' => true,
|
||||
);
|
||||
$this->advanced_fields['borders']['image']['css']['main']['border_radii'] = '%%order_class%%.et_pb_wc_reviews #reviews #comments ol.commentlist li img.avatar';
|
||||
$this->advanced_fields['borders']['image']['css']['main']['border_styles'] = '%%order_class%%.et_pb_wc_reviews #reviews #comments ol.commentlist li img.avatar';
|
||||
$this->advanced_fields['box_shadow']['image']['css']['main'] = '%%order_class%%.et_pb_wc_reviews #reviews #comments ol.commentlist li img.avatar';
|
||||
$this->advanced_fields['image']['css']['main'] = '%%order_class%%.et_pb_wc_reviews #reviews #comments ol.commentlist li img.avatar';
|
||||
|
||||
$this->advanced_fields['form_field']['form_field']['font_field']['css']['main'] = "{$this->main_css_element} #commentform textarea, {$this->main_css_element} #commentform input[type='text'], {$this->main_css_element} #commentform input[type='email'], {$this->main_css_element} #commentform input[type='url']";
|
||||
$this->advanced_fields['form_field']['form_field']['font_field']['font_size'] = array(
|
||||
'default' => '18px',
|
||||
);
|
||||
|
||||
// Disable form title heading level because it uses span tag.
|
||||
unset( $this->advanced_fields['fonts']['title']['header_level'] );
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'main_header' => array(
|
||||
'label' => esc_html__( 'Reviews Count', 'et_builder' ),
|
||||
'selector' => '.woocommerce-Reviews-title',
|
||||
),
|
||||
'comment_body' => array(
|
||||
'label' => esc_html__( 'Review Body', 'et_builder' ),
|
||||
'selector' => '.comment_container',
|
||||
),
|
||||
'comment_meta' => array(
|
||||
'label' => esc_html__( 'Review Meta', 'et_builder' ),
|
||||
'selector' => '#reviews #comments ol.commentlist li .comment-text p.meta',
|
||||
),
|
||||
'comment_content' => array(
|
||||
'label' => esc_html__( 'Review Rating', 'et_builder' ),
|
||||
'selector' => '.comment-form-rating',
|
||||
),
|
||||
'comment_avatar' => array(
|
||||
'label' => esc_html__( 'Review Avatar', 'et_builder' ),
|
||||
'selector' => '#reviews #comments ol.commentlist li img.avatar',
|
||||
),
|
||||
'new_title' => array(
|
||||
'label' => esc_html__( 'New Review Title', 'et_builder' ),
|
||||
'selector' => '#reply-title',
|
||||
),
|
||||
'message_field' => array(
|
||||
'label' => esc_html__( 'Message Field', 'et_builder' ),
|
||||
'selector' => '.comment-form-comment textarea#comment',
|
||||
),
|
||||
'name_field' => array(
|
||||
'label' => esc_html__( 'Name Field', 'et_builder' ),
|
||||
'selector' => '.comment-form-author input#author',
|
||||
),
|
||||
'email_field' => array(
|
||||
'label' => esc_html__( 'Email Field', 'et_builder' ),
|
||||
'selector' => '.comment-form-email input#email',
|
||||
),
|
||||
'submit_button' => array(
|
||||
'label' => esc_html__( 'Submit Button', 'et_builder' ),
|
||||
'selector' => '#submit',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
|
||||
// Insert classname to module wrapper.
|
||||
add_filter(
|
||||
'et_builder_wc_reviews_classes',
|
||||
array(
|
||||
$this,
|
||||
'add_wc_reviews_classname',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Insert Woo Reviews specific fields and modify fields inherited from base module (comments).
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_fields() {
|
||||
$et_accent_color = et_builder_accent_color();
|
||||
|
||||
// Get base module (comment)'s fields.
|
||||
$fields = parent::get_fields();
|
||||
|
||||
$fields['product'] = ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__reviews',
|
||||
),
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
)
|
||||
);
|
||||
$fields['product_filter'] = ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__reviews',
|
||||
),
|
||||
)
|
||||
);
|
||||
$fields['__reviews'] = array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Reviews',
|
||||
'get_reviews_html',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'header_level',
|
||||
),
|
||||
);
|
||||
|
||||
/*
|
||||
* Modify base module (comment) fields; These fields can't be hidden because Woo Reviews
|
||||
* uses base module's `render()` method which it expects
|
||||
* `$this->props['show_reply']` to exist
|
||||
*/
|
||||
$fields['show_reply']['type'] = 'hidden';
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_transition_fields_css_props() {
|
||||
$fields = parent::get_transition_fields_css_props();
|
||||
|
||||
$fields['rating_letter_spacing'] = array(
|
||||
'font-size' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars',
|
||||
'width' => '%%order_class%% .star-rating',
|
||||
'letter-spacing' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars',
|
||||
);
|
||||
$fields['rating_font_size'] = array(
|
||||
'font-size' => '%%order_class%% .star-rating, %%order_class%% .comment-form-rating p.stars a',
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get reviews HTML.
|
||||
*
|
||||
* @param array $args Arguments from Computed Prop AJAX call.
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
* @param array $current_page Current page args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reviews_html( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
$maybe_product_id = 'current';
|
||||
|
||||
$defaults = array(
|
||||
'header_level' => 'h2',
|
||||
);
|
||||
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// Get correct product ID when current request is computed callback request.
|
||||
if ( ET_Builder_Element::get_current_post_id() && ! et_builder_tb_enabled() ) {
|
||||
$maybe_product_id = ET_Builder_Element::get_current_post_id();
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'id', $current_page ) ) {
|
||||
$maybe_product_id = $current_page['id'];
|
||||
}
|
||||
|
||||
if ( array_key_exists( 'product', $args ) && ! empty( $args['product'] ) ) {
|
||||
$maybe_product_id = $args['product'];
|
||||
}
|
||||
|
||||
$is_tb = et_builder_tb_enabled();
|
||||
|
||||
if ( $is_tb ) {
|
||||
global $product;
|
||||
|
||||
et_theme_builder_wc_set_global_objects();
|
||||
} else {
|
||||
$product = ET_Builder_Module_Helper_Woocommerce_Modules::get_product( $maybe_product_id );
|
||||
}
|
||||
|
||||
if ( ! ( $product instanceof WC_Product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$reviews_markup = self::get_reviews_markup( $product, $args['header_level'], true );
|
||||
|
||||
if ( $is_tb ) {
|
||||
et_theme_builder_wc_reset_global_objects();
|
||||
}
|
||||
|
||||
return $reviews_markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Reviews markup.
|
||||
*
|
||||
* This includes the Reviews and the Review comment form.
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param WC_Product $product WooCommerce Product.
|
||||
* @param string $header_level Heading level.
|
||||
* @param bool $is_ajax Should be set to TRUE when used in AJAX call for proper
|
||||
* results.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_reviews_markup( $product, $header_level, $is_ajax = false ) {
|
||||
if ( ! ( $product instanceof WC_Product ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( ! comments_open( $product->get_id() ) ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$reviews_title = ET_Builder_Module_Helper_Woocommerce_Modules::get_reviews_title( $product );
|
||||
// Product could be changed using the Product filter in the Settings modal.
|
||||
// Hence supplying the Product ID to fetch data based on the selected Product.
|
||||
$reviews = get_comments(
|
||||
array(
|
||||
'post_id' => $product->get_id(),
|
||||
'status' => 'approve',
|
||||
)
|
||||
);
|
||||
$total_pages = get_comment_pages_count( $reviews );
|
||||
$reviews_content = wp_list_comments(
|
||||
array(
|
||||
'callback' => 'woocommerce_comments',
|
||||
'echo' => false,
|
||||
),
|
||||
$reviews
|
||||
);
|
||||
|
||||
// Supply the `$total_pages` var. Otherwise $pagination would always be empty.
|
||||
if ( $is_ajax ) {
|
||||
$page = get_query_var( 'cpage' );
|
||||
if ( ! $page ) {
|
||||
$page = 1;
|
||||
}
|
||||
$args = array(
|
||||
'base' => add_query_arg( 'cpage', '%#%' ),
|
||||
'format' => '',
|
||||
'total' => $total_pages,
|
||||
'current' => $page,
|
||||
'echo' => false,
|
||||
'add_fragment' => '#comments',
|
||||
'type' => 'list',
|
||||
);
|
||||
global $wp_rewrite;
|
||||
if ( $wp_rewrite->using_permalinks() ) {
|
||||
$args['base'] = user_trailingslashit( trailingslashit( get_permalink() ) . $wp_rewrite->comments_pagination_base . '-%#%', 'commentpaged' );
|
||||
}
|
||||
|
||||
$pagination = paginate_links( $args );
|
||||
} else {
|
||||
$pagination = paginate_comments_links(
|
||||
array(
|
||||
'echo' => false,
|
||||
'type' => 'list',
|
||||
'total' => $total_pages,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Pass $product, $reviews to unify the flow of data.
|
||||
$reviews_comment_form = ET_Builder_Module_Helper_Woocommerce_Modules::get_reviews_comment_form( $product, $reviews );
|
||||
|
||||
return sprintf(
|
||||
'
|
||||
<div id="reviews" class="woocommerce-Reviews">
|
||||
<div id="comments">
|
||||
<%3$s class="woocommerce-Reviews-title">
|
||||
%1$s
|
||||
</%3$s>
|
||||
<ol class="commentlist">
|
||||
%2$s
|
||||
</ol>
|
||||
<nav class="woocommerce-pagination">
|
||||
%4$s
|
||||
</nav>
|
||||
</div>
|
||||
<div id="review_form_wrapper">
|
||||
%5$s
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
',
|
||||
/* 1$s */
|
||||
$reviews_title,
|
||||
/* 2$s */
|
||||
$reviews_content,
|
||||
/* 3$s */
|
||||
$header_level,
|
||||
/* 4$s */
|
||||
$pagination,
|
||||
/* 5$s */
|
||||
$reviews_comment_form
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add classname into module wrapper.
|
||||
*
|
||||
* @param array $classname List of class names.
|
||||
* @param int $render_count Count of times the module is rendered.
|
||||
*/
|
||||
public function add_wc_reviews_classname( $classname, $render_count ) {
|
||||
/*
|
||||
* Woo Reviews can't add `et_pb_wc_reviews` via `$this->add_classname()` method because
|
||||
* comments module specifically remove slug classname at the end of its rendering process
|
||||
* {@link https://github.com/elegantthemes/submodule-builder/pull/2910/files#diff-832b621946ab4f4dee33ddbf442d0225R348}
|
||||
*/
|
||||
$classname[] = $this->slug;
|
||||
|
||||
return $classname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove action and filter hook performed before comment contents rendering by extending
|
||||
* the method because Woo Reviews doesn't need it
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public function before_comments_content() {
|
||||
/* intentionally empty*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Render review (comments) content
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public function get_comments_content() {
|
||||
$header_level = $this->props['header_level'];
|
||||
$product = $this->props['product'];
|
||||
$verified_product = ET_Builder_Module_Helper_Woocommerce_Modules::get_product( $product );
|
||||
|
||||
return self::get_reviews_markup(
|
||||
$verified_product,
|
||||
et_pb_process_header_level( $header_level, 'h2' )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove action and filter hook performed before comment contents rendering by extending
|
||||
* the method because Woo Reviews doesn't need it.
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
public function after_comments_content() {
|
||||
/* intentionally empty*/
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
// Image - CSS Filters.
|
||||
if ( et_()->array_get( $this->advanced_fields, 'image.css', false ) ) {
|
||||
$classes = $this->generate_css_filters( $this->slug, 'child_', et_()->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' ) );
|
||||
$this->add_classname( $classes );
|
||||
}
|
||||
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::add_star_rating_style(
|
||||
$render_slug,
|
||||
$this->props,
|
||||
'%%order_class%% .star-rating',
|
||||
'%%order_class%% .star-rating:hover'
|
||||
);
|
||||
|
||||
// Fixes right text alignment of review form star rating. By default, WC adds text-indent -999em to
|
||||
// hide the original rating number. However, it causes an issue if the alignment is set to right
|
||||
// position. We should push the rating value to the right side and hide the overflow.
|
||||
$rating_alignments = array();
|
||||
$rating_alignment_values = et_pb_responsive_options()->get_property_values( $this->props, 'rating_text_align' );
|
||||
foreach ( $rating_alignment_values as $mode => $value ) {
|
||||
// Should be added only when the alignment is right.
|
||||
if ( 'right' !== $value ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$rating_alignments[ $mode ] = 'overflow: hidden; text-indent: 999em;';
|
||||
}
|
||||
|
||||
// Generate style for desktop, tablet, and phone.
|
||||
et_pb_responsive_options()->declare_responsive_css(
|
||||
$rating_alignments,
|
||||
'%%order_class%% p.stars a',
|
||||
$render_slug
|
||||
);
|
||||
|
||||
return parent::render( $attrs, $content, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Reviews();
|
205
includes/builder/module/woocommerce/Stock.php
Normal file
205
includes/builder/module/woocommerce/Stock.php
Normal file
@ -0,0 +1,205 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Stock class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Stock Class is responsible for rendering the
|
||||
* Stock markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Stock component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Stock extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Stock', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Stock', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_stock';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'instock' => array(
|
||||
'label' => esc_html__( 'In Stock', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_pb_module_inner .stock.in-stock',
|
||||
'plugin_main' => '%%order_class%% .in-stock, %%order_class%% .in-stock a, %%order_class%% .in-stock span',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '13px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
),
|
||||
'outofstock' => array(
|
||||
'label' => esc_html__( 'Out Of Stock', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_pb_module_inner .stock.out-of-stock',
|
||||
'plugin_main' => '%%order_class%% .out-of-stock, %%order_class%% .out-of-stock a, %%order_class%% .out-of-stock span',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '13px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
),
|
||||
'onbackorder' => array(
|
||||
'label' => esc_html__( 'On Backorder', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .available-on-backorder',
|
||||
'plugin_main' => '%%order_class%% .available-on-backorder, %%order_class%% .available-on-backorder a, %%order_class%% .available-on-backorder span',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '13px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'instock_text' => array(
|
||||
'label' => esc_html__( 'In Stock Text', 'et_builder' ),
|
||||
'selector' => '.in-stock',
|
||||
),
|
||||
'outofstock_text' => array(
|
||||
'label' => esc_html__( 'Out of Stock Text', 'et_builder' ),
|
||||
'selector' => '.out-of-stock',
|
||||
),
|
||||
'backorder_text' => array(
|
||||
'label' => esc_html__( 'On Backorder Text', 'et_builder' ),
|
||||
'selector' => '.available-on-backorder',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__stock',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__stock',
|
||||
),
|
||||
)
|
||||
),
|
||||
'__stock' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Stock',
|
||||
'get_stock',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get stock output
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_stock( $args = array() ) {
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
$rating = et_builder_wc_render_module_template(
|
||||
'wc_get_stock_html',
|
||||
$args
|
||||
);
|
||||
|
||||
return $rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$output = self::get_stock( $this->props );
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Stock();
|
453
includes/builder/module/woocommerce/Tabs.php
Normal file
453
includes/builder/module/woocommerce/Tabs.php
Normal file
@ -0,0 +1,453 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Tabs class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Tabs Class is responsible for rendering the
|
||||
* Tabs markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
if ( ! class_exists( 'ET_Builder_Module_Tabs' ) ) {
|
||||
require_once ET_BUILDER_DIR_RESOLVED_PATH . '/module/Tabs.php';
|
||||
}
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Add to cart component.
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Tabs extends ET_Builder_Module_Tabs {
|
||||
/**
|
||||
* Define WooCommerce Tabs property.
|
||||
*/
|
||||
public function init() {
|
||||
// Inherit tabs module property.
|
||||
parent::init();
|
||||
|
||||
// Define WooCommerce Tabs module property; overwriting inherited property.
|
||||
$this->name = esc_html__( 'Woo Tabs', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Tabs', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_tabs';
|
||||
|
||||
/*
|
||||
* Set property for holding rendering data so the data rendering via
|
||||
* ET_Builder_Module_Woocommerce_Tabs::get_tabs() is only need to be done once.
|
||||
*/
|
||||
$this->rendered_tabs_data = array();
|
||||
|
||||
// Remove module item.
|
||||
$this->child_slug = null;
|
||||
$this->child_item_text = null;
|
||||
|
||||
// Set WooCommerce Tabs specific toggle / options group.
|
||||
$this->settings_modal_toggles['general']['toggles']['main_content'] = array(
|
||||
'title' => et_builder_i18n( 'Content' ),
|
||||
'priority' => 10,
|
||||
);
|
||||
|
||||
$this->advanced_fields['fonts']['tab']['font_size'] = array(
|
||||
'default' => '14px',
|
||||
);
|
||||
$this->advanced_fields['fonts']['tab']['line_height'] = array(
|
||||
'default' => '1.7em',
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product all possible tabs data
|
||||
*
|
||||
* @since 3.29
|
||||
* @since 4.4.2 Fix to include Custom tabs.
|
||||
*
|
||||
* @global WP_Post $post WordPress Post.
|
||||
* @global WC_Product $product WooCommerce Product.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_product_tabs() {
|
||||
static $tabs = null;
|
||||
|
||||
if ( ! is_null( $tabs ) ) {
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
global $post, $product;
|
||||
|
||||
// Save existing $post and $product global.
|
||||
$original_post = $post;
|
||||
$original_product = $product;
|
||||
|
||||
$post_id = 'product' === $this->get_post_type()
|
||||
? ET_Builder_Element::get_current_post_id()
|
||||
: ET_Builder_Module_Helper_Woocommerce_Modules::get_product_id( 'latest' );
|
||||
|
||||
// Overwriting global $post is necessary as WooCommerce relies on it.
|
||||
$post = get_post( $post_id );
|
||||
$product = wc_get_product( $post_id );
|
||||
|
||||
/*
|
||||
* Get relevant product tabs data. Product tabs hooks use global based conditional
|
||||
* for adding / removing product tabs data via filter hoook callback, hence the
|
||||
* need to overwrite the global for determining product tabs data
|
||||
*/
|
||||
$tabs = is_object( $product )
|
||||
? apply_filters( 'woocommerce_product_tabs', array() )
|
||||
: ET_Builder_Module_Helper_Woocommerce_Modules::get_default_product_tabs();
|
||||
|
||||
// Reset $post and $product global.
|
||||
$post = $original_post;
|
||||
$product = $original_product;
|
||||
|
||||
/*
|
||||
* Always return all possible tabs
|
||||
*/
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product tabs options; product data formatted for checkbox control's options
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_tab_options() {
|
||||
$tabs = $this->get_product_tabs();
|
||||
$options = array();
|
||||
|
||||
foreach ( $tabs as $name => $tab ) {
|
||||
if ( ! isset( $tab['title'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$options[ $name ] = array(
|
||||
'value' => $name,
|
||||
'label' => 'reviews' === $name ? esc_html__( 'Reviews', 'et_builder' ) :
|
||||
esc_html( $tab['title'] ),
|
||||
);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product tabs default based on product tabs options
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_tab_defaults() {
|
||||
return implode( '|', array_keys( $this->get_product_tabs() ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Define Woo Tabs fields
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array_merge(
|
||||
parent::get_fields(),
|
||||
array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__tabs',
|
||||
'include_tabs',
|
||||
),
|
||||
)
|
||||
),
|
||||
'include_tabs' => array(
|
||||
'label' => esc_html__( 'Include Tabs', 'et_builder' ),
|
||||
'type' => 'checkboxes_advanced_woocommerce',
|
||||
'option_category' => 'configuration',
|
||||
'default' =>
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::get_woo_default_tabs(),
|
||||
'description' => esc_html__( 'Here you can select the tabs that you would like to display.', 'et_builder' ),
|
||||
'toggle_slug' => 'main_content',
|
||||
'mobile_options' => true,
|
||||
'hover' => 'tabs',
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
'__tabs' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Tabs',
|
||||
'get_tabs',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabs nav output
|
||||
*
|
||||
* @since 3.29
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_tabs_nav() {
|
||||
$nav = '';
|
||||
$index = 0;
|
||||
|
||||
// get_tabs_content() method is called earlier so get_tabs_nav() can reuse tabs data.
|
||||
if ( ! empty( $this->rendered_tabs_data ) ) {
|
||||
foreach ( $this->rendered_tabs_data as $name => $tab ) {
|
||||
$index ++;
|
||||
|
||||
$nav .= sprintf(
|
||||
'<li class="%3$s%1$s"><a href="#tab-%4$s">%2$s</a></li>',
|
||||
( 1 === $index ? ' et_pb_tab_active' : '' ),
|
||||
esc_html( $tab['title'] ),
|
||||
sprintf( '%1$s_tab', esc_attr( $name ) ),
|
||||
esc_attr( $name )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $nav;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabs content output
|
||||
*
|
||||
* @since 4.4.1 Fix [embed][/embed] shortcodes not working in tab content
|
||||
* @since 3.29
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_tabs_content() {
|
||||
// Get tabs data.
|
||||
$this->rendered_tabs_data = self::get_tabs(
|
||||
array(
|
||||
'product' => $this->props['product'],
|
||||
'include_tabs' => $this->props['include_tabs'],
|
||||
)
|
||||
);
|
||||
|
||||
// Add tabs module classname.
|
||||
$this->add_classname( 'et_pb_tabs' );
|
||||
|
||||
// Render tabs content output.
|
||||
$index = 0;
|
||||
$content = '';
|
||||
|
||||
foreach ( $this->rendered_tabs_data as $name => $tab ) {
|
||||
$index ++;
|
||||
|
||||
$content .= sprintf(
|
||||
'<div class="et_pb_tab clearfix%2$s">
|
||||
<div class="et_pb_tab_content">
|
||||
%1$s
|
||||
</div>
|
||||
</div>',
|
||||
$tab['content'],
|
||||
1 === $index ? ' et_pb_active_content' : ''
|
||||
);
|
||||
}
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load comments template.
|
||||
*
|
||||
* @param string $template template to load.
|
||||
* @return string
|
||||
*/
|
||||
public static function comments_template_loader( $template ) {
|
||||
if ( ! et_builder_tb_enabled() ) {
|
||||
return $template;
|
||||
}
|
||||
|
||||
$check_dirs = array(
|
||||
trailingslashit( get_stylesheet_directory() ) . WC()->template_path(),
|
||||
trailingslashit( get_template_directory() ) . WC()->template_path(),
|
||||
trailingslashit( get_stylesheet_directory() ),
|
||||
trailingslashit( get_template_directory() ),
|
||||
trailingslashit( WC()->plugin_path() ) . 'templates/',
|
||||
);
|
||||
|
||||
if ( WC_TEMPLATE_DEBUG_MODE ) {
|
||||
$check_dirs = array( array_pop( $check_dirs ) );
|
||||
}
|
||||
|
||||
foreach ( $check_dirs as $dir ) {
|
||||
if ( file_exists( trailingslashit( $dir ) . 'single-product-reviews.php' ) ) {
|
||||
return trailingslashit( $dir ) . 'single-product-reviews.php';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tabs data
|
||||
*
|
||||
* @since 4.0.9 Avoid fetching Tabs content using `the_content` when editing TB layout.
|
||||
*
|
||||
* @param array $args Additional args.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_tabs( $args = array() ) {
|
||||
global $product, $post, $wp_query;
|
||||
|
||||
/*
|
||||
* Visual builder fetches all tabs data and filter the included tab on the app to save
|
||||
* app to server request for faster user experience. Frontend passes `includes_tab` to
|
||||
* this method so it only process required tabs
|
||||
*/
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
|
||||
// Get actual product id based on given `product` attribute.
|
||||
$product_id = ET_Builder_Module_Helper_Woocommerce_Modules::get_product_id( $args['product'] );
|
||||
|
||||
// Determine whether current tabs data needs global variable overwrite or not.
|
||||
$overwrite_global = et_builder_wc_need_overwrite_global( $args['product'] );
|
||||
|
||||
// Check if TB is used
|
||||
$is_tb = et_builder_tb_enabled();
|
||||
|
||||
if ( $is_tb ) {
|
||||
et_theme_builder_wc_set_global_objects();
|
||||
} elseif ( $overwrite_global ) {
|
||||
// Save current global variable for later reset.
|
||||
$original_product = $product;
|
||||
$original_post = $post;
|
||||
$original_wp_query = $wp_query;
|
||||
|
||||
// Overwrite global variable.
|
||||
$post = get_post( $product_id );
|
||||
$product = wc_get_product( $product_id );
|
||||
$wp_query = new WP_Query( array( 'p' => $product_id ) );
|
||||
}
|
||||
|
||||
// Get product tabs.
|
||||
$all_tabs = apply_filters( 'woocommerce_product_tabs', array() );
|
||||
$active_tabs = isset( $args['include_tabs'] ) ? explode( '|', $args['include_tabs'] ) : false;
|
||||
$tabs = array();
|
||||
|
||||
// Get product tabs data.
|
||||
foreach ( $all_tabs as $name => $tab ) {
|
||||
// Skip if current tab is not included, based on `include_tabs` attribute value.
|
||||
if ( $active_tabs && ! in_array( $name, $active_tabs, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'description' === $name ) {
|
||||
if ( ! et_builder_tb_enabled() && ! et_pb_is_pagebuilder_used( $product_id ) ) {
|
||||
// If selected product doesn't use builder, retrieve post content.
|
||||
if ( et_theme_builder_overrides_layout( ET_THEME_BUILDER_BODY_LAYOUT_POST_TYPE ) ) {
|
||||
$tab_content = apply_filters( 'et_builder_wc_description', $post->post_content );
|
||||
} else {
|
||||
$tab_content = $post->post_content;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Description can't use built in callback data because it gets `the_content`
|
||||
* which might cause infinite loop; get Divi's long description from
|
||||
* post meta instead.
|
||||
*/
|
||||
if ( et_builder_tb_enabled() ) {
|
||||
$placeholders = et_theme_builder_wc_placeholders();
|
||||
|
||||
$tab_content = $placeholders['description'];
|
||||
} else {
|
||||
$tab_content = get_post_meta( $product_id, ET_BUILDER_WC_PRODUCT_LONG_DESC_META_KEY, true );
|
||||
|
||||
// Cannot use `the_content` filter since it adds content wrapper.
|
||||
// Content wrapper added at
|
||||
// `includes/builder/core.php`::et_builder_add_builder_content_wrapper()
|
||||
// This filter is documented at
|
||||
// includes/builder/feature/woocommerce-modules.php
|
||||
$tab_content = apply_filters( 'et_builder_wc_description', $tab_content );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Skip if the 'callback' key does not exist.
|
||||
if ( ! isset( $tab['callback'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get tab value based on defined product tab's callback attribute.
|
||||
ob_start();
|
||||
// @phpcs:ignore Generic.PHP.ForbiddenFunctions.Found
|
||||
call_user_func( $tab['callback'], $name, $tab );
|
||||
$tab_content = ob_get_clean();
|
||||
}
|
||||
|
||||
// Populate product tab data.
|
||||
$tabs[ $name ] = array(
|
||||
'name' => $name,
|
||||
'title' => $tab['title'],
|
||||
'content' => $tab_content,
|
||||
);
|
||||
}
|
||||
|
||||
// Reset overwritten global variable.
|
||||
if ( $is_tb ) {
|
||||
et_theme_builder_wc_reset_global_objects();
|
||||
} elseif ( $overwrite_global ) {
|
||||
$product = $original_product;
|
||||
$post = $original_post;
|
||||
$wp_query = $original_wp_query;
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets Multi view attributes to the Outer wrapper.
|
||||
*
|
||||
* Since we do not have control over the WooCommerce Breadcrumb markup, we inject Multi view
|
||||
* attributes on to the Outer wrapper.
|
||||
*
|
||||
* @used-by ET_Builder_Module_Tabs::render()
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_multi_view_attrs() {
|
||||
$multi_view = et_pb_multi_view_options( $this );
|
||||
|
||||
$multi_view_attrs = $multi_view->render_attrs(
|
||||
array(
|
||||
'attrs' => array(
|
||||
'data-include_tabs' => '{{include_tabs}}',
|
||||
),
|
||||
'target' => '%%order_class%%',
|
||||
)
|
||||
);
|
||||
|
||||
return $multi_view_attrs;
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Tabs();
|
214
includes/builder/module/woocommerce/Title.php
Normal file
214
includes/builder/module/woocommerce/Title.php
Normal file
@ -0,0 +1,214 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Title class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Title Class is responsible for rendering the
|
||||
* Title markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Title component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Title extends ET_Builder_Module {
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Title', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Titles', 'et_builder' );
|
||||
$this->slug = 'et_pb_wc_title';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'header' => array(
|
||||
'title' => esc_html__( 'Title Text', 'et_builder' ),
|
||||
'priority' => 49,
|
||||
),
|
||||
'width' => array(
|
||||
'title' => et_builder_i18n( 'Sizing' ),
|
||||
'priority' => 65,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'header' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% h1, %%order_class%% h2, %%order_class%% h3, %%order_class%% h4, %%order_class%% h5, %%order_class%% h6',
|
||||
),
|
||||
'header_level' => array(
|
||||
'default' => 'h1',
|
||||
),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'header',
|
||||
),
|
||||
),
|
||||
'background' => array(
|
||||
'settings' => array(
|
||||
'color' => 'alpha',
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'important' => 'all',
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'use_background_layout' => true,
|
||||
'use_text_orientation' => false,
|
||||
'css' => array(
|
||||
'text_shadow' => '%%order_class%% .et_pb_wc_title',
|
||||
),
|
||||
'options' => array(
|
||||
'background_layout' => array(
|
||||
'default_on_front' => 'light',
|
||||
'hover' => 'tabs',
|
||||
),
|
||||
),
|
||||
'toggle_slug' => 'header',
|
||||
),
|
||||
'text_shadow' => array(
|
||||
// Don't add text-shadow fields since they already are via font-options.
|
||||
'default' => false,
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'title_text' => array(
|
||||
'label' => esc_html__( 'Title Text', 'et_builder' ),
|
||||
'selector' => '%%order_class%% h1, %%order_class%% h2, %%order_class%% h3, %%order_class%% h4, %%order_class%% h5, %%order_class%% h6',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__title',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__title',
|
||||
),
|
||||
)
|
||||
),
|
||||
'__title' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Title',
|
||||
'get_title',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Title.
|
||||
*
|
||||
* @param array $args Additional arguments.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_title( $args = array() ) {
|
||||
if ( et_builder_tb_enabled() ) {
|
||||
return esc_html( 'Product Name', 'et_builder' );
|
||||
}
|
||||
|
||||
$defaults = array(
|
||||
'product' => 'current',
|
||||
);
|
||||
$args = wp_parse_args( $args, $defaults );
|
||||
$title = et_builder_wc_render_module_template(
|
||||
'the_title',
|
||||
$args,
|
||||
array( 'post' )
|
||||
);
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the WooCommerce Product Title markup.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_title_markup() {
|
||||
$header_level = $this->props['header_level'];
|
||||
$product_title = self::get_title( $this->props );
|
||||
|
||||
return sprintf(
|
||||
'
|
||||
<%1$s>%2$s</%1$s>',
|
||||
et_pb_process_header_level( $header_level, 'h1' ),
|
||||
et_core_esc_previously( $product_title )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$output = self::get_title_markup();
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return $this->_render_module_wrapper( $output, $render_slug );
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Title();
|
686
includes/builder/module/woocommerce/Upsells.php
Normal file
686
includes/builder/module/woocommerce/Upsells.php
Normal file
@ -0,0 +1,686 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Modules: ET_Builder_Module_Woocommerce_Upsells class
|
||||
*
|
||||
* The ET_Builder_Module_Woocommerce_Upsells Class is responsible for rendering the
|
||||
* Upsells markup using the WooCommerce template.
|
||||
*
|
||||
* @package Divi\Builder
|
||||
*
|
||||
* @since 3.29
|
||||
*/
|
||||
|
||||
/**
|
||||
* Class representing WooCommerce Upsells component.
|
||||
*/
|
||||
class ET_Builder_Module_Woocommerce_Upsells extends ET_Builder_Module {
|
||||
/**
|
||||
* Holds Prop values across static methods.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $static_props;
|
||||
|
||||
/**
|
||||
* Initialize.
|
||||
*/
|
||||
public function init() {
|
||||
$this->name = esc_html__( 'Woo Upsell', 'et_builder' );
|
||||
$this->plural = esc_html__( 'Woo Upsells', 'et_builder' );
|
||||
|
||||
// Use `et_pb_wc_{module}` for all WooCommerce modules.
|
||||
$this->slug = 'et_pb_wc_upsells';
|
||||
$this->vb_support = 'on';
|
||||
|
||||
$this->main_css_element = '%%order_class%%';
|
||||
|
||||
$this->settings_modal_toggles = array(
|
||||
'general' => array(
|
||||
'toggles' => array(
|
||||
'main_content' => et_builder_i18n( 'Content' ),
|
||||
),
|
||||
),
|
||||
'advanced' => array(
|
||||
'toggles' => array(
|
||||
'overlay' => et_builder_i18n( 'Overlay' ),
|
||||
'image' => et_builder_i18n( 'Image' ),
|
||||
// Avoid Text suffix by manually defining the `star` toggle slug.
|
||||
'star' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$this->advanced_fields = array(
|
||||
'fonts' => array(
|
||||
'title' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% section.products > h1, %%order_class%% section.products > h2, %%order_class%% section.products > h3, %%order_class%% section.products > h4, %%order_class%% section.products > h5, %%order_class%% section.products > h6',
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '26px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1',
|
||||
),
|
||||
),
|
||||
'rating' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% ul.products li.product .star-rating',
|
||||
'color' => '%%order_class%% li.product .star-rating > span:before',
|
||||
'letter_spacing_hover' => '%%order_class%% ul.products li.product:hover .star-rating',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => 14,
|
||||
),
|
||||
'hide_font' => true,
|
||||
'hide_line_height' => true,
|
||||
'hide_text_shadow' => true,
|
||||
'text_align' => array(
|
||||
'label' => esc_html__( 'Star Rating Alignment', 'et_builder' ),
|
||||
),
|
||||
'font_size' => array(
|
||||
'label' => esc_html__( 'Star Rating Size', 'et_builder' ),
|
||||
),
|
||||
'text_color' => array(
|
||||
'label' => esc_html__( 'Star Rating Color', 'et_builder' ),
|
||||
),
|
||||
'toggle_slug' => 'star',
|
||||
),
|
||||
'product_title' => array(
|
||||
'label' => esc_html__( 'Product Title', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product h3, {$this->main_css_element} ul.products li.product h1, {$this->main_css_element} ul.products li.product h2, {$this->main_css_element} ul.products li.product h4, {$this->main_css_element} ul.products li.product h5, {$this->main_css_element} ul.products li.product h6",
|
||||
'important' => 'all',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '1em',
|
||||
),
|
||||
'line_height' => array(
|
||||
'default' => '1',
|
||||
),
|
||||
),
|
||||
'price' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .price, {$this->main_css_element} ul.products li.product .price .amount",
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'range_settings' => array(
|
||||
'min' => '1',
|
||||
'max' => '100',
|
||||
'step' => '1',
|
||||
),
|
||||
'default' => floatval( et_get_option( 'body_font_height', '1.7' ) ) . 'em',
|
||||
),
|
||||
),
|
||||
'sale_badge' => array(
|
||||
'label' => esc_html__( 'Sale Badge', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .onsale",
|
||||
'important' => array( 'line-height', 'font', 'text-shadow' ),
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'line_height' => array(
|
||||
'default' => '1.7em',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '20px',
|
||||
),
|
||||
'letter_spacing' => array(
|
||||
'default' => '0px',
|
||||
),
|
||||
),
|
||||
'sale_price' => array(
|
||||
'label' => esc_html__( 'Sale Price', 'et_builder' ),
|
||||
'css' => array(
|
||||
'main' => "{$this->main_css_element} ul.products li.product .price ins .amount",
|
||||
),
|
||||
'hide_text_align' => true,
|
||||
'font' => array(
|
||||
'default' => '|700|||||||',
|
||||
),
|
||||
'font_size' => array(
|
||||
'default' => '14px',
|
||||
),
|
||||
'line_height' => array(
|
||||
'range_settings' => array(
|
||||
'min' => '1',
|
||||
'max' => '100',
|
||||
'step' => '1',
|
||||
),
|
||||
'default' => '1.7em',
|
||||
),
|
||||
),
|
||||
),
|
||||
'borders' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%%.et_pb_wc_upsells .product',
|
||||
'border_styles' => '%%order_class%%.et_pb_wc_upsells .product',
|
||||
),
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'css' => array(
|
||||
'main' => array(
|
||||
'border_radii' => '%%order_class%%.et_pb_module .et_shop_image',
|
||||
'border_styles' => '%%order_class%%.et_pb_module .et_shop_image',
|
||||
),
|
||||
'important' => 'all',
|
||||
),
|
||||
'label_prefix' => et_builder_i18n( 'Image' ),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
),
|
||||
),
|
||||
'box_shadow' => array(
|
||||
'default' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .product',
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'label' => esc_html__( 'Image Box Shadow', 'et_builder' ),
|
||||
'option_category' => 'layout',
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_shop_image',
|
||||
'overlay' => 'inset',
|
||||
),
|
||||
'default_on_fronts' => array(
|
||||
'color' => '',
|
||||
'position' => '',
|
||||
),
|
||||
),
|
||||
),
|
||||
'margin_padding' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%%',
|
||||
// Needed to overwrite last module margin-bottom styling.
|
||||
'important' => array( 'custom_margin' ),
|
||||
),
|
||||
),
|
||||
'text' => array(
|
||||
'css' => array(
|
||||
'text_shadow' => implode(
|
||||
', ',
|
||||
array(
|
||||
// Title.
|
||||
"{$this->main_css_element} ul.products h3",
|
||||
"{$this->main_css_element} ul.products h1",
|
||||
"{$this->main_css_element} ul.products h2",
|
||||
"{$this->main_css_element} ul.products h4",
|
||||
"{$this->main_css_element} ul.products h5",
|
||||
"{$this->main_css_element} ul.products h6",
|
||||
// Price.
|
||||
"{$this->main_css_element} ul.products .price",
|
||||
"{$this->main_css_element} ul.products .price .amount",
|
||||
|
||||
)
|
||||
),
|
||||
),
|
||||
),
|
||||
'filters' => array(
|
||||
'child_filters_target' => array(
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'image',
|
||||
),
|
||||
),
|
||||
'image' => array(
|
||||
'css' => array(
|
||||
'main' => '%%order_class%% .et_shop_image',
|
||||
),
|
||||
),
|
||||
'button' => false,
|
||||
);
|
||||
|
||||
$this->custom_css_fields = array(
|
||||
'product' => array(
|
||||
'label' => esc_html__( 'Product', 'et_builder' ),
|
||||
'selector' => 'li.product',
|
||||
),
|
||||
'onsale' => array(
|
||||
'label' => esc_html__( 'Onsale', 'et_builder' ),
|
||||
'selector' => 'li.product .onsale',
|
||||
),
|
||||
'image' => array(
|
||||
'label' => et_builder_i18n( 'Image' ),
|
||||
'selector' => '.et_shop_image',
|
||||
),
|
||||
'overlay' => array(
|
||||
'label' => et_builder_i18n( 'Overlay' ),
|
||||
'selector' => '.et_overlay',
|
||||
),
|
||||
'title' => array(
|
||||
'label' => et_builder_i18n( 'Title' ),
|
||||
'selector' => ET_Builder_Module_Helper_Woocommerce_Modules::get_title_selector(),
|
||||
),
|
||||
'rating' => array(
|
||||
'label' => esc_html__( 'Star Rating', 'et_builder' ),
|
||||
'selector' => '.star-rating',
|
||||
),
|
||||
'price' => array(
|
||||
'label' => esc_html__( 'Price', 'et_builder' ),
|
||||
'selector' => 'li.product .price',
|
||||
),
|
||||
'price_old' => array(
|
||||
'label' => esc_html__( 'Old Price', 'et_builder' ),
|
||||
'selector' => 'li.product .price del span.amount',
|
||||
),
|
||||
);
|
||||
|
||||
$this->help_videos = array(
|
||||
array(
|
||||
'id' => '7X03vBPYJ1o',
|
||||
'name' => esc_html__( 'Divi WooCommerce Modules', 'et_builder' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_fields() {
|
||||
$fields = array(
|
||||
'product' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_product_default(),
|
||||
'computed_affects' => array(
|
||||
'__upsells',
|
||||
),
|
||||
)
|
||||
),
|
||||
'product_filter' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'product_filter',
|
||||
array(
|
||||
'computed_affects' => array(
|
||||
'__upsells',
|
||||
),
|
||||
)
|
||||
),
|
||||
'posts_number' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'posts_number',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default(),
|
||||
'computed_affects' => array(
|
||||
'__upsells',
|
||||
),
|
||||
)
|
||||
),
|
||||
'columns_number' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'columns_number',
|
||||
array(
|
||||
'default' => ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default(),
|
||||
'computed_affects' => array(
|
||||
'__upsells',
|
||||
),
|
||||
)
|
||||
),
|
||||
'orderby' => ET_Builder_Module_Helper_Woocommerce_Modules::get_field(
|
||||
'orderby',
|
||||
array(
|
||||
'options' => array(
|
||||
'default' => esc_html__( 'Random Order', 'et_builder' ),
|
||||
'menu_order' => esc_html__( 'Sort by Menu Order', 'et_builder' ),
|
||||
'popularity' => esc_html__( 'Sort By Popularity', 'et_builder' ),
|
||||
'date' => esc_html__( 'Sort By Date: Oldest To Newest', 'et_builder' ),
|
||||
'date-desc' => esc_html__( 'Sort By Date: Newest To Oldest', 'et_builder' ),
|
||||
'price' => esc_html__( 'Sort By Price: Low To High', 'et_builder' ),
|
||||
'price-desc' => esc_html__( 'Sort By Price: High To Low', 'et_builder' ),
|
||||
),
|
||||
'computed_affects' => array(
|
||||
'__upsells',
|
||||
),
|
||||
)
|
||||
),
|
||||
'sale_badge_color' => array(
|
||||
'label' => esc_html__( 'Sale Badge Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Pick a color to use for the sales bade that appears on products that are on sale.', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'sale_badge',
|
||||
'hover' => 'tabs',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'icon_hover_color' => array(
|
||||
'label' => esc_html__( 'Overlay Icon Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Pick a color to use for the icon that appears when hovering over a product.', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'hover_overlay_color' => array(
|
||||
'label' => esc_html__( 'Overlay Background Color', 'et_builder' ),
|
||||
'description' => esc_html__( 'Here you can define a custom color for the overlay', 'et_builder' ),
|
||||
'type' => 'color-alpha',
|
||||
'custom_color' => true,
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'hover_icon' => array(
|
||||
'label' => esc_html__( 'Overlay Icon', 'et_builder' ),
|
||||
'description' => esc_html__( 'Here you can define a custom icon for the overlay', 'et_builder' ),
|
||||
'type' => 'select_icon',
|
||||
'option_category' => 'configuration',
|
||||
'class' => array( 'et-pb-font-icon' ),
|
||||
'tab_slug' => 'advanced',
|
||||
'toggle_slug' => 'overlay',
|
||||
'mobile_options' => true,
|
||||
'sticky' => true,
|
||||
),
|
||||
'__upsells' => array(
|
||||
'type' => 'computed',
|
||||
'computed_callback' => array(
|
||||
'ET_Builder_Module_Woocommerce_Upsells',
|
||||
'get_upsells',
|
||||
),
|
||||
'computed_depends_on' => array(
|
||||
'product',
|
||||
'product_filter',
|
||||
'posts_number',
|
||||
'columns_number',
|
||||
'orderby',
|
||||
),
|
||||
'computed_minimum' => array(
|
||||
'product',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function get_transition_fields_css_props() {
|
||||
$fields = parent::get_transition_fields_css_props();
|
||||
|
||||
$fields['rating_letter_spacing'] = array(
|
||||
'width' => '%%order_class%% .star-rating',
|
||||
'letter-spacing' => '%%order_class%% .star-rating',
|
||||
);
|
||||
|
||||
return $fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Upsells Products.
|
||||
*
|
||||
* Used as a callback to the __upsells computed prop.
|
||||
*
|
||||
* @param array $args Arguments from Computed Prop AJAX call.
|
||||
* @param array $conditional_tags Conditional Tags.
|
||||
* @param array $current_page Current page args.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function get_upsells( $args = array(), $conditional_tags = array(), $current_page = array() ) {
|
||||
self::$static_props = $args;
|
||||
|
||||
// Force set product's class to ET_Theme_Builder_Woocommerce_Product_Variable_Placeholder
|
||||
// in TB so related product can outputs visible content based on pre-filled value in TB
|
||||
if ( 'true' === et_()->array_get( $conditional_tags, 'is_tb', false ) ) {
|
||||
// Set upsells id; adjust it with module's arguments. This is specifically needed if
|
||||
// the module fetched the value via computed callback due to some fields no longer uses
|
||||
// default value
|
||||
ET_Theme_Builder_Woocommerce_Product_Variable_Placeholder::set_tb_upsells_ids(
|
||||
array(
|
||||
'limit' => et_()->array_get( $args, 'posts_number', 4 ),
|
||||
)
|
||||
);
|
||||
|
||||
add_filter( 'woocommerce_product_class', 'et_theme_builder_wc_product_class' );
|
||||
}
|
||||
|
||||
add_filter(
|
||||
'woocommerce_upsell_display_args',
|
||||
array(
|
||||
'ET_Builder_Module_Woocommerce_Upsells',
|
||||
'set_upsell_display_args',
|
||||
)
|
||||
);
|
||||
|
||||
if ( isset( $args['orderby'] ) ) {
|
||||
$orderby = $args['orderby'];
|
||||
|
||||
if ( in_array( $orderby, array( 'price', 'date' ), true ) ) {
|
||||
/*
|
||||
* For the list of all allowed Orderby values, refer
|
||||
*
|
||||
* @see wc_products_array_orderby
|
||||
*/
|
||||
$args['order'] = 'asc';
|
||||
}
|
||||
}
|
||||
|
||||
$output = et_builder_wc_render_module_template( 'woocommerce_upsell_display', $args );
|
||||
|
||||
remove_filter(
|
||||
'woocommerce_upsell_display_args',
|
||||
array(
|
||||
'ET_Builder_Module_Woocommerce_Upsells',
|
||||
'set_upsell_display_args',
|
||||
)
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the User selected Posts per page, columns and Order by values to WooCommerce.
|
||||
*
|
||||
* @param array $args Documented at
|
||||
* {@see woocommerce_upsell_display()}.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function set_upsell_display_args( $args ) {
|
||||
$selected_args = self::get_selected_upsell_display_args();
|
||||
|
||||
return wp_parse_args( $selected_args, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the User set Posts per page, columns and Order by values.
|
||||
*
|
||||
* The static variable used in this method is set by
|
||||
*
|
||||
* @see ET_Builder_Module_Woocommerce_Upsells::get_upsells()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_selected_upsell_display_args() {
|
||||
$selected_args = array();
|
||||
$selected_args['posts_per_page'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'posts_number',
|
||||
''
|
||||
);
|
||||
$selected_args['columns'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'columns_number',
|
||||
''
|
||||
);
|
||||
$selected_args['orderby'] = et_()->array_get(
|
||||
self::$static_props,
|
||||
'orderby',
|
||||
''
|
||||
);
|
||||
|
||||
// Set default values when parameters are empty.
|
||||
$default = ET_Builder_Module_Helper_Woocommerce_Modules::get_columns_posts_default_value();
|
||||
if ( empty( $selected_args['posts_per_page'] ) ) {
|
||||
$selected_args['posts_per_page'] = $default;
|
||||
}
|
||||
if ( empty( $selected_args['columns'] ) ) {
|
||||
$selected_args['columns'] = $default;
|
||||
}
|
||||
|
||||
$selected_args = array_filter( $selected_args, 'strlen' );
|
||||
|
||||
return $selected_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the module output.
|
||||
*
|
||||
* @param array $attrs List of attributes.
|
||||
* @param string $content Content being processed.
|
||||
* @param string $render_slug Slug of module that is used for rendering output.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render( $attrs, $content, $render_slug ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::process_background_layout_data( $render_slug, $this );
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::add_star_rating_style(
|
||||
$render_slug,
|
||||
$this->props,
|
||||
'%%order_class%% ul.products li.product .star-rating',
|
||||
'%%order_class%% ul.products li.product:hover .star-rating'
|
||||
);
|
||||
|
||||
// Sale Badge Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'base_attr_name' => 'sale_badge_color',
|
||||
'selector' => '%%order_class%% span.onsale',
|
||||
'css_property' => 'background-color',
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Icon Hover Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'hover' => false,
|
||||
'base_attr_name' => 'icon_hover_color',
|
||||
'selector' => '%%order_class%% .et_overlay:before',
|
||||
'css_property' => 'color',
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Hover Overlay Color.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'hover' => false,
|
||||
'base_attr_name' => 'hover_overlay_color',
|
||||
'selector' => '%%order_class%% .et_overlay',
|
||||
'css_property' => array( 'background-color', 'border-color' ),
|
||||
'important' => true,
|
||||
'render_slug' => $render_slug,
|
||||
'type' => 'color',
|
||||
)
|
||||
);
|
||||
|
||||
// Extended Icon Styles.
|
||||
$this->generate_styles(
|
||||
array(
|
||||
'utility_arg' => 'icon_font_family',
|
||||
'render_slug' => $render_slug,
|
||||
'base_attr_name' => 'hover_icon',
|
||||
'important' => true,
|
||||
'selector' => '%%order_class%% .et_overlay:before',
|
||||
'processor' => array(
|
||||
'ET_Builder_Module_Helper_Style_Processor',
|
||||
'process_extended_icon',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
// Images: Add CSS Filters and Mix Blend Mode rules (if set).
|
||||
if ( array_key_exists( 'image', $this->advanced_fields ) && array_key_exists( 'css', $this->advanced_fields['image'] ) ) {
|
||||
$this->add_classname(
|
||||
$this->generate_css_filters(
|
||||
$render_slug,
|
||||
'child_',
|
||||
self::$data_utils->array_get( $this->advanced_fields['image']['css'], 'main', '%%order_class%%' )
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->add_classname( $this->get_text_orientation_classname() );
|
||||
|
||||
$is_shop = function_exists( 'is_shop' ) && is_shop();
|
||||
$is_wc_loop_prop_get_set_exists = function_exists( 'wc_get_loop_prop' ) && function_exists( 'wc_set_loop_prop' );
|
||||
$is_product_category = function_exists( 'is_product_category' ) && is_product_category();
|
||||
|
||||
if ( $is_shop ) {
|
||||
$display_type = ET_Builder_Module_Helper_Woocommerce_Modules::set_display_type_to_render_only_products( 'woocommerce_shop_page_display' );
|
||||
} elseif ( is_product_category() ) {
|
||||
$display_type = ET_Builder_Module_Helper_Woocommerce_Modules::set_display_type_to_render_only_products( 'woocommerce_category_archive_display' );
|
||||
}
|
||||
|
||||
// Required to handle Customizer preview pane.
|
||||
// Refer: https://github.com/elegantthemes/Divi/issues/17998#issuecomment-565955422
|
||||
if ( $is_wc_loop_prop_get_set_exists && is_customize_preview() ) {
|
||||
$is_filtered = wc_get_loop_prop( 'is_filtered' );
|
||||
wc_set_loop_prop( 'is_filtered', true );
|
||||
}
|
||||
|
||||
$output = self::get_upsells( $this->props );
|
||||
|
||||
// Required to handle Customizer preview pane.
|
||||
// Refer: https://github.com/elegantthemes/Divi/issues/17998#issuecomment-565955422
|
||||
if ( $is_wc_loop_prop_get_set_exists && is_customize_preview() && isset( $is_filtered ) ) {
|
||||
wc_set_loop_prop( 'is_filtered', $is_filtered );
|
||||
}
|
||||
|
||||
if ( $is_shop && isset( $display_type ) ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::reset_display_type( 'woocommerce_shop_page_display', $display_type );
|
||||
} elseif ( $is_product_category && isset( $display_type ) ) {
|
||||
ET_Builder_Module_Helper_Woocommerce_Modules::reset_display_type( 'woocommerce_category_archive_display', $display_type );
|
||||
}
|
||||
|
||||
// Render empty string if no output is generated to avoid unwanted vertical space.
|
||||
if ( '' === $output ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
add_filter(
|
||||
"et_builder_module_{$render_slug}_outer_wrapper_attrs",
|
||||
array(
|
||||
'ET_Builder_Module_Helper_Woocommerce_Modules',
|
||||
'output_data_icon_attrs',
|
||||
),
|
||||
10,
|
||||
2
|
||||
);
|
||||
|
||||
$output = $this->_render_module_wrapper( $output, $render_slug );
|
||||
|
||||
remove_filter(
|
||||
"et_builder_module_{$render_slug}_outer_wrapper_attrs",
|
||||
array(
|
||||
'ET_Builder_Module_Helper_Woocommerce_Modules',
|
||||
'output_data_icon_attrs',
|
||||
),
|
||||
10
|
||||
);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
||||
new ET_Builder_Module_Woocommerce_Upsells();
|
Reference in New Issue
Block a user