PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.0.1
ShopBuilder – WooCommerce Builder For Elementor v2.0.1
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.1, at app/Elementor/Render/Render.php

1,013 lines 31.0 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 * @param array $raw_settings Raw Settings.
179 *
180 * @return string
181 */
182 public function row( $content, $settings, $hook_html = '', $raw_settings = [] ) {
183 $masonry_class = null;
184 $loader_class = ' rtsb-pre-loader';
185
186 $layout = $settings['layout'];
187 $grid_type = $settings['grid_type'];
188 $is_carousel = preg_match( '/slider/', $layout );
189
190 if ( 'even' === $grid_type ) {
191 $masonry_class = ' rtsb-even';
192 } elseif ( 'masonry' === $grid_type ) {
193 $masonry_class = ' rtsb-masonry';
194 }
195
196 if ( ! rtsb()->has_pro() || $is_carousel ) {
197 $masonry_class = ' rtsb-even';
198 }
199
200 $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 );
201 $row_wrapper = '<div data-title="' . esc_html__( 'Loading ...', 'shopbuilder' ) . '" class="' . $row_start_class . '">';
202 $start_wrapper = apply_filters( 'rtsb/custom/layout/row/start', $row_wrapper, $row_start_class );
203 if ( ! empty( $settings['show_filter'] ) ) {
204 $this->html = $hook_html;
205 $this->html .= $start_wrapper;
206 } else {
207 $this->html = $start_wrapper;
208 }
209
210 if ( $is_carousel ) {
211 $slider_data = RenderHelpers::slider_data( $settings, $raw_settings );
212
213 $this->html .= '<div class="rtsb-col-grid ' . esc_attr( $slider_data['class'] ) . '" ' . $slider_data['data'] . '>';
214 $this->html .= '<div class="swiper-wrapper">';
215 }
216
217 $this->html .= $content;
218
219 if ( $is_carousel ) {
220 $this->html .= '</div><!-- .swiper-wrapper -->';
221
222 $left_icon = $settings['left_arrow_icon'];
223 $right_icon = $settings['right_arrow_icon'];
224
225 if ( ! empty( $settings['slider_nav'] ) ) {
226 $this->html .=
227 '<div class="swiper-nav">
228 <div class="swiper-arrow swiper-button-next">
229 ' . Fns::icons_manager( $right_icon ) . '
230 </div>
231 <div class="swiper-arrow swiper-button-prev">
232 ' . Fns::icons_manager( $left_icon ) . '
233 </div>
234 </div>';
235 }
236
237 $this->html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
238
239 $this->html .= '</div><!-- .rtsb-carousel-slider -->';
240 }
241
242 $row_end = '</div><!-- .rtsb-row -->';
243
244 $this->html .= apply_filters( 'rtsb/custom/layout/row/end', $row_end );
245
246 $this->html .= RenderHelpers::pre_loader( $layout );
247
248 return $this->html;
249 }
250
251 /**
252 * Product loop.
253 *
254 * @param object $query The query.
255 * @param array $settings Settings.
256 * @param string $template Template.
257 *
258 * @return string|null
259 */
260 public function product_loop( $query, $settings, $template ) {
261 $html = null;
262
263 if ( empty( $query ) ) {
264 return null;
265 }
266
267 $i = 0;
268
269 while ( $query->have_posts() ) {
270 $query->the_post();
271 $i++;
272
273 // Loop arg.
274 $arg = $this->arg_dataset( $settings, get_the_ID(), $settings['lazy_load'], $i );
275
276 // Get template.
277 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
278 }
279
280 return $html;
281 }
282
283 /**
284 * Product loop.
285 *
286 * @param object $query The query.
287 * @param array $settings Settings.
288 * @param string $template Template.
289 * @param bool $is_single Single category.
290 *
291 * @return string|null
292 */
293 public function category_loop( $query, $settings, $template, $is_single = false ) {
294 $html = null;
295
296 if ( $is_single ) {
297 // Loop arg.
298 $arg = $this->cat_arg_dataset( $settings, $query, true );
299
300 // Get template.
301 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
302 } else {
303 foreach ( $query as $term ) {
304 // Loop arg.
305 $arg = $this->cat_arg_dataset( $settings, $term );
306
307 // Get template.
308 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
309 }
310 }
311
312 return $html;
313 }
314
315 /**
316 * Render Product View.
317 *
318 * @param string $template Template name.
319 * @param array $settings Control settings.
320 *
321 * @return string
322 */
323 public function product_view( $template, $settings ) {
324 $this->get_settings = $settings;
325
326 $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
327 $is_carousel = preg_match( '/slider/', $metas['layout'] );
328 $pagination = $metas['pagination'];
329 $hook_html = '';
330
331 // Query Args.
332 $args = ( new QueryArgs() )->buildArgs( $metas, 'product', $is_carousel );
333
334 $temp_args = $args;
335 $args = apply_filters( 'rtsb/elementor/args_before_loop', $args, $metas );
336
337 // Query.
338 $product_query = new WP_Query( $args );
339
340 if ( $product_query->have_posts() ) {
341 // Elementor Render hook before row.
342 ob_start();
343 do_action( 'rtsb/elementor/render/before_row', $metas, $settings, $product_query, $temp_args );
344 $hook_html .= ob_get_clean();
345
346 // Row.
347 $this->row( $this->product_loop( $product_query, $metas, $template ), $metas, $hook_html, $settings );
348
349 // Pagination.
350 if ( $pagination ) {
351 $this->html .= RenderHelpers::render_pagination(
352 $product_query,
353 $metas,
354 $settings['posts_limit'],
355 $settings['pagination_per_page']
356 );
357 }
358
359 // Elementor Render hook before row.
360 ob_start();
361 do_action( 'rtsb/elementor/render/after_row', $metas, $settings, $product_query );
362 $this->html .= ob_get_clean();
363
364 } else {
365 $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
366
367 $this->row( $content, $metas );
368 }
369
370 wp_reset_postdata();
371
372 unset( $args['tax_query'] );
373
374 // Container.
375 $this->container( $this->html, $settings, 'rtsb-products-container', $template, $is_carousel );
376
377 return $this->html;
378 }
379
380
381 /**
382 * Render Product View.
383 *
384 * @param string $template Template name.
385 * @param array $settings Control settings.
386 * @param object $widget Reference widget.
387 *
388 * @return string
389 */
390 public function wc_loop_for_product_view( $template, $settings, $widget ) {
391 global $wp_query, $post;
392
393 $this->get_settings = $settings;
394 $metas = RenderHelpers::meta_dataset( $settings, $template, $widget->get_settings_for_display() );
395
396 $settings['rtsb_order'] = ! empty( $wp_query->query_vars['order'] ) ? $wp_query->query_vars['order'] : 'ASC';
397 $settings['rtsb_orderby'] = ! empty( $wp_query->query_vars['orderby'] ) ? $wp_query->query_vars['orderby'] : 'menu_order';
398
399 $pagination = $metas['pagination'];
400
401 $page_type = BuilderFns::builder_type( get_the_ID() );
402 $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
403 $posts_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
404
405 if ( $is_preview ) {
406 $main_query = clone $wp_query;
407 $main_post = clone $post;
408
409 $ordering = ( new \WC_Query() )->get_catalog_ordering_args();
410 $wp_query_args = [
411 'post_type' => 'product',
412 'posts_per_page' => $posts_per_page,
413 ];
414
415 if ( ! empty( $ordering['orderby'] ) ) {
416 $wp_query_args['orderby'] = $ordering['orderby'];
417 }
418
419 if ( ! empty( $ordering['order'] ) ) {
420 $wp_query_args['order'] = $ordering['order'];
421 }
422
423 $wp_query = new \WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
424 wc_set_loop_prop( 'total', $wp_query->found_posts );
425 wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
426 }
427
428 // column_per_row.
429 if ( woocommerce_product_loop() ) {
430 if ( wc_get_loop_prop( 'total' ) ) {
431 if ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) {
432 echo '<div class="rtsb-active-filters-wrapper"></div>';
433 }
434
435 // Row.
436 $this->row( $this->product_loop( $wp_query, $metas, $template ), $metas );
437 }
438
439 // Pagination.
440 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
441
442 if ( $pagination ) {
443 if ( Fns::product_filters_has_ajax( 'shop' ) || Fns::product_filters_has_ajax( 'archive' ) ) {
444 if ( $wp_query->max_num_pages > 1 ) {
445 $this->html .= "
446 <div class='rtsb-load-more rtsb-pos-r'>
447 <button data-paged='2' data-max-page='{$wp_query->max_num_pages}'><span>" . esc_html__( 'Load More', 'shopbuilder-pro' ) . "</span></button>
448 <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
449 </div>
450 ";
451 }
452 } else {
453 $this->html .= RenderHelpers::render_pagination(
454 $wp_query,
455 $metas,
456 wc_get_loop_prop( 'total' ),
457 $posts_per_page
458 );
459 }
460 }
461
462 $this->html .= '</div>';
463 } else {
464 $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
465
466 $this->row( $content, $metas );
467 }
468
469 if ( $is_preview ) {
470 $wp_query = $main_query;
471 $post = $main_post;
472
473 wp_reset_query();
474 wp_reset_postdata();
475 }
476
477 // Container.
478 $this->container( $this->html, $settings, 'rtsb-products-container', $template );
479
480 return $this->html;
481 }
482
483 /**
484 * Render Product View.
485 *
486 * @param string $template Template name.
487 * @param array $settings Control settings.
488 *
489 * @return string
490 */
491 public function setup_loop_for_product_view( $template, $settings, $widget ) {
492 if ( empty( $settings['query_products'] ) ) {
493 return $this->html;
494 }
495
496 $html = null;
497
498 $metas = RenderHelpers::meta_dataset( $settings, '', $widget->get_settings_for_display() );
499
500 foreach ( $settings['query_products'] as $_product ) {
501 $post_object = get_post( $_product->get_id() );
502
503 setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found
504
505 // Loop arg.
506 $arg = $this->arg_dataset( $metas, $_product->get_id() );
507 // Get template.
508 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
509
510 $this->row( $html, $metas );
511 }
512
513 // Container.
514 $this->container( $this->html, $settings, 'rtsb-products-container' );
515
516 wp_reset_postdata();
517
518 return $this->html;
519 }
520
521 /**
522 * Render Category View.
523 *
524 * @param string $template Template name.
525 * @param array $settings Control settings.
526 * @param bool $is_single Single category.
527 *
528 * @return string
529 */
530 public function category_view( $template, $settings, $is_single = false ) {
531 $this->get_settings = $settings;
532
533 $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
534 $taxonomy = $metas['category_source'];
535 $term = $metas['category_term'];
536
537 if ( rtsb()->has_pro() && ( ! empty( $metas['tag_term'] ) ) ) {
538 $term = $metas['tag_term'];
539 }
540
541 // Query.
542 if ( $is_single ) {
543 if ( empty( $term ) ) {
544 return '<p>' . esc_html__( 'Please select a category.', 'shopbuilder' ) . '</p>';
545 }
546
547 $taxonomy_query = get_term( $term, $taxonomy );
548 } else {
549 // Query Args.
550 $args = ( new QueryArgs() )->buildArgs( $metas, 'category' );
551
552 $taxonomy_query = get_terms( $args );
553 }
554
555 if ( ! empty( $taxonomy_query ) ) {
556 // Row.
557 $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
558 } else {
559 $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
560 }
561
562 // Container.
563 $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
564
565 return $this->html;
566 }
567
568 /**
569 * Render Category View.
570 *
571 * @param string $template Template name.
572 * @param array $settings Control settings.
573 *
574 * @return string
575 */
576 public function social_share_view( $template, $settings ) {
577 $this->get_settings = $settings;
578 $share_items = [];
579
580 foreach ( $settings['share_platforms'] as $platform ) {
581 $share_items[] = [
582 'share_items' => $platform['share_items'],
583 'share_text' => $platform['share_text'],
584 ];
585 }
586
587 if ( ! empty( $share_items ) && is_array( $share_items ) ) {
588 $arg['p_id'] = get_the_ID();
589 $arg['share_items'] = $share_items;
590 $arg['preset'] = $settings['layout'];
591 $arg['direction'] = ! empty( $settings['layout_direction'] ) ? $settings['layout_direction'] : 'horizontal';
592 $arg['show_icon'] = ! empty( $settings['show_share_icon'] );
593 $arg['show_text'] = ! empty( $settings['show_share_text'] );
594 $arg['show_pre_text'] = ! empty( $settings['show_share_pre_text'] );
595 $arg['share_pre_text'] = ! empty( $settings['share_pre_text'] ) ? $settings['share_pre_text'] : '';
596 $arg['raw_settings'] = $this->get_settings_for_display();
597 $this->html = Fns::load_template( $template, $arg, true );
598 } else {
599 $this->html = '<p>' . esc_html__( 'Please select a social sharing platform.', 'shopbuilder' ) . '</p>';
600 }
601
602 return $this->html;
603 }
604
605 /**
606 * Builds an array with meta values.
607 *
608 * @param array $meta Meta values.
609 * @param int $post_id Post ID.
610 * @param bool $lazy_load Lazy Load.
611 * @param int $i Integer.
612 *
613 * @return array
614 */
615 public function arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
616 if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
617 return [];
618 }
619
620 global $post;
621
622 $arg = [];
623 $_product = wc_get_product( $post_id );
624 $p_type = $_product->get_type();
625
626 $arg['class'] = null;
627 $arg['grid'] = null;
628 $arg['anchor_class'] = null;
629 $arg['hover_img_html'] = null;
630 $arg['s_link'] = [];
631 $arg['add_to_cart'] = '';
632 $arg['p_id'] = $post_id;
633 $arg['p_link'] = get_permalink();
634 $arg['p_sale'] = '';
635 $arg['has_attributes'] = $_product->is_type( 'variable' ) && $_product->get_attributes();
636 $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
637 $cart_icon_html = '';
638
639 $layout = $meta['layout'];
640
641 $arg['target'] = '_self';
642 $arg['f_img'] = $meta['f_img'];
643 $arg['items'] = $meta['visibility'];
644 $arg['title_tag'] = $meta['title_tag'];
645 $arg['title_class'] = 'product-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
646 $arg['title'] = Fns::text_truncation( get_the_title(), $meta['title_limit_custom'] );
647 $arg['excerpt_limit'] = $meta['excerpt_limit'];
648 $arg['excerpt'] = wpautop( Fns::text_truncation( do_shortcode( $post->post_excerpt ), $meta['excerpt_limit_custom'] ) );
649 $arg['title_link'] = $meta['title_link'];
650 $arg['image_link'] = $meta['image_link'];
651 $arg['out_of_stock'] = $meta['out_of_stock_badge_text'];
652 $arg['action_btn_preset'] = $meta['btn_preset'];
653 $arg['action_btn_position'] = $meta['btn_position'];
654 $arg['swatch_position'] = $meta['swatch_position'];
655 $arg['swatch_type'] = $meta['swatch_type'];
656 $arg['tooltip_position'] = $meta['tooltip_position'];
657
658 $is_list = preg_match( '/list/', $layout );
659 $is_carousel = preg_match( '/slider/', $layout );
660
661 if ( ! $is_carousel ) {
662 $arg['grid'] .= 'rtsb-col-grid ';
663 $arg['class'] .= ' even-grid-item ';
664 } else {
665 $arg['grid'] .= 'rtsb-col-grid rtsb-col-full rtsb-slide-item swiper-slide ';
666 }
667
668 $d_cols = 0 === $meta['d_cols'] ? RenderHelpers::default_columns( $layout ) : $meta['d_cols'];
669 $t_cols = 0 === $meta['t_cols'] ? 2 : $meta['t_cols'];
670 $m_cols = 0 === $meta['m_cols'] ? 1 : $meta['m_cols'];
671
672 $arg['grid'] .= 0 === $i % $d_cols ? ' row-last desktop-row-last' : '';
673 $arg['grid'] .= 0 === $i % $t_cols ? ' row-last tablet-row-last' : '';
674 $arg['grid'] .= 0 === $i % $m_cols ? ' row-last mobile-row-last' : '';
675
676 $arg['class'] .= 'rtsb-product';
677
678 if ( $is_list ) {
679 $arg['class'] .= ' rtsb-product-list';
680 }
681
682 $arg['class'] .= ' animated rtFadeIn';
683
684 if ( in_array( 'badges', $meta['visibility'], true ) ) {
685 $arg['p_sale'] = Fns::get_sale_badge(
686 $meta['sale_badge_type'],
687 $meta['sale_badge_text'],
688 $meta['out_of_stock_badge_text']
689 );
690 }
691
692 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
693
694 if ( ! $meta['show_cart_text'] ) {
695 $meta['add_to_cart_text'] = '';
696 $meta['add_to_cart_success_text'] = '';
697 }
698
699 if ( in_array( 'add_to_cart', $meta['visibility'], true ) ) {
700 if ( ! empty( $meta['add_to_cart_icon'] ) ) {
701 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_icon'], 'cart-icon' );
702 }
703
704 if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
705 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
706 }
707
708 $cart_icon = '<span class="icon">' . $cart_icon_html . '</span>';
709
710 if ( $_product->is_purchasable() || 'grouped' === $p_type || 'external' === $p_type ) {
711 if ( $_product->is_in_stock() ) {
712 $arg['add_to_cart'] = $this->render_add_to_cart_button(
713 get_permalink(),
714 $post_id,
715 $p_type,
716 $meta['add_to_cart_text'],
717 $meta['add_to_cart_success_text'],
718 $cart_icon,
719 $meta['add_to_cart_alignment']
720 );
721 }
722 }
723 }
724
725 if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
726 add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
727 add_filter( 'rtsb/module/quick_view/icon_html', [ $this, 'quick_view_icon' ] );
728 }
729
730 if ( in_array( 'compare', $meta['visibility'], true ) ) {
731 add_filter( 'rtsb/module/compare/button_params', [ $this, 'button_classes' ] );
732 add_filter( 'rtsb/module/compare/icon_html', [ $this, 'compare_icon' ] );
733 }
734
735 if ( in_array( 'wishlist', $meta['visibility'], true ) ) {
736 add_filter( 'rtsb/module/wishlist/button_params', [ $this, 'button_classes' ] );
737 add_filter( 'rtsb/module/wishlist/icon_html', [ $this, 'wishlist_icon' ] );
738 }
739
740 $arg['img_html'] = $meta['f_img'] ? Fns::get_product_image_html(
741 'product',
742 $post_id,
743 $meta['f_img_size'],
744 $meta['default_img_id'],
745 $meta['custom_img_size'],
746 $lazy_load
747 ) : null;
748
749 if ( ! ( function_exists( 'rtwpvsp' ) && $_product->is_type( 'variable' ) && $_product->get_attributes() ) ) {
750 $gallery_ids = $_product->get_gallery_image_ids();
751
752 if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
753 $arg['class'] .= ! $meta['gallery_img'] ? ' rtsb-double-img' : '';
754
755 if ( ! rtsb()->has_pro() ) {
756 $arg['class'] .= ' rtsb-double-img';
757 }
758
759 $arg['hover_img_html'] = Fns::get_product_image_html(
760 'product',
761 $gallery_ids[0],
762 $meta['f_img_size'],
763 null,
764 $meta['custom_img_size'],
765 $lazy_load,
766 true
767 );
768 }
769 }
770
771 $arg['hover_btn_text'] = $meta['hover_btn_text'];
772
773 if ( $meta['show_hover_btn_icon'] && ! empty( $meta['hover_btn_icon'] ) ) {
774 $arg['hover_btn_icon'] = '<span class="icon">' . Fns::icons_manager( $meta['hover_btn_icon'], 'hover-btn-icon' ) . '</span>';
775 }
776
777 $arg['img_args'] = [
778 'p_id' => $arg['p_id'],
779 'title' => get_the_title(),
780 'p_link' => $arg['p_link'],
781 'image_link' => $arg['image_link'],
782 'img_html' => $arg['img_html'],
783 'hover_img_html' => $arg['hover_img_html'],
784 'meta' => $meta,
785 ];
786
787 return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
788 }
789
790 /**
791 * Builds an array with meta values.
792 *
793 * @param array $meta Meta values.
794 * @param Object $query Category object.
795 * @param bool $fullwidth Fullwidth check.
796 * @param bool $lazy_load Lazy Load.
797 *
798 * @return array
799 */
800 public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false ) {
801 if ( empty( $meta ) ) {
802 return [];
803 }
804
805 $arg = [];
806
807 $arg['class'] = null;
808 $arg['grid'] = null;
809 $arg['anchor_class'] = null;
810 $arg['p_sale'] = null;
811 $arg['count'] = max( $query->count, 0 );
812 $arg['count_position'] = $meta['count_position'];
813 $arg['excerpt_position'] = $meta['cat_excerpt_position'];
814 $arg['cat_link'] = get_term_link( $query );
815 $arg['target'] = '_self';
816 $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
817
818 if ( ! empty( $meta['tag_term'] ) ) {
819 $arg['tag_term'] = $meta['tag_term'];
820 }
821
822 if ( ! empty( $meta['custom_link']['url'] ) ) {
823 $arg['cat_link'] = $meta['custom_link']['url'];
824 $arg['target'] = $meta['custom_link']['is_external'] ? '_blank' : '_self';
825 }
826
827 $title = $query->name;
828 $excerpt = $query->description;
829
830 if ( in_array( 'badges', $meta['visibility'], true ) ) {
831 $arg['p_sale'] = $meta['custom_badge_text'];
832 }
833
834 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
835
836 if ( $arg['count'] >= 0 ) {
837 $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
838 $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
839
840 $arg['count'] = $prefix . $arg['count'] . $suffix;
841 }
842
843 if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
844 $title = $meta['cat_custom_title'];
845 }
846
847 if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
848 $excerpt = $meta['cat_custom_excerpt'];
849 }
850
851 $layout = $meta['layout'];
852
853 $arg['c_img'] = $meta['c_img'];
854 $arg['items'] = $meta['visibility'];
855 $arg['title_tag'] = $meta['title_tag'];
856 $arg['title_class'] = 'category-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
857 $arg['title'] = Fns::text_truncation( $title, $meta['title_limit_custom'] );
858 $arg['excerpt_limit'] = $meta['excerpt_limit'];
859 $arg['excerpt'] = wpautop( Fns::text_truncation( $excerpt, $meta['excerpt_limit_custom'] ) );
860 $arg['title_link'] = $meta['title_link'];
861 $arg['image_link'] = $meta['image_link'];
862
863 if ( ! $fullwidth ) {
864 $arg['grid'] .= 'rtsb-col-grid ';
865 $arg['class'] .= ' even-grid-item ';
866 } else {
867 $arg['grid'] .= 'rtsb-col-grid ';
868 }
869
870 $arg['class'] .= 'rtsb-category-grid';
871
872 $arg['img_html'] = $meta['c_img'] ? Fns::get_product_image_html(
873 'category',
874 $query->term_id,
875 $meta['f_img_size'],
876 $meta['default_img_id'],
877 $meta['custom_img_size'],
878 $lazy_load
879 ) : null;
880
881 if ( $meta['show_custom_image'] && ! empty( $meta['custom_image'] ) ) {
882 $arg['img_html'] = Fns::get_product_image_html(
883 'custom',
884 null,
885 $meta['f_img_size'],
886 $meta['custom_image'],
887 $meta['custom_img_size'],
888 $lazy_load
889 );
890 }
891
892 $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' : '' );
893
894 return $arg;
895 }
896
897 /**
898 * Renders add to cart button.
899 *
900 * @param string $link Product link.
901 * @param int $id Product ID.
902 * @param string $type Product type.
903 * @param string $text Custom text.
904 * @param string $success Success text.
905 * @param string $icon_html Custom icon.
906 * @param string $alignment Icon alignment.
907 *
908 * @return string
909 */
910 public function render_add_to_cart_button( $link, $id, $type, $text, $success, $icon_html, $alignment ) {
911 $content = null;
912 $tooltip_attr = '';
913 $ext_link = get_post_meta( $id, '_product_url', true );
914 $btn_txt = get_post_meta( $id, '_button_text', true );
915
916 if ( empty( $text ) ) {
917 $tooltip_attr = ' title="' . esc_attr__( 'Add to Cart', 'shopbuilder' ) . '"';
918
919 if ( 'variable' === $type ) {
920 $tooltip_attr = ' title="' . esc_attr__( 'Select Options', 'shopbuilder' ) . '"';
921 }
922
923 if ( 'grouped' === $type ) {
924 $tooltip_attr = ' title="' . esc_attr__( 'View Products', 'shopbuilder' ) . '"';
925 }
926
927 if ( 'external' === $type ) {
928 $tooltip_txt = ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' );
929 $tooltip_attr = ' title="' . esc_attr( $tooltip_txt ) . '"';
930 }
931 }
932
933 ob_start();
934 do_action( 'rtsb/before/cart/button' );
935 $content .= ob_get_clean();
936
937 if ( 'variable' === $type ) {
938 $content .= sprintf(
939 '<div class="rtsb-wc-add-to-cart-wrap">
940 <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>
941 </div>',
942 esc_url( $link ),
943 esc_html__( 'Select Options', 'shopbuilder' ),
944 absint( $id ),
945 esc_attr( $alignment ),
946 empty( $text ) ? 'no-text' : 'has-text',
947 $tooltip_attr,
948 $icon_html,
949 );
950 } elseif ( 'grouped' === $type ) {
951 $content .= sprintf(
952 '<div class="rtsb-wc-add-to-cart-wrap">
953 <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>
954 </div>',
955 esc_url( $link ),
956 esc_html__( 'View Products', 'shopbuilder' ),
957 absint( $id ),
958 esc_attr( $alignment ),
959 empty( $text ) ? 'no-text' : 'has-text',
960 $tooltip_attr,
961 $icon_html,
962 );
963 } elseif ( 'external' === $type ) {
964 $content .= sprintf(
965 '<div class="rtsb-wc-add-to-cart-wrap">
966 <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 %8$s>%7$s<span class="text">%2$s</span></a>
967 </div>',
968 ! empty( $ext_link ) ? esc_url( $ext_link ) : esc_url( $link ),
969 ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
970 absint( $id ),
971 esc_attr( $alignment ),
972 empty( $text ) ? 'no-text' : 'has-text',
973 $tooltip_attr,
974 $icon_html,
975 ! empty( $ext_link ) ? ' target="_blank"' : ''
976 );
977 } else {
978 $content .= sprintf(
979 '<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>',
980 esc_url( $link ),
981 absint( $id ),
982 esc_attr( $type ),
983 $icon_html,
984 esc_html( $text ),
985 esc_attr( $alignment ),
986 empty( $text ) ? 'no-text' : 'has-text',
987 $tooltip_attr,
988 esc_html( $success ),
989 ! empty( $success ) ? 'has-success-text' : 'no-success-text',
990 );
991 }
992
993 ob_start();
994 do_action( 'rtsb/after/cart/button' );
995 $content .= ob_get_clean();
996
997 return $content;
998 }
999
1000 /**
1001 * Button classes.
1002 *
1003 * @param array $params Button params.
1004 *
1005 * @return array
1006 */
1007 public function button_classes( $params ) {
1008 $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
1009
1010 return $params;
1011 }
1012 }
1013