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 +367 -133 1.0.15 → 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,109 +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
291 + $this->add_control(
292 + 'swatches_inner_radius',
293 + [
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,
197 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 + ],
320 + ]
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 +
335 + $this->add_control(
336 + 'hover_border_size',
337 + [
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 + ],
359 + ]
360 + );
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 +
198 427 // Update controls that uses 'posts_filter' to 'product_filter'
199 428 $this->update_control(
200 429 'item_limit',
201 430 [
@@ -263,9 +492,9 @@
263 492 ]
264 493 );
265 494 $this->update_control(
266 495 'excerpt_trim',
267 - [ 'label' => esc_html__('Summary Length (words)', 'uicore-elements') ]
496 + ['label' => esc_html__('Summary Length (words)', 'uicore-elements')]
268 497 );
269 498 $this->update_control(
270 499 'show_button',
271 500 [
@@ -275,24 +504,25 @@
275 504 );
276 505 $this->update_control(
277 506 'text',
278 507 [
279 - 'label' => esc_html__('Custom Text', 'uicore-elements'),
280 - 'default' => esc_html__('', 'uicore-elements'),
281 - 'description' => esc_html__('If left blank, the default add to cart button text will be used.', 'uicore-elements')
508 + 'label' => esc_html__('Add to Cart Text', 'uicore-elements'),
509 + 'label_block' => true,
510 + 'default' => '',
511 + 'placeholder' => esc_html__('Add to cart', 'uicore-elements'),
282 512 ]
283 513 );
284 514 $this->update_control(
285 515 'text_color',
286 - [ 'label' => esc_html__('Summary Color', 'uicore-elements') ]
516 + ['label' => esc_html__('Summary Color', 'uicore-elements')]
287 517 );
288 518 $this->update_control(
289 519 'text_typography',
290 - [ 'label' => esc_html__('Summary Typography', 'uicore-elements') ]
520 + ['label' => esc_html__('Summary Typography', 'uicore-elements')]
291 521 );
292 522 $this->update_control(
293 523 'text_gap',
294 - [ 'label' => esc_html__('Summary Top Space', 'uicore-elements') ]
524 + ['label' => esc_html__('Summary Top Space', 'uicore-elements')]
295 525 );
296 526
297 527 // Update button controls
298 528 $this->update_control(
@@ -297,15 +527,15 @@
297 527 // Update button controls
298 528 $this->update_control(
299 529 'border_radius', // button border-radius
300 530 [
301 - 'default' => [ 'top' => 0, 'right' => 0, 'bottom' => 0, 'left' => 0 ]
531 + 'default' => ['top' => 0, 'right' => 0, 'bottom' => 0, 'left' => 0]
302 532 ]
303 533 );
304 534 $this->update_control(
305 535 'text_padding', // button padding
306 536 [
307 - 'default' => [ 'top' => 10, 'right' => 10, 'bottom' => 10, 'left' => 10, 'unit' => 'px' ]
537 + 'default' => ['top' => 10, 'right' => 10, 'bottom' => 10, 'left' => 10, 'unit' => 'px']
308 538 ]
309 539 );
310 540 $this->update_control(
311 541 'button_align',
@@ -311,8 +541,13 @@
311 541 'button_align',
312 542 [
313 543 'condition' => [
314 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;',
315 550 ]
316 551 ]
317 552 );
318 553 $this->update_control(
@@ -331,34 +566,33 @@
331 566 * This method retrieves the widget settings; set up the query, and renders each post item.
332 567 * If no posts are found, it returns false. After rendering, it resets the query and returns the output.
333 568 *
334 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.
335 571 *
336 572 * @return string|false The rendered widget content or false if no posts are found.
337 - */
573 + */
338 574 public function render_ajax($current_query)
339 575 {
340 576 // Get settings and post type
341 577 $settings = $this->get_settings();
342 578
343 - $this->TRAIT_query_products( $settings, $current_query );
579 + $this->TRAIT_query_products($settings, $current_query);
344 580 $wc_query = $this->get_query();
345 581
346 582 $products = wc_get_products($wc_query);
347 583
348 584 // No products found
349 - if ( empty($products) ) {
585 + if (empty($products)) {
350 586 return false;
351 587 }
352 588
353 - // TODO: check related render method
354 -
355 589 \ob_start();
356 - foreach ($products as $product) {
590 + foreach ($products as $index => $product) {
357 591 $post_object = get_post($product->get_id());
358 592 setup_postdata($post_object);
359 593
360 - $this->TRAIT_render_product($product, false, true, true);
594 + $this->TRAIT_render_product($product, $index, false, true, true);
361 595
362 596 wp_reset_postdata();
363 597 }
364 598 $markup = \ob_get_clean();
@@ -370,11 +604,11 @@
370 604 }
371 605
372 606 protected function render()
373 607 {
374 - if( !class_exists('WooCommerce') ) {
375 - if ( $this->is_edit_mode() ) {
376 - echo '<p>' . __('Please enable WooCommerce to use this widget.', 'uicore-elements') . '</p>';
608 + if (!class_exists('WooCommerce')) {
609 + if ($this->is_edit_mode()) {
610 + echo '<p>' . esc_html__('Please enable WooCommerce to use this widget.', 'uicore-elements') . '</p>';
377 611 }
378 612 return;
379 613 }
380 614
@@ -380,21 +614,22 @@
380 614
381 615 global $wp_query;
382 616 $settings = $this->get_settings();
383 617
618 + // Get product ID
619 + $product_id = get_the_ID();
620 +
384 621 // Related products, on save page action at editor, triggers an fata error upon post object handle.
385 622 // Prevent it for now by disabling the widget on edit mode. TODO: remove it after fixing the issue
386 - if ( 'related' === $settings['product-filter_post_type'] && $this->is_edit_mode() ) {
387 - echo '<p>' . __('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>';
623 + if ('related' === $settings['product-filter_post_type'] && $this->is_edit_mode()) {
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>';
388 625 return;
389 626 }
390 627
391 628 // Build query
392 - $products = $this->TRAIT_query_products( $settings, $wp_query->query );
629 + $products = $this->TRAIT_query_products($settings, $wp_query->query);
393 630 $wc_query = $this->get_query();
394 631
395 - $this->TRAIT_set_meta_font_size_to_svg($settings); // SVG icon experiment font-size adjustment
396 -
397 632 // Store widget settings in a transient
398 633 $ID = strval($this->get_ID());
399 634 set_transient('ui_elements_widgetdata_' . $ID, $settings, \MONTH_IN_SECONDS);
400 635
@@ -404,53 +639,52 @@
404 639
405 640 $this->TRAIT_render_filters($settings, true);
406 641
407 642 // No posts found
408 - if ( empty($products) ) {
409 - echo '<p style="text-align:center">' . __('No products found.', 'uicore-elements') . '</p>';
410 -
643 + if (empty($products)) {
644 + echo '<p style="text-align:center">' . esc_html__('No products found.', 'uicore-elements') . '</p>';
411 645 } else {
412 - ?>
413 - <div class="ui-e-adv-grid">
414 - <?php
415 - foreach ($products as $product) {
646 +?>
647 + <div class="ui-e-adv-grid">
648 + <?php
649 + foreach ($products as $index => $product) {
416 650
417 - // sticky posts disregards posts per page, so ending the loop if $items == $loop forces the query respects the users item limit
418 - if ($settings['sticky'] && $items == $loops) {
419 - break;
420 - }
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 + }
421 655
422 - // check is is related post type
423 - if ( 'related' === $settings['product-filter_post_type'] ) {
424 - $product = wc_get_product($product);
425 - }
656 + // check is is related post type
657 + if ('related' === $settings['product-filter_post_type']) {
658 + $product = wc_get_product($product);
659 + }
426 660
427 - $post_object = get_post($product->get_id());
428 - setup_postdata($post_object);
661 + $post_object = get_post($product->get_id());
662 + setup_postdata($post_object);
429 663
430 - $this->TRAIT_render_product($product, false, true);
664 + $this->TRAIT_render_product($product, $index, false, true);
431 665
432 - wp_reset_postdata(); // Reset post data after rendering each product
433 - $loops++;
434 - }
435 - ?>
436 - </div>
437 - <?php
666 + wp_reset_postdata(); // Reset post data after rendering each product
667 + $loops++;
668 + }
669 + ?>
670 + </div>
671 +<?php
438 672
439 - $this->TRAIT_render_pagination($settings, true);
673 + $this->TRAIT_render_pagination($settings, $product_id, true);
440 674
441 - // Add some data, to help rest api, to the js
442 - 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')) {
443 677
444 678 echo '<script>';
445 679
446 - // Add total pages to js variable
447 - 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']) . ';';
448 682
449 - // Pass current query to js variable
450 - if( $settings['product-filter_post_type'] == 'current' ) {
451 - echo 'window.ui_query_' . esc_html($ID) . ' = ' . \json_encode($wc_query) . ';';
452 - }
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 + }
453 687
454 688 echo '</script>';
455 689 }
456 690 }