From c7300fd9d3301d20ab7b4ecbdead80c6d534023e Mon Sep 17 00:00:00 2001 From: Mike Jolley Date: Tue, 1 Nov 2011 15:41:47 +0000 Subject: [PATCH] Total_sales / Best sellers widget --- classes/order.class.php | 30 +++++++- readme.txt | 2 + widgets/widget-best_sellers.php | 125 ++++++++++++++++++++++++++++++++ widgets/widgets-init.php | 2 + 4 files changed, 157 insertions(+), 2 deletions(-) create mode 100644 widgets/widget-best_sellers.php diff --git a/classes/order.class.php b/classes/order.class.php index 6d10fecd608..4107f52e128 100644 --- a/classes/order.class.php +++ b/classes/order.class.php @@ -379,7 +379,15 @@ class woocommerce_order { clean_term_cache( '', 'shop_order_status' ); // Date - if ($new_status->slug=='completed') update_post_meta( $this->id, '_completed_date', current_time('mysql') ); + if ($new_status->slug=='completed') : + update_post_meta( $this->id, '_completed_date', current_time('mysql') ); + endif; + + // Sales + if ($this->status == 'on-hold' && ($new_status->slug=='processing' || $new_status->slug=='completed')) : + $this->record_product_sales(); + endif; + endif; endif; @@ -405,6 +413,7 @@ class woocommerce_order { * Most of the time this should mark an order as 'processing' so that admin can process/post the items * If the cart contains only downloadable items then the order is 'complete' since the admin needs to take no action * Stock levels are reduced at this point + * Sales are also recorded for products */ function payment_complete() { @@ -415,6 +424,7 @@ class woocommerce_order { if (sizeof($this->items)>0) foreach ($this->items as $item) : if ($item['id']>0) : + $_product = $this->get_product_from_item( $item ); if ( $_product->exists && $_product->is_type('downloadable') ) : @@ -439,11 +449,27 @@ class woocommerce_order { $this->update_status($new_order_status); - // Payment is complete so reduce stock levels + // Payment is complete so reduce stock levels and record sales + $this->record_product_sales(); $this->reduce_order_stock(); } + /** + * Record sales + */ + function record_product_sales() { + + if (sizeof($this->items)>0) foreach ($this->items as $item) : + if ($item['id']>0) : + $sales = (int) get_post_meta( $item['id'], 'total_sales', true ); + $sales += (int) $item['qty']; + if ($sales) update_post_meta( $item['id'], 'total_sales', $sales ); + endif; + endforeach; + + } + /** * Reduce stock levels */ diff --git a/readme.txt b/readme.txt index 9caa129d0a5..41762867c52 100644 --- a/readme.txt +++ b/readme.txt @@ -91,6 +91,8 @@ Yes you can! Join in on our GitHub repository :) https://github.com/woothemes/wo * Added basic rss feeds for products and product categories * Added functions which show tax/vat conditionally * Made use of transients to store average ratings and improve performance +* Custom field for product total_sales when sold +* Best sellers widget based on new total_sales field * Edit category - image fix * Order Complete email heading fix * 100% discount when price excludes tax logic fix diff --git a/widgets/widget-best_sellers.php b/widgets/widget-best_sellers.php new file mode 100644 index 00000000000..35785cef9e6 --- /dev/null +++ b/widgets/widget-best_sellers.php @@ -0,0 +1,125 @@ +woo_widget_cssclass = 'widget_best_sellers'; + $this->woo_widget_description = __( 'Display a list of your best selling products on your site.', 'woothemes' ); + $this->woo_widget_idbase = 'woocommerce_best_sellers'; + $this->woo_widget_name = __('WooCommerce Best Sellers', 'woothemes' ); + + /* Widget settings. */ + $widget_ops = array( 'classname' => $this->woo_widget_cssclass, 'description' => $this->woo_widget_description ); + + /* Create the widget. */ + $this->WP_Widget('best_sellers', $this->woo_widget_name, $widget_ops); + + add_action( 'save_post', array(&$this, 'flush_widget_cache') ); + add_action( 'deleted_post', array(&$this, 'flush_widget_cache') ); + add_action( 'switch_theme', array(&$this, 'flush_widget_cache') ); + } + + /** @see WP_Widget */ + function widget($args, $instance) { + global $woocommerce; + + $cache = wp_cache_get('widget_best_sellers', 'widget'); + + if ( !is_array($cache) ) $cache = array(); + + if ( isset($cache[$args['widget_id']]) ) { + echo $cache[$args['widget_id']]; + return; + } + + ob_start(); + extract($args); + + $title = apply_filters('widget_title', empty($instance['title']) ? __('Best Sellers', 'woothemes') : $instance['title'], $instance, $this->id_base); + if ( !$number = (int) $instance['number'] ) + $number = 10; + else if ( $number < 1 ) + $number = 1; + else if ( $number > 15 ) + $number = 15; + + $query_args = array( + 'showposts' => $number, + 'nopaging' => 0, + 'post_status' => 'publish', + 'post_type' => 'product', + 'meta_key' => 'total_sales', + 'orderby' => 'meta_value' + ); + + $r = new WP_Query($query_args); + + if ($r->have_posts()) : +?> + + + + +update */ + function update( $new_instance, $old_instance ) { + $instance = $old_instance; + $instance['title'] = strip_tags($new_instance['title']); + $instance['number'] = (int) $new_instance['number']; + + $this->flush_widget_cache(); + + $alloptions = wp_cache_get( 'alloptions', 'options' ); + if ( isset($alloptions['widget_best_sellers']) ) delete_option('widget_best_sellers'); + + return $instance; + } + + function flush_widget_cache() { + wp_cache_delete('widget_best_sellers', 'widget'); + } + + /** @see WP_Widget->form */ + function form( $instance ) { + $title = isset($instance['title']) ? esc_attr($instance['title']) : ''; + if ( !isset($instance['number']) || !$number = (int) $instance['number'] ) $number = 5; + + ?> +

+

+ +

+

+ +