PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.0.0
ShopBuilder – WooCommerce Builder For Elementor v2.0.0
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
shopbuilder / app / Elementor / Render / Render.php

Render.php in ShopBuilder – WooCommerce Builder For Elementor 2.0.0, at app/Elementor/Render/Render.php

973 lines 29.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Elementor Render Class.
4 *
5 * This class contains render logics & output.
6 *
7 * @package RadiusTheme\SB
8 */
9
10 namespace RadiusTheme\SB\Elementor\Render;
11
12 use WP_Query;
13 use RadiusTheme\SB\Helpers\Fns;
14 use RadiusTheme\SB\Models\QueryArgs;
15 use RadiusTheme\SB\Helpers\BuilderFns;
16 use RadiusTheme\SB\Traits\SingletonTrait;
17 use RadiusTheme\SB\Traits\ActionBtnTraits;
18 use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
19
20 // Do not allow directly accessing this file.
21 if ( ! defined( 'ABSPATH' ) ) {
22 exit( 'This script cannot be accessed directly.' );
23 }
24
25 /**
26 * Elementor Render Class.
27 */
28 class Render {
29 /**
30 * Singleton Trait.
31 */
32 use SingletonTrait;
33
34 /**
35 * Action button trait.
36 */
37 use ActionBtnTraits;
38
39 /**
40 * HTML.
41 *
42 * @var string
43 */
44 private $html = null;
45
46 /**
47 * Settings array
48 *
49 * @var array
50 */
51 public $get_settings;
52
53 /**
54 * Get elementor settings.
55 *
56 * @return array
57 */
58 public function get_settings_for_display() {
59 return $this->get_settings;
60 }
61
62 /**
63 * Container Wrapper HTML.
64 *
65 * @param string $content The content.
66 * @param array $settings Settings.
67 * @param string $class Class.
68 * @param string $template Template name.
69 * @param bool $fullwidth Fullwidth check.
70 *
71 * @return string
72 */
73 public function container( $content, $settings, $class = '', $template = '', $fullwidth = false ) {
74 $layout_id = 'rtsb-container-' . absint( wp_rand() );
75 $container_attr = null;
76 $cart_txt_class = '';
77 $container_class = 'rtsb-elementor-container products rtsb-pos-r ' . esc_attr( $class );
78 $metas = RenderHelpers::meta_dataset( $settings, $template );
79
80 $layout = $metas['layout'];
81 $animation = $metas['hover_animation'];
82
83 $is_cat = preg_match( '/category/', $layout );
84 $is_carousel = preg_match( '/slider/', $layout );
85
86 if ( ! $is_cat ) {
87 $cart_txt_class = $metas['show_cart_text'] ? ' has-cart-text' : ' no-cart-text';
88 }
89
90 if ( $is_carousel ) {
91 $fullwidth = true;
92 }
93
94 $badge_class = [
95 'position' => $metas['badge_position'],
96 'alignment' => $metas['badge_alignment'],
97 ];
98
99 if ( ! in_array( $layout, array_keys( Fns::free_layouts() ), true ) ) {
100 $layout = RenderHelpers::set_default_layout( $layout );
101 }
102
103 if ( $is_carousel ) {
104 $pagination_attr = ! empty( $metas['show_filter'] ) ? RenderHelpers::pagination_data( $settings, $template ) : '';
105 } elseif ( $is_cat ) {
106 $pagination_attr = '';
107 } else {
108 $pagination_attr = RenderHelpers::pagination_data( $settings, $template );
109 }
110
111 if ( ! in_array( 'clear-btn', $metas['visibility'], true ) ) {
112 $container_class .= ' no-clear-btn';
113 }
114
115 $style_attr = ' style="--rtsb-default-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) ) . '"';
116 $tooltip_attr = ' data-tooltip-position="' . esc_attr( $metas['tooltip_position'] ) . '"';
117
118 $view_mode = $settings['view_mode'] ?? 'grid';
119
120 if ( isset( $_GET['displayview'] ) ) {
121 $view_mode = sanitize_text_field( wp_unslash( $_GET['displayview'] ) );
122 }
123
124 if ( 'list' == $view_mode && ! empty( $metas['tooltip_position_list'] ) ) {
125 $tooltip_attr = ' data-tooltip-position="' . esc_attr( $metas['tooltip_position_list'] ) . '"';
126 }
127
128 $container_attr .= ' data-layout="' . esc_attr( $layout ) . '"' . $style_attr . $tooltip_attr . $pagination_attr;
129 $container_class .= ' badge-' . esc_attr( $badge_class['position'] ) . ' badge-' . esc_attr( $badge_class['alignment'] ) . esc_attr( $cart_txt_class ) . ' img-hover-' . esc_attr( $animation ) . ' excerpt-' . esc_attr( $metas['cat_excerpt_position'] );
130
131 if ( $metas['show_overlay'] ) {
132 $container_class .= ' has-overlay';
133 }
134
135 if ( in_array( 'single-cat', $metas['visibility'], true ) ) {
136 $container_class .= ' show-single-cat';
137 }
138
139 $container_class = apply_filters( 'rtsb/product/container/class', $container_class, $settings );
140 $this->html = '<div class="' . esc_attr( $container_class ) . '" id="' . esc_attr( $layout_id ) . '" ' . $container_attr . '>';
141
142 if ( ! empty( $settings['query_products'] ) && count( $settings['query_products'] ) && 'yes' === $settings['show_section_title'] ) {
143 $this->html .= '<div class="rtsb-section-title-wrapper">';
144 $this->html .= '<' . esc_attr( $settings['section_title_tag'] ) . ' class="rtsb-section-title" >';
145 $this->html .= esc_html( $settings['section_title_text'] );
146 $this->html .= '</' . esc_attr( $settings['section_title_tag'] ) . '>';
147 $this->html .= '</div>';
148 }
149
150 $this->html .= $content;
151
152 $this->html .= '</div><!-- .rtsb-elementor-container -->';
153
154 // Action button icon reset.
155 $this->action_button_icon_set_default();
156
157 $script_generator = [];
158 $script_generator['layout'] = $layout_id;
159 $script_generator['rand'] = absint( wp_rand() );
160 $script_generator['isCarousel'] = $is_carousel;
161
162 add_action(
163 'wp_footer',
164 static function () use ( $script_generator ) {
165 RenderHelpers::register_scripts( $script_generator );
166 }
167 );
168
169 return $this->html;
170 }
171
172 /**
173 * Row Wrapper HTML.
174 *
175 * @param string $content The content.
176 * @param array $settings Settings.
177 * @param string $hook_html Hook HTML.
178 *
179 * @return string
180 */
181 public function row( $content, $settings, $hook_html = '' ) {
182 $masonry_class = null;
183 $loader_class = ' rtsb-pre-loader';
184
185 $layout = $settings['layout'];
186 $grid_type = $settings['grid_type'];
187 $is_carousel = preg_match( '/slider/', $layout );
188
189 if ( 'even' === $grid_type ) {
190 $masonry_class = ' rtsb-even';
191 } elseif ( 'masonry' === $grid_type ) {
192 $masonry_class = ' rtsb-masonry';
193 }
194
195 if ( ! rtsb()->has_pro() || $is_carousel ) {
196 $masonry_class = ' rtsb-even';
197 }
198
199 $row_start_class = apply_filters( 'rtsb/custom/layout/row/classes', esc_attr( 'rtsb-row rtsb-content-loader element-loading rtsb-' . $layout . $masonry_class . $loader_class ), $settings );
200 $row_wrapper = '<div data-title="' . esc_html__( 'Loading ...', 'shopbuilder' ) . '" class="' . $row_start_class . '">';
201 $start_wrapper = apply_filters( 'rtsb/custom/layout/row/start', $row_wrapper, $row_start_class );
202 if ( ! empty( $settings['show_filter'] ) ) {
203 $this->html = $hook_html;
204 $this->html .= $start_wrapper;
205 } else {
206 $this->html = $start_wrapper;
207 }
208
209 if ( $is_carousel ) {
210 $slider_data = RenderHelpers::slider_data( $settings );
211
212 $this->html .= '<div class="rtsb-col-grid ' . esc_attr( $slider_data['class'] ) . '" ' . $slider_data['data'] . '>';
213 $this->html .= '<div class="swiper-wrapper">';
214 }
215
216 $this->html .= $content;
217
218 if ( $is_carousel ) {
219 $this->html .= '</div><!-- .swiper-wrapper -->';
220
221 $left_icon = $settings['left_arrow_icon'];
222 $right_icon = $settings['right_arrow_icon'];
223
224 if ( ! empty( $settings['slider_nav'] ) ) {
225 $this->html .=
226 '<div class="swiper-nav">
227 <div class="swiper-arrow swiper-button-next">
228 ' . Fns::icons_manager( $right_icon ) . '
229 </div>
230 <div class="swiper-arrow swiper-button-prev">
231 ' . Fns::icons_manager( $left_icon ) . '
232 </div>
233 </div>';
234 }
235
236 $this->html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
237
238 $this->html .= '</div><!-- .rtsb-carousel-slider -->';
239 }
240
241 $row_end = '</div><!-- .rtsb-row -->';
242
243 $this->html .= apply_filters( 'rtsb/custom/layout/row/end', $row_end );
244
245 $this->html .= RenderHelpers::pre_loader( $layout );
246
247 return $this->html;
248 }
249
250 /**
251 * Product loop.
252 *
253 * @param object $query The query.
254 * @param array $settings Settings.
255 * @param string $template Template.
256 *
257 * @return string|null
258 */
259 public function product_loop( $query, $settings, $template ) {
260 $html = null;
261
262 if ( empty( $query ) ) {
263 return null;
264 }
265
266 $i = 0;
267
268 while ( $query->have_posts() ) {
269 $query->the_post();
270 $i++;
271
272 // Loop arg.
273 $arg = $this->arg_dataset( $settings, get_the_ID(), $settings['lazy_load'], $i );
274
275 // Get template.
276 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
277 }
278
279 return $html;
280 }
281
282 /**
283 * Product loop.
284 *
285 * @param object $query The query.
286 * @param array $settings Settings.
287 * @param string $template Template.
288 * @param bool $is_single Single category.
289 *
290 * @return string|null
291 */
292 public function category_loop( $query, $settings, $template, $is_single = false ) {
293 $html = null;
294
295 if ( $is_single ) {
296 // Loop arg.
297 $arg = $this->cat_arg_dataset( $settings, $query, true );
298
299 // Get template.
300 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
301 } else {
302 foreach ( $query as $term ) {
303 // Loop arg.
304 $arg = $this->cat_arg_dataset( $settings, $term );
305
306 // Get template.
307 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
308 }
309 }
310
311 return $html;
312 }
313
314 /**
315 * Render Product View.
316 *
317 * @param string $template Template name.
318 * @param array $settings Control settings.
319 *
320 * @return string
321 */
322 public function product_view( $template, $settings ) {
323 $this->get_settings = $settings;
324
325 $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
326 $is_carousel = preg_match( '/slider/', $metas['layout'] );
327 $pagination = $metas['pagination'];
328 $hook_html = '';
329
330 // Query Args.
331 $args = ( new QueryArgs() )->buildArgs( $metas, 'product', $is_carousel );
332
333 $temp_args = $args;
334 $args = apply_filters( 'rtsb/elementor/args_before_loop', $args, $metas );
335
336 // Query.
337 $product_query = new WP_Query( $args );
338
339 if ( $product_query->have_posts() ) {
340 // Elementor Render hook before row.
341 ob_start();
342 do_action( 'rtsb/elementor/render/before_row', $metas, $settings, $product_query, $temp_args );
343 $hook_html .= ob_get_clean();
344
345 // Row.
346 $this->row( $this->product_loop( $product_query, $metas, $template ), $metas, $hook_html );
347
348 // Pagination.
349 if ( $pagination ) {
350 $this->html .= RenderHelpers::render_pagination(
351 $product_query,
352 $metas,
353 $settings['posts_limit'],
354 $settings['pagination_per_page']
355 );
356 }
357
358 // Elementor Render hook before row.
359 ob_start();
360 do_action( 'rtsb/elementor/render/after_row', $metas, $settings, $product_query );
361 $this->html .= ob_get_clean();
362
363 } else {
364 $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
365
366 $this->row( $content, $metas );
367 }
368
369 wp_reset_postdata();
370
371 unset( $args['tax_query'] );
372
373 // Container.
374 $this->container( $this->html, $settings, 'rtsb-products-container', $template, $is_carousel );
375
376 return $this->html;
377 }
378
379
380 /**
381 * Render Product View.
382 *
383 * @param string $template Template name.
384 * @param array $settings Control settings.
385 * @param object $widget Reference widget.
386 *
387 * @return string
388 */
389 public function wc_loop_for_product_view( $template, $settings, $widget ) {
390 global $wp_query, $post;
391
392 $this->get_settings = $settings;
393 $metas = RenderHelpers::meta_dataset( $settings, $template, $widget->get_settings_for_display() );
394
395 $settings['rtsb_order'] = ! empty( $wp_query->query_vars['order'] ) ? $wp_query->query_vars['order'] : 'ASC';
396 $settings['rtsb_orderby'] = ! empty( $wp_query->query_vars['orderby'] ) ? $wp_query->query_vars['orderby'] : 'menu_order';
397
398 $pagination = $metas['pagination'];
399
400 $page_type = BuilderFns::builder_type( get_the_ID() );
401 $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
402 $posts_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
403
404 if ( $is_preview ) {
405 $main_query = clone $wp_query;
406 $main_post = clone $post;
407
408 $ordering = ( new \WC_Query() )->get_catalog_ordering_args();
409 $wp_query_args = [
410 'post_type' => 'product',
411 'posts_per_page' => $posts_per_page,
412 ];
413
414 if ( ! empty( $ordering['orderby'] ) ) {
415 $wp_query_args['orderby'] = $ordering['orderby'];
416 }
417
418 if ( ! empty( $ordering['order'] ) ) {
419 $wp_query_args['order'] = $ordering['order'];
420 }
421
422 $wp_query = new \WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
423 wc_set_loop_prop( 'total', $wp_query->found_posts );
424 wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
425 }
426
427 // column_per_row.
428 if ( woocommerce_product_loop() ) {
429 if ( wc_get_loop_prop( 'total' ) ) {
430 if ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) {
431 echo '<div class="rtsb-active-filters-wrapper"></div>';
432 }
433
434 // Row.
435 $this->row( $this->product_loop( $wp_query, $metas, $template ), $metas );
436 }
437
438 // Pagination.
439 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
440
441 if ( $pagination ) {
442 if ( Fns::product_filters_has_ajax( 'shop' ) || Fns::product_filters_has_ajax( 'archive' ) ) {
443 if ( $wp_query->max_num_pages > 1 ) {
444 $this->html .= "
445 <div class='rtsb-load-more rtsb-pos-r'>
446 <button data-paged='2' data-max-page='{$wp_query->max_num_pages}'><span>" . esc_html__( 'Load More', 'shopbuilder-pro' ) . "</span></button>
447 <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
448 </div>
449 ";
450 }
451 } else {
452 $this->html .= RenderHelpers::render_pagination(
453 $wp_query,
454 $metas,
455 wc_get_loop_prop( 'total' ),
456 $posts_per_page
457 );
458 }
459 }
460
461 $this->html .= '</div>';
462 } else {
463 $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
464
465 $this->row( $content, $metas );
466 }
467
468 if ( $is_preview ) {
469 $wp_query = $main_query;
470 $post = $main_post;
471
472 wp_reset_query();
473 wp_reset_postdata();
474 }
475
476 // Container.
477 $this->container( $this->html, $settings, 'rtsb-products-container', $template );
478
479 return $this->html;
480 }
481
482 /**
483 * Render Product View.
484 *
485 * @param string $template Template name.
486 * @param array $settings Control settings.
487 *
488 * @return string
489 */
490 public function setup_loop_for_product_view( $template, $settings, $widget ) {
491 if ( empty( $settings['query_products'] ) ) {
492 return $this->html;
493 }
494
495 $html = null;
496
497 $metas = RenderHelpers::meta_dataset( $settings, '', $widget->get_settings_for_display() );
498
499 foreach ( $settings['query_products'] as $_product ) {
500 $post_object = get_post( $_product->get_id() );
501
502 setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found
503
504 // Loop arg.
505 $arg = $this->arg_dataset( $metas, $_product->get_id() );
506 // Get template.
507 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
508
509 $this->row( $html, $metas );
510 }
511
512 // Container.
513 $this->container( $this->html, $settings, 'rtsb-products-container' );
514
515 wp_reset_postdata();
516
517 return $this->html;
518 }
519
520 /**
521 * Render Category View.
522 *
523 * @param string $template Template name.
524 * @param array $settings Control settings.
525 * @param bool $is_single Single category.
526 *
527 * @return string
528 */
529 public function category_view( $template, $settings, $is_single = false ) {
530 $this->get_settings = $settings;
531
532 $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
533 $taxonomy = $metas['category_source'];
534 $term = $metas['category_term'];
535
536 if ( rtsb()->has_pro() && ( ! empty( $metas['tag_term'] ) ) ) {
537 $term = $metas['tag_term'];
538 }
539
540 // Query.
541 if ( $is_single ) {
542 if ( empty( $term ) ) {
543 return '<p>' . esc_html__( 'Please select a category.', 'shopbuilder' ) . '</p>';
544 }
545
546 $taxonomy_query = get_term( $term, $taxonomy );
547 } else {
548 // Query Args.
549 $args = ( new QueryArgs() )->buildArgs( $metas, 'category' );
550
551 $taxonomy_query = get_terms( $args );
552 }
553
554 if ( ! empty( $taxonomy_query ) ) {
555 // Row.
556 $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
557 } else {
558 $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
559 }
560
561 // Container.
562 $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
563
564 return $this->html;
565 }
566
567 /**
568 * Render Category View.
569 *
570 * @param string $template Template name.
571 * @param array $settings Control settings.
572 *
573 * @return string
574 */
575 public function social_share_view( $template, $settings ) {
576 $this->get_settings = $settings;
577 $share_items = [];
578
579 foreach ( $settings['share_platforms'] as $platform ) {
580 $share_items[] = [
581 'share_items' => $platform['share_items'],
582 'share_text' => $platform['share_text'],
583 ];
584 }
585
586 if ( ! empty( $share_items ) && is_array( $share_items ) ) {
587 $arg['p_id'] = get_the_ID();
588 $arg['share_items'] = $share_items;
589 $arg['preset'] = $settings['layout'];
590 $arg['direction'] = ! empty( $settings['layout_direction'] ) ? $settings['layout_direction'] : 'horizontal';
591 $arg['show_icon'] = ! empty( $settings['show_share_icon'] );
592 $arg['show_text'] = ! empty( $settings['show_share_text'] );
593 $arg['show_pre_text'] = ! empty( $settings['show_share_pre_text'] );
594 $arg['share_pre_text'] = ! empty( $settings['share_pre_text'] ) ? $settings['share_pre_text'] : '';
595 $arg['raw_settings'] = $this->get_settings_for_display();
596 $this->html = Fns::load_template( $template, $arg, true );
597 } else {
598 $this->html = '<p>' . esc_html__( 'Please select a social sharing platform.', 'shopbuilder' ) . '</p>';
599 }
600
601 return $this->html;
602 }
603
604 /**
605 * Builds an array with meta values.
606 *
607 * @param array $meta Meta values.
608 * @param int $post_id Post ID.
609 * @param bool $lazy_load Lazy Load.
610 * @param int $i Integer.
611 *
612 * @return array
613 */
614 public function arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
615 if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
616 return [];
617 }
618
619 global $post;
620
621 $arg = [];
622 $_product = wc_get_product( $post_id );
623 $p_type = $_product->get_type();
624
625 $arg['class'] = null;
626 $arg['grid'] = null;
627 $arg['anchor_class'] = null;
628 $arg['hover_img_html'] = null;
629 $arg['s_link'] = [];
630 $arg['add_to_cart'] = '';
631 $arg['p_id'] = $post_id;
632 $arg['p_link'] = get_permalink();
633 $arg['p_sale'] = '';
634 $arg['has_attributes'] = $_product->is_type( 'variable' ) && $_product->get_attributes();
635 $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
636 $cart_icon_html = '';
637
638 $layout = $meta['layout'];
639
640 $arg['target'] = '_self';
641 $arg['f_img'] = $meta['f_img'];
642 $arg['items'] = $meta['visibility'];
643 $arg['title_tag'] = $meta['title_tag'];
644 $arg['title_class'] = 'product-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
645 $arg['title'] = Fns::text_truncation( get_the_title(), $meta['title_limit_custom'] );
646 $arg['excerpt_limit'] = $meta['excerpt_limit'];
647 $arg['excerpt'] = wpautop( Fns::text_truncation( do_shortcode( $post->post_excerpt ), $meta['excerpt_limit_custom'] ) );
648 $arg['title_link'] = $meta['title_link'];
649 $arg['image_link'] = $meta['image_link'];
650 $arg['out_of_stock'] = $meta['out_of_stock_badge_text'];
651 $arg['action_btn_preset'] = $meta['btn_preset'];
652 $arg['action_btn_position'] = $meta['btn_position'];
653 $arg['swatch_position'] = $meta['swatch_position'];
654 $arg['swatch_type'] = $meta['swatch_type'];
655 $arg['tooltip_position'] = $meta['tooltip_position'];
656
657 $is_list = preg_match( '/list/', $layout );
658 $is_carousel = preg_match( '/slider/', $layout );
659
660 if ( ! $is_carousel ) {
661 $arg['grid'] .= 'rtsb-col-grid ';
662 $arg['class'] .= ' even-grid-item ';
663 } else {
664 $arg['grid'] .= 'rtsb-col-grid rtsb-col-full rtsb-slide-item swiper-slide ';
665 }
666
667 $d_cols = 0 === $meta['d_cols'] ? RenderHelpers::default_columns( $layout ) : $meta['d_cols'];
668 $t_cols = 0 === $meta['t_cols'] ? 2 : $meta['t_cols'];
669 $m_cols = 0 === $meta['m_cols'] ? 1 : $meta['m_cols'];
670
671 $arg['grid'] .= 0 === $i % $d_cols ? ' row-last desktop-row-last' : '';
672 $arg['grid'] .= 0 === $i % $t_cols ? ' row-last tablet-row-last' : '';
673 $arg['grid'] .= 0 === $i % $m_cols ? ' row-last mobile-row-last' : '';
674
675 $arg['class'] .= 'rtsb-product';
676
677 if ( $is_list ) {
678 $arg['class'] .= ' rtsb-product-list';
679 }
680
681 $arg['class'] .= ' animated rtFadeIn';
682
683 if ( in_array( 'badges', $meta['visibility'], true ) ) {
684 $arg['p_sale'] = Fns::get_sale_badge(
685 $meta['sale_badge_type'],
686 $meta['sale_badge_text'],
687 $meta['out_of_stock_badge_text']
688 );
689 }
690
691 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
692
693 if ( ! $meta['show_cart_text'] ) {
694 $meta['add_to_cart_text'] = '';
695 $meta['add_to_cart_success_text'] = '';
696 }
697
698 if ( in_array( 'add_to_cart', $meta['visibility'], true ) ) {
699 if ( ! empty( $meta['add_to_cart_icon'] ) ) {
700 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_icon'], 'cart-icon' );
701 }
702
703 if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
704 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
705 }
706
707 $cart_icon = '<span class="icon">' . $cart_icon_html . '</span>';
708
709 if ( $_product->is_purchasable() ) {
710 if ( $_product->is_in_stock() ) {
711 $arg['add_to_cart'] = $this->render_add_to_cart_button(
712 get_permalink(),
713 $post_id,
714 $p_type,
715 $meta['add_to_cart_text'],
716 $meta['add_to_cart_success_text'],
717 $cart_icon,
718 $meta['add_to_cart_alignment']
719 );
720 }
721 }
722 }
723
724 if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
725 add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
726 add_filter( 'rtsb/module/quick_view/icon_html', [ $this, 'quick_view_icon' ] );
727 }
728
729 if ( in_array( 'compare', $meta['visibility'], true ) ) {
730 add_filter( 'rtsb/module/compare/button_params', [ $this, 'button_classes' ] );
731 add_filter( 'rtsb/module/compare/icon_html', [ $this, 'compare_icon' ] );
732 }
733
734 if ( in_array( 'wishlist', $meta['visibility'], true ) ) {
735 add_filter( 'rtsb/module/wishlist/button_params', [ $this, 'button_classes' ] );
736 add_filter( 'rtsb/module/wishlist/icon_html', [ $this, 'wishlist_icon' ] );
737 }
738
739 $arg['img_html'] = $meta['f_img'] ? Fns::get_product_image_html(
740 'product',
741 $post_id,
742 $meta['f_img_size'],
743 $meta['default_img_id'],
744 $meta['custom_img_size'],
745 $lazy_load
746 ) : null;
747
748 if ( ! ( function_exists( 'rtwpvsp' ) && $_product->is_type( 'variable' ) && $_product->get_attributes() ) ) {
749 $gallery_ids = $_product->get_gallery_image_ids();
750
751 if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
752 $arg['class'] .= ! $meta['gallery_img'] ? ' rtsb-double-img' : '';
753
754 if ( ! rtsb()->has_pro() ) {
755 $arg['class'] .= ' rtsb-double-img';
756 }
757
758 $arg['hover_img_html'] = Fns::get_product_image_html(
759 'product',
760 $gallery_ids[0],
761 $meta['f_img_size'],
762 null,
763 $meta['custom_img_size'],
764 $lazy_load,
765 true
766 );
767 }
768 }
769
770 $arg['hover_btn_text'] = $meta['hover_btn_text'];
771
772 if ( $meta['show_hover_btn_icon'] && ! empty( $meta['hover_btn_icon'] ) ) {
773 $arg['hover_btn_icon'] = '<span class="icon">' . Fns::icons_manager( $meta['hover_btn_icon'], 'hover-btn-icon' ) . '</span>';
774 }
775
776 $arg['img_args'] = [
777 'p_id' => $arg['p_id'],
778 'title' => get_the_title(),
779 'p_link' => $arg['p_link'],
780 'image_link' => $arg['image_link'],
781 'img_html' => $arg['img_html'],
782 'hover_img_html' => $arg['hover_img_html'],
783 'meta' => $meta,
784 ];
785
786 return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
787 }
788
789 /**
790 * Builds an array with meta values.
791 *
792 * @param array $meta Meta values.
793 * @param Object $query Category object.
794 * @param bool $fullwidth Fullwidth check.
795 * @param bool $lazy_load Lazy Load.
796 *
797 * @return array
798 */
799 public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false ) {
800 if ( empty( $meta ) ) {
801 return [];
802 }
803
804 $arg = [];
805
806 $arg['class'] = null;
807 $arg['grid'] = null;
808 $arg['anchor_class'] = null;
809 $arg['p_sale'] = null;
810 $arg['count'] = max( $query->count, 0 );
811 $arg['count_position'] = $meta['count_position'];
812 $arg['excerpt_position'] = $meta['cat_excerpt_position'];
813 $arg['cat_link'] = get_term_link( $query );
814 $arg['target'] = '_self';
815 $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
816
817 if ( ! empty( $meta['tag_term'] ) ) {
818 $arg['tag_term'] = $meta['tag_term'];
819 }
820
821 if ( ! empty( $meta['custom_link']['url'] ) ) {
822 $arg['cat_link'] = $meta['custom_link']['url'];
823 $arg['target'] = $meta['custom_link']['is_external'] ? '_blank' : '_self';
824 }
825
826 $title = $query->name;
827 $excerpt = $query->description;
828
829 if ( in_array( 'badges', $meta['visibility'], true ) ) {
830 $arg['p_sale'] = $meta['custom_badge_text'];
831 }
832
833 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
834
835 if ( $arg['count'] >= 0 ) {
836 $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
837 $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
838
839 $arg['count'] = $prefix . $arg['count'] . $suffix;
840 }
841
842 if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
843 $title = $meta['cat_custom_title'];
844 }
845
846 if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
847 $excerpt = $meta['cat_custom_excerpt'];
848 }
849
850 $layout = $meta['layout'];
851
852 $arg['c_img'] = $meta['c_img'];
853 $arg['items'] = $meta['visibility'];
854 $arg['title_tag'] = $meta['title_tag'];
855 $arg['title_class'] = 'category-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
856 $arg['title'] = Fns::text_truncation( $title, $meta['title_limit_custom'] );
857 $arg['excerpt_limit'] = $meta['excerpt_limit'];
858 $arg['excerpt'] = wpautop( Fns::text_truncation( $excerpt, $meta['excerpt_limit_custom'] ) );
859 $arg['title_link'] = $meta['title_link'];
860 $arg['image_link'] = $meta['image_link'];
861
862 if ( ! $fullwidth ) {
863 $arg['grid'] .= 'rtsb-col-grid ';
864 $arg['class'] .= ' even-grid-item ';
865 } else {
866 $arg['grid'] .= 'rtsb-col-grid ';
867 }
868
869 $arg['class'] .= 'rtsb-category-grid';
870
871 $arg['img_html'] = $meta['c_img'] ? Fns::get_product_image_html(
872 'category',
873 $query->term_id,
874 $meta['f_img_size'],
875 $meta['default_img_id'],
876 $meta['custom_img_size'],
877 $lazy_load
878 ) : null;
879
880 if ( $meta['show_custom_image'] && ! empty( $meta['custom_image'] ) ) {
881 $arg['img_html'] = Fns::get_product_image_html(
882 'custom',
883 null,
884 $meta['f_img_size'],
885 $meta['custom_image'],
886 $meta['custom_img_size'],
887 $lazy_load
888 );
889 }
890
891 $arg['excerpt_class'] = 'category-info' . ( 'block' === $meta['count_position'] ? ' block-count' : ' inline-count' ) . ( 'above' === $meta['cat_excerpt_position'] ? ' excerpt-above' : '' ) . ( empty( $arg['excerpt'] ) ? ' no-excerpt' : '' );
892
893 return $arg;
894 }
895
896 /**
897 * Renders add to cart button.
898 *
899 * @param string $link Product link.
900 * @param int $id Product ID.
901 * @param string $type Product type.
902 * @param string $text Custom text.
903 * @param string $success Success text.
904 * @param string $icon_html Custom icon.
905 * @param string $alignment Icon alignment.
906 *
907 * @return string
908 */
909 public function render_add_to_cart_button( $link, $id, $type, $text, $success, $icon_html, $alignment ) {
910 $content = null;
911 $tooltip_attr = '';
912
913 if ( empty( $text ) ) {
914 $tooltip_attr = ' title="' . esc_attr__( 'Add to Cart', 'shopbuilder' ) . '"';
915
916 if ( 'variable' === $type ) {
917 $tooltip_attr = ' title="' . esc_attr__( 'Select Options', 'shopbuilder' ) . '"';
918 }
919 }
920 ob_start();
921 do_action( 'rtsb/before/cart/button' );
922 $content .= ob_get_clean();
923
924 if ( 'variable' === $type ) {
925 $content .= sprintf(
926 '<div class="rtsb-wc-add-to-cart-wrap">
927 <a href="%1$s" data-quantity="1" class="rtsb-action-btn variable-product tipsy icon-%4$s %5$s" data-product_id="%3$s" rel="nofollow"%6$s>%7$s<span class="text">%2$s</span></a>
928 </div>',
929 esc_url( $link ),
930 esc_html__( 'Select Options', 'shopbuilder' ),
931 absint( $id ),
932 esc_attr( $alignment ),
933 empty( $text ) ? 'no-text' : 'has-text',
934 $tooltip_attr,
935 $icon_html,
936 );
937 } else {
938 $content .= sprintf(
939 '<a href="%1$s?add-to-cart=%2$d" data-quantity="1" class="rtsb-action-btn rtsb-add-to-cart-btn tipsy icon-%6$s %7$s" data-id="%2$d" data-type="%3$s"%8$s>%4$s<span class="text %10$s" data-success="%9$s">%5$s</span><span></span></a>',
940 esc_url( $link ),
941 absint( $id ),
942 esc_attr( $type ),
943 $icon_html,
944 esc_html( $text ),
945 esc_attr( $alignment ),
946 empty( $text ) ? 'no-text' : 'has-text',
947 $tooltip_attr,
948 esc_html( $success ),
949 ! empty( $success ) ? 'has-success-text' : 'no-success-text',
950 );
951 }
952
953 ob_start();
954 do_action( 'rtsb/after/cart/button' );
955 $content .= ob_get_clean();
956
957 return $content;
958 }
959
960 /**
961 * Button classes.
962 *
963 * @param array $params Button params.
964 *
965 * @return array
966 */
967 public function button_classes( $params ) {
968 $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
969
970 return $params;
971 }
972 }
973