PluginProbe
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets / 4.1.8
Ultimate Post Kit – Elementor Post Grid, Post Carousel, Post Slider & Blog Layout Widgets v4.1.8
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.8, at includes/controls/group-query/group-control-query.php

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