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