PluginProbe
UiCore Elements – Free widgets and templates for Elementor / trunk
UiCore Elements – Free widgets and templates for Elementor vtrunk
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 1.3.0 All 40 releases
uicore-elements / includes / controls / class-query.php

class-query.php in UiCore Elements – Free widgets and templates for Elementor trunk, at includes/controls/class-query.php

235 lines 7.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace UiCoreElements\Controls;
4
5 use UiCoreElements\Helper;
6 use Elementor\Control_Select2;
7
8 defined('ABSPATH') || exit();
9
10 class Query extends Control_Select2
11 {
12 const CONTROL_ID = 'elements_query';
13
14 public function get_type()
15 {
16 return self::CONTROL_ID;
17 }
18
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)
27 {
28 // get post type
29 $post_type = $settings[$control_id . '_post_type'];
30
31 // Add extra settings
32 $defaults = [
33 $control_id . '_post_type' => $post_type,
34 $control_id . '_posts_ids' => [],
35 'orderby' => 'date',
36 'order' => 'desc',
37 ];
38 $settings = wp_parse_args($settings, $defaults);
39
40 $paged = self::get_queried_page($settings);
41
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 ];
51
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']);
60 }
61
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'])) {
111 if (get_query_var('paged')) {
112 $paged = get_query_var('paged');
113 } elseif (get_query_var('page')) {
114 $paged = get_query_var('page');
115 } else {
116 $paged = 1;
117 }
118 } else {
119 $paged = $settings['__current_page'];
120 }
121
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' => [],
139 ];
140
141 $term = self::get_query_term_compatibility('term');
142 $tax = self::get_query_term_compatibility('tax');
143
144 if (
145 isset($settings['post_filtering']) &&
146 $settings['post_filtering'] &&
147 isset($tax) &&
148 isset($term)
149 ) {
150
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
155 ];
156 } else {
157 $taxonomies = get_object_taxonomies($post_type, 'objects');
158
159 foreach ($taxonomies as $object) {
160 $setting_key = $control_id . '_' . $object->name . '_ids';
161
162 if (!empty($settings[$setting_key])) {
163 $terms_list = $settings[$setting_key];
164
165 if (!is_array($terms_list)) {
166 $terms_list = explode(',', $terms_list);
167 }
168
169 $args['tax_query'][] = [
170 'taxonomy' => $object->name,
171 'field' => 'term_id',
172 'terms' => array_map('intval', $terms_list),
173 ];
174 }
175 }
176 }
177
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 };
182
183 return $args;
184 }
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 }
232 }
233
234 \Elementor\Plugin::$instance->controls_manager->register_control('elements_query', new Query());
235