Guest User

Untitled

a guest
Jul 5th, 2024
15
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.72 KB | None | 0 0
  1. // Define the Custom Dimension Filter Widget
  2. class Custom_Dimension_Filter_Widget extends WP_Widget {
  3. public function __construct() {
  4. parent::__construct(
  5. 'custom_dimension_filter_widget',
  6. __('Custom Dimension Filter', 'xstore-core'),
  7. array('description' => __('Filter products by dimensions', 'xstore-core'))
  8. );
  9. }
  10.  
  11. public function widget($args, $instance) {
  12. $title = apply_filters('widget_title', $instance['title']);
  13.  
  14. if (is_shop() || is_product_category()) {
  15. $current_category = get_queried_object();
  16.  
  17. // Check if there are products with dimensions in the current category
  18. if ($this->category_has_dimensions($current_category->term_id)) {
  19. $base_link = remove_query_arg(array('filter_width', 'filter_length'));
  20.  
  21. echo $args['before_widget'];
  22. if (!empty($title)) {
  23. echo $args['before_title'] . $title . $args['after_title'];
  24. }
  25.  
  26. ?>
  27. <form id="custom-filters" method="get">
  28. <select name="filter_width" id="filter_width">
  29. <option value=""><?php _e('Selecteer breedte in cm', 'xstore-core'); ?></option>
  30. <?php $this->generate_dimension_options('filter_width', 'width', $current_category->term_id); ?>
  31. </select>
  32. <select name="filter_length" id="filter_length">
  33. <option value=""><?php _e('Selecteer lengte in cm', 'xstore-core'); ?></option>
  34. <?php $this->generate_dimension_options('filter_length', 'length', $current_category->term_id); ?>
  35. </select>
  36. </form>
  37. <?php
  38.  
  39. echo $args['after_widget'];
  40. }
  41. }
  42. }
  43.  
  44. public function form($instance) {
  45. $title = !empty($instance['title']) ? $instance['title'] : '';
  46. ?>
  47. <p>
  48. <label for="<?php echo $this->get_field_id('title'); ?>"><?php _e('Title:'); ?></label>
  49. <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>">
  50. </p>
  51. <?php
  52. }
  53.  
  54. public function update($new_instance, $old_instance) {
  55. $instance = array();
  56. $instance['title'] = sanitize_text_field($new_instance['title']);
  57. return $instance;
  58. }
  59.  
  60. private function category_has_dimensions($category_id) {
  61. global $wpdb;
  62. $meta_query = array('relation' => 'OR');
  63. $meta_keys = array('_width', '_length');
  64.  
  65. foreach ($meta_keys as $meta_key) {
  66. $meta_query[] = array(
  67. 'key' => $meta_key,
  68. 'value' => 0,
  69. 'compare' => '>',
  70. 'type' => 'NUMERIC'
  71. );
  72. }
  73.  
  74. $query = new WP_Query(array(
  75. 'post_type' => 'product',
  76. 'posts_per_page' => 1,
  77. 'meta_query' => $meta_query,
  78. 'tax_query' => array(
  79. array(
  80. 'taxonomy' => 'product_cat',
  81. 'field' => 'term_id',
  82. 'terms' => $category_id
  83. )
  84. )
  85. ));
  86.  
  87. return $query->have_posts();
  88. }
  89.  
  90. private function generate_dimension_options($filter_key, $dimension, $category_id) {
  91. $ranges = array('1-10', '11-20', '21-30', '31-40', '41-50'); // Adjusted ranges as per your requirement
  92. foreach ($ranges as $range) {
  93. list($min, $max) = explode('-', $range);
  94. $count = $this->count_products_in_range($dimension, $min, $max, $category_id);
  95. if ($count > 0) {
  96. $selected = isset($_GET[$filter_key]) && $_GET[$filter_key] == $range ? 'selected' : '';
  97. echo '<option value="' . esc_attr($range) . '" ' . $selected . '>' . esc_html($range) . ' (' . $count . ')</option>';
  98. }
  99. }
  100. }
  101.  
  102. private function count_products_in_range($dimension, $min, $max, $category_id) {
  103. global $wpdb;
  104. $meta_key = '_' . $dimension;
  105. $sql = $wpdb->prepare(
  106. "SELECT COUNT(p.ID)
  107. FROM {$wpdb->posts} p
  108. INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
  109. INNER JOIN {$wpdb->term_relationships} tr ON p.ID = tr.object_id
  110. INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
  111. WHERE pm.meta_key = %s
  112. AND pm.meta_value > %d
  113. AND pm.meta_value <= %d
  114. AND tt.taxonomy = 'product_cat'
  115. AND tt.term_id = %d
  116. AND p.post_type = 'product'
  117. AND p.post_status = 'publish'",
  118. $meta_key, floatval($min), floatval($max), $category_id
  119. );
  120. return $wpdb->get_var($sql);
  121. }
  122.  
  123. }
  124.  
  125. // Register the Custom Dimension Filter Widget
  126. function register_custom_dimension_filter_widget() {
  127. register_widget('Custom_Dimension_Filter_Widget');
  128. }
  129. add_action('widgets_init', 'register_custom_dimension_filter_widget');
  130.  
  131. // Add JavaScript to auto-submit the form on select change
  132. function custom_dimension_filter_scripts() {
  133. if (is_shop() || is_product_category()) {
  134. ?>
  135. <script type="text/javascript">
  136. document.addEventListener('DOMContentLoaded', function() {
  137. var filterWidth = document.getElementById('filter_width');
  138. var filterLength = document.getElementById('filter_length');
  139.  
  140. if (filterWidth) {
  141. filterWidth.addEventListener('change', function() {
  142. document.getElementById('custom-filters').submit();
  143. });
  144. }
  145.  
  146. if (filterLength) {
  147. filterLength.addEventListener('change', function() {
  148. document.getElementById('custom-filters').submit();
  149. });
  150. }
  151. });
  152. </script>
  153. <?php
  154. }
  155. }
  156. add_action('wp_footer', 'custom_dimension_filter_scripts');
  157.  
  158. // Add custom filter query logic
  159. function custom_filter_query($query) {
  160. if (!is_admin() && $query->is_main_query() && (is_shop() || is_product_category())) {
  161. $meta_query = array('relation' => 'AND');
  162. $filtering = false;
  163.  
  164. if (isset($_GET['filter_width']) && !empty($_GET['filter_width'])) {
  165. $width_range = explode('-', sanitize_text_field($_GET['filter_width']));
  166. if (count($width_range) == 2) {
  167. $meta_query[] = array(
  168. 'key' => '_width',
  169. 'value' => array(floatval($width_range[0]), floatval($width_range[1])),
  170. 'compare' => 'BETWEEN',
  171. 'type' => 'DECIMAL(10,2)',
  172. );
  173. $filtering = true;
  174. }
  175. }
  176.  
  177. if (isset($_GET['filter_length']) && !empty($_GET['filter_length'])) {
  178. $length_range = explode('-', sanitize_text_field($_GET['filter_length']));
  179. if (count($length_range) == 2) {
  180. $meta_query[] = array(
  181. 'key' => '_length',
  182. 'value' => array(floatval($length_range[0]), floatval($length_range[1])),
  183. 'compare' => 'BETWEEN',
  184. 'type' => 'DECIMAL(10,2)',
  185. );
  186. $filtering = true;
  187. }
  188. }
  189.  
  190. // Only set the meta query if a filter is being applied
  191. if ($filtering) {
  192. $query->set('meta_query', $meta_query);
  193. }
  194. }
  195. }
  196. add_action('pre_get_posts', 'custom_filter_query');
Advertisement
Add Comment
Please, Sign In to add comment