PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.1.3
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.1.3
4.5.4 4.2.1 4.2.2 4.2.3 4.5.0 4.5.2 4.5.3 4.2.0 4.1.18 4.1.17 4.1.16 4.1.15 4.1.14 4.1.13 4.1.12 4.1.11 4.1.10 4.1.9 4.1.8 4.0.9 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 All 146 releases
ultimate-post-kit / includes / controls / group-query / group-control-query.php

group-control-query.php in Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets 4.1.3, at includes/controls/group-query/group-control-query.php

739 lines 24.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UltimatePostKit\Includes\Controls\GroupQuery;
4
5 use Elementor\Controls_Manager;
6 use UltimatePostKit\Includes\Controls\SelectInput\Dynamic_Select;
7 use UltimatePostKit\Base\Module_Base;
8
9 if (!defined('ABSPATH')) {
10 exit; // Exit if accessed directly.
11 }
12
13 abstract class Group_Control_Query extends Module_Base {
14
15 protected function register_query_builder_controls() {
16
17 $this->add_control(
18 'posts_source',
19 [
20 'label' => __('Source', 'ultimate-post-kit'),
21 'type' => Controls_Manager::SELECT,
22 'options' => $this->getGroupControlQueryPostTypes(),
23 'default' => 'post',
24 ]
25 );
26
27 $this->add_control(
28 'posts_selected_ids',
29 [
30 'label' => __('Search & Select', 'ultimate-post-kit'),
31 'type' => Dynamic_Select::TYPE,
32 'multiple' => true,
33 'label_block' => true,
34 'query_args' => [
35 'query' => 'posts',
36 ],
37 'condition' => [
38 'posts_source' => 'manual_selection',
39 ]
40 ]
41 );
42
43 $this->start_controls_tabs(
44 'tabs_posts_include_exclude',
45 [
46 'condition' => [
47 'posts_source!' => ['manual_selection', 'current_query'],
48 ]
49 ]
50 );
51
52 $this->start_controls_tab(
53 'tab_posts_include',
54 [
55 'label' => __('Include', 'ultimate-post-kit'),
56 'condition' => [
57 'posts_source!' => ['manual_selection', 'current_query'],
58 ]
59 ]
60 );
61
62 $this->add_control(
63 'posts_include_by',
64 [
65 'label' => __('Include By', 'ultimate-post-kit'),
66 'type' => Controls_Manager::SELECT2,
67 'multiple' => true,
68 'label_block' => true,
69 'options' => [
70 'authors' => __('Authors', 'ultimate-post-kit'),
71 'terms' => __('Terms', 'ultimate-post-kit'),
72 ],
73 'condition' => [
74 'posts_source!' => ['manual_selection', 'current_query'],
75 ]
76 ]
77 );
78
79 $this->add_control(
80 'posts_include_author_ids',
81 [
82 'label' => __('Authors', 'ultimate-post-kit'),
83 'type' => Dynamic_Select::TYPE,
84 'multiple' => true,
85 'label_block' => true,
86 'query_args' => [
87 'query' => 'authors',
88 ],
89 'condition' => [
90 'posts_include_by' => 'authors',
91 'posts_source!' => ['manual_selection', 'current_query'],
92 ]
93 ]
94 );
95
96 $this->add_control(
97 'posts_include_term_ids',
98 [
99 'label' => __('Terms', 'ultimate-post-kit'),
100 'description' => __('Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'ultimate-post-kit'),
101 'type' => Dynamic_Select::TYPE,
102 'multiple' => true,
103 'label_block' => true,
104 'placeholder' => __('Type and select terms', 'ultimate-post-kit'),
105 'query_args' => [
106 'query' => 'terms',
107 'widget_props' => [
108 'post_type' => 'posts_source'
109 ]
110 ],
111 'condition' => [
112 'posts_include_by' => 'terms',
113 'posts_source!' => ['manual_selection', 'current_query'],
114 ]
115 ]
116 );
117
118 $this->end_controls_tab();
119
120 $this->start_controls_tab(
121 'tab_posts_exclude',
122 [
123 'label' => __('Exclude', 'ultimate-post-kit'),
124 'condition' => [
125 'posts_source!' => ['manual_selection', 'current_query'],
126 ]
127 ]
128 );
129
130 $this->add_control(
131 'posts_exclude_by',
132 [
133 'label' => __('Exclude By', 'ultimate-post-kit'),
134 'type' => Controls_Manager::SELECT2,
135 'multiple' => true,
136 'label_block' => true,
137 'options' => [
138 'authors' => __('Authors', 'ultimate-post-kit'),
139 'current_post' => __('Current Post', 'ultimate-post-kit'),
140 'manual_selection' => __('Manual Selection', 'ultimate-post-kit'),
141 'terms' => __('Terms', 'ultimate-post-kit'),
142 ],
143 'condition' => [
144 'posts_source!' => ['manual_selection', 'current_query'],
145 ]
146 ]
147 );
148
149 $this->add_control(
150 'posts_exclude_ids',
151 [
152 'label' => __('Search & Select', 'ultimate-post-kit'),
153 'type' => Dynamic_Select::TYPE,
154 'multiple' => true,
155 'label_block' => true,
156 'query_args' => [
157 'query' => 'posts',
158 'widget_props' => [
159 'post_type' => 'posts_source'
160 ]
161 ],
162 'condition' => [
163 'posts_source!' => ['manual_selection', 'current_query'],
164 'posts_exclude_by' => 'manual_selection',
165 ]
166 ]
167 );
168
169 $this->add_control(
170 'posts_exclude_author_ids',
171 [
172 'label' => __('Authors', 'ultimate-post-kit'),
173 'type' => Dynamic_Select::TYPE,
174 'multiple' => true,
175 'label_block' => true,
176 'query_args' => [
177 'query' => 'authors',
178 ],
179 'condition' => [
180 'posts_exclude_by' => 'authors',
181 'posts_source!' => ['manual_selection', 'current_query'],
182 ]
183 ]
184 );
185
186 $this->add_control(
187 'posts_exclude_term_ids',
188 [
189 'label' => __('Terms', 'ultimate-post-kit'),
190 'description' => __('Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'ultimate-post-kit'),
191 'type' => Dynamic_Select::TYPE,
192 'multiple' => true,
193 'label_block' => true,
194 'placeholder' => __('Type and select terms', 'ultimate-post-kit'),
195 'query_args' => [
196 'query' => 'terms',
197 'widget_props' => [
198 'post_type' => 'posts_source'
199 ]
200 ],
201 'condition' => [
202 'posts_exclude_by' => 'terms',
203 'posts_source!' => ['manual_selection', 'current_query'],
204 ]
205 ]
206 );
207
208 $this->end_controls_tab();
209 $this->end_controls_tabs();
210
211 $this->add_control(
212 'posts_divider',
213 [
214 'type' => Controls_Manager::DIVIDER,
215 'condition' => [
216 'posts_source!' => 'current_query',
217 ]
218 ]
219 );
220
221 $this->add_control(
222 'posts_offset',
223 [
224 'label' => __('Offset', 'ultimate-post-kit'),
225 'type' => Controls_Manager::NUMBER,
226 'default' => 0,
227 ]
228 );
229
230 $this->add_control(
231 'posts_select_date',
232 [
233 'label' => __('Date', 'ultimate-post-kit'),
234 'type' => Controls_Manager::SELECT,
235 'default' => 'anytime',
236 'options' => [
237 'anytime' => __('All', 'ultimate-post-kit'),
238 'today' => __('Past Day', 'ultimate-post-kit'),
239 'week' => __('Past Week', 'ultimate-post-kit'),
240 'month' => __('Past Month', 'ultimate-post-kit'),
241 'quarter' => __('Past Quarter', 'ultimate-post-kit'),
242 'year' => __('Past Year', 'ultimate-post-kit'),
243 'exact' => __('Custom', 'ultimate-post-kit'),
244 ],
245 'condition' => [
246 'posts_source!' => 'current_query',
247 ]
248 ]
249 );
250
251 $this->add_control(
252 'posts_date_before',
253 [
254 'label' => __('Before', 'ultimate-post-kit'),
255 'type' => Controls_Manager::DATE_TIME,
256 'description' => __('Setting a ‘Before’ date will show all the posts published until the chosen date (inclusive).', 'ultimate-post-kit'),
257 'condition' => [
258 'posts_select_date' => 'exact',
259 'posts_source!' => 'current_query',
260 ]
261 ]
262 );
263
264 $this->add_control(
265 'posts_date_after',
266 [
267 'label' => __('After', 'ultimate-post-kit'),
268 'type' => Controls_Manager::DATE_TIME,
269 'description' => __('Setting an ‘After’ date will show all the posts published since the chosen date (inclusive).', 'ultimate-post-kit'),
270 'condition' => [
271 'posts_select_date' => 'exact',
272 'posts_source!' => 'current_query',
273 ]
274 ]
275 );
276
277 $this->add_control(
278 'posts_orderby',
279 [
280 'label' => __('Order By', 'ultimate-post-kit'),
281 'type' => Controls_Manager::SELECT,
282 'default' => 'date',
283 'options' => [
284 'title' => __('Title', 'ultimate-post-kit'),
285 'ID' => __('ID', 'ultimate-post-kit'),
286 'date' => __('Date', 'ultimate-post-kit'),
287 'author' => __('Author', 'ultimate-post-kit'),
288 'comment_count' => __('Comment Count', 'ultimate-post-kit'),
289 'menu_order' => __('Menu Order', 'ultimate-post-kit'),
290 'modified' => __( 'Last Modified', 'ultimate-post-kit' ),
291 'rand' => __('Random', 'ultimate-post-kit'),
292 ],
293 ]
294 );
295
296 $this->add_control(
297 'posts_order',
298 [
299 'label' => __('Order', 'ultimate-post-kit'),
300 'type' => Controls_Manager::SELECT,
301 'default' => 'desc',
302 'options' => [
303 'asc' => __('ASC', 'ultimate-post-kit'),
304 'desc' => __('DESC', 'ultimate-post-kit'),
305 ],
306 ]
307 );
308
309 $this->add_control(
310 'posts_ignore_sticky_posts',
311 [
312 'label' => __('Ignore Sticky Posts', 'ultimate-post-kit'),
313 'type' => Controls_Manager::SWITCHER,
314 'return_value' => 'yes',
315 'default' => 'yes',
316 'condition' => [
317 'posts_source' => ['post', 'current_query'],
318 ]
319 ]
320 );
321
322 $this->add_control(
323 'posts_only_with_featured_image',
324 [
325 'label' => __('Only Featured Image Post', 'ultimate-post-kit'),
326 'description' => __('Enable to display posts only when featured image is present.', 'ultimate-post-kit'),
327 'type' => Controls_Manager::SWITCHER,
328 'return_value' => 'yes',
329 'condition' => [
330 'posts_source!' => 'current_query',
331 ]
332 ]
333 );
334
335 $this->add_control(
336 'query_id',
337 [
338 'label' => __('Query ID', 'ultimate-post-kit'),
339 'description' => __('Give your Query a custom unique id to allow server side filtering', 'ultimate-post-kit'),
340 'type' => Controls_Manager::TEXT,
341 'separator' => 'before',
342 ]
343 );
344 }
345
346 private function setMetaQueryArgs() {
347
348 $args = [];
349
350 if ('current_query' === $this->getGroupControlQueryPostType()) {
351 return [];
352 }
353
354 $args['order'] = $this->get_settings_for_display('posts_order');
355 $args['orderby'] = $this->get_settings_for_display('posts_orderby');
356
357 /**
358 * Set Feature Images
359 */
360
361 if ($this->get_settings_for_display('posts_only_with_featured_image') === 'yes') {
362 $args['meta_key'] = '_thumbnail_id';
363 }
364
365 /**
366 * Set Date
367 */
368
369 $selected_date = $this->get_settings_for_display('posts_select_date');
370
371 if (!empty($selected_date)) {
372 $date_query = [];
373
374 switch ($selected_date) {
375 case 'today':
376 $date_query['after'] = '-1 day';
377 break;
378
379 case 'week':
380 $date_query['after'] = '-1 week';
381 break;
382
383 case 'month':
384 $date_query['after'] = '-1 month';
385 break;
386
387 case 'quarter':
388 $date_query['after'] = '-3 month';
389 break;
390
391 case 'year':
392 $date_query['after'] = '-1 year';
393 break;
394
395 case 'exact':
396 $after_date = $this->get_settings_for_display('posts_date_after');
397
398 if (!empty($after_date)) {
399 $date_query['after'] = $after_date;
400 }
401
402 $before_date = $this->get_settings_for_display('posts_date_before');
403
404 if (!empty($before_date)) {
405 $date_query['before'] = $before_date;
406 }
407
408 $date_query['inclusive'] = true;
409 break;
410 }
411
412 if (!empty($date_query)) {
413 $args['date_query'] = $date_query;
414 }
415 }
416
417 return $args;
418 }
419
420 protected function getGroupControlQueryArgs() {
421
422 $settings = $this->get_settings_for_display();
423 $args = $this->setMetaQueryArgs();
424
425 $args['post_status'] = 'publish';
426 $args['suppress_filters'] = false;
427 $exclude_by = $this->getGroupControlQueryParamBy('exclude');
428
429 if (0 < $settings['posts_offset']) {
430 $args['offset_to_fix'] = $settings['posts_offset'];
431 }
432
433 /**
434 * Set Ignore Sticky
435 */
436 if (
437 $this->getGroupControlQueryPostType() === 'post'
438 && $this->get_settings_for_display('posts_ignore_sticky_posts') === 'yes'
439 ) {
440 $args['ignore_sticky_posts'] = true;
441
442 if (in_array('current_post', $exclude_by)) {
443 $args['post__not_in'] = [get_the_ID()];
444 }
445 }
446
447 if ($this->getGroupControlQueryPostType() === 'manual_selection') {
448 /**
449 * Set Including Manually
450 */
451 $selected_ids = $this->get_settings_for_display('posts_selected_ids');
452 $selected_ids = wp_parse_id_list($selected_ids);
453 $args['post_type'] = 'any';
454 if (!empty($selected_ids)) {
455 $args['post__in'] = $selected_ids;
456 }
457
458 $args['ignore_sticky_posts'] = 1;
459 } elseif ('current_query' === $this->getGroupControlQueryPostType()) {
460 /**
461 * Make Current Query
462 */
463 $args = $GLOBALS['wp_query']->query_vars;
464 $args = apply_filters('ultimate_post_kit/query/get_query_args/current_query', $args);
465 } elseif ('_ultimate_post_kit_pro_related_post_type' == $this->getGroupControlQueryPostType()) {
466 /**
467 * Set Related Query
468 */
469 $post_id = get_queried_object_id();
470 $related_post_id = is_singular() && (0 !== $post_id) ? $post_id : null;
471 $args['post_type'] = get_post_type($related_post_id);
472
473 $exclude_by = $this->getGroupControlQueryParamBy('exclude');
474 if (in_array('current_post', $exclude_by)) {
475 $args['post__not_in'] = [get_the_ID()];
476 }
477
478 /**
479 * Set Authors
480 */
481 $args = $this->getAuthorArgs($args, $settings, $related_post_id);
482
483 /**
484 * Set Taxonomy
485 */
486 $args = $this->getTermsArgs($args, $settings);
487
488 $args['ignore_sticky_posts'] = 1;
489 $args = apply_filters('ultimate_post_kit/query/get_query_args/related_query', $args);
490 } else {
491
492 /**
493 * Set Post Type
494 */
495 $args['post_type'] = $this->getGroupControlQueryPostType();
496
497 /**
498 * Set Exclude Post
499 */
500 $exclude_by = $this->getGroupControlQueryParamBy('exclude');
501 $current_post = [];
502
503 if (in_array('current_post', $exclude_by) && is_singular()) {
504 $current_post = [get_the_ID()];
505 }
506
507 if (in_array('manual_selection', $exclude_by)) {
508 $exclude_ids = $settings['posts_exclude_ids'];
509 $args['post__not_in'] = array_merge($current_post, wp_parse_id_list($exclude_ids));
510 }
511
512 /**
513 * Set Authors
514 */
515 $args = $this->getAuthorArgs($args, $settings);
516
517 /**
518 * Set Taxonomy
519 */
520 $args = $this->getTermsArgs($args, $settings);
521 }
522
523 if ($this->get_settings_for_display('query_id')) {
524 add_action('pre_get_posts', [$this, 'pre_get_posts_query_filter']);
525 }
526
527 // fixing custom offset
528 ## https://codex.wordpress.org/Making_Custom_Queries_using_Offset_and_Pagination
529 add_action('pre_get_posts', [$this, 'fix_query'], 1);
530 add_filter('found_posts', [$this, 'prefix_adjust_offset_pagination'], 1, 2);
531
532 return $args;
533 }
534
535 private function getAuthorArgs($args, $settings, mixed $post = null) {
536
537 $include_by = $this->getGroupControlQueryParamBy('include');
538 $exclude_by = $this->getGroupControlQueryParamBy('exclude');
539 $include_users = [];
540 $exclude_users = [];
541
542 if (in_array('authors', $include_by)) {
543 $include_users = wp_parse_id_list($settings['posts_include_author_ids']);
544 } elseif ($post) {
545 $include_users = get_post_field('post_author', $post);
546 }
547
548 if (in_array('authors', $exclude_by)) {
549 $exclude_users = wp_parse_id_list($settings['posts_exclude_author_ids']);
550 $include_users = array_diff($include_users, $exclude_users);
551 }
552
553 if (!empty($include_users)) {
554 $args['author__in'] = $include_users;
555 }
556
557 if (!empty($exclude_users)) {
558 $args['author__not_in'] = $exclude_users;
559 }
560
561 return $args;
562 }
563
564 private function getTermsArgs($args, $settings) {
565
566 $include_by = $this->getGroupControlQueryParamBy('include');
567 $exclude_by = $this->getGroupControlQueryParamBy('exclude');
568 $include_terms = [];
569 $terms_query = [];
570
571 if (in_array('terms', $include_by)) {
572 $include_terms = wp_parse_id_list($settings['posts_include_term_ids']);
573 }
574
575 if (in_array('terms', $exclude_by)) {
576 $exclude_terms = wp_parse_id_list($settings['posts_exclude_term_ids']);
577 $include_terms = array_diff($include_terms, $exclude_terms);
578 }
579
580 if (!empty($include_terms)) {
581 $tax_terms_map = $this->mapGroupControlQuery($include_terms);
582
583 foreach ($tax_terms_map as $tax => $terms) {
584 $terms_query[] = [
585 'taxonomy' => $tax,
586 'field' => 'term_id',
587 'terms' => $terms,
588 'operator' => 'IN',
589 ];
590 }
591 }
592
593 if (!empty($exclude_terms)) {
594 $tax_terms_map = $this->mapGroupControlQuery($exclude_terms);
595
596 foreach ($tax_terms_map as $tax => $terms) {
597 $terms_query[] = [
598 'taxonomy' => $tax,
599 'field' => 'term_id',
600 'terms' => $terms,
601 'operator' => 'NOT IN',
602 ];
603 }
604 }
605
606 if (!empty($terms_query)) {
607 $args['tax_query'] = $terms_query;
608 $args['tax_query']['relation'] = 'AND';
609 }
610
611 return $args;
612 }
613
614 /**
615 * @return mixed
616 */
617 private function getGroupControlQueryPostType() {
618 return $this->get_settings_for_display('posts_source');
619 }
620
621 /**
622 * Get Query Params by args
623 *
624 * @param string $by
625 *
626 * @return array|mixed
627 */
628 private function getGroupControlQueryParamBy($by = 'exclude') {
629 $mapBy = [
630 'exclude' => 'posts_exclude_by',
631 'include' => 'posts_include_by',
632 ];
633
634 $setting = $this->get_settings_for_display($mapBy[$by]);
635
636 return (!empty($setting) ? $setting : []);
637 }
638
639 /**
640 * @param array $term_ids
641 *
642 * @return array
643 */
644 private function mapGroupControlQuery($term_ids = []) {
645 $terms = get_terms(
646 [
647 'term_taxonomy_id' => $term_ids,
648 'hide_empty' => false,
649 ]
650 );
651
652 $tax_terms_map = [];
653
654 foreach ($terms as $term) {
655 $taxonomy = $term->taxonomy;
656 $tax_terms_map[$taxonomy][] = $term->term_id;
657 }
658
659 return $tax_terms_map;
660 }
661
662
663 /**
664 * @return array|string[]|\WP_Post_Type[]
665 */
666 private function getGroupControlQueryPostTypes() {
667 $post_types = get_post_types(['public' => true], 'objects');
668 $post_types = array_column($post_types, 'label', 'name');
669
670 $ignorePostTypes = [
671 'elementor_library' => '',
672 'attachment' => '',
673 'bdt_template_manager' => '',
674 'bdt-custom-template' => '',
675 ];
676
677 $post_types = array_diff_key($post_types, $ignorePostTypes);
678
679 $extra_types = [
680 'manual_selection' => __('Manual Selection', 'ultimate-post-kit'),
681 'current_query' => __('Current Query', 'ultimate-post-kit'),
682 '_ultimate_post_kit_pro_related_post_type' => __('Related', 'ultimate-post-kit'),
683 ];
684
685 $post_types = array_merge($post_types, $extra_types);
686
687 return $post_types;
688 }
689
690 /**
691 * @param WP_Query $query fix the offset
692 */
693
694 function fix_query(&$query) {
695
696 $settings = $this->get_settings_for_display();
697
698 $query->set('order', $settings['posts_order']);
699 $query->set('orderby', $settings['posts_orderby']);
700
701 if (isset($query->query_vars['offset_to_fix'])) {
702
703 if ($query->is_paged) {
704 $page_offset = $query->query_vars['offset_to_fix'] + (($query->query_vars['paged'] - 1) * $query->query_vars['posts_per_page']);
705 $query->set('offset', $page_offset);
706 } else {
707 $query->set('offset', $query->query_vars['offset_to_fix']);
708 }
709 } else {
710 if ($query->is_paged) {
711 $page_offset = (int) $settings['posts_offset'] + (($query->query_vars['paged'] - 1) * $query->query_vars['posts_per_page']);
712 $query->set('offset', $page_offset);
713 } else {
714 $query->set('offset', $settings['posts_offset']);
715 }
716 }
717 }
718
719 public function prefix_adjust_offset_pagination($found_posts, $query) {
720
721 if (isset($query->query_vars['offset_to_fix'])) {
722 $offset_to_fix = intval($query->query_vars['offset_to_fix']);
723
724 if ($offset_to_fix) {
725 $found_posts -= $offset_to_fix;
726 }
727 }
728
729 return $found_posts;
730 }
731
732 public function pre_get_posts_query_filter($wp_query) {
733 if ($this) {
734 $query_id = $this->get_settings_for_display('query_id');
735 do_action("ultimate_post_kit_pro/query/{$query_id}", $wp_query, $this);
736 }
737 }
738 }
739