From 0caca2d401f265a0263e50d05b79d5244e46e6e2 Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Sat, 12 Jan 2013 10:53:08 +0000 Subject: [PATCH] GET vars for sorting (to work better with cache) --- admin/settings/settings-init.php | 12 +-- classes/class-wc-query.php | 74 ++++++++++++++----- .../class-wc-widget-top-rated-products.php | 29 +------- templates/loop/sorting.php | 20 +++-- 4 files changed, 75 insertions(+), 60 deletions(-) diff --git a/admin/settings/settings-init.php b/admin/settings/settings-init.php index 358ba907f29..4ccafeca915 100644 --- a/admin/settings/settings-init.php +++ b/admin/settings/settings-init.php @@ -511,10 +511,12 @@ $woocommerce_settings['catalog'] = apply_filters('woocommerce_catalog_settings', 'default' => 'title', 'type' => 'select', 'options' => apply_filters('woocommerce_default_catalog_orderby_options', array( - 'menu_order' => __( 'Default sorting', 'woocommerce' ), - 'title' => __( 'Sort alphabetically', 'woocommerce' ), - 'date' => __( 'Sort by most recent', 'woocommerce' ), - 'price' => __( 'Sort by price', 'woocommerce' ), + 'menu_order' => __( 'Default sorting (custom ordering + name)', 'woocommerce' ), + 'popularity' => __( 'Popularity (sales)', 'woocommerce' ), + 'rating' => __( 'Average Rating', 'woocommerce' ), + 'date' => __( 'Sort by most recent', 'woocommerce' ), + 'price' => __( 'Sort by price (asc)', 'woocommerce' ), + 'price-desc' => __( 'Sort by price (desc)', 'woocommerce' ), )), 'desc_tip' => true, ), @@ -638,7 +640,7 @@ $woocommerce_settings['catalog'] = apply_filters('woocommerce_catalog_settings', array( 'title' => __( 'Product Ratings', 'woocommerce' ), - 'desc' => __( 'Enable the rating field on the review form', 'woocommerce' ), + 'desc' => __( 'Enable ratings on reviews', 'woocommerce' ), 'id' => 'woocommerce_enable_review_rating', 'default' => 'yes', 'type' => 'checkbox', diff --git a/classes/class-wc-query.php b/classes/class-wc-query.php index bca977be0e8..ac3aaef12ed 100644 --- a/classes/class-wc-query.php +++ b/classes/class-wc-query.php @@ -97,7 +97,7 @@ class WC_Query { } $this->product_query( $q ); - + if ( is_search() ) { add_filter( 'posts_where', array( $this, 'search_post_excerpt' ) ); add_filter( 'wp', array( $this, 'remove_posts_where' ) ); @@ -105,13 +105,13 @@ class WC_Query { // 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(); } /** - * search_post_excerpt function. + * search_post_excerpt function. * * @access public * @param string $where (default: '') @@ -119,15 +119,15 @@ class WC_Query { */ public function search_post_excerpt( $where = '' ) { global $wp_the_query; - + // If this is not a WC Query, do not modify the query if ( empty( $wp_the_query->query_vars['wc_query'] ) ) return $where; $where = preg_replace( "/post_title\s+LIKE\s*(\'[^\']+\')/", - "post_title LIKE $1) OR (post_excerpt LIKE $1", $where ); - + "post_title LIKE $1) OR (post_excerpt LIKE $1", $where ); + return $where; } @@ -272,10 +272,10 @@ class WC_Query { * @access public * @return void */ - public function remove_posts_where() { + public function remove_posts_where() { 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. @@ -346,36 +346,44 @@ class WC_Query { public function get_catalog_ordering_args( $orderby = '', $order = '' ) { global $woocommerce; - // Get ordering from session unless defined - if ( ! $orderby ) - $orderby = isset( $woocommerce->session->orderby ) ? $woocommerce->session->orderby : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); + // Get ordering from query string unless defined + if ( ! $orderby ) { + $orderby_value = isset( $_GET['orderby'] ) ? woocommerce_clean( $_GET['orderby'] ) : apply_filters( 'woocommerce_default_catalog_orderby', get_option( 'woocommerce_default_catalog_orderby' ) ); + + // Get order + orderby args from string + $orderby_value = explode( '-', $orderby_value ); + $orderby = esc_attr( $orderby_value[0] ); + $order = ! empty( $orderby_value[1] ) ? $orderby_value[1] : $order; + } $args = array(); switch ( $orderby ) { case 'date' : $args['orderby'] = 'date'; - $args['order'] = $order ? $order : 'desc'; + $args['order'] = $order == 'asc' ? 'asc' : 'desc'; $args['meta_key'] = ''; break; case 'price' : $args['orderby'] = 'meta_value_num'; - $args['order'] = $order ? $order : 'asc'; + $args['order'] = $order == 'desc' ? 'desc' : 'asc'; $args['meta_key'] = '_price'; break; - case 'high_price' : + case 'popularity' : $args['orderby'] = 'meta_value_num'; - $args['order'] = $order ? $order : 'desc'; - $args['meta_key'] = '_price'; + $args['order'] = $order == 'asc' ? 'asc' : 'desc'; + $args['meta_key'] = 'total_sales'; break; - case 'title' : - $args['orderby'] = 'title'; - $args['order'] = $order ? $order : 'asc'; + case 'rating' : + $args['orderby'] = 'menu_order title'; + $args['order'] = $order == 'desc' ? 'desc' : 'asc'; $args['meta_key'] = ''; + + add_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) ); break; default : $args['orderby'] = 'menu_order title'; - $args['order'] = $order ? $order : 'asc'; + $args['order'] = $order == 'desc' ? 'desc' : 'asc'; $args['meta_key'] = ''; break; } @@ -383,6 +391,32 @@ class WC_Query { return apply_filters( 'woocommerce_get_catalog_ordering_args', $args ); } + /** + * order_by_rating_post_clauses function. + * + * @access public + * @param array $args + * @return array + */ + public function order_by_rating_post_clauses( $args ) { + + 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"; + + $args['groupby'] = "$wpdb->posts.ID"; + + return $args; + } /** * Returns a meta query to handle product visibility diff --git a/classes/widgets/class-wc-widget-top-rated-products.php b/classes/widgets/class-wc-widget-top-rated-products.php index cc727f7d9ce..f73e844668d 100644 --- a/classes/widgets/class-wc-widget-top-rated-products.php +++ b/classes/widgets/class-wc-widget-top-rated-products.php @@ -75,7 +75,7 @@ class WC_Widget_Top_Rated_Products extends WP_Widget { else if ( $number < 1 ) $number = 1; else if ( $number > 15 ) $number = 15; - add_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) ); + add_filter( 'posts_clauses', array( $woocommerce->query, 'order_by_rating_post_clauses' ) ); $query_args = array('posts_per_page' => $number, 'no_found_rows' => 1, 'post_status' => 'publish', 'post_type' => 'product' ); @@ -107,7 +107,7 @@ class WC_Widget_Top_Rated_Products extends WP_Widget { endif; wp_reset_query(); - remove_filter( 'posts_clauses', array( $this, 'order_by_rating_post_clauses' ) ); + remove_filter( 'posts_clauses', array( $woocommerce->query, 'order_by_rating_post_clauses' ) ); $content = ob_get_clean(); @@ -118,31 +118,6 @@ class WC_Widget_Top_Rated_Products extends WP_Widget { wp_cache_set('widget_top_rated_products', $cache, 'widget'); } - /** - * order_by_rating_post_clauses function. - * - * @access public - * @param array $args - * @return array - */ - function order_by_rating_post_clauses( $args ) { - - global $wpdb; - - $args['where'] .= " AND $wpdb->commentmeta.meta_key = 'rating' "; - - $args['join'] .= " - LEFT 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'] = "$wpdb->commentmeta.meta_value DESC"; - - $args['groupby'] = "$wpdb->posts.ID"; - - return $args; - } - /** * update function. * diff --git a/templates/loop/sorting.php b/templates/loop/sorting.php index 71cdd688fc1..b9c1eca12bd 100644 --- a/templates/loop/sorting.php +++ b/templates/loop/sorting.php @@ -14,19 +14,23 @@ global $woocommerce, $wp_query; if ( ! woocommerce_products_will_display() || 1 == $wp_query->found_posts ) return; ?> -
- __( 'Default sorting', 'woocommerce' ), - 'title' => __( 'Sort alphabetically', 'woocommerce' ), - 'date' => __( 'Sort by most recent', 'woocommerce' ), - 'price' => __( 'Sort by price - low to high', 'woocommerce' ), - 'high_price' => __( 'Sort by price - high to low', 'woocommerce' ) + 'menu_order' => __( 'Default sorting', 'woocommerce' ), + 'popularity' => __( 'Sort by popularity', 'woocommerce' ), + 'rating' => __( 'Sort by average rating', 'woocommerce' ), + 'date' => __( 'Sort by newness', 'woocommerce' ), + 'price' => __( 'Sort by price: low to high', 'woocommerce' ), + 'price-desc' => __( 'Sort by price: high to low', 'woocommerce' ) ) ); + if ( get_option( 'woocommerce_enable_review_rating' ) == 'no' ) + unset( $catalog_orderby['rating'] ); + foreach ( $catalog_orderby as $id => $name ) - echo ''; + echo ''; ?>