PluginProbe
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder / 3.1.4
Ultimate Store Kit – Store Builder Addons for Elementor, WooCommerce Store Builder, EDD Store Builder v3.1.4
3.1.4 3.0.8 3.0.9 3.1.0 3.1.2 3.1.3 3.0.7 3.0.5 3.0.4 3.0.3 3.0.2 trunk 1.5.0 1.5.1 1.5.2 1.6.1 1.6.2 1.6.3 1.6.4 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 All 93 releases
← All changes | includes/controls/group-query/group-control-query.php +683 -394 1.6.13.1.4 View file →
@@ -4,23 +4,28 @@
4 4
5 5 use Elementor\Controls_Manager;
6 6 use UltimateStoreKit\Includes\Controls\SelectInput\Dynamic_Select;
7 7
8 -if (!defined('ABSPATH')) {
8 +if (! defined('ABSPATH')) {
9 9 exit; // Exit if accessed directly.
10 10 }
11 11
12 -trait Group_Control_Query {
12 +// phpcs:disable WordPressVIPMinimum.Performance.WPQueryParams -- WordPressVIPMinimum targets the VIP platform, not the plugin directory. These exclusionary parameters come from a widget's own "exclude" control: the list is whatever the site owner picked in Elementor, applied to a bounded result set, not an unbounded catalogue scan.
13 +// phpcs:disable WordPress.DB.SlowDBQuery -- meta_query / tax_query / meta_key are the documented way to express these widget filters. Removing them means fetching every post and filtering in PHP, which is strictly slower.
13 14
14 - public function register_query_builder_controls() {
15 +trait Group_Control_Query
16 +{
15 17
18 + public function register_query_builder_controls()
19 + {
20 +
16 21 $this->add_control(
17 22 'product_source',
18 23 [
19 - 'label' => __('Source', 'ultimate-store-kit'),
20 - 'type' => Controls_Manager::SELECT,
21 - 'options' => $this->getGroupControlQueryPostTypes(),
22 - 'default' => 'product',
24 + 'label' => __('Source', 'ultimate-store-kit'),
25 + 'type' => Controls_Manager::SELECT,
26 + 'options' => $this->getGroupControlQueryPostTypes(),
27 + 'default' => 'product',
23 28 ]
24 29 );
25 30 $this->add_control(
26 31 'product_limit',
@@ -39,11 +44,12 @@
39 44 'multiple' => true,
40 45 'label_block' => true,
41 46 'query_args' => [
42 47 'query' => 'posts',
48 + 'post_type' => 'product',
43 49 ],
44 50 'condition' => [
45 - 'product_source' => 'manual_selection',
51 + 'product_source' => 'manual_selection',
46 52 ]
47 53 ]
48 54 );
49 55
@@ -50,9 +56,9 @@
50 56 $this->start_controls_tabs(
51 57 'tabs_product_include_exclude',
52 58 [
53 59 'condition' => [
54 - 'product_source!' => ['manual_selection', 'current_query'],
60 + 'product_source!' => ['manual_selection', 'current_query'],
55 61 ]
56 62 ]
57 63 );
58 64
@@ -60,9 +66,9 @@
60 66 'tab_product_include',
61 67 [
62 68 'label' => __('Include', 'ultimate-store-kit'),
63 69 'condition' => [
64 - 'product_source!' => ['manual_selection', 'current_query'],
70 + 'product_source!' => ['manual_selection'],
65 71 ]
66 72 ]
67 73 );
68 74
@@ -73,56 +79,194 @@
73 79 'type' => Controls_Manager::SELECT2,
74 80 'multiple' => true,
75 81 'label_block' => true,
76 82 'options' => [
77 - 'authors' => __('Authors', 'ultimate-store-kit'),
78 - 'terms' => __('Terms', 'ultimate-store-kit'),
83 + 'categories' => __('Categories', 'ultimate-store-kit'),
84 + 'tags' => __('Tags', 'ultimate-store-kit'),
85 + 'brands' => __('Brands', 'ultimate-store-kit'),
86 + 'attributes' => __('Attributes', 'ultimate-store-kit'),
87 + 'date' => __('Date', 'ultimate-store-kit'),
88 + 'image' => __('Product Image', 'ultimate-store-kit'),
89 + 'price' => __('Price', 'ultimate-store-kit'),
90 + 'stock' => __('Stock', 'ultimate-store-kit'),
79 91 ],
80 92 'condition' => [
81 - 'product_source!' => ['manual_selection', 'current_query'],
93 + 'product_source!' => ['manual_selection'],
82 94 ]
83 95 ]
84 96 );
85 97
86 98 $this->add_control(
87 - 'product_include_author_ids',
99 + 'product_include_category_ids',
88 100 [
89 - 'label' => __('Authors', 'ultimate-store-kit'),
101 + 'label' => __('Categories', 'ultimate-store-kit'),
90 102 'type' => Dynamic_Select::TYPE,
91 103 'multiple' => true,
92 104 'label_block' => true,
93 105 'query_args' => [
94 - 'query' => 'authors',
106 + 'query' => 'product_cat',
95 107 ],
96 108 'condition' => [
97 - 'product_include_by' => 'authors',
98 - 'product_source!' => ['manual_selection', 'current_query'],
109 + 'product_include_by' => 'categories',
110 + 'product_source!' => ['manual_selection'],
99 111 ]
100 112 ]
101 113 );
102 114
103 115 $this->add_control(
104 - 'product_include_term_ids',
116 + 'product_include_tag_ids',
105 117 [
106 - 'label' => __('Terms', 'ultimate-store-kit'),
107 - 'description' => __('Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'ultimate-store-kit'),
118 + 'label' => __('Tags', 'ultimate-store-kit'),
108 119 'type' => Dynamic_Select::TYPE,
109 120 'multiple' => true,
110 121 'label_block' => true,
111 - 'placeholder' => __('Type and select terms', 'ultimate-store-kit'),
112 122 'query_args' => [
113 - 'query' => 'terms',
114 - 'widget_props' => [
115 - 'post_type' => 'product_source'
116 - ]
123 + 'query' => 'product_tag',
117 124 ],
118 125 'condition' => [
119 - 'product_include_by' => 'terms',
120 - 'product_source!' => ['manual_selection', 'current_query', '_related_post_type'],
126 + 'product_include_by' => 'tags',
127 + 'product_source!' => ['manual_selection'],
121 128 ]
122 129 ]
123 130 );
124 131
132 + $this->add_control(
133 + 'product_include_brand_ids',
134 + [
135 + 'label' => __('Brands', 'ultimate-store-kit'),
136 + 'type' => Dynamic_Select::TYPE,
137 + 'multiple' => true,
138 + 'label_block' => true,
139 + 'query_args' => [
140 + 'query' => 'product_brand',
141 + ],
142 + 'condition' => [
143 + 'product_include_by' => 'brands',
144 + 'product_source!' => ['manual_selection'],
145 + ]
146 + ]
147 + );
148 +
149 + $this->add_control(
150 + 'product_include_attribute_ids',
151 + [
152 + 'label' => __('Attributes', 'ultimate-store-kit'),
153 + 'type' => Dynamic_Select::TYPE,
154 + 'multiple' => true,
155 + 'label_block' => true,
156 + 'query_args' => [
157 + 'query' => 'product_attributes',
158 + ],
159 + 'condition' => [
160 + 'product_include_by' => 'attributes',
161 + 'product_source!' => ['manual_selection'],
162 + ]
163 + ]
164 + );
165 +
166 + $this->add_control(
167 + 'product_include_date',
168 + [
169 + 'label' => __('Date', 'ultimate-store-kit'),
170 + 'type' => Controls_Manager::SELECT,
171 + 'default' => 'anytime',
172 + 'options' => [
173 + 'anytime' => __('All', 'ultimate-store-kit'),
174 + 'today' => __('Past Day', 'ultimate-store-kit'),
175 + 'week' => __('Past Week', 'ultimate-store-kit'),
176 + 'month' => __('Past Month', 'ultimate-store-kit'),
177 + 'quarter' => __('Past Quarter', 'ultimate-store-kit'),
178 + 'year' => __('Past Year', 'ultimate-store-kit'),
179 + 'exact' => __('Custom', 'ultimate-store-kit'),
180 + ],
181 + 'condition' => [
182 + 'product_source!' => 'manual_selection',
183 + 'product_include_by' => 'date',
184 + ]
185 + ]
186 + );
187 +
188 + $this->add_control(
189 + 'product_date_before',
190 + [
191 + 'label' => __('Before', 'ultimate-store-kit'),
192 + 'type' => Controls_Manager::DATE_TIME,
193 + 'description' => __('Setting a "Before" date will show all the posts published until the chosen date (inclusive).', 'ultimate-store-kit'),
194 + 'condition' => [
195 + 'product_include_date' => 'exact',
196 + 'product_source!' => 'manual_selection',
197 + ]
198 + ]
199 + );
200 +
201 + $this->add_control(
202 + 'product_date_after',
203 + [
204 + 'label' => __('After', 'ultimate-store-kit'),
205 + 'type' => Controls_Manager::DATE_TIME,
206 + 'description' => __('Setting an "After" date will show all the posts published since the chosen date (inclusive).', 'ultimate-store-kit'),
207 + 'condition' => [
208 + 'product_include_date' => 'exact',
209 + 'product_source!' => 'manual_selection',
210 + ]
211 + ]
212 + );
213 +
214 + $this->add_control(
215 + 'product_image_include',
216 + [
217 + 'label' => esc_html__('Product Image', 'ultimate-store-kit'),
218 + 'type' => \Elementor\Controls_Manager::SELECT,
219 + 'default' => '',
220 + 'options' => [
221 + '' => esc_html__('Default', 'ultimate-store-kit'),
222 + 'set' => esc_html__('Set', 'ultimate-store-kit'),
223 + 'not_set' => esc_html__('Not Set', 'ultimate-store-kit'),
224 + ],
225 + 'condition' => [
226 + 'product_include_by' => 'image',
227 + 'product_source!' => ['manual_selection'],
228 + ]
229 + ]
230 + );
231 +
232 + $this->add_control(
233 + 'product_price_include',
234 + [
235 + 'label' => esc_html__('Price', 'ultimate-store-kit'),
236 + 'type' => \Elementor\Controls_Manager::SELECT,
237 + 'default' => '',
238 + 'options' => [
239 + '' => esc_html__('Default', 'ultimate-store-kit'),
240 + 'set' => esc_html__('Set', 'ultimate-store-kit'),
241 + 'not_set' => esc_html__('Not Set', 'ultimate-store-kit'),
242 + ],
243 + 'condition' => [
244 + 'product_include_by' => 'price',
245 + 'product_source!' => ['manual_selection'],
246 + ]
247 + ]
248 + );
249 +
250 + $this->add_control(
251 + 'product_stock_include',
252 + [
253 + 'label' => esc_html__('Stock', 'ultimate-store-kit'),
254 + 'type' => \Elementor\Controls_Manager::SELECT,
255 + 'default' => '',
256 + 'options' => [
257 + '' => esc_html__('Default', 'ultimate-store-kit'),
258 + 'in_stock' => esc_html__('In Stock', 'ultimate-store-kit'),
259 + 'out_of_stock' => esc_html__('Out of Stock', 'ultimate-store-kit'),
260 + ],
261 + 'condition' => [
262 + 'product_include_by' => 'stock',
263 + 'product_source!' => ['manual_selection'],
264 + ]
265 + ]
266 + );
267 +
268 +
125 269 $this->end_controls_tab();
126 270
127 271 $this->start_controls_tab(
128 272 'tab_product_exclude',
@@ -141,15 +285,20 @@
141 285 'type' => Controls_Manager::SELECT2,
142 286 'multiple' => true,
143 287 'label_block' => true,
144 288 'options' => [
145 - 'authors' => __('Authors', 'ultimate-store-kit'),
146 - 'current_post' => __('Current Post', 'ultimate-store-kit'),
289 + 'categories' => __('Categories', 'ultimate-store-kit'),
290 + 'tags' => __('Tags', 'ultimate-store-kit'),
291 + 'brands' => __('Brands', 'ultimate-store-kit'),
292 + 'attributes' => __('Attributes', 'ultimate-store-kit'),
147 293 'manual_selection' => __('Manual Selection', 'ultimate-store-kit'),
148 - 'terms' => __('Terms', 'ultimate-store-kit'),
294 + 'date' => __('Date', 'ultimate-store-kit'),
295 + 'image' => __('Product Image', 'ultimate-store-kit'),
296 + 'price' => __('Price', 'ultimate-store-kit'),
297 + 'stock' => __('Stock', 'ultimate-store-kit'),
149 298 ],
150 299 'condition' => [
151 - 'product_source!' => ['manual_selection', 'current_query'],
300 + 'product_source!' => ['manual_selection'],
152 301 ]
153 302 ]
154 303 );
155 304
@@ -161,14 +310,12 @@
161 310 'multiple' => true,
162 311 'label_block' => true,
163 312 'query_args' => [
164 313 'query' => 'posts',
165 - 'widget_props' => [
166 - 'post_type' => 'product_source'
167 - ]
314 + 'post_type' => 'product',
168 315 ],
169 316 'condition' => [
170 - 'product_source!' => ['manual_selection', 'current_query'],
317 + 'product_source!' => ['manual_selection'],
171 318 'product_exclude_by' => 'manual_selection',
172 319 ]
173 320 ]
174 321 );
@@ -173,61 +320,75 @@
173 320 ]
174 321 );
175 322
176 323 $this->add_control(
177 - 'product_exclude_author_ids',
324 + 'product_exclude_category_ids',
178 325 [
179 - 'label' => __('Authors', 'ultimate-store-kit'),
326 + 'label' => __('Categories', 'ultimate-store-kit'),
180 327 'type' => Dynamic_Select::TYPE,
181 328 'multiple' => true,
182 329 'label_block' => true,
183 330 'query_args' => [
184 - 'query' => 'authors',
331 + 'query' => 'product_cat',
185 332 ],
186 333 'condition' => [
187 - 'product_exclude_by' => 'authors',
188 - 'product_source!' => ['manual_selection', 'current_query'],
334 + 'product_exclude_by' => 'categories',
335 + 'product_source!' => ['manual_selection'],
189 336 ]
190 337 ]
191 338 );
192 -
193 339 $this->add_control(
194 - 'product_exclude_term_ids',
340 + 'product_exclude_tag_ids',
195 341 [
196 - 'label' => __('Terms', 'ultimate-store-kit'),
197 - 'description' => __('Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'ultimate-store-kit'),
342 + 'label' => __('Tags', 'ultimate-store-kit'),
198 343 'type' => Dynamic_Select::TYPE,
199 344 'multiple' => true,
200 345 'label_block' => true,
201 - 'placeholder' => __('Type and select terms', 'ultimate-store-kit'),
202 346 'query_args' => [
203 - 'query' => 'terms',
204 - 'widget_props' => [
205 - 'post_type' => 'product_source'
206 - ]
347 + 'query' => 'product_tag',
207 348 ],
208 349 'condition' => [
209 - 'product_exclude_by' => 'terms',
210 - 'product_source!' => ['manual_selection', 'current_query', '_related_post_type'],
350 + 'product_exclude_by' => 'tags',
351 + 'product_source!' => ['manual_selection'],
211 352 ]
212 353 ]
213 354 );
214 -
215 - $this->end_controls_tab();
216 - $this->end_controls_tabs();
217 -
218 355 $this->add_control(
219 - 'product_divider',
356 + 'product_exclude_brand_ids',
220 357 [
221 - 'type' => Controls_Manager::DIVIDER,
222 - 'condition' => [
223 - 'product_source!' => 'current_query',
358 + 'label' => __('Brands', 'ultimate-store-kit'),
359 + 'type' => Dynamic_Select::TYPE,
360 + 'multiple' => true,
361 + 'label_block' => true,
362 + 'query_args' => [
363 + 'query' => 'product_brand',
364 + ],
365 + 'condition' => [
366 + 'product_exclude_by' => 'brands',
367 + 'product_source!' => ['manual_selection'],
224 368 ]
225 369 ]
226 370 );
227 371 $this->add_control(
228 - 'product_select_date',
372 + 'product_exclude_attribute_ids',
229 373 [
374 + 'label' => __('Attributes', 'ultimate-store-kit'),
375 + 'type' => Dynamic_Select::TYPE,
376 + 'multiple' => true,
377 + 'label_block' => true,
378 + 'query_args' => [
379 + 'query' => 'product_attributes',
380 + ],
381 + 'condition' => [
382 + 'product_exclude_by' => 'attributes',
383 + 'product_source!' => ['manual_selection'],
384 + ]
385 + ]
386 + );
387 +
388 + $this->add_control(
389 + 'product_exclude_date',
390 + [
230 391 'label' => __('Date', 'ultimate-store-kit'),
231 392 'type' => Controls_Manager::SELECT,
232 393 'default' => 'anytime',
233 394 'options' => [
@@ -239,117 +400,171 @@
239 400 'year' => __('Past Year', 'ultimate-store-kit'),
240 401 'exact' => __('Custom', 'ultimate-store-kit'),
241 402 ],
242 403 'condition' => [
243 - 'product_source!' => 'current_query',
404 + 'product_exclude_by' => 'date',
405 + 'product_source!' => ['manual_selection'],
244 406 ]
245 407 ]
246 408 );
247 409
248 410 $this->add_control(
249 - 'product_date_before',
411 + 'product_exclude_date_before',
250 412 [
251 413 'label' => __('Before', 'ultimate-store-kit'),
252 414 'type' => Controls_Manager::DATE_TIME,
253 - 'description' => __('Setting a ‘Before’ date will show all the posts published until the chosen date (inclusive).', 'ultimate-store-kit'),
415 + 'description' => __('Show all posts published until the chosen date (inclusive).', 'ultimate-store-kit'),
254 416 'condition' => [
255 - 'product_select_date' => 'exact',
256 - 'product_source!' => 'current_query',
417 + 'product_exclude_date' => 'exact',
418 + 'product_source!' => ['manual_selection'],
257 419 ]
258 420 ]
259 421 );
260 422
261 423 $this->add_control(
262 - 'product_date_after',
424 + 'product_exclude_date_after',
263 425 [
264 426 'label' => __('After', 'ultimate-store-kit'),
265 427 'type' => Controls_Manager::DATE_TIME,
266 - 'description' => __('Setting an ‘After’ date will show all the posts published since the chosen date (inclusive).', 'ultimate-store-kit'),
428 + 'description' => __('Show all posts published since the chosen date (inclusive).', 'ultimate-store-kit'),
267 429 'condition' => [
268 - 'product_select_date' => 'exact',
269 - 'product_source!' => 'current_query',
430 + 'product_exclude_date' => 'exact',
431 + 'product_source!' => ['manual_selection'],
270 432 ]
271 433 ]
272 434 );
273 435
274 436 $this->add_control(
275 - 'product_orderby',
437 + 'product_image_exclude',
276 438 [
277 - 'label' => __('Order By', 'bdthemes-prime-slider'),
278 - 'type' => Controls_Manager::SELECT,
279 - 'default' => 'date',
280 - 'options' => [
281 - 'title' => __('Title', 'bdthemes-prime-slider'),
282 - 'ID' => __('ID', 'bdthemes-prime-slider'),
283 - 'date' => __('Date', 'bdthemes-prime-slider'),
284 - 'author' => __('Author', 'bdthemes-prime-slider'),
285 - 'comment_count' => __('Comment Count', 'bdthemes-prime-slider'),
286 - 'menu_order' => __('Menu Order', 'bdthemes-prime-slider'),
287 - 'rand' => __('Random', 'bdthemes-prime-slider'),
288 - 'price' => __('Price', 'bdthemes-prime-slider'),
289 - 'sales' => __('Sales', 'bdthemes-prime-slider'),
439 + 'label' => esc_html__('Product Image', 'ultimate-store-kit'),
440 + 'type' => \Elementor\Controls_Manager::SELECT,
441 + 'default' => '',
442 + 'options' => [
443 + '' => esc_html__('Default', 'ultimate-store-kit'),
444 + 'set' => esc_html__('Set', 'ultimate-store-kit'),
445 + 'not_set' => esc_html__('Not Set', 'ultimate-store-kit'),
446 + ],
447 + 'condition' => [
448 + 'product_exclude_by' => 'image',
449 + 'product_source!' => ['manual_selection'],
290 450 ]
291 451 ]
292 452 );
453 +
293 454 $this->add_control(
294 - 'product_order',
455 + 'product_price_exclude',
295 456 [
296 - 'label' => __('Order', 'ultimate-store-kit'),
297 - 'type' => Controls_Manager::SELECT,
298 - 'default' => 'desc',
299 - 'options' => [
300 - 'asc' => __('ASC', 'ultimate-store-kit'),
301 - 'desc' => __('DESC', 'ultimate-store-kit'),
457 + 'label' => esc_html__('Price', 'ultimate-store-kit'),
458 + 'type' => \Elementor\Controls_Manager::SELECT,
459 + 'default' => '',
460 + 'options' => [
461 + '' => esc_html__('Default', 'ultimate-store-kit'),
462 + 'set' => esc_html__('Set', 'ultimate-store-kit'),
463 + 'not_set' => esc_html__('Not Set', 'ultimate-store-kit'),
302 464 ],
303 465 'condition' => [
304 - 'product_source!' => 'current_query',
466 + 'product_exclude_by' => 'price',
467 + 'product_source!' => ['manual_selection'],
305 468 ]
306 469 ]
307 470 );
308 - // Others Features
309 - }
310 471
311 - public function register_controls_wc_additional() {
312 472 $this->add_control(
313 - 'product_show_only',
473 + 'product_stock_exclude',
314 474 [
315 - 'label' => esc_html__('Show Product', 'bdthemes-element-pack'),
316 - 'type' => Controls_Manager::SELECT,
317 - 'default' => 'all',
475 + 'label' => esc_html__('Stock', 'ultimate-store-kit'),
476 + 'type' => \Elementor\Controls_Manager::SELECT,
477 + 'default' => '',
318 478 'options' => [
319 - 'all' => esc_html__('All Products', 'bdthemes-element-pack'),
320 - 'onsale' => esc_html__('On Sale', 'bdthemes-element-pack'),
321 - 'featured' => esc_html__('Featured', 'bdthemes-element-pack'),
479 + '' => esc_html__('Default', 'ultimate-store-kit'),
480 + 'in_stock' => esc_html__('In Stock', 'ultimate-store-kit'),
481 + 'out_of_stock' => esc_html__('Out of Stock', 'ultimate-store-kit'),
482 + ],
483 + 'condition' => [
484 + 'product_exclude_by' => 'stock',
485 + 'product_source!' => ['manual_selection'],
322 486 ]
323 487 ]
324 488 );
489 +
325 490 $this->add_control(
326 - 'product_hide_free',
491 + 'product_exclude_term_ids',
327 492 [
328 - 'label' => esc_html__('Hide Free Product', 'ultimate-store-kit'),
329 - 'type' => Controls_Manager::SWITCHER,
493 + 'label' => __('Terms', 'ultimate-store-kit'),
494 + 'description' => __('Terms are items in a taxonomy. The available taxonomies are: Categories, Tags, Formats and custom taxonomies.', 'ultimate-store-kit'),
495 + 'type' => Dynamic_Select::TYPE,
496 + 'multiple' => true,
497 + 'label_block' => true,
498 + 'placeholder' => __('Type and select terms', 'ultimate-store-kit'),
499 + 'query_args' => [
500 + 'query' => 'terms',
501 + 'widget_props' => [
502 + 'post_type' => 'product_source'
503 + ]
504 + ],
505 + 'condition' => [
506 + 'product_exclude_by' => 'terms',
507 + 'product_source!' => ['manual_selection'],
508 + ]
509 + ]
510 + );
330 511
512 + $this->end_controls_tab();
513 + $this->end_controls_tabs();
514 +
515 + $this->add_control(
516 + 'product_divider',
517 + [
518 + 'type' => Controls_Manager::DIVIDER,
519 + 'condition' => [
520 + 'product_source!' => 'current_query',
521 + ]
331 522 ]
332 523 );
524 +
333 525 $this->add_control(
334 - 'product_hide_out_stock',
526 + 'product_orderby',
335 527 [
336 - 'label' => esc_html__('Hide Out of Stock', 'ultimate-store-kit'),
337 - 'type' => Controls_Manager::SWITCHER,
528 + 'label' => __('Order By', 'ultimate-store-kit'),
529 + 'type' => Controls_Manager::SELECT,
530 + 'default' => 'date',
531 + 'options' => [
532 + 'title' => __('Title', 'ultimate-store-kit'),
533 + 'ID' => __('ID', 'ultimate-store-kit'),
534 + 'date' => __('Date', 'ultimate-store-kit'),
535 + 'author' => __('Author', 'ultimate-store-kit'),
536 + 'comment_count' => __('Comment Count', 'ultimate-store-kit'),
537 + 'menu_order' => __('Menu Order', 'ultimate-store-kit'),
538 + 'modified' => __('Modified', 'ultimate-store-kit'),
539 + 'rand' => __('Random', 'ultimate-store-kit'),
540 + 'price' => __('Price', 'ultimate-store-kit'),
541 + 'sales' => __('Sales', 'ultimate-store-kit'),
542 + ],
543 + 'condition' => [
544 + 'product_source!' => ['current_query'],
545 + ]
338 546 ]
339 547 );
340 548 $this->add_control(
341 - 'product_only_with_featured_image',
549 + 'product_order',
342 550 [
343 - 'label' => __('Only Featured Image Post', 'ultimate-store-kit'),
344 - 'description' => __('Enable to display posts only when featured image is present.', 'ultimate-store-kit'),
345 - 'type' => Controls_Manager::SWITCHER,
346 - 'return_value' => 'yes',
347 - 'condition' => [
348 - 'product_source!' => 'current_query',
551 + 'label' => __('Order', 'ultimate-store-kit'),
552 + 'type' => Controls_Manager::SELECT,
553 + 'default' => 'desc',
554 + 'options' => [
555 + 'asc' => __('ASC', 'ultimate-store-kit'),
556 + 'desc' => __('DESC', 'ultimate-store-kit'),
557 + ],
558 + 'condition' => [
559 + 'product_source!' => 'current_query',
349 560 ]
350 561 ]
351 562 );
563 + }
564 +
565 + public function register_controls_wc_additional()
566 + {
352 567 $this->add_control(
353 568 'query_id',
354 569 [
355 570 'label' => __('Query ID', 'ultimate-store-kit'),
@@ -355,300 +570,402 @@
355 570 'label' => __('Query ID', 'ultimate-store-kit'),
356 571 'description' => __('Give your Query a custom unique id to allow server side filtering', 'ultimate-store-kit'),
357 572 'type' => Controls_Manager::TEXT,
358 573 'separator' => 'before',
574 + 'dynamic' => [ 'active' => true ],
359 575 ]
360 576 );
361 577 }
362 578
363 - private function setMetaQueryArgs() {
579 + /**
580 + * @return array|string[]|\WP_Post_Type[]
581 + */
582 + private function getGroupControlQueryPostTypes()
583 + {
364 584
365 - $args = [];
585 + $post_types = [
586 + 'product' => __('Product', 'ultimate-store-kit'),
587 + 'sale' => __('On Sale', 'ultimate-store-kit'),
588 + 'featured' => __('Featured', 'ultimate-store-kit'),
589 + 'manual_selection' => __('Manual Selection', 'ultimate-store-kit'),
590 + 'current_query' => __('Current Query', 'ultimate-store-kit'),
591 + ];
366 592
367 - if ('current_query' === $this->getGroupControlQueryPostType()) {
368 - return [];
593 + return $post_types;
594 + }
595 +
596 + public function pre_get_posts_query_filter($wp_query)
597 + {
598 + if ($this) {
599 + $query_id = $this->get_settings('query_id');
600 + do_action("ultimate_store_kit/query/{$query_id}", $wp_query, $this);
369 601 }
370 - $args['paged'] = max(1, get_query_var('paged'), get_query_var('page'));
371 - $args['posts_per_page'] = $this->get_settings('product_limit');
372 - $args['order'] = $this->get_settings('product_order');
373 - // $args['orderby'] = $this->get_settings('product_orderby');
602 + }
374 603
375 - if ('product' === $this->getGroupControlQueryPostType()) {
376 - $product_visibility_term_ids = wc_get_product_visibility_term_ids();
377 - if ('yes' == $this->get_settings('product_hide_free')) {
378 - $args['meta_query'][] = [
379 - 'key' => '_price',
380 - 'value' => 0,
381 - 'compare' => '>',
382 - 'type' => 'DECIMAL',
604 + private function get_product_source_args($source)
605 + {
606 + $args = [];
607 +
608 + switch ($source) {
609 + case 'sale':
610 + $args['meta_query'] = [
611 + [
612 + 'key' => '_sale_price',
613 + 'value' => 0,
614 + 'compare' => '>',
615 + ],
383 616 ];
384 - }
385 -
386 - if ('yes' == $this->get_settings('product_hide_out_stock')) {
387 - $args['tax_query'][] = [
617 + break;
618 + case 'featured':
619 + $args['tax_query'] = [
388 620 [
389 621 'taxonomy' => 'product_visibility',
390 - 'field' => 'term_taxonomy_id',
391 - 'terms' => $product_visibility_term_ids['outofstock'],
392 - 'operator' => 'NOT IN',
622 + 'field' => 'name',
623 + 'terms' => 'featured',
624 + 'operator' => 'IN',
393 625 ],
394 - ]; // WPCS: slow query ok.
395 - }
396 - switch ($this->get_settings('product_show_only')) {
397 - case 'featured':
398 - $args['tax_query'][] = [
399 - 'taxonomy' => 'product_visibility',
400 - 'field' => 'term_taxonomy_id',
401 - 'terms' => $product_visibility_term_ids['featured'],
402 - ];
403 - break;
404 - case 'onsale':
405 - $product_ids_on_sale = wc_get_product_ids_on_sale();
406 - $product_ids_on_sale[] = 0;
407 - $args['post__in'] = $product_ids_on_sale;
408 - break;
409 - }
410 - switch ($this->get_settings('product_orderby')) {
411 - case 'price':
412 - $args['meta_key'] = '_price'; // WPCS: slow query ok.
413 - $args['orderby'] = 'meta_value_num';
414 - break;
415 - case 'sales':
416 - $args['meta_key'] = 'total_sales'; // WPCS: slow query ok.
417 - $args['orderby'] = 'meta_value_num';
418 - break;
419 - default:
420 - $args['orderby'] = $this->get_settings('product_orderby');
421 - }
626 + ];
627 + break;
628 + case 'manual_selection':
629 + $selected_ids = $this->get_settings('product_selected_ids');
630 + if (!empty($selected_ids)) {
631 + $args['post__in'] = $selected_ids;
632 + }
633 + break;
422 634 }
423 635
636 + return $args;
637 + }
424 638
639 + /**
640 + * Apply "Include By" logic to WP_Query args.
641 + */
642 + private function apply_include_by_args($args, $settings)
643 + {
644 + $include_by = $settings['product_include_by'] ?? [];
425 645
426 - /**
427 - * Set Feature Images
428 - */
429 - if ($this->get_settings('product_only_with_featured_image') === 'yes') {
430 - $args['meta_key'] = '_thumbnail_id';
646 + if (!is_array($include_by)) {
647 + $include_by = [$include_by];
431 648 }
432 649
433 - /**
434 - * Set Date
435 - */
650 + // Categories
651 + if (in_array('categories', $include_by) && !empty($settings['product_include_category_ids'])) {
652 + $args['tax_query'][] = [
653 + 'taxonomy' => 'product_cat',
654 + 'field' => 'term_id',
655 + 'terms' => $settings['product_include_category_ids'],
656 + 'operator' => 'IN',
657 + ];
658 + }
436 659
437 - $selected_date = $this->get_settings('product_select_date');
660 + // Tags
661 + if (in_array('tags', $include_by) && !empty($settings['product_include_tag_ids'])) {
662 + $args['tax_query'][] = [
663 + 'taxonomy' => 'product_tag',
664 + 'field' => 'term_id',
665 + 'terms' => $settings['product_include_tag_ids'],
666 + 'operator' => 'IN',
667 + ];
668 + }
438 669
439 - if (!empty($selected_date)) {
670 + // Brands
671 + if (in_array('brands', $include_by) && !empty($settings['product_include_brand_ids'])) {
672 + $args['tax_query'][] = [
673 + 'taxonomy' => 'product_brand',
674 + 'field' => 'term_id',
675 + 'terms' => $settings['product_include_brand_ids'],
676 + 'operator' => 'IN',
677 + ];
678 + }
679 +
680 + // Attributes
681 + if (in_array('attributes', $include_by) && !empty($settings['product_include_attribute_ids'])) {
682 + $args['tax_query'][] = [
683 + 'taxonomy' => 'product_attributes',
684 + 'field' => 'term_id',
685 + 'terms' => $settings['product_include_attribute_ids'],
686 + 'operator' => 'IN',
687 + ];
688 + }
689 +
690 + // Date
691 + if (in_array('date', $include_by) && !empty($settings['product_include_date'])) {
440 692 $date_query = [];
441 -
442 - switch ($selected_date) {
693 + switch ($settings['product_include_date']) {
443 694 case 'today':
444 - $date_query['after'] = '-1 day';
695 + $date_query['after'] = '1 day ago';
445 696 break;
446 -
447 697 case 'week':
448 - $date_query['after'] = '-1 week';
698 + $date_query['after'] = '1 week ago';
449 699 break;
450 -
451 700 case 'month':
452 - $date_query['after'] = '-1 month';
701 + $date_query['after'] = '1 month ago';
453 702 break;
454 -
455 703 case 'quarter':
456 - $date_query['after'] = '-3 month';
704 + $date_query['after'] = '3 months ago';
457 705 break;
458 -
459 706 case 'year':
460 - $date_query['after'] = '-1 year';
707 + $date_query['after'] = '1 year ago';
461 708 break;
462 -
463 709 case 'exact':
464 - $after_date = $this->get_settings('product_date_after');
465 - if (!empty($after_date)) {
466 - $date_query['after'] = $after_date;
710 + if (!empty($settings['product_date_after'])) {
711 + $date_query['after'] = $settings['product_date_after'];
467 712 }
468 -
469 - $before_date = $this->get_settings('product_date_before');
470 - if (!empty($before_date)) {
471 - $date_query['before'] = $before_date;
713 + if (!empty($settings['product_date_before'])) {
714 + $date_query['before'] = $settings['product_date_before'];
472 715 }
473 -
474 716 $date_query['inclusive'] = true;
475 717 break;
476 718 }
477 -
478 719 if (!empty($date_query)) {
479 - $args['date_query'] = $date_query;
720 + $args['date_query'][] = $date_query;
480 721 }
481 722 }
482 723
483 - return $args;
484 - }
724 + // Product Image
725 + if (in_array('image', $include_by) && isset($settings['product_image_include']) && $settings['product_image_include'] !== '') {
726 + if ($settings['product_image_include'] === 'set') {
727 + $args['meta_query'][] = [
728 + 'key' => '_thumbnail_id',
729 + 'compare' => 'EXISTS',
730 + ];
731 + } elseif ($settings['product_image_include'] === 'not_set') {
732 + $args['meta_query'][] = [
733 + 'key' => '_thumbnail_id',
734 + 'compare' => 'NOT EXISTS',
735 + ];
736 + }
737 + }
485 738
486 - protected function getGroupControlQueryArgs() {
739 + // Price
740 + if (in_array('price', $include_by) && isset($settings['product_price_include']) && $settings['product_price_include'] !== '') {
741 + if ($settings['product_price_include'] === 'set') {
742 + $args['meta_query'][] = [
743 + 'key' => '_price',
744 + 'compare' => 'EXISTS',
745 + ];
746 + } elseif ($settings['product_price_include'] === 'not_set') {
747 + $args['meta_query'][] = [
748 + 'key' => '_price',
749 + 'compare' => 'NOT EXISTS',
750 + ];
751 + }
752 + }
487 753
488 - $settings = $this->get_settings();
489 - $args = $this->setMetaQueryArgs();
490 - $args['post_status'] = 'publish';
491 - $args['suppress_filters'] = false;
492 - $exclude_by = $this->getGroupControlQueryParamBy('exclude');
754 + // Stock
755 + if (in_array('stock', $include_by) && isset($settings['product_stock_include']) && $settings['product_stock_include'] !== '') {
756 + if ($settings['product_stock_include'] === 'in_stock') {
757 + $args['meta_query'][] = [
758 + 'key' => '_stock_status',
759 + 'value' => 'instock',
760 + 'compare' => '=',
761 + ];
762 + } elseif ($settings['product_stock_include'] === 'out_of_stock') {
763 + $args['meta_query'][] = [
764 + 'key' => '_stock_status',
765 + 'value' => 'outofstock',
766 + 'compare' => '=',
767 + ];
768 + }
769 + }
493 770
494 - // /**
495 - // * Set Ignore Sticky
496 - // */
497 - // if (
498 - // $this->getGroupControlQueryPostType() === 'post'
499 - // && $this->get_settings('posts_ignore_sticky_posts') === 'yes'
500 - // ) {
501 - // $args['ignore_sticky_posts'] = true;
771 + return $args;
772 + }
502 773
503 - // if (in_array('current_post', $exclude_by)) {
504 - // $args['post__not_in'] = [get_the_ID()];
505 - // }
506 - // }
774 + /**
775 + * Apply "Exclude By" logic to WP_Query args.
776 + */
777 + private function apply_exclude_by_args($args, $settings)
778 + {
779 + $exclude_by = $settings['product_exclude_by'] ?? [];
507 780
781 + if (!is_array($exclude_by)) {
782 + $exclude_by = [$exclude_by];
783 + }
508 784
509 - if ($this->getGroupControlQueryPostType() === 'manual_selection') {
510 - /**
511 - * Set Including Manually
512 - */
513 - $selected_ids = $this->get_settings('product_selected_ids');
514 - $selected_ids = wp_parse_id_list($selected_ids);
515 - $args['post_type'] = 'product';
516 - if (!empty($selected_ids)) {
517 - $args['post__in'] = $selected_ids;
518 - }
519 - $args['ignore_sticky_posts'] = 1;
520 - } elseif ('current_query' === $this->getGroupControlQueryPostType()) {
521 - /**
522 - * Make Current Query
523 - */
524 - $args = $GLOBALS['wp_query']->query_vars;
525 - $args['paged'] = 1;
526 - $args = apply_filters('ultimate_store_kit/query/get_query_args/current_query', $args);
527 - } elseif ('_related_post_type' === $this->getGroupControlQueryPostType()) {
528 - /**
529 - * Set Related Query
530 - */
531 - $post_id = get_queried_object_id();
532 - $related_post_id = is_singular() && (0 !== $post_id) ? $post_id : null;
533 - $args['post_type'] = get_post_type($related_post_id);
785 + // Categories
786 + if (in_array('categories', $exclude_by) && !empty($settings['product_exclude_category_ids'])) {
787 + $args['tax_query'][] = [
788 + 'taxonomy' => 'product_cat',
789 + 'field' => 'term_id',
790 + 'terms' => $settings['product_exclude_category_ids'],
791 + 'operator' => 'NOT IN',
792 + ];
793 + }
534 794
535 - $include_by = $this->getGroupControlQueryParamBy('include');
536 - if (in_array('authors', $include_by)) {
537 - $args['author__in'] = wp_parse_id_list($settings['product_include_author_ids']);
538 - } else {
539 - $args['author__in'] = get_post_field('post_author', $related_post_id);
540 - }
795 + // Tags
796 + if (in_array('tags', $exclude_by) && !empty($settings['product_exclude_tag_ids'])) {
797 + $args['tax_query'][] = [
798 + 'taxonomy' => 'product_tag',
799 + 'field' => 'term_id',
800 + 'terms' => $settings['product_exclude_tag_ids'],
801 + 'operator' => 'NOT IN',
802 + ];
803 + }
541 804
542 - $exclude_by = $this->getGroupControlQueryParamBy('exclude');
543 - if (in_array('authors', $exclude_by)) {
544 - $args['author__not_in'] = wp_parse_id_list($settings['product_exclude_author_ids']);
545 - }
805 + // Brands
806 + if (in_array('brands', $exclude_by) && !empty($settings['product_exclude_brand_ids'])) {
807 + $args['tax_query'][] = [
808 + 'taxonomy' => 'product_brand',
809 + 'field' => 'term_id',
810 + 'terms' => $settings['product_exclude_brand_ids'],
811 + 'operator' => 'NOT IN',
812 + ];
813 + }
546 814
547 - if (in_array('current_post', $exclude_by)) {
548 - $args['post__not_in'] = [get_the_ID()];
549 - }
815 + // Attributes
816 + if (in_array('attributes', $exclude_by) && !empty($settings['product_exclude_attribute_ids'])) {
817 + $args['tax_query'][] = [
818 + 'taxonomy' => 'product_attributes',
819 + 'field' => 'term_id',
820 + 'terms' => $settings['product_exclude_attribute_ids'],
821 + 'operator' => 'NOT IN',
822 + ];
823 + }
550 824
551 - $args['ignore_sticky_posts'] = 1;
552 - $args = apply_filters('ultimate_store_kit/query/get_query_args/related_query', $args);
553 - } else {
825 + // Manual Selection
826 + if (in_array('manual_selection', $exclude_by) && !empty($settings['posts_exclude_ids'])) {
827 + $args['post__not_in'] = $settings['posts_exclude_ids'];
828 + }
554 829
555 - /**
556 - * Set Post Type
557 - */
558 - $args['post_type'] = $this->getGroupControlQueryPostType();
559 -
560 - /**
561 - * Set Exclude Post
562 - */
563 - $exclude_by = $this->getGroupControlQueryParamBy('exclude');
564 - $current_post = [];
565 -
566 - if (in_array('current_post', $exclude_by) && is_singular()) {
567 - $current_post = [get_the_ID()];
830 + // Date
831 + if (in_array('date', $exclude_by) && !empty($settings['product_exclude_date'])) {
832 + $date_query = [];
833 + switch ($settings['product_exclude_date']) {
834 + case 'today':
835 + $date_query['before'] = '1 day ago';
836 + break;
837 + case 'week':
838 + $date_query['before'] = '1 week ago';
839 + break;
840 + case 'month':
841 + $date_query['before'] = '1 month ago';
842 + break;
843 + case 'quarter':
844 + $date_query['before'] = '3 months ago';
845 + break;
846 + case 'year':
847 + $date_query['before'] = '1 year ago';
848 + break;
849 + case 'exact':
850 + if (!empty($settings['product_exclude_date_after'])) {
851 + $date_query['after'] = $settings['product_exclude_date_after'];
852 + }
853 + if (!empty($settings['product_exclude_date_before'])) {
854 + $date_query['before'] = $settings['product_exclude_date_before'];
855 + }
856 + $date_query['inclusive'] = true;
857 + break;
568 858 }
569 -
570 - if (in_array('manual_selection', $exclude_by)) {
571 - $exclude_ids = $settings['posts_exclude_ids'];
572 - $args['post__not_in'] = array_merge($current_post, wp_parse_id_list($exclude_ids));
859 + if (!empty($date_query)) {
860 + $args['date_query'][] = $date_query;
573 861 }
574 - /**
575 - * Set Authors
576 - */
577 - $include_by = $this->getGroupControlQueryParamBy('include');
578 - $exclude_by = $this->getGroupControlQueryParamBy('exclude');
579 - $include_users = [];
580 - $exclude_users = [];
862 + }
581 863
582 - if (in_array('authors', $include_by)) {
583 - $include_users = wp_parse_id_list($settings['product_include_author_ids']);
864 + // Product Image
865 + if (in_array('image', $exclude_by) && isset($settings['product_image_exclude']) && $settings['product_image_exclude'] !== '') {
866 + if ($settings['product_image_exclude'] === 'set') {
867 + $args['meta_query'][] = [
868 + 'key' => '_thumbnail_id',
869 + 'compare' => 'NOT EXISTS',
870 + ];
871 + } elseif ($settings['product_image_exclude'] === 'not_set') {
872 + $args['meta_query'][] = [
873 + 'key' => '_thumbnail_id',
874 + 'compare' => 'EXISTS',
875 + ];
584 876 }
877 + }
585 878
586 - if (in_array('authors', $exclude_by)) {
587 - $exclude_users = wp_parse_id_list($settings['product_exclude_author_ids']);
588 - $include_users = array_diff($include_users, $exclude_users);
879 + // Price
880 + if (in_array('price', $exclude_by) && isset($settings['product_price_exclude']) && $settings['product_price_exclude'] !== '') {
881 + if ($settings['product_price_exclude'] === 'set') {
882 + $args['meta_query'][] = [
883 + 'key' => '_price',
884 + 'compare' => 'NOT EXISTS',
885 + ];
886 + } elseif ($settings['product_price_exclude'] === 'not_set') {
887 + $args['meta_query'][] = [
888 + 'key' => '_price',
889 + 'compare' => 'EXISTS',
890 + ];
589 891 }
892 + }
590 893
591 - if (!empty($include_users)) {
592 - $args['author__in'] = $include_users;
894 + // Stock
895 + if (in_array('stock', $exclude_by) && isset($settings['product_stock_exclude']) && $settings['product_stock_exclude'] !== '') {
896 + if ($settings['product_stock_exclude'] === 'in_stock') {
897 + $args['meta_query'][] = [
898 + 'key' => '_stock_status',
899 + 'value' => 'instock',
900 + 'compare' => '!=',
901 + ];
902 + } elseif ($settings['product_stock_exclude'] === 'out_of_stock') {
903 + $args['meta_query'][] = [
904 + 'key' => '_stock_status',
905 + 'value' => 'outofstock',
906 + 'compare' => '!=',
907 + ];
593 908 }
909 + }
594 910
595 - if (!empty($exclude_users)) {
596 - $args['author__not_in'] = $exclude_users;;
597 - }
911 + return $args;
912 + }
598 913
599 - /**
600 - * Set Taxonomy
601 - */
602 - $include_by = $this->getGroupControlQueryParamBy('include');
603 - $exclude_by = $this->getGroupControlQueryParamBy('exclude');
604 - $include_terms = [];
605 - $exclude_terms = [];
606 - $terms_query = [];
914 + protected function getGroupControlQueryArgs()
915 + {
916 + $settings = $this->get_settings();
917 + $source = $settings['product_source'] ?? 'product';
918 +
919 + // If current_query is selected, return special flag
920 + if ($source === 'current_query') {
921 + return ['__use_global_query' => true];
922 + }
923 +
924 + $page = max(1, get_query_var('paged'), get_query_var('page'));
925 + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Pagination number off a public archive URL; cast to int and used only to page a query.
926 + $page = absint(empty($_GET['product-page']) ? $page : $_GET['product-page']);
927 + $paged = absint($page);
607 928
608 - if (in_array('terms', $include_by)) {
609 - $include_terms = wp_parse_id_list($settings['product_include_term_ids']);
610 - }
929 + $args = [
930 + 'post_type' => 'product',
931 + 'paged' => $paged
932 + ];
611 933
612 - if (in_array('terms', $exclude_by)) {
613 - $exclude_terms = wp_parse_id_list($settings['product_exclude_term_ids']);
614 - $include_terms = array_diff($include_terms, $exclude_terms);
615 - }
934 + if (!empty($settings['product_limit'])) {
935 + $args['posts_per_page'] = $settings['product_limit'];
936 + }
616 937
617 - if (!empty($include_terms)) {
618 - $tax_terms_map = $this->mapGroupControlQuery($include_terms);
938 + $args = $args + $this->get_product_source_args($source);
619 939
620 - foreach ($tax_terms_map as $tax => $terms) {
621 - $terms_query[] = [
622 - 'taxonomy' => $tax,
623 - 'field' => 'term_id',
624 - 'terms' => $terms,
625 - 'operator' => 'IN',
626 - ];
627 - }
628 - }
940 + // Apply "Include By" logic
941 + $args = $this->apply_include_by_args($args, $settings);
629 942
630 - if (!empty($exclude_terms)) {
631 - $tax_terms_map = $this->mapGroupControlQuery($exclude_terms);
943 + // Apply "Exclude By" logic
944 + $args = $this->apply_exclude_by_args($args, $settings);
632 945
633 - foreach ($tax_terms_map as $tax => $terms) {
634 - $terms_query[] = [
635 - 'taxonomy' => $tax,
636 - 'field' => 'term_id',
637 - 'terms' => $terms,
638 - 'operator' => 'NOT IN',
639 - ];
640 - }
946 + // Apply Order and OrderBy
947 + if (!empty($settings['product_orderby'])) {
948 + switch ($settings['product_orderby']) {
949 + case 'price':
950 + $args['meta_key'] = '_price';
951 + $args['orderby'] = 'meta_value_num';
952 + break;
953 + case 'sales':
954 + $args['meta_key'] = 'total_sales';
955 + $args['orderby'] = 'meta_value_num';
956 + break;
957 + default:
958 + $args['orderby'] = $settings['product_orderby'];
641 959 }
960 + }
642 961
643 - if (!empty($terms_query)) {
644 - $args['tax_query'] = $terms_query;
645 - $args['tax_query']['relation'] = 'AND';
646 - }
962 + if (!empty($settings['product_order'])) {
963 + $args['order'] = $settings['product_order'];
647 964 }
648 965
649 966 $query_id = $this->get_settings('query_id');
650 - if (!empty($query_id)) {
967 + if (! empty($query_id)) {
651 968 add_action('pre_get_posts', [$this, 'pre_get_posts_query_filter']);
652 969 }
653 970
654 971 return $args;
@@ -653,77 +970,49 @@
653 970
654 971 return $args;
655 972 }
656 973
657 -
658 974 /**
659 - * @return mixed
975 + * Get query - returns global query if current_query is selected, otherwise returns custom query
660 976 */
661 - private function getGroupControlQueryPostType() {
662 - return $this->get_settings('product_source');
977 + public function get_query()
978 + {
979 + return $this->_query;
663 980 }
664 981
665 982 /**
666 - * Get Query Params by args
667 - *
668 - * @param string $by
669 - *
670 - * @return array|mixed
983 + * Query products - handles both custom and global queries
984 + * This is a helper method that can be called from widget's query_product() method
671 985 */
672 - private function getGroupControlQueryParamBy($by = 'exclude') {
673 - $mapBy = [
674 - 'exclude' => 'product_exclude_by',
675 - 'include' => 'product_include_by',
676 - ];
677 -
678 - $setting = $this->get_settings($mapBy[$by]);
679 -
680 - return (!empty($setting) ? $setting : []);
681 - }
682 -
683 - /**
684 - * @param array $term_ids
685 - *
686 - * @return array
687 - */
688 - private function mapGroupControlQuery($term_ids = []) {
689 - $terms = get_terms(
690 - [
691 - 'term_taxonomy_id' => $term_ids,
692 - 'hide_empty' => false,
693 - ]
694 - );
695 -
696 - $tax_terms_map = [];
697 -
698 - foreach ($terms as $term) {
699 - $taxonomy = $term->taxonomy;
700 - $tax_terms_map[$taxonomy][] = $term->term_id;
986 + protected function build_query_from_args($query_args)
987 + {
988 + // Check if we should use global query
989 + if (isset($query_args['__use_global_query']) && $query_args['__use_global_query'] === true) {
990 + global $wp_query;
991 +
992 + // Get the product limit setting
993 + $settings = $this->get_settings();
994 + $product_limit = $settings['product_limit'] ?? null;
995 +
996 + // If product limit is set, create a new query based on global query args
997 + if (!empty($product_limit)) {
998 + $args = $wp_query->query_vars;
999 + $args['posts_per_page'] = $product_limit;
1000 + return new \WP_Query($args);
1001 + }
1002 +
1003 + return $wp_query;
1004 + } else {
1005 + return new \WP_Query($query_args);
701 1006 }
702 -
703 - return $tax_terms_map;
704 1007 }
705 1008
706 1009 /**
707 - * @return array|string[]|\WP_Post_Type[]
1010 + * Query products - handles both custom and global queries
1011 + * Default implementation - widgets can override this
708 1012 */
709 - private function getGroupControlQueryPostTypes() {
710 -
711 - $post_types = [
712 - 'product' => __('Product', 'ultimate-store-kit'),
713 - 'manual_selection' => __('Manual Selection', 'ultimate-store-kit'),
714 - 'current_query' => __('Current Query', 'ultimate-store-kit'),
715 - '_related_post_type' => __('Related', 'ultimate-store-kit'),
716 - ];
717 -
718 - // $post_types = array_merge($post_types, $extra_types);
719 -
720 - return $post_types;
721 - }
722 -
723 - public function pre_get_posts_query_filter($wp_query) {
724 - if ($this) {
725 - $query_id = $this->get_settings('query_id');
726 - do_action("ultimate_store_kit/query/{$query_id}", $wp_query, $this);
727 - }
1013 + public function query_product()
1014 + {
1015 + $query_args = $this->getGroupControlQueryArgs();
1016 + $this->_query = $this->build_query_from_args($query_args);
728 1017 }
729 1018 }