Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Diego Zanella 2016-02-13 22:59:28 +00:00
commit f83a6c0850
153 changed files with 1219 additions and 1334 deletions

File diff suppressed because one or more lines are too long

View File

@ -1083,29 +1083,12 @@ class WC_Product {
* @return string
*/
public function get_average_rating() {
global $wpdb;
// No meta date? Do the calculation
// No meta data? Do the calculation
if ( ! metadata_exists( 'post', $this->id, '_wc_average_rating' ) ) {
if ( $count = $this->get_rating_count() ) {
$ratings = $wpdb->get_var( $wpdb->prepare("
SELECT SUM(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
AND meta_value > 0
", $this->id ) );
$average = number_format( $ratings / $count, 2, '.', '' );
} else {
$average = 0;
}
update_post_meta( $this->id, '_wc_average_rating', $average );
} else {
$average = get_post_meta( $this->id, '_wc_average_rating', true );
$this->sync_average_rating( $this->id );
}
return (string) floatval( $average );
return (string) floatval( get_post_meta( $this->id, '_wc_average_rating', true ) );
}
/**
@ -1114,10 +1097,56 @@ class WC_Product {
* @return int
*/
public function get_rating_count( $value = null ) {
// No meta data? Do the calculation
if ( ! metadata_exists( 'post', $this->id, '_wc_rating_count' ) ) {
$this->sync_rating_count( $this->id );
}
$counts = get_post_meta( $this->id, '_wc_rating_count', true );
if ( is_null( $value ) ) {
return array_sum( $counts );
} else {
return isset( $counts[ $value ] ) ? $counts[ $value ] : 0;
}
}
/**
* Sync product rating. Can be called statically.
* @param int $post_id
*/
public static function sync_average_rating( $post_id ) {
if ( ! metadata_exists( 'post', $post_id, '_wc_rating_count' ) ) {
self::sync_rating_count( $post_id );
}
$count = array_sum( (array) get_post_meta( $post_id, '_wc_rating_count', true ) );
if ( $count ) {
global $wpdb;
$ratings = $wpdb->get_var( $wpdb->prepare("
SELECT SUM(meta_value) FROM $wpdb->commentmeta
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_post_ID = %d
AND comment_approved = '1'
AND meta_value > 0
", $post_id ) );
$average = number_format( $ratings / $count, 2, '.', '' );
} else {
$average = 0;
}
update_post_meta( $post_id, '_wc_average_rating', $average );
}
/**
* Sync product rating count. Can be called statically.
* @param int $post_id
*/
public static function sync_rating_count( $post_id ) {
global $wpdb;
// No meta date? Do the calculation
if ( ! metadata_exists( 'post', $this->id, '_wc_rating_count' ) ) {
$counts = array();
$raw_counts = $wpdb->get_results( $wpdb->prepare("
SELECT meta_value, COUNT( * ) as meta_value_count FROM $wpdb->commentmeta
@ -1127,22 +1156,13 @@ class WC_Product {
AND comment_approved = '1'
AND meta_value > 0
GROUP BY meta_value
", $this->id ) );
", $post_id ) );
foreach ( $raw_counts as $count ) {
$counts[ $count->meta_value ] = $count->meta_value_count;
}
update_post_meta( $this->id, '_wc_rating_count', $counts );
} else {
$counts = get_post_meta( $this->id, '_wc_rating_count', true );
}
if ( is_null( $value ) ) {
return array_sum( $counts );
} else {
return isset( $counts[ $value ] ) ? $counts[ $value ] : 0;
}
update_post_meta( $post_id, '_wc_rating_count', $counts );
}
/**

View File

@ -78,7 +78,7 @@ if ( ! defined( 'ABSPATH' ) ) {
echo ( isset( $item['qty'] ) ) ? esc_html( $item['qty'] ) : '';
if ( $refunded_qty = $order->get_qty_refunded_for_item( $item_id ) ) {
echo '<small class="refunded">-' . $refunded_qty . '</small>';
echo '<small class="refunded">' . $refunded_qty . '</small>';
}
?>
</div>

View File

@ -191,7 +191,7 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
'order_by' => 'post_date ASC',
'query_type' => 'get_results',
'filter_range' => true,
'order_types' => wc_get_order_types( 'sales-reports' ), // Orders, not refunds
'order_types' => wc_get_order_types( 'sales-reports' ),
'order_status' => array( 'completed', 'processing', 'on-hold', 'refunded' )
) );
@ -343,7 +343,7 @@ class WC_Report_Sales_By_Date extends WC_Admin_Report {
$this->report_data->total_refunded_orders = absint( count( $this->report_data->full_refunds ) );
// Item counts
$this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->order_items, 'order_item_count' ) ) );
$this->report_data->total_items = absint( array_sum( wp_list_pluck( $this->report_data->order_items, 'order_item_count' ) ) ) - $this->report_data->refunded_order_items;
}
/**

View File

@ -99,7 +99,6 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
)
),
'query_type' => 'get_var',
'order_types' => wc_get_order_types( 'order-count' ),
'filter_range' => true
) ) );
@ -110,7 +109,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
);
$legend[] = array(
'title' => sprintf( __( '%s purchases for the selected items', 'woocommerce' ), '<strong>' . $total_items . '</strong>' ),
'title' => sprintf( __( '%s purchases for the selected items', 'woocommerce' ), '<strong>' . ( $total_items ) . '</strong>' ),
'color' => $this->chart_colours['item_count'],
'highlight_series' => 0
);
@ -230,20 +229,11 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
'name' => 'order_item_qty'
)
),
'where_meta' => array(
array(
'type' => 'order_item_meta',
'meta_key' => '_line_subtotal',
'meta_value' => '0',
'operator' => '>'
)
),
'order_by' => 'order_item_qty DESC',
'group_by' => 'product_id',
'limit' => 12,
'query_type' => 'get_results',
'filter_range' => true,
'order_types' => wc_get_order_types( 'order-count' ),
'filter_range' => true
) );
if ( $top_sellers ) {
@ -291,9 +281,7 @@ class WC_Report_Sales_By_Product extends WC_Admin_Report {
'group_by' => 'product_id',
'limit' => 12,
'query_type' => 'get_results',
'filter_range' => true,
'order_types' => wc_get_order_types( 'order-count' ),
'nocache' => true
'filter_range' => true
) );
if ( $top_freebies ) {

View File

@ -79,7 +79,6 @@ class WC_Settings_Payment_Gateways extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => 'start',
'desc_tip' => __( 'Coupons can be applied from the cart and checkout pages.', 'woocommerce' ),
'autoload' => false,
),
array(

View File

@ -323,8 +323,7 @@ class WC_Settings_Products extends WC_Settings_Page {
'min' => 0,
'step' => 1
),
'default' => '0',
'autoload' => false
'default' => '0'
),
array(
@ -456,14 +455,14 @@ class WC_Settings_Products extends WC_Settings_Page {
array(
'type' => 'sectionend',
'id' => 'product_measurement_options'
'id' => 'product_measurement_options',
),
array(
'title' => __( 'Reviews', 'woocommerce' ),
'type' => 'title',
'desc' => '',
'id' => 'product_rating_options'
'id' => 'product_rating_options',
),
array(
@ -474,7 +473,6 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => 'start',
'show_if_checked' => 'option',
'autoload' => false
),
array(
@ -484,7 +482,7 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => '',
'show_if_checked' => 'yes',
'autoload' => false
'autoload' => false,
),
array(
@ -494,7 +492,7 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => '',
'show_if_checked' => 'yes',
'autoload' => false
'autoload' => false,
),
array(
@ -504,7 +502,7 @@ class WC_Settings_Products extends WC_Settings_Page {
'type' => 'checkbox',
'checkboxgroup' => 'end',
'show_if_checked' => 'yes',
'autoload' => false
'autoload' => false,
),
array(

View File

@ -329,7 +329,10 @@ if ( ! defined( 'ABSPATH' ) ) {
'woocommerce_order_items',
'woocommerce_order_itemmeta',
'woocommerce_tax_rates',
'woocommerce_tax_rate_locations'
'woocommerce_tax_rate_locations',
'woocommerce_shipping_zones',
'woocommerce_shipping_zone_locations',
'woocommerce_shipping_zone_methods',
);
foreach ( $tables as $table ) {

View File

@ -1137,7 +1137,7 @@ class WC_API_Products extends WC_API_Resource {
'related_ids' => array_map( 'absint', array_values( $product->get_related() ) ),
'upsell_ids' => array_map( 'absint', $product->get_upsells() ),
'cross_sell_ids' => array_map( 'absint', $product->get_cross_sells() ),
'parent_id' => $product->post->post_parent,
'parent_id' => $product->is_type( 'variation' ) ? $product->parent->id : $product->post->post_parent,
'categories' => wp_get_post_terms( $product->id, 'product_cat', array( 'fields' => 'names' ) ),
'tags' => wp_get_post_terms( $product->id, 'product_tag', array( 'fields' => 'names' ) ),
'images' => $this->get_images( $product ),
@ -1152,10 +1152,28 @@ class WC_API_Products extends WC_API_Resource {
'variations' => array(),
'parent' => array(),
'grouped_products' => array(),
'menu_order' => $product->post->menu_order,
'menu_order' => $this->get_product_menu_order( $product ),
);
}
/**
* Get product menu order.
*
* @since 2.5.3
* @param WC_Product $product
* @return int
*/
private function get_product_menu_order( $product ) {
$menu_order = $product->post->menu_order;
if ( $product->is_type( 'variation' ) ) {
$_product = get_post( $product->get_variation_id() );
$menu_order = $_product->menu_order;
}
return apply_filters( 'woocommerce_api_product_menu_order', $menu_order, $product );
}
/**
* Get an individual variation's data
*

View File

@ -101,59 +101,10 @@ class WC_Cart {
*/
public $fees = array();
/**
* Prices include tax.
*
* @var bool
*/
public $prices_include_tax;
/**
* Round at subtotal.
*
* @var bool
*/
public $round_at_subtotal;
/**
* Tax display cart.
*
* @var string
*/
public $tax_display_cart;
/**
* Prices inc tax.
*
* @var int
*/
public $dp;
/**
* Display totals excluding tax.
*
* @var bool
*/
public $display_totals_ex_tax;
/**
* Display cart excluding tax.
*
* @var bool
*/
public $display_cart_ex_tax;
/**
* Constructor for the cart class. Loads options and hooks in the init method.
*/
public function __construct() {
$this->prices_include_tax = wc_prices_include_tax();
$this->round_at_subtotal = get_option( 'woocommerce_tax_round_at_subtotal' ) == 'yes';
$this->tax_display_cart = get_option( 'woocommerce_tax_display_cart' );
$this->dp = wc_get_price_decimals();
$this->display_totals_ex_tax = $this->tax_display_cart == 'excl';
$this->display_cart_ex_tax = $this->tax_display_cart == 'excl';
add_action( 'wp_loaded', array( $this, 'init' ) ); // Get cart after WP and plugins are loaded.
add_action( 'wp', array( $this, 'maybe_set_cart_cookies' ), 99 ); // Set cookies
add_action( 'shutdown', array( $this, 'maybe_set_cart_cookies' ), 0 ); // Set cookies before shutdown and ob flushing
@ -169,6 +120,22 @@ class WC_Cart {
*/
public function __get( $key ) {
switch ( $key ) {
case 'prices_include_tax' :
return wc_prices_include_tax();
break;
case 'round_at_subtotal' :
return 'yes' === get_option( 'woocommerce_tax_round_at_subtotal' );
break;
case 'tax_display_cart' :
return get_option( 'woocommerce_tax_display_cart' );
break;
case 'dp' :
return wc_get_price_decimals();
break;
case 'display_totals_ex_tax' :
case 'display_cart_ex_tax' :
return $this->tax_display_cart === 'excl';
break;
case 'cart_contents_weight' :
return $this->get_cart_contents_weight();
break;
@ -256,6 +223,9 @@ class WC_Cart {
}
if ( is_array( $cart ) ) {
// Prime meta cache to reduce future queries
update_meta_cache( 'post', wp_list_pluck( $cart, 'product_id' ) );
foreach ( $cart as $key => $values ) {
$_product = wc_get_product( $values['variation_id'] ? $values['variation_id'] : $values['product_id'] );

View File

@ -235,6 +235,7 @@ class WC_Comments {
delete_post_meta( $post_id, '_wc_average_rating' );
delete_post_meta( $post_id, '_wc_rating_count' );
delete_post_meta( $post_id, '_wc_review_count' );
WC_Product::sync_average_rating( $post_id );
}
/**

View File

@ -63,7 +63,7 @@ class WC_Product_Factory {
if ( isset( $args['product_type'] ) ) {
$product_type = $args['product_type'];
} else {
$terms = get_the_terms( $product_id, 'product_type' );
$terms = get_the_terms( $the_product, 'product_type' );
$product_type = ! empty( $terms ) ? sanitize_title( current( $terms )->name ) : 'simple';
}
} elseif( 'product_variation' === $post_type ) {

View File

@ -824,8 +824,10 @@ class WC_Product_Variable extends WC_Product {
update_post_meta( $product_id, '_max_' . $price_type . '_variation_id', ${"max_{$price_type}_id"} );
}
// The VARIABLE PRODUCT price should equal the min price of any type
update_post_meta( $product_id, '_price', $min_price );
// Sync _price meta
delete_post_meta( $product_id, '_price' );
add_post_meta( $product_id, '_price', $min_price, false );
add_post_meta( $product_id, '_price', $max_price, false );
delete_transient( 'wc_products_onsale' );
// Sync attributes

View File

@ -3,7 +3,7 @@
* Contains the query functions for WooCommerce which alter the front-end post queries and loops
*
* @class WC_Query
* @version 2.3.0
* @version 2.6.0
* @package WooCommerce/Classes
* @category Class
* @author WooThemes
@ -23,26 +23,11 @@ class WC_Query {
/** @public array Query vars to add to wp */
public $query_vars = array();
/** @public array Unfiltered product ids (before layered nav etc) */
public $unfiltered_product_ids = array();
/** @public array Filtered product ids (after layered nav) */
public $filtered_product_ids = array();
/** @public array Filtered product ids (after layered nav, per taxonomy) */
public $filtered_product_ids_for_taxonomy = array();
/** @public array Product IDs that match the layered nav + price filter */
public $post__in = array();
/** @public array|string The meta query for the page */
public $meta_query = '';
/** @public array Post IDs matching layered nav only */
public $layered_nav_post__in = array();
/** @public array Stores post IDs matching layered nav, so price filter can find max price in view */
public $layered_nav_product_ids = array();
/**
* Stores chosen attributes
* @var array
*/
private static $_chosen_attributes;
/**
* Constructor for the query class. Hooks in methods.
@ -51,20 +36,14 @@ class WC_Query {
*/
public function __construct() {
add_action( 'init', array( $this, 'add_endpoints' ) );
add_action( 'init', array( $this, 'layered_nav_init' ) );
add_action( 'init', array( $this, 'price_filter_init' ) );
add_action( 'init', array( $this, 'rating_filter_init' ) );
if ( ! is_admin() ) {
add_action( 'wp_loaded', array( $this, 'get_errors' ), 20 );
add_filter( 'query_vars', array( $this, 'add_query_vars'), 0 );
add_action( 'parse_request', array( $this, 'parse_request'), 0 );
add_action( 'pre_get_posts', array( $this, 'pre_get_posts' ) );
add_filter( 'the_posts', array( $this, 'the_posts' ), 11, 2 );
add_action( 'wp', array( $this, 'remove_product_query' ) );
add_action( 'wp', array( $this, 'remove_ordering_args' ) );
}
$this->init_query_vars();
}
@ -155,7 +134,6 @@ class WC_Query {
foreach ( $this->query_vars as $key => $var ) {
$vars[] = $key;
}
return $vars;
}
@ -301,9 +279,6 @@ class WC_Query {
add_filter( 'wp', array( $this, 'remove_posts_where' ) );
}
// We're on a shop page so queue the woocommerce_get_products_in_view function
add_action( 'wp', array( $this, 'get_products_in_view' ), 2);
// And remove the pre_get_posts hook
$this->remove_product_query();
}
@ -338,7 +313,7 @@ class WC_Query {
* @return string
*/
public function wpseo_metadesc() {
return WPSEO_Meta::get_value( 'metadesc', wc_get_page_id('shop') );
return WPSEO_Meta::get_value( 'metadesc', wc_get_page_id( 'shop' ) );
}
/**
@ -350,82 +325,17 @@ class WC_Query {
* @return string
*/
public function wpseo_metakey() {
return WPSEO_Meta::get_value( 'metakey', wc_get_page_id('shop') );
return WPSEO_Meta::get_value( 'metakey', wc_get_page_id( 'shop' ) );
}
/**
* Hook into the_posts to do the main product query if needed - relevanssi compatibility.
*
* @access public
* @param array $posts
* @param WP_Query|bool $query (default: false)
* @return array
*/
public function the_posts( $posts, $query = false ) {
// Abort if there's no query
if ( ! $query )
return $posts;
// Abort if we're not filtering posts
if ( empty( $this->post__in ) )
return $posts;
// Abort if this query has already been done
if ( ! empty( $query->wc_query ) )
return $posts;
// Abort if this isn't a search query
if ( empty( $query->query_vars["s"] ) )
return $posts;
// Abort if we're not on a post type archive/product taxonomy
if ( ! $query->is_post_type_archive( 'product' ) && ! $query->is_tax( get_object_taxonomies( 'product' ) ) )
return $posts;
$filtered_posts = array();
$queried_post_ids = array();
foreach ( $posts as $post ) {
if ( in_array( $post->ID, $this->post__in ) ) {
$filtered_posts[] = $post;
$queried_post_ids[] = $post->ID;
}
}
$query->posts = $filtered_posts;
$query->post_count = count( $filtered_posts );
// Ensure filters are set
$this->unfiltered_product_ids = $queried_post_ids;
$this->filtered_product_ids = $queried_post_ids;
if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
$this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
} else {
$this->layered_nav_product_ids = $this->unfiltered_product_ids;
}
return $filtered_posts;
}
/**
* Query the products, applying sorting/ordering etc. This applies to the main wordpress loop.
*
* @param mixed $q
*/
public function product_query( $q ) {
// Meta query
$meta_query = $this->get_meta_query( $q->get( 'meta_query' ) );
// Ordering
$ordering = $this->get_catalog_ordering_args();
// Get a list of post id's which match the current filters set (in the layered nav and price filter)
$post__in = array_unique( apply_filters( 'loop_shop_post_in', array() ) );
// Ordering query vars
$ordering = $this->get_catalog_ordering_args();
$q->set( 'orderby', $ordering['orderby'] );
$q->set( 'order', $ordering['order'] );
if ( isset( $ordering['meta_key'] ) ) {
@ -433,16 +343,11 @@ class WC_Query {
}
// Query vars that affect posts shown
$q->set( 'meta_query', $meta_query );
$q->set( 'post__in', $post__in );
$q->set( 'meta_query', $this->get_meta_query( $q->get( 'meta_query' ) ) );
$q->set( 'tax_query', $this->get_tax_query( $q->get( 'tax_query' ) ) );
$q->set( 'posts_per_page', $q->get( 'posts_per_page' ) ? $q->get( 'posts_per_page' ) : apply_filters( 'loop_shop_per_page', get_option( 'posts_per_page' ) ) );
// Set a special variable
$q->set( 'wc_query', 'product_query' );
// Store variables
$this->post__in = $post__in;
$this->meta_query = $meta_query;
$q->set( 'post__in', array_unique( apply_filters( 'loop_shop_post_in', array() ) ) );
do_action( 'woocommerce_product_query', $q, $this );
}
@ -470,66 +375,6 @@ class WC_Query {
remove_filter( 'posts_where', array( $this, 'search_post_excerpt' ) );
}
/**
* Get an unpaginated list all product ID's (both filtered and unfiltered). Makes use of transients.
*/
public function get_products_in_view() {
global $wp_the_query;
// Get main query
$current_wp_query = $wp_the_query->query;
// Get WP Query for current page (without 'paged')
unset( $current_wp_query['paged'] );
// Generate a transient name based on current query
$transient_name = 'wc_uf_pid_' . md5( http_build_query( $current_wp_query ) . WC_Cache_Helper::get_transient_version( 'product_query' ) );
$transient_name = ( is_search() ) ? $transient_name . '_s' : $transient_name;
if ( false === ( $unfiltered_product_ids = get_transient( $transient_name ) ) ) {
// Get all visible posts, regardless of filters
$unfiltered_args = array_merge(
$current_wp_query,
array(
'post_type' => 'product',
'numberposts' => -1,
'post_status' => 'publish',
'meta_query' => $this->meta_query,
'fields' => 'ids',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
'pagename' => '',
'wc_query' => 'get_products_in_view'
)
);
$unfiltered_product_ids = apply_filters( 'woocommerce_unfiltered_product_ids', get_posts( $unfiltered_args ), $unfiltered_args );
set_transient( $transient_name, $unfiltered_product_ids, DAY_IN_SECONDS * 30 );
}
// Store the variable
$this->unfiltered_product_ids = $unfiltered_product_ids;
// Also store filtered posts ids...
if ( sizeof( $this->post__in ) > 0 ) {
$this->filtered_product_ids = array_intersect( $this->unfiltered_product_ids, $this->post__in );
} else {
$this->filtered_product_ids = $this->unfiltered_product_ids;
}
// And filtered post ids which just take layered nav into consideration (to find max price in the price widget)
if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
$this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
} else {
$this->layered_nav_product_ids = $this->unfiltered_product_ids;
}
}
/**
* Returns an array of arguments for ordering products based on the selected values.
*
@ -601,9 +446,7 @@ class WC_Query {
*/
public function order_by_popularity_post_clauses( $args ) {
global $wpdb;
$args['orderby'] = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_date DESC";
return $args;
}
@ -618,16 +461,12 @@ class WC_Query {
global $wpdb;
$args['fields'] .= ", AVG( $wpdb->commentmeta.meta_value ) as average_rating ";
$args['where'] .= " AND ( $wpdb->commentmeta.meta_key = 'rating' OR $wpdb->commentmeta.meta_key IS null ) ";
$args['join'] .= "
LEFT OUTER JOIN $wpdb->comments ON($wpdb->posts.ID = $wpdb->comments.comment_post_ID)
LEFT JOIN $wpdb->commentmeta ON($wpdb->comments.comment_ID = $wpdb->commentmeta.comment_id)
";
$args['orderby'] = "average_rating DESC, $wpdb->posts.post_date DESC";
$args['groupby'] = "$wpdb->posts.ID";
return $args;
@ -640,35 +479,80 @@ class WC_Query {
* @return array
*/
public function get_meta_query( $meta_query = array() ) {
if ( ! is_array( $meta_query ) )
if ( ! is_array( $meta_query ) ) {
$meta_query = array();
}
$meta_query[] = $this->visibility_meta_query();
$meta_query[] = $this->stock_status_meta_query();
$meta_query[] = $this->price_filter_meta_query();
$meta_query[] = $this->rating_filter_meta_query();
return array_filter( $meta_query );
return array_filter( apply_filters( 'woocommerce_product_query_meta_query', $meta_query, $this ) );
}
/**
* Return a meta query for filtering by price.
* @return array
*/
private function price_filter_meta_query() {
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) {
$min = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0;
$max = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999;
// If displaying prices in the shop including taxes, but prices don't include taxes..
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class );
$class_min = $min - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $min, $tax_rates ) );
$class_max = $max - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $max, $tax_rates ) );
if ( $class_min < $min ) {
$min = $class_min;
}
if ( $class_max > $max ) {
$max = $class_max;
}
}
}
return array(
'key' => '_price',
'value' => array( $min, $max ),
'compare' => 'BETWEEN',
'type' => 'DECIMAL',
'price_filter' => true,
);
}
return array();
}
/**
* Return a meta query for filtering by rating.
* @return array
*/
public function rating_filter_meta_query() {
return isset( $_GET['min_rating'] ) ? array(
'key' => '_wc_average_rating',
'value' => isset( $_GET['min_rating'] ) ? floatval( $_GET['min_rating'] ) : 0,
'compare' => '>=',
'type' => 'DECIMAL',
'rating_filter' => true,
) : array();
}
/**
* Returns a meta query to handle product visibility.
*
* @access public
* @param string $compare (default: 'IN')
* @return array
*/
public function visibility_meta_query( $compare = 'IN' ) {
if ( is_search() )
$in = array( 'visible', 'search' );
else
$in = array( 'visible', 'catalog' );
$meta_query = array(
return array(
'key' => '_visibility',
'value' => $in,
'compare' => $compare
'value' => is_search() ? array( 'visible', 'search' ) : array( 'visible', 'catalog' ),
'compare' => $compare,
);
return $meta_query;
}
/**
@ -679,299 +563,121 @@ class WC_Query {
* @return array
*/
public function stock_status_meta_query( $status = 'instock' ) {
$meta_query = array();
if ( get_option( 'woocommerce_hide_out_of_stock_items' ) == 'yes' ) {
$meta_query = array(
return 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ? array(
'key' => '_stock_status',
'value' => $status,
'compare' => '='
'compare' => '=',
) : array();
}
/**
* Appends tax queries to an array.
* @param array $tax_query
* @return array
*/
public function get_tax_query( $tax_query = array() ) {
if ( ! is_array( $tax_query ) ) {
$tax_query = array();
}
// Layered nav filters on terms
if ( $_chosen_attributes = $this->get_layered_nav_chosen_attributes() ) {
foreach ( $_chosen_attributes as $taxonomy => $data ) {
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $data['terms'],
'operator' => 'and' === $data['query_type'] ? 'AND' : 'IN',
'include_children' => false,
);
}
}
return array_filter( apply_filters( 'woocommerce_product_query_tax_query', $tax_query, $this ) );
}
/**
* Get the tax query which was used by the main query.
* @return array
*/
public static function get_main_tax_query() {
global $wp_the_query;
$args = $wp_the_query->query_vars;
$tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array();
if ( ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) {
$tax_query[] = array(
'taxonomy' => $args['taxonomy'],
'terms' => array( $args['term'] ),
'field' => 'slug',
);
}
return $tax_query;
}
/**
* Get the meta query which was used by the main query.
* @return array
*/
public static function get_main_meta_query() {
global $wp_the_query;
$args = $wp_the_query->query_vars;
$meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array();
return $meta_query;
}
/**
* Layered Nav Init.
*/
public function layered_nav_init( ) {
if ( apply_filters( 'woocommerce_is_layered_nav_active', is_active_widget( false, false, 'woocommerce_layered_nav', true ) ) && ! is_admin() ) {
global $_chosen_attributes;
$_chosen_attributes = array();
public static function get_layered_nav_chosen_attributes() {
if ( ! is_array( self::$_chosen_attributes ) ) {
self::$_chosen_attributes = array();
if ( $attribute_taxonomies = wc_get_attribute_taxonomies() ) {
foreach ( $attribute_taxonomies as $tax ) {
$attribute = wc_sanitize_taxonomy_name( $tax->attribute_name );
$taxonomy = wc_attribute_taxonomy_name( $attribute );
$name = 'filter_' . $attribute;
$filter_terms = ! empty( $_GET[ 'filter_' . $attribute ] ) ? explode( ',', wc_clean( $_GET[ 'filter_' . $attribute ] ) ) : array();
if ( empty( $filter_terms ) || ! taxonomy_exists( $taxonomy ) ) {
continue;
}
$query_type = ! empty( $_GET[ 'query_type_' . $attribute ] ) && in_array( $_GET[ 'query_type_' . $attribute ], array( 'and', 'or' ) ) ? wc_clean( $_GET[ 'query_type_' . $attribute ] ) : '';
if ( ! $query_type ) {
$query_type = apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
self::$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding
self::$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type ? $query_type : apply_filters( 'woocommerce_layered_nav_default_query_type', 'and' );
}
}
}
return self::$_chosen_attributes;
}
if ( ! empty( $filter_terms ) && taxonomy_exists( $taxonomy ) ) {
$_chosen_attributes[ $taxonomy ]['terms'] = array_map( 'sanitize_title', $filter_terms ); // Ensures correct encoding
$_chosen_attributes[ $taxonomy ]['query_type'] = $query_type;
}
}
/**
* @deprecated 2.6.0
*/
public function layered_nav_init() {
_deprecated_function( 'layered_nav_init', '2.6', '' );
}
add_filter( 'loop_shop_post_in', array( $this, 'layered_nav_query' ) );
}
/**
* Get an unpaginated list all product ID's (both filtered and unfiltered). Makes use of transients.
* @deprecated 2.6.0 due to performance concerns
*/
public function get_products_in_view() {
_deprecated_function( 'get_products_in_view', '2.6', '' );
}
/**
* Layered Nav post filter.
*
* @param array $filtered_posts
* @return array
* @deprecated 2.6.0 due to performance concerns
*/
public function layered_nav_query( $filtered_posts ) {
global $_chosen_attributes;
if ( sizeof( $_chosen_attributes ) > 0 ) {
$matched_products = array(
'and' => array(),
'or' => array()
);
$filtered_attribute = array(
'and' => false,
'or' => false
);
foreach ( $_chosen_attributes as $attribute => $data ) {
$matched_products_from_attribute = array();
$filtered = false;
if ( sizeof( $data['terms'] ) > 0 ) {
foreach ( $data['terms'] as $value ) {
$args = array(
'post_type' => 'product',
'numberposts' => -1,
'post_status' => 'publish',
'fields' => 'ids',
'no_found_rows' => true,
'tax_query' => array(
array(
'taxonomy' => $attribute,
'terms' => $value,
'field' => 'slug'
)
)
);
$post_ids = apply_filters( 'woocommerce_layered_nav_query_post_ids', get_posts( $args ), $args, $attribute, $value );
if ( ! is_wp_error( $post_ids ) ) {
if ( sizeof( $matched_products_from_attribute ) > 0 || $filtered ) {
$matched_products_from_attribute = $data['query_type'] == 'or' ? array_merge( $post_ids, $matched_products_from_attribute ) : array_intersect( $post_ids, $matched_products_from_attribute );
} else {
$matched_products_from_attribute = $post_ids;
_deprecated_function( 'layered_nav_query', '2.6', '' );
}
$filtered = true;
}
}
}
if ( sizeof( $matched_products[ $data['query_type'] ] ) > 0 || $filtered_attribute[ $data['query_type'] ] === true ) {
$matched_products[ $data['query_type'] ] = ( $data['query_type'] == 'or' ) ? array_merge( $matched_products_from_attribute, $matched_products[ $data['query_type'] ] ) : array_intersect( $matched_products_from_attribute, $matched_products[ $data['query_type'] ] );
} else {
$matched_products[ $data['query_type'] ] = $matched_products_from_attribute;
}
$filtered_attribute[ $data['query_type'] ] = true;
$this->filtered_product_ids_for_taxonomy[ $attribute ] = $matched_products_from_attribute;
}
// Combine our AND and OR result sets
if ( $filtered_attribute['and'] && $filtered_attribute['or'] )
$results = array_intersect( $matched_products[ 'and' ], $matched_products[ 'or' ] );
else
$results = array_merge( $matched_products[ 'and' ], $matched_products[ 'or' ] );
if ( $filtered ) {
WC()->query->layered_nav_post__in = $results;
WC()->query->layered_nav_post__in[] = 0;
if ( sizeof( $filtered_posts ) == 0 ) {
$filtered_posts = $results;
$filtered_posts[] = 0;
} else {
$filtered_posts = array_intersect( $filtered_posts, $results );
$filtered_posts[] = 0;
}
}
}
return (array) $filtered_posts;
}
/**
* Price filter Init.
*/
public function price_filter_init() {
if ( apply_filters( 'woocommerce_is_price_filter_active', is_active_widget( false, false, 'woocommerce_price_filter', true ) ) && ! is_admin() ) {
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), WC_VERSION, true );
wp_register_script( 'wc-price-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch' ), WC_VERSION, true );
wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array(
'currency_symbol' => get_woocommerce_currency_symbol(),
'currency_pos' => get_option( 'woocommerce_currency_pos' ),
'min_price' => isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : '',
'max_price' => isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : ''
) );
add_filter( 'loop_shop_post_in', array( $this, 'price_filter' ) );
}
}
/**
* Price Filter post filter.
*
* @param array $filtered_posts
* @return array
*/
public function price_filter( $filtered_posts = array() ) {
global $wpdb;
if ( isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) {
$matched_products = array();
$min = isset( $_GET['min_price'] ) ? floatval( $_GET['min_price'] ) : 0;
$max = isset( $_GET['max_price'] ) ? floatval( $_GET['max_price'] ) : 9999999999;
// If displaying prices in the shop including taxes, but prices don't include taxes..
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class );
$min_class = $min - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $min, $tax_rates ) );
$max_class = $max - WC_Tax::get_tax_total( WC_Tax::calc_inclusive_tax( $max, $tax_rates ) );
$matched_products_query = apply_filters( 'woocommerce_price_filter_results', $wpdb->get_results( $wpdb->prepare( "
SELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}
INNER JOIN {$wpdb->postmeta} pm1 ON ID = pm1.post_id
INNER JOIN {$wpdb->postmeta} pm2 ON ID = pm2.post_id
WHERE post_type IN ( 'product', 'product_variation' )
AND post_status = 'publish'
AND pm1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')
AND pm1.meta_value BETWEEN %f AND %f
AND pm2.meta_key = '_tax_class'
AND pm2.meta_value = %s
", $min_class, $max_class, sanitize_title( $tax_class ) ), OBJECT_K ), $min_class, $max_class );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $product ) {
if ( $product->post_type == 'product' ) {
$matched_products[] = $product->ID;
}
if ( $product->post_parent > 0 ) {
$matched_products[] = $product->post_parent;
}
}
}
}
} else {
$matched_products_query = apply_filters( 'woocommerce_price_filter_results', $wpdb->get_results( $wpdb->prepare( "
SELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}
INNER JOIN {$wpdb->postmeta} pm1 ON ID = pm1.post_id
WHERE post_type IN ( 'product', 'product_variation' )
AND post_status = 'publish'
AND pm1.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')
AND pm1.meta_value BETWEEN %f AND %f
", $min, $max ), OBJECT_K ), $min, $max );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $product ) {
if ( $product->post_type == 'product' ) {
$matched_products[] = $product->ID;
}
if ( $product->post_parent > 0 ) {
$matched_products[] = $product->post_parent;
}
}
}
}
$matched_products = array_unique( $matched_products );
// Filter the id's
if ( 0 === sizeof( $filtered_posts ) ) {
$filtered_posts = $matched_products;
} else {
$filtered_posts = array_intersect( $filtered_posts, $matched_products );
}
$filtered_posts[] = 0;
}
return (array) $filtered_posts;
}
/**
* Rating filter Init.
*/
public function rating_filter_init() {
if ( apply_filters( 'woocommerce_is_rating_filter_active', is_active_widget( false, false, 'woocommerce_rating_filter', true ) ) && ! is_admin() ) {
add_filter( 'loop_shop_post_in', array( $this, 'rating_filter' ) );
}
}
/**
* Rating Filter post filter.
*
* @param array $filtered_posts
* @return array
*/
public function rating_filter( $filtered_posts = array() ) {
global $wpdb;
if( isset( $_GET['min_rating'] ) ) {
$matched_products = array();
$min = isset( $_GET['min_rating'] ) ? floatval( $_GET['min_rating'] ) : 0;
$matched_products_query = apply_filters( 'woocommerce_rating_filter_results', $wpdb->get_results( $wpdb->prepare( "
SELECT comment_post_ID, ROUND( AVG( meta_value ), 2 ) as average_rating FROM {$wpdb->commentmeta}
LEFT JOIN $wpdb->comments ON $wpdb->commentmeta.comment_id = $wpdb->comments.comment_ID
WHERE meta_key = 'rating'
AND comment_approved = '1'
AND meta_value > 0
GROUP BY comment_post_ID
HAVING ROUND( AVG( meta_value ), 2 ) >= %d
", $min ), OBJECT_K ), $min );
if ( $matched_products_query ) {
foreach ( $matched_products_query as $commentmeta ) {
$matched_products[] = $commentmeta->comment_post_ID;
}
}
$matched_products = array_unique( $matched_products );
// Filter the id's
if ( 0 === sizeof( $filtered_posts ) ) {
$filtered_posts = $matched_products;
} else {
$filtered_posts = array_intersect( $filtered_posts, $matched_products );
}
$filtered_posts[] = 0;
}
return (array) $filtered_posts;
}
}
endif;

View File

@ -87,6 +87,7 @@ class WC_Shortcodes {
$products = new WP_Query( apply_filters( 'woocommerce_shortcode_products_query', $query_args, $atts, $loop_name ) );
$columns = absint( $atts['columns'] );
$woocommerce_loop['columns'] = $columns;
$woocommerce_loop['name'] = $loop_name;
ob_start();

View File

@ -544,7 +544,9 @@ class WC_Webhook {
'wp_trash_post',
),
'customer.created' => array(
'user_register',
'woocommerce_created_customer',
'woocommerce_api_create_customer'
),
'customer.updated' => array(
'profile_update',

View File

@ -89,3 +89,14 @@ if ( $wpdb->get_var( "SHOW TABLES LIKE '{$wpdb->prefix}woocommerce_shipping_zone
if ( 'no' === get_option( 'woocommerce_calc_shipping' ) ) {
update_option( 'woocommerce_ship_to_countries', 'disabled' );
}
/**
* Refund item qty should be negative
*/
$wpdb->query( "
UPDATE {$wpdb->prefix}woocommerce_order_itemmeta as item_meta
LEFT JOIN {$wpdb->prefix}woocommerce_order_items as items ON item_meta.order_item_id = items.order_item_id
LEFT JOIN {$wpdb->posts} as posts ON items.order_id = posts.ID
SET item_meta.meta_value = item_meta.meta_value * -1
WHERE item_meta.meta_value > 0 AND item_meta.meta_key = '_qty' AND posts.post_type = 'shop_order_refund'
" );

View File

@ -107,11 +107,15 @@ function wc_attribute_label( $name, $product = '' ) {
* @return string
*/
function wc_attribute_orderby( $name ) {
global $wpdb;
global $wc_product_attributes, $wpdb;
$name = str_replace( 'pa_', '', sanitize_title( $name ) );
if ( isset( $wc_product_attributes[ 'pa_' . $name ] ) ) {
$orderby = $wc_product_attributes[ 'pa_' . $name ]->attribute_orderby;
} else {
$orderby = $wpdb->get_var( $wpdb->prepare( "SELECT attribute_orderby FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = %s;", $name ) );
}
return apply_filters( 'woocommerce_attribute_orderby', $orderby, $name );
}

View File

@ -254,9 +254,7 @@ if ( ! function_exists( 'is_filtered' ) ) {
* @return bool
*/
function is_filtered() {
global $_chosen_attributes;
return apply_filters( 'woocommerce_is_filtered', ( sizeof( $_chosen_attributes ) > 0 || isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) ) );
return apply_filters( 'woocommerce_is_filtered', ( sizeof( WC_Query::get_layered_nav_chosen_attributes() ) > 0 || isset( $_GET['max_price'] ) || isset( $_GET['min_price'] ) || isset( $_GET['min_rating'] ) ) );
}
}

View File

@ -695,7 +695,7 @@ function wc_create_refund( $args = array() ) {
'tax_data' => array( 'total' => array_map( 'wc_format_refund_total', $refund_item['refund_tax'] ), 'subtotal' => array_map( 'wc_format_refund_total', $refund_item['refund_tax'] ) )
)
);
$new_item_id = $refund->add_product( $order->get_product_from_item( $order_items[ $refund_item_id ] ), isset( $refund_item['qty'] ) ? $refund_item['qty'] : 0, $line_item_args );
$new_item_id = $refund->add_product( $order->get_product_from_item( $order_items[ $refund_item_id ] ), isset( $refund_item['qty'] ) ? $refund_item['qty'] * -1 : 0, $line_item_args );
wc_add_order_item_meta( $new_item_id, '_refunded_item_id', $refund_item_id );
break;
case 'shipping' :

View File

@ -202,23 +202,22 @@ function wc_get_featured_product_ids() {
/**
* Filter to allow product_cat in the permalinks for products.
*
* @access public
* @param string $permalink The existing permalink URL.
* @param WP_Post $post
* @return string
*/
function wc_product_post_type_link( $permalink, $post ) {
// Abort if post is not a product
// Abort if post is not a product.
if ( $post->post_type !== 'product' ) {
return $permalink;
}
// Abort early if the placeholder rewrite tag isn't in the generated URL
// Abort early if the placeholder rewrite tag isn't in the generated URL.
if ( false === strpos( $permalink, '%' ) ) {
return $permalink;
}
// Get the custom taxonomy terms in use by this post
// Get the custom taxonomy terms in use by this post.
$terms = get_the_terms( $post->ID, 'product_cat' );
if ( ! empty( $terms ) ) {
@ -228,7 +227,7 @@ function wc_product_post_type_link( $permalink, $post ) {
$category_object = get_term( $category_object, 'product_cat' );
$product_cat = $category_object->slug;
if ( $parent = $category_object->parent ) {
if ( $category_object->parent ) {
$ancestors = get_ancestors( $category_object->term_id, 'product_cat' );
foreach ( $ancestors as $ancestor ) {
$ancestor_object = get_term( $ancestor, 'product_cat' );

View File

@ -106,13 +106,14 @@ if ( ! function_exists( 'woocommerce_reset_loop' ) ) {
/**
* Reset the loop's index and columns when we're done outputting a product loop.
*
* @subpackage Loop
*/
function woocommerce_reset_loop() {
global $woocommerce_loop;
// Reset loop/columns globals when starting a new loop
$woocommerce_loop['loop'] = $woocommerce_loop['columns'] = '';
$GLOBALS['woocommerce_loop'] = array(
'loop' => '',
'columns' => '',
'name' => '',
);
}
}
add_filter( 'loop_end', 'woocommerce_reset_loop' );
@ -220,6 +221,26 @@ function wc_product_cat_class( $class = '', $category = null ) {
echo 'class="' . esc_attr( join( ' ', wc_get_product_cat_class( $class, $category ) ) ) . '"';
}
/**
* Get classname for loops based on $woocommerce_loop global.
* @since 2.6.0
* @return string
*/
function wc_get_loop_class() {
global $woocommerce_loop;
$woocommerce_loop['loop'] = ! empty( $woocommerce_loop['loop'] ) ? $woocommerce_loop['loop'] + 1 : 1;
$woocommerce_loop['columns'] = ! empty( $woocommerce_loop['columns'] ) ? $woocommerce_loop['columns'] : apply_filters( 'loop_shop_columns', 4 );
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) {
return 'first';
} elseif ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
return 'last';
} else {
return '';
}
}
/**
* Get the classes for the product cat div.
*
@ -228,20 +249,10 @@ function wc_product_cat_class( $class = '', $category = null ) {
* @param object $category object Optional.
*/
function wc_get_product_cat_class( $class = '', $category = null ) {
global $woocommerce_loop;
$classes = is_array( $class ) ? $class : array_map( 'trim', explode( ' ', $class ) );
$classes[] = 'product-category';
$classes[] = 'product';
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) {
$classes[] = 'first';
}
if ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
$classes[] = 'last';
}
$classes[] = wc_get_loop_class();
$classes = apply_filters( 'product_cat_class', $classes, $class, $category );
return array_unique( array_filter( $classes ) );
@ -264,6 +275,9 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
$product = wc_get_product( $post_id );
if ( $product ) {
$classes[] = wc_get_loop_class();
$classes[] = $product->stock_status;
if ( $product->is_on_sale() ) {
$classes[] = 'sale';
}
@ -291,32 +305,14 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
if ( $product->get_type() ) {
$classes[] = "product-type-" . $product->get_type();
}
// add category slugs
$categories = get_the_terms( $product->id, 'product_cat' );
if ( ! empty( $categories ) ) {
foreach ( $categories as $key => $value ) {
$classes[] = 'product-cat-' . $value->slug;
}
}
// add tag slugs
$tags = get_the_terms( $product->id, 'product_tag' );
if ( ! empty( $tags ) ) {
foreach ( $tags as $key => $value ) {
$classes[] = 'product-tag-' . $value->slug;
}
}
if ('variable' === $product->product_type && $product->has_default_attributes() ) {
if ( $product->is_type( 'variable' ) ) {
if ( $product->has_default_attributes() ) {
$classes[] = 'has-default-attributes';
}
if ( 'variable' === $product->product_type && $product->has_child() ) {
if ( $product->has_child() ) {
$classes[] = 'has-children';
}
$classes[] = $product->stock_status;
}
}
if ( false !== ( $key = array_search( 'hentry', $classes ) ) ) {
@ -489,6 +485,7 @@ if ( ! function_exists( 'woocommerce_product_loop_start' ) ) {
*/
function woocommerce_product_loop_start( $echo = true ) {
ob_start();
$GLOBALS['woocommerce_loop']['loop'] = 0;
wc_get_template( 'loop/loop-start.php' );
if ( $echo )
echo ob_get_clean();

View File

@ -43,18 +43,14 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
* @param array $instance
*/
public function widget( $args, $instance ) {
global $_chosen_attributes;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
// Price
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$min_price = isset( $_GET['min_price'] ) ? wc_clean( $_GET['min_price'] ) : 0;
$max_price = isset( $_GET['max_price'] ) ? wc_clean( $_GET['max_price'] ) : 0;
// Rating
$min_rating = isset( $_GET['min_rating'] ) ? wc_clean( $_GET['min_rating'] ) : 0;
$min_rating = isset( $_GET['min_rating'] ) ? absint( $_GET['min_rating'] ) : 0;
if ( 0 < count( $_chosen_attributes ) || 0 < $min_price || 0 < $max_price || 0 < $min_rating ) {
@ -63,7 +59,7 @@ class WC_Widget_Layered_Nav_Filters extends WC_Widget {
echo '<ul>';
// Attributes
if ( ! is_null( $_chosen_attributes ) ) {
if ( $_chosen_attributes ) {
foreach ( $_chosen_attributes as $taxonomy => $data ) {
foreach ( $data['terms'] as $term_slug ) {
if ( ! $term = get_term_by( 'slug', $term_slug, $taxonomy ) ) {

View File

@ -110,12 +110,11 @@ class WC_Widget_Layered_Nav extends WC_Widget {
* @param array $instance
*/
public function widget( $args, $instance ) {
global $_chosen_attributes;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$taxonomy = isset( $instance['attribute'] ) ? wc_attribute_taxonomy_name( $instance['attribute'] ) : $this->settings['attribute']['std'];
$query_type = isset( $instance['query_type'] ) ? $instance['query_type'] : $this->settings['query_type']['std'];
$display_type = isset( $instance['display_type'] ) ? $instance['display_type'] : $this->settings['display_type']['std'];
@ -205,11 +204,11 @@ class WC_Widget_Layered_Nav extends WC_Widget {
* @return bool Will nav display?
*/
protected function layered_nav_dropdown( $terms, $taxonomy, $query_type ) {
global $_chosen_attributes;
$found = false;
if ( $taxonomy !== $this->get_current_taxonomy() ) {
$term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type );
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$taxonomy_filter_name = str_replace( 'pa_', '', $taxonomy );
echo '<select class="dropdown_layered_nav_' . esc_attr( $taxonomy_filter_name ) . '">';
@ -223,31 +222,17 @@ class WC_Widget_Layered_Nav extends WC_Widget {
}
// Get count based on current view
$_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
$option_is_set = in_array( $term->slug, $current_values );
$count = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : 0;
// If this is an AND query, only show options with count > 0
if ( 'and' === $query_type ) {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->filtered_product_ids ) );
// Only show options with count > 0
if ( 0 < $count ) {
$found = true;
}
if ( 0 === $count && ! $option_is_set ) {
} elseif ( 'and' === $query_type && 0 === $count && ! $option_is_set ) {
continue;
}
// If this is an OR query, show all options so search can be expanded
} else {
$count = sizeof( array_intersect( $_products_in_term, WC()->query->unfiltered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
}
echo '<option value="' . esc_attr( $term->slug ) . '" ' . selected( $option_is_set, true, false ) . '>' . esc_html( $term->name ) . '</option>';
}
@ -268,7 +253,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
* Get current page URL for layered nav items.
* @return string
*/
protected function get_page_base_url() {
protected function get_page_base_url( $taxonomy ) {
if ( defined( 'SHOP_IS_ON_FRONT' ) ) {
$link = home_url();
} elseif ( is_post_type_archive( 'product' ) || is_page( wc_get_page_id('shop') ) ) {
@ -306,9 +291,66 @@ class WC_Widget_Layered_Nav extends WC_Widget {
$link = add_query_arg( 'min_rating', wc_clean( $_GET['min_rating'] ), $link );
}
// All current filters
if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) {
foreach ( $_chosen_attributes as $name => $data ) {
if ( $name === $taxonomy ) {
continue;
}
$filter_name = sanitize_title( str_replace( 'pa_', '', $name ) );
if ( ! empty( $data['terms'] ) ) {
$link = add_query_arg( 'filter_' . $filter_name, implode( ',', $data['terms'] ), $link );
}
if ( 'or' == $data['query_type'] ) {
$link = add_query_arg( 'query_type_' . $filter_name, 'or', $link );
}
}
}
return $link;
}
/**
* Count products within certain terms, taking the main WP query into consideration.
* @param array $term_ids
* @param string $taxonomy
* @param string $query_type
* @return array
*/
protected function get_filtered_term_product_counts( $term_ids, $taxonomy, $query_type ) {
global $wpdb;
$tax_query = WC_Query::get_main_tax_query();
$meta_query = WC_Query::get_main_meta_query();
if ( 'or' === $query_type ) {
foreach ( $tax_query as $key => $query ) {
if ( $taxonomy === $query['taxonomy'] ) {
unset( $tax_query[ $key ] );
}
}
}
$meta_query = new WP_Meta_Query( $meta_query );
$tax_query = new WP_Tax_Query( $tax_query );
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
$tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' );
$sql = "
SELECT COUNT( {$wpdb->posts}.ID ) as term_count, term_count_relationships.term_taxonomy_id as term_count_id FROM {$wpdb->posts}
INNER JOIN {$wpdb->term_relationships} AS term_count_relationships ON ({$wpdb->posts}.ID = term_count_relationships.object_id)
" . $tax_query_sql['join'] . $meta_query_sql['join'] . "
WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish'
" . $tax_query_sql['where'] . $meta_query_sql['where'] . "
AND term_count_relationships.term_taxonomy_id IN (" . implode( ',', array_map( 'absint', $term_ids ) ) . ")
GROUP BY term_count_relationships.term_taxonomy_id;
";
$results = $wpdb->get_results( $sql );
return wp_list_pluck( $results, 'term_count', 'term_count_id' );
}
/**
* Show list based layered nav.
* @param array $terms
@ -317,51 +359,30 @@ class WC_Widget_Layered_Nav extends WC_Widget {
* @return bool Will nav display?
*/
protected function layered_nav_list( $terms, $taxonomy, $query_type ) {
global $_chosen_attributes;
// List display
echo '<ul>';
// flip the filtered_products_ids array so that we can use the more efficient array_intersect_key
$filtered_product_ids = array_flip( WC()->query->filtered_product_ids );
$unfiltered_product_ids = array_flip( WC()->query->unfiltered_product_ids );
$term_counts = $this->get_filtered_term_product_counts( wp_list_pluck( $terms, 'term_id' ), $taxonomy, $query_type );
$_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes();
$found = false;
foreach ( $terms as $term ) {
// Get count based on current view - uses transients
// flip the product_in_term array so that we can use array_intersect_key
$_products_in_term = array_flip( wc_get_term_product_ids( $term->term_id, $taxonomy ) );
$current_values = isset( $_chosen_attributes[ $taxonomy ]['terms'] ) ? $_chosen_attributes[ $taxonomy ]['terms'] : array();
$option_is_set = in_array( $term->slug, $current_values );
$count = isset( $term_counts[ $term->term_id ] ) ? $term_counts[ $term->term_id ] : 0;
// skip the term for the current archive
if ( $this->get_current_term_id() === $term->term_id ) {
continue;
}
// If this is an AND query, only show options with count > 0
if ( 'and' === $query_type ) {
// Intersect both arrays now they have been flipped so that we can use their keys
$count = sizeof( array_intersect_key( $_products_in_term, $filtered_product_ids ) );
// Only show options with count > 0
if ( 0 < $count ) {
$found = true;
}
if ( 0 === $count && ! $option_is_set ) {
} elseif ( 'and' === $query_type && 0 === $count && ! $option_is_set ) {
continue;
}
// If this is an OR query, show all options so search can be expanded
} else {
// Intersect both arrays now they have been flipped so that we can use their keys
$count = sizeof( array_intersect_key( $_products_in_term, $unfiltered_product_ids ) );
if ( 0 < $count ) {
$found = true;
}
}
$filter_name = 'filter_' . sanitize_title( str_replace( 'pa_', '', $taxonomy ) );
$current_filter = isset( $_GET[ $filter_name ] ) ? explode( ',', wc_clean( $_GET[ $filter_name ] ) ) : array();
$current_filter = array_map( 'sanitize_title', $current_filter );
@ -370,7 +391,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
$current_filter[] = $term->slug;
}
$link = $this->get_page_base_url();
$link = $this->get_page_base_url( $taxonomy );
// Add current filters to URL.
foreach ( $current_filter as $key => $value ) {

View File

@ -32,7 +32,15 @@ class WC_Widget_Price_Filter extends WC_Widget {
'label' => __( 'Title', 'woocommerce' )
)
);
$suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
wp_register_script( 'wc-jquery-ui-touchpunch', WC()->plugin_url() . '/assets/js/jquery-ui-touch-punch/jquery-ui-touch-punch' . $suffix . '.js', array( 'jquery-ui-slider' ), WC_VERSION, true );
wp_register_script( 'wc-price-slider', WC()->plugin_url() . '/assets/js/frontend/price-slider' . $suffix . '.js', array( 'jquery-ui-slider', 'wc-jquery-ui-touchpunch' ), WC_VERSION, true );
wp_localize_script( 'wc-price-slider', 'woocommerce_price_slider_params', array(
'currency_symbol' => get_woocommerce_currency_symbol(),
'currency_pos' => get_option( 'woocommerce_currency_pos' ),
'min_price' => isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : '',
'max_price' => isset( $_GET['max_price'] ) ? esc_attr( $_GET['max_price'] ) : ''
) );
parent::__construct();
}
@ -45,14 +53,14 @@ class WC_Widget_Price_Filter extends WC_Widget {
* @param array $instance
*/
public function widget( $args, $instance ) {
global $_chosen_attributes, $wpdb, $wp;
global $wp, $wp_the_query;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
if ( sizeof( WC()->query->unfiltered_product_ids ) == 0 ) {
return; // None shown - return
if ( ! $wp_the_query->post_count ) {
return;
}
$min_price = isset( $_GET['min_price'] ) ? esc_attr( $_GET['min_price'] ) : '';
@ -87,7 +95,7 @@ class WC_Widget_Price_Filter extends WC_Widget {
$fields .= '<input type="hidden" name="min_rating" value="' . esc_attr( $_GET['min_rating'] ) . '" />';
}
if ( $_chosen_attributes ) {
if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) {
foreach ( $_chosen_attributes as $attribute => $data ) {
$taxonomy_filter = 'filter_' . str_replace( 'pa_', '', $attribute );
@ -99,51 +107,12 @@ class WC_Widget_Price_Filter extends WC_Widget {
}
}
if ( 0 === sizeof( WC()->query->layered_nav_product_ids ) ) {
$min = floor( $wpdb->get_var( "
SELECT min(meta_value + 0)
FROM {$wpdb->posts} as posts
LEFT JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
WHERE meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price', '_min_variation_price' ) ) ) ) . "')
AND meta_value != ''
" ) );
$max = ceil( $wpdb->get_var( "
SELECT max(meta_value + 0)
FROM {$wpdb->posts} as posts
LEFT JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
WHERE meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')
" ) );
} else {
$min = floor( $wpdb->get_var( "
SELECT min(meta_value + 0)
FROM {$wpdb->posts} as posts
LEFT JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
WHERE meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price', '_min_variation_price' ) ) ) ) . "')
AND meta_value != ''
AND (
posts.ID IN (" . implode( ',', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ")
OR (
posts.post_parent IN (" . implode( ',', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ")
AND posts.post_parent != 0
)
)
" ) );
$max = ceil( $wpdb->get_var( "
SELECT max(meta_value + 0)
FROM {$wpdb->posts} as posts
LEFT JOIN {$wpdb->postmeta} as postmeta ON posts.ID = postmeta.post_id
WHERE meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')
AND (
posts.ID IN (" . implode( ',', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ")
OR (
posts.post_parent IN (" . implode( ',', array_map( 'absint', WC()->query->layered_nav_product_ids ) ) . ")
AND posts.post_parent != 0
)
)
" ) );
}
// Find min and max price in current result set
$prices = $this->get_filtered_price();
$min = floor( $prices->min_price );
$max = ceil( $prices->max_price );
if ( $min == $max ) {
if ( $min === $max ) {
return;
}
@ -155,16 +124,15 @@ class WC_Widget_Price_Filter extends WC_Widget {
$form_action = preg_replace( '%\/page/[0-9]+%', '', home_url( trailingslashit( $wp->request ) ) );
}
// Adjust min and max if the store taxes are not displayed how they are stored
if ( wc_tax_enabled() && 'incl' === get_option( 'woocommerce_tax_display_shop' ) && ! wc_prices_include_tax() ) {
$tax_classes = array_merge( array( '' ), WC_Tax::get_tax_classes() );
$min = 0;
foreach ( $tax_classes as $tax_class ) {
$tax_rates = WC_Tax::get_rates( $tax_class );
$class_min = $min + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $min, $tax_rates ) );
$class_max = $max + WC_Tax::get_tax_total( WC_Tax::calc_exclusive_tax( $max, $tax_rates ) );
if ( $min === 0 || $class_min < $min ) {
if ( $class_min < $min ) {
$min = $class_min;
}
if ( $class_max > $max ) {
@ -177,7 +145,7 @@ class WC_Widget_Price_Filter extends WC_Widget {
<div class="price_slider_wrapper">
<div class="price_slider" style="display:none;"></div>
<div class="price_slider_amount">
<input type="text" id="min_price" name="min_price" value="' . esc_attr( $min_price ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_min_amount', $min ) ) . '" placeholder="' . esc_attr__('Min price', 'woocommerce' ) . '" />
<input type="text" id="min_price" name="min_price" value="' . esc_attr( $min_price ) . '" data-min="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_min_amount', $min ) ) . '" placeholder="' . esc_attr__( 'Min price', 'woocommerce' ) . '" />
<input type="text" id="max_price" name="max_price" value="' . esc_attr( $max_price ) . '" data-max="' . esc_attr( apply_filters( 'woocommerce_price_filter_widget_max_amount', $max ) ) . '" placeholder="' . esc_attr__( 'Max price', 'woocommerce' ) . '" />
<button type="submit" class="button">' . __( 'Filter', 'woocommerce' ) . '</button>
<div class="price_label" style="display:none;">
@ -191,4 +159,46 @@ class WC_Widget_Price_Filter extends WC_Widget {
$this->widget_end( $args );
}
/**
* Get filtered min price for current products.
* @return int
*/
protected function get_filtered_price() {
global $wpdb, $wp_the_query;
$args = $wp_the_query->query_vars;
$tax_query = isset( $args['tax_query'] ) ? $args['tax_query'] : array();
$meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array();
if ( ! empty( $args['taxonomy'] ) && ! empty( $args['term'] ) ) {
$tax_query[] = array(
'taxonomy' => $args['taxonomy'],
'terms' => array( $args['term'] ),
'field' => 'slug',
);
}
foreach ( $meta_query as $key => $query ) {
if ( ! empty( $query['price_filter'] ) || ! empty( $query['rating_filter'] ) ) {
unset( $meta_query[ $key ] );
}
}
$meta_query = new WP_Meta_Query( $meta_query );
$tax_query = new WP_Tax_Query( $tax_query );
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
$tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' );
$sql = "SELECT min( CAST( price_meta.meta_value AS UNSIGNED ) ) as min_price, max( CAST( price_meta.meta_value AS UNSIGNED ) ) as max_price FROM {$wpdb->posts} ";
$sql .= " LEFT JOIN {$wpdb->postmeta} as price_meta ON {$wpdb->posts}.ID = price_meta.post_id " . $tax_query_sql['join'] . $meta_query_sql['join'];
$sql .= " WHERE {$wpdb->posts}.post_type = 'product'
AND {$wpdb->posts}.post_status = 'publish'
AND price_meta.meta_key IN ('" . implode( "','", array_map( 'esc_sql', apply_filters( 'woocommerce_price_filter_meta_keys', array( '_price' ) ) ) ) . "')
AND price_meta.meta_value > '' ";
$sql .= $tax_query_sql['where'] . $meta_query_sql['where'];
return $wpdb->get_row( $sql );
}
}

View File

@ -71,9 +71,63 @@ class WC_Widget_Rating_Filter extends WC_Widget {
$link = add_query_arg( 'post_type', wc_clean( $_GET['post_type'] ), $link );
}
// All current filters
if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) {
foreach ( $_chosen_attributes as $name => $data ) {
$filter_name = sanitize_title( str_replace( 'pa_', '', $name ) );
if ( ! empty( $data['terms'] ) ) {
$link = add_query_arg( 'filter_' . $filter_name, implode( ',', $data['terms'] ), $link );
}
if ( 'or' == $data['query_type'] ) {
$link = add_query_arg( 'query_type_' . $filter_name, 'or', $link );
}
}
}
return $link;
}
/**
* Count products after other filters have occured by adjusting the main query.
* @param int $rating
* @return int
*/
protected function get_filtered_product_count( $rating ) {
global $wpdb;
$tax_query = WC_Query::get_main_tax_query();
$meta_query = WC_Query::get_main_meta_query();
// Unset current rating filter
foreach ( $meta_query as $key => $query ) {
if ( ! empty( $query['rating_filter'] ) ) {
unset( $meta_query[ $key ] );
}
}
// Set new rating filter
$meta_query[] = array(
'key' => '_wc_average_rating',
'value' => $rating,
'compare' => '>=',
'type' => 'DECIMAL',
'rating_filter' => true
);
$meta_query = new WP_Meta_Query( $meta_query );
$tax_query = new WP_Tax_Query( $tax_query );
$meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' );
$tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' );
$sql = "SELECT COUNT( {$wpdb->posts}.ID ) FROM {$wpdb->posts} ";
$sql .= $tax_query_sql['join'] . $meta_query_sql['join'];
$sql .= " WHERE {$wpdb->posts}.post_type = 'product' AND {$wpdb->posts}.post_status = 'publish' ";
$sql .= $tax_query_sql['where'] . $meta_query_sql['where'];
return absint( $wpdb->get_var( $sql ) );
}
/**
* widget function.
*
@ -83,16 +137,18 @@ class WC_Widget_Rating_Filter extends WC_Widget {
* @param array $instance
*/
public function widget( $args, $instance ) {
global $_chosen_attributes, $wpdb, $wp;
global $wp_the_query;
if ( ! is_post_type_archive( 'product' ) && ! is_tax( get_object_taxonomies( 'product' ) ) ) {
return;
}
if ( ! sizeof( WC()->query->unfiltered_product_ids ) ) {
return; // None shown - return
if ( ! $wp_the_query->post_count ) {
return;
}
ob_start();
$min_rating = isset( $_GET['min_rating'] ) ? absint( $_GET['min_rating'] ) : '';
$this->widget_start( $args, $instance );
@ -100,6 +156,13 @@ class WC_Widget_Rating_Filter extends WC_Widget {
echo '<ul>';
for ( $rating = 4; $rating >= 1; $rating-- ) {
$count = $this->get_filtered_product_count( $rating );
if ( ! $count ) {
continue;
}
$found = true;
$link = $this->get_page_base_url();
$link = $min_rating !== $rating ? add_query_arg( 'min_rating', $rating, $link ) : $link;
@ -109,7 +172,7 @@ class WC_Widget_Rating_Filter extends WC_Widget {
echo '<span class="star-rating" title="' . esc_attr( sprintf( __( 'Rated %s and above', 'woocommerce' ), $rating ) ). '">
<span style="width:' . esc_attr( ( $rating / 5 ) * 100 ) . '%">' . sprintf( __( 'Rated %s and above', 'woocommerce'), $rating ) . '</span>
</span>';
</span> (' . esc_html( $count ) . ')';
echo '</a>';
@ -119,5 +182,11 @@ class WC_Widget_Rating_Filter extends WC_Widget {
echo '</ul>';
$this->widget_end( $args );
if ( ! $found ) {
ob_end_clean();
} else {
echo ob_get_clean();
}
}
}

View File

@ -7,6 +7,7 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true"
syntaxCheck="true"
>
<testsuites>
<testsuite name="WooCommerce Test Suite">

View File

@ -7,6 +7,7 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
verbose="true"
syntaxCheck="true"
>
<testsuites>
<testsuite name="WooCommerce Test Suite">

View File

@ -160,6 +160,7 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
= 2.6.0 - TBD =
* Dev - Made coupon optional in cart has_discount() method.
* Tweak - Removed tag/cat classes from loops since WP does the same.
* Tweak - Added hash check for orders so that if the cart changes before payment, a new order is made.
[See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt).

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/archive-product.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/auth/footer.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/auth/form-grant-access.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/auth/form-login.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/auth/header.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-empty.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-item-data.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -6,10 +6,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-shipping.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart-totals.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cart.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/cross-sells.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
@ -16,16 +17,14 @@
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
exit;
}
global $product, $woocommerce_loop;
$crosssells = WC()->cart->get_cross_sells();
if ( 0 === sizeof( $crosssells ) ) return;
$meta_query = WC()->query->get_meta_query();
if ( ! $crosssells = WC()->cart->get_cross_sells() ) {
return;
}
$args = array(
'post_type' => 'product',
@ -34,11 +33,11 @@ $args = array(
'posts_per_page' => apply_filters( 'woocommerce_cross_sells_total', $posts_per_page ),
'orderby' => $orderby,
'post__in' => $crosssells,
'meta_query' => $meta_query
'meta_query' => WC()->query->get_meta_query()
);
$products = new WP_Query( $args );
$woocommerce_loop['name'] = 'cross-sells';
$woocommerce_loop['columns'] = apply_filters( 'woocommerce_cross_sells_columns', $columns );
if ( $products->have_posts() ) : ?>

View File

@ -6,10 +6,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/mini-cart.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -6,10 +6,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/proceed-to-checkout-button.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/cart/shipping-calculator.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/cart-errors.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-billing.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-checkout.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-coupon.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-login.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-pay.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/form-shipping.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/payment-method.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/payment.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/review-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/checkout/thankyou.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/content-product.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
@ -19,37 +20,14 @@ if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
global $product, $woocommerce_loop;
// Store loop count we're currently on
if ( empty( $woocommerce_loop['loop'] ) ) {
$woocommerce_loop['loop'] = 0;
}
// Store column count for displaying the grid
if ( empty( $woocommerce_loop['columns'] ) ) {
$woocommerce_loop['columns'] = apply_filters( 'loop_shop_columns', 4 );
}
global $product;
// Ensure visibility
if ( ! $product || ! $product->is_visible() ) {
if ( empty( $product ) || ! $product->is_visible() ) {
return;
}
// Increase loop count
$woocommerce_loop['loop']++;
// Extra post classes
$classes = array();
if ( 0 === ( $woocommerce_loop['loop'] - 1 ) % $woocommerce_loop['columns'] || 1 === $woocommerce_loop['columns'] ) {
$classes[] = 'first';
}
if ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
$classes[] = 'last';
}
?>
<li <?php post_class( $classes ); ?>>
<li <?php post_class(); ?>>
<?php
/**
* woocommerce_before_shop_loop_item hook.
@ -89,5 +67,4 @@ if ( 0 === $woocommerce_loop['loop'] % $woocommerce_loop['columns'] ) {
*/
do_action( 'woocommerce_after_shop_loop_item' );
?>
</li>

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/content-product_cat.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes
@ -18,21 +19,6 @@
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $woocommerce_loop;
// Store loop count we're currently on.
if ( empty( $woocommerce_loop['loop'] ) ) {
$woocommerce_loop['loop'] = 0;
}
// Store column count for displaying the grid.
if ( empty( $woocommerce_loop['columns'] ) ) {
$woocommerce_loop['columns'] = apply_filters( 'loop_shop_columns', 4 );
}
// Increase loop count.
$woocommerce_loop['loop']++;
?>
<li <?php wc_product_cat_class( '', $category ); ?>>
<?php

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/content-single-product.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/content-widget-product.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/admin-cancelled-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/admin-failed-order.php
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer)
* will need to copy the new files to your theme to maintain compatibility. We try to do this
* as little as possible, but it does happen. When this occurs the version of the template file will
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/admin-new-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-completed-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-invoice.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-new-account.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-note.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-refunded-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/customer-reset-password.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-addresses.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -6,10 +6,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-addresses.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-footer.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-header.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-order-details.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-order-items.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/email-styles.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/admin-cancelled-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/admin-failed-order.php
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer)
* will need to copy the new files to your theme to maintain compatibility. We try to do this
* as little as possible, but it does happen. When this occurs the version of the template file will
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/admin-new-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-completed-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-invoice.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-new-account.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-note.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-processing-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-refunded-order.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/customer-reset-password.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/email-addresses.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -6,10 +6,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/email-addresses.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/email-order-details.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/emails/plain/email-order-items.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/breadcrumb.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/form-login.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/quantity-input.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/sidebar.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/wrapper-end.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/global/wrapper-start.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/loop/add-to-cart.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/loop/loop-end.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

View File

@ -4,10 +4,11 @@
*
* This template can be overridden by copying it to yourtheme/woocommerce/loop/loop-start.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you (the theme developer).
* will need to copy the new files to your theme to maintain compatibility. We try to do this.
* as little as possible, but it does happen. When this occurs the version of the template file will.
* be bumped and the readme will list any important changes.
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see http://docs.woothemes.com/document/template-structure/
* @author WooThemes

Some files were not shown because too many files have changed in this diff Show More