PluginProbe
Filter Everything — WordPress & WooCommerce Filters / 1.9.7
Filter Everything — WordPress & WooCommerce Filters v1.9.7
1.9.7 1.9.6 1.9.5 1.9.4 1.9.3 1.9.2.2 1.9.2.1 trunk 1.2.1 1.2.3 1.2.4 1.2.5 1.3.0 1.3.1 1.3.2 1.4.1 1.4.4 1.4.5 1.4.8 1.4.9 1.5.0 1.5.1 1.6.0 1.6.1 1.6.2 All 52 releases
filter-everything / src / helpers / instant-recount.php

instant-recount.php in Filter Everything — WordPress & WooCommerce Filters 1.9.7, at src/helpers/instant-recount.php

264 lines 8.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if (!defined('ABSPATH')) {
4 exit;
5 }
6
7 use \FilterEverything\Filter\Container;
8 use \FilterEverything\Filter\FilterSet;
9 use \FilterEverything\Filter\FilterFields;
10 use \FilterEverything\Filter\PostMetaNumEntity;
11 use \FilterEverything\Filter\PostDateEntity;
12 use \FilterEverything\Filter\PostMetaDateEntity;
13
14 /**
15 * Apply-button / instant-recount helpers: "query on the page" set detection and
16 * the data passed to the frontend recount engine.
17 *
18 * Split out of src/wpc-helpers.php on 2026-09-14; function names and bodies are
19 * unchanged. Loaded from filter-everything.php right after wpc-helpers.php.
20 */
21
22 /**
23 * Combines all filter sets for the same WP_Query
24 *
25 * @param array $all_sets - list of all page related sets
26 * @param $current_set
27 * @return array $queryRelatedSets IDs of all query related sets
28 */
29 function flrt_get_sets_with_the_same_query($all_sets, $current_set)
30 {
31 $queryRelatedSets = [];
32 // First detect desired query index;
33 $query = '';
34 $post_type = '';
35 $location = '';
36 $set_id = $current_set['ID'];
37
38 foreach ($all_sets as $set) {
39 if ($set['ID'] === $set_id) {
40 // Current Set values
41 $query = $set['query'];
42 $post_type = $set['filtered_post_type'];
43 $location = $set['query_location'];
44 break;
45 }
46 }
47
48 // Then find all sets with such query
49 foreach ($all_sets as $set) {
50 if ($set['query'] === $query && $post_type === $set['filtered_post_type'] && $location === $set['query_location']) {
51 $queryRelatedSets[] = $set['ID'];
52 }
53 }
54
55 if (empty($queryRelatedSets)) {
56 $queryRelatedSets[] = $set_id;
57 }
58
59 return $queryRelatedSets;
60 }
61
62 function flrt_is_query_on_page($setPosts, $searchKey)
63 {
64 $filterSet = Container::instance()->getFilterSetService();
65 $sets = [];
66 if (!is_array($setPosts)) {
67 return $sets;
68 }
69
70 foreach ($setPosts as $set) {
71
72 $parameters = maybe_unserialize($set->post_content);
73 $query = isset($parameters['wp_filter_query']) ? $parameters['wp_filter_query'] : '-1';
74 if ($filterSet->under_limit_filter_set($set->ID)) {
75 continue;
76 }
77
78 if (isset($parameters['use_apply_button']) && $parameters['use_apply_button'] === 'yes') {
79
80 $query_on_the_page = false;
81 $show_on_the_page = false;
82
83 if (defined('FLRT_FILTERS_PRO') && FLRT_FILTERS_PRO) {
84 if (isset($parameters['apply_button_post_name'])) {
85
86 if ($parameters['apply_button_post_name'] === $set->post_name ||
87 $parameters['apply_button_post_name'] === 'no_page___no_page') {
88 $query_on_the_page = true;
89 }
90
91 if (in_array($parameters['apply_button_post_name'], $searchKey) || ($parameters['apply_button_post_name'] === 'no_page___no_page')) {
92 $show_on_the_page = true;
93 }
94 }
95
96 } else {
97 $query_on_the_page = true;
98 $show_on_the_page = true;
99 }
100
101 $sets[] = array(
102 'ID' => (string)$set->ID,
103 'filtered_post_type' => $set->post_excerpt,
104 'query' => $query, // query hash
105 'query_location' => $set->post_name,
106 'query_on_the_page' => $query_on_the_page,
107 'page_search_keys' => $searchKey,
108 'show_on_the_page' => $show_on_the_page
109 );
110
111 } else {
112 if (in_array($set->post_name, $searchKey)) {
113 $sets[] = array(
114 'ID' => (string)$set->ID,
115 'filtered_post_type' => $set->post_excerpt,
116 'query' => $query, // query hash
117 'query_location' => $set->post_name,
118 'query_on_the_page' => true,
119 'page_search_keys' => $searchKey,
120 'show_on_the_page' => true
121 );
122 } else {
123 // This set is for another page and was selected by Apply button location but the button disabled
124 continue;
125 }
126 }
127
128 }
129
130 return $sets;
131 }
132
133 function flrt_rating_slugs()
134 {
135 return array(
136 'rated-1' => 1,
137 'rated-2' => 2,
138 'rated-3' => 3,
139 'rated-4' => 4,
140 'rated-5' => 5
141 );
142 }
143
144 /**
145 * Whether Apply button Sets recalculate counters instantly in the browser
146 * (the 1.9.3 client-side recount) instead of the legacy per-click AJAX
147 * request. Disabled by default, so existing Apply button users keep the
148 * pre-1.9.3 behaviour after the update until they opt in.
149 *
150 * The option is PRO-only: in the free version the preserved DB value stays
151 * inert and Apply button Sets always use the legacy AJAX recount. The whole
152 * client-side engine works in free too — this gate is the only thing to
153 * relax if instant recount ever ships in the free version.
154 */
155 function flrt_instant_recount()
156 {
157 return defined('FLRT_FILTERS_PRO') && flrt_get_option('apply_button_instant_recount') === 'on';
158 }
159
160 function flrt_check_apply_buttom_mode($set)
161 {
162 return ((isset($set['use_apply_button']['value']) && $set['use_apply_button']['value'] === 'yes') && flrt_instant_recount());
163 }
164
165
166 function flrt_parent_filter_apply_button_data($filter, $args = [])
167 {
168 $data = '';
169 if($args['use_apply_button'] && (int) $filter['parent_filter'] > 0){
170 $hide_until_parent = 0;
171 if($filter['hide_until_parent'] === 'yes'){
172 $hide_until_parent = 1;
173 }
174 $data .= ' data-parent-filter-id="' . esc_attr($filter['parent_filter']) . '" data-hide-until-parent="' . esc_attr($hide_until_parent) .'"';
175 }
176 return $data;
177 }
178
179 function flrt_parent_filter_apply_class($filter, $args = [], $terms = [])
180 {
181 $css_class = '';
182 // '-1', the legacy 'no' placeholder and anything non-numeric all mean "no parent"
183 if( (int) $filter['parent_filter'] <= 0 ){
184 return $css_class;
185 }
186
187 $checked = false;
188
189 $css_class = ' ' . esc_attr('wpc-has-parent-filter');
190
191 $is_parent_has_terms = false;
192 if(!empty($terms)){
193 foreach ($terms as $term){
194 if(isset($term->show_with_parent)){
195 $is_parent_has_terms = true;
196 }
197 if( in_array( $term->slug, $filter['values'] ) ){
198 $checked = true;
199 }
200 if($is_parent_has_terms && $checked){
201 break;
202 }
203 }
204 }
205
206
207 if($args['use_apply_button'] && $is_parent_has_terms === false){
208 $css_class .= ' ' . esc_attr('wpc-parent-filter-terms-unselected');
209 }
210
211 if($args['use_apply_button'] && $is_parent_has_terms === false && $checked){
212 $css_class .= ' ' . esc_attr('wpc-child-selected-no-parent');
213 }
214
215 if($args['use_apply_button'] && $is_parent_has_terms === true){
216 $css_class .= ' ' . esc_attr('wpc-parent-filter-terms-selected');
217 }
218
219 if(empty($filter['hide_until_parent']) || $filter['hide_until_parent'] !== 'yes'){
220 return $css_class;
221 }
222
223 if($args['use_apply_button'] && !empty($filter['hide_until_parent']) && $filter['hide_until_parent'] === 'yes' && $is_parent_has_terms === false){
224 $css_class .= ' ' . esc_attr('wpc-hide-terms-until-parent-unselected');
225 }
226
227 return $css_class;
228 }
229
230 function flrtIsMoreLess($filter)
231 {
232 return (!empty($filter['more_less']) && $filter['more_less'] === 'yes') ? true : false;
233 }
234
235 function flrtParentFilter($filter)
236 {
237 // Positive filter ID only. '-1' means no parent, and single-filter sets used
238 // to save the 'no' select placeholder — on PHP 8 the string comparison
239 // 'no' > 0 is true, so a plain numeric check would treat it as a parent
240 return !empty($filter['parent_filter']) && (int) $filter['parent_filter'] > 0;
241 }
242
243 function flrt_get_filtered_term_url( $term, $filter, $url_manager ) {
244 $exclude_from_url = [];
245
246 if ( ! empty( $filter['has_child_filter'] ) ) {
247 if ( $filter['has_child_filter'] === true && count( $filter['values'] ) === 1 ) {
248 if ( $term->slug === $filter['values'][0] ) {
249 foreach ( $filter['child_values'] as $child_value ) {
250 $exclude_from_url[ $child_value ] = true;
251 }
252 }
253 }
254 }
255
256 return $url_manager->getTermUrl(
257 $term->slug,
258 $filter['e_name'],
259 $filter['entity'],
260 '',
261 $exclude_from_url
262 );
263 }
264