PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.17
UiCore Elements – Free widgets and templates for Elementor v1.3.17
1.3.17 1.3.16 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 All 41 releases
← All changes | includes/controls/class-query.php +173 -55 1.0.71.3.17 View file →
@@ -1,13 +1,16 @@
1 1 <?php
2 +
2 3 namespace UiCoreElements\Controls;
3 4
5 +use UiCoreElements\Helper;
4 6 use Elementor\Control_Select2;
7 +
5 8 defined('ABSPATH') || exit();
6 9
7 10 class Query extends Control_Select2
8 11 {
9 - const CONTROL_ID = 'query';
12 + const CONTROL_ID = 'elements_query';
10 13
11 14 public function get_type()
12 15 {
13 16 return self::CONTROL_ID;
@@ -12,40 +15,100 @@
12 15 {
13 16 return self::CONTROL_ID;
14 17 }
15 18
16 - public static function get_query_args($control_id, $settings, $current_id = null)
19 + /**
20 + * Get query args for a given post type query
21 + *
22 + * @param string $control_id The control slug, should be '{post-type}-filter'. Eg: `product-filter`.
23 + * @param array $settings The control settings array.
24 + * @param bool $is_product If the args are for woocommerce products. Default is false.
25 + */
26 + public static function get_query_args($control_id, $settings, $is_product = false)
17 27 {
28 + // get post type
29 + $post_type = $settings[$control_id . '_post_type'];
18 30
31 + // Add extra settings
19 32 $defaults = [
20 - $control_id . '_post_type' => 'post',
33 + $control_id . '_post_type' => $post_type,
21 34 $control_id . '_posts_ids' => [],
22 35 'orderby' => 'date',
23 36 'order' => 'desc',
24 37 ];
38 + $settings = wp_parse_args($settings, $defaults);
25 39
26 - $settings = wp_parse_args($settings, $defaults);
40 + $paged = self::get_queried_page($settings);
27 41
28 - $post_type = $settings[$control_id . '_post_type'];
29 - if($post_type == 'current'){
42 + // Build query args
43 + $query_args = [
44 + 'post_type' => $post_type,
45 + 'orderby' => $settings['item_order_by'] ?? 'date',
46 + 'order' => $settings['item_order'] ?? 'desc',
47 + 'post_status' => 'publish', // Hide drafts/private posts for admins
48 + 'paged' => $paged,
49 + 'ignore_sticky_posts' => true
50 + ];
30 51
31 - $query_type = get_post_meta( $current_id, 'tb_rule_include', true );
32 - $query_type = isset($query_type[0]['rule']['value']) ? $query_type[0]['rule']['value'] : '';
33 - switch ( $query_type ) {
34 - case 'special-blog':
35 - $post_type = 'post';
36 - break;
37 - default:
38 - if( ($type = substr( $query_type, 0, 11 )) === "cp-archive-" ){
39 - $post_type = str_replace($type,'',$query_type);
40 - break;
41 - }
42 - $post_type = 'post';
43 - break;
44 - }
52 + // Get posts per page
53 + $query_args['posts_per_page'] = self::get_posts_per_page($post_type, $settings);
54 +
55 + // Update posts quantity to woo requirements
56 + if ($is_product) {
57 + $query_args['limit'] = $query_args['posts_per_page'];
58 + unset($query_args['posts_per_page']);
59 + unset($query_args['post_type']);
45 60 }
46 61
47 - if(!isset($settings['__current_page'])){
62 + // Offset arg
63 + if (isset($settings['offset']) && !empty($settings['offset']['size'])) {
64 + $query_args['offset'] = $settings['offset']['size'];
65 + }
66 +
67 + // Sticky arg
68 + if (isset($settings['sticky']) && $settings['sticky']) {
69 + $query_args['ignore_sticky_posts'] = false;
70 + }
71 +
72 + //
73 + $queried_filters = self::get_queried_filters($settings, $post_type, $control_id);
74 + if (!empty($queried_filters['tax_query'])) {
75 + $query_args['tax_query'] = $queried_filters['tax_query'];
76 + }
77 +
78 + //Enable for data analysis
79 + // error_log( __FILE__ . '@' . __LINE__ );
80 + // error_log( __METHOD__);
81 + // \error_log(print_r($query_args, true));
82 + // \error_log("-----------------");
83 +
84 + return $query_args;
85 + }
86 +
87 + /**
88 + * Get the amount of posts per page from a given widget settings, with fallback to framework and wordpress.
89 + * @param string $post_type The post type slug.
90 + * @param array $settings The control settings array.
91 + *
92 + * @return int The posts per page value.
93 + */
94 + public static function get_posts_per_page($post_type, $settings)
95 + {
96 + if (isset($settings['item_limit'])) {
97 + return $settings['item_limit']['size'];
98 + }
99 +
100 + return Helper::get_framework_visible_posts($post_type);
101 + }
102 +
103 + /**
104 + * Get the current page value in a query.
105 + *
106 + * @param array $settings The control settings array.
107 + */
108 + public static function get_queried_page($settings)
109 + {
110 + if (!isset($settings['__current_page'])) {
48 111 if (get_query_var('paged')) {
49 112 $paged = get_query_var('paged');
50 113 } elseif (get_query_var('page')) {
51 114 $paged = get_query_var('page');
@@ -55,38 +118,43 @@
55 118 } else {
56 119 $paged = $settings['__current_page'];
57 120 }
58 121
59 - $query_args = [
60 - 'orderby' => $settings['orderby'],
61 - 'order' => $settings['order'],
62 - 'post_status' => 'publish', // Hide drafts/private posts for admins
63 - 'paged' => $paged,
64 - 'posts_per_page' => isset( $settings['item_limit'] ) ? $settings['item_limit']['size'] : get_option('posts_per_page'),
122 + return $paged;
123 + }
124 +
125 + /**
126 + * Build the `tax_query` args to work with filter component.
127 + *
128 + * @param array $settings The control settings array.
129 + * @param string $post_type The post type slug.
130 + * @param string $control_id The control slug. Can be 'posts-type' or 'product-filter'.
131 + *
132 + * @return array The query args.
133 + */
134 + public static function get_queried_filters($settings, $post_type, $control_id)
135 + {
136 + $args = [
137 + 'post_type' => $post_type,
138 + 'tax_query' => [],
65 139 ];
66 140
67 - // If the offset is set, we need to set the offset and paged parameters
68 - if(isset($settings['offset']) && !empty($settings['offset']['size'])){
69 - $query_args['offset'] = $settings['offset']['size'];
70 - }
141 + $term = self::get_query_term_compatibility('term');
142 + $tax = self::get_query_term_compatibility('tax');
71 143
72 - if(isset($settings['sticky']) && $settings['sticky']){
73 - $query_args['ignore_sticky_posts'] = 0;
74 - }
144 + if (
145 + isset($settings['post_filtering']) &&
146 + $settings['post_filtering'] &&
147 + isset($tax) &&
148 + isset($term)
149 + ) {
75 150
76 - // If filters are enabled, checks for url taxonomy params. Eg: since not every post widget has filters, so we also need to check if is set.
77 - if( isset($settings['post_filtering']) && $settings['post_filtering'] && isset($_GET['tax']) && isset($_GET['term'])){
78 -
79 - $query_args['tax_query'][] = [
80 - 'taxonomy' => $_GET['tax'],
81 - 'field' => 'term_id',
82 - 'terms' => $_GET['term'],
151 + $args['tax_query'][] = [
152 + 'taxonomy' => sanitize_text_field(wp_unslash($tax)), //phpcs:ignore WordPress.Security.NonceVerification.Recommended
153 + 'field' => 'term_id',
154 + 'terms' => intval($term), //phpcs:ignore WordPress.Security.NonceVerification.Recommended
83 155 ];
84 -
85 156 } else {
86 - $query_args['post_type'] = $post_type;
87 - $query_args['tax_query'] = [];
88 -
89 157 $taxonomies = get_object_taxonomies($post_type, 'objects');
90 158
91 159 foreach ($taxonomies as $object) {
92 160 $setting_key = $control_id . '_' . $object->name . '_ids';
@@ -92,25 +160,75 @@
92 160 $setting_key = $control_id . '_' . $object->name . '_ids';
93 161
94 162 if (!empty($settings[$setting_key])) {
95 163 $terms_list = $settings[$setting_key];
96 - $query_args['tax_query'][] = [
164 +
165 + if (!is_array($terms_list)) {
166 + $terms_list = explode(',', $terms_list);
167 + }
168 +
169 + $args['tax_query'][] = [
97 170 'taxonomy' => $object->name,
98 - 'field' => 'term_id',
99 - 'terms' => $terms_list,
171 + 'field' => 'term_id',
172 + 'terms' => array_map('intval', $terms_list),
100 173 ];
101 174 }
102 175 }
103 176 }
104 177
105 - //Enable for data analysis
106 - // error_log( __FILE__ . '@' . __LINE__ );
107 - // error_log( __METHOD__);
108 - // \error_log(print_r($query_args, true));
109 - // \error_log("-----------------");
178 + // Set `AND` relation if we're working with multiple tax queries
179 + if (count($args['tax_query']) > 1) {
180 + $args['tax_query']['relation'] = 'AND';
181 + };
110 182
111 - return $query_args;
183 + return $args;
112 184 }
113 185
186 + /**
187 + * Get the query terms from URL params, checking for both 'ui_{arg}' and '{arg}' params.
188 + */
189 + public static function get_query_term_compatibility(string $arg)
190 + {
191 + if (isset($_GET['ui_' . $arg])) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
192 + return $_GET['ui_' . $arg]; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
193 + }
194 + if (isset($_GET[$arg])) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
195 + return $_GET[$arg]; //phpcs:ignore WordPress.Security.NonceVerification.Recommended
196 + }
197 + return null;
198 + }
199 +
200 + /**
201 + * Get all products from a given product query and return the total amount of pages for it. Only for woo product queries.
202 + *
203 + * TODO: investigate more performatic approaches, not only we're running a query for the second time,
204 + * but we're using -1, wich means a big CPU and memory usage.
205 + */
206 + public static function get_total_pages($default_query)
207 + {
208 + // Set non-limit posts and a light return type
209 + $calc_args = [
210 + 'limit' => '-1',
211 + 'return' => 'ids'
212 + ];
213 + $calc_args = array_merge($default_query, $calc_args);
214 +
215 + // Makes sure we have a limit set
216 + if (isset($default_query['limit']) || isset($default_query['posts_per_page'])) {
217 + $limit = isset($default_query['limit'])
218 + ? $default_query['limit']
219 + : $default_query['posts_per_page'];
220 +
221 + // Get limit from framework otherwise
222 + } else {
223 + $limit = Helper::get_framework_visible_posts('product');
224 + }
225 +
226 + // Get total pages value
227 + $total_products = wc_get_products($calc_args);
228 + $total = ceil(count($total_products) / $limit);
229 +
230 + return $total;
231 + }
114 232 }
115 233
116 -\Elementor\Plugin::$instance->controls_manager->register_control('query', new Query());
234 +\Elementor\Plugin::$instance->controls_manager->register_control('elements_query', new Query());