PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.0.0
ShopBuilder – WooCommerce Builder For Elementor v2.0.0
3.4.2 3.4.1 3.4.0 2.0.1 2.0.2 2.0.3 2.1.0 2.1.1 2.1.10 2.1.11 2.1.12 2.1.13 2.1.14 2.1.15 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 All 63 releases
← All changes | app/Elementor/Render/Render.php +322 -738 2.1.9 → 2.0.0 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,100 @@
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 + $style_attr = ' style="--rtsb-default-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) ) . '"';
116 + $tooltip_attr = ' data-tooltip-position="' . esc_attr( $metas['tooltip_position'] ) . '"';
116 117
117 - if ( ! empty( $pagination_attributes ) ) {
118 - $container_attributes['data-rtsb-ajax'] = $pagination_attributes;
118 + $view_mode = $settings['view_mode'] ?? 'grid';
119 +
120 + if ( isset( $_GET['displayview'] ) ) {
121 + $view_mode = sanitize_text_field( wp_unslash( $_GET['displayview'] ) );
119 122 }
120 123
121 - // Adding render attributes.
122 - $this->add_attribute( 'rtsb_container_attr_' . $rand, $container_attributes );
124 + if ( 'list' == $view_mode && ! empty( $metas['tooltip_position_list'] ) ) {
125 + $tooltip_attr = ' data-tooltip-position="' . esc_attr( $metas['tooltip_position_list'] ) . '"';
126 + }
123 127
124 - // Start rendering.
125 - $this->html = '<div ' . $this->get_attribute_string( 'rtsb_container_attr_' . $rand ) . '>';
128 + $container_attr .= ' data-layout="' . esc_attr( $layout ) . '"' . $style_attr . $tooltip_attr . $pagination_attr;
129 + $container_class .= ' badge-' . esc_attr( $badge_class['position'] ) . ' badge-' . esc_attr( $badge_class['alignment'] ) . esc_attr( $cart_txt_class ) . ' img-hover-' . esc_attr( $animation ) . ' excerpt-' . esc_attr( $metas['cat_excerpt_position'] );
126 130
127 - // Section title.
128 - $this->html .= $this->render_section_title( $settings );
131 + if ( $metas['show_overlay'] ) {
132 + $container_class .= ' has-overlay';
133 + }
129 134
130 - // Content.
135 + if ( in_array( 'single-cat', $metas['visibility'], true ) ) {
136 + $container_class .= ' show-single-cat';
137 + }
138 +
139 + $container_class = apply_filters( 'rtsb/product/container/class', $container_class, $settings );
140 + $this->html = '<div class="' . esc_attr( $container_class ) . '" id="' . esc_attr( $layout_id ) . '" ' . $container_attr . '>';
141 +
142 + if ( ! empty( $settings['query_products'] ) && count( $settings['query_products'] ) && 'yes' === $settings['show_section_title'] ) {
143 + $this->html .= '<div class="rtsb-section-title-wrapper">';
144 + $this->html .= '<' . esc_attr( $settings['section_title_tag'] ) . ' class="rtsb-section-title" >';
145 + $this->html .= esc_html( $settings['section_title_text'] );
146 + $this->html .= '</' . esc_attr( $settings['section_title_tag'] ) . '>';
147 + $this->html .= '</div>';
148 + }
149 +
131 150 $this->html .= $content;
132 151
133 - // End rendering.
134 152 $this->html .= '</div><!-- .rtsb-elementor-container -->';
135 153
136 154 // Action button icon reset.
137 155 $this->action_button_icon_set_default();
138 156
139 - // Script generator.
140 157 $script_generator = [];
141 158 $script_generator['layout'] = $layout_id;
142 - $script_generator['rand'] = absint( $rand );
143 - $script_generator['isCarousel'] = preg_match( '/slider/', $layout );
159 + $script_generator['rand'] = absint( wp_rand() );
160 + $script_generator['isCarousel'] = $is_carousel;
144 161
145 - // Register scripts in the wp_footer action.
146 162 add_action(
147 163 'wp_footer',
148 164 static function () use ( $script_generator ) {
149 165 RenderHelpers::register_scripts( $script_generator );
@@ -158,46 +174,43 @@
158 174 *
159 175 * @param string $content The content.
160 176 * @param array $settings Settings.
161 177 * @param string $hook_html Hook HTML.
162 - * @param array $raw_settings Raw Settings.
163 178 *
164 179 * @return string
165 180 */
166 - public function row( $content, $settings, $hook_html = '', $raw_settings = [] ) {
181 + public function row( $content, $settings, $hook_html = '' ) {
182 + $masonry_class = null;
183 + $loader_class = ' rtsb-pre-loader';
184 +
167 185 $layout = $settings['layout'];
168 - $rand = wp_rand();
186 + $grid_type = $settings['grid_type'];
169 187 $is_carousel = preg_match( '/slider/', $layout );
170 188
171 - if ( preg_match( '/category/', $layout ) && ( ! empty( $settings['active_cat_slider'] ) ) ) {
172 - $is_carousel = true;
189 + if ( 'even' === $grid_type ) {
190 + $masonry_class = ' rtsb-even';
191 + } elseif ( 'masonry' === $grid_type ) {
192 + $masonry_class = ' rtsb-masonry';
173 193 }
174 194
175 - // Row classes.
176 - $row_classes = RenderHelpers::prepare_row_classes( $settings );
195 + if ( ! rtsb()->has_pro() || $is_carousel ) {
196 + $masonry_class = ' rtsb-even';
197 + }
177 198
178 - // Adding render attributes.
179 - $this->add_attribute( 'rtsb_row_attr_' . $rand, 'class', $row_classes );
199 + $row_start_class = apply_filters( 'rtsb/custom/layout/row/classes', esc_attr( 'rtsb-row rtsb-content-loader element-loading rtsb-' . $layout . $masonry_class . $loader_class ), $settings );
200 + $row_wrapper = '<div data-title="' . esc_html__( 'Loading ...', 'shopbuilder' ) . '" class="' . $row_start_class . '">';
201 + $start_wrapper = apply_filters( 'rtsb/custom/layout/row/start', $row_wrapper, $row_start_class );
202 + if ( ! empty( $settings['show_filter'] ) ) {
203 + $this->html = $hook_html;
204 + $this->html .= $start_wrapper;
205 + } else {
206 + $this->html = $start_wrapper;
207 + }
180 208
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 209 if ( $is_carousel ) {
188 - $slider_data = RenderHelpers::slider_data( $settings, $raw_settings );
210 + $slider_data = RenderHelpers::slider_data( $settings );
189 211
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 ) . '>';
212 + $this->html .= '<div class="rtsb-col-grid ' . esc_attr( $slider_data['class'] ) . '" ' . $slider_data['data'] . '>';
200 213 $this->html .= '<div class="swiper-wrapper">';
201 214 }
202 215
203 216 $this->html .= $content;
@@ -204,18 +217,32 @@
204 217
205 218 if ( $is_carousel ) {
206 219 $this->html .= '</div><!-- .swiper-wrapper -->';
207 220
208 - // Slider buttons.
209 - $this->html .= $this->render_slider_buttons( $settings );
221 + $left_icon = $settings['left_arrow_icon'];
222 + $right_icon = $settings['right_arrow_icon'];
223 +
224 + if ( ! empty( $settings['slider_nav'] ) ) {
225 + $this->html .=
226 + '<div class="swiper-nav">
227 + <div class="swiper-arrow swiper-button-next">
228 + ' . Fns::icons_manager( $right_icon ) . '
229 + </div>
230 + <div class="swiper-arrow swiper-button-prev">
231 + ' . Fns::icons_manager( $left_icon ) . '
232 + </div>
233 + </div>';
234 + }
235 +
236 + $this->html .= ! empty( $settings['slider_dot'] ) ? '<div class="swiper-pagination rtsb-pos-s"></div>' : '';
237 +
210 238 $this->html .= '</div><!-- .rtsb-carousel-slider -->';
211 239 }
212 240
213 241 $row_end = '</div><!-- .rtsb-row -->';
214 242
215 - $this->html .= apply_filters( 'rtsb/elementor/row/end', $row_end );
243 + $this->html .= apply_filters( 'rtsb/custom/layout/row/end', $row_end );
216 244
217 - // Preloader.
218 245 $this->html .= RenderHelpers::pre_loader( $layout );
219 246
220 247 return $this->html;
221 248 }
@@ -222,52 +249,8 @@
222 249
223 250 /**
224 251 * Product loop.
225 252 *
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 253 * @param object $query The query.
271 254 * @param array $settings Settings.
272 255 * @param string $template Template.
273 256 *
@@ -272,9 +255,9 @@
272 255 * @param string $template Template.
273 256 *
274 257 * @return string|null
275 258 */
276 - public function wc_product_loop( $query, $settings, $template ) {
259 + public function product_loop( $query, $settings, $template ) {
277 260 $html = null;
278 261
279 262 if ( empty( $query ) ) {
280 263 return null;
@@ -286,9 +269,9 @@
286 269 $query->the_post();
287 270 $i++;
288 271
289 272 // Loop arg.
290 - $arg = $this->arg_dataset( $settings, wc_get_product( get_the_ID() ), $settings['lazy_load'], $i );
273 + $arg = $this->arg_dataset( $settings, get_the_ID(), $settings['lazy_load'], $i );
291 274
292 275 // Get template.
293 276 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
294 277 }
@@ -296,9 +279,9 @@
296 279 return $html;
297 280 }
298 281
299 282 /**
300 - * Category loop.
283 + * Product loop.
301 284 *
302 285 * @param object $query The query.
303 286 * @param array $settings Settings.
304 287 * @param string $template Template.
@@ -306,18 +289,13 @@
306 289 *
307 290 * @return string|null
308 291 */
309 292 public function category_loop( $query, $settings, $template, $is_single = false ) {
310 - $html = null;
311 - $category_loop = false;
293 + $html = null;
312 294
313 - if ( 'category-layout3' === $settings['raw_settings']['layout'] || 'category-single-layout2' === $settings['raw_settings']['layout'] ) {
314 - $category_loop = true;
315 - }
316 -
317 295 if ( $is_single ) {
318 296 // Loop arg.
319 - $arg = $this->cat_arg_dataset( $settings, $query, true, false, $category_loop );
297 + $arg = $this->cat_arg_dataset( $settings, $query, true );
320 298
321 299 // Get template.
322 300 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
323 301 } else {
@@ -322,9 +300,9 @@
322 300 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
323 301 } else {
324 302 foreach ( $query as $term ) {
325 303 // Loop arg.
326 - $arg = $this->cat_arg_dataset( $settings, $term, false, false, $category_loop );
304 + $arg = $this->cat_arg_dataset( $settings, $term );
327 305
328 306 // Get template.
329 307 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
330 308 }
@@ -351,50 +329,42 @@
351 329
352 330 // Query Args.
353 331 $args = ( new QueryArgs() )->buildArgs( $metas, 'product', $is_carousel );
354 332
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 );
333 + $temp_args = $args;
334 + $args = apply_filters( 'rtsb/elementor/args_before_loop', $args, $metas );
362 335
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 336 // Query.
371 - $product_query = new WC_Product_Query( $args );
372 - $products = $pagination ? $product_query->get_products()->products : $product_query->get_products();
337 + $product_query = new WP_Query( $args );
373 338
374 - if ( ! empty( $products ) ) {
375 - // Start rendering.
376 - $hook_html .= $this->render_start( $metas, $settings, $temp_args );
339 + if ( $product_query->have_posts() ) {
340 + // Elementor Render hook before row.
341 + ob_start();
342 + do_action( 'rtsb/elementor/render/before_row', $metas, $settings, $product_query, $temp_args );
343 + $hook_html .= ob_get_clean();
377 344
378 345 // Row.
379 - $this->row( $this->product_loop( $products, $metas, $template ), $metas, $hook_html, $settings );
346 + $this->row( $this->product_loop( $product_query, $metas, $template ), $metas, $hook_html );
380 347
381 348 // Pagination.
382 349 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 - ];
350 + $this->html .= RenderHelpers::render_pagination(
351 + $product_query,
352 + $metas,
353 + $settings['posts_limit'],
354 + $settings['pagination_per_page']
355 + );
356 + }
389 357
390 - $this->html .= $this->render_products_pagination( $pagination_args );
391 - }
358 + // Elementor Render hook before row.
359 + ob_start();
360 + do_action( 'rtsb/elementor/render/after_row', $metas, $settings, $product_query );
361 + $this->html .= ob_get_clean();
392 362
393 - // End rendering.
394 - $this->html .= $this->render_end( $metas, $settings, $products );
395 363 } else {
396 - $this->no_products_msg( $metas );
364 + $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
365 +
366 + $this->row( $content, $metas );
397 367 }
398 368
399 369 wp_reset_postdata();
400 370
@@ -399,15 +369,8 @@
399 369 wp_reset_postdata();
400 370
401 371 unset( $args['tax_query'] );
402 372
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 373 // Container.
411 374 $this->container( $this->html, $settings, 'rtsb-products-container', $template, $is_carousel );
412 375
413 376 return $this->html;
@@ -412,8 +375,9 @@
412 375
413 376 return $this->html;
414 377 }
415 378
379 +
416 380 /**
417 381 * Render Product View.
418 382 *
419 383 * @param string $template Template name.
@@ -425,9 +389,8 @@
425 389 public function wc_loop_for_product_view( $template, $settings, $widget ) {
426 390 global $wp_query, $post;
427 391
428 392 $this->get_settings = $settings;
429 - $rand = wp_rand();
430 393 $metas = RenderHelpers::meta_dataset( $settings, $template, $widget->get_settings_for_display() );
431 394
432 395 $settings['rtsb_order'] = ! empty( $wp_query->query_vars['order'] ) ? $wp_query->query_vars['order'] : 'ASC';
433 396 $settings['rtsb_orderby'] = ! empty( $wp_query->query_vars['orderby'] ) ? $wp_query->query_vars['orderby'] : 'menu_order';
@@ -441,9 +404,9 @@
441 404 if ( $is_preview ) {
442 405 $main_query = clone $wp_query;
443 406 $main_post = clone $post;
444 407
445 - $ordering = ( new WC_Query() )->get_catalog_ordering_args();
408 + $ordering = ( new \WC_Query() )->get_catalog_ordering_args();
446 409 $wp_query_args = [
447 410 'post_type' => 'product',
448 411 'posts_per_page' => $posts_per_page,
449 412 ];
@@ -455,24 +418,22 @@
455 418 if ( ! empty( $ordering['order'] ) ) {
456 419 $wp_query_args['order'] = $ordering['order'];
457 420 }
458 421
459 - $wp_query = new WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
460 -
422 + $wp_query = new \WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
461 423 wc_set_loop_prop( 'total', $wp_query->found_posts );
462 424 wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
463 425 }
464 426
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 427 // column_per_row.
470 428 if ( woocommerce_product_loop() ) {
471 429 if ( wc_get_loop_prop( 'total' ) ) {
430 + if ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) {
431 + echo '<div class="rtsb-active-filters-wrapper"></div>';
432 + }
472 433
473 434 // Row.
474 - $this->row( $this->wc_product_loop( $wp_query, $metas, $template ), $metas, '', $settings );
435 + $this->row( $this->product_loop( $wp_query, $metas, $template ), $metas );
475 436 }
476 437
477 438 // Pagination.
478 439 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
@@ -477,51 +438,40 @@
477 438 // Pagination.
478 439 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
479 440
480 441 if ( $pagination ) {
481 - if ( Fns::product_filters_has_ajax( apply_filters( 'rtsb/builder/set/current/page/type', '' ) ) ) {
442 + if ( Fns::product_filters_has_ajax( 'shop' ) || Fns::product_filters_has_ajax( 'archive' ) ) {
482 443 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>";
444 + $this->html .= "
445 + <div class='rtsb-load-more rtsb-pos-r'>
446 + <button data-paged='2' data-max-page='{$wp_query->max_num_pages}'><span>" . esc_html__( 'Load More', 'shopbuilder-pro' ) . "</span></button>
447 + <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
448 + </div>
449 + ";
498 450 }
499 451 } 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' );
452 + $this->html .= RenderHelpers::render_pagination(
453 + $wp_query,
454 + $metas,
455 + wc_get_loop_prop( 'total' ),
456 + $posts_per_page
457 + );
508 458 }
509 459 }
510 460
511 461 $this->html .= '</div>';
512 462 } else {
513 - $this->no_products_msg( $metas );
463 + $content = '<div class="woocommerce-no-products-found"><div class="woocommerce-info">' . esc_html__( 'No products were found matching your selection.', 'shopbuilder-pro' ) . '</div></div>';
464 +
465 + $this->row( $content, $metas );
514 466 }
515 467
516 468 if ( $is_preview ) {
517 - // phpcs:disable
518 469 $wp_query = $main_query;
519 470 $post = $main_post;
520 471
521 472 wp_reset_query();
522 473 wp_reset_postdata();
523 - // phpcs:enable
524 474 }
525 475
526 476 // Container.
527 477 $this->container( $this->html, $settings, 'rtsb-products-container', $template );
@@ -529,13 +479,12 @@
529 479 return $this->html;
530 480 }
531 481
532 482 /**
533 - * Loop Setup for Product View.
483 + * Render Product View.
534 484 *
535 485 * @param string $template Template name.
536 486 * @param array $settings Control settings.
537 - * @param object $widget Widget object.
538 487 *
539 488 * @return string
540 489 */
541 490 public function setup_loop_for_product_view( $template, $settings, $widget ) {
@@ -552,17 +501,17 @@
552 501
553 502 setup_postdata( $GLOBALS['post'] =& $post_object ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited, Squiz.PHP.DisallowMultipleAssignments.Found
554 503
555 504 // Loop arg.
556 - $arg = $this->arg_dataset( $metas, $_product );
505 + $arg = $this->arg_dataset( $metas, $_product->get_id() );
557 506 // Get template.
558 507 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
559 508
560 - $this->row( $html, $metas, '', $settings );
509 + $this->row( $html, $metas );
561 510 }
562 511
563 512 // Container.
564 - $this->container( $this->html, $settings, 'rtsb-products-container', '', false, false );
513 + $this->container( $this->html, $settings, 'rtsb-products-container' );
565 514
566 515 wp_reset_postdata();
567 516
568 517 return $this->html;
@@ -601,9 +550,9 @@
601 550
602 551 $taxonomy_query = get_terms( $args );
603 552 }
604 553
605 - if ( ! is_wp_error( $taxonomy_query ) && ! empty( $taxonomy_query ) ) {
554 + if ( ! empty( $taxonomy_query ) ) {
606 555 // Row.
607 556 $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
608 557 } else {
609 558 $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
@@ -654,34 +603,8 @@
654 603
655 604 /**
656 605 * Builds an array with meta values.
657 606 *
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 607 * @param array $meta Meta values.
685 608 * @param int $post_id Post ID.
686 609 * @param bool $lazy_load Lazy Load.
687 610 * @param int $i Integer.
@@ -687,179 +610,19 @@
687 610 * @param int $i Integer.
688 611 *
689 612 * @return array
690 613 */
691 - public function wp_arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
614 + public function arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
692 615 if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
693 616 return [];
694 617 }
695 618
696 - global $product;
619 + global $post;
697 620
698 - if ( ! $product instanceof WC_Product && $post_id ) {
699 - $product = wc_get_product( $post_id );
700 - }
621 + $arg = [];
622 + $_product = wc_get_product( $post_id );
623 + $p_type = $_product->get_type();
701 624
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 625 $arg['class'] = null;
863 626 $arg['grid'] = null;
864 627 $arg['anchor_class'] = null;
865 628 $arg['hover_img_html'] = null;
@@ -865,26 +628,24 @@
865 628 $arg['hover_img_html'] = null;
866 629 $arg['s_link'] = [];
867 630 $arg['add_to_cart'] = '';
868 631 $arg['p_id'] = $post_id;
869 - $arg['product'] = $product;
870 - $arg['p_link'] = $product->get_permalink();
632 + $arg['p_link'] = get_permalink();
871 633 $arg['p_sale'] = '';
872 - $arg['rating_args'] = [];
873 - $arg['has_attributes'] = $product->is_type( 'variable' ) && $product->get_attributes();
634 + $arg['has_attributes'] = $_product->is_type( 'variable' ) && $_product->get_attributes();
874 635 $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
875 636 $cart_icon_html = '';
876 - $layout = $meta['layout'];
877 637
878 - // Building the arg.
638 + $layout = $meta['layout'];
639 +
879 640 $arg['target'] = '_self';
880 641 $arg['f_img'] = $meta['f_img'];
881 642 $arg['items'] = $meta['visibility'];
882 643 $arg['title_tag'] = $meta['title_tag'];
883 644 $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'] );
645 + $arg['title'] = Fns::text_truncation( get_the_title(), $meta['title_limit_custom'] );
885 646 $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'] ) );
647 + $arg['excerpt'] = wpautop( Fns::text_truncation( do_shortcode( $post->post_excerpt ), $meta['excerpt_limit_custom'] ) );
887 648 $arg['title_link'] = $meta['title_link'];
888 649 $arg['image_link'] = $meta['image_link'];
889 650 $arg['out_of_stock'] = $meta['out_of_stock_badge_text'];
890 651 $arg['action_btn_preset'] = $meta['btn_preset'];
@@ -919,14 +680,12 @@
919 680
920 681 $arg['class'] .= ' animated rtFadeIn';
921 682
922 683 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,
684 + $arg['p_sale'] = Fns::get_sale_badge(
926 685 $meta['sale_badge_type'],
927 686 $meta['sale_badge_text'],
928 - apply_filters( 'rtsb/elementor/render/out_of_stock_badge_text', $meta['out_of_stock_badge_text'] )
687 + $meta['out_of_stock_badge_text']
929 688 );
930 689 }
931 690
932 691 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
@@ -944,22 +703,20 @@
944 703 if ( ! empty( $meta['add_to_cart_success_icon'] ) ) {
945 704 $cart_icon_html .= Fns::icons_manager( $meta['add_to_cart_success_icon'], 'cart-success-icon' );
946 705 }
947 706
948 - $cart_icon = ! empty( $cart_icon_html ) ? '<span class="icon">' . $cart_icon_html . '</span>' : '';
707 + $cart_icon = '<span class="icon">' . $cart_icon_html . '</span>';
949 708
950 - if ( $product->is_purchasable() || 'grouped' === $p_type || 'external' === $p_type ) {
951 - if ( $product->is_in_stock() ) {
709 + if ( $_product->is_purchasable() ) {
710 + if ( $_product->is_in_stock() ) {
952 711 $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 - ]
712 + get_permalink(),
713 + $post_id,
714 + $p_type,
715 + $meta['add_to_cart_text'],
716 + $meta['add_to_cart_success_text'],
717 + $cart_icon,
718 + $meta['add_to_cart_alignment']
962 719 );
963 720 }
964 721 }
965 722 }
@@ -987,10 +744,10 @@
987 744 $meta['custom_img_size'],
988 745 $lazy_load
989 746 ) : null;
990 747
991 - if ( ! ( function_exists( 'rtwpvsp' ) && $product->is_type( 'variable' ) && $product->get_attributes() ) ) {
992 - $gallery_ids = $product->get_gallery_image_ids();
748 + if ( ! ( function_exists( 'rtwpvsp' ) && $_product->is_type( 'variable' ) && $_product->get_attributes() ) ) {
749 + $gallery_ids = $_product->get_gallery_image_ids();
993 750
994 751 if ( $meta['hover_img'] && ! empty( $gallery_ids ) ) {
995 752 $arg['class'] .= ! $meta['gallery_img'] ? ' rtsb-double-img' : '';
996 753
@@ -1025,364 +782,191 @@
1025 782 'hover_img_html' => $arg['hover_img_html'],
1026 783 'meta' => $meta,
1027 784 ];
1028 785
1029 - return $arg;
786 + return apply_filters( 'rtsb/elementor/render/arg_dataset', $arg, $post_id, $meta, $lazy_load );
1030 787 }
1031 788
1032 789 /**
1033 - * Renders add to cart button.
790 + * Builds an array with meta values.
1034 791 *
1035 - * @param array $args Cart args.
792 + * @param array $meta Meta values.
793 + * @param Object $query Category object.
794 + * @param bool $fullwidth Fullwidth check.
795 + * @param bool $lazy_load Lazy Load.
1036 796 *
1037 - * @return string
797 + * @return array
1038 798 */
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;
799 + public function cat_arg_dataset( $meta, $query = null, $fullwidth = false, $lazy_load = false ) {
800 + if ( empty( $meta ) ) {
801 + return [];
802 + }
1049 803
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 );
804 + $arg = [];
1054 805
1055 - ob_start();
1056 - do_action( 'rtsb/before/cart/button' );
1057 - $content .= ob_get_clean();
806 + $arg['class'] = null;
807 + $arg['grid'] = null;
808 + $arg['anchor_class'] = null;
809 + $arg['p_sale'] = null;
810 + $arg['count'] = max( $query->count, 0 );
811 + $arg['count_position'] = $meta['count_position'];
812 + $arg['excerpt_position'] = $meta['cat_excerpt_position'];
813 + $arg['cat_link'] = get_term_link( $query );
814 + $arg['target'] = '_self';
815 + $arg['raw_settings'] = ! empty( $meta['raw_settings'] ) ? $meta['raw_settings'] : [];
1058 816
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 - ];
817 + if ( ! empty( $meta['tag_term'] ) ) {
818 + $arg['tag_term'] = $meta['tag_term'];
819 + }
1067 820
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 ];
821 + if ( ! empty( $meta['custom_link']['url'] ) ) {
822 + $arg['cat_link'] = $meta['custom_link']['url'];
823 + $arg['target'] = $meta['custom_link']['is_external'] ? '_blank' : '_self';
1077 824 }
1078 825
1079 - $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
826 + $title = $query->name;
827 + $excerpt = $query->description;
1080 828
1081 - if ( 'variable' === $type || 'grouped' === $type ) {
1082 - $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
829 + if ( in_array( 'badges', $meta['visibility'], true ) ) {
830 + $arg['p_sale'] = $meta['custom_badge_text'];
831 + }
1083 832
1084 - $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
833 + $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
1085 834
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 - }
835 + if ( $arg['count'] >= 0 ) {
836 + $prefix = ! empty( $meta['before_count'] ) ? $meta['before_count'] : '';
837 + $suffix = ! empty( $meta['after_count'] ) ? $meta['after_count'] : '';
1094 838
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>';
839 + $arg['count'] = $prefix . $arg['count'] . $suffix;
1113 840 }
1114 841
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;
842 + if ( $meta['show_custom_title'] && ! empty( $meta['cat_custom_title'] ) ) {
843 + $title = $meta['cat_custom_title'];
1151 844 }
1152 845
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 - }
846 + if ( $meta['show_custom_excerpt'] && ! empty( $meta['cat_custom_excerpt'] ) ) {
847 + $excerpt = $meta['cat_custom_excerpt'];
1201 848 }
1202 849
1203 - $total_page = absint( $total_page );
850 + $layout = $meta['layout'];
1204 851
1205 - $args = [
1206 - 'total_page' => $total_page,
1207 - 'posts_per_page' => 'wc' === $query_type ? $per_page : $posts_per_page,
1208 - 'ajax' => $ajax,
1209 - ];
852 + $arg['c_img'] = $meta['c_img'];
853 + $arg['items'] = $meta['visibility'];
854 + $arg['title_tag'] = $meta['title_tag'];
855 + $arg['title_class'] = 'category-title rtsb-text-limit limit-' . $meta['title_limit'] . ( ! $meta['title_link'] ? ' no-link' : '' );
856 + $arg['title'] = Fns::text_truncation( $title, $meta['title_limit_custom'] );
857 + $arg['excerpt_limit'] = $meta['excerpt_limit'];
858 + $arg['excerpt'] = wpautop( Fns::text_truncation( $excerpt, $meta['excerpt_limit_custom'] ) );
859 + $arg['title_link'] = $meta['title_link'];
860 + $arg['image_link'] = $meta['image_link'];
1210 861
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 - }
862 + if ( ! $fullwidth ) {
863 + $arg['grid'] .= 'rtsb-col-grid ';
864 + $arg['class'] .= ' even-grid-item ';
1218 865 } else {
1219 - ob_start();
1220 - do_action( 'rtsb/elementor/render/pagination', $meta, $query, $args );
1221 - $html_utility .= ob_get_clean();
866 + $arg['grid'] .= 'rtsb-col-grid ';
1222 867 }
1223 868
1224 - if ( $html_utility ) {
1225 - $rand = wp_rand();
869 + $arg['class'] .= 'rtsb-category-grid';
1226 870
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 - ]
871 + $arg['img_html'] = $meta['c_img'] ? Fns::get_product_image_html(
872 + 'category',
873 + $query->term_id,
874 + $meta['f_img_size'],
875 + $meta['default_img_id'],
876 + $meta['custom_img_size'],
877 + $lazy_load
878 + ) : null;
879 +
880 + if ( $meta['show_custom_image'] && ! empty( $meta['custom_image'] ) ) {
881 + $arg['img_html'] = Fns::get_product_image_html(
882 + 'custom',
883 + null,
884 + $meta['f_img_size'],
885 + $meta['custom_image'],
886 + $meta['custom_img_size'],
887 + $lazy_load
1236 888 );
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 889 }
1243 890
1244 - return $html;
1245 - }
891 + $arg['excerpt_class'] = 'category-info' . ( 'block' === $meta['count_position'] ? ' block-count' : ' inline-count' ) . ( 'above' === $meta['cat_excerpt_position'] ? ' excerpt-above' : '' ) . ( empty( $arg['excerpt'] ) ? ' no-excerpt' : '' );
1246 892
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;
893 + return $arg;
1274 894 }
1275 895
1276 896 /**
1277 - * No products message.
897 + * Renders add to cart button.
1278 898 *
1279 - * @param array $metas Meta data.
899 + * @param string $link Product link.
900 + * @param int $id Product ID.
901 + * @param string $type Product type.
902 + * @param string $text Custom text.
903 + * @param string $success Success text.
904 + * @param string $icon_html Custom icon.
905 + * @param string $alignment Icon alignment.
1280 906 *
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 907 * @return string
1300 908 */
1301 - public function render_start( $metas, $settings, $temp_args ) {
1302 - ob_start();
909 + public function render_add_to_cart_button( $link, $id, $type, $text, $success, $icon_html, $alignment ) {
910 + $content = null;
911 + $tooltip_attr = '';
1303 912
1304 - /**
1305 - * Before render row hook.
1306 - */
1307 - do_action( 'rtsb/elementor/render/before_row', $metas, $settings, $temp_args, $this );
913 + if ( empty( $text ) ) {
914 + $tooltip_attr = ' title="' . esc_attr__( 'Add to Cart', 'shopbuilder' ) . '"';
1308 915
1309 - return ob_get_clean();
1310 - }
1311 -
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 );
916 + if ( 'variable' === $type ) {
917 + $tooltip_attr = ' title="' . esc_attr__( 'Select Options', 'shopbuilder' ) . '"';
1346 918 }
1347 -
1348 - return $this;
1349 919 }
920 + ob_start();
921 + do_action( 'rtsb/before/cart/button' );
922 + $content .= ob_get_clean();
1350 923
1351 - if ( is_array( $key ) ) {
1352 - foreach ( $key as $attribute_key => $attributes ) {
1353 - $this->add_attribute( $element, $attribute_key, $attributes, $overwrite );
1354 - }
1355 -
1356 - return $this;
924 + if ( 'variable' === $type ) {
925 + $content .= sprintf(
926 + '<div class="rtsb-wc-add-to-cart-wrap">
927 + <a href="%1$s" data-quantity="1" class="rtsb-action-btn variable-product tipsy icon-%4$s %5$s" data-product_id="%3$s" rel="nofollow"%6$s>%7$s<span class="text">%2$s</span></a>
928 + </div>',
929 + esc_url( $link ),
930 + esc_html__( 'Select Options', 'shopbuilder' ),
931 + absint( $id ),
932 + esc_attr( $alignment ),
933 + empty( $text ) ? 'no-text' : 'has-text',
934 + $tooltip_attr,
935 + $icon_html,
936 + );
937 + } else {
938 + $content .= sprintf(
939 + '<a href="%1$s?add-to-cart=%2$d" data-quantity="1" class="rtsb-action-btn rtsb-add-to-cart-btn tipsy icon-%6$s %7$s" data-id="%2$d" data-type="%3$s"%8$s>%4$s<span class="text %10$s" data-success="%9$s">%5$s</span><span></span></a>',
940 + esc_url( $link ),
941 + absint( $id ),
942 + esc_attr( $type ),
943 + $icon_html,
944 + esc_html( $text ),
945 + esc_attr( $alignment ),
946 + empty( $text ) ? 'no-text' : 'has-text',
947 + $tooltip_attr,
948 + esc_html( $success ),
949 + ! empty( $success ) ? 'has-success-text' : 'no-success-text',
950 + );
1357 951 }
1358 952
1359 - if ( empty( $this->attributes[ $element ][ $key ] ) ) {
1360 - $this->attributes[ $element ][ $key ] = [];
1361 - }
953 + ob_start();
954 + do_action( 'rtsb/after/cart/button' );
955 + $content .= ob_get_clean();
1362 956
1363 - settype( $value, 'array' );
1364 -
1365 - if ( $overwrite ) {
1366 - $this->attributes[ $element ][ $key ] = $value;
1367 - } else {
1368 - $this->attributes[ $element ][ $key ] = array_merge( $this->attributes[ $element ][ $key ], $value );
1369 - }
1370 -
1371 - return $this;
957 + return $content;
1372 958 }
1373 959
1374 960 /**
1375 - * Get render attribute string.
961 + * Button classes.
1376 962 *
1377 - * @param string $element The element.
963 + * @param array $params Button params.
1378 964 *
1379 - * @return string
965 + * @return array
1380 966 */
1381 - public function get_attribute_string( $element ) {
1382 - if ( empty( $this->attributes[ $element ] ) ) {
1383 - return '';
1384 - }
967 + public function button_classes( $params ) {
968 + $params['classes'] = array_merge( $params['classes'], [ 'rtsb-action-btn', 'tipsy' ] );
1385 969
1386 - return Utils::render_html_attributes( $this->attributes[ $element ] );
970 + return $params;
1387 971 }
1388 972 }