FCDM-website-new/wp-content/themes/primer/inc/compat/woocommerce.php

714 lines
18 KiB
PHP

<?php
/**
* WooCommerce compatibility.
*
* @package Compatibility
* @subpackage WooCommerce
* @category Core
* @author GoDaddy
* @since 1.0.0
*/
/**
* Enable support for WooCommerce.
*
* @action after_setup_theme
* @uses [add_theme_support](https://developer.wordpress.org/reference/functions/add_theme_support/) To enable WooCommerce support.
*
* @link https://docs.woothemes.com/document/third-party-custom-theme-compatibility/
*
* @since 1.0.0
*/
function primer_wc_setup() {
add_theme_support( 'woocommerce' );
}
add_action( 'after_setup_theme', 'primer_wc_setup' );
/**
* Add body class to indicate when WooCommerce is localized.
*
* @filter body_class
*
* @since 1.6.0
*
* @param array $classes Array of body classes.
*
* @return array
*/
function primer_wc_l10n_body_class( array $classes ) {
global $l10n;
if ( ! empty( $l10n['woocommerce'] ) ) {
$classes[] = 'primer-woocommerce-l10n';
}
return $classes;
}
add_filter( 'body_class', 'primer_wc_l10n_body_class' );
/**
* Remove the default WooCommerce page wrapper.
*
* @since 1.0.0
*/
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper' );
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end' );
/**
* Markup for page wrapper start.
*
* @action woocommerce_before_main_content
*
* @since 1.0.0
*
* @return mixed Returns the opening WooCommerce content wrappers.
*/
function primer_wc_wrapper_start() {
?>
<div id="primary" class="content-area">
<main id="main" class="site-main" role="main">
<article class="primer-woocommerce hentry">
<?php
}
add_action( 'woocommerce_before_main_content', 'primer_wc_wrapper_start' );
/**
* Markup for page wrapper end.
*
* @action woocommerce_after_main_content
*
* @since 1.0.0
*
* @return mixed Returns the closing WooCommerce content wrappers.
*/
function primer_wc_wrapper_end() {
?>
</article></main></div>
<?php
}
add_action( 'woocommerce_after_main_content', 'primer_wc_wrapper_end' );
/**
* Add tertiary sidebar to WooCommerce templates.
*
* @action woocommerce_sidebar
* @uses [get_sidebar](https://developer.wordpress.org/reference/functions/get_sidebar/) To display the sidebar.
*
* @since 1.0.0
*/
function primer_wc_sidebar() {
get_sidebar( 'tertiary' );
}
add_action( 'woocommerce_sidebar', 'primer_wc_sidebar' );
/**
* Display WooCommerce messages above post and page content.
*
* @action primer_before_post_content
* @action primer_before_page_content
* @uses [is_checkout](https://docs.woocommerce.com/wc-apidocs/function-is_checkout.html) To confirm user is not on the checkout page.
*
* @since 1.0.0
*
* @return mixed Returns `[woocommerce_message]` shortcode if not on the checkout page.
*/
function primer_wc_shop_messages() {
if ( function_exists( 'is_checkout' ) && ! is_checkout() ) {
echo wp_kses_post( do_shortcode( '[woocommerce_messages]' ) );
}
}
add_action( 'primer_before_post_content', 'primer_wc_shop_messages' );
add_action( 'primer_before_page_content', 'primer_wc_shop_messages' );
/**
* Filter the layout for the WooCommerce shop page.
*
* @filter primer_current_layout
* @uses primer_get_layout To retreive the page layout.
*
* @since 1.0.0
*
* @param string $layout The default layout for the page.
*
* @return mixed string Returns the shop page layout.
*/
function primer_wc_shop_layout( $layout ) {
if ( is_shop() ) {
remove_filter( 'primer_current_layout', __FUNCTION__ ); // Prevent infinite loop.
$layout = primer_get_layout( wc_get_page_id( 'shop' ) );
}
return $layout;
}
add_filter( 'primer_current_layout', 'primer_wc_shop_layout' );
/**
* Filter the WooCommerce shop page title.
*
* @filter primer_the_page_title
* @uses [get_the_title](https://developer.wordpress.org/reference/functions/get_the_title/) To retreive the shop page title.
*
* @since 1.0.0
*
* @param string $title The page title.
*
* @return string Returns the shop page title.
*/
function primer_wc_shop_title( $title ) {
if ( is_shop() ) {
add_filter( 'woocommerce_page_title', '__return_null' );
$title = get_the_title( wc_get_page_id( 'shop' ) );
}
if ( is_product() ) {
$labels = get_post_type_labels( get_post_type_object( 'product' ) );
$title = ! empty( $labels->singular_name ) ? $labels->singular_name : $title;
}
return $title;
}
add_filter( 'primer_the_page_title', 'primer_wc_shop_title' );
/**
* Change the number of shop columns based on the Primer layout.
*
* @filter loop_shop_columns
* @filter woocommerce_related_products_columns
* @filter woocommerce_upsells_products_columns
*
* @global WP_Post $post
*
* @uses [is_shop](https://docs.woocommerce.com/wc-apidocs/function-is_shop.html) To check the if on the WooCommerce shop page.
* @uses [wc_get_page_id](https://docs.woocommerce.com/wc-apidocs/function-wc_get_page_id.html) To retreive the WooCommerce page id.
* @uses primer_get_layout To check if the current page is three columns.
*
* @since 1.0.0
*
* @param int $columns $columns The default number of columns.
*
* @return int The number of columns to use.
*/
function primer_wc_shop_columns( $columns ) {
global $post;
$page_id = ( is_shop() ) ? wc_get_page_id( 'shop' ) : $post->ID;
if ( 0 === strpos( primer_get_layout( absint( $page_id ) ), 'three-column-' ) ) {
add_filter( 'post_class', 'primer_wc_product_classes' );
$columns = 2;
}
return $columns;
}
add_filter( 'loop_shop_columns', 'primer_wc_shop_columns' );
add_filter( 'woocommerce_related_products_columns', 'primer_wc_shop_columns' );
add_filter( 'woocommerce_upsells_products_columns', 'primer_wc_shop_columns' );
/**
* Add post class to support 2-column product layouts in Primer.
*
* @filter post_class
*
* @global WP_Post $post
* @global array $woocommerce_loop
*
* @since 1.0.0
*
* @param array $classes Array of body classes.
*
* @return array Returns the array of body classes.
*/
function primer_wc_product_classes( $classes ) {
global $post, $woocommerce_loop;
// Check if we are on a single product page.
$is_product = ( is_shop() && 'product' === $post->post_type );
// Check if we are in an upsell or related product loop.
$is_upsell_or_related = (
is_single()
&&
isset( $woocommerce_loop['name'] )
&&
'product' === $post->post_type
&&
( 'related' === $woocommerce_loop['name'] || 'up-sells' === $woocommerce_loop['name'] )
);
if ( $is_product || $is_upsell_or_related ) {
$classes[] = 'primer-2-column-product';
}
return $classes;
}
/**
* Add color scheme targets for WooCommerce elements.
*
* @filter primer_colors
* @uses primer_array_replace_recursive To replace items in the colors array with new values.
*
* @since 1.0.0
*
* @param array $colors Original Primer_Customizer_Colors color array.
*
* @return array Returns the CSS replacements for WooCommerce elements.
*/
function primer_wc_colors( $colors ) {
$wc_colors = array(
'primary_text_color' => array(
'css' => array(
'ul.cart_list li.mini_cart_item a:nth-child(2)' => array(
'color' => '%1$s',
),
),
'rgba_css' => array(
'ul.cart_list li.mini_cart_item a:nth-child(2):hover' => array(
'color' => 'rgba(%1$s, 0.8)',
),
),
),
'link_color' => array(
'css' => array(
'.woocommerce .star-rating' => array(
'color' => '%1$s',
),
),
),
'button_color' => array(
'css' => array(
'.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce a.button,
.woocommerce a.button.alt,
.woocommerce button.button.alt.disabled,
.woocommerce button.button.alt.disabled:hover,
.woocommerce #respond input#submit,
.woocommerce .product span.onsale,
.primer-wc-cart-menu .widget_shopping_cart p.buttons a,
.primer-wc-cart-menu .widget_shopping_cart p.buttons a:visited,
ul.products a.button,
ul.products a.button:visited' => array(
'background-color' => '%1$s',
'border-color' => '%1$s',
),
),
'rgba_css' => array(
'.woocommerce button.button.alt:hover, .woocommerce button.button.alt:active, .woocommerce button.button.alt:focus,
.woocommerce input.button.alt:hover, .woocommerce input.button.alt:active, .woocommerce input.button.alt:focus,
.woocommerce a.button:hover, .woocommerce a.button:active, .woocommerce a.button:focus,
.woocommerce a.button.alt:hover, .woocommerce a.button.alt:active, .woocommerce a.button.alt:focus,
.woocommerce #respond input#submit:hover,
.primer-wc-cart-menu .widget_shopping_cart p.buttons a:hover,
a.button:hover,
ul.products .button:hover, ul.products .button:active, ul.products .button:focus' => array(
'background-color' => 'rgba(%1$s, 0.8)',
'border-color' => 'rgba(%1$s, 0.8)',
),
),
),
'button_text_color' => array(
'css' => array(
'.woocommerce button.button.alt, .woocommerce button.button.alt:hover,
.woocommerce input.button.alt, .woocommerce input.button.alt:hover,
.woocommerce a.button, .woocommerce a.button:visited, .woocommerce a.button:hover, .woocommerce a.button:visited:hover,
.woocommerce a.button.alt, .woocommerce a.button.alt:visited, .woocommerce a.button.alt:hover, .woocommerce a.button.alt:visited:hover,
.woocommerce #respond input#submit, .woocommerce #respond input#submit:hover,
.woocommerce .product span.onsale' => array(
'color' => '%1$s',
),
),
),
'background_color' => array(
'css' => array(
'li.primer-wc-cart-menu .primer-wc-cart-sub-menu' => array(
'background-color' => '%1$s',
),
),
),
);
return primer_array_replace_recursive( $colors, $wc_colors );
}
add_filter( 'primer_colors', 'primer_wc_colors' );
/**
* Add font type targets for WooCommerce elements.
*
* @filter primer_font_types
* @uses primer_array_replace_recursive To replace items in the font types array with new values.
*
* @since 1.0.0
*
* @param array $font_types Original Primer_Customizer_Fonts font type array.
*
* @return array Returns an array of font alterations for WooCommerce elements.
*/
function primer_wc_font_types( $font_types ) {
$wc_font_types = array(
'navigation_font' => array(
'css' => array(
'.woocommerce button.button.alt,
.woocommerce input.button.alt,
.woocommerce a.button' => array(
'font-family' => '"%1$s", sans-serif',
),
),
),
);
return primer_array_replace_recursive( $font_types, $wc_font_types );
}
add_filter( 'primer_font_types', 'primer_wc_font_types' );
/**
* Change the theme overrides path for WooCommerce templates.
*
* @filter woocommerce_template_path
*
* @since 1.6.0
*
* @return string
*/
function primer_wc_template_path() {
return 'templates/woocommerce/';
}
add_filter( 'woocommerce_template_path', 'primer_wc_template_path' );
/**
* Load a custom template for WooCommerce 404 pages.
*
* @filter template_include
*
* @since 1.5.0
*
* @param string $template The path of the template to include.
*
* @return string
*/
function primer_wc_404_template( $template ) {
return ( is_404() && locate_template( 'templates/woocommerce/404.php' ) ) ? get_template_part( 'templates/woocommerce/404' ) : $template;
}
add_filter( 'template_include', 'primer_wc_404_template' );
/**
* Add a custom "Cart" menu item when WooCommerce is active.
*
* @filter wp_get_nav_menu_items
*
* @since 1.5.0
*
* @param array $items An array of menu item post objects.
* @param object $menu The menu object.
*
* @return array
*/
function primer_wc_generate_cart_menu_item( $items, $menu ) {
if ( ! primer_child_compat( 'wc__cart_menu_item', true ) ) {
return $items;
}
$theme_locations = get_nav_menu_locations();
if ( empty( $theme_locations['primary'] ) ) {
return $items;
}
$nav_obj = wp_get_nav_menu_object( $theme_locations['primary'] );
if ( $menu->term_id !== $theme_locations['primary'] || is_admin() ) {
return $items;
}
add_filter( "wp_nav_menu_{$nav_obj->slug}_items", 'primer_wc_cart_menu', 10, 2 );
return $items;
}
add_filter( 'wp_get_nav_menu_items', 'primer_wc_generate_cart_menu_item', 20, 2 );
/**
* Append a WooCommerce cart item to a navigation menu.
*
* @filter wp_nav_menu_{$menu}_items
*
* @global WooCommerce $woocommerce
*
* @since 1.5.0
*
* @param string $items The HTML list content for the menu items.
* @param stdClass $args An object containing wp_nav_menu() arguments.
*
* @return string
*/
function primer_wc_cart_menu( $items, $args ) {
/**
* Filter whether to display the WooCommerce cart menu item.
*
* Default: `true`
*
* @since 1.5.0
*
* @var bool
*/
if ( ! (bool) apply_filters( 'primer_wc_show_cart_menu', true ) ) {
return $items;
}
if ( is_customize_preview() ) {
add_filter( 'woocommerce_cart_contents_count', '__return_zero' );
add_filter( 'woocommerce_cart_contents_total', 'primer_wc_customize_preview_cart_contents_total' );
}
global $woocommerce;
$sub_menu = '';
$classes = array( 'menu-item', 'menu-item-type-nav_menu_item', 'menu-item-object-cart' );
if ( $woocommerce->cart->get_cart_contents_count() ) {
$sub_menu = sprintf(
'<ul class="sub-menu primer-wc-cart-sub-menu">
<li class="primer-wc-cart-sub-menu-item">%s</li>
</ul>',
primer_get_the_widget( 'WC_Widget_Cart' )
);
$classes[] = 'menu-item-has-children';
}
$cart_menu_item = sprintf(
'<li class="primer-wc-cart-menu primer-wc-cart-menu-item %s">
<a>
<span class="cart-preview-total">
<span class="woocommerce-price-amount amount">%s</span>
</span>
<span class="cart-preview-count">%s</span>
</a>
%s
%s
</li>',
implode( ' ', array_map( 'esc_attr', $classes ) ),
$woocommerce->cart->get_cart_total(),
esc_html( sprintf( _n( '%d item', '%d items', $woocommerce->cart->get_cart_contents_count(), 'primer' ), $woocommerce->cart->get_cart_contents_count() ) ),
$woocommerce->cart->get_cart_contents_count() ? '<a class="expand" href="#"></a>' : '',
$sub_menu
);
return $items . $cart_menu_item;
}
/**
* Empty the cart total during Customize preview.
*
* @filter woocommerce_cart_contents_total
* @uses [wc_price](https://docs.woocommerce.com/wc-apidocs/function-wc_price.html) To format the price with a currency symbol.
*
* @since 1.5.0
*
* @return string
*/
function primer_wc_customize_preview_cart_contents_total() {
return wc_price( 0 );
}
if ( ! function_exists( 'primer_wc_promoted_products' ) ) {
/**
* Display promoted products.
*
* Check for featured products then on-sale products and use the appropiate
* shortcode. If neither exist, the default fallback is to display recently
* added products.
*
* @since 1.5.0
*
* @uses [wc_get_featured_product_ids](https://docs.woocommerce.com/wc-apidocs/function-wc_get_featured_product_ids.html) To retreive the products that are featured.
* @uses [wc_get_product_ids_on_sale](https://docs.woocommerce.com/wc-apidocs/function-wc_get_product_ids_on_sale.html) To retreive the products that are on sale.
*
* @param int $per_page (optional) Total number of promoted products to display. Defaults to `4`.
* @param int $columns (optional) Number of columns to display promoted products in. Defaults to `4`.
* @param bool $recent_fallback (optional) Whether to display recent products as a fallback when there are no featured or on-sale products. Defaults to `true`.
*/
function primer_wc_promoted_products( $per_page = 4, $columns = 4, $recent_fallback = true ) {
/**
* Filter the total number of promoted products to display.
*
* Default: `4`
*
* @since 1.5.0
*
* @var int
*/
$per_page = (int) apply_filters( 'primer_wc_promoted_products_per_page', $per_page ); // Can be negative.
/**
* Filter the number of columns to display promoted products in.
*
* Default: `4`
*
* @since 1.5.0
*
* @var int
*/
$columns = absint( apply_filters( 'primer_wc_promoted_products_columns', $columns ) );
if ( wc_get_featured_product_ids() ) {
echo '<h2>' . esc_html__( 'Featured Products', 'primer' ) . '</h2>';
echo do_shortcode( "[featured_products per_page='{$per_page}' columns='{$columns}']" );
return;
}
if ( wc_get_product_ids_on_sale() ) {
echo '<h2>' . esc_html__( 'On Sale Now', 'primer' ) . '</h2>';
echo do_shortcode( "[sale_products per_page='{$per_page}' columns='{$columns}']" );
return;
}
if ( ! $recent_fallback ) {
return;
}
echo '<h2>' . esc_html__( 'New In Store', 'primer' ) . '</h2>';
echo do_shortcode( "[recent_products per_page='{$per_page}' columns='{$columns}']" );
}
}
if ( ! function_exists( 'primer_wc_best_selling_products' ) ) {
/**
* Display best-selling products.
*
* @since 1.5.0
*
* @param int $per_page (optional) Total number of best-selling products to display. Defaults to `4`.
* @param int $columns (optional) Number of columns to display best-selling products in. Defaults to `4`.
*/
function primer_wc_best_selling_products( $per_page = 4, $columns = 4 ) {
/**
* Filter the total number of best-selling products to display.
*
* Default: `4`
*
* @since 1.5.0
*
* @var int
*/
$per_page = (int) apply_filters( 'primer_wc_best_selling_products_per_page', $per_page ); // Can be negative.
/**
* Filter the number of columns to display best-selling products in.
*
* Default: `4`
*
* @since 1.5.0
*
* @var int
*/
$columns = absint( apply_filters( 'primer_wc_best_selling_products_columns', $columns ) );
echo do_shortcode( "[best_selling_products per_page='{$per_page}' columns='{$columns}']" );
}
}
/**
* Prevent WooCommerce product image from loading as the header image
*
* @return boolean False if a WooCommerce product, else true
*
* @since 1.7.0
*/
function primer_wc_product_header_image() {
/**
* Filter whether the WooCommerce product should be used as the header image
*
* @since 1.7.0
*/
return apply_filters( 'primer_wc_product_header_image', ! is_product() );
}
add_filter( 'primer_use_featured_hero_image', 'primer_wc_product_header_image' );