PageRenderTime 47ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/widgets/recently_viewed.php

https://github.com/ThemesWpFr/jigoshop
PHP | 253 lines | 131 code | 44 blank | 78 comment | 14 complexity | 33c41821857e7674b0e3ef068390fbce MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /**
  3. * Recently Viewed Products Widget
  4. *
  5. * DISCLAIMER
  6. *
  7. * Do not edit or add directly to this file if you wish to upgrade Jigoshop to newer
  8. * versions in the future. If you wish to customise Jigoshop core for your needs,
  9. * please use our GitHub repository to publish essential changes for consideration.
  10. *
  11. * @package Jigoshop
  12. * @category Widgets
  13. * @author Jigowatt
  14. * @copyright Copyright Š 2011-2012 Jigowatt Ltd.
  15. * @license http://jigoshop.com/license/commercial-edition
  16. */
  17. class Jigoshop_Widget_Recently_Viewed_Products extends WP_Widget {
  18. /**
  19. * Constructor
  20. *
  21. * Setup the widget with the available options
  22. * Add actions to clear the cache whenever a post is saved|deleted or a theme is switched
  23. */
  24. public function __construct() {
  25. $options = array(
  26. 'classname' => 'widget_recently_viewed_products',
  27. 'description' => __( 'A list of your customers most recently viewed products', 'jigoshop' )
  28. );
  29. // Create the widget
  30. parent::__construct( 'recently_viewed_products', __( 'Jigoshop: Recently Viewed', 'jigoshop' ), $options );
  31. // Flush cache after every save
  32. add_action( 'save_post', array( &$this, 'flush_widget_cache' ) );
  33. add_action( 'deleted_post', array( &$this, 'flush_widget_cache' ) );
  34. add_action( 'switch_theme', array( &$this, 'flush_widget_cache' ) );
  35. // Attach the tracker to the product view action
  36. add_action( 'jigoshop_before_single_product', array( &$this, 'jigoshop_product_view_tracker' ), 10, 2 );
  37. }
  38. /**
  39. * Widget
  40. *
  41. * Display the widget in the sidebar
  42. * Save output to the cache if empty
  43. *
  44. * @param array sidebar arguments
  45. * @param array instance
  46. */
  47. public function widget( $args, $instance ) {
  48. // Get the most recently viewed products from the cache
  49. $cache = wp_cache_get( 'widget_recently_viewed_products', 'widget' );
  50. // If no entry exists use array
  51. if ( ! is_array( $cache ) ) {
  52. $cache = array();
  53. }
  54. // If cached get from the cache
  55. if ( isset( $cache[$args['widget_id']] ) ) {
  56. echo $cache[$args['widget_id']];
  57. return false;
  58. }
  59. // Check if session contains recently viewed products
  60. if ( empty( jigoshop_session::instance()->recently_viewed_products ) )
  61. return false;
  62. // Start buffering the output
  63. ob_start();
  64. extract($args);
  65. // Set the widget title
  66. $title = apply_filters(
  67. 'widget_title',
  68. ($instance['title']) ? $instance['title'] : __('Recently Viewed Products', 'jigoshop'),
  69. $instance,
  70. $this->id_base
  71. );
  72. // Set number of products to fetch
  73. if( ! $number = absint( $instance['number'] ) ) {
  74. $number = 5;
  75. }
  76. // Set up query
  77. $query_args = array(
  78. 'posts_per_page' => $number,
  79. 'post_type' => 'product',
  80. 'post_status' => 'publish',
  81. 'nopaging' => true,
  82. 'post__in' => jigoshop_session::instance()->recently_viewed_products,
  83. 'orderby' => 'date', // TODO: Not ideal as it doesn't order latest first
  84. 'meta_query' => array(
  85. array(
  86. 'key' => 'visibility',
  87. 'value' => array('catalog', 'visible'),
  88. 'compare' => 'IN',
  89. ),
  90. )
  91. );
  92. // Run the query
  93. $q = new WP_Query( $query_args );
  94. if( $q->have_posts() ) {
  95. // Print the widget wrapper & title
  96. echo $before_widget;
  97. echo $before_title . $title . $after_title;
  98. // Open the list
  99. echo '<ul class="product_list_widget recently_viewed_products">';
  100. // Print out each produt
  101. while( $q->have_posts() ) : $q->the_post();
  102. // Get new jigoshop_product instance
  103. $_product = new jigoshop_product(get_the_ID());
  104. echo '<li>';
  105. //print the product title with a permalink
  106. echo '<a href="'.get_permalink().'" title="'.esc_attr( get_the_title() ).'">';
  107. // Print the product image
  108. echo (has_post_thumbnail())
  109. ? the_post_thumbnail('shop_tiny')
  110. : jigoshop_get_image_placeholder('shop_tiny');
  111. echo '<span class="js_widget_product_title">' . get_the_title() . '</span>';
  112. echo '</a>';
  113. // Print the price with wrappers ..yum!
  114. echo '<span class="js_widget_product_price">' . $_product->get_price_html() . '</span>';
  115. echo '</li>';
  116. endwhile;
  117. echo '</ul>'; // Close the list
  118. // Print closing widget wrapper
  119. echo $after_widget;
  120. // Reset the global $the_post as this query will have stomped on it
  121. wp_reset_postdata();
  122. }
  123. // Flush output buffer and save to cache
  124. $cache[$args['widget_id']] = ob_get_flush();
  125. wp_cache_set( 'widget_recent_products', $cache, 'widget' );
  126. }
  127. public function update( $new_instance, $old_instance ) {
  128. $instance = $old_instance;
  129. // Save the new values
  130. $instance['title'] = strip_tags( $new_instance['title'] );
  131. $instance['number'] = absint( $new_instance['number'] );
  132. // Flush the cache
  133. $this->flush_widget_cache();
  134. // Unset the session array
  135. unset( jigoshop_session::instance()->recently_viewed_products );
  136. // Remove the cache entry from the options array
  137. $alloptions = wp_cache_get( 'alloptions', 'options' );
  138. if ( isset( $alloptions['widget_recently_viewed_products'] ) ) {
  139. delete_option( 'widget_recently_viewed_products' );
  140. }
  141. return $instance;
  142. }
  143. /**
  144. * Flush Widget Cache
  145. *
  146. * Flushes the cached output
  147. */
  148. public function flush_widget_cache() {
  149. wp_cache_delete( 'widget_recently_viewed_products', 'widget' );
  150. }
  151. /**
  152. * Logs viewed products into the session
  153. *
  154. * @return void
  155. **/
  156. public function jigoshop_product_view_tracker( $post, $_product ) {
  157. $instance = get_option('widget_recently_viewed_products');
  158. $number = 0;
  159. if ( ! empty( $instance )) foreach ( $instance as $index => $entry ) {
  160. if ( is_array( $entry )) foreach ( $entry as $key => $value ) {
  161. if ( $key == 'number' ) {
  162. $number = $value;
  163. break;
  164. }
  165. }
  166. }
  167. if ( ! $number ) return false; // stop the show!
  168. // Check if we already have some data
  169. if ( ! is_array( jigoshop_session::instance()->recently_viewed_products ) ) {
  170. $viewed = array();
  171. jigoshop_session::instance()->recently_viewed_products = $viewed;
  172. }
  173. // If the product isn't in the list, add it
  174. if ( ! in_array( $post->ID, jigoshop_session::instance()->recently_viewed_products) ) {
  175. $viewed = jigoshop_session::instance()->recently_viewed_products;
  176. $viewed[] = $post->ID;
  177. jigoshop_session::instance()->recently_viewed_products = $viewed;
  178. }
  179. if ( sizeof( jigoshop_session::instance()->recently_viewed_products) > $number ) {
  180. $viewed = jigoshop_session::instance()->recently_viewed_products;
  181. array_shift( $viewed );
  182. jigoshop_session::instance()->recently_viewed_products = $viewed;
  183. }
  184. }
  185. /**
  186. * Form
  187. *
  188. * Displays the form for the wordpress admin
  189. *
  190. * @param array instance
  191. */
  192. public function form( $instance ) {
  193. // Get instance data
  194. $title = isset( $instance['title'] ) ? esc_attr( $instance['title'] ) : null;
  195. $number = isset( $instance['number'] ) ? absint( $instance['number'] ) : 5;
  196. // Widget Title
  197. echo "
  198. <p>
  199. <label for='{$this->get_field_id( 'title' )}'>" . __( 'Title:', 'jigoshop' ) . "</label>
  200. <input class='widefat' id='{$this->get_field_id( 'title' )}' name='{$this->get_field_name( 'title' )}' type='text' value='{$title}' />
  201. </p>";
  202. // Number of posts to fetch
  203. echo "
  204. <p>
  205. <label for='{$this->get_field_id( 'number' )}'>" . __( 'Number of products to show:', 'jigoshop' ) . "</label>
  206. <input id='{$this->get_field_id( 'number' )}' name='{$this->get_field_name( 'number' )}' type='number' value='{$number}' />
  207. </p>";
  208. }
  209. }