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 +356 -731 2.1.11 → 2.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">';
@@ -477,51 +440,40 @@
477 440 // Pagination.
478 441 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
479 442
480 443 if ( $pagination ) {
481 - if ( Fns::product_filters_has_ajax( apply_filters( 'rtsb/builder/set/current/page/type', '' ) ) ) {
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,14 +682,12 @@
919 682
920 683 $arg['class'] .= ' animated rtFadeIn';
921 684
922 685 if ( in_array( 'badges', $meta['visibility'], true ) ) {
923 - $badge_module = ! empty( $meta['enable_badges_module'] );
924 - $arg['p_sale'] = Fns::is_module_active( 'product_badges' ) && $badge_module ? 'rtsb_yes' : Fns::get_promo_badge(
925 - $product,
686 + $arg['p_sale'] = Fns::get_sale_badge(
926 687 $meta['sale_badge_type'],
927 688 $meta['sale_badge_text'],
928 - apply_filters( 'rtsb/elementor/render/out_of_stock_badge_text', $meta['out_of_stock_badge_text'] )
689 + $meta['out_of_stock_badge_text']
929 690 );
930 691 }
931 692
932 693 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
@@ -944,22 +705,20 @@
944 705 if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
945 706 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
946 707 }
947 708
948 - $cart_icon = ! empty( $cart_icon_html ) ? '<span class="icon">' . $cart_icon_html . '</span>' : '';
709 + $cart_icon = '<span class="icon">' . $cart_icon_html . '</span>';
949 710
950 - if ( $product->is_purchasable() || 'grouped' === $p_type || 'external' === $p_type ) {
951 - if ( $product->is_in_stock() ) {
711 + if ( $_product->is_purchasable() || 'grouped' === $p_type || 'external' === $p_type ) {
712 + if ( $_product->is_in_stock() ) {
952 713 $arg['add_to_cart'] = $this->render_add_to_cart_button(
953 - [
954 - 'link' => $product->get_permalink(),
955 - 'id' => $post_id,
956 - 'type' => $p_type,
957 - 'text' => $meta['add_to_cart_text'],
958 - 'success' => $meta['add_to_cart_success_text'],
959 - 'icon_html' => $cart_icon,
960 - 'alignment' => $meta['add_to_cart_alignment'],
961 - ]
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']
962 721 );
963 722 }
964 723 }
965 724 }
@@ -987,10 +746,10 @@
987 746 $meta['custom_img_size'],
988 747 $lazy_load
989 748 ) : null;
990 749
991 - if ( ! ( function_exists( 'rtwpvsp' ) && $product->is_type( 'variable' ) && $product->get_attributes() ) ) {
992 - $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();
993 752
994 753 if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
995 754 $arg['class'] .= ! $meta['gallery_img'] ? ' rtsb-double-img' : '';
996 755
@@ -1025,364 +784,230 @@
1025 784 'hover_img_html' => $arg['hover_img_html'],
1026 785 'meta' => $meta,
1027 786 ];
1028 787
1029 - return $arg;
788 + return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
1030 789 }
1031 790
1032 791 /**
1033 - * Renders add to cart button.
792 + * Builds an array with meta values.
1034 793 *
1035 - * @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.
1036 798 *
1037 - * @return string
799 + * @return array
1038 800 */
1039 - public function render_add_to_cart_button( $args ) {
1040 - list(
1041 - 'link' => $link,
1042 - 'id' => $id,
1043 - 'type' => $type,
1044 - 'text' => $text,
1045 - 'success' => $success,
1046 - 'icon_html' => $icon_html,
1047 - 'alignment' => $alignment
1048 - ) = $args;
801 + public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false ) {
802 + if ( empty( $meta ) ) {
803 + return [];
804 + }
1049 805
1050 - $content = null;
1051 - $rand = wp_rand();
1052 - $ext_link = get_post_meta( $id, '_product_url', true );
1053 - $btn_txt = get_post_meta( $id, '_button_text', true );
806 + $arg = [];
1054 807
1055 - ob_start();
1056 - do_action( 'rtsb/before/cart/button' );
1057 - $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'] : [];
1058 818
1059 - $cart_attr = [
1060 - 'class' => 'rtsb-action-btn ' . $type . '-product tipsy icon-' . $alignment . ' ' . ( empty( $text ) ? 'no-text' : 'has-text' ),
1061 - 'href' => esc_url( $link ),
1062 - 'rel' => 'nofollow',
1063 - 'data-quantity' => '1',
1064 - 'data-product_id' => absint( $id ),
1065 - 'data-id' => absint( $id ),
1066 - ];
819 + if ( ! empty( $meta['tag_term'] ) ) {
820 + $arg['tag_term'] = $meta['tag_term'];
821 + }
1067 822
1068 - if ( empty( $text ) ) {
1069 - $tooltip_mapping = [
1070 - 'simple' => esc_attr__( 'Add to Cart', 'shopbuilder' ),
1071 - 'variable' => esc_attr__( 'Select Options', 'shopbuilder' ),
1072 - 'grouped' => esc_attr__( 'View Products', 'shopbuilder' ),
1073 - 'external' => ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
1074 - ];
1075 -
1076 - $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';
1077 826 }
1078 827
1079 - $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
828 + $title = $query->name;
829 + $excerpt = $query->description;
1080 830
1081 - if ( 'variable' === $type || 'grouped' === $type ) {
1082 - $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 + }
1083 834
1084 - $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
835 + $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
1085 836
1086 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1087 - $content .= $icon_html;
1088 - $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>';
1089 - $content .= '<span></span>';
1090 - } elseif ( 'external' === $type ) {
1091 - if ( ! empty( $ext_link ) ) {
1092 - $cart_attr['target'] = '_blank';
1093 - }
837 + if ( $arg['count'] >= 0 ) {
838 + $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
839 + $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
1094 840
1095 - $cart_attr['href'] = ! empty( $ext_link ) ? esc_url( $ext_link ) : esc_url( $link );
1096 -
1097 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1098 -
1099 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1100 - $content .= $icon_html;
1101 - $content .= '<span class="text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1102 - } else {
1103 - $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1104 - $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1105 - $cart_attr['data-type'] = $type;
1106 -
1107 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1108 -
1109 - $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1110 - $content .= $icon_html;
1111 - $content .= '<span class="text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1112 - $content .= '<span></span>';
841 + $arg['count'] = $prefix . $arg['count'] . $suffix;
1113 842 }
1114 843
1115 - $content .= '</a>';
1116 - $content .= '</div>';
1117 -
1118 - ob_start();
1119 - do_action( 'rtsb/after/cart/button' );
1120 - $content .= ob_get_clean();
1121 -
1122 - return apply_filters( 'rtsb/render/cart/button', $content, $args );
1123 - }
1124 -
1125 - /**
1126 - * Button classes.
1127 - *
1128 - * @param array $params Button params.
1129 - *
1130 - * @return array
1131 - */
1132 - public function button_classes( $params ) {
1133 - $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
1134 -
1135 - return $params;
1136 - }
1137 -
1138 - /**
1139 - * Render the section title.
1140 - *
1141 - * @param array $settings The Elementor settings.
1142 - *
1143 - * @return string
1144 - */
1145 - public function render_section_title( $settings ) {
1146 - $html = '';
1147 - $rand = wp_rand();
1148 -
1149 - if ( empty( $settings['show_section_title'] ) || ( empty( $settings['query_products'] ) && 0 === count( $settings['query_products'] ) ) ) {
1150 - return $html;
844 + if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
845 + $title = $meta['cat_custom_title'];
1151 846 }
1152 847
1153 - // Set attributes for the section title.
1154 - $this->add_attribute( 'rtsb_section_title_wrapper_' . $rand, 'class', 'rtsb-section-title-wrapper' );
1155 - $this->add_attribute( 'rtsb_section_title_' . $rand, 'class', 'rtsb-section-title' );
1156 -
1157 - // Start rendering.
1158 - $html .= '<div ' . $this->get_attribute_string( 'rtsb_section_title_wrapper_' . $rand ) . '>';
1159 - $html .= '<' . esc_attr( $settings['section_title_tag'] ) . ' ' . $this->get_attribute_string( 'rtsb_section_title_' . $rand ) . '>';
1160 - $html .= esc_html( $settings['section_title_text'] );
1161 - $html .= '</' . esc_attr( $settings['section_title_tag'] ) . '>';
1162 - $html .= '</div>';
1163 -
1164 - return $html;
1165 - }
1166 -
1167 - /**
1168 - * Renders products pagination
1169 - *
1170 - * @param array $args Pagination args.
1171 - * @param string $query_type Query type.
1172 - *
1173 - * @return string
1174 - */
1175 - public function render_products_pagination( $args, $query_type = 'wc' ) {
1176 - list(
1177 - 'query' => $query,
1178 - 'meta' => $meta,
1179 - 'limit' => $limit,
1180 - 'per_page' => $per_page
1181 - ) = $args;
1182 -
1183 - $html_utility = null;
1184 - $html = null;
1185 - $ajax = false;
1186 - $is_grid = preg_match( '/grid-layout/', $meta['layout'] ) || preg_match( '/list-layout/', $meta['layout'] );
1187 - $posts_per_page = 'wp' === $query_type ? $query->query_vars['posts_per_page'] : null;
1188 - $total_page = 'wp' === $query_type ? $query->max_num_pages : $query->get_products()->max_num_pages;
1189 -
1190 - if ( $limit ) {
1191 - if ( 'wc' === $query_type ) {
1192 - $found_post = $query->get_products()->total;
1193 - } elseif ( 'wp' === $query_type && ( empty( $wp_query->query['tax_query'] ) ) ) {
1194 - $found_post = $query->found_posts;
1195 - }
1196 -
1197 - if ( $per_page && $found_post > $per_page ) {
1198 - $found_post = $limit;
1199 - $total_page = ceil( $found_post / $per_page );
1200 - }
848 + if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
849 + $excerpt = $meta['cat_custom_excerpt'];
1201 850 }
1202 851
1203 - $total_page = absint( $total_page );
852 + $layout = $meta['layout'];
1204 853
1205 - $args = [
1206 - 'total_page' => $total_page,
1207 - 'posts_per_page' => 'wc' === $query_type ? $per_page : $posts_per_page,
1208 - 'ajax' => $ajax,
1209 - ];
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'];
1210 863
1211 - if ( 'pagination' === $meta['posts_loading_type'] ) {
1212 - if ( $is_grid ) {
1213 - $html_utility .= Fns::custom_pagination(
1214 - $total_page,
1215 - 'wc' === $query_type ? $per_page : $posts_per_page
1216 - );
1217 - }
864 + if ( ! $fullwidth ) {
865 + $arg['grid'] .= 'rtsb-col-grid ';
866 + $arg['class'] .= ' even-grid-item ';
1218 867 } else {
1219 - ob_start();
1220 - do_action( 'rtsb/elementor/render/pagination', $meta, $query, $args );
1221 - $html_utility .= ob_get_clean();
868 + $arg['grid'] .= 'rtsb-col-grid ';
1222 869 }
1223 870
1224 - if ( $html_utility ) {
1225 - $rand = wp_rand();
871 + $arg['class'] .= 'rtsb-category-grid';
1226 872
1227 - // Adding pagination render attributes.
1228 - $this->add_attribute(
1229 - 'rtsb_pagination_attr_' . $rand,
1230 - [
1231 - 'class' => 'rtsb-pagination-wrap element-loading',
1232 - 'data-total-pages' => $total_page,
1233 - 'data-posts-per-page' => 'wc' === $query_type ? $per_page : $posts_per_page,
1234 - 'data-type' => $meta['posts_loading_type'],
1235 - ]
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
1236 890 );
1237 -
1238 - // Start rendering.
1239 - $html = '<div ' . $this->get_attribute_string( 'rtsb_pagination_attr_' . $rand ) . '>';
1240 - $html .= $html_utility;
1241 - $html .= '</div><!-- .rtsb-pagination-wrap -->';
1242 891 }
1243 892
1244 - return $html;
1245 - }
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' : '' );
1246 894
1247 - /**
1248 - * Renders slider buttons
1249 - *
1250 - * @param array $settings Settings array.
1251 - *
1252 - * @return string
1253 - */
1254 - public function render_slider_buttons( $settings ) {
1255 - $html = '';
1256 - $left_icon = $settings['left_arrow_icon'];
1257 - $right_icon = $settings['right_arrow_icon'];
1258 -
1259 - if ( ! empty( $settings['slider_nav'] ) ) {
1260 - $html .=
1261 - '<div class="swiper-nav">
1262 - <div class="swiper-arrow swiper-button-next">
1263 - ' . Fns::icons_manager( $right_icon ) . '
1264 - </div>
1265 - <div class="swiper-arrow swiper-button-prev">
1266 - ' . Fns::icons_manager( $left_icon ) . '
1267 - </div>
1268 - </div>';
1269 - }
1270 -
1271 - $html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
1272 -
1273 - return $html;
895 + return $arg;
1274 896 }
1275 897
1276 898 /**
1277 - * No products message.
899 + * Renders add to cart button.
1278 900 *
1279 - * @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.
1280 908 *
1281 - * @return void
1282 - */
1283 - public function no_products_msg( $metas ) {
1284 - $content =
1285 - '<div class="rtsb-notice woocommerce-no-products-found">
1286 - <div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder' ) . '</div>
1287 - </div>';
1288 -
1289 - $this->row( $content, $metas );
1290 - }
1291 -
1292 - /**
1293 - * Start the rendering.
1294 - *
1295 - * @param array $metas Meta Data.
1296 - * @param array $settings Widget settings.
1297 - * @param array $temp_args Additional temporary arguments for rendering.
1298 - *
1299 909 * @return string
1300 910 */
1301 - public function render_start( $metas, $settings, $temp_args ) {
1302 - 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 );
1303 916
1304 - /**
1305 - * Before render row hook.
1306 - */
1307 - 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' ) . '"';
1308 919
1309 - return ob_get_clean();
1310 - }
920 + if ( 'variable' === $type ) {
921 + $tooltip_attr = ' title="' . esc_attr__( 'Select Options', 'shopbuilder' ) . '"';
922 + }
1311 923
1312 - /**
1313 - * End the rendering.
1314 - *
1315 - * @param array $metas Meta Data.
1316 - * @param array $settings Widget settings.
1317 - * @param array $products Array of products being rendered.
1318 - *
1319 - * @return string
1320 - */
1321 - public function render_end( $metas, $settings, $products ) {
1322 - ob_start();
1323 -
1324 - /**
1325 - * After render row hook.
1326 - */
1327 - do_action( 'rtsb/elementor/render/after_row', $metas, $settings, $products );
1328 -
1329 - return ob_get_clean();
1330 - }
1331 -
1332 - /**
1333 - * Add render attribute.
1334 - *
1335 - * @param array|string $element The HTML element.
1336 - * @param array|string $key Optional. Attribute key. Default is null.
1337 - * @param array|string $value Optional. Attribute value. Default is null.
1338 - * @param bool $overwrite Optional. Whether to overwrite existing.
1339 - *
1340 - * @return self
1341 - */
1342 - public function add_attribute( $element, $key = null, $value = null, $overwrite = false ) {
1343 - if ( is_array( $element ) ) {
1344 - foreach ( $element as $element_key => $attributes ) {
1345 - $this->add_attribute( $element_key, $attributes, null, $overwrite );
924 + if ( 'grouped' === $type ) {
925 + $tooltip_attr = ' title="' . esc_attr__( 'View Products', 'shopbuilder' ) . '"';
1346 926 }
1347 927
1348 - return $this;
1349 - }
1350 -
1351 - if ( is_array( $key ) ) {
1352 - foreach ( $key as $attribute_key => $attributes ) {
1353 - $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 ) . '"';
1354 931 }
1355 -
1356 - return $this;
1357 932 }
1358 933
1359 - if ( empty( $this->attributes[ $element ][ $key ] ) ) {
1360 - $this->attributes[ $element ][ $key ] = [];
1361 - }
934 + ob_start();
935 + do_action( 'rtsb/before/cart/button' );
936 + $content .= ob_get_clean();
1362 937
1363 - settype( $value, 'array' );
1364 -
1365 - if ( $overwrite ) {
1366 - $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 + );
1367 978 } else {
1368 - $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 + );
1369 992 }
1370 993
1371 - return $this;
994 + ob_start();
995 + do_action( 'rtsb/after/cart/button' );
996 + $content .= ob_get_clean();
997 +
998 + return $content;
1372 999 }
1373 1000
1374 1001 /**
1375 - * Get render attribute string.
1002 + * Button classes.
1376 1003 *
1377 - * @param string $element The element.
1004 + * @param array $params Button params.
1378 1005 *
1379 - * @return string
1006 + * @return array
1380 1007 */
1381 - public function get_attribute_string( $element ) {
1382 - if ( empty( $this->attributes[ $element ] ) ) {
1383 - return '';
1384 - }
1008 + public function button_classes( $params ) {
1009 + $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
1385 1010
1386 - return Utils::render_html_attributes( $this->attributes[ $element ] );
1011 + return $params;
1387 1012 }
1388 1013 }