PluginProbe
UiCore Elements – Free widgets and templates for Elementor / 1.3.18
UiCore Elements – Free widgets and templates for Elementor v1.3.18
1.3.18 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 All 42 releases
← All changes | includes/widgets/advanced-product-grid.php +350 -141 1.2.1 → 1.3.18 View file →
@@ -37,9 +37,9 @@
37 37 return 'eicon-gallery-grid ui-e-widget';
38 38 }
39 39 public function get_keywords()
40 40 {
41 - return [ 'woocommerce', 'product', 'shop', 'store', 'post', 'grid' ];
41 + return ['woocommerce', 'product', 'shop', 'store', 'post', 'grid'];
42 42 }
43 43 public function get_styles()
44 44 {
45 45 // get parent get_styles
@@ -47,9 +47,9 @@
47 47
48 48 // remove parent AdvancedPostGrid widget main style. OBS: the IDE complains because get_styles doc
49 49 // says it returns obj, but we're extending a widget that returns the array, so the parent
50 50 // is not widget base, but the AdvancedPostGrid widget
51 - if ( ($key = array_search('advanced-post-grid', $styles)) !== false) {
51 + if (($key = array_search('advanced-post-grid', $styles)) !== false) {
52 52 unset($styles[$key]);
53 53 }
54 54
55 55 // Add the product grid style
@@ -56,8 +56,26 @@
56 56 $styles[] = 'advanced-product-grid';
57 57
58 58 return $styles;
59 59 }
60 +
61 + /**
62 + * Makes sure some of our custom controls are present. This should be a
63 + * temporary fix to a problem that do not happens consistently.
64 + */
65 + function custom_controls_verification()
66 + {
67 + // In some contexts, such as theme-builder, our custom controls are not available
68 + // and requiring in register_controls method breaks the widget render in editor
69 + if (! defined('DOING_AJAX') || ! DOING_AJAX) {
70 + if (! class_exists('UiCoreElements\Controls\Post_Filter')) {
71 + require_once UICORE_ELEMENTS_INCLUDES . '/controls/class-post-filter-control.php';
72 + }
73 + if (! class_exists('UiCoreElements\Controls\Product_Filter')) {
74 + require_once UICORE_ELEMENTS_INCLUDES . '/controls/class-product-filter-control.php';
75 + }
76 + }
77 + }
60 78 function get_query()
61 79 {
62 80 return $this->_query;
63 81 }
@@ -63,10 +81,12 @@
63 81 }
64 82
65 83 protected function register_controls()
66 84 {
85 + $this->custom_controls_verification();
86 +
67 87 // Fallback
68 - if( !class_exists('WooCommerce') ) {
88 + if (!class_exists('WooCommerce')) {
69 89 $this->start_controls_section(
70 90 'section_fallback',
71 91 [
72 92 'label' => esc_html__('Content', 'uicore-elements'),
@@ -71,16 +91,16 @@
71 91 [
72 92 'label' => esc_html__('Content', 'uicore-elements'),
73 93 ]
74 94 );
75 - $this->add_control(
76 - 'woocommerce_warning',
77 - [
78 - 'type' => \Elementor\Controls_Manager::ALERT,
79 - 'alert_type' => 'warning',
80 - 'content' => esc_html__('Please enable WooCommerce to use this widget.', 'uicore-elements'),
81 - ]
82 - );
95 + $this->add_control(
96 + 'woocommerce_warning',
97 + [
98 + 'type' => \Elementor\Controls_Manager::ALERT,
99 + 'alert_type' => 'warning',
100 + 'content' => esc_html__('Please enable WooCommerce to use this widget.', 'uicore-elements'),
101 + ]
102 + );
83 103 $this->end_controls_section();
84 104 return;
85 105 }
86 106
@@ -93,135 +113,318 @@
93 113 $this->remove_control('after_title_meta');
94 114 $this->remove_control('bottom_meta');
95 115
96 116 // Register query control with updated options
97 - $this->start_injection( [
98 - 'of' => 'section_post_grid_def',
99 - 'at' => 'after',
100 - ] );
101 - $this->add_group_control(
102 - Product_Filter::get_type(),
103 - [
104 - 'name' => 'product-filter',
105 - 'label' => esc_html__('Products', 'uicore-elements'),
106 - 'description' => esc_html__('Current Query Settings > Reading', 'uicore-elements'),
107 - ]
108 - );
109 - $this->end_injection();
117 + $this->start_injection([
118 + 'of' => 'section_post_grid_def',
119 + 'at' => 'after',
120 + ]);
121 + $this->add_group_control(
122 + Product_Filter::get_type(),
123 + [
124 + 'name' => 'product-filter',
125 + 'label' => esc_html__('Products', 'uicore-elements'),
126 + 'description' => esc_html__('Current Query Settings > Reading', 'uicore-elements'),
127 + ]
128 + );
129 + $this->end_injection();
110 130
111 131 // Register meta controls with updated options
112 - $this->start_injection( [
113 - 'of' => 'section_extra_item_content',
114 - 'at' => 'after',
115 - ] );
116 - $this->TRAIT_register_post_meta_controls(false, true);
117 - $this->end_injection();
132 + $this->start_injection([
133 + 'of' => 'section_extra_item_content',
134 + 'at' => 'after',
135 + ]);
136 + $this->TRAIT_register_post_meta_controls(false, true);
137 + $this->end_injection();
118 138
119 139 // Register new button placement control
120 - $this->start_injection( [
121 - 'of' => 'section_button_style',
122 - 'at' => 'after',
123 - ] );
124 - $this->add_control(
125 - 'button_position',
126 - [
127 - 'label' => esc_html__('Placement', 'uicore-elements'),
128 - 'type' => \Elementor\Controls_Manager::SELECT,
129 - 'options' => [
130 - '' => 'Default',
131 - 'ui-e-button-placement-image' => 'On Image',
132 - ],
133 - 'default' => 'ui-e-button-placement-image',
134 - 'render_type' => 'template',
135 - 'prefix_class' => ''
136 - ]
137 - );
138 - $this->end_injection();
140 + $this->start_injection([
141 + 'of' => 'section_button_style',
142 + 'at' => 'after',
143 + ]);
144 + $this->add_control(
145 + 'button_position',
146 + [
147 + 'label' => esc_html__('Placement', 'uicore-elements'),
148 + 'type' => \Elementor\Controls_Manager::SELECT,
149 + 'options' => [
150 + '' => 'Default',
151 + 'ui-e-button-placement-image' => 'On Image',
152 + ],
153 + 'default' => 'ui-e-button-placement-image',
154 + 'render_type' => 'template',
155 + 'prefix_class' => ''
156 + ]
157 + );
158 + $this->end_injection();
139 159
140 160 // Register new Swatches and Sale Badge controls
141 - $this->start_injection( [
142 - 'of' => 'show_button',
143 - 'at' => 'after',
144 - ] );
161 + $this->start_injection([
162 + 'of' => 'show_button',
163 + 'at' => 'after',
164 + ]);
165 +
166 + if (defined('UICORE_ASSETS')) {
145 167 $this->add_control(
146 168 'show_swatches',
147 169 [
148 170 'label' => esc_html__('Swatches', 'uicore-elements'),
149 171 'type' => \Elementor\Controls_Manager::SWITCHER,
150 - 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
151 - 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
172 + 'label_on' => esc_html__('Show', 'uicore-elements'),
173 + 'label_off' => esc_html__('Hide', 'uicore-elements'),
152 174 'description' => esc_html__('Will only work if you have Uicore Framework plugin active at least on version 6.0.1', 'uicore-elements'),
153 175 'default' => 'yes',
154 176 ]
155 177 );
178 + }
179 +
180 + $this->add_control(
181 + 'show_sale_badge',
182 + [
183 + 'label' => esc_html__('Sale Badge', 'uicore-elements'),
184 + 'type' => \Elementor\Controls_Manager::SWITCHER,
185 + 'label_on' => esc_html__('Show', 'uicore-elements'),
186 + 'label_off' => esc_html__('Hide', 'uicore-elements'),
187 + 'default' => 'yes',
188 + 'prefix_class' => 'ui-e-show-sale-badge-',
189 + ]
190 + );
191 + $this->add_control(
192 + 'badge_warning',
193 + [
194 + 'type' => \Elementor\Controls_Manager::RAW_HTML,
195 + 'raw' => __("If you can't see the Sale Badge after setting 'Show', you problably didn't set any Meta option as 'Product Sale', or you don't have products on sale.", 'uicore-elements'),
196 + 'content_classes' => 'elementor-control-field-description',
197 + 'condition' => [
198 + 'show_sale_badge' => 'yes',
199 + ],
200 + ]
201 + );
202 +
203 + $this->end_injection();
204 +
205 + if (defined('UICORE_ASSETS')) {
206 + $this->start_injection([
207 + 'of' => 'section_style_content',
208 + 'at' => 'after',
209 + ]);
210 + $this->start_controls_section(
211 + 'section_swatches',
212 + [
213 + 'label' => esc_html__('Swatches', 'uicore-elements') . UICORE_ELEMENTS_NEW_OPTION,
214 + 'tab' => \Elementor\Controls_Manager::TAB_STYLE,
215 + 'condition' => [
216 + 'show_swatches' => 'yes',
217 + ],
218 + ]
219 + );
220 +
156 221 $this->add_control(
157 - 'show_sale_badge',
222 + 'swatches_to',
158 223 [
159 - 'label' => esc_html__('Sale Badge', 'uicore-elements'),
224 + 'label' => esc_html__('Use Framework defaults', 'uicore-elements'),
160 225 'type' => \Elementor\Controls_Manager::SWITCHER,
161 - 'label_on' => esc_html__( 'Show', 'uicore-elements' ),
162 - 'label_off' => esc_html__( 'Hide', 'uicore-elements' ),
226 + 'description' => esc_html__('If enabled, the swatches will inherit your theme options.', 'uicore-elements'),
227 + 'label_on' => esc_html__('Yes', 'uicore-elements'),
228 + 'label_off' => esc_html__('No', 'uicore-elements'),
163 229 'default' => 'yes',
164 - 'prefix_class' => 'ui-e-show-sale-badge-',
165 230 ]
166 231 );
232 +
167 233 $this->add_control(
168 - 'badge_warning',
234 + 'swatches_size',
169 235 [
170 - 'type' => \Elementor\Controls_Manager::RAW_HTML,
171 - 'raw' => __("If you can't see the Sale Badge after setting 'Show', you problably didn't set any Meta option as 'Product Sale', or you don't have products on sale.", 'uicore-elements'),
172 - 'content_classes' => 'elementor-control-field-description',
236 + 'label' => esc_html__('Size', 'uicore-elements'),
237 + 'type' => \Elementor\Controls_Manager::SLIDER,
238 + 'size_units' => ['px'],
239 + 'range' => [
240 + 'px' => [
241 + 'min' => 10,
242 + 'max' => 100,
243 + ],
244 + ],
245 + 'default' => [
246 + 'unit' => 'px',
247 + 'size' => 30,
248 + ],
173 249 'condition' => [
174 - 'show_sale_badge' => 'yes',
250 + 'show_swatches' => 'yes',
251 + 'swatches_to!' => 'yes',
175 252 ],
253 + 'selectors' => [
254 + '{{WRAPPER}}' => '--uicore-swatch-size: {{SIZE}}{{UNIT}};',
255 + ],
176 256 ]
177 257 );
178 - $this->end_injection();
179 258
180 - // Register new Hide out of stock products control
181 - $this->start_injection( [
182 - 'of' => 'sticky',
183 - 'at' => 'before',
184 - ] );
185 259 $this->add_control(
186 - 'hide_out_of_stock',
260 + 'swatches_outer_radius',
187 261 [
188 - 'label' => esc_html__('Hide out of stock', 'uicore-elements'),
189 - 'type' => \Elementor\Controls_Manager::SWITCHER,
262 + 'label' => esc_html__('Outer Border Radius', 'uicore-elements'),
263 + 'type' => \Elementor\Controls_Manager::SLIDER,
264 + 'size_units' => ['%', 'px'],
265 + 'range' => [
266 + '%' => [
267 + 'min' => 0,
268 + 'max' => 100,
269 + ],
270 + 'px' => [
271 + 'min' => 0,
272 + 'max' => 50,
273 + ],
274 + ],
275 + 'default' => [
276 + 'unit' => '%',
277 + 'size' => 50,
278 + ],
279 + 'separator' => 'before',
190 280 'condition' => [
191 - 'product-filter_post_type!' => 'related',
281 + 'show_swatches' => 'yes',
282 + 'swatches_to!' => 'yes',
192 283 ],
284 + 'selectors' => [
285 + '{{WRAPPER}}' => '--uicore-swatch-radius: {{SIZE}}{{UNIT}}; --uicore-swatch-big-radius: {{SIZE}}{{UNIT}};',
286 + '{{WRAPPER}} .uicore-swatch.uicore-swatch--color' => 'border-radius: {{SIZE}}{{UNIT}};',
287 + ],
193 288 ]
194 289 );
195 - $this->end_injection();
196 290
197 - //
198 - $this->start_injection( [
199 - 'of' => 'text',
200 - 'at' => 'after',
201 - ] );
202 291 $this->add_control(
203 - 'variations_text',
292 + 'swatches_inner_radius',
204 293 [
205 - 'label' => esc_html__('Select Options Text', 'uicore-elements'),
206 - 'label_block' => true,
207 - 'default' => '',
208 - 'description' => esc_html__('Variable product purchase text.', 'uicore-elements'),
209 - 'placeholder' => esc_html__('Select Options', 'uicore-elements'),
294 + 'label' => esc_html__('Inner Border Radius', 'uicore-elements'),
295 + 'type' => \Elementor\Controls_Manager::SLIDER,
296 + 'size_units' => ['px', '%'],
297 + 'range' => [
298 + 'px' => [
299 + 'min' => 0,
300 +
301 + 'max' => 100,
302 + ],
303 + '%' => [
304 + 'min' => 0,
305 + 'max' => 50,
306 + ],
307 + ],
308 + 'default' => [
309 + 'unit' => 'px',
310 + 'size' => 4,
311 + ],
312 + 'separator' => 'after',
313 + 'condition' => [
314 + 'show_swatches' => 'yes',
315 + 'swatches_to!' => 'yes',
316 + ],
317 + 'selectors' => [
318 + '{{WRAPPER}} .uicore-swatch > div' => 'border-radius: {{SIZE}}{{UNIT}};',
319 + ],
210 320 ]
211 321 );
322 +
323 + $this->add_group_control(
324 + \Elementor\Group_Control_Border::get_type(),
325 + [
326 + 'name' => 'swatch_border',
327 + 'selector' => '{{WRAPPER}} .uicore-swatch',
328 + 'condition' => [
329 + 'show_swatches' => 'yes',
330 + 'swatches_to!' => 'yes',
331 + ],
332 + ]
333 + );
334 +
212 335 $this->add_control(
213 - 'unavailable_text',
336 + 'hover_border_size',
214 337 [
215 - 'label' => esc_html__('Unavailable Text', 'uicore-elements'),
216 - 'label_block' => true,
217 - 'default' => '',
218 - 'description' => esc_html__('Out of stock or not available purchase text.', 'uicore-elements'),
219 - 'placeholder' => esc_html__('Read more', 'uicore-elements'),
338 + 'label' => esc_html__('Hover Border Size', 'uicore-elements'),
339 + 'type' => \Elementor\Controls_Manager::SLIDER,
340 + 'size_units' => ['px'],
341 + 'range' => [
342 + 'px' => [
343 + 'min' => 0,
344 +
345 + 'max' => 5,
346 + ],
347 + ],
348 + 'default' => [
349 + 'unit' => 'px',
350 + 'size' => 1,
351 + ],
352 + 'condition' => [
353 + 'show_swatches' => 'yes',
354 + 'swatches_to!' => 'yes',
355 + ],
356 + 'selectors' => [
357 + '{{WRAPPER}} .uicore-swatch:hover' => 'box-shadow: 0 0 0 {{SIZE}}{{UNIT}} var(--uicore-swatch-border);',
358 + ],
220 359 ]
221 360 );
222 - $this->end_injection();
223 361
362 + $this->add_control(
363 + 'swatch_hover_color',
364 + [
365 + 'label' => esc_html__('Hover Border Color', 'uicore-elements'),
366 + 'type' => \Elementor\Controls_Manager::COLOR,
367 + 'condition' => [
368 + 'show_swatches' => 'yes',
369 + 'swatches_to!' => 'yes',
370 + ],
371 + 'selectors' => [
372 + '{{WRAPPER}}' => '--uicore-swatch-border: {{VALUE}};',
373 + '{{WRAPPER}} .uicore-swatch:hover' => 'border-color: {{VALUE}};',
374 + ],
375 + ]
376 + );
377 +
378 + $this->end_controls_section();
379 + $this->end_injection();
380 + }
381 +
382 + // Register new Hide out of stock products control
383 + $this->start_injection([
384 + 'of' => 'sticky',
385 + 'at' => 'before',
386 + ]);
387 + $this->add_control(
388 + 'hide_out_of_stock',
389 + [
390 + 'label' => esc_html__('Hide out of stock', 'uicore-elements'),
391 + 'type' => \Elementor\Controls_Manager::SWITCHER,
392 + 'condition' => [
393 + 'product-filter_post_type!' => 'related',
394 + ],
395 + ]
396 + );
397 + $this->end_injection();
398 +
399 + $this->start_injection([
400 + 'of' => 'text',
401 + 'at' => 'after',
402 + ]);
403 + $this->add_control(
404 + 'variations_text',
405 + [
406 + 'type' => \Elementor\Controls_Manager::TEXT,
407 + 'label' => esc_html__('Select Options Text', 'uicore-elements'),
408 + 'label_block' => true,
409 + 'default' => '',
410 + 'description' => esc_html__('Variable product purchase text.', 'uicore-elements'),
411 + 'placeholder' => esc_html__('Select Options', 'uicore-elements'),
412 + ]
413 + );
414 + $this->add_control(
415 + 'unavailable_text',
416 + [
417 + 'type' => \Elementor\Controls_Manager::TEXT,
418 + 'label' => esc_html__('Unavailable Text', 'uicore-elements'),
419 + 'label_block' => true,
420 + 'default' => '',
421 + 'description' => esc_html__('Out of stock or not available purchase text.', 'uicore-elements'),
422 + 'placeholder' => esc_html__('Read more', 'uicore-elements'),
423 + ]
424 + );
425 + $this->end_injection();
426 +
224 427 // Update controls that uses 'posts_filter' to 'product_filter'
225 428 $this->update_control(
226 429 'item_limit',
227 430 [
@@ -289,9 +492,9 @@
289 492 ]
290 493 );
291 494 $this->update_control(
292 495 'excerpt_trim',
293 - [ 'label' => esc_html__('Summary Length (words)', 'uicore-elements') ]
496 + ['label' => esc_html__('Summary Length (words)', 'uicore-elements')]
294 497 );
295 498 $this->update_control(
296 499 'show_button',
297 500 [
@@ -309,17 +512,17 @@
309 512 ]
310 513 );
311 514 $this->update_control(
312 515 'text_color',
313 - [ 'label' => esc_html__('Summary Color', 'uicore-elements') ]
516 + ['label' => esc_html__('Summary Color', 'uicore-elements')]
314 517 );
315 518 $this->update_control(
316 519 'text_typography',
317 - [ 'label' => esc_html__('Summary Typography', 'uicore-elements') ]
520 + ['label' => esc_html__('Summary Typography', 'uicore-elements')]
318 521 );
319 522 $this->update_control(
320 523 'text_gap',
321 - [ 'label' => esc_html__('Summary Top Space', 'uicore-elements') ]
524 + ['label' => esc_html__('Summary Top Space', 'uicore-elements')]
322 525 );
323 526
324 527 // Update button controls
325 528 $this->update_control(
@@ -324,15 +527,15 @@
324 527 // Update button controls
325 528 $this->update_control(
326 529 'border_radius', // button border-radius
327 530 [
328 - 'default' => [ 'top' => 0, 'right' => 0, 'bottom' => 0, 'left' => 0 ]
531 + 'default' => ['top' => 0, 'right' => 0, 'bottom' => 0, 'left' => 0]
329 532 ]
330 533 );
331 534 $this->update_control(
332 535 'text_padding', // button padding
333 536 [
334 - 'default' => [ 'top' => 10, 'right' => 10, 'bottom' => 10, 'left' => 10, 'unit' => 'px' ]
537 + 'default' => ['top' => 10, 'right' => 10, 'bottom' => 10, 'left' => 10, 'unit' => 'px']
335 538 ]
336 539 );
337 540 $this->update_control(
338 541 'button_align',
@@ -338,8 +541,13 @@
338 541 'button_align',
339 542 [
340 543 'condition' => [
341 544 'button_position!' => 'ui-e-button-placement-image',
545 + ],
546 + // since product might have ajax add to cart, wich has flex display so the cart added icon do not break button layout,
547 + // we justify the flex content to center so justified text align button keeps text centralized. See: https://uicore.atlassian.net/browse/ELM-429
548 + 'selectors' => [
549 + '{{WRAPPER}} .ui-e-readmore' => 'align-self: {{VALUE}}; justify-content: center;',
342 550 ]
343 551 ]
344 552 );
345 553 $this->update_control(
@@ -358,23 +566,24 @@
358 566 * This method retrieves the widget settings; set up the query, and renders each post item.
359 567 * If no posts are found, it returns false. After rendering, it resets the query and returns the output.
360 568 *
361 569 * @param array|false $current_query The current query args, or false if the widget isn't set to use the current query.
570 + * @param int $pageID The ID of the page where the widget is located.
362 571 *
363 572 * @return string|false The rendered widget content or false if no posts are found.
364 - */
573 + */
365 574 public function render_ajax($current_query)
366 575 {
367 576 // Get settings and post type
368 577 $settings = $this->get_settings();
369 578
370 - $this->TRAIT_query_products( $settings, $current_query );
579 + $this->TRAIT_query_products($settings, $current_query);
371 580 $wc_query = $this->get_query();
372 581
373 582 $products = wc_get_products($wc_query);
374 583
375 584 // No products found
376 - if ( empty($products) ) {
585 + if (empty($products)) {
377 586 return false;
378 587 }
379 588
380 589 \ob_start();
@@ -395,10 +604,10 @@
395 604 }
396 605
397 606 protected function render()
398 607 {
399 - if( !class_exists('WooCommerce') ) {
400 - if ( $this->is_edit_mode() ) {
608 + if (!class_exists('WooCommerce')) {
609 + if ($this->is_edit_mode()) {
401 610 echo '<p>' . esc_html__('Please enable WooCommerce to use this widget.', 'uicore-elements') . '</p>';
402 611 }
403 612 return;
404 613 }
@@ -405,21 +614,22 @@
405 614
406 615 global $wp_query;
407 616 $settings = $this->get_settings();
408 617
618 + // Get product ID
619 + $product_id = get_the_ID();
620 +
409 621 // Related products, on save page action at editor, triggers an fata error upon post object handle.
410 622 // Prevent it for now by disabling the widget on edit mode. TODO: remove it after fixing the issue
411 - if ( 'related' === $settings['product-filter_post_type'] && $this->is_edit_mode() ) {
623 + if ('related' === $settings['product-filter_post_type'] && $this->is_edit_mode()) {
412 624 echo '<p>' . esc_html__('This widget is set to display related products. To see the results, please preview the page, or customize your widget before setting "current" query.', 'uicore-elements') . '</p>';
413 625 return;
414 626 }
415 627
416 628 // Build query
417 - $products = $this->TRAIT_query_products( $settings, $wp_query->query );
629 + $products = $this->TRAIT_query_products($settings, $wp_query->query);
418 630 $wc_query = $this->get_query();
419 631
420 - $this->TRAIT_set_meta_font_size_to_svg($settings); // SVG icon experiment font-size adjustment
421 -
422 632 // Store widget settings in a transient
423 633 $ID = strval($this->get_ID());
424 634 set_transient('ui_elements_widgetdata_' . $ID, $settings, \MONTH_IN_SECONDS);
425 635
@@ -429,53 +639,52 @@
429 639
430 640 $this->TRAIT_render_filters($settings, true);
431 641
432 642 // No posts found
433 - if ( empty($products) ) {
643 + if (empty($products)) {
434 644 echo '<p style="text-align:center">' . esc_html__('No products found.', 'uicore-elements') . '</p>';
435 -
436 645 } else {
437 - ?>
438 - <div class="ui-e-adv-grid">
439 - <?php
440 - foreach ($products as $index => $product) {
646 +?>
647 + <div class="ui-e-adv-grid">
648 + <?php
649 + foreach ($products as $index => $product) {
441 650
442 - // sticky posts disregards posts per page, so ending the loop if $items == $loop forces the query respects the users item limit
443 - if ($settings['sticky'] && $items == $loops) {
444 - break;
445 - }
651 + // sticky posts disregards posts per page, so ending the loop if $items == $loop forces the query respects the users item limit
652 + if ($settings['sticky'] && $items == $loops) {
653 + break;
654 + }
446 655
447 - // check is is related post type
448 - if ( 'related' === $settings['product-filter_post_type'] ) {
449 - $product = wc_get_product($product);
450 - }
656 + // check is is related post type
657 + if ('related' === $settings['product-filter_post_type']) {
658 + $product = wc_get_product($product);
659 + }
451 660
452 - $post_object = get_post($product->get_id());
453 - setup_postdata($post_object);
661 + $post_object = get_post($product->get_id());
662 + setup_postdata($post_object);
454 663
455 - $this->TRAIT_render_product($product, $index, false, true);
664 + $this->TRAIT_render_product($product, $index, false, true);
456 665
457 - wp_reset_postdata(); // Reset post data after rendering each product
458 - $loops++;
459 - }
460 - ?>
461 - </div>
462 - <?php
666 + wp_reset_postdata(); // Reset post data after rendering each product
667 + $loops++;
668 + }
669 + ?>
670 + </div>
671 +<?php
463 672
464 - $this->TRAIT_render_pagination($settings, true);
673 + $this->TRAIT_render_pagination($settings, $product_id, true);
465 674
466 - // Add some data, to help rest api, to the js
467 - if( $settings['pagination'] == 'yes' && $settings['pagination_type'] == 'load_more' ) {
675 + // Add some data, to help rest api, to the js
676 + if ($this->is_option('pagination', 'yes') && $this->is_option('pagination_type', 'load_more')) {
468 677
469 678 echo '<script>';
470 679
471 - // Add total pages to js variable
472 - echo 'window.ui_total_pages_' . esc_html($ID) . ' = ' . esc_html( $wc_query['total_pages'] ) . ';';
680 + // Add total pages to js variable
681 + echo 'window.ui_total_pages_' . esc_html($ID) . ' = ' . esc_html($wc_query['total_pages']) . ';';
473 682
474 - // Pass current query to js variable
475 - if( $settings['product-filter_post_type'] == 'current' ) {
476 - echo 'window.ui_query_' . esc_html($ID) . ' = ' . \json_encode($wc_query) . ';';
477 - }
683 + // Pass current query to js variable
684 + if ($settings['product-filter_post_type'] == 'current') {
685 + echo 'window.ui_query_' . esc_html($ID) . ' = ' . \json_encode($wc_query) . ';';
686 + }
478 687
479 688 echo '</script>';
480 689 }
481 690 }