PluginProbe
Filter Everything — WordPress & WooCommerce Filters / trunk
Filter Everything — WordPress & WooCommerce Filters vtrunk
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 1.6.3 All 51 releases
filter-everything / src / PluginHelpers.php

PluginHelpers.php in Filter Everything — WordPress & WooCommerce Filters trunk, at src/PluginHelpers.php

805 lines 30.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FilterEverything\Filter;
4 trait PluginHelpers
5 {
6 public function sendSetLocationTerms()
7 {
8 $postData = Container::instance()->getThePost();
9 $filterSet = Container::instance()->getFilterSetService();
10
11 $full_label = true;
12 $post_type = isset( $postData['postType'] ) ? $postData['postType'] : 'post';
13 $wpPageType = isset( $postData['wpPageType'] ) ? $postData['wpPageType'] : false;
14 $post_id = isset( $postData['postId'] ) ? $postData['postId'] : '';
15 $nonce = isset( $postData['_wpnonce'] ) ? $postData['_wpnonce'] : false;
16 $fieldkey = isset( $postData['fieldKey'] ) ? $postData['fieldKey'] : 'post_name';
17
18 $errorResponse = array(
19 'postId' => $post_id,
20 'message' => esc_html__('An error occurred. Please, refresh the page and try again.', 'filter-everything')
21 );
22
23 if( ! wp_verify_nonce( $nonce, FilterSet::NONCE_ACTION ) ){
24 wp_send_json_error($errorResponse);
25 }
26
27 $set = $filterSet->getSet( $post_id );
28
29 // Get prepared field with populated saved values
30 if( ! empty( $set ) && $set['post_type']['value'] == $post_type ){
31 $location = $set[$fieldkey];
32 }else{
33 // Or create new one, if it is new set
34 $fields = $filterSet->getFieldsMapping();
35 $location = $fields[$fieldkey];
36 }
37
38 if( $fieldkey === 'apply_button_post_name' ){
39 $full_label = false;
40 }
41
42 $location['options'] = flrt_get_set_location_terms( $wpPageType, $post_type, $full_label );
43
44 $response = [];
45
46 ob_start();
47
48 echo flrt_render_input($location);
49
50 $response['isLimitFilterSet'] = $filterSet->under_limit_filter_set($post_id, $post_type);
51 $response['html'] = ob_get_clean();
52
53 wp_send_json_success($response);
54 die();
55 }
56
57 public function showLocationFields( &$set_settings_fields )
58 {
59 $location_fields = flrt_extract_vars( $set_settings_fields, array('wp_page_type', 'post_name') );
60 ?>
61 <tr class="wpc-filter-tr <?php echo esc_attr( $location_fields['wp_page_type']['class'] ); ?>-tr"<?php flrt_maybe_hide_row( $location_fields['wp_page_type'] ); ?>><?php
62
63 flrt_include_admin_view('filter-field-label', array(
64 'field_key' => 'wp_page_type',
65 'attributes' => $location_fields['wp_page_type']
66 )
67 );
68 ?>
69 <td class="wpc-filter-field-td wpc-filter-field-location-td">
70 <div class="wpc-field-wrap <?php echo esc_attr( $location_fields['wp_page_type']['id'] ); ?>-wrap">
71 <?php echo flrt_render_input( $location_fields['wp_page_type'] ); // Already escaped in function ?>
72 </div>
73 <div class="wpc-field-wrap <?php echo esc_attr( $location_fields['post_name']['id'] ); ?>-wrap">
74 <?php echo flrt_render_input( $location_fields['post_name'] ); // Already escaped in function ?>
75 </div>
76 </td>
77 </tr>
78 <?php
79 }
80 public function isFilteredQuery( $result, $query_to_check )
81 {
82 $wpManager = Container::instance()->getWpManager();
83 $sets = $wpManager->getQueryVar('wpc_page_related_set_ids');
84
85 if( empty( $sets ) ){
86 return false;
87 }
88
89 $filterSet = Container::instance()->getFilterSetService();
90 remove_filter('wpc_prepare_filter_set_parameters', [$this, 'prepareSetParameters'], 10, 2);
91
92 foreach ( $sets as $set ){
93
94 $theSet = $filterSet->getSet( $set['ID'] );
95
96 if( isset( $theSet['wp_filter_query']['value'] ) && $theSet['wp_filter_query']['value'] ){
97 $savedValue = $theSet['wp_filter_query']['value'];
98 // We have to avoid recognize similar queries that have the same hash
99 if(!empty($query_to_check->get('flrt_query_hash')) && $savedValue === $query_to_check->get('flrt_query_hash') /*&& isset($set['query_on_the_page']) &&
100 $set['query_on_the_page'] === true*/
101 ){
102 $result[] = $set['ID'];
103 }
104 }
105 }
106
107 if( empty( $result ) ){
108 // Let's do it again.
109 foreach ( $sets as $set ) {
110
111 $theSet = $filterSet->getSet($set['ID']);
112
113 if( isset( $theSet['wp_filter_query']['value'] ) && $theSet['wp_filter_query']['value'] ) {
114 $savedValue = $theSet['wp_filter_query']['value'];
115
116 // For backward compatibility, when savedValue isn't specified and is default -1
117 if ($query_to_check->is_main_query() && $savedValue === '-1') {
118 $result[] = $set['ID'];
119
120 break;
121 }
122
123 // For All Post type archive pages
124 if (isset($theSet['post_name']['value']) && $theSet['post_name']['value'] === '1' && $query_to_check->is_main_query()) {
125 /* if( isset( $theSet['use_apply_button']['value'] ) && $theSet['use_apply_button']['value'] === 'yes' ){
126 continue;
127 }else{
128 $result[] = $set['ID'];
129 break;
130 }*/
131 $result[] = $set['ID'];
132 break;
133 }
134 }
135 }
136 }
137
138 add_filter('wpc_prepare_filter_set_parameters', [$this, 'prepareSetParameters'], 10, 2);
139
140 unset($filterSet, $wpManager);
141
142 return $result;
143 }
144
145 public function burpOutAllWpQueries( $wp_query )
146 {
147 $postData = Container::instance()->getThePost();
148 if( isset( $postData['action'] ) && $postData['action'] === 'wpc_get_wp_queries' ){
149
150 $do_security_check = true;
151
152 if( flrt_wpml_active() ){
153 $wpml_settings = get_option( 'icl_sitepress_settings' );
154 if ( isset( $wpml_settings['language_negotiation_type'] ) && $wpml_settings['language_negotiation_type'] === '2' ) {
155 $do_security_check = false;
156 }
157 }
158
159 if ( $do_security_check ) {
160 if( ! isset( $postData['_wpnonce'] ) || ! wp_verify_nonce( $postData['_wpnonce'], FilterSet::NONCE_ACTION ) ){
161 return $wp_query;
162 }
163
164 if( ! current_user_can( flrt_plugin_user_caps() ) ) {
165 return $wp_query;
166 }
167 }
168
169 add_action( 'wp_footer', [$this, 'showCollectedWpQueries'] );
170 }
171
172 return $wp_query;
173 }
174
175 /**
176 * Checks if provided WP_Query is filtered query
177 * @param $result
178 * @param $query_to_check
179 * @return array with filter set IDs related to the Query
180 */
181
182
183 public function showCollectedWpQueries()
184 {
185 global $flrt_queries;
186 $filterSet = Container::instance()->getFilterSetService();
187 $postData = Container::instance()->getThePost();
188 $postType = isset($postData['postType']) ? $postData['postType'] : false;
189 $postId = isset($postData['postId']) ? $postData['postId'] : false;
190 $flatten_queries = $this->flatAllWpQueriesList($flrt_queries, $postType);
191 $fieldName = 'wp_filter_query';
192 // For Any case if the 'flrt_render_input()' return false;
193 $postTypeObject = get_post_type_object($postType);
194 $postNameLabel = isset($postTypeObject->labels->name) ? $postTypeObject->labels->name : $postType;
195
196 $theSet = $filterSet->getSet($postId);
197 // Set includes field configuration arrays together with saved values
198 $select_atts = isset($theSet[$fieldName]) ? $theSet[$fieldName] : false;
199 if ($select_atts) {
200 $select_atts['options'] = $flatten_queries['options'];
201 }
202
203 // Remove all additional HTML from the 'wp_filter_query' Select field
204 remove_all_filters('wpc_input_type_select');
205 if (!empty($flatten_queries['disabled'])) {
206 $select_atts['disabled'] = [];
207 foreach ($flatten_queries['disabled'] as $hash => $val) {
208 $select_atts['disabled'][] = $hash;
209 }
210 }
211 if (!empty($select_atts['disabled'])) {
212 if (count($select_atts['options']) === count($select_atts['disabled'])) {
213 $select_atts['options']['-1'] = sprintf(esc_html__('No %s enabled lists found on the page', 'filter-everything'), $postTypeObject->labels->name);
214 $select_atts['selected'] = '-1';
215 }
216 }
217
218 $selectField = flrt_render_input($select_atts);
219
220 if( ! $selectField ) {
221
222 $selectField = '<div><select class="wpc-field-wp-filter-query" id="wpc_set_fields-wp_filter_query" name="wpc_set_fields[wp_filter_query]">'."\n";
223 $selectField .= '<option value="-1" >'.sprintf( esc_html__('No list of %s found on this page', 'filter-everything' ), flrt_lcfirst($postNameLabel) ).'</option>'."\n";
224 $selectField .= '</select></div>'."\n";
225 }
226
227 echo '<div>'.$selectField.'</div>';
228
229 echo '<div><div id="wpc_query_vars">';
230 if( isset( $flatten_queries['query_vars'] ) && ! empty( $flatten_queries['query_vars'] ) ){
231 foreach ( $flatten_queries['query_vars'] as $hash => $vars ){
232 $hiddenFieldName = esc_attr( $filterSet::FIELD_NAME_PREFIX . '[wp_filter_query_vars]['.$hash.']' );
233 echo '<input type="hidden" name="'.$hiddenFieldName.'" value="'.esc_attr( $vars ).'"/>'."\n";
234 }
235 }
236 echo '</div></div>';
237
238 }
239
240 /**
241 * Converts queries array from multidimensional to simple
242 * Optionally removes queries with unnecessary post type
243 * @param array $queries
244 * @param false|string $postType
245 */
246 public function flatAllWpQueriesList( $queries, $postType = false )
247 {
248 $flatten = [];
249
250 $postTypeObject = get_post_type_object( $postType );
251 $postNameLabel = isset( $postTypeObject->labels->name) ? $postTypeObject->labels->name : $postType;
252
253 if( empty( $queries ) ){
254 $flatten['options']['-1'] = sprintf( esc_html__('No list of %s found on this page', 'filter-everything' ), flrt_lcfirst($postNameLabel) );
255 return $flatten;
256 }
257
258 foreach ( $queries as $hash => $single_query ){
259 foreach ($single_query as $index => $values ) {
260 if( $postType ){
261 if( ! in_array( $postType, $values['post_types'], true ) ){
262 continue;
263 }
264 }
265
266 // We should use another label numeration logic
267 $new_hash = md5( $hash . $index );
268 $flatten['options'][ $new_hash ] = $values['label'];
269 if( ! empty( $values['disabled'] ) && $values['disabled'] === true ){
270 $flatten['disabled'][ $new_hash ] = $values['disabled'];
271 }
272 $flatten['query_vars'][ $new_hash ] = $values['query_vars'];
273 }
274 }
275
276 // Add numeration for equal labels
277 if( ! empty( $flatten['options'] ) ){
278 $copy_flatten = $flatten['options'];
279 $count_labels = array_count_values($copy_flatten);
280 $i = [];
281
282 foreach ( $copy_flatten as $hash => $label ){
283 if( $count_labels[$label] > 1 ){
284 if( ! isset( $i[$label] ) ){
285 $i[$label] = 0;
286 }
287 $i[$label]++;
288 if(str_contains( $label, '»' ) ){
289 $changed_label = str_replace("»", " #%s»", $label);
290 $new_label = sprintf( $changed_label, $i[$label] );
291 }
292
293 $flatten['options'][ $hash ] = $new_label;
294 }
295 }
296 }else{
297 $flatten['options']['-1'] = sprintf( esc_html__('No list of %s found on this page', 'filter-everything' ), flrt_lcfirst($postNameLabel) );
298 return $flatten;
299 }
300
301 return $flatten;
302 }
303
304 public function validationLocationEntities( $possibleEntities, $setFields )
305 {
306 $possibleEntities = flrt_get_set_location_terms( $setFields['wp_page_type'], $setFields['post_type'] );
307 return array_keys( $possibleEntities );
308 }
309
310 public function validationWpPageTypeEntities( $possibleWpPageTypes )
311 {
312 $possibleWpPageTypes = $this->flattenValues( flrt_get_set_location_groups() );
313 return array_keys( $possibleWpPageTypes );
314 }
315
316 public function prepareSetParameters( $defaults, $set_post )
317 {
318 // Set location dropdown fields related to saved post_type and wp_page_type
319 $postType = $set_post->post_excerpt ? $set_post->post_excerpt : 'post';
320 $unserialized = maybe_unserialize( $set_post->post_content );
321
322 // For backward compatibility. From v.1.1.24
323 if( isset( $unserialized['wp_page_type'] ) ){
324 $unserialized['wp_page_type'] = str_replace(":", "___", $unserialized['wp_page_type']);
325 }
326
327 $wpPageType = isset( $unserialized['wp_page_type'] ) ? $unserialized['wp_page_type'] : $this->detectWpPageTypeByLocation( $set_post->post_name );
328 $applyButtonPageType = isset( $unserialized['apply_button_page_type'] ) ? $unserialized['apply_button_page_type'] : 'no_page___no_page';
329
330 // Location preview URLs (option 'data-link') are language-sensitive under Polylang:
331 // flrt_get_common_location_terms() resolves the language from the global $post_id.
332 // On the edit screen post.php sets that global, but the Filter Set list table does
333 // not — so previews there lost their language prefix (e.g. /shop/ instead of
334 // /en/shop/). Anchor the global to this set's own post while the options are built
335 // so both screens agree. An AJAX $_POST['postId'] still takes priority inside
336 // flrt_get_common_location_terms().
337 $flrt_had_global_post_id = array_key_exists( 'post_id', $GLOBALS );
338 $flrt_prev_global_post_id = $flrt_had_global_post_id ? $GLOBALS['post_id'] : null;
339 if ( is_object( $set_post ) && ! empty( $set_post->ID ) ) {
340 $GLOBALS['post_id'] = $set_post->ID;
341 }
342
343 $defaults['post_name']['options'] = flrt_get_set_location_terms( $wpPageType, $postType );
344
345 // The field is defined in PRO only — don't create a value-less stub of it in the free version
346 if ( isset( $defaults['apply_button_post_name'] ) ) {
347 $defaults['apply_button_post_name']['options'] = flrt_get_set_location_terms( $applyButtonPageType, $postType, false );
348 }
349
350 if ( $flrt_had_global_post_id ) {
351 $GLOBALS['post_id'] = $flrt_prev_global_post_id;
352 } else {
353 unset( $GLOBALS['post_id'] );
354 }
355
356 return $defaults;
357 }
358
359 public function detectWpPageTypeByLocation( $locationValue )
360 {
361 $wpPostType = 'common___common';
362
363
364 if( $locationValue == '1' ){
365 $wpPostType = 'common___common';
366 }else if( mb_strpos( $locationValue, 'author' ) !== false ){
367 $wpPostType = 'author___author';
368
369 }else if( mb_strpos( $locationValue, 'post_type' ) !== false ){
370 $postTypeParts = explode("___", $locationValue);
371 $postTypeName = $postTypeParts[0];
372 $wpPostType = 'post_type___'.$postTypeName;
373 }else if( $locationValue ){
374 $taxonomyParts = explode("___", $locationValue);
375 $taxName = $taxonomyParts[0];
376 $wpPostType = 'taxonomy___'.$taxName;
377 }
378 ;
379 return $wpPostType;
380 }
381
382 public function flattenValues( $entities )
383 {
384 if( empty( $entities ) ){
385 return $entities;
386 }
387 $flat_entities = [];
388
389 array_walk_recursive( $entities, function ( $value, $key ) use ( &$flat_entities ) {
390 if( $key !== 'group_label' /*&& isset( $value['label'] ) && $value['label'] */){
391 $flat_entities[ $key ] = $value;
392 }
393 }, $flat_entities );
394
395 return $flat_entities;
396 }
397
398 public function legacyPrepareWpPageTypeValue( $prepared )
399 {
400 if( isset($prepared['post_name']['value']) && $prepared['post_name']['value'] ){
401 if( ! isset( $prepared['wp_page_type']['value'] ) ){
402 $prepared['wp_page_type']['value'] = $this->detectWpPageTypeByLocation( $prepared['post_name']['value']);
403 }
404 }
405 return $prepared;
406 }
407
408 public function filterSetPostTypeCol( $columns )
409 {
410 $newColumns = [];
411
412 foreach ( $columns as $columnId => $columnName ) {
413
414 $newColumns[$columnId] = $columnName;
415 if( $columnId === 'title' ){
416 $newColumns['location'] = esc_html__( 'Available on', 'filter-everything' );
417 }
418 }
419
420 return $newColumns;
421 }
422
423 // Show selected location in the Available on column of admin Filter Sets list
424 public function filterSetPostTypeColContent( $column_name, $post_id )
425 {
426 if ( 'location' == $column_name ){
427 $fss = Container::instance()->getFilterSetService();
428 $theSet = $fss->getSet( $post_id );
429
430 $wpPageType = isset( $theSet['wp_page_type'] ) ? $theSet['wp_page_type'] : '';
431 $location = isset( $theSet['post_name'] ) ? $theSet['post_name'] : '';
432 $post_type = isset( $theSet['post_type']['value'] ) ? $theSet['post_type']['value'] : 'post';
433
434 if( $label = $this->getSetLocationLabel( $wpPageType['options'], $location['value'] , $post_type) ){
435 echo esc_html( $label );
436 }
437
438 unset($fss);
439 }
440 }
441
442 private function getSetLocationLabel( $options, $value, $post_type = 'post' )
443 {
444 $entityLabel = $entityGroup = $entity = '';
445
446 if( ! isset($options['common']['entities']) ){
447 return false;
448 }
449
450 $parts = explode("___", $value);
451 $selectedEntity = $parts[0];
452 $selectedValue = isset($parts[1]) ? $parts[1] : $parts[0];
453
454 unset($parts);
455
456 if( $selectedValue == '1' && $selectedEntity == '1' ){
457 $entityGroup = 'common';
458 $entity = 'common';
459 $entityLabel = esc_html__('All archive pages for this Post Type', 'filter-everything');
460 }else{
461 foreach( $options as $section ){
462 foreach( $section['entities'] as $groupAndEntity => $label ){
463 $parts = explode("___", $groupAndEntity);
464 $entityGroup = $parts[0];
465 $entity = $parts[1];
466
467 unset($parts);
468
469 if( $entity === $selectedEntity ){
470 $entityLabel = $label;
471 break;
472 }
473
474 $entityGroup = $entity = '';
475
476 }
477
478 if( $entityGroup && $entity ){
479 break;
480 }
481 }
482 }
483
484 if( $entityGroup && $entity && $entityLabel ) {
485
486 switch ( $entityGroup ){
487 case 'common':
488
489 $commonPages = flrt_get_common_location_terms( $post_type );
490
491 if( isset( $commonPages[ $selectedEntity .'___'. $selectedValue ]['label'] ) ){
492 $toShow = $commonPages[ $selectedEntity .'___'. $selectedValue ]['label'];
493 }else{
494 $toShow = $entityLabel;
495 }
496
497 break;
498 case 'taxonomy':
499 // could be -1
500 if( $selectedValue == '-1' ){
501 $toShow = sprintf(esc_html__('Any %s', 'filter-everything'), $entityLabel );
502 }else{
503 $term = get_term( $selectedValue, $selectedEntity );
504 $name = ( is_wp_error( $term ) || is_null( $term ) ) ? '' : $term->name;
505 $toShow = sprintf(esc_html__('%s: %s', 'filter-everything'), $entityLabel, $name);
506 }
507
508 break;
509
510 case 'post_type':
511 // could be -1
512 if( $selectedValue == '-1' ){
513 $toShow = sprintf(esc_html__('Any %s', 'filter-everything'), $entityLabel );
514 }else{
515 $name = get_the_title($selectedValue);
516 $toShow = sprintf(esc_html__('%s: %s', 'filter-everything'), $entityLabel, $name);
517 }
518 break;
519 case 'author':
520 // could be -1
521 if( $selectedValue == '-1' ){
522 $toShow = sprintf(esc_html__('Any %s', 'filter-everything'), $entityLabel );
523 }else{
524 $author = get_userdata($selectedValue);
525 $name = ( $author ) ? $author->data->display_name : '';
526 $toShow = sprintf(esc_html__('%s: %s', 'filter-everything'), $entityLabel, $name);
527 }
528 break;
529
530 }
531
532 return apply_filters( 'wpc_set_location_label', $toShow, $selectedValue, $entityGroup, $entity, $entityLabel );
533 }
534
535 return false;
536 }
537
538 /**
539 * @param $filterSet array
540 * @param $queriedObject array
541 * @return array
542 */
543 public function findRelevantSets( $filterSet, $queriedObject )
544 {
545 // Singular page
546 if( isset( $queriedObject[ 'post_id' ] ) ){
547 $sets = $this->getSetIdForSingular( $queriedObject[ 'post_types' ], $queriedObject[ 'post_id' ] );
548 if( $sets !== false ){
549 return $sets;
550 }
551
552 //@todo Try to find common set for all pages this post type
553 $sets = $this->getSetIdForSingular( $queriedObject[ 'post_types' ], '-1' );
554 if( $sets !== false ){
555 return $sets;
556 }
557 }
558
559 // We need to process Common WordPress pages first as more prioritized
560 // Than archive pages
561 if( isset( $queriedObject[ 'common' ] ) ){
562 $sets = $this->getSetIdForCommon( $queriedObject[ 'common' ] );
563 if( ! empty( $sets )){
564 return $sets;
565 }
566 }
567
568 // Get filter set specified for term (if exists)
569 if( isset( $queriedObject[ 'taxonomy' ] ) ){
570 // get term related Filter Set
571 $sets = $this->getSetIdForTerm( $queriedObject[ 'taxonomy' ], $queriedObject[ 'term_id' ] );
572
573 if( $sets !== false ){
574 return $sets;
575 }
576 // Try to find common set for taxonomy archive
577 $sets = $this->getSetIdForTerm( $queriedObject[ 'taxonomy' ], '-1' );
578
579 if( $sets !== false ){
580 return $sets;
581 }
582 }
583
584 if( isset( $queriedObject[ 'author' ] ) ){
585 $sets = $this->getSetIdForAuthor( $queriedObject[ 'author' ] );
586 if( $sets !== false ){
587 return $sets;
588 }
589 }
590
591 return apply_filters( 'wpc_pro_relevant_set_ids', $filterSet, $queriedObject, $this );
592 }
593
594 /**
595 * @param $common array
596 * @return false|mixed
597 */
598 private function getSetIdForCommon( $common )
599 {
600 $storeKey = 'set_common';
601 $searchKey = [];
602
603 foreach( $common as $value ){
604 if( ! in_array( $value, array(
605 'page_on_front',
606 'page_for_posts',
607 'search_results',
608 'shop_page' ) ) ){
609 return false;
610 }
611
612 $storeKey .= '_'.$value;
613 $searchKey[] = "common___".$value;
614 }
615
616 return $this->querySets( $storeKey, $searchKey );
617
618 }
619
620 private function getSetIdForSingular( $postTypes, $postId )
621 {
622 if( ! $postTypes || ! $postId ){
623 return false;
624 }
625
626 $postType = reset($postTypes);
627
628 $storeKey = 'set_' . $postType . '_' .$postId;
629 $searchKey = $postType.'___'.$postId;
630
631 return $this->querySets( $storeKey, $searchKey );
632
633 }
634
635 /**
636 * @return int|false
637 */
638 private function getSetIdForTerm( $taxonomy, $termId )
639 {
640 if( ! $taxonomy || ! $termId ){
641 return false;
642 }
643
644 $storeKey = 'set_' . $taxonomy . '_' .$termId;
645 $searchKey = $taxonomy.'___'.$termId;
646
647 $sets = $this->querySets( $storeKey, $searchKey );
648
649 if( ! $sets ){
650 $parentTermId = wp_get_term_taxonomy_parent_id( $termId, $taxonomy );
651
652 if($parentTermId){
653 return $this->getSetIdForTerm( $taxonomy, $parentTermId );
654 }
655 }
656
657 return $sets;
658 }
659
660 /**
661 * @param $author user_id|user slug
662 * @return int|false
663 */
664 private function getSetIdForAuthor( $authorSlug )
665 {
666 $user_id = false;
667
668 if( ! $authorSlug ){
669 return false;
670 }
671
672 if( $user = get_user_by( 'slug', $authorSlug ) ){
673 $user_id = $user->ID;
674 }
675
676 $storeKey = 'set_author_' . $user_id;
677 $searchKey = 'author___'.$user_id;
678
679 $sets = $this->querySets( $storeKey, $searchKey );
680
681 // Try to find common author page sets
682 if( ! $sets ){
683 $user_id = '-1';
684 $storeKey = 'set_author_' . $user_id;
685 $searchKey = 'author___'.$user_id;
686
687 $sets = $this->querySets( $storeKey, $searchKey );
688 }
689
690 return $sets;
691 }
692 public function querySets( $storeKey, $searchKey )
693 {
694 $container = Container::instance();
695
696 if( ! $sets = $container->getParam( $storeKey ) ){
697 global $wpdb;
698 $sql = [];
699 $is_common = false;
700 $IN = false;
701 $pll_lang_id = false;
702 $is_fitler_set_translatable = false;
703
704 if( ! is_array( $searchKey ) ){
705 $searchKey = array( $searchKey );
706 }
707
708 foreach( $searchKey as $set_key ){
709 $set_key_parts = explode("___", $set_key);
710
711 if ( isset( $set_key_parts[1] ) && $set_key_parts[1] === '-1' ) {
712 $is_common = true;
713 }
714
715 if ( isset( $set_key_parts[0] ) && $set_key_parts[0] === 'common' ) {
716 $is_common = true;
717 }
718
719 $pieces[] = $wpdb->prepare( "%s", $set_key );
720 }
721
722 if( flrt_wpml_active() ){
723 $wpml_settings = get_option( 'icl_sitepress_settings' );
724 if( isset( $wpml_settings['custom_posts_sync_option'][FLRT_FILTERS_SET_POST_TYPE] ) ){
725 if( $wpml_settings['custom_posts_sync_option'][FLRT_FILTERS_SET_POST_TYPE] === '1' ){
726 $is_fitler_set_translatable = true;
727 }
728 }
729 }
730
731 $IN = implode(", ", $pieces );
732
733 $sql[] = "SELECT {$wpdb->posts}.ID,{$wpdb->posts}.post_content,{$wpdb->posts}.post_excerpt,{$wpdb->posts}.post_name";
734 $sql[] = "FROM {$wpdb->posts}";
735
736 // We check if it is common because other thing have their own ID
737 // and do not require separate language versions
738 if ( flrt_wpml_active() && defined('ICL_LANGUAGE_CODE') && $is_common && $is_fitler_set_translatable ) {
739 $sql[] = "LEFT JOIN {$wpdb->prefix}icl_translations AS wpml_translations";
740 $sql[] = "ON {$wpdb->posts}.ID = wpml_translations.element_id";
741 $sql[] = "AND wpml_translations.element_type IN(";
742 $sql[] = $wpdb->prepare( "CONCAT('post_', '%s')", FLRT_FILTERS_SET_POST_TYPE );
743 $sql[] = ")";
744 }
745
746 // Check common if Polylang PRO is active and Filter Set is translatable post type
747 if( flrt_pll_pro_active() && defined('FLRT_ALLOW_PLL_TRANSLATIONS') && FLRT_ALLOW_PLL_TRANSLATIONS && $is_common ){
748 if( function_exists('pll_current_language') && function_exists('pll_the_languages') ) {
749 $pll_current_language = pll_current_language();
750 $pll_languages = pll_the_languages(array('raw' => 1));
751 if ( $pll_current_language && isset( $pll_languages[$pll_current_language]['id'] ) ) {
752 $pll_lang_id = $pll_languages[$pll_current_language]['id'];
753
754 $sql[] = "LEFT JOIN {$wpdb->term_relationships}";
755 $sql[] = "ON ({$wpdb->posts}.ID = {$wpdb->term_relationships}.object_id)";
756 }
757 }
758 }
759
760 $sql[] = "WHERE 1=1";
761
762 $sql[] = "AND ( ";
763 $sql[] = "{$wpdb->posts}.post_name IN ( {$IN} )";
764 $sql[] = "OR {$wpdb->posts}.ID IN ( ";
765 $sql[] = "SELECT {$wpdb->posts}.ID FROM {$wpdb->posts}";
766 $sql[] = "LEFT JOIN {$wpdb->postmeta} ON ( {$wpdb->posts}.ID = {$wpdb->postmeta}.post_id )";
767 $sql[] = "WHERE 1=1";
768 $sql[] = $wpdb->prepare( "AND {$wpdb->postmeta}.meta_key = %s", FLRT_APPLY_BUTTON_META_KEY);
769 $sql[] = "AND {$wpdb->postmeta}.meta_value IN ( {$IN} )";
770 $sql[] = ")";
771 $sql[] = ")";
772
773 $sql[] = $wpdb->prepare("AND {$wpdb->posts}.post_type = '%s'", FLRT_FILTERS_SET_POST_TYPE );
774 $sql[] = "AND ( ({$wpdb->posts}.post_status = 'publish') )";
775
776 if( flrt_wpml_active() && defined( 'ICL_LANGUAGE_CODE' ) && $is_common && $is_fitler_set_translatable ){
777 $sql[] = $wpdb->prepare("AND wpml_translations.language_code = '%s'", ICL_LANGUAGE_CODE );
778 }
779
780 if( flrt_pll_pro_active() && defined('FLRT_ALLOW_PLL_TRANSLATIONS') && FLRT_ALLOW_PLL_TRANSLATIONS && $is_common ){
781 if( $pll_lang_id ){
782 $sql[] = $wpdb->prepare("AND {$wpdb->term_relationships}.term_taxonomy_id IN (%d)", $pll_lang_id );
783 }
784 }
785
786 // First Set is that has larger value Menu order or was created first.
787 $sql[] = "ORDER BY {$wpdb->posts}.menu_order DESC, {$wpdb->posts}.ID ASC";
788
789 $sql = implode(' ', $sql );
790 $setPosts = $wpdb->get_results( $sql, OBJECT );
791
792 if( ! empty( $setPosts ) ){
793 $sets = flrt_is_query_on_page( $setPosts, $searchKey );
794 }else{
795 return false;
796 }
797
798 $container->storeParam( $storeKey, $sets );
799 }
800
801 unset( $container );
802
803 return $sets;
804 }
805 }