2013-06-06 12:27:04 +00:00
|
|
|
<?php
|
2013-09-12 13:41:02 +00:00
|
|
|
/**
|
2015-11-03 13:53:50 +00:00
|
|
|
* Template Loader
|
2013-09-12 13:41:02 +00:00
|
|
|
*
|
|
|
|
* @class WC_Template
|
|
|
|
* @package WooCommerce/Classes
|
|
|
|
* @category Class
|
2017-11-08 19:57:49 +00:00
|
|
|
* @author Automattic
|
|
|
|
*/
|
|
|
|
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
|
|
exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* WC_Template_Loader.
|
2013-09-12 13:41:02 +00:00
|
|
|
*/
|
|
|
|
class WC_Template_Loader {
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2017-11-09 10:44:29 +00:00
|
|
|
/**
|
|
|
|
* Store the shop page ID.
|
|
|
|
*
|
|
|
|
* @var integer
|
|
|
|
*/
|
|
|
|
private static $shop_page_id = 0;
|
|
|
|
|
2017-11-13 18:42:28 +00:00
|
|
|
/**
|
|
|
|
* Store whether we're processing a product inside the_content filter.
|
|
|
|
*
|
|
|
|
* @var boolean
|
|
|
|
*/
|
2017-11-10 20:48:45 +00:00
|
|
|
private static $in_content_filter = false;
|
|
|
|
|
2013-09-12 13:41:02 +00:00
|
|
|
/**
|
2015-11-03 13:31:20 +00:00
|
|
|
* Hook in methods.
|
2013-09-12 13:41:02 +00:00
|
|
|
*/
|
2014-05-28 13:52:50 +00:00
|
|
|
public static function init() {
|
2017-11-09 10:44:29 +00:00
|
|
|
self::$shop_page_id = wc_get_page_id( 'shop' );
|
|
|
|
|
2017-11-10 20:48:45 +00:00
|
|
|
// Supported themes.
|
2017-11-13 18:42:28 +00:00
|
|
|
if ( current_theme_supports( 'woocommerce' ) || in_array( get_template(), array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' ), true ) ) {
|
2017-11-10 20:48:45 +00:00
|
|
|
add_filter( 'template_include', array( __CLASS__, 'template_loader' ) );
|
|
|
|
add_filter( 'comments_template', array( __CLASS__, 'comments_template_loader' ) );
|
2017-11-13 18:08:46 +00:00
|
|
|
} else {
|
2017-11-13 18:42:28 +00:00
|
|
|
// Unsupported themes.
|
2017-11-13 18:08:46 +00:00
|
|
|
add_action( 'template_redirect', array( __CLASS__, 'unsupported_theme_init' ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Hook in methods to enhance the unsupported theme experience on Shop and Product pages.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_init() {
|
|
|
|
if ( self::$shop_page_id || is_product() ) {
|
2017-11-10 20:48:45 +00:00
|
|
|
add_filter( 'the_content', array( __CLASS__, 'unsupported_theme_content_filter' ), 10 );
|
|
|
|
add_filter( 'the_title', array( __CLASS__, 'unsupported_theme_title_filter' ), 10, 2 );
|
|
|
|
add_filter( 'post_thumbnail_html', array( __CLASS__, 'unsupported_theme_single_featured_image_filter' ) );
|
|
|
|
add_filter( 'woocommerce_product_tabs', array( __CLASS__, 'unsupported_theme_remove_review_tab' ) );
|
2017-11-09 10:44:29 +00:00
|
|
|
add_filter( 'comments_number', '__return_empty_string' );
|
2017-11-10 20:48:45 +00:00
|
|
|
|
|
|
|
if ( is_product() ) {
|
|
|
|
remove_action( 'woocommerce_before_main_content', 'woocommerce_output_content_wrapper', 10 );
|
|
|
|
remove_action( 'woocommerce_after_main_content', 'woocommerce_output_content_wrapper_end', 10 );
|
|
|
|
add_theme_support( 'wc-product-gallery-zoom' );
|
|
|
|
add_theme_support( 'wc-product-gallery-lightbox' );
|
|
|
|
add_theme_support( 'wc-product-gallery-slider' );
|
|
|
|
}
|
2017-11-09 10:44:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get information about the current shop page view.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
private static function get_current_shop_view_args() {
|
|
|
|
return (object) array(
|
|
|
|
'page' => absint( max( 1, absint( get_query_var( 'paged' ) ) ) ),
|
2017-11-09 17:34:54 +00:00
|
|
|
'columns' => wc_get_default_products_per_row(),
|
|
|
|
'rows' => wc_get_default_product_rows_per_page(),
|
2017-11-09 10:44:29 +00:00
|
|
|
);
|
2017-11-08 16:46:15 +00:00
|
|
|
}
|
|
|
|
|
2013-06-06 12:27:04 +00:00
|
|
|
/**
|
|
|
|
* Load a template.
|
|
|
|
*
|
|
|
|
* Handles template usage so that we can use our own templates instead of the themes.
|
|
|
|
*
|
2015-11-03 13:31:20 +00:00
|
|
|
* Templates are in the 'templates' folder. woocommerce looks for theme.
|
|
|
|
* overrides in /theme/woocommerce/ by default.
|
2013-06-06 12:27:04 +00:00
|
|
|
*
|
2015-11-03 13:31:20 +00:00
|
|
|
* For beginners, it also looks for a woocommerce.php template first. If the user adds.
|
|
|
|
* this to the theme (containing a woocommerce() inside) this will be used for all.
|
2013-06-06 12:27:04 +00:00
|
|
|
* woocommerce templates.
|
|
|
|
*
|
2017-11-09 10:44:29 +00:00
|
|
|
* @param string $template Template to load.
|
2013-06-06 12:27:04 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
2014-05-28 13:52:50 +00:00
|
|
|
public static function template_loader( $template ) {
|
2017-11-09 10:44:29 +00:00
|
|
|
if ( is_embed() ) {
|
2016-04-25 09:27:53 +00:00
|
|
|
return $template;
|
|
|
|
}
|
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
if ( $default_file = self::get_template_loader_default_file() ) {
|
|
|
|
/**
|
|
|
|
* Filter hook to choose which files to find before WooCommerce does it's own logic.
|
|
|
|
*
|
2017-03-15 16:36:53 +00:00
|
|
|
* @since 3.0.0
|
2016-12-06 11:52:15 +00:00
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
$search_files = self::get_template_loader_files( $default_file );
|
|
|
|
$template = locate_template( $search_files );
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
if ( ! $template || WC_TEMPLATE_DEBUG_MODE ) {
|
|
|
|
$template = WC()->plugin_path() . '/templates/' . $default_file;
|
|
|
|
}
|
|
|
|
}
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
return $template;
|
|
|
|
}
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
/**
|
|
|
|
* Get the default filename for a template.
|
|
|
|
*
|
2017-03-15 16:36:53 +00:00
|
|
|
* @since 3.0.0
|
2016-12-06 11:52:15 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
private static function get_template_loader_default_file() {
|
|
|
|
if ( is_singular( 'product' ) ) {
|
|
|
|
$default_file = 'single-product.php';
|
|
|
|
} elseif ( is_product_taxonomy() ) {
|
|
|
|
$term = get_queried_object();
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2014-05-22 09:51:40 +00:00
|
|
|
if ( is_tax( 'product_cat' ) || is_tax( 'product_tag' ) ) {
|
2016-12-06 11:52:15 +00:00
|
|
|
$default_file = 'taxonomy-' . $term->taxonomy . '.php';
|
2014-05-22 09:51:40 +00:00
|
|
|
} else {
|
2016-12-06 11:52:15 +00:00
|
|
|
$default_file = 'archive-product.php';
|
2014-05-22 09:51:40 +00:00
|
|
|
}
|
2016-12-06 11:52:15 +00:00
|
|
|
} elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id( 'shop' ) ) ) {
|
2017-11-09 10:44:29 +00:00
|
|
|
$default_file = current_theme_supports( 'woocommerce' ) ? 'archive-product.php' : '';
|
2016-12-06 11:52:15 +00:00
|
|
|
} else {
|
|
|
|
$default_file = '';
|
|
|
|
}
|
|
|
|
return $default_file;
|
|
|
|
}
|
2014-05-22 09:51:40 +00:00
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
/**
|
|
|
|
* Get an array of filenames to search for a given template.
|
|
|
|
*
|
2017-03-15 16:36:53 +00:00
|
|
|
* @since 3.0.0
|
2017-05-15 11:50:52 +00:00
|
|
|
* @param string $default_file The default file name.
|
2016-12-06 11:52:15 +00:00
|
|
|
* @return string[]
|
|
|
|
*/
|
|
|
|
private static function get_template_loader_files( $default_file ) {
|
|
|
|
$search_files = apply_filters( 'woocommerce_template_loader_files', array(), $default_file );
|
|
|
|
$search_files[] = 'woocommerce.php';
|
|
|
|
|
2017-09-20 14:47:30 +00:00
|
|
|
if ( is_page_template() ) {
|
|
|
|
$search_files[] = get_page_template_slug();
|
|
|
|
}
|
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
if ( is_product_taxonomy() ) {
|
|
|
|
$term = get_queried_object();
|
2017-01-31 08:56:27 +00:00
|
|
|
$search_files[] = 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
|
|
|
|
$search_files[] = WC()->template_path() . 'taxonomy-' . $term->taxonomy . '-' . $term->slug . '.php';
|
|
|
|
$search_files[] = 'taxonomy-' . $term->taxonomy . '.php';
|
|
|
|
$search_files[] = WC()->template_path() . 'taxonomy-' . $term->taxonomy . '.php';
|
2013-06-06 12:27:04 +00:00
|
|
|
}
|
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
$search_files[] = $default_file;
|
|
|
|
$search_files[] = WC()->template_path() . $default_file;
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2016-12-06 11:52:15 +00:00
|
|
|
return array_unique( $search_files );
|
2013-06-06 12:27:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-01-06 15:24:47 +00:00
|
|
|
* Load comments template.
|
2013-06-06 12:27:04 +00:00
|
|
|
*
|
2017-11-08 19:57:49 +00:00
|
|
|
* @param string $template template to load.
|
2013-06-06 12:27:04 +00:00
|
|
|
* @return string
|
|
|
|
*/
|
2014-05-28 13:52:50 +00:00
|
|
|
public static function comments_template_loader( $template ) {
|
2017-11-09 10:44:29 +00:00
|
|
|
if ( get_post_type() !== 'product' ) {
|
2013-06-06 12:27:04 +00:00
|
|
|
return $template;
|
2014-10-03 09:52:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$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() ),
|
2016-08-27 02:08:49 +00:00
|
|
|
trailingslashit( WC()->plugin_path() ) . 'templates/',
|
2014-10-03 09:52:11 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
if ( WC_TEMPLATE_DEBUG_MODE ) {
|
|
|
|
$check_dirs = array( array_pop( $check_dirs ) );
|
|
|
|
}
|
2013-06-06 12:27:04 +00:00
|
|
|
|
2014-10-03 09:52:11 +00:00
|
|
|
foreach ( $check_dirs as $dir ) {
|
|
|
|
if ( file_exists( trailingslashit( $dir ) . 'single-product-reviews.php' ) ) {
|
|
|
|
return trailingslashit( $dir ) . 'single-product-reviews.php';
|
|
|
|
}
|
|
|
|
}
|
2013-06-06 12:27:04 +00:00
|
|
|
}
|
2017-11-13 18:08:46 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Add a class to the body so we can better style things to look good when rendered in the content.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
2017-11-13 18:42:28 +00:00
|
|
|
* @param array $classes Classes to add to body.
|
2017-11-13 18:08:46 +00:00
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_body_class( $classes ) {
|
|
|
|
$classes[] = 'woocommerce-normalized-theme';
|
|
|
|
return $classes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter the title and insert WooCommerce content on the shop page.
|
|
|
|
*
|
|
|
|
* For non-WC themes, this will setup the main shop page to be shortcode based to improve default appearance.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
* @param string $title Existing title.
|
|
|
|
* @param int $id ID of the post being filtered.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_title_filter( $title, $id ) {
|
|
|
|
if ( ! current_theme_supports( 'woocommerce' ) && is_page( self::$shop_page_id ) && $id === self::$shop_page_id ) {
|
|
|
|
$args = self::get_current_shop_view_args();
|
|
|
|
$title_suffix = array();
|
|
|
|
|
|
|
|
if ( $args->page > 1 ) {
|
|
|
|
$title_suffix[] = sprintf( esc_html__( 'Page %d', 'woocommerce' ), $args->page );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $title_suffix ) {
|
|
|
|
$title = $title . ' – ' . implode( ', ', $title_suffix );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $title;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Filter the content and insert WooCommerce content on the shop page.
|
|
|
|
*
|
|
|
|
* For non-WC themes, this will setup the main shop page to be shortcode based to improve default appearance.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
* @param string $content Existing post content.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_content_filter( $content ) {
|
|
|
|
global $wp_query;
|
|
|
|
|
|
|
|
if ( current_theme_supports( 'woocommerce' ) || ! is_main_query() ) {
|
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
|
|
|
self::$in_content_filter = true;
|
|
|
|
|
|
|
|
// Remove the filter we're in to avoid nested calls.
|
|
|
|
remove_filter( 'the_content', array( __CLASS__, 'the_content_filter' ) );
|
|
|
|
|
|
|
|
// Unsupported theme shop page.
|
|
|
|
if ( is_page( self::$shop_page_id ) ) {
|
|
|
|
$args = self::get_current_shop_view_args();
|
|
|
|
$shortcode = new WC_Shortcode_Products(
|
|
|
|
array_merge(
|
|
|
|
wc()->query->get_catalog_ordering_args(),
|
|
|
|
array(
|
|
|
|
'page' => $args->page,
|
|
|
|
'columns' => $args->columns,
|
|
|
|
'rows' => $args->rows,
|
|
|
|
'orderby' => '',
|
|
|
|
'order' => '',
|
|
|
|
'paginate' => true,
|
|
|
|
'cache' => false,
|
|
|
|
)
|
|
|
|
),
|
|
|
|
'products' );
|
|
|
|
|
|
|
|
// Allow queries to run e.g. layered nav.
|
|
|
|
add_action( 'pre_get_posts', array( wc()->query, 'product_query' ) );
|
|
|
|
|
|
|
|
$content = $content . $shortcode->get_content();
|
|
|
|
|
|
|
|
// Remove actions and self to avoid nested calls.
|
|
|
|
remove_action( 'pre_get_posts', array( wc()->query, 'product_query' ) );
|
|
|
|
|
2017-11-13 18:42:28 +00:00
|
|
|
// Unsupported theme product page.
|
2017-11-13 18:08:46 +00:00
|
|
|
} elseif ( is_product() ) {
|
2017-11-13 18:36:58 +00:00
|
|
|
$content = do_shortcode( '[product_page id="' . get_the_ID() . '" show_title=0]' );
|
2017-11-13 18:08:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self::$in_content_filter = false;
|
|
|
|
|
|
|
|
return $content;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prevent the main featured image on product pages because there will be another featured image
|
|
|
|
* in the gallery.
|
|
|
|
*
|
|
|
|
* @since 3.3.0
|
|
|
|
* @param string $html Img element HTML.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_single_featured_image_filter( $html ) {
|
|
|
|
if ( self::$in_content_filter || ! is_product() || ! is_main_query() ) {
|
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove the Review tab and just use the regular comment form.
|
|
|
|
*
|
|
|
|
* @param array $tabs Tab info.
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public static function unsupported_theme_remove_review_tab( $tabs ) {
|
|
|
|
unset( $tabs['reviews'] );
|
|
|
|
return $tabs;
|
|
|
|
}
|
2013-08-06 17:04:10 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 19:56:24 +00:00
|
|
|
add_action( 'init', array( 'WC_Template_Loader', 'init' ) );
|