BeRocket_AAPF_Widget

BeRocket_AAPF_Widget - main filter widget.

Defined (1)

The class is defined in the following location(s).

/includes/widget.php  
  1. class BeRocket_AAPF_Widget extends WP_Widget { 
  2.  
  3. /** 
  4. * Constructor 
  5. */ 
  6. function __construct() { 
  7. global $wp_version; 
  8. /** Widget settings. */ 
  9. $widget_ops = array( 'classname' => 'widget_berocket_aapf', 'description' => __('Add Filters to Products page', 'BeRocket_AJAX_domain') ); 
  10.  
  11. /** Widget control settings. */ 
  12. $control_ops = array( 'id_base' => 'berocket_aapf_widget' ); 
  13.  
  14. /** Create the widget. */ 
  15. parent::__construct( 'berocket_aapf_widget', __('AJAX Product Filters', 'BeRocket_AJAX_domain'), $widget_ops, $control_ops ); 
  16.  
  17. add_filter( 'berocket_aapf_listener_wp_query_args', 'br_aapf_args_parser' ); 
  18.  
  19. /** 
  20. * Show widget to user 
  21. * @param array $args 
  22. * @param array $instance 
  23. */ 
  24. function widget( $args, $instance ) { 
  25. $br_options = apply_filters( 'berocket_aapf_listener_br_options', get_option('br_filters_options') ); 
  26.  
  27. if( @ $br_options['filters_turn_off'] || ( ! is_shop() && ! is_product_category() && ! is_product_taxonomy() && ! is_product_tag() ) ) return false; 
  28.  
  29. global $wp_query, $wp, $sitepress; 
  30.  
  31. /** main scripts */ 
  32. wp_enqueue_script( 'jquery-ui-core' ); 
  33. wp_enqueue_script( 'jquery-ui-slider' ); 
  34. wp_enqueue_script( 'berocket_aapf_widget-script', plugins_url( '../js/widget.min.js', __FILE__ ), array( 'jquery' ), BeRocket_AJAX_filters_version ); 
  35. wp_enqueue_script( 'berocket_aapf_widget-hack-script', plugins_url( '../js/mobiles.min.js', __FILE__ ), array( 'jquery' ), BeRocket_AJAX_filters_version ); 
  36.  
  37. $wp_query_product_cat = '-1'; 
  38. if ( @ $wp_query->query['product_cat'] ) { 
  39. $wp_query_product_cat = explode( "/", $wp_query->query['product_cat'] ); 
  40. $wp_query_product_cat = $wp_query_product_cat[ count( $wp_query_product_cat ) - 1 ]; 
  41.  
  42. if ( ! $br_options['products_holder_id'] ) $br_options['products_holder_id'] = 'ul.products'; 
  43.  
  44. $post_temrs = "[]"; 
  45. if ( @ $_POST['terms'] ) { 
  46. $post_temrs = @ json_encode( $_POST['terms'] ); 
  47.  
  48. if ( method_exists($sitepress, 'get_current_language') ) { 
  49. $current_language = $sitepress->get_current_language(); 
  50. } else { 
  51. $current_language = ''; 
  52.  
  53. $product_taxonomy = '-1'; 
  54. if ( is_product_taxonomy() ) { 
  55. $product_taxonomy = $wp_query->query_vars['taxonomy'].'|'.$wp_query->query_vars['term']; 
  56.  
  57. wp_localize_script( 
  58. 'berocket_aapf_widget-script',  
  59. 'the_ajax_script',  
  60. array( 
  61. 'version' => BeRocket_AJAX_filters_version,  
  62. 'current_language' => $current_language,  
  63. 'current_page_url' => preg_replace( "~paged?/[0-9]+/?~", "", home_url( $wp->request ) ),  
  64. 'ajaxurl' => admin_url( 'admin-ajax.php' ),  
  65. 'product_cat' => $wp_query_product_cat,  
  66. 'product_taxonomy' => $product_taxonomy,  
  67. 'products_holder_id' => @ $br_options['products_holder_id'],  
  68. 'control_sorting' => @ $br_options['control_sorting'],  
  69. 'seo_friendly_urls' => @ $br_options['seo_friendly_urls'],  
  70. 'berocket_aapf_widget_product_filters' => $post_temrs,  
  71. 'user_func' => apply_filters( 'berocket_aapf_user_func', @ $br_options['user_func'] ),  
  72. 'default_sorting' => get_option('woocommerce_default_catalog_orderby'),  
  73. 'first_page' => @ $br_options['first_page_jump'],  
  74. 'scroll_shop_top' => @ $br_options['scroll_shop_top'],  
  75. 'hide_sel_value' => @ $br_options['hide_value']['sel'],  
  76. 'ajax_request_load' => @ $br_options['ajax_request_load'],  
  77. 's' => @ $_GET['s'],  
  78. ); 
  79. unset( $current_language ); 
  80. unset( $post_temrs ); 
  81.  
  82. extract( $args ); 
  83. extract( $instance ); 
  84. unset( $args ); 
  85. unset( $instance ); 
  86.  
  87. if ( $widget_type == 'update_button' ) { 
  88. set_query_var( 'title', apply_filters( 'berocket_aapf_widget_title', $title ) ); 
  89. echo $before_widget; 
  90. br_get_template_part( 'widget_update_button' ); 
  91. echo $after_widget; 
  92. return ''; 
  93.  
  94. $product_cat = @ json_decode( $product_cat ); 
  95.  
  96. if ( $product_cat ) { 
  97. $hide_widget = true; 
  98.  
  99. $cur_cat = get_term_by( 'slug', $wp_query_product_cat, 'product_cat' ); 
  100. $cur_cat_ancestors = get_ancestors( $cur_cat->term_id, 'product_cat' ); 
  101. $cur_cat_ancestors[] = $cur_cat->term_id; 
  102.  
  103. if( $product_cat ) { 
  104. if ( $cat_propagation ) { 
  105. foreach ( $product_cat as $cat ) { 
  106. $cat = get_term_by( 'slug', $cat, 'product_cat' ); 
  107.  
  108. if ( @ in_array( $cat->term_id, $cur_cat_ancestors ) ) { 
  109. $hide_widget = false; 
  110. } else { 
  111. foreach ( $product_cat as $cat ) { 
  112. if ( $cat == $wp_query_product_cat ) { 
  113. $hide_widget = false; 
  114.  
  115. if ( $hide_widget ) { 
  116. return true; 
  117. unset( $product_cat ); 
  118.  
  119. $woocommerce_hide_out_of_stock_items = BeRocket_AAPF_Widget::woocommerce_hide_out_of_stock_items(); 
  120. $terms = $sort_terms = $price_range = array(); 
  121.  
  122. if ( $attribute == 'price' ) { 
  123. $price_range = BeRocket_AAPF_Widget::get_price_range( $wp_query_product_cat, $woocommerce_hide_out_of_stock_items ); 
  124. if ( ! $price_range or count( $price_range ) < 2 ) return false; 
  125. } else { 
  126. $sort_array = array(); 
  127. $wc_order_by = wc_attribute_orderby( $attribute ); 
  128.  
  129. if ( @ $br_options['show_all_values'] ) { 
  130. $terms = BeRocket_AAPF_Widget::get_attribute_values( $attribute ); 
  131. } else { 
  132. $terms = BeRocket_AAPF_Widget::get_attribute_values( $attribute, 'id', true ); 
  133.  
  134. if ( @ count( $terms ) < 1 ) return false; 
  135.  
  136. if ( $wc_order_by == 'menu_order' ) { 
  137. foreach ( $terms as $term ) { 
  138. $sort_array[] = get_woocommerce_term_meta( $term->term_id, 'order_' . $attribute ); 
  139. array_multisort( $sort_array, $terms ); 
  140. } elseif ( $wc_order_by == 'name' or $wc_order_by == 'name_num' ) { 
  141. foreach ( $terms as $term ) { 
  142. $sort_array[] = $term->name; 
  143. $sort_as = SORT_STRING; 
  144. if ( $wc_order_by == 'name_num' ) { 
  145. $sort_as = SORT_NUMERIC; 
  146. array_multisort( $sort_array, $terms, SORT_ASC, $sort_as ); 
  147.  
  148. set_query_var( 'terms', apply_filters( 'berocket_aapf_widget_terms', $terms ) ); 
  149.  
  150. $style = $class = ''; 
  151. if( @$height and $height != 'auto' ) { 
  152. $style = "style='height: {$height}px; overflow: hidden;'"; 
  153. $class = "berocket_aapf_widget_height_control"; 
  154.  
  155. if( !$scroll_theme ) $scroll_theme = 'dark'; 
  156.  
  157. set_query_var( 'operator', $operator ); 
  158. set_query_var( 'type', $type ); 
  159. set_query_var( 'title', apply_filters( 'berocket_aapf_widget_title', $title ) ); 
  160. set_query_var( 'class', apply_filters( 'berocket_aapf_widget_class', $class ) ); 
  161. set_query_var( 'css_class', apply_filters( 'berocket_aapf_widget_css_class', @ $css_class ) ); 
  162. set_query_var( 'style', apply_filters( 'berocket_aapf_widget_style', $style ) ); 
  163. set_query_var( 'scroll_theme', $scroll_theme ); 
  164. set_query_var( 'x', time() ); 
  165. set_query_var( 'hide_o_value', @ $br_options['hide_value']['o'] ); 
  166. set_query_var( 'hide_sel_value', @ $br_options['hide_value']['sel'] ); 
  167. set_query_var( 'before_title', @ $before_title ); 
  168. set_query_var( 'after_title', @ $after_title ); 
  169.  
  170. echo $before_widget; 
  171.  
  172. // widget title and start tag ( <ul> ) can be found in templates/widget_start.php 
  173. br_get_template_part('widget_start'); 
  174.  
  175. if( $type == 'slider' ) { 
  176. $min = $max = false; 
  177. $main_class = 'slider'; 
  178. $slider_class = 'berocket_filter_slider'; 
  179.  
  180. if( $attribute == 'price' ) { 
  181. wp_localize_script( 
  182. 'berocket_aapf_widget-script',  
  183. 'br_price_text',  
  184. array( 
  185. 'before' => @ $text_before_price,  
  186. 'after' => @ $text_after_price,  
  187. ); 
  188. if( $price_range ) { 
  189. foreach ( $price_range as $price ) { 
  190. if ( $min === false or $min > (int) $price ) { 
  191. $min = $price; 
  192. if ( $max === false or $max < (int) $price ) { 
  193. $max = $price; 
  194. $id = 'br_price'; 
  195. $slider_class .= ' berocket_filter_price_slider'; 
  196. $main_class .= ' price'; 
  197.  
  198. $min = number_format( floor( $min ), 2, '.', '' ); 
  199. $max = number_format( ceil( $max ), 2, '.', '' ); 
  200. } else { 
  201. if( @ $terms ) { 
  202. foreach ( $terms as $term ) { 
  203. if ( $min === false or $min > (int) $term->name ) { 
  204. $min = floor( (float) $term->name ); 
  205. if ( $max === false or $max < (int) $term->name ) { 
  206. $max = ceil( (float) $term->name ); 
  207. $id = $term->taxonomy; 
  208.  
  209. $slider_value1 = $min; 
  210. $slider_value2 = $max; 
  211.  
  212. if( $attribute == 'price' and @ $_POST['price'] ) { 
  213. $slider_value1 = apply_filters('woocommerce_price_filter_widget_min_amount', $_POST['price'][0]); 
  214. $slider_value2 = apply_filters('woocommerce_price_filter_widget_max_amount', $_POST['price'][1]); 
  215. if( $attribute != 'price' and @ $_POST['limits'] ) { 
  216. foreach( $_POST['limits'] as $p_limit ) { 
  217. if( $p_limit[0] == $attribute ) { 
  218. $slider_value1 = $p_limit[1]; 
  219. $slider_value2 = $p_limit[2]; 
  220.  
  221. set_query_var( 'slider_value1', $slider_value1 ); 
  222. set_query_var( 'slider_value2', $slider_value2 ); 
  223. set_query_var( 'filter_slider_id', $id ); 
  224. set_query_var( 'main_class', $main_class ); 
  225. set_query_var( 'slider_class', $slider_class ); 
  226. set_query_var( 'min', $min ); 
  227. set_query_var( 'max', $max ); 
  228. set_query_var( 'text_before_price', @ $text_before_price ); 
  229. set_query_var( 'text_after_price', @ $text_after_price ); 
  230. set_query_var( 'first_page_jump', @ $first_page_jump ); 
  231.  
  232. br_get_template_part( $type ); 
  233.  
  234. br_get_template_part('widget_end'); 
  235. echo $after_widget; 
  236.  
  237. public static function woocommerce_hide_out_of_stock_items() { 
  238. $hide = get_option( 'woocommerce_hide_out_of_stock_items', null ); 
  239.  
  240. if ( is_array( $hide ) ) { 
  241. $hide = array_map( 'stripslashes', $hide ); 
  242. } elseif ( ! is_null( $hide ) ) { 
  243. $hide = stripslashes( $hide ); 
  244.  
  245. return apply_filters( 'berocket_aapf_hide_out_of_stock_items', $hide ); 
  246.  
  247. public static function get_price_range( $wp_query_product_cat, $woocommerce_hide_out_of_stock_items ) { 
  248. global $wpdb, $wp_query; 
  249.  
  250. if( method_exists('WC_Query', 'get_main_tax_query') && method_exists('WC_Query', 'get_main_tax_query') &&  
  251. class_exists('WP_Meta_Query') && class_exists('WP_Tax_Query') ) { 
  252. $query_string = array( 
  253. 'select' => "SELECT MIN(cast(FLOOR(br_prices.meta_value) as decimal)) as min_price, MAX(cast(CEIL(br_prices.meta_value) as decimal)) as max_price 
  254. FROM {$wpdb->posts}",  
  255. 'join' => " INNER JOIN {$wpdb->postmeta} as br_prices ON ({$wpdb->posts}.ID = br_prices.post_id)",  
  256. 'where' => " WHERE {$wpdb->posts}.post_type = 'product' 
  257. AND {$wpdb->posts}.post_status = 'publish' 
  258. AND br_prices.meta_key = '_price' AND br_prices.meta_value > 0"); 
  259. $tax_query = array(); 
  260. $args = $wp_query->query_vars; 
  261. $meta_query = isset( $args['meta_query'] ) ? $args['meta_query'] : array(); 
  262. foreach ( $meta_query as $key => $query ) { 
  263. if ( ! empty( $query['price_filter'] ) || ! empty( $query['rating_filter'] ) ) { 
  264. unset( $meta_query[ $key ] ); 
  265. if ( ! empty( $args['product_cat'] ) ) { 
  266. $tax_query[ 'product_cat' ] = array( 
  267. 'taxonomy' => 'product_cat',  
  268. 'terms' => array( $args['product_cat'] ),  
  269. 'field' => 'slug',  
  270. ); 
  271. $queried_object = $wp_query->get_queried_object_id(); 
  272. if( ! empty($queried_object) ) { 
  273. $query_object = $wp_query->get_queried_object(); 
  274. if( ! empty($query_object->taxonomy) && ! empty($query_object->slug) ) { 
  275. $tax_query[ $query_object->taxonomy ] = array( 
  276. 'taxonomy' => $query_object->taxonomy,  
  277. 'terms' => array( $query_object->slug ),  
  278. 'field' => 'slug',  
  279. ); 
  280. $meta_query = new WP_Meta_Query( $meta_query ); 
  281. $tax_query = new WP_Tax_Query( $tax_query ); 
  282. $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); 
  283. $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); 
  284. $query_string['join'] = $query_string['join'].' '. $tax_query_sql['join'] . $meta_query_sql['join']; 
  285. $query_string['where'] = $query_string['where'].' '. $tax_query_sql['where'] . $meta_query_sql['where']; 
  286. $query_string = implode( ' ', $query_string ); 
  287. } else { 
  288. $_POST['product_cat'] = $wp_query_product_cat; 
  289. $extra_inner = $extra_where = ''; 
  290.  
  291. if ( @ $_POST['product_cat'] and $_POST['product_cat'] != '-1' ) { 
  292. $product_cat = get_term_by( 'slug', $_POST['product_cat'], 'product_cat' ); 
  293. $sub_categories = get_term_children($product_cat->term_id, 'product_cat'); 
  294. if( empty($sub_categories) || ! is_array($sub_categories) ) { 
  295. $sub_categories = array(); 
  296. $sub_categories[] = $product_cat->term_id; 
  297. $sub_categories = implode(', ', $sub_categories); 
  298.  
  299. $extra_inner = " INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id) "; 
  300. $extra_where = " AND ( {$wpdb->term_relationships}.term_taxonomy_id IN (" . $sub_categories . ") ) "; 
  301.  
  302. unset( $sub_categories ); 
  303. } elseif ( isset($wp_query->query_vars['product_tag']) ) { 
  304. $product_tag = get_term_by( 'slug', $wp_query->query_vars['product_tag'], 'product_tag' ); 
  305. $extra_inner = " INNER JOIN {$wpdb->term_relationships} ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id) "; 
  306. $extra_where = " AND ( {$wpdb->term_relationships}.term_taxonomy_id IN (" . $product_tag->term_id . ") ) "; 
  307. $hide_out_of_stock = BeRocket_AAPF_Widget::woocommerce_hide_out_of_stock_items(); 
  308. $out_of_stock1 = ''; 
  309. $out_of_stock2 = ''; 
  310. if ( $hide_out_of_stock == 'yes' ) { 
  311. $out_of_stock1 = "INNER JOIN {$wpdb->postmeta} AS pm2 ON ({$wpdb->posts}.ID = pm2.post_id)"; 
  312. $out_of_stock2 = "AND ( pm2.meta_key = '_stock_status' AND CAST(pm2.meta_value AS CHAR) = 'instock' )"; 
  313.  
  314.  
  315. $query_string = " 
  316. SELECT MIN(cast({$wpdb->postmeta}.meta_value as unsigned)) as min_price, MAX(cast({$wpdb->postmeta}.meta_value as unsigned)) as max_price 
  317. FROM {$wpdb->posts} 
  318. INNER JOIN {$wpdb->postmeta} ON ({$wpdb->posts}.ID = {$wpdb->postmeta}.post_id) 
  319. INNER JOIN {$wpdb->postmeta} AS pm1 ON ({$wpdb->posts}.ID = pm1.post_id) 
  320. {$out_of_stock1} 
  321. {$extra_inner} 
  322. WHERE {$wpdb->posts}.post_type = 'product' 
  323. AND {$wpdb->posts}.post_status = 'publish' 
  324. {$extra_where} 
  325. AND ( {$wpdb->postmeta}.meta_key = '_price' AND {$wpdb->postmeta}.meta_value > 0 
  326. AND ( pm1.meta_key = '_visibility' AND CAST(pm1.meta_value AS CHAR) IN ('visible', 'catalog') ) 
  327. {$out_of_stock2} ) "; 
  328.  
  329. $prices = $wpdb->get_row($query_string); 
  330. $price_range = false; 
  331. if( isset($prices->min_price) && isset($prices->max_price) && $prices->min_price != $prices->max_price ) { 
  332. $price_range = array( 
  333. apply_filters( 'woocommerce_price_filter_widget_min_amount', $prices->min_price ),  
  334. apply_filters( 'woocommerce_price_filter_widget_max_amount', $prices->max_price ) 
  335. ); 
  336. return apply_filters( 'berocket_aapf_get_price_range', $price_range ); 
  337.  
  338. public static function get_attribute_values( $taxonomy = '', $order_by = 'id', $hide_empty = false ) { 
  339. if ( ! $taxonomy ) return array(); 
  340. $re = array(); 
  341. if( $hide_empty ) { 
  342. global $wp_query, $post, $wp_the_query; 
  343. $old_wp_the_query = $wp_the_query; 
  344. $wp_the_query = $wp_query; 
  345. if( method_exists('WC_Query', 'get_main_tax_query') && method_exists('WC_Query', 'get_main_tax_query') &&  
  346. class_exists('WP_Meta_Query') && class_exists('WP_Tax_Query') ) { 
  347. $args = array( 
  348. 'orderby' => $order_by,  
  349. 'order' => 'ASC',  
  350. 'hide_empty' => false,  
  351. ); 
  352. $re = get_terms( $taxonomy, $args ); 
  353. global $wpdb; 
  354. $meta_query = WC_Query::get_main_meta_query(); 
  355. $args = $wp_the_query->query_vars; 
  356. $tax_query = array(); 
  357. if ( ! empty( $args['product_cat'] ) ) { 
  358. $tax_query[ 'product_cat' ] = array( 
  359. 'taxonomy' => 'product_cat',  
  360. 'terms' => array( $args['product_cat'] ),  
  361. 'field' => 'slug',  
  362. ); 
  363.  
  364. $meta_query = new WP_Meta_Query( $meta_query ); 
  365. $tax_query = new WP_Tax_Query( $tax_query ); 
  366. $meta_query_sql = $meta_query->get_sql( 'post', $wpdb->posts, 'ID' ); 
  367. $tax_query_sql = $tax_query->get_sql( $wpdb->posts, 'ID' ); 
  368. $term_ids = wp_list_pluck( $re, 'term_id' ); 
  369.  
  370. // Generate query 
  371. $query = array(); 
  372. $query['select'] = "SELECT COUNT( DISTINCT {$wpdb->posts}.ID ) as term_count, terms.term_id as term_count_id"; 
  373. $query['from'] = "FROM {$wpdb->posts}"; 
  374. $query['join'] = " 
  375. INNER JOIN {$wpdb->term_relationships} AS term_relationships ON {$wpdb->posts}.ID = term_relationships.object_id 
  376. INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id ) 
  377. INNER JOIN {$wpdb->terms} AS terms USING( term_id ) 
  378. " . $tax_query_sql['join'] . $meta_query_sql['join']; 
  379. $query['where'] = " 
  380. WHERE {$wpdb->posts}.post_type IN ( 'product' ) 
  381. AND {$wpdb->posts}.post_status = 'publish' 
  382. " . $tax_query_sql['where'] . $meta_query_sql['where'] . " 
  383. AND terms.term_id IN (" . implode( ', ', array_map( 'absint', $term_ids ) ) . ") 
  384. "; 
  385. $query['group_by'] = "GROUP BY terms.term_id"; 
  386. $query = apply_filters( 'woocommerce_get_filtered_term_product_counts_query', $query ); 
  387. $query = implode( ' ', $query ); 
  388. $results = $wpdb->get_results( $query ); 
  389. $results = wp_list_pluck( $results, 'term_count', 'term_count_id' ); 
  390. $term_count = array(); 
  391. $terms = array(); 
  392. foreach($re as &$res_count) { 
  393. if( ! empty($results[$res_count->term_id] ) ) { 
  394. $res_count->count = $results[$res_count->term_id]; 
  395. } else { 
  396. $res_count->count = 0; 
  397. if( $res_count->count > 0 ) { 
  398. $terms[] = $res_count; 
  399. $re = $terms; 
  400. } else { 
  401. $terms = array(); 
  402. $q_args = $wp_query->query_vars; 
  403. $q_args['posts_per_page'] = 2000; 
  404. $q_args['post__in'] = ''; 
  405. $q_args['tax_query'] = ''; 
  406. $q_args['taxonomy'] = ''; 
  407. $q_args['term'] = ''; 
  408. $q_args['meta_query'] = ''; 
  409. $q_args['attribute'] = ''; 
  410. $q_args['title'] = ''; 
  411. $q_args['post_type'] = 'product'; 
  412. $q_args['fields'] = 'ids'; 
  413. $paged = 1; 
  414. do{ 
  415. $q_args['paged'] = $paged; 
  416. $the_query = new WP_Query($q_args); 
  417. if ( $the_query->have_posts() ) { 
  418. foreach ( $the_query->posts as $post_id ) { 
  419. $curent_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'ids' ) ); 
  420. foreach ( $curent_terms as $t ) { 
  421. if ( ! in_array( $t, $terms ) ) { 
  422. $terms[] = $t; 
  423. $paged++; 
  424. } while($paged <= $the_query->max_num_pages); 
  425. unset( $q_args ); 
  426. unset( $the_query ); 
  427. wp_reset_query(); 
  428. $args = array( 
  429. 'orderby' => $order_by,  
  430. 'order' => 'ASC',  
  431. 'hide_empty' => false,  
  432. ); 
  433. $terms2 = get_terms( $taxonomy, $args ); 
  434. foreach ( $terms2 as $t ) { 
  435. if ( in_array( $t->term_id, $terms ) ) { 
  436. $re[] = $t; 
  437. $wp_the_query = $old_wp_the_query; 
  438. return $re; 
  439. } else { 
  440. $args = array( 
  441. 'orderby' => $order_by,  
  442. 'order' => 'ASC',  
  443. 'hide_empty' => false,  
  444. ); 
  445. return get_terms( $taxonomy, $args ); 
  446.  
  447. public static function get_filter_products( $wp_query_product_cat, $woocommerce_hide_out_of_stock_items, $use_filters = true ) { 
  448. global $wp_query, $wp_rewrite; 
  449. $_POST['product_cat'] = $wp_query_product_cat; 
  450.  
  451. add_filter( 'woocommerce_pagination_args', array( __CLASS__, 'pagination_args' ) ); 
  452.  
  453. $args = apply_filters( 'berocket_aapf_listener_wp_query_args', array() ); 
  454.  
  455. if ( $use_filters ) { 
  456. $args['post__in'] = BeRocket_AAPF::limits_filter( array() ); 
  457. $args['post__in'] = BeRocket_AAPF::price_filter( $args['post__in'] ); 
  458. } else { 
  459. $args = array( 'posts_per_page' => -1 ); 
  460. if ( @$_POST['product_cat'] and $_POST['product_cat'] != '-1' ) { 
  461. $args['tax_query'][] = array( 
  462. 'taxonomy' => 'product_cat',  
  463. 'field' => 'slug',  
  464. 'terms' => strip_tags( $_POST['product_cat'] ),  
  465. 'operator' => 'IN' 
  466. ); 
  467.  
  468. $args['post_status'] = 'publish'; 
  469. $args['post_type'] = 'product'; 
  470.  
  471. $wp_query = new WP_Query( $args ); 
  472.  
  473. // here we get max products to know if current page is not too big 
  474. if ( $wp_rewrite->using_permalinks() and preg_match( "~/page/([0-9]+)~", @ $_POST['location'], $mathces ) or preg_match( "~paged?=([0-9]+)~", @ $_POST['location'], $mathces ) ) { 
  475. $args['paged'] = min( $mathces[1], $wp_query->max_num_pages ); 
  476. $wp_query = new WP_Query( $args ); 
  477.  
  478. $products = array(); 
  479. if ( $wp_query->have_posts() ) { 
  480. while ( have_posts() ) { 
  481. the_post(); 
  482. $products[] = get_the_ID(); 
  483.  
  484. wp_reset_query(); 
  485.  
  486. return $products; 
  487.  
  488. /** 
  489. * Validating and updating widget data 
  490. * @param array $new_instance 
  491. * @param array $old_instance 
  492. * @return array - new merged instance 
  493. */ 
  494. function update( $new_instance, $old_instance ) { 
  495. $instance = $old_instance; 
  496.  
  497. /** Strip tags (if needed) and update the widget settings. */ 
  498. $instance['widget_type'] = strip_tags( $new_instance['widget_type'] ); 
  499. $instance['title'] = strip_tags( $new_instance['title'] ); 
  500. $instance['attribute'] = strip_tags( $new_instance['attribute'] ); 
  501. $instance['type'] = strip_tags( $new_instance['type'] ); 
  502. $instance['product_cat'] = ( $new_instance['product_cat'] ) ? json_encode( $new_instance['product_cat'] ) : ''; 
  503. $instance['scroll_theme'] = strip_tags( $new_instance['scroll_theme'] ); 
  504. $instance['cat_propagation'] = (int) $new_instance['cat_propagation']; 
  505. $instance['css_class'] = strip_tags( $new_instance['css_class'] ); 
  506. $instance['text_before_price'] = strip_tags( $new_instance['text_before_price'] ); 
  507. $instance['text_after_price'] = strip_tags( $new_instance['text_after_price'] ); 
  508.  
  509. if( $new_instance['height'] != 'auto' ) $new_instance['height'] = (float) $new_instance['height']; 
  510. if( !$new_instance['height'] ) $new_instance['height'] = 'auto'; 
  511. $instance['height'] = $new_instance['height']; 
  512.  
  513. if( $new_instance['operator'] != 'OR' ) $new_instance['operator'] = 'AND'; 
  514. $instance['operator'] = $new_instance['operator']; 
  515.  
  516. if( $instance['attribute'] == 'price' ) $instance['type'] = 'slider'; 
  517.  
  518. do_action( 'berocket_aapf_admin_update', $instance, $new_instance, $old_instance ); 
  519.  
  520. return apply_filters( 'berocket_aapf_admin_update_instance', $instance ); 
  521.  
  522. /** 
  523. * Output admin form 
  524. * @param array $instance 
  525. * @return string|void 
  526. */ 
  527. function form( $instance ) { 
  528. wp_enqueue_script( 'berocket_aapf_widget-admin-script', plugins_url('../js/admin.js', __FILE__), array('jquery'), BeRocket_AJAX_filters_version ); 
  529. wp_register_style( 'berocket_aapf_widget-style', plugins_url('../css/admin.css', __FILE__), array(), BeRocket_AJAX_filters_version ); 
  530. wp_enqueue_style( 'berocket_aapf_widget-style' ); 
  531.  
  532. /** Set up some default widget settings. */ 
  533. $defaults = array( 
  534. 'widget_type' => 'filter',  
  535. 'title' => '',  
  536. 'attribute' => 'price',  
  537. 'type' => 'slider',  
  538. 'operator' => '',  
  539. 'product_cat' => '',  
  540. 'text_before_price' => '',  
  541. 'text_after_price' => '',  
  542. 'height' => 'auto',  
  543. 'scroll_theme' => 'dark',  
  544. ); 
  545.  
  546. $defaults = apply_filters( 'berocket_aapf_form_defaults', $defaults ); 
  547.  
  548. $instance = wp_parse_args( (array) $instance, $defaults ); 
  549. $attributes = br_aapf_get_attributes(); 
  550. $categories = self::get_product_categories( @ json_decode( $instance['product_cat'] ) ); 
  551.  
  552. include AAPF_TEMPLATE_PATH . "admin.php"; 
  553.  
  554. /** 
  555. * Widget ajax listener 
  556. */ 
  557. public static function listener() { 
  558. global $wp_query, $wp_rewrite; 
  559. $br_options = apply_filters( 'berocket_aapf_listener_br_options', get_option('br_filters_options') ); 
  560.  
  561. add_filter( 'post_class', array( __CLASS__, 'add_product_class' ) ); 
  562. add_filter( 'woocommerce_pagination_args', array( __CLASS__, 'pagination_args' ) ); 
  563.  
  564. $args = apply_filters( 'berocket_aapf_listener_wp_query_args', array() ); 
  565.  
  566. if( ! isset($args['post__in']) ) { 
  567. $args['post__in'] = array(); 
  568. $woocommerce_hide_out_of_stock_items = BeRocket_AAPF_Widget::woocommerce_hide_out_of_stock_items(); 
  569. if( $woocommerce_hide_out_of_stock_items == 'yes' ) { 
  570. $args['post__in'] = BeRocket_AAPF::remove_out_of_stock( $args['post__in'] ); 
  571. if( ! br_woocommerce_version_check() ) { 
  572. $args['post__in'] = BeRocket_AAPF::remove_hidden( $args['post__in'] ); 
  573.  
  574. $args['post__in'] = BeRocket_AAPF::limits_filter( $args['post__in'] ); 
  575. if( isset($_POST['price']) && is_array($_POST['price']) ) { 
  576. $_POST['price'] = apply_filters('berocket_min_max_filter', $_POST['price']); 
  577. $args['post__in'] = BeRocket_AAPF::price_filter( $args['post__in'] ); 
  578. $args['post_status'] = 'publish'; 
  579. $args['post_type'] = 'product'; 
  580. $default_posts_per_page = get_option( 'posts_per_page' ); 
  581. $args['posts_per_page'] = apply_filters( 'loop_shop_per_page', $default_posts_per_page ); 
  582. unset( $default_posts_per_page ); 
  583.  
  584. if( isset($_POST['product_taxonomy']) && $_POST['product_taxonomy'] != '-1' && strpos( $_POST['product_taxonomy'], '|' ) !== FALSE ) { 
  585. $product_taxonomy = explode( '|', $_POST['product_taxonomy'] ); 
  586. $args['taxonomy'] = $product_taxonomy[0]; 
  587. $args['term'] = $product_taxonomy[1]; 
  588. if( isset($_POST['s']) && strlen($_POST['s']) > 0 ) { 
  589. $args['s'] = $_POST['s']; 
  590. $wp_query = new WP_Query( $args ); 
  591.  
  592. // here we get max products to know if current page is not too big 
  593. if ( $wp_rewrite->using_permalinks() and preg_match( "~/page/([0-9]+)~", $_POST['location'], $mathces ) or preg_match( "~paged?=([0-9]+)~", $_POST['location'], $mathces ) ) { 
  594. $args['paged'] = min( $mathces[1], $wp_query->max_num_pages ); 
  595. $wp_query = new WP_Query( $args ); 
  596. //echo '<pre>', print_r($wp_query, true), '</pre>'; 
  597. unset( $args ); 
  598.  
  599. if( @ ! $br_options['ajax_request_load'] ) { 
  600. ob_start(); 
  601.  
  602. if ( $wp_query->have_posts() ) { 
  603.  
  604. do_action('woocommerce_before_shop_loop'); 
  605.  
  606. woocommerce_product_loop_start(); 
  607. woocommerce_product_subcategories(); 
  608.  
  609. while ( have_posts() ) { 
  610. the_post(); 
  611. wc_get_template_part( 'content', 'product' ); 
  612.  
  613. woocommerce_product_loop_end(); 
  614.  
  615. do_action('woocommerce_after_shop_loop'); 
  616.  
  617. wp_reset_postdata(); 
  618.  
  619. $_RESPONSE['products'] = ob_get_contents(); 
  620. } else { 
  621. echo apply_filters( 'berocket_aapf_listener_no_products_message', "<div class='no-products" . ( ( $br_options['no_products_class'] ) ? ' '.$br_options['no_products_class'] : '' ) . "'>" . $br_options['no_products_message'] . "</div>" ); 
  622.  
  623. $_RESPONSE['no_products'] = ob_get_contents(); 
  624. ob_end_clean(); 
  625.  
  626. echo json_encode( $_RESPONSE ); 
  627.  
  628. die(); 
  629. public static function woocommerce_before_main_content() { 
  630. ?>||EXPLODE||<?php 
  631. public static function woocommerce_after_main_content() { 
  632. ?>||EXPLODE||<?php 
  633. public static function pre_get_posts() { 
  634. add_action('woocommerce_before_shop_loop', array( __CLASS__, 'woocommerce_before_main_content' ), 1); 
  635. add_action('woocommerce_after_shop_loop', array( __CLASS__, 'woocommerce_after_main_content' ), 999999); 
  636. public static function end_clean() { 
  637. $_RESPONSE['products'] = explode('||EXPLODE||', ob_get_contents()); 
  638. $_RESPONSE['products'] = $_RESPONSE['products'][1]; 
  639. ob_end_clean(); 
  640. global $wp_query, $wp_rewrite; 
  641.  
  642. if( $_RESPONSE['products'] == null ) { 
  643. unset( $_RESPONSE['products'] ); 
  644. ob_start(); 
  645. $br_options = apply_filters( 'berocket_aapf_listener_br_options', get_option('br_filters_options') ); 
  646. echo apply_filters( 'berocket_aapf_listener_no_products_message', "<p class='no-products woocommerce-info" . ( ( $br_options['no_products_class'] ) ? ' '.$br_options['no_products_class'] : '' ) . "'>" . $br_options['no_products_message'] . "</p>" ); 
  647. unset( $br_options ); 
  648. $_RESPONSE['no_products'] = ob_get_contents(); 
  649. ob_end_clean(); 
  650. } else { 
  651. $_RESPONSE['products'] = str_replace( 'explode=explode#038;', '', $_RESPONSE['products'] ); 
  652. $_RESPONSE['products'] = str_replace( '&explode=explode', '', $_RESPONSE['products'] ); 
  653. $_RESPONSE['products'] = str_replace( '?explode=explode', '', $_RESPONSE['products'] ); 
  654. echo json_encode( $_RESPONSE ); 
  655.  
  656. die(); 
  657. public static function start_clean() { 
  658. ob_start(); 
  659.  
  660. function get_product_categories( $current_product_cat = '', $parent = 0, $data = array(), $depth = 0 ) { 
  661. $args = array( 
  662. 'pad_counts' => 1,  
  663. 'show_counts' => 1,  
  664. 'hierarchical' => 0,  
  665. 'hide_empty' => 0,  
  666. 'show_uncategorized' => 0,  
  667. 'parent' => $parent,  
  668. 'selected' => $current_product_cat,  
  669. 'menu_order' => false 
  670. ); 
  671.  
  672. $product_cats = get_terms( 'product_cat', apply_filters( 'wc_product_dropdown_categories_get_terms_args', $args ) ); 
  673. unset( $args ); 
  674. if ( ! empty( $product_cats ) ) { 
  675. foreach ( $product_cats as $single_cat ) { 
  676. $single_cat->depth = $depth; 
  677. $data[] = $single_cat; 
  678. $data = self::get_product_categories( $current_product_cat, $single_cat->term_id, $data, $depth + 1 ); 
  679.  
  680. return $data; 
  681.  
  682. public static function add_product_class( $classes ) { 
  683. $classes[] = 'product'; 
  684. return apply_filters( 'berocket_aapf_add_product_class', $classes ); 
  685.  
  686. public static function pagination_args( $args = array() ) { 
  687. if ( defined('DOING_AJAX') && DOING_AJAX ) { 
  688. $args['base'] = str_replace( 999999999, '%#%', self::get_pagenum_link( 999999999 ) ); 
  689. return $args; 
  690.  
  691. // 99% copy of WordPress' get_pagenum_link. 
  692. public static function get_pagenum_link($pagenum = 1, $escape = true ) { 
  693. global $wp_rewrite; 
  694.  
  695. $pagenum = (int) $pagenum; 
  696.  
  697. $request = remove_query_arg( 'paged', preg_replace( "~".home_url()."~", "", @$_POST['location'] ) ); 
  698.  
  699. $home_root = parse_url(home_url()); 
  700. $home_root = ( isset($home_root['path']) ) ? $home_root['path'] : ''; 
  701. $home_root = preg_quote( $home_root, '|' ); 
  702.  
  703. $request = preg_replace('|^'. $home_root . '|i', '', $request); 
  704. unset( $home_root ); 
  705. $request = preg_replace('|^/+|', '', $request); 
  706.  
  707. if ( !$wp_rewrite->using_permalinks() ) { 
  708. $base = trailingslashit( get_bloginfo( 'url' ) ); 
  709.  
  710. if ( $pagenum > 1 ) { 
  711. $result = add_query_arg( 'paged', $pagenum, $base . $request ); 
  712. } else { 
  713. $result = $base . $request; 
  714. } else { 
  715. $qs_regex = '|\?.*?$|'; 
  716. preg_match( $qs_regex, $request, $qs_match ); 
  717.  
  718. if ( !empty( $qs_match[0] ) ) { 
  719. $query_string = $qs_match[0]; 
  720. $request = preg_replace( $qs_regex, '', $request ); 
  721. } else { 
  722. $query_string = ''; 
  723.  
  724. $request = preg_replace( "|$wp_rewrite->pagination_base/\d+/?$|", '', $request); 
  725. $request = preg_replace( '|^' . preg_quote( $wp_rewrite->index, '|' ) . '|i', '', $request); 
  726. $request = ltrim($request, '/'); 
  727.  
  728. $base = trailingslashit( get_bloginfo( 'url' ) ); 
  729.  
  730. if ( $wp_rewrite->using_index_permalinks() && ( $pagenum > 1 || '' != $request ) ) 
  731. $base .= $wp_rewrite->index . '/'; 
  732.  
  733. if ( $pagenum > 1 ) { 
  734. $request = ( ( !empty( $request ) ) ? trailingslashit( $request ) : $request ) . user_trailingslashit( $wp_rewrite->pagination_base . "/" . $pagenum, 'paged' ); 
  735.  
  736. $result = $base . $request . $query_string; 
  737.  
  738. /** 
  739. * Filter the page number link for the current request. 
  740. * @since 2.5.0 
  741. * @param string $result The page number link. 
  742. */ 
  743. $result = apply_filters( 'get_pagenum_link', $result ); 
  744.  
  745. if ( $escape ) 
  746. return esc_url( $result ); 
  747. else 
  748. return esc_url_raw( $result );