PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 1.0.0
ShopBuilder – WooCommerce Builder For Elementor v1.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
← All changes | app/Elementor/Render/Render.php +857 -1406 2.2.21.0.0 View file →
@@ -1,1406 +1,857 @@
1 -<?php
2 -/**
3 - * Elementor Render Class.
4 - *
5 - * This class contains render logics & output. It utilizes WC_Products_Query().
6 - *
7 - * @package RadiusTheme\SB
8 - */
9 -
10 -namespace RadiusTheme\SB\Elementor\Render;
11 -
12 -use WC_Query;
13 -use WP_Query;
14 -use WC_Product;
15 -use Elementor\Utils;
16 -use WC_Product_Query;
17 -use RadiusTheme\SB\Helpers\Fns;
18 -use RadiusTheme\SB\Models\QueryArgs;
19 -use RadiusTheme\SB\Helpers\BuilderFns;
20 -use RadiusTheme\SB\Traits\SingletonTrait;
21 -use RadiusTheme\SB\Traits\ActionBtnTraits;
22 -use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
23 -
24 -// Do not allow directly accessing this file.
25 -if ( ! defined( 'ABSPATH' ) ) {
26 - exit( 'This script cannot be accessed directly.' );
27 -}
28 -
29 -/**
30 - * Elementor Render Class.
31 - */
32 -class Render {
33 - /**
34 - * Singleton Trait.
35 - */
36 - use SingletonTrait;
37 -
38 - /**
39 - * Action button trait.
40 - */
41 - use ActionBtnTraits;
42 -
43 - /**
44 - * HTML.
45 - *
46 - * @var string
47 - */
48 - private $html = null;
49 -
50 - /**
51 - * Settings array
52 - *
53 - * @var array
54 - */
55 - public $get_settings;
56 -
57 - /**
58 - * Element attributes.
59 - *
60 - * @var array
61 - */
62 - private $attributes = [];
63 -
64 - /**
65 - * Get elementor settings.
66 - *
67 - * @return array
68 - */
69 - public function get_settings_for_display() {
70 - return $this->get_settings;
71 - }
72 -
73 - /**
74 - * Container Wrapper HTML.
75 - *
76 - * @param string $content The content.
77 - * @param array $settings Settings.
78 - * @param string $class Class.
79 - * @param string $template Template name.
80 - * @param bool $fullwidth Fullwidth check.
81 - * @param bool $ajax Ajax attributes.
82 - *
83 - * @return string
84 - */
85 - public function container( $content, $settings, $class = '', $template = '', $fullwidth = false, $ajax = true ) {
86 - $rand = wp_rand();
87 - $layout_id = 'rtsb-container-' . $rand;
88 - $metas = RenderHelpers::meta_dataset( $settings, $template );
89 - $raw_layout = esc_html( $metas['layout'] );
90 - $layout = RenderHelpers::filter_layout( $raw_layout, $template );
91 - $style_attr = '--rtsb-default-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) );
92 - $view_mode = $settings['view_mode'] ?? 'grid';
93 - $view_mode = isset( $_GET['displayview'] ) ? sanitize_text_field( wp_unslash( $_GET['displayview'] ) ) : $view_mode; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
94 - $tooltip_attr = 'list' == $view_mode && ! empty( $metas['tooltip_position_list'] ) ? esc_attr( $metas['tooltip_position_list'] ) : $metas['tooltip_position'];
95 - $has_pro = rtsb()->has_pro();
96 - $has_filters = $has_pro && ! empty( $settings['tax_filter'] );
97 -
98 - // Set default layout.
99 - if ( ! $has_pro && ! in_array( $layout, array_keys( Fns::free_layouts() ), true ) ) {
100 - $layout = RenderHelpers::set_default_layout( $layout );
101 - }
102 -
103 - // Container classes.
104 - $container_classes = RenderHelpers::prepare_container_classes( $metas, $settings, $class );
105 -
106 - // Pagination attributes.
107 - $pagination_attributes = RenderHelpers::prepare_pagination_attr( $layout, $has_filters, $template, $settings, $ajax );
108 -
109 - // Attributes for the container.
110 - $container_attributes = [
111 - 'id' => $layout_id,
112 - 'class' => $container_classes,
113 - 'style' => apply_filters( 'rtsb/product/container/attr', $style_attr, $settings ),
114 - 'data-layout' => $layout,
115 - 'data-tooltip-position' => $tooltip_attr,
116 - ];
117 -
118 - if ( ! empty( $pagination_attributes ) ) {
119 - $container_attributes['data-rtsb-ajax'] = $pagination_attributes;
120 - }
121 -
122 - // Adding render attributes.
123 - $this->add_attribute( 'rtsb_container_attr_' . $rand, $container_attributes );
124 -
125 - // Start rendering.
126 - $this->html = '<div ' . $this->get_attribute_string( 'rtsb_container_attr_' . $rand ) . '>';
127 -
128 - // Section title.
129 - $this->html .= $this->render_section_title( $settings );
130 -
131 - // Content.
132 - $this->html .= $content;
133 -
134 - // End rendering.
135 - $this->html .= '</div><!-- .rtsb-elementor-container -->';
136 -
137 - // Action button icon reset.
138 - $this->action_button_icon_set_default();
139 -
140 - // Script generator.
141 - $script_generator = [];
142 - $script_generator['layout'] = $layout_id;
143 - $script_generator['rand'] = absint( $rand );
144 - $script_generator['isCarousel'] = preg_match( '/slider/', $layout );
145 -
146 - // Register scripts in the wp_footer action.
147 - add_action(
148 - 'wp_footer',
149 - static function () use ( $script_generator ) {
150 - RenderHelpers::register_scripts( $script_generator );
151 - }
152 - );
153 -
154 - return $this->html;
155 - }
156 -
157 - /**
158 - * Row Wrapper HTML.
159 - *
160 - * @param string $content The content.
161 - * @param array $settings Settings.
162 - * @param string $hook_html Hook HTML.
163 - * @param array $raw_settings Raw Settings.
164 - *
165 - * @return string
166 - */
167 - public function row( $content, $settings, $hook_html = '', $raw_settings = [] ) {
168 - $raw_layout = esc_html( $settings['layout'] );
169 - $layout = RenderHelpers::filter_layout( $raw_layout );
170 -
171 - $rand = wp_rand();
172 - $is_carousel = preg_match( '/slider/', $raw_layout );
173 -
174 - if ( preg_match( '/category/', $raw_layout ) && ( ! empty( $settings['active_cat_slider'] ) ) ) {
175 - $is_carousel = true;
176 - }
177 -
178 - // Row classes.
179 - $row_classes = RenderHelpers::prepare_row_classes( $settings );
180 -
181 - // Adding render attributes.
182 - $this->add_attribute( 'rtsb_row_attr_' . $rand, 'class', $row_classes );
183 -
184 - // Start rendering.
185 - $row_wrapper = '<div ' . $this->get_attribute_string( 'rtsb_row_attr_' . $rand ) . '>';
186 - $start_wrapper = apply_filters( 'rtsb/elementor/row/start', $row_wrapper, $raw_settings );
187 -
188 - $this->html = ! empty( $settings['show_filter'] ) ? $hook_html . $start_wrapper : $start_wrapper;
189 -
190 - if ( $is_carousel ) {
191 - $slider_data = RenderHelpers::slider_data( $settings, $raw_settings );
192 -
193 - // Adding slider render attributes.
194 - $this->add_attribute(
195 - 'rtsb_slider_attr_' . $rand,
196 - [
197 - 'class' => 'rtsb-col-grid ' . $slider_data['class'],
198 - 'data-options' => $slider_data['data'],
199 - ]
200 - );
201 -
202 - $this->html .= '<div ' . $this->get_attribute_string( 'rtsb_slider_attr_' . $rand ) . '>';
203 - $this->html .= '<div class="swiper-wrapper">';
204 - }
205 -
206 - $this->html .= $content;
207 -
208 - if ( $is_carousel ) {
209 - $this->html .= '</div><!-- .swiper-wrapper -->';
210 -
211 - // Slider buttons.
212 - $this->html .= $this->render_slider_buttons( $settings );
213 - $this->html .= '</div><!-- .rtsb-carousel-slider -->';
214 - }
215 -
216 - $row_end = '</div><!-- .rtsb-row -->';
217 -
218 - $this->html .= apply_filters( 'rtsb/elementor/row/end', $row_end );
219 -
220 - // Preloader.
221 - $this->html .= RenderHelpers::pre_loader( $layout );
222 -
223 - return $this->html;
224 - }
225 -
226 - /**
227 - * Product loop.
228 - *
229 - * @param object $products Products.
230 - * @param array $settings Settings.
231 - * @param string $template Template.
232 - *
233 - * @return string|null
234 - */
235 - public function product_loop( $products, $settings, $template ) {
236 - $html = null;
237 -
238 - if ( empty( $products ) ) {
239 - return null;
240 - }
241 -
242 - $i = 0;
243 -
244 - foreach ( $products as $product ) {
245 - $i++;
246 - $GLOBALS['product'] = $product;
247 - $layout = RenderHelpers::filter_layout( esc_html( $settings['layout'] ), $template );
248 -
249 - /**
250 - * Before product template render hook.
251 - */
252 - do_action( 'rtsb_before_product_template_render' );
253 -
254 - // Loop arg.
255 - $arg = $this->arg_dataset( $settings, $product, $settings['lazy_load'], $i );
256 -
257 - // Get template.
258 - $html .= Fns::load_template( $template . $layout, $arg, true );
259 -
260 - /**
261 - * After product template render hook.
262 - */
263 - do_action( 'rtsb_after_product_template_render' );
264 -
265 - unset( $GLOBALS['product'] );
266 - }
267 -
268 - return $html;
269 - }
270 -
271 - /**
272 - * WC Product loop.
273 - *
274 - * @param object $query The query.
275 - * @param array $settings Settings.
276 - * @param string $template Template.
277 - *
278 - * @return string|null
279 - */
280 - public function wc_product_loop( $query, $settings, $template ) {
281 - $html = null;
282 -
283 - if ( empty( $query ) ) {
284 - return null;
285 - }
286 -
287 - $i = 0;
288 -
289 - while ( $query->have_posts() ) {
290 - $query->the_post();
291 - $i++;
292 -
293 - // Loop arg.
294 - $arg = $this->arg_dataset( $settings, wc_get_product( get_the_ID() ), $settings['lazy_load'], $i );
295 -
296 - // Get template.
297 - $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
298 - }
299 -
300 - return $html;
301 - }
302 -
303 - /**
304 - * Category loop.
305 - *
306 - * @param object $query The query.
307 - * @param array $settings Settings.
308 - * @param string $template Template.
309 - * @param bool $is_single Single category.
310 - *
311 - * @return string|null
312 - */
313 - public function category_loop( $query, $settings, $template, $is_single = false ) {
314 - $html = null;
315 - $category_loop = false;
316 -
317 - if ( 'category-layout3' === $settings['raw_settings']['layout'] || 'category-single-layout2' === $settings['raw_settings']['layout'] ) {
318 - $category_loop = true;
319 - }
320 -
321 - if ( $is_single ) {
322 - // Loop arg.
323 - $arg = $this->cat_arg_dataset( $settings, $query, true, false, $category_loop );
324 -
325 - // Get template.
326 - $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
327 - } else {
328 - foreach ( $query as $term ) {
329 - // Loop arg.
330 - $arg = $this->cat_arg_dataset( $settings, $term, false, false, $category_loop );
331 -
332 - // Get template.
333 - $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
334 - }
335 - }
336 -
337 - return $html;
338 - }
339 -
340 - /**
341 - * Render Product View.
342 - *
343 - * @param string $template Template name.
344 - * @param array $settings Control settings.
345 - *
346 - * @return string
347 - */
348 - public function product_view( $template, $settings ) {
349 - $this->get_settings = $settings;
350 -
351 - $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
352 - $is_carousel = preg_match( '/slider/', $metas['layout'] );
353 - $pagination = $metas['pagination'];
354 - $hook_html = '';
355 -
356 - // Query Args.
357 - $args = ( new QueryArgs() )->buildArgs( $metas, 'product', $is_carousel );
358 -
359 - $temp_args = $args;
360 - $default_args = [
361 - 'visibility' => 'visible',
362 - 'status' => 'publish',
363 - ];
364 - $custom_args = apply_filters( 'rtsb/elementor/args_before_loop', $args, $metas );
365 - $args = wp_parse_args( $custom_args, $default_args );
366 -
367 - /**
368 - * Before Product query hook.
369 - *
370 - * @hooked RadiusTheme\SB\Controllers\Hooks\ActionHooks::modify_wc_query_args 10
371 - */
372 - do_action( 'rtsb/elements/render/before_query', $settings, $args );
373 -
374 - // Query.
375 - $product_query = new WC_Product_Query( $args );
376 -
377 - /**
378 - * Product query hook.
379 - */
380 - do_action( 'rtsb/elements/render/product_query', $product_query, $this );
381 -
382 - $products = $pagination ? $product_query->get_products()->products : $product_query->get_products();
383 -
384 - if ( ! empty( $products ) ) {
385 - // Start rendering.
386 - $hook_html .= $this->render_start( $metas, $settings, $temp_args );
387 -
388 - // Row.
389 - $this->row( $this->product_loop( $products, $metas, $template ), $metas, $hook_html, $settings );
390 -
391 - // Pagination.
392 - if ( $pagination ) {
393 - $pagination_args = [
394 - 'query' => $product_query,
395 - 'meta' => $metas,
396 - 'limit' => $settings['posts_limit'],
397 - 'per_page' => $settings['pagination_per_page'],
398 - ];
399 -
400 - $this->html .= $this->render_products_pagination( $pagination_args );
401 - }
402 -
403 - // End rendering.
404 - $this->html .= $this->render_end( $metas, $settings, $products );
405 - } else {
406 - $this->no_products_msg( $metas );
407 - }
408 -
409 - wp_reset_postdata();
410 -
411 - unset( $args['tax_query'] );
412 -
413 - /**
414 - * After Product query hook.
415 - *
416 - * @hooked RadiusTheme\SB\Controllers\Hooks\ActionHooks::reset_wc_query_args 10
417 - */
418 - do_action( 'rtsb/elements/render/after_query', $settings, $args );
419 -
420 - // Container.
421 - $this->container( $this->html, $settings, 'rtsb-products-container', $template, $is_carousel );
422 -
423 - return $this->html;
424 - }
425 -
426 - /**
427 - * Render Product View.
428 - *
429 - * @param string $template Template name.
430 - * @param array $settings Control settings.
431 - * @param object $widget Reference widget.
432 - *
433 - * @return string
434 - */
435 - public function wc_loop_for_product_view( $template, $settings, $widget ) {
436 - global $wp_query, $post;
437 -
438 - $this->get_settings = $settings;
439 - $rand = wp_rand();
440 - $metas = RenderHelpers::meta_dataset( $settings, $template, $widget->get_settings_for_display() );
441 -
442 - $settings['rtsb_order'] = ! empty( $wp_query->query_vars['order'] ) ? $wp_query->query_vars['order'] : 'ASC';
443 - $settings['rtsb_orderby'] = ! empty( $wp_query->query_vars['orderby'] ) ? $wp_query->query_vars['orderby'] : 'menu_order';
444 -
445 - $pagination = $metas['pagination'];
446 -
447 - $page_type = BuilderFns::builder_type( get_the_ID() );
448 - $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
449 - $posts_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
450 -
451 - if ( $is_preview ) {
452 - $main_query = clone $wp_query;
453 - $main_post = clone $post;
454 -
455 - $ordering = ( new WC_Query() )->get_catalog_ordering_args();
456 - $wp_query_args = [
457 - 'post_type' => 'product',
458 - 'posts_per_page' => $posts_per_page,
459 - ];
460 -
461 - if ( ! empty( $ordering['orderby'] ) ) {
462 - $wp_query_args['orderby'] = $ordering['orderby'];
463 - }
464 -
465 - if ( ! empty( $ordering['order'] ) ) {
466 - $wp_query_args['order'] = $ordering['order'];
467 - }
468 -
469 - $wp_query = new WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
470 -
471 - wc_set_loop_prop( 'total', $wp_query->found_posts );
472 - wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
473 - }
474 -
475 - if ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) {
476 - echo '<div class="rtsb-active-filters-wrapper"></div>';
477 - }
478 -
479 - // column_per_row.
480 - if ( woocommerce_product_loop() ) {
481 - if ( wc_get_loop_prop( 'total' ) ) {
482 -
483 - // Row.
484 - $this->row( $this->wc_product_loop( $wp_query, $metas, $template ), $metas, '', $settings );
485 - }
486 -
487 - // Pagination.
488 - $this->html .= '<div class="rtsb-archive-pagination-wrap">';
489 -
490 - if ( $pagination ) {
491 - if ( Fns::product_filters_has_ajax( apply_filters( 'rtsb/builder/set/current/page/type', '' ) ) ) {
492 - if ( $wp_query->max_num_pages > 1 ) {
493 - $this->add_attribute(
494 - 'rtsb_load_more_btn_attr_' . $rand,
495 - [
496 - 'data-paged' => '2',
497 - 'data-max-page' => $wp_query->max_num_pages,
498 - ]
499 - );
500 -
501 - $this->html .=
502 - "<div class='rtsb-load-more rtsb-pos-r'>
503 - <button {$this->get_attribute_string( 'rtsb_load_more_btn_attr_' . $rand )}>
504 - <span>" . esc_html__( 'Load More', 'shopbuilder' ) . "</span>
505 - </button>
506 - <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
507 - </div>";
508 - }
509 - } else {
510 - $pagination_args = [
511 - 'query' => $wp_query,
512 - 'meta' => $metas,
513 - 'limit' => wc_get_loop_prop( 'total' ),
514 - 'per_page' => $posts_per_page,
515 - ];
516 -
517 - $this->html .= $this->render_products_pagination( $pagination_args, 'wp' );
518 - }
519 - }
520 -
521 - $this->html .= '</div>';
522 - } else {
523 - $this->no_products_msg( $metas );
524 - }
525 -
526 - if ( $is_preview ) {
527 - // phpcs:disable
528 - $wp_query = $main_query;
529 - $post = $main_post;
530 -
531 - wp_reset_query();
532 - wp_reset_postdata();
533 - // phpcs:enable
534 - }
535 -
536 - // Container.
537 - $this->container( $this->html, $settings, 'rtsb-products-container', $template );
538 -
539 - return $this->html;
540 - }
541 -
542 - /**
543 - * Loop Setup for Product View.
544 - *
545 - * @param string $template Template name.
546 - * @param array $settings Control settings.
547 - * @param object $widget Widget object.
548 - *
549 - * @return string
550 - */
551 - public function setup_loop_for_product_view( $template, $settings, $widget ) {
552 - if ( empty( $settings['query_products'] ) ) {
553 - return $this->html;
554 - }
555 -
556 - $html = null;
557 -
558 - $metas = RenderHelpers::meta_dataset( $settings, '', $widget->get_settings_for_display() );
559 -
560 - foreach ( $settings['query_products'] as $_product ) {
561 - $post_object = get_post( $_product->get_id() );
562 -
563 - setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found
564 -
565 - // Loop arg.
566 - $arg = $this->arg_dataset( $metas, $_product );
567 - // Get template.
568 - $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
569 -
570 - $this->row( $html, $metas, '', $settings );
571 - }
572 -
573 - // Container.
574 - $this->container( $this->html, $settings, 'rtsb-products-container', '', false, false );
575 -
576 - wp_reset_postdata();
577 -
578 - return $this->html;
579 - }
580 -
581 - /**
582 - * Render Category View.
583 - *
584 - * @param string $template Template name.
585 - * @param array $settings Control settings.
586 - * @param bool $is_single Single category.
587 - *
588 - * @return string
589 - */
590 - public function category_view( $template, $settings, $is_single = false ) {
591 - $this->get_settings = $settings;
592 -
593 - $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
594 - $taxonomy = $metas['category_source'];
595 - $term = $metas['category_term'];
596 -
597 - if ( rtsb()->has_pro() && ( ! empty( $metas['tag_term'] ) ) ) {
598 - $term = $metas['tag_term'];
599 - }
600 -
601 - // Query.
602 - if ( $is_single ) {
603 - if ( empty( $term ) ) {
604 - return '<p>' . esc_html__( 'Please select a category.', 'shopbuilder' ) . '</p>';
605 - }
606 -
607 - $taxonomy_query = get_term( $term, $taxonomy );
608 - } else {
609 - // Query Args.
610 - $args = ( new QueryArgs() )->buildArgs( $metas, 'category' );
611 -
612 - $taxonomy_query = get_terms( $args );
613 - }
614 -
615 - if ( ! is_wp_error( $taxonomy_query ) && ! empty( $taxonomy_query ) ) {
616 - // Row.
617 - $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
618 - } else {
619 - $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
620 - }
621 -
622 - // Container.
623 - $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
624 -
625 - return $this->html;
626 - }
627 -
628 - /**
629 - * Render Category View.
630 - *
631 - * @param string $template Template name.
632 - * @param array $settings Control settings.
633 - *
634 - * @return string
635 - */
636 - public function social_share_view( $template, $settings ) {
637 - $this->get_settings = $settings;
638 - $share_items = [];
639 -
640 - foreach ( $settings['share_platforms'] as $platform ) {
641 - $share_items[] = [
642 - 'share_items' => $platform['share_items'],
643 - 'share_text' => $platform['share_text'],
644 - ];
645 - }
646 -
647 - if ( ! empty( $share_items ) && is_array( $share_items ) ) {
648 - $arg['p_id'] = get_the_ID();
649 - $arg['share_items'] = $share_items;
650 - $arg['preset'] = $settings['layout'];
651 - $arg['direction'] = ! empty( $settings['layout_direction'] ) ? $settings['layout_direction'] : 'horizontal';
652 - $arg['show_icon'] = ! empty( $settings['show_share_icon'] );
653 - $arg['show_text'] = ! empty( $settings['show_share_text'] );
654 - $arg['show_pre_text'] = ! empty( $settings['show_share_pre_text'] );
655 - $arg['share_pre_text'] = ! empty( $settings['share_pre_text'] ) ? $settings['share_pre_text'] : '';
656 - $arg['raw_settings'] = $this->get_settings_for_display();
657 - $this->html = Fns::load_template( $template, $arg, true );
658 - } else {
659 - $this->html = '<p>' . esc_html__( 'Please select a social sharing platform.', 'shopbuilder' ) . '</p>';
660 - }
661 -
662 - return $this->html;
663 - }
664 -
665 - /**
666 - * Builds an array with meta values.
667 - *
668 - * @param array $meta Meta values.
669 - * @param object $product Product object.
670 - * @param bool $lazy_load Lazy Load.
671 - * @param int $i Integer.
672 - *
673 - * @return array
674 - */
675 - public function arg_dataset( array $meta, object $product, bool $lazy_load = false, $i = 0 ) {
676 - $post_id = $product->get_id();
677 - $arg = $this->build_product_arg(
678 - [
679 - 'product' => $product,
680 - 'id' => $product->get_id(),
681 - 'type' => $product->get_type(),
682 - 'meta' => $meta,
683 - 'lazy_load' => $lazy_load,
684 - 'i' => $i,
685 - ]
686 - );
687 -
688 - return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
689 - }
690 -
691 - /**
692 - * Builds an array with meta values for WP_Query.
693 - *
694 - * @param array $meta Meta values.
695 - * @param int $post_id Post ID.
696 - * @param bool $lazy_load Lazy Load.
697 - * @param int $i Integer.
698 - *
699 - * @return array
700 - */
701 - public function wp_arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
702 - if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
703 - return [];
704 - }
705 -
706 - global $product;
707 -
708 - if ( ! $product instanceof WC_Product && $post_id ) {
709 - $product = wc_get_product( $post_id );
710 - }
711 -
712 - $post_id = $product->get_id();
713 - $arg = $this->build_product_arg(
714 - [
715 - 'product' => $product,
716 - 'id' => $post_id,
717 - 'type' => $product->get_type(),
718 - 'meta' => $meta,
719 - 'lazy_load' => $lazy_load,
720 - 'i' => $i,
721 - ]
722 - );
723 -
724 - return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
725 - }
726 -
727 - /**
728 - * Builds an array with meta values.
729 - *
730 - * @param array $meta Meta values.
731 - * @param Object $query Category object.
732 - * @param bool $fullwidth Fullwidth check.
733 - * @param bool $lazy_load Lazy Load.
734 - * @param bool $category_loop Category loop.
735 - *
736 - * @return array
737 - */
738 - public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false, $category_loop = false ) {
739 - if ( empty( $meta ) ) {
740 - return [];
741 - }
742 -
743 - $arg = [];
744 -
745 - $products = null;
746 - $arg['class'] = null;
747 - $arg['grid'] = null;
748 - $arg['anchor_class'] = null;
749 - $arg['p_sale'] = null;
750 - $arg['count'] = max( $query->count, 0 );
751 - $arg['count_position'] = $meta['count_position'];
752 - $arg['excerpt_position'] = $meta['cat_excerpt_position'];
753 - $arg['cat_link'] = get_term_link( $query );
754 - $arg['target'] = '_self';
755 - $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
756 -
757 - if ( ! empty( $meta['tag_term'] ) ) {
758 - $arg['tag_term'] = $meta['tag_term'];
759 - }
760 -
761 - if ( ! empty( $meta['custom_link']['url'] ) ) {
762 - $arg['cat_link'] = $meta['custom_link']['url'];
763 - $arg['target'] = $meta['custom_link']['is_external'] ? '_blank' : '_self';
764 - }
765 -
766 - $title = $query->name;
767 - $excerpt = $query->description;
768 -
769 - if ( in_array( 'badges', $meta['visibility'], true ) ) {
770 - $arg['p_sale'] = $meta['custom_badge_text'];
771 - }
772 -
773 - $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
774 -
775 - if ( $arg['count'] >= 0 ) {
776 - $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
777 - $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
778 -
779 - $arg['count'] = $prefix . $arg['count'] . $suffix;
780 - }
781 -
782 - if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
783 - $title = $meta['cat_custom_title'];
784 - }
785 -
786 - if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
787 - $excerpt = $meta['cat_custom_excerpt'];
788 - }
789 -
790 - $arg['c_img'] = $meta['c_img'];
791 - $arg['items'] = $meta['visibility'];
792 - $arg['title_tag'] = $meta['title_tag'];
793 - $arg['title_class'] = 'category-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
794 - $arg['title'] = Fns::text_truncation( $title, $meta['title_limit_custom'] );
795 - $arg['excerpt_limit'] = $meta['excerpt_limit'];
796 - $arg['excerpt'] = wpautop( Fns::text_truncation( $excerpt, $meta['excerpt_limit_custom'] ) );
797 - $arg['title_link'] = $meta['title_link'];
798 - $arg['image_link'] = $meta['image_link'];
799 - $arg['grid'] .= 'rtsb-col-grid ';
800 -
801 - if ( ! $fullwidth ) {
802 - $arg['class'] .= ' even-grid-item ';
803 - }
804 -
805 - if ( ! empty( $meta['active_cat_slider'] ) ) {
806 - $arg['class'] .= ' rtsb-slide-item swiper-slide animated rtFadeIn ';
807 - }
808 -
809 - $arg['class'] .= 'rtsb-category-grid';
810 -
811 - ob_start();
812 - do_action( 'rtsb/categories/category_image_override', $meta, $query->term_id );
813 - $override_category_image = ob_get_clean();
814 -
815 - $arg['img_html'] = $meta['c_img'] ? Fns::get_product_image_html(
816 - 'category',
817 - $query->term_id,
818 - $meta['f_img_size'],
819 - $meta['default_img_id'],
820 - $meta['custom_img_size'],
821 - $lazy_load,
822 - false,
823 - false,
824 - $override_category_image
825 - ) : null;
826 -
827 - if ( $meta['show_custom_image'] && ! empty( $meta['custom_image'] ) ) {
828 - $arg['img_html'] = Fns::get_product_image_html(
829 - 'custom',
830 - null,
831 - $meta['f_img_size'],
832 - $meta['custom_image'],
833 - $meta['custom_img_size'],
834 - $lazy_load
835 - );
836 - }
837 -
838 - $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' : '' );
839 -
840 - if ( $category_loop ) {
841 - $query_args = [
842 - 'product_category_id' => $query->term_id,
843 - 'limit' => -1,
844 - 'order' => 'DESC',
845 - 'orderby' => 'date',
846 - ];
847 -
848 - $products_query = new WC_Product_Query( $query_args );
849 - $products = $products_query->get_products();
850 - }
851 -
852 - return apply_filters( 'rtsb/elementor/render/cat_arg_dataset', $arg, $meta, $query, $fullwidth, $lazy_load, $products );
853 - }
854 -
855 - /**
856 - * Building product args.
857 - *
858 - * @param array $args Args.
859 - * @return array
860 - */
861 - public function build_product_arg( $args ) {
862 - list(
863 - 'product' => $product,
864 - 'id' => $post_id,
865 - 'type' => $p_type,
866 - 'meta' => $meta,
867 - 'lazy_load' => $lazy_load,
868 - 'i' => $i,
869 - ) = $args;
870 -
871 - $arg = [];
872 - $arg['class'] = null;
873 - $arg['grid'] = null;
874 - $arg['anchor_class'] = null;
875 - $arg['hover_img_html'] = null;
876 - $arg['s_link'] = [];
877 - $arg['add_to_cart'] = '';
878 - $arg['p_counter'] = absint( $i );
879 - $arg['p_id'] = $post_id;
880 - $arg['product'] = $product;
881 - $arg['p_link'] = $product->get_permalink();
882 - $arg['p_sale'] = '';
883 - $arg['rating_args'] = [];
884 - $arg['has_attributes'] = $product->is_type( 'variable' ) && $product->get_attributes();
885 - $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
886 - $cart_icon_html = '';
887 - $layout = $meta['layout'];
888 -
889 - // Building the arg.
890 - $arg['target'] = '_self';
891 - $arg['f_img'] = $meta['f_img'];
892 - $arg['items'] = $meta['visibility'];
893 - $arg['title_tag'] = $meta['title_tag'];
894 - $arg['title_class'] = 'product-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
895 - $arg['title'] = Fns::text_truncation( $product->get_title(), $meta['title_limit_custom'] );
896 - $arg['excerpt_limit'] = $meta['excerpt_limit'];
897 - $arg['excerpt'] = wpautop( Fns::text_truncation( do_shortcode( get_post_field( 'post_excerpt', $post_id ) ), $meta['excerpt_limit_custom'] ) );
898 - $arg['title_link'] = $meta['title_link'];
899 - $arg['image_link'] = $meta['image_link'];
900 - $arg['out_of_stock'] = $meta['out_of_stock_badge_text'];
901 - $arg['action_btn_preset'] = $meta['btn_preset'];
902 - $arg['action_btn_position'] = $meta['btn_position'];
903 - $arg['swatch_position'] = $meta['swatch_position'];
904 - $arg['swatch_type'] = $meta['swatch_type'];
905 - $arg['tooltip_position'] = $meta['tooltip_position'];
906 -
907 - $is_list = preg_match( '/list/', $layout );
908 - $is_carousel = preg_match( '/slider/', $layout );
909 -
910 - if ( ! $is_carousel ) {
911 - $arg['grid'] .= 'rtsb-col-grid ';
912 - $arg['class'] .= ' even-grid-item ';
913 - } else {
914 - $arg['grid'] .= 'rtsb-col-grid rtsb-col-full rtsb-slide-item swiper-slide ';
915 - }
916 -
917 - $d_cols = 0 === $meta['d_cols'] ? RenderHelpers::default_columns( $layout ) : $meta['d_cols'];
918 - $t_cols = 0 === $meta['t_cols'] ? 2 : $meta['t_cols'];
919 - $m_cols = 0 === $meta['m_cols'] ? 1 : $meta['m_cols'];
920 -
921 - $arg['grid'] .= 0 === $i % $d_cols ? ' row-last desktop-row-last' : '';
922 - $arg['grid'] .= 0 === $i % $t_cols ? ' row-last tablet-row-last' : '';
923 - $arg['grid'] .= 0 === $i % $m_cols ? ' row-last mobile-row-last' : '';
924 -
925 - $arg['class'] .= 'rtsb-product';
926 -
927 - if ( $is_list ) {
928 - $arg['class'] .= ' rtsb-product-list';
929 - }
930 -
931 - $arg['class'] .= ' animated rtFadeIn';
932 -
933 - if ( in_array( 'badges', $meta['visibility'], true ) ) {
934 - $badge_module = ! empty( $meta['enable_badges_module'] );
935 - $arg['p_sale'] = Fns::is_module_active( 'product_badges' ) && $badge_module ? 'rtsb_yes' : Fns::get_promo_badge(
936 - $product,
937 - $meta['sale_badge_type'],
938 - $meta['sale_badge_text'],
939 - apply_filters( 'rtsb/elementor/render/out_of_stock_badge_text', $meta['out_of_stock_badge_text'] )
940 - );
941 - }
942 -
943 - $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
944 -
945 - $meta['add_to_cart_text'] = apply_filters( 'rtsb/elementor/render/add_to_cart_text', $meta['add_to_cart_text'], $product );
946 -
947 - if ( ! $meta['show_cart_text'] ) {
948 - $meta['add_to_cart_text'] = '';
949 - $meta['add_to_cart_success_text'] = '';
950 - }
951 -
952 - if ( in_array( 'add_to_cart', $meta['visibility'], true ) ) {
953 - if ( ! empty( $meta['add_to_cart_icon'] ) ) {
954 - $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_icon'], 'cart-icon' );
955 - }
956 -
957 - if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
958 - $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
959 - }
960 -
961 - $cart_icon = ! empty( $cart_icon_html ) ? '<span class="icon">' . $cart_icon_html . '</span>' : '';
962 -
963 - if ( $product->is_purchasable() || 'grouped' === $p_type || 'external' === $p_type ) {
964 - if ( $product->is_in_stock() ) {
965 - $arg['add_to_cart'] = $this->render_add_to_cart_button(
966 - [
967 - 'link' => $product->get_permalink(),
968 - 'id' => $post_id,
969 - 'type' => $p_type,
970 - 'text' => $meta['add_to_cart_text'],
971 - 'success' => $meta['add_to_cart_success_text'],
972 - 'icon_html' => $cart_icon,
973 - 'alignment' => $meta['add_to_cart_alignment'],
974 - 'product' => $product,
975 - ]
976 - );
977 - }
978 - }
979 - }
980 -
981 - if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
982 - add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
983 - add_filter( 'rtsb/module/quick_view/icon_html', [ $this, 'quick_view_icon' ] );
984 - }
985 -
986 - if ( in_array( 'compare', $meta['visibility'], true ) ) {
987 - add_filter( 'rtsb/module/compare/button_params', [ $this, 'button_classes' ] );
988 - add_filter( 'rtsb/module/compare/icon_html', [ $this, 'compare_icon' ] );
989 - }
990 -
991 - if ( in_array( 'wishlist', $meta['visibility'], true ) ) {
992 - add_filter( 'rtsb/module/wishlist/button_params', [ $this, 'button_classes' ] );
993 - add_filter( 'rtsb/module/wishlist/icon_html', [ $this, 'wishlist_icon' ] );
994 - }
995 -
996 - $arg['img_html'] = $meta['f_img'] ? Fns::get_product_image_html(
997 - 'product',
998 - $post_id,
999 - $meta['f_img_size'],
1000 - $meta['default_img_id'],
1001 - $meta['custom_img_size'],
1002 - $lazy_load
1003 - ) : null;
1004 -
1005 - if ( ! ( function_exists( 'rtwpvsp' ) && $product->is_type( 'variable' ) && $product->get_attributes() ) ) {
1006 - $gallery_ids = $product->get_gallery_image_ids();
1007 -
1008 - if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
1009 - $arg['class'] .= ! $meta['gallery_img'] ? ' rtsb-double-img' : '';
1010 -
1011 - if ( ! rtsb()->has_pro() ) {
1012 - $arg['class'] .= ' rtsb-double-img';
1013 - }
1014 -
1015 - $arg['hover_img_html'] = Fns::get_product_image_html(
1016 - 'product',
1017 - $gallery_ids[0],
1018 - $meta['f_img_size'],
1019 - null,
1020 - $meta['custom_img_size'],
1021 - $lazy_load,
1022 - true
1023 - );
1024 - }
1025 - }
1026 -
1027 - $arg['hover_btn_text'] = $meta['hover_btn_text'];
1028 -
1029 - if ( $meta['show_hover_btn_icon'] && ! empty( $meta['hover_btn_icon'] ) ) {
1030 - $arg['hover_btn_icon'] = '<span class="icon">' . Fns::icons_manager( $meta['hover_btn_icon'], 'hover-btn-icon' ) . '</span>';
1031 - }
1032 -
1033 - $arg['img_args'] = [
1034 - 'p_id' => $arg['p_id'],
1035 - 'title' => get_the_title(),
1036 - 'p_link' => $arg['p_link'],
1037 - 'image_link' => $arg['image_link'],
1038 - 'img_html' => $arg['img_html'],
1039 - 'hover_img_html' => $arg['hover_img_html'],
1040 - 'meta' => $meta,
1041 - ];
1042 -
1043 - return $arg;
1044 - }
1045 -
1046 - /**
1047 - * Renders add to cart button.
1048 - *
1049 - * @param array $args Cart args.
1050 - *
1051 - * @return string
1052 - */
1053 - public function render_add_to_cart_button( $args ) {
1054 - list(
1055 - 'link' => $link,
1056 - 'id' => $id,
1057 - 'type' => $type,
1058 - 'text' => $text,
1059 - 'success' => $success,
1060 - 'icon_html' => $icon_html,
1061 - 'alignment' => $alignment,
1062 - 'product' => $product
1063 - ) = $args;
1064 -
1065 - $content = null;
1066 - $rand = wp_rand();
1067 - $ext_link = get_post_meta( $id, '_product_url', true );
1068 - $btn_txt = get_post_meta( $id, '_button_text', true );
1069 -
1070 - ob_start();
1071 - do_action( 'rtsb/before/cart/button' );
1072 - $content .= ob_get_clean();
1073 -
1074 - $cart_attr = [
1075 - 'class' => 'rtsb-action-btn ' . $type . '-product tipsy icon-' . $alignment . ' ' . ( empty( $text ) ? 'no-text' : 'has-text' ),
1076 - 'href' => esc_url( $link ),
1077 - 'rel' => 'nofollow',
1078 - 'data-quantity' => '1',
1079 - 'data-product_id' => absint( $id ),
1080 - 'data-id' => absint( $id ),
1081 - ];
1082 -
1083 - if ( empty( $text ) ) {
1084 - $tooltip_mapping = [
1085 - 'simple' => esc_attr__( 'Add to Cart', 'shopbuilder' ),
1086 - 'variable' => esc_attr__( 'Select Options', 'shopbuilder' ),
1087 - 'grouped' => esc_attr__( 'View Products', 'shopbuilder' ),
1088 - 'external' => ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
1089 - ];
1090 -
1091 - $cart_attr['title'] = $tooltip_mapping[ $type ];
1092 - }
1093 -
1094 - $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
1095 -
1096 - if ( 'variable' === $type || 'grouped' === $type ) {
1097 - $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1098 -
1099 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1100 -
1101 - $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
1102 -
1103 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1104 - $content .= $icon_html;
1105 - $content .= '<span class="text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '" data-cart-text="' . ( ! empty( $text ) ? esc_attr( $text ) : $tooltip_mapping['simple'] ) . '" data-variable-text="' . esc_attr( $text_btn ) . '">' . esc_html( $text_btn ) . '</span>';
1106 - $content .= '<span></span>';
1107 - } elseif ( 'external' === $type ) {
1108 - if ( ! empty( $ext_link ) ) {
1109 - $cart_attr['target'] = '_blank';
1110 - }
1111 -
1112 - $cart_attr['href'] = ! empty( $ext_link ) ? esc_url( $ext_link ) : esc_url( $link );
1113 -
1114 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1115 -
1116 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1117 - $content .= $icon_html;
1118 - $content .= '<span class="text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1119 - } else {
1120 - $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1121 - $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1122 - $cart_attr['data-type'] = $type;
1123 - $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1124 -
1125 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1126 -
1127 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1128 - $content .= $icon_html;
1129 - $content .= '<span class="text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1130 - $content .= '<span></span>';
1131 - }
1132 -
1133 - $content .= '</a>';
1134 - $content .= '</div>';
1135 -
1136 - ob_start();
1137 - do_action( 'rtsb/after/cart/button' );
1138 - $content .= ob_get_clean();
1139 -
1140 - return apply_filters( 'rtsb/render/cart/button', $content, $args );
1141 - }
1142 -
1143 - /**
1144 - * Button classes.
1145 - *
1146 - * @param array $params Button params.
1147 - *
1148 - * @return array
1149 - */
1150 - public function button_classes( $params ) {
1151 - $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
1152 -
1153 - return $params;
1154 - }
1155 -
1156 - /**
1157 - * Render the section title.
1158 - *
1159 - * @param array $settings The Elementor settings.
1160 - *
1161 - * @return string
1162 - */
1163 - public function render_section_title( $settings ) {
1164 - $html = '';
1165 - $rand = wp_rand();
1166 -
1167 - if ( empty( $settings['show_section_title'] ) || ( empty( $settings['query_products'] ) && 0 === count( $settings['query_products'] ) ) ) {
1168 - return $html;
1169 - }
1170 -
1171 - // Set attributes for the section title.
1172 - $this->add_attribute( 'rtsb_section_title_wrapper_' . $rand, 'class', 'rtsb-section-title-wrapper' );
1173 - $this->add_attribute( 'rtsb_section_title_' . $rand, 'class', 'rtsb-section-title' );
1174 -
1175 - // Start rendering.
1176 - $html .= '<div ' . $this->get_attribute_string( 'rtsb_section_title_wrapper_' . $rand ) . '>';
1177 - $html .= '<' . esc_attr( $settings['section_title_tag'] ) . ' ' . $this->get_attribute_string( 'rtsb_section_title_' . $rand ) . '>';
1178 - $html .= esc_html( $settings['section_title_text'] );
1179 - $html .= '</' . esc_attr( $settings['section_title_tag'] ) . '>';
1180 - $html .= '</div>';
1181 -
1182 - return $html;
1183 - }
1184 -
1185 - /**
1186 - * Renders products pagination
1187 - *
1188 - * @param array $args Pagination args.
1189 - * @param string $query_type Query type.
1190 - *
1191 - * @return string
1192 - */
1193 - public function render_products_pagination( $args, $query_type = 'wc' ) {
1194 - list(
1195 - 'query' => $query,
1196 - 'meta' => $meta,
1197 - 'limit' => $limit,
1198 - 'per_page' => $per_page
1199 - ) = $args;
1200 -
1201 - $html_utility = null;
1202 - $html = null;
1203 - $ajax = false;
1204 - $is_grid = preg_match( '/grid-layout/', $meta['layout'] ) || preg_match( '/list-layout/', $meta['layout'] );
1205 - $posts_per_page = 'wp' === $query_type ? $query->query_vars['posts_per_page'] : null;
1206 - $total_page = 'wp' === $query_type ? $query->max_num_pages : $query->get_products()->max_num_pages;
1207 -
1208 - if ( $limit ) {
1209 - if ( 'wc' === $query_type ) {
1210 - $found_post = $query->get_products()->total;
1211 - } elseif ( 'wp' === $query_type && ( empty( $wp_query->query['tax_query'] ) ) ) {
1212 - $found_post = $query->found_posts;
1213 - }
1214 -
1215 - if ( $per_page && $found_post > $per_page ) {
1216 - $found_post = $limit;
1217 - $total_page = ceil( $found_post / $per_page );
1218 - }
1219 - }
1220 -
1221 - $total_page = absint( $total_page );
1222 -
1223 - $args = [
1224 - 'total_page' => $total_page,
1225 - 'posts_per_page' => 'wc' === $query_type ? $per_page : $posts_per_page,
1226 - 'ajax' => $ajax,
1227 - ];
1228 -
1229 - if ( 'pagination' === $meta['posts_loading_type'] ) {
1230 - if ( $is_grid ) {
1231 - $html_utility .= Fns::custom_pagination(
1232 - $total_page,
1233 - 'wc' === $query_type ? $per_page : $posts_per_page
1234 - );
1235 - }
1236 - } else {
1237 - ob_start();
1238 - do_action( 'rtsb/elementor/render/pagination', $meta, $query, $args );
1239 - $html_utility .= ob_get_clean();
1240 - }
1241 -
1242 - if ( $html_utility ) {
1243 - $rand = wp_rand();
1244 -
1245 - // Adding pagination render attributes.
1246 - $this->add_attribute(
1247 - 'rtsb_pagination_attr_' . $rand,
1248 - [
1249 - 'class' => 'rtsb-pagination-wrap element-loading',
1250 - 'data-total-pages' => $total_page,
1251 - 'data-posts-per-page' => 'wc' === $query_type ? $per_page : $posts_per_page,
1252 - 'data-type' => $meta['posts_loading_type'],
1253 - ]
1254 - );
1255 -
1256 - // Start rendering.
1257 - $html = '<div ' . $this->get_attribute_string( 'rtsb_pagination_attr_' . $rand ) . '>';
1258 - $html .= $html_utility;
1259 - $html .= '</div><!-- .rtsb-pagination-wrap -->';
1260 - }
1261 -
1262 - return $html;
1263 - }
1264 -
1265 - /**
1266 - * Renders slider buttons
1267 - *
1268 - * @param array $settings Settings array.
1269 - *
1270 - * @return string
1271 - */
1272 - public function render_slider_buttons( $settings ) {
1273 - $html = '';
1274 - $left_icon = $settings['left_arrow_icon'];
1275 - $right_icon = $settings['right_arrow_icon'];
1276 -
1277 - if ( ! empty( $settings['slider_nav'] ) ) {
1278 - $html .=
1279 - '<div class="swiper-nav">
1280 - <div class="swiper-arrow swiper-button-next">
1281 - ' . Fns::icons_manager( $right_icon ) . '
1282 - </div>
1283 - <div class="swiper-arrow swiper-button-prev">
1284 - ' . Fns::icons_manager( $left_icon ) . '
1285 - </div>
1286 - </div>';
1287 - }
1288 -
1289 - $html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
1290 -
1291 - return $html;
1292 - }
1293 -
1294 - /**
1295 - * No products message.
1296 - *
1297 - * @param array $metas Meta data.
1298 - *
1299 - * @return void
1300 - */
1301 - public function no_products_msg( $metas ) {
1302 - $content =
1303 - '<div class="rtsb-notice woocommerce-no-products-found">
1304 - <div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder' ) . '</div>
1305 - </div>';
1306 -
1307 - $this->row( $content, $metas );
1308 - }
1309 -
1310 - /**
1311 - * Start the rendering.
1312 - *
1313 - * @param array $metas Meta Data.
1314 - * @param array $settings Widget settings.
1315 - * @param array $temp_args Additional temporary arguments for rendering.
1316 - *
1317 - * @return string
1318 - */
1319 - public function render_start( $metas, $settings, $temp_args ) {
1320 - ob_start();
1321 -
1322 - /**
1323 - * Before render row hook.
1324 - */
1325 - do_action( 'rtsb/elementor/render/before_row', $metas, $settings, $temp_args, $this );
1326 -
1327 - return ob_get_clean();
1328 - }
1329 -
1330 - /**
1331 - * End the rendering.
1332 - *
1333 - * @param array $metas Meta Data.
1334 - * @param array $settings Widget settings.
1335 - * @param array $products Array of products being rendered.
1336 - *
1337 - * @return string
1338 - */
1339 - public function render_end( $metas, $settings, $products ) {
1340 - ob_start();
1341 -
1342 - /**
1343 - * After render row hook.
1344 - */
1345 - do_action( 'rtsb/elementor/render/after_row', $metas, $settings, $products );
1346 -
1347 - return ob_get_clean();
1348 - }
1349 -
1350 - /**
1351 - * Add render attribute.
1352 - *
1353 - * @param array|string $element The HTML element.
1354 - * @param array|string $key Optional. Attribute key. Default is null.
1355 - * @param array|string $value Optional. Attribute value. Default is null.
1356 - * @param bool $overwrite Optional. Whether to overwrite existing.
1357 - *
1358 - * @return self
1359 - */
1360 - public function add_attribute( $element, $key = null, $value = null, $overwrite = false ) {
1361 - if ( is_array( $element ) ) {
1362 - foreach ( $element as $element_key => $attributes ) {
1363 - $this->add_attribute( $element_key, $attributes, null, $overwrite );
1364 - }
1365 -
1366 - return $this;
1367 - }
1368 -
1369 - if ( is_array( $key ) ) {
1370 - foreach ( $key as $attribute_key => $attributes ) {
1371 - $this->add_attribute( $element, $attribute_key, $attributes, $overwrite );
1372 - }
1373 -
1374 - return $this;
1375 - }
1376 -
1377 - if ( empty( $this->attributes[ $element ][ $key ] ) ) {
1378 - $this->attributes[ $element ][ $key ] = [];
1379 - }
1380 -
1381 - settype( $value, 'array' );
1382 -
1383 - if ( $overwrite ) {
1384 - $this->attributes[ $element ][ $key ] = $value;
1385 - } else {
1386 - $this->attributes[ $element ][ $key ] = array_merge( $this->attributes[ $element ][ $key ], $value );
1387 - }
1388 -
1389 - return $this;
1390 - }
1391 -
1392 - /**
1393 - * Get render attribute string.
1394 - *
1395 - * @param string $element The element.
1396 - *
1397 - * @return string
1398 - */
1399 - public function get_attribute_string( $element ) {
1400 - if ( empty( $this->attributes[ $element ] ) ) {
1401 - return '';
1402 - }
1403 -
1404 - return Utils::render_html_attributes( $this->attributes[ $element ] );
1405 - }
1406 -}
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 RadiusTheme\SB\Helpers\BuilderFns;
13 +use WP_Query;
14 +use Elementor\Icons_Manager;
15 +use RadiusTheme\SB\Helpers\Fns;
16 +use RadiusTheme\SB\Models\QueryArgs;
17 +use RadiusTheme\SB\Traits\SingletonTrait;
18 +use RadiusTheme\SB\Traits\ActionBtnTraits;
19 +use RadiusTheme\SB\Elementor\Helper\RenderHelpers;
20 +
21 +// Do not allow directly accessing this file.
22 +if ( ! defined( 'ABSPATH' ) ) {
23 + exit( 'This script cannot be accessed directly.' );
24 +}
25 +
26 +/**
27 + * Elementor Render Class.
28 + */
29 +class Render {
30 + /**
31 + * Singleton Trait.
32 + */
33 + use SingletonTrait;
34 +
35 + /**
36 + * Action button trait.
37 + */
38 + use ActionBtnTraits;
39 +
40 + /**
41 + * HTML.
42 + *
43 + * @var string
44 + */
45 + private $html = null;
46 +
47 + /**
48 + * Settings array
49 + *
50 + * @var array
51 + */
52 + public $get_settings;
53 +
54 + /**
55 + * Get elementor settings.
56 + *
57 + * @return array
58 + */
59 + public function get_settings_for_display() {
60 + return $this->get_settings;
61 + }
62 +
63 + /**
64 + * Container Wrapper HTML.
65 + *
66 + * @param string $content The content.
67 + * @param array $settings Settings.
68 + * @param string $class Class.
69 + * @param bool $fullwidth Fullwidth check.
70 + *
71 + * @return string
72 + */
73 + public function container( $content, $settings, $class = '', $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 +
79 + $metas = RenderHelpers::meta_dataset( $settings );
80 +
81 + $layout = $metas['layout'];
82 + $animation = $metas['hover_animation'];
83 +
84 + $is_cat = preg_match( '/category/', $layout );
85 + $is_carousel = preg_match( '/slider/', $layout );
86 +
87 + if ( ! $is_cat ) {
88 + $cart_txt_class = $metas['show_cart_text'] ? ' has-cart-text' : ' no-cart-text';
89 + }
90 +
91 + if ( $is_carousel ) {
92 + $fullwidth = true;
93 + }
94 +
95 + $badge_class = [
96 + 'position' => $metas['badge_position'],
97 + 'alignment' => $metas['badge_alignment'],
98 + ];
99 +
100 + if ( ! in_array( $layout, array_keys( Fns::free_layouts() ), true ) ) {
101 + $layout = RenderHelpers::set_default_layout( $layout );
102 + }
103 +
104 + $d_col = 0 === $metas['d_cols'] ? RenderHelpers::default_columns( $layout ) : $metas['d_cols'];
105 + $t_col = 0 === $metas['t_cols'] ? 2 : $metas['t_cols'];
106 + $m_col = 0 === $metas['m_cols'] ? 1 : $metas['m_cols'];
107 +
108 + if ( $fullwidth ) {
109 + $d_col = 12;
110 + $t_col = 12;
111 + $m_col = 12;
112 + }
113 +
114 + $pagination_attr = ( $is_carousel || $is_cat ? '' : RenderHelpers::pagination_data( $settings ) );
115 +
116 + if ( ! in_array( 'clear-btn', $metas['visibility'], true ) ) {
117 + $container_class .= ' no-clear-btn';
118 + }
119 +
120 + $container_attr .= ' data-layout="' . esc_attr( $layout ) . '" data-desktop-col="' . absint( $d_col ) . '" data-tab-col="' . absint( $t_col ) . '" data-mobile-col="' . absint( $m_col ) . '" ' . $pagination_attr;
121 + $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'] );
122 +
123 + if ( $metas['show_overlay'] ) {
124 + $container_class .= ' has-overlay';
125 + }
126 +
127 + $this->html = '<div class="' . esc_attr( $container_class ) . '" id="' . esc_attr( $layout_id ) . '" ' . $container_attr . '>';
128 +
129 + if( ! empty( $settings['query_products'] ) && count( $settings['query_products'] ) && 'yes' === $settings['show_section_title'] ){
130 + $this->html .='<div class="rtsb-section-title-wrapper">';
131 + $this->html .='<'.esc_attr( $settings['section_title_tag']).' class="rtsb-section-title" >';
132 + $this->html .=esc_html($settings['section_title_text']);
133 + $this->html .='</'.esc_attr( $settings['section_title_tag']).'>';
134 + $this->html .='</div>';
135 + }
136 +
137 + $this->html .= $content;
138 +
139 + $this->html .= '</div><!-- .rtsb-elementor-container -->';
140 +
141 + // Action button icon reset.
142 + $this->action_button_icon_set_default();
143 +
144 + $script_generator = [];
145 + $script_generator['layout'] = $layout_id;
146 + $script_generator['rand'] = absint( wp_rand() );
147 + $script_generator['isCarousel'] = $is_carousel;
148 +
149 + add_action(
150 + 'wp_footer',
151 + static function () use ( $script_generator ) {
152 + RenderHelpers::register_scripts( $script_generator );
153 + }
154 + );
155 +
156 + return $this->html;
157 + }
158 +
159 + /**
160 + * Row Wrapper HTML.
161 + *
162 + * @param string $content The content.
163 + * @param array $settings Settings.
164 + *
165 + * @return string
166 + */
167 + public function row( $content, $settings ) {
168 + $masonry_class = null;
169 + $loader_class = ' rtsb-pre-loader';
170 +
171 + $layout = $settings['layout'];
172 + $grid_type = $settings['grid_type'];
173 + $is_carousel = preg_match( '/slider/', $layout );
174 +
175 + if ( 'even' === $grid_type ) {
176 + $masonry_class = ' rtsb-even';
177 + } elseif ( 'masonry' === $grid_type ) {
178 + $masonry_class = ' rtsb-masonry';
179 + }
180 +
181 + if ( ! rtsb()->has_pro() || $is_carousel ) {
182 + $masonry_class = ' rtsb-even';
183 + }
184 +
185 + $this->html = '<div data-title="' . esc_html__( 'Loading ...', 'shopbuilder' ) . '" class="rtsb-row rtsb-content-loader element-loading ' . esc_attr( 'rtsb-'.$layout . $masonry_class . $loader_class ) . '">';
186 +
187 + if ( $is_carousel ) {
188 + $slider_data = RenderHelpers::slider_data( $settings );
189 +
190 + $this->html .= '<div class="rtsb-col-xs-12 ' . esc_attr( $slider_data['class'] ) . '" ' . $slider_data['data'] . '>';
191 + $this->html .= '<div class="swiper-wrapper">';
192 + }
193 +
194 + $this->html .= $content;
195 +
196 + if ( $is_carousel ) {
197 + $this->html .= '</div><!-- .swiper-wrapper -->';
198 +
199 + $left_icon = $settings['left_arrow_icon'];
200 + $right_icon = $settings['right_arrow_icon'];
201 +
202 + if ( ! empty( $settings['slider_nav'] ) ) {
203 + $this->html .=
204 + '<div class="swiper-nav">
205 + <div class="swiper-arrow swiper-button-next">
206 + ' . Fns::icons_manager( $right_icon ) . '
207 + </div>
208 + <div class="swiper-arrow swiper-button-prev">
209 + ' . Fns::icons_manager( $left_icon ) . '
210 + </div>
211 + </div>';
212 + }
213 +
214 + $this->html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
215 +
216 + $this->html .= '</div><!-- .rtsb-carousel-slider -->';
217 + }
218 +
219 + $this->html .= RenderHelpers::pre_loader( $layout );
220 +
221 + $this->html .= '</div><!-- .rtsb-row -->';
222 +
223 + return $this->html;
224 + }
225 +
226 + /**
227 + * Product loop.
228 + *
229 + * @param object $query The query.
230 + * @param array $settings Settings.
231 + * @param string $template Template.
232 + *
233 + * @return string|null
234 + */
235 + public function product_loop( $query, $settings, $template ) {
236 + $html = null;
237 +
238 + if ( empty( $query ) ) {
239 + return null;
240 + }
241 +
242 + while ( $query->have_posts() ) {
243 + $query->the_post();
244 +
245 + // Loop arg.
246 + $arg = $this->arg_dataset( $settings, get_the_ID(), $settings['lazy_load'] );
247 +
248 + // Get template.
249 + $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
250 + }
251 +
252 + return $html;
253 + }
254 +
255 + /**
256 + * Product loop.
257 + *
258 + * @param object $query The query.
259 + * @param array $settings Settings.
260 + * @param string $template Template.
261 + * @param bool $is_single Single category.
262 + *
263 + * @return string|null
264 + */
265 + public function category_loop( $query, $settings, $template, $is_single = false ) {
266 + $html = null;
267 + $term_link = null;
268 +
269 + if ( $is_single ) {
270 + // Loop arg.
271 + $arg = $this->cat_arg_dataset( $settings, $query, true );
272 +
273 + // Get template.
274 + $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
275 + } else {
276 + foreach ( $query as $term ) {
277 + // Loop arg.
278 + $arg = $this->cat_arg_dataset( $settings, $term );
279 +
280 + // Get template.
281 + $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
282 + }
283 + }
284 +
285 + return $html;
286 + }
287 +
288 + /**
289 + * Render Product View.
290 + *
291 + * @param string $template Template name.
292 + * @param array $settings Control settings.
293 + *
294 + * @return string
295 + */
296 + public function product_view( $template, $settings ) {
297 + $this->get_settings = $settings;
298 +
299 + $metas = RenderHelpers::meta_dataset( $settings );
300 + $is_carousel = preg_match( '/slider/', $metas['layout'] );
301 + $pagination = $metas['pagination'];
302 +
303 + // Query Args.
304 + $args = ( new QueryArgs() )->buildArgs( $metas, 'product', $is_carousel );
305 +
306 + // Query.
307 + $product_query = new WP_Query( $args );
308 +
309 + if ( $product_query->have_posts() ) {
310 + // Row.
311 + $this->row( $this->product_loop( $product_query, $metas, $template ), $metas );
312 +
313 + // Pagination.
314 + if ( $pagination ) {
315 + $this->html .= RenderHelpers::render_pagination(
316 + $product_query,
317 + $metas,
318 + $settings['posts_limit'],
319 + $settings['pagination_per_page']
320 + );
321 + }
322 + } else {
323 + $this->html .= '<p>' . esc_html__( 'No products found', 'shopbuilder' ) . '</p>';
324 + }
325 +
326 + wp_reset_postdata();
327 +
328 + // Container.
329 + $this->container( $this->html, $settings, 'rtsb-products-container', $is_carousel );
330 +
331 + return $this->html;
332 + }
333 +
334 +
335 + /**
336 + * Render Product View.
337 + *
338 + * @param string $template Template name.
339 + * @param array $settings Control settings.
340 + *
341 + * @return string
342 + */
343 + public function wc_loop_for_product_view( $template, $settings ) {
344 + global $wp_query, $post;
345 +
346 + $this->get_settings = $settings;
347 +
348 + $metas = RenderHelpers::meta_dataset( $settings );
349 + $pagination = $metas['pagination'];
350 +
351 + $page_type = BuilderFns::builder_type( get_the_ID() );
352 + $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
353 + $posts_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
354 +
355 + if ( $is_preview ) {
356 + $main_query = clone $wp_query;
357 + $main_post = clone $post;
358 +
359 + $ordering = ( new \WC_Query() )->get_catalog_ordering_args();
360 + $wp_query_args = [
361 + 'post_type' => 'product',
362 + 'posts_per_page' => $posts_per_page,
363 + ];
364 +
365 + if ( ! empty( $ordering['orderby'] ) ) {
366 + $wp_query_args['orderby'] = $ordering['orderby'];
367 + }
368 +
369 + if ( ! empty( $ordering['order'] ) ) {
370 + $wp_query_args['order'] = $ordering['order'];
371 + }
372 +
373 + $wp_query = new \WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
374 + wc_set_loop_prop( 'total', $wp_query->found_posts );
375 + wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
376 + }
377 +
378 + // column_per_row.
379 + if ( woocommerce_product_loop() ) {
380 + if ( wc_get_loop_prop( 'total' ) ) {
381 + // Row.
382 + $this->row( $this->product_loop( $wp_query, $metas, $template ), $metas );
383 + }
384 +
385 + // Pagination.
386 + if ( $pagination ) {
387 + $this->html .= RenderHelpers::render_pagination(
388 + $wp_query,
389 + $metas,
390 + wc_get_loop_prop( 'total' ),
391 + $posts_per_page
392 + );
393 + }
394 + } else {
395 + $this->html .= '<p>' . esc_html__( 'No products found', 'shopbuilder' ) . '</p>';
396 + }
397 +
398 + if ( $is_preview ) {
399 + $wp_query = $main_query;
400 + $post = $main_post;
401 +
402 + wp_reset_query();
403 + wp_reset_postdata();
404 + }
405 +
406 + // Container.
407 + $this->container( $this->html, $settings, 'rtsb-products-container' );
408 +
409 + return $this->html;
410 + }
411 +
412 + /**
413 + * Render Product View.
414 + *
415 + * @param string $template Template name.
416 + * @param array $settings Control settings.
417 + *
418 + * @return string
419 + */
420 + public function setup_loop_for_product_view( $template, $settings ) {
421 + if ( empty( $settings['query_products'] ) ) {
422 + return $this->html;
423 + }
424 +
425 + $html = null;
426 +
427 + $metas = RenderHelpers::meta_dataset( $settings );
428 +
429 + foreach ( $settings['query_products'] as $_product ) {
430 + $post_object = get_post( $_product->get_id() );
431 +
432 + setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found
433 +
434 + // Loop arg.
435 + $arg = $this->arg_dataset( $metas, get_the_ID() );
436 + // Get template.
437 + $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
438 +
439 + $this->row( $html, $metas );
440 + }
441 +
442 + // Container.
443 + $this->container( $this->html, $settings, 'rtsb-products-container' );
444 +
445 + wp_reset_postdata();
446 +
447 + return $this->html;
448 +
449 + }
450 + /**
451 + * Render Category View.
452 + *
453 + * @param string $template Template name.
454 + * @param array $settings Control settings.
455 + * @param bool $is_single Single category.
456 + *
457 + * @return string
458 + */
459 + public function category_view( $template, $settings, $is_single = false ) {
460 + $this->get_settings = $settings;
461 +
462 + $metas = RenderHelpers::meta_dataset( $settings );
463 + $taxonomy = $metas['category_source'];
464 + $term = $metas['category_term'];
465 +
466 + // Query.
467 + if ( $is_single ) {
468 + if ( empty( $term ) ) {
469 + return '<p>' . esc_html__( 'Please select a category.', 'shopbuilder' ) . '</p>';
470 + }
471 +
472 + $category_query = get_term( $term, $taxonomy );
473 + } else {
474 + // Query Args.
475 + $args = ( new QueryArgs() )->buildArgs( $metas, 'category' );
476 +
477 + $category_query = get_terms( $args );
478 + }
479 +
480 + if ( ! empty( $category_query ) ) {
481 + // Row.
482 + $this->row( $this->category_loop( $category_query, $metas, $template, $is_single ), $metas );
483 + } else {
484 + $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
485 + }
486 +
487 + // Container.
488 + $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
489 +
490 + return $this->html;
491 + }
492 +
493 + /**
494 + * Render Category View.
495 + *
496 + * @param string $template Template name.
497 + * @param array $settings Control settings.
498 + *
499 + * @return string
500 + */
501 + public function social_share_view( $template, $settings ) {
502 + $share_items = [];
503 +
504 + foreach ( $settings['share_platforms'] as $platform ) {
505 + $share_items[] = [
506 + 'share_items' => $platform['share_items'],
507 + 'share_text' => $platform['share_text'],
508 + ];
509 + }
510 +
511 + if ( ! empty( $share_items ) && is_array( $share_items ) ) {
512 + $arg['p_id'] = get_the_ID();
513 + $arg['share_items'] = $share_items;
514 + $arg['preset'] = $settings['layout'];
515 + $arg['show_icon'] = $settings['show_share_icon'];
516 + $this->html = Fns::load_template( $template, $arg, true );
517 + } else {
518 + $this->html = '<p>' . esc_html__( 'Please select a social sharing platform.', 'shopbuilder' ) . '</p>';
519 + }
520 +
521 + return $this->html;
522 + }
523 +
524 + /**
525 + * Builds an array with meta values.
526 + *
527 + * @param array $meta Meta values.
528 + * @param int $post_id Post ID.
529 + * @param bool $lazy_load Lazy Load.
530 + * @return array
531 + */
532 + public function arg_dataset( array $meta, int $post_id, bool $lazy_load = false ) {
533 + if ( empty( $meta ) && ! $post_id ) {
534 + return [];
535 + }
536 +
537 + $arg = [];
538 + $_product = wc_get_product( $post_id );
539 + $p_type = $_product->get_type();
540 +
541 + $arg['class'] = null;
542 + $arg['grid'] = null;
543 + $arg['anchor_class'] = null;
544 + $arg['hover_img_html'] = null;
545 + $arg['s_link'] = [];
546 + $arg['add_to_cart'] = '';
547 + $arg['p_id'] = $post_id;
548 + $arg['p_link'] = get_permalink();
549 + $arg['p_sale'] = '';
550 + $cart_icon_html = '';
551 +
552 + $layout = $meta['layout'];
553 +
554 + $arg['target'] = '_self';
555 + $arg['f_img'] = $meta['f_img'];
556 + $arg['items'] = $meta['visibility'];
557 + $arg['title_tag'] = $meta['title_tag'];
558 + $arg['title_class'] = 'product-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
559 + $arg['title'] = Fns::text_truncation( get_the_title(), $meta['title_limit_custom'] );
560 + $arg['excerpt_limit'] = $meta['excerpt_limit'];
561 + $arg['excerpt'] = wpautop( Fns::text_truncation( get_the_excerpt(), $meta['excerpt_limit_custom'] ) );
562 + $arg['title_link'] = $meta['title_link'];
563 + $arg['image_link'] = $meta['image_link'];
564 + $arg['out_of_stock'] = $meta['out_of_stock_badge_text'];
565 + $arg['action_btn_preset'] = $meta['btn_preset'];
566 + $arg['action_btn_position'] = $meta['btn_position'];
567 +
568 + $is_list = preg_match( '/list/', $layout );
569 + $is_carousel = preg_match( '/slider/', $layout );
570 +
571 + $d_col = 0 === $meta['d_cols'] ? RenderHelpers::default_columns( $layout ) : $meta['d_cols'];
572 + $t_col = 0 === $meta['t_cols'] ? 2 : $meta['t_cols'];
573 + $m_col = 0 === $meta['m_cols'] ? 1 : $meta['m_cols'];
574 +
575 + $d_col = 5 === $d_col ? '24' : round( 12 / $d_col );
576 + $t_col = 5 === $t_col ? '24' : round( 12 / $t_col );
577 + $m_col = 5 === $m_col ? '24' : round( 12 / $m_col );
578 +
579 + if ( ! $is_carousel ) {
580 + $arg['grid'] .= 'rtsb-col-md-' . $d_col . ' rtsb-col-sm-' . $t_col . ' rtsb-col-xs-' . $m_col . ' ';
581 + $arg['class'] .= ' ' . ( rtsb()->has_pro() ? $meta['gridType'] : 'even' ) . '-grid-item ';
582 + } else {
583 + $arg['grid'] .= 'rtsb-slide-item swiper-slide ';
584 + }
585 +
586 + $arg['class'] .= 'rtsb-product';
587 +
588 + if ( $is_list ) {
589 + $arg['class'] .= ' rtsb-product-list';
590 + }
591 +
592 + $arg['class'] .= ' animated fadeIn';
593 +
594 + if ( in_array( 'badges', $meta['visibility'], true ) ) {
595 + $arg['p_sale'] = Fns::get_sale_badge(
596 + $meta['sale_badge_type'],
597 + $meta['sale_badge_text'],
598 + $meta['out_of_stock_badge_text']
599 + );
600 + }
601 +
602 + $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
603 +
604 + if ( ! $meta['show_cart_text'] ) {
605 + $meta['add_to_cart_text'] = '';
606 + }
607 +
608 + if ( in_array( 'add_to_cart', $meta['visibility'], true ) ) {
609 + if ( ! empty( $meta['add_to_cart_icon'] ) ) {
610 + $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_icon'], 'cart-icon' );
611 + }
612 +
613 + if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
614 + $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
615 + }
616 +
617 + $cart_icon = '<span class="icon">' . $cart_icon_html . '</span>';
618 +
619 + if ( $_product->is_purchasable() ) {
620 + if ( $_product->is_in_stock() ) {
621 + // TODO:: Replace add to cart with WC hooks
622 + $arg['add_to_cart'] = $this->render_add_to_cart_button(
623 + get_permalink(),
624 + $post_id,
625 + $p_type,
626 + $meta['add_to_cart_text'],
627 + $cart_icon,
628 + $meta['add_to_cart_alignment']
629 + );
630 + }
631 + }
632 + }
633 +
634 + if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
635 + add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
636 + add_filter( 'rtsb/module/quick_view/icon_html', [ $this, 'quick_view_icon' ] );
637 + }
638 +
639 + if ( in_array( 'compare', $meta['visibility'], true ) ) {
640 + add_filter( 'rtsb/module/compare/button_params', [ $this, 'button_classes' ] );
641 + add_filter( 'rtsb/module/compare/icon_html', [ $this, 'compare_icon' ] );
642 + }
643 +
644 + if ( in_array( 'wishlist', $meta['visibility'], true ) ) {
645 + add_filter( 'rtsb/module/wishlist/button_params', [ $this, 'button_classes' ] );
646 + add_filter( 'rtsb/module/wishlist/icon_html', [ $this, 'wishlist_icon' ] );
647 + }
648 +
649 + $arg['img_html'] = $meta['f_img'] ? Fns::get_product_image_html(
650 + 'product',
651 + $post_id,
652 + $meta['f_img_size'],
653 + $meta['default_img_id'],
654 + $meta['custom_img_size'],
655 + $lazy_load
656 + ) : null;
657 +
658 + $gallery_ids = $_product->get_gallery_image_ids();
659 +
660 + if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
661 + $arg['class'] .= ' rtsb-double-img';
662 + $arg['hover_img_html'] = Fns::get_product_image_html(
663 + 'product',
664 + $gallery_ids[0],
665 + $meta['f_img_size'],
666 + null,
667 + $meta['custom_img_size'],
668 + $lazy_load,
669 + true
670 + );
671 + }
672 +
673 + $arg['hover_btn_text'] = $meta['hover_btn_text'];
674 +
675 + if ( $meta['show_hover_btn_icon'] && ! empty( $meta['hover_btn_icon'] ) ) {
676 + $arg['hover_btn_icon'] = '<span class="icon">' . Fns::icons_manager( $meta['hover_btn_icon'], 'hover-btn-icon' ) . '</span>';
677 + }
678 +
679 + return $arg;
680 + }
681 +
682 + /**
683 + * Builds an array with meta values.
684 + *
685 + * @param array $meta Meta values.
686 + * @param Object $query Category object.
687 + * @param bool $fullwidth Fullwidth check.
688 + * @param bool $lazy_load Lazy Load.
689 + * @return array
690 + */
691 + public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false ) {
692 + if ( empty( $meta ) ) {
693 + return [];
694 + }
695 +
696 + $arg = [];
697 +
698 + $arg['class'] = null;
699 + $arg['grid'] = null;
700 + $arg['anchor_class'] = null;
701 + $arg['p_sale'] = null;
702 + $arg['count'] = max( $query->count, 0 );
703 + $arg['count_position'] = $meta['count_position'];
704 + $arg['excerpt_position'] = $meta['cat_excerpt_position'];
705 + $arg['cat_link'] = get_term_link( $query );
706 + $arg['target'] = '_self';
707 +
708 + if ( ! empty( $meta['custom_link']['url'] ) ) {
709 + $arg['cat_link'] = $meta['custom_link']['url'];
710 + $arg['target'] = $meta['custom_link']['is_external'] ? '_blank' : '_self';
711 + }
712 +
713 + $title = $query->name;
714 + $excerpt = $query->description;
715 +
716 + if ( in_array( 'badges', $meta['visibility'], true ) ) {
717 + $arg['p_sale'] = $meta['custom_badge_text'];
718 + }
719 +
720 + $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
721 +
722 + if ( $arg['count'] >= 0 ) {
723 + $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
724 + $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
725 +
726 + $arg['count'] = $prefix . $arg['count'] . $suffix;
727 + }
728 +
729 + if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
730 + $title = $meta['cat_custom_title'];
731 + }
732 +
733 + if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
734 + $excerpt = $meta['cat_custom_excerpt'];
735 + }
736 +
737 + $layout = $meta['layout'];
738 +
739 + $arg['c_img'] = $meta['c_img'];
740 + $arg['items'] = $meta['visibility'];
741 + $arg['title_tag'] = $meta['title_tag'];
742 + $arg['title_class'] = 'category-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
743 + $arg['title'] = Fns::text_truncation( $title, $meta['title_limit_custom'] );
744 + $arg['excerpt_limit'] = $meta['excerpt_limit'];
745 + $arg['excerpt'] = wpautop( Fns::text_truncation( $excerpt, $meta['excerpt_limit_custom'] ) );
746 + $arg['title_link'] = $meta['title_link'];
747 + $arg['image_link'] = $meta['image_link'];
748 +
749 + $d_col = 0 === $meta['d_cols'] ? RenderHelpers::default_columns( $layout ) : absint( $meta['d_cols'] );
750 + $t_col = 0 === $meta['t_cols'] ? 2 : absint( $meta['t_cols'] );
751 + $m_col = 0 === $meta['m_cols'] ? 1 : absint( $meta['m_cols'] );
752 +
753 + $d_col = 5 === $d_col ? '24' : round( 12 / $d_col );
754 + $t_col = 5 === $t_col ? '24' : round( 12 / $t_col );
755 + $m_col = 5 === $m_col ? '24' : round( 12 / $m_col );
756 +
757 + if ( ! $fullwidth ) {
758 + $arg['grid'] .= 'rtsb-col-md-' . $d_col . ' rtsb-col-sm-' . $t_col . ' rtsb-col-xs-' . $m_col . ' ';
759 + $arg['class'] .= ' ' . ( rtsb()->has_pro() ? $meta['gridType'] : 'even' ) . '-grid-item ';
760 + } else {
761 + $arg['grid'] .= 'rtsb-col-xs-12 ';
762 + }
763 +
764 + $arg['class'] .= 'rtsb-category-grid';
765 +
766 + $arg['img_html'] = $meta['c_img'] ? Fns::get_product_image_html(
767 + 'category',
768 + $query->term_id,
769 + $meta['f_img_size'],
770 + $meta['default_img_id'],
771 + $meta['custom_img_size'],
772 + $lazy_load
773 + ) : null;
774 +
775 + if ( $meta['show_custom_image'] && ! empty( $meta['custom_image'] ) ) {
776 + $arg['img_html'] = Fns::get_product_image_html(
777 + 'custom',
778 + null,
779 + $meta['f_img_size'],
780 + $meta['custom_image'],
781 + $meta['custom_img_size'],
782 + $lazy_load
783 + );
784 + }
785 +
786 + $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' : '' );
787 +
788 + return $arg;
789 + }
790 +
791 + /**
792 + * Renders add to cart button.
793 + *
794 + * @param string $link Product link.
795 + * @param int $id Product ID.
796 + * @param string $type Product type.
797 + * @param string $text Custom text.
798 + * @param string $icon_html Custom icon.
799 + * @param string $alignment Icon alignment.
800 + * @return string
801 + */
802 + public function render_add_to_cart_button( $link, $id, $type, $text, $icon_html, $alignment ) {
803 + $content = null;
804 + $tooltip_attr = '';
805 +
806 + if ( empty( $text ) ) {
807 + $tooltip_attr = ' title="' . esc_attr__( 'Add to Cart', 'shopbuilder' ) . '"';
808 +
809 + if ( 'variable' === $type ) {
810 + $tooltip_attr = ' title="' . esc_attr__( 'Select Options', 'shopbuilder' ) . '"';
811 + }
812 + }
813 +
814 + if ( 'variable' === $type ) {
815 + $content .= sprintf(
816 + '<div class="rtsb-wc-add-to-cart-wrap">
817 + <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>
818 + </div>',
819 + esc_url( $link ),
820 + esc_html__( 'Select Options', 'shopbuilder' ),
821 + absint( $id ),
822 + esc_attr( $alignment ),
823 + empty( $text ) ? 'no-text' : 'has-text',
824 + $tooltip_attr,
825 + $icon_html,
826 + );
827 +
828 + return $content;
829 + }
830 +
831 + $content .= sprintf(
832 + '<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">%5$s</span><span></span></a>',
833 + esc_url( $link ),
834 + absint( $id ),
835 + esc_attr( $type ),
836 + $icon_html,
837 + esc_html( $text ),
838 + esc_attr( $alignment ),
839 + empty( $text ) ? 'no-text' : 'has-text',
840 + $tooltip_attr
841 + );
842 +
843 + return $content;
844 + }
845 +
846 + /**
847 + * Button classes.
848 + *
849 + * @param array $params Button params.
850 + * @return array
851 + */
852 + public function button_classes( $params ) {
853 + $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
854 +
855 + return $params;
856 + }
857 +}