2021-12-07 11:08:05 +00:00
< ? php
/**
* WooCommerce Module Helper
*
* @ package Divi
* @ sub - package Builder
* @ since 3.29
*/
if ( ! defined ( 'ABSPATH' ) ) {
die ( 'Direct access forbidden.' );
}
if ( et_is_woocommerce_plugin_active () ) {
/**
* Class ET_Builder_Module_Helper_Woocommerce_Modules
*
* Shared code between all Woo Modules .
*/
class ET_Builder_Module_Helper_Woocommerce_Modules {
/**
* Returns TRUE if the Product attribute value is valid .
*
* Valid values are Product Ids , `current` and `latest` .
*
2021-12-20 18:06:11 +00:00
* @ param string $maybe_product_id Product ID .
2021-12-07 11:08:05 +00:00
*
* @ return bool
*/
public static function is_product_attr_valid ( $maybe_product_id ) {
if ( empty ( $maybe_product_id ) ) {
return false ;
}
if ( absint ( $maybe_product_id ) === 0
&& ! in_array ( $maybe_product_id , array ( 'current' , 'latest' ) ) ) {
return false ;
}
return true ;
}
/**
* Gets the Product Id by the given Product prop value .
*
* @ param string $valid_product_attr
*
* @ return int
*/
public static function get_product_id_by_prop ( $valid_product_attr ) {
if ( ! self :: is_product_attr_valid ( $valid_product_attr ) ) {
return 0 ;
}
if ( 'current' === $valid_product_attr ) {
$current_post_id = ET_Builder_Element :: get_current_post_id ();
if ( et_theme_builder_is_layout_post_type ( get_post_type ( $current_post_id ) ) ) {
// We want to use the latest product when we are editing a TB layout.
$valid_product_attr = 'latest' ;
}
}
if ( ! in_array (
$valid_product_attr ,
array (
'current' ,
'latest' ,
)
) && false === get_post_status ( $valid_product_attr ) ) {
$valid_product_attr = 'latest' ;
}
if ( 'current' === $valid_product_attr ) {
$product_id = ET_Builder_Element :: get_current_post_id ();
} elseif ( 'latest' === $valid_product_attr ) {
$args = array (
'limit' => 1 ,
'post_status' => array ( 'publish' , 'private' ),
'perm' => 'readable' ,
);
$products = wc_get_products ( $args );
if ( ! empty ( $products ) ) {
$product_id = $products [ 0 ] -> get_id ();
} else {
return 0 ;
}
} elseif ( is_numeric ( $valid_product_attr ) && 'product' !== get_post_type ( $valid_product_attr ) ) {
// There is a condition that $valid_product_attr value passed here is not the product ID.
// For example when you set product breadcrumb as Blurb Title when building layout in TB.
// So we get the most recent product ID in date descending order.
$query = new WC_Product_Query (
array (
'limit' => 1 ,
'orderby' => 'date' ,
'order' => 'DESC' ,
'return' => 'ids' ,
'status' => array ( 'publish' ),
)
);
$products = $query -> get_products ();
if ( $products && ! empty ( $products [ 0 ] ) ) {
$product_id = absint ( $products [ 0 ] );
} else {
$product_id = absint ( $valid_product_attr );
}
} else {
$product_id = absint ( $valid_product_attr );
}
return $product_id ;
}
/**
* Gets the Product ( WC_Product ) by the value stored in the Product attribute .
*
* @ see WC_Product
*
* @ param string $maybe_product_id The Value stored in the Product attribute using VB .
*
* @ return false | WC_Product
*/
public static function get_product ( $maybe_product_id ) {
$product_id = self :: get_product_id_by_prop ( $maybe_product_id );
/*
* No need to check `wc_get_product()` exists since this Class is defined only when
* WooCommerce is active .
*/
$product = wc_get_product ( $product_id );
if ( empty ( $product ) ) {
return false ;
}
return $product ;
}
/**
* Gets the Product ID .
*
* @ see WC_Product
*
* @ param string $maybe_product_id The Value stored in the Product attribute using VB .
*
* @ return int WP_Product ID .
*/
public static function get_product_id ( $maybe_product_id ) {
$product = self :: get_product ( $maybe_product_id );
if ( ! $product ) {
return 0 ;
}
return $product -> get_id ();
}
/**
* Get reusable WooCommerce field definition
*
* @ since 3.29
*
* @ param string $name Field template name .
* @ param array $attrs Attribute that need to be inserted into field definition .
* @ param array $unset Attribute that need to be removed from field definition .
*
* @ return array
*/
public static function get_field ( $name , $attrs = array (), $unset = array () ) {
switch ( $name ) {
case 'product' :
$field = array (
'label' => esc_html__ ( 'Product' , 'et_builder' ),
'type' => 'select_product' ,
'option_category' => 'basic_option' ,
'description' => esc_html__ ( 'Here you can select the Product.' , 'et_builder' ),
'toggle_slug' => 'main_content' ,
'searchable' => true ,
'displayRecent' => false ,
'default' => 'current' ,
'post_type' => 'product' ,
'computed_affects' => array (
'__product' ,
),
);
break ;
case 'product_filter' :
$field = array (
'label' => esc_html__ ( 'Filter By' , 'et_builder' ),
'type' => 'select' ,
'option_category' => 'configuration' ,
'options' => array (
'newest' => esc_html__ ( 'Newest' , 'et_builder' ),
),
'toggle_slug' => 'main_content' ,
'description' => esc_html__ ( 'Here you can filter the Products.' , 'et_builder' ),
'default' => 'newest' ,
'show_if' => array (
'product' => '-1' ,
),
'computed_affects' => array (
'__product' ,
),
);
break ;
case 'posts_number' :
$field = array (
'default' => '12' ,
'label' => esc_html__ ( 'Product Count' , 'et_builder' ),
'type' => 'text' ,
'option_category' => 'configuration' ,
'description' => esc_html__ ( 'Define the number of products that should be displayed per page.' , 'et_builder' ),
'computed_affects' => array (
'__product' ,
),
'toggle_slug' => 'main_content' ,
);
break ;
case 'columns_number' :
$field = array (
'label' => esc_html__ ( 'Column Layout' , 'et_builder' ),
'type' => 'select' ,
'option_category' => 'layout' ,
'options' => array (
'6' => sprintf ( esc_html__ ( '%1$s Columns' , 'et_builder' ), esc_html ( '6' ) ),
'5' => sprintf ( esc_html__ ( '%1$s Columns' , 'et_builder' ), esc_html ( '5' ) ),
'4' => sprintf ( esc_html__ ( '%1$s Columns' , 'et_builder' ), esc_html ( '4' ) ),
'3' => sprintf ( esc_html__ ( '%1$s Columns' , 'et_builder' ), esc_html ( '3' ) ),
'2' => sprintf ( esc_html__ ( '%1$s Columns' , 'et_builder' ), esc_html ( '2' ) ),
'1' => esc_html__ ( '1 Column' , 'et_builder' ),
),
'default' => '0' ,
'description' => esc_html__ ( 'Choose how many columns to display.' , 'et_builder' ),
'computed_affects' => array (
'__product' ,
),
'toggle_slug' => 'main_content' ,
);
break ;
case 'orderby' :
$field = array (
'label' => esc_html__ ( 'Order' , 'et_builder' ),
'type' => 'select' ,
'option_category' => 'configuration' ,
'options' => array (
'default' => esc_html__ ( 'Default Sorting' , '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' ),
),
'default_on_front' => 'default' ,
'description' => esc_html__ ( 'Choose how your products should be ordered.' , 'et_builder' ),
'computed_affects' => array (
'__shop' ,
),
'toggle_slug' => 'main_content' ,
);
break ;
2021-12-20 18:06:11 +00:00
case 'offset_number' :
$field = array (
'label' => esc_html__ ( 'Product Offset Number' , 'et_builder' ),
'type' => 'text' ,
'option_category' => 'configuration' ,
'description' => esc_html__ ( 'Choose how many products you would like to skip. These products will not be shown in the feed.' , 'et_builder' ),
'toggle_slug' => 'main_content' ,
'default' => 0 ,
);
break ;
case 'fields_width' :
$field = array (
'label' => esc_html__ ( 'Fields Width' , 'et_builder' ),
'description' => esc_html__ ( 'Set the width of the fields.' , 'et_builder' ),
'type' => 'select' ,
'option_category' => 'configuration' ,
'options' => array (
'default' => __ ( 'Default' , 'et_builder' ),
'fullwidth' => __ ( 'Fullwidth' , 'et_builder' ),
'2_column' => __ ( '2 Column' , 'et_builder' ),
),
'default' => 'default' ,
'tab_slug' => 'advanced' ,
'toggle_slug' => 'layout' ,
'mobile_options' => true ,
);
break ;
case 'collapse_table_gutters_borders' :
$field = array (
'label' => esc_html__ ( 'Collapse Table Gutters and Borders' , 'et_builder' ),
'type' => 'yes_no_button' ,
'option_category' => 'configuration' ,
'options' => array (
'on' => et_builder_i18n ( 'Yes' ),
'off' => et_builder_i18n ( 'No' ),
),
'description' => esc_html__ ( 'Collapse Table Gutters and Borders.' , 'et_builder' ),
'toggle_slug' => 'table' ,
'tab_slug' => 'advanced' ,
'default' => 'off' ,
'mobile_options' => true ,
);
break ;
case 'vertical_gutter_width' :
$field = array (
'label' => esc_html__ ( 'Vertical Gutters' , 'et_builder' ),
'type' => 'range' ,
'default_unit' => 'px' ,
'allowed_units' => array (
'em' ,
'rem' ,
'px' ,
'cm' ,
'mm' ,
'in' ,
'pt' ,
'pc' ,
'ex' ,
'vh' ,
'vw' ,
),
'range_settings' => array (
'min' => 0 ,
'max' => 50 ,
'step' => 1 ,
'min_limit' => 0 ,
),
'default' => '0px' ,
'mobile_options' => true ,
'sticky' => false ,
'tab_slug' => 'advanced' ,
'toggle_slug' => 'table' ,
'show_if' => array (
'collapse_table_gutters_borders' => 'off' ,
),
);
break ;
case 'horizontal_gutter_width' :
$field = array (
'label' => esc_html__ ( 'Horizontal Gutters' , 'et_builder' ),
'type' => 'range' ,
'default_unit' => 'px' ,
'allowed_units' => array (
'em' ,
'rem' ,
'px' ,
'cm' ,
'mm' ,
'in' ,
'pt' ,
'pc' ,
'ex' ,
'vh' ,
'vw' ,
),
'range_settings' => array (
'min' => 0 ,
'max' => 50 ,
'step' => 1 ,
'min_limit' => 0 ,
),
'default' => '0px' ,
'mobile_options' => true ,
'sticky' => false ,
'tab_slug' => 'advanced' ,
'toggle_slug' => 'table' ,
'show_if' => array (
'collapse_table_gutters_borders' => 'off' ,
),
);
break ;
case 'placeholder_color' :
$field = array (
'label' => esc_html__ ( 'Placeholder Color' , 'et_builder' ),
'description' => esc_html__ ( 'Pick a color to be used for the placeholder written inside input fields.' , 'et_builder' ),
'type' => 'color-alpha' ,
'custom_color' => true ,
'tab_slug' => 'advanced' ,
'toggle_slug' => 'form_field' ,
'hover' => 'tabs' ,
'mobile_options' => true ,
'sticky' => false ,
);
break ;
case 'table_cell_alternating_background_color' :
$field = array (
'label' => esc_html__ ( 'Table Cell Alternating Background Color' , 'et_builder' ),
'description' => esc_html__ ( 'Pick a color to be used for the alternating table cells.' , 'et_builder' ),
'type' => 'color-alpha' ,
'custom_color' => true ,
'tab_slug' => 'advanced' ,
'toggle_slug' => 'table_cell' ,
'hover' => 'tabs' ,
'mobile_options' => true ,
'sticky' => false ,
'priority' => 9 ,
);
break ;
2021-12-07 11:08:05 +00:00
default :
$field = array ();
break ;
}
// Added custom attribute(s).
if ( ! empty ( $attrs ) ) {
$field = wp_parse_args ( $attrs , $field );
}
// Remove default attribute(s).
if ( ! empty ( $unset ) ) {
foreach ( $unset as $unset_attr ) {
unset ( $field [ $unset_attr ] );
}
}
return $field ;
}
/**
* Gets the Reviews title .
*
* @ since 3.29
*
* @ param WC_Product $product The Product Post .
*
* @ return string
*/
public static function get_reviews_title ( $product ) {
$reviews_title = '' ;
if ( ! ( $product instanceof WC_Product ) ) {
return $reviews_title ;
}
$count = $product -> get_review_count ();
if ( $count ) {
$reviews_title = sprintf (
esc_html ( _n ( '%1$s review for %2$s' , '%1$s reviews for %2$s' , $count , 'et_builder' ) ),
esc_html ( $count ),
'<span>' . $product -> get_title () . '</span>'
);
} else {
$reviews_title = esc_html__ ( 'Reviews' , 'et_builder' );
}
return $reviews_title ;
}
/**
* Gets the Reviews comment form .
*
* @ since 3.29
*
* @ param WC_Product $product The Product Post .
* @ param WP_Comment [] $comments Array of Comment objects .
*
* @ return string
*/
public static function get_reviews_comment_form ( $product , $comments ) {
$has_reviews = empty ( $comments ) ? false : true ;
ob_start ();
?>
< ? php
if ( get_option ( 'woocommerce_review_rating_verification_required' ) === 'no' ||
wc_customer_bought_product ( '' , get_current_user_id (), $product -> get_id () ) ) :
?>
< div id = " review_form_wrapper " >
< div id = " review_form " >
< ? php
$commenter = wp_get_current_commenter ();
$comment_form = array (
'title_reply' => $has_reviews ? esc_html__ ( 'Add a review' , 'et_builder' ) : sprintf ( esc_html__ ( 'Be the first to review “%s”' , 'woocommerce' ), get_the_title ( $product -> get_id () ) ),
'title_reply_to' => esc_html__ ( 'Leave a Reply to %s' , 'et_builder' ),
'title_reply_before' => '<span id="reply-title" class="comment-reply-title">' ,
'title_reply_after' => '</span>' ,
'comment_notes_after' => '' ,
'fields' => array (
'author' => '<p class="comment-form-author">' . '<label for="author">' . esc_html__ ( 'Name' , 'woocommerce' ) . ' <span class="required">*</span></label> ' .
'<input id="author" name="author" type="text" value="' . esc_attr ( $commenter [ 'comment_author' ] ) . '" size="30" required /></p>' ,
'email' => '<p class="comment-form-email"><label for="email">' . esc_html__ ( 'Email' , 'woocommerce' ) . ' <span class="required">*</span></label> ' .
'<input id="email" name="email" type="email" value="' . esc_attr ( $commenter [ 'comment_author_email' ] ) . '" size="30" required /></p>' ,
),
'label_submit' => esc_html__ ( 'Submit' , 'et_builder' ),
'submit_button' => '<button name="%1$s" type="submit" id="%2$s" class="et_pb_button %3$s" />%4$s</button>' ,
'logged_in_as' => '' ,
'comment_field' => '' ,
);
if ( $account_page_url = wc_get_page_permalink ( 'myaccount' ) ) {
/* translators: %s opening and closing link tags respectively */
$comment_form [ 'must_log_in' ] = '<p class="must-log-in">' . sprintf ( esc_html__ ( 'You must be %1$slogged in%2$s to post a review.' , 'woocommerce' ), '<a href="' . esc_url ( $account_page_url ) . '">' , '</a>' ) . '</p>' ;
}
if ( get_option ( 'woocommerce_enable_review_rating' ) === 'yes' ) {
$comment_form [ 'comment_field' ] = '<div class="comment-form-rating"><label for="rating">' . esc_html__ ( 'Your rating' , 'et_builder' ) . ' </ label >< select name = " rating " id = " rating " required >
< option value = " " > ' . esc_html__( ' Rate & hellip ; ', ' et_builder ' ) . ' </ option >
< option value = " 5 " > ' . esc_html__( ' Perfect ', ' et_builder ' ) . ' </ option >
< option value = " 4 " > ' . esc_html__( ' Good ', ' et_builder ' ) . ' </ option >
< option value = " 3 " > ' . esc_html__( ' Average ', ' et_builder ' ) . ' </ option >
< option value = " 2 " > ' . esc_html__( ' Not that bad ', ' et_builder ' ) . ' </ option >
< option value = " 1 " > ' . esc_html__( ' Very poor ', ' et_builder ' ) . ' </ option >
</ select ></ div > ' ;
}
$comment_form [ 'comment_field' ] .= '<p class="comment-form-comment"><label for="comment">' . esc_html__ ( 'Your review' , 'et_builder' ) . ' <span class="required">*</span></label><textarea id="comment" name="comment" cols="45" rows="8" required></textarea></p>' ;
comment_form (
apply_filters ( 'woocommerce_product_review_comment_form_args' , $comment_form ),
$product -> get_id ()
);
?>
</ div >
</ div >
< ? php else : ?>
< p class = " woocommerce-verification-required " >< ? php esc_html_e ( 'Only logged in customers who have purchased this product may leave a review.' , 'woocommerce' ); ?> </p>
< ? php endif ; ?>
< ? php
return ob_get_clean ();
}
/**
* Gets the formatted weight markup for the given Product Id .
*
* @ param int $product_id Product Id .
*
* @ return string
*/
public static function get_weight_formatted ( $product_id ) {
$product = self :: get_product ( $product_id );
$markup = '' ;
if ( ! $product ) {
return $markup ;
}
return ( $product -> has_weight () ) ? wc_format_weight ( $product -> get_weight () ) : $markup ;
}
/**
* Gets the formatted dimension markup for the given Product Id .
*
* @ param int $product_id Product Id .
*
* @ return string
*/
public static function get_dimensions_formatted ( $product_id ) {
$product = self :: get_product ( $product_id );
$markup = '' ;
if ( ! $product ) {
return $markup ;
}
return ( $product -> has_dimensions () ) ? wc_format_dimensions ( $product -> get_dimensions ( false ) ) : $markup ;
}
/**
* Filters the $outer_wrapper_attrs .
* Adds 'data-background-layout' and 'data-background-layout-hover' attributes if needed .
*
* @ since 3.29
*
* @ param array $outer_wrapper_attrs Key value pairs of outer wrapper attributes .
* @ param ET_Builder_Element $this_class Module ' s class .
*
* @ return array filtered $outer_wrapper_attrs .
*/
public static function maybe_add_background_layout_data ( $outer_wrapper_attrs , $this_class ) {
$background_layout = et_ () -> array_get ( $this_class -> props , 'background_layout' , '' );
$background_layout_hover = et_pb_hover_options () -> get_value ( 'background_layout' , $this_class -> props , 'light' );
$background_layout_hover_enabled = et_pb_hover_options () -> is_enabled ( 'background_layout' , $this_class -> props );
if ( $background_layout_hover_enabled ) {
$outer_wrapper_attrs [ 'data-background-layout' ] = esc_attr ( $background_layout );
$outer_wrapper_attrs [ 'data-background-layout-hover' ] = esc_attr ( $background_layout_hover );
}
return $outer_wrapper_attrs ;
}
/**
* Processes the Background Layout options for Woocommerce Modules .
* Adds Background Layout related classes .
* Adds Filter for $outer_wrapper_attrs , so required data attributes can be added for specific modules .
*
* @ since 3.29
*
* @ param string $render_slug Module ' s render slug .
* @ param ET_Builder_Element $this_class Module ' s class .
*
* @ return void .
*/
public static function process_background_layout_data ( $render_slug , $this_class ) {
$background_layout = et_ () -> array_get ( $this_class -> props , 'background_layout' , '' );
$background_layout_values = et_pb_responsive_options () -> get_property_values ( $this_class -> props , 'background_layout' );
$background_layout_tablet = et_ () -> array_get ( $background_layout_values , 'tablet' , '' );
$background_layout_phone = et_ () -> array_get ( $background_layout_values , 'phone' , '' );
$this_class -> add_classname ( " et_pb_bg_layout_ { $background_layout } " );
if ( ! empty ( $background_layout_tablet ) ) {
$this_class -> add_classname ( " et_pb_bg_layout_ { $background_layout_tablet } _tablet " );
}
if ( ! empty ( $background_layout_phone ) ) {
$this_class -> add_classname ( " et_pb_bg_layout_ { $background_layout_phone } _phone " );
}
add_filter ( " et_builder_module_ { $render_slug } _outer_wrapper_attrs " , array ( 'ET_Builder_Module_Helper_Woocommerce_Modules' , 'maybe_add_background_layout_data' ), 10 , 2 );
}
/**
* Processes the Button Icon options for Woocommerce Modules .
* Adds et_pb_woo_custom_button_icon class if needed .
* Adds Filter for $outer_wrapper_attrs , so required button icon attributes can be added for specific modules .
*
* @ since 3.29
*
* @ param string $render_slug Module ' s render slug .
* @ param ET_Builder_Element $this_class Module ' s class .
*
* @ return void .
*/
public static function process_custom_button_icons ( $render_slug , $this_class ) {
$button_custom = $this_class -> props [ 'custom_button' ];
$custom_icon_values = et_ () -> array_get ( $this_class -> props , 'button_icon' , '' );
// Exit if no custom styles or icons defined for button.
if ( 'on' !== $button_custom || '' === $custom_icon_values ) {
return ;
}
$this_class -> add_classname ( 'et_pb_woo_custom_button_icon' );
add_filter ( " et_builder_module_ { $render_slug } _outer_wrapper_attrs " , array ( 'ET_Builder_Module_Helper_Woocommerce_Modules' , 'add_custom_button_icons' ), 10 , 2 );
}
/**
* Filters the $outer_wrapper_attrs .
* Adds 'data-button-class' , 'data-button-icon' , 'data-button-icon-tablet' and 'data-button-icon-phone' attributes if needed .
*
* @ since 3.29
*
* @ param array $outer_wrapper_attrs Key value pairs of outer wrapper attributes .
* @ param ET_Builder_Element $this_class Module ' s class .
*
* @ return array filtered $outer_wrapper_attrs .
*/
public static function add_custom_button_icons ( $outer_wrapper_attrs , $this_class ) {
$custom_icon_values = et_pb_responsive_options () -> get_property_values ( $this_class -> props , 'button_icon' );
$custom_icon = isset ( $custom_icon_values [ 'desktop' ] ) ? $custom_icon_values [ 'desktop' ] : '' ;
$custom_icon_tablet = isset ( $custom_icon_values [ 'tablet' ] ) ? $custom_icon_values [ 'tablet' ] : '' ;
$custom_icon_phone = isset ( $custom_icon_values [ 'phone' ] ) ? $custom_icon_values [ 'phone' ] : '' ;
if ( '' !== $custom_icon || '' !== $custom_icon_tablet || '' !== $custom_icon_phone ) {
$outer_wrapper_attrs [ 'data-button-class' ] = esc_attr ( $this_class -> get_button_classname () );
$outer_wrapper_attrs [ 'data-button-icon' ] = esc_attr ( et_pb_process_font_icon ( $custom_icon ) );
$outer_wrapper_attrs [ 'data-button-icon-tablet' ] = esc_attr ( et_pb_process_font_icon ( $custom_icon_tablet ) );
$outer_wrapper_attrs [ 'data-button-icon-phone' ] = esc_attr ( et_pb_process_font_icon ( $custom_icon_phone ) );
}
return $outer_wrapper_attrs ;
}
/**
* Gets the columns default .
*
* @ return string
*/
public static function get_columns_posts_default () {
return array (
'filter' ,
'et_builder_get_woo_default_columns' ,
);
}
/**
* Gets the columns default value for the current Product .
*
* @ return string
*/
public static function get_columns_posts_default_value () {
$post_id = et_core_page_resource_get_the_ID ();
$post_id = $post_id ? $post_id : ( int ) et_ () -> array_get ( $_POST , 'current_page.id' );
$page_layout = get_post_meta ( $post_id , '_et_pb_page_layout' , true );
if ( $page_layout && 'et_full_width_page' !== $page_layout && ! ET_Builder_Element :: is_theme_builder_layout () ) {
return '3' ; // Set to 3 if page has sidebar.
}
/*
* Default number is based on the WooCommerce plugin default value .
*
* @ see woocommerce_output_related_products ()
*/
return '4' ;
}
/**
* Gets the Title header tag .
*
* WooCommerce version influences the returned header .
*
* @ return string
*/
public static function get_title_header () {
$header = 'h3' ;
if ( ! et_is_woocommerce_plugin_active () ) {
return $header ;
}
global $woocommerce ;
if ( version_compare ( $woocommerce -> version , '3.0.0' , '>=' ) ) {
$header = 'h2' ;
}
return $header ;
}
/**
* Gets the Title selector .
*
* WooCommerce changed the title tag from h3 to h2 in v3 . 0.0
*
* @ uses ET_Builder_Module_Helper_Woocommerce_Modules :: get_title_header ()
*
* @ return string
*/
public static function get_title_selector () {
return sprintf ( 'li.product %s' , self :: get_title_header () );
}
/**
* Appends Data Icon attribute to the Outer wrapper .
*
* @ param array $outer_wrapper_attrs Key value pairs of outer wrapper attributes .
* @ param mixed $this_class Module ' s class .
*
* @ return array
*/
public static function output_data_icon_attrs ( $outer_wrapper_attrs , $this_class ) {
$hover_icon = et_ () -> array_get ( $this_class -> props , 'hover_icon' , '' );
$hover_icon_values = et_pb_responsive_options () -> get_property_values ( $this_class -> props , 'hover_icon' );
$hover_icon_tablet = et_ () -> array_get ( $hover_icon_values , 'tablet' , '' );
$hover_icon_phone = et_ () -> array_get ( $hover_icon_values , 'phone' , '' );
$hover_icon_sticky = et_pb_sticky_options () -> get_value ( 'hover_icon' , $this_class -> props );
$overlay_attributes = ET_Builder_Module_Helper_Overlay :: get_attributes (
array (
'icon' => $hover_icon ,
'icon_tablet' => $hover_icon_tablet ,
'icon_phone' => $hover_icon_phone ,
'icon_sticky' => $hover_icon_sticky ,
)
);
return array_merge ( $outer_wrapper_attrs , $overlay_attributes );
}
/**
* Return all possible product tabs .
* See woocommerce_default_product_tabs () in woocommerce / includes / wc - template - functions . php
*
* @ return array
*/
public static function get_default_product_tabs () {
$tabs = array (
'description' => array (
'title' => esc_html__ ( 'Description' , 'et_builder' ),
'priority' => 10 ,
'callback' => 'woocommerce_product_description_tab' ,
),
'additional_information' => array (
'title' => esc_html__ ( 'Additional information' , 'et_builder' ),
'priority' => 20 ,
'callback' => 'woocommerce_product_additional_information_tab' ,
),
'reviews' => array (
'title' => esc_html__ ( 'Reviews' , 'et_builder' ),
'priority' => 30 ,
'callback' => 'comments_template' ,
),
);
// Add custom tabs on default for theme builder.
if ( et_builder_tb_enabled () ) {
et_theme_builder_wc_set_global_objects ();
$tabs = apply_filters ( 'woocommerce_product_tabs' , $tabs );
et_theme_builder_wc_reset_global_objects ();
}
return $tabs ;
}
public static function get_default_tab_options () {
$tabs = self :: get_default_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 calculated star rating width based on letter spacing value .
*
* WooCommerce ' s . star - rating uses `em` based width on float layout ;
* any additional width caused by letter - spacing makes the calculation incorrect ;
* thus the `width: calc()` overwrite .
*
* @ param string $value
*
* @ return string
*/
public static function get_rating_width_style ( $value ) {
$value = et_builder_process_range_value ( $value );
$property_value = 'calc(5.4em + (' . $value . ' * 4))' ;
return sprintf ( 'width: %1$s;' , esc_html ( $property_value ) );
}
/**
* Get margin properties & values based on current alignment status .
*
* Default star alignment is not controlled by standard text align system . It uses float to control
* how stars symbol will be displayed based on the percentage . It ' s not possible to convert it to
* simple text align . We have to use margin left & right to set the alignment .
*
* @ param string $align
* @ param string $mode
*
* @ return string
*/
public static function get_rating_alignment_style ( $align , $mode = 'desktop' ) {
// Bail early if mode is desktop and alignment is left or justify.
if ( 'desktop' === $mode && in_array ( $align , array ( 'left' , 'justify' ) ) ) {
return array ();
}
$margin_properties = array (
'center' => array (
'left' => 'auto' ,
'right' => 'auto' ,
),
'right' => array (
'left' => 'auto' ,
'right' => '0' ,
),
);
// By default (left or justify), the margin will be left: inherit and right: auto.
$margin_left = et_ () -> array_get ( $margin_properties , " { $align } .left " , '0' );
$margin_right = et_ () -> array_get ( $margin_properties , " { $align } .right " , 'auto' );
return sprintf (
'margin-left: %1$s !important; margin-right: %2$s !important;' ,
esc_html ( $margin_left ),
esc_html ( $margin_right )
);
}
/**
* Get specific star rating style based on property type .
*
* @ param string $type
* @ param string $value
* @ param string $mode
*
* @ return array
*/
public static function get_rating_style ( $type , $value , $mode = 'desktop' ) {
$style = array ();
switch ( $type ) {
case 'rating_letter_spacing' :
$style = self :: get_rating_width_style ( $value );
break ;
case 'rating_text_align' :
$style = self :: get_rating_alignment_style ( $value , $mode );
break ;
}
return $style ;
}
/**
* Set styles for Woo ' s . star - rating element .
*
* @ since 3.29
*
* @ param string $render_slug
* @ param array $attrs
* @ param string $selector
* @ param string $hover_selector
*
* @ return void
*/
public static function add_star_rating_style ( $render_slug , $attrs , $selector = '%%order_class%% .star-rating' , $hover_selector = '%%order_class%%:hover .star-rating' , $props = array () ) {
// Supported star rating properties will be handled here.
if ( ! is_array ( $props ) || empty ( $props ) ) {
$props = array ( 'rating_letter_spacing' , 'rating_text_align' );
}
foreach ( $props as $prop ) {
// Get raw value.
$values = et_pb_responsive_options () -> get_property_values ( $attrs , $prop );
$hover_value = et_pb_hover_options () -> get_value ( $prop , $attrs , '' );
$processed_values = array ();
// Get specific style value for desktop, tablet, and phone.
foreach ( $values as $device => $value ) {
if ( empty ( $value ) ) {
continue ;
}
$processed_values [ $device ] = self :: get_rating_style ( $prop , $value , $device );
}
// Generate style for desktop, tablet, and phone.
et_pb_responsive_options () -> declare_responsive_css (
$processed_values ,
$selector ,
$render_slug
);
// Generate style for hover.
if ( et_builder_is_hover_enabled ( $prop , $attrs ) && ! empty ( $hover_value ) ) {
ET_Builder_Element :: set_style (
$render_slug ,
array (
'selector' => $hover_selector ,
'declaration' => self :: get_rating_style ( $prop , $hover_value , 'hover' , true ),
)
);
}
}
}
/**
* Get the product default .
*
* @ return array
*/
public static function get_product_default () {
return array (
'filter' ,
'et_builder_get_woo_default_product' ,
);
}
/**
* Get the product default value for the current post type .
*
* @ return string
*/
public static function get_product_default_value () {
$post_id = et_core_page_resource_get_the_ID ();
$post_id = $post_id ? $post_id : ( int ) et_ () -> array_get ( $_POST , 'current_page.id' );
$post_type = get_post_type ( $post_id );
if ( 'product' === $post_type || et_theme_builder_is_layout_post_type ( $post_type ) ) {
return 'current' ;
}
return 'latest' ;
}
/**
* Converts the special chars in to their entities to be used in : before or : after
* pseudo selector content .
*
* @ param string $chars
*
* @ since 4.0
* @ see https :// github . com / elegantthemes / Divi / issues / 16976
*
* @ return string
*/
public static function escape_special_chars ( $chars ) {
switch ( trim ( $chars ) ) {
case '&' :
return '\0026' ;
case '>' :
case '”>”' :
return '\003e' ;
default :
return $chars ;
}
}
/**
* Gets the WooCommerce Tabs defaults .
*
* Implementation based on
*
* @ see https :// github . com / elegantthemes / submodule - builder / pull / 6568
*
* @ since 4.4 . 2
*
* @ return array
*/
public static function get_woo_default_tabs () {
return array (
'filter' ,
'et_builder_get_woo_default_tabs' ,
);
}
/**
* Gets the WooCommerce Tabs options for the given Product .
*
* @ since 4.4 . 2
*
* @ return string
*/
public static function get_woo_default_tabs_options () {
$maybe_product_id = self :: get_product_default_value ();
$product_id = self :: get_product ( $maybe_product_id );
$current_product = wc_get_product ( $product_id );
if ( ! $current_product ) {
return '' ;
}
global $product , $post ;
$original_product = $product ;
$original_post = $post ;
$product = $current_product ;
$post = get_post ( $product -> get_id () );
$tabs = apply_filters ( 'woocommerce_product_tabs' , array () );
// Reset global $product.
$product = $original_product ;
$post = $original_post ;
if ( ! empty ( $tabs ) ) {
return implode ( '|' , array_keys ( $tabs ) );
}
return '' ;
}
/**
* Sets the Display type to render only Products .
*
* @ since 4.1 . 0
*
* @ see https :// github . com / elegantthemes / Divi / issues / 17998
*
* @ used - by ET_Builder_Module_Woocommerce_Related_Products :: render ()
* @ used - by ET_Builder_Module_Woocommerce_Upsells :: render ()
*
* @ param string $option_name
* @ param string $display_type
*
* @ return string
*/
public static function set_display_type_to_render_only_products ( $option_name , $display_type = '' ) {
$existing_display_type = get_option ( $option_name );
update_option ( $option_name , $display_type );
return $existing_display_type ;
}
/**
* Resets the display type to the existing value .
*
* @ since 4.1 . 0
*
* @ see https :// github . com / elegantthemes / Divi / issues / 17998
*
* @ used - by ET_Builder_Module_Woocommerce_Related_Products :: render ()
* @ used - by ET_Builder_Module_Woocommerce_Upsells :: render ()
*
* @ param $option_name
* @ param $display_type
*/
public static function reset_display_type ( $option_name , $display_type ) {
update_option ( $option_name , $display_type );
}
2021-12-20 18:06:11 +00:00
/**
* Stops Checkout Coupon form from rendering .
*
* @ deprecated
*/
public static function detach_wc_before_checkout_form () {
remove_action ( 'woocommerce_before_checkout_form' , 'woocommerce_checkout_coupon_form' , 10 );
}
/**
* Stops Checkout Coupon form from rendering .
*/
public static function detach_wc_checkout_coupon_form () {
remove_action ( 'woocommerce_before_checkout_form' , 'woocommerce_checkout_coupon_form' , 10 );
}
/**
* Stops Login Coupon form from rendering .
*/
public static function detach_wc_checkout_login_form () {
remove_action ( 'woocommerce_before_checkout_form' , 'woocommerce_checkout_login_form' , 10 );
}
/**
* Enable `woocommerce_before_checkout_form` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_before_checkout_form () {
add_action (
'woocommerce_before_checkout_form' ,
'woocommerce_checkout_coupon_form' ,
10
);
}
/**
* Enable `woocommerce_before_checkout_form` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_coupon_form () {
add_action (
'woocommerce_before_checkout_form' ,
'woocommerce_checkout_coupon_form' ,
10
);
}
/**
* Enable `woocommerce_before_checkout_form` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_login_form () {
add_action (
'woocommerce_before_checkout_form' ,
'woocommerce_checkout_login_form' ,
10
);
}
/**
* Remove `woocommerce_checkout_billing` hook .
*
* @ since 4.14 . 0
*/
public static function detach_wc_checkout_billing () {
if ( ! function_exists ( 'WC' ) ) {
return ;
}
$class = get_class ( WC () );
if ( ! method_exists ( $class , 'checkout' ) ) {
return ;
}
$checkout = WC () -> checkout ();
remove_action (
'woocommerce_checkout_billing' ,
array ( $checkout , 'checkout_form_billing' )
);
}
/**
* Enable `woocommerce_checkout_billing` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_billing () {
if ( ! function_exists ( 'WC' ) ) {
return ;
}
$class = get_class ( WC () );
if ( ! method_exists ( $class , 'checkout' ) ) {
return ;
}
$checkout = WC () -> checkout ();
add_action ( 'woocommerce_checkout_billing' , array ( $checkout , 'checkout_form_billing' ) );
}
/**
* Remove `woocommerce_checkout_shipping` hook .
*
* @ since 4.14 . 0
*/
public static function detach_wc_checkout_shipping () {
if ( ! function_exists ( 'WC' ) ) {
return ;
}
$class = get_class ( WC () );
if ( ! method_exists ( $class , 'checkout' ) ) {
return ;
}
$checkout = WC () -> checkout ();
remove_action (
'woocommerce_checkout_shipping' ,
array ( $checkout , 'checkout_form_shipping' )
);
}
/**
* Enable `woocommerce_checkout_shipping` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_shipping () {
if ( ! function_exists ( 'WC' ) ) {
return ;
}
$class = get_class ( WC () );
if ( ! method_exists ( $class , 'checkout' ) ) {
return ;
}
$checkout = WC () -> checkout ();
add_action (
'woocommerce_checkout_shipping' ,
array ( $checkout , 'checkout_form_shipping' )
);
}
/**
* Remove `woocommerce_checkout_order_review` hook .
*
* @ since 4.14 . 0
*/
public static function detach_wc_checkout_payment () {
remove_action (
'woocommerce_checkout_order_review' ,
'woocommerce_checkout_payment' ,
20
);
}
/**
* Enable `woocommerce_checkout_order_review` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_payment () {
add_action (
'woocommerce_checkout_order_review' ,
'woocommerce_checkout_payment' ,
20
);
}
/**
* Stops Order review ( Mini cart ) and Checkout Payment from rendering .
*
* @ used - by ET_Builder_Module_Woocommerce_Checkout_Billing :: get_checkout_billing ()
* @ used - by ET_Builder_Module_Woocommerce_Checkout_Additional_Info :: get_additional_info ()
*/
public static function detach_wc_checkout_order_review () {
remove_action (
'woocommerce_checkout_order_review' ,
'woocommerce_order_review' ,
10
);
}
/**
* Enable `woocommerce_checkout_order_review` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_checkout_order_review () {
add_action ( 'woocommerce_checkout_order_review' , 'woocommerce_order_review' , 10 );
}
/**
* Remove `woocommerce_cart_collaterals` hook .
*
* @ since 4.14 . 0
*/
public static function detach_wc_cart_totals () {
remove_action (
'woocommerce_cart_collaterals' ,
'woocommerce_cart_totals' ,
10
);
}
/**
* Enable `woocommerce_cart_collaterals` hook .
*
* @ since 4.14 . 0
*/
public static function attach_wc_cart_totals () {
add_action ( 'woocommerce_cart_collaterals' , 'woocommerce_cart_totals' , 10 );
}
/**
* Gets the required HTML data attributes based on the button name and slug .
*
* @ param array $module_props Module attributes .
* @ param string $btn_slug Shortcode attribute name ( i . e button_ { device }) .
* @ param string $btn_class Class name of the button to target in JS .
*
* @ return array
*/
public static function get_button_icon_attrs ( $module_props , $btn_slug = 'button' , $btn_class = 'button' ) {
$attrs = array ();
// Get Icon values based on Device.
$custom_icon_values = et_pb_responsive_options () -> get_property_values ( $module_props , " { $btn_slug } _icon " , '' , true );
$custom_icon = et_ () -> array_get ( $custom_icon_values , 'desktop' );
$custom_icon_tablet = et_ () -> array_get ( $custom_icon_values , 'tablet' );
$custom_icon_phone = et_ () -> array_get ( $custom_icon_values , 'phone' );
if ( empty ( $btn_name ) ) {
$btn_name = 'button' ;
}
$icon_values = array (
" data- { $btn_name } -icon " => $custom_icon ,
" data- { $btn_name } -icon-tablet " => $custom_icon_tablet ,
" data- { $btn_name } -icon-phone " => $custom_icon_phone ,
);
// Verify if Custom icon value exists at least in one of Desktop / Tablet / Phone.
$has_custom_icon = count ( array_filter ( $icon_values ) ) > 0 ;
if ( ! $has_custom_icon ) {
return $attrs ;
}
$attrs [ 'data-button-class' ] = et_core_intentionally_unescaped ( $btn_class , 'fixed_string' );
// Get the icon data-* attributes based on values set in DB.
foreach ( $icon_values as $attr_name => $attr_value ) {
if ( empty ( $attr_value ) ) {
continue ;
}
$attrs [ $attr_name ] = esc_attr ( et_pb_process_font_icon ( $attr_value ) );
}
return $attrs ;
}
/**
* Sets the Button ' s data -* attrs for the Icons to render .
*
* These attributes are set on the outer wrapper & will be set on the Button elements using JS .
*
* @ param array $module_props Module attributes / properties .
*
* @ return array
*/
public static function add_custom_icon_attrs ( $module_props ) {
if ( ! is_array ( $module_props ) || empty ( $module_props ) ) {
return array ();
}
$btn_attrs = self :: get_button_icon_attrs ( $module_props );
return $btn_attrs ;
}
/**
* Adds mock Products to Cart .
*
* Otherwise Checkout modules won ' t output content . The output is made visible only to VB .
*
* @ param array $cart_contents Cart contents .
*
* @ return array
* @ since 4.14 . 0
*/
public static function set_dummy_cart_contents ( $cart_contents ) {
if ( ! is_array ( $cart_contents ) ) {
return $cart_contents ;
}
$cart_contents = array ();
$fake_products = array (
999 => array (
'name' => esc_html__ ( 'Product 1' , 'et_builder' ),
'price' => '12.00' ,
'quantity' => 3 ,
),
1000 => array (
'name' => esc_html__ ( 'Product 2' , 'et_builder' ),
'price' => '75.00' ,
'quantity' => 1 ,
),
1001 => array (
'name' => esc_html__ ( 'Product 3' , 'et_builder' ),
'price' => '38.00' ,
'quantity' => 2 ,
),
);
foreach ( $fake_products as $id => $details ) {
$product = new ET_Builder_Woocommerce_Product_Simple_Placeholder ();
$product -> set_name ( $details [ 'name' ] );
$product -> set_id ( $id );
$product -> set_price ( $details [ 'price' ] );
$cart_item_key = WC () -> cart -> generate_cart_id ( $product -> get_id () );
$cart_contents [ $cart_item_key ] = array (
'key' => $cart_item_key ,
'product_id' => $product -> get_id (),
'variation_id' => 0 ,
'variation' => array (),
'quantity' => $details [ 'quantity' ],
'data' => $product ,
'data_hash' => wc_get_cart_item_data_hash ( $product ),
);
}
return $cart_contents ;
}
/**
* Get the product default .
*
* @ return array
*/
public static function get_page_type_default () {
return array (
'filter' ,
'et_builder_get_woo_default_page_type' ,
);
}
/**
* Get the Page Type default based on the Cart & Checkout pages .
*
* @ since 4.14 . 0
*
* @ return string
*/
public static function get_page_type_default_value () {
$is_cart_page = function_exists ( 'is_cart' ) && is_cart ();
$is_checkout_page = function_exists ( 'is_checkout' ) && is_checkout ();
if ( $is_cart_page ) {
return 'cart' ;
} elseif ( $is_checkout_page ) {
return 'checkout' ;
} else {
return 'product' ;
}
}
/**
* Gets the TB Post ID That Uses Body Template .
*
* @ param int $post_id Post ID .
*
* @ return mixed Template Post ID .
*/
public static function get_tb_template_id_by_current_page_id ( $post_id ) {
if ( ! $post_id ) {
return ;
}
$args = array (
'post_type' => 'et_template' ,
'meta_query' => array (
array (
'key' => '_et_body_layout_id' ,
'value' => $post_id ,
),
),
);
$query = new WP_Query ( $args );
$template_id = 0 ;
while ( $query -> have_posts () ) {
the_post ();
$template_id = get_the_ID ();
if ( 0 !== $template_id ) {
break ;
}
}
wp_reset_postdata ();
return $template_id ;
}
2021-12-07 11:08:05 +00:00
}
add_filter (
'et_builder_get_woo_default_columns' ,
array (
'ET_Builder_Module_Helper_Woocommerce_Modules' ,
'get_columns_posts_default_value' ,
)
);
add_filter (
'et_builder_get_woo_default_product' ,
array (
'ET_Builder_Module_Helper_Woocommerce_Modules' ,
'get_product_default_value' ,
)
);
add_filter (
'et_builder_get_woo_default_tabs' ,
array (
'ET_Builder_Module_Helper_Woocommerce_Modules' ,
'get_woo_default_tabs_options' ,
)
);
2021-12-20 18:06:11 +00:00
add_filter (
'et_builder_get_woo_default_page_type' ,
array (
'ET_Builder_Module_Helper_Woocommerce_Modules' ,
'get_page_type_default_value' ,
)
);
2021-12-07 11:08:05 +00:00
}