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