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