PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.6.2
ShopBuilder – WooCommerce Builder For Elementor v2.6.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 +119 -19 2.1.7 → 2.6.2 View file →
@@ -85,9 +85,10 @@
85 85 public function container( $content, $settings, $class = '', $template = '', $fullwidth = false, $ajax = true ) {
86 86 $rand = wp_rand();
87 87 $layout_id = 'rtsb-container-' . $rand;
88 88 $metas = RenderHelpers::meta_dataset( $settings, $template );
89 - $layout = $metas['layout'];
89 + $raw_layout = esc_html( $metas['layout'] );
90 + $layout = RenderHelpers::filter_layout( $raw_layout, $template );
90 91 $style_attr = '--rtsb-default-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) );
91 92 $view_mode = $settings['view_mode'] ?? 'grid';
92 93 $view_mode = isset( $_GET['displayview'] ) ? sanitize_text_field( wp_unslash( $_GET['displayview'] ) ) : $view_mode; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
93 94 $tooltip_attr = 'list' == $view_mode && ! empty( $metas['tooltip_position_list'] ) ? esc_attr( $metas['tooltip_position_list'] ) : $metas['tooltip_position'];
@@ -92,8 +93,9 @@
92 93 $view_mode = isset( $_GET['displayview'] ) ? sanitize_text_field( wp_unslash( $_GET['displayview'] ) ) : $view_mode; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
93 94 $tooltip_attr = 'list' == $view_mode && ! empty( $metas['tooltip_position_list'] ) ? esc_attr( $metas['tooltip_position_list'] ) : $metas['tooltip_position'];
94 95 $has_pro = rtsb()->has_pro();
95 96 $has_filters = $has_pro && ! empty( $settings['tax_filter'] );
97 + $grid_style = $settings['grid_style'] ?? 'even';
96 98
97 99 // Set default layout.
98 100 if ( ! $has_pro && ! in_array( $layout, array_keys( Fns::free_layouts() ), true ) ) {
99 101 $layout = RenderHelpers::set_default_layout( $layout );
@@ -98,8 +100,13 @@
98 100 if ( ! $has_pro && ! in_array( $layout, array_keys( Fns::free_layouts() ), true ) ) {
99 101 $layout = RenderHelpers::set_default_layout( $layout );
100 102 }
101 103
104 + if ( $has_pro && 'masonry' === $grid_style ) {
105 + $style_attr .= '; --rtsb-masonry-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) );
106 + $style_attr .= '; --rtsb-masonry-list-columns: ' . esc_attr( RenderHelpers::default_columns( $layout ) );
107 + }
108 +
102 109 // Container classes.
103 110 $container_classes = RenderHelpers::prepare_container_classes( $metas, $settings, $class );
104 111
105 112 // Pagination attributes.
@@ -108,9 +115,9 @@
108 115 // Attributes for the container.
109 116 $container_attributes = [
110 117 'id' => $layout_id,
111 118 'class' => $container_classes,
112 - 'style' => $style_attr,
119 + 'style' => apply_filters( 'rtsb/product/container/attr', $style_attr, $settings ),
113 120 'data-layout' => $layout,
114 121 'data-tooltip-position' => $tooltip_attr,
115 122 ];
116 123
@@ -140,8 +147,9 @@
140 147 $script_generator = [];
141 148 $script_generator['layout'] = $layout_id;
142 149 $script_generator['rand'] = absint( $rand );
143 150 $script_generator['isCarousel'] = preg_match( '/slider/', $layout );
151 + $script_generator['isMasonry'] = $has_pro && 'masonry' === $grid_style;
144 152
145 153 // Register scripts in the wp_footer action.
146 154 add_action(
147 155 'wp_footer',
@@ -163,13 +171,15 @@
163 171 *
164 172 * @return string
165 173 */
166 174 public function row( $content, $settings, $hook_html = '', $raw_settings = [] ) {
167 - $layout = $settings['layout'];
175 + $raw_layout = esc_html( $settings['layout'] );
176 + $layout = RenderHelpers::filter_layout( $raw_layout );
177 +
168 178 $rand = wp_rand();
169 - $is_carousel = preg_match( '/slider/', $layout );
179 + $is_carousel = preg_match( '/slider/', $raw_layout );
170 180
171 - if ( preg_match( '/category/', $layout ) && ( ! empty( $settings['active_cat_slider'] ) ) ) {
181 + if ( preg_match( '/category/', $raw_layout ) && ( ! empty( $settings['active_cat_slider'] ) ) ) {
172 182 $is_carousel = true;
173 183 }
174 184
175 185 // Row classes.
@@ -185,9 +195,8 @@
185 195 $this->html = ! empty( $settings['show_filter'] ) ? $hook_html . $start_wrapper : $start_wrapper;
186 196
187 197 if ( $is_carousel ) {
188 198 $slider_data = RenderHelpers::slider_data( $settings, $raw_settings );
189 -
190 199 // Adding slider render attributes.
191 200 $this->add_attribute(
192 201 'rtsb_slider_attr_' . $rand,
193 202 [
@@ -237,11 +246,18 @@
237 246 }
238 247
239 248 $i = 0;
240 249
241 - foreach ( $products as $product ) {
250 + global $product;
251 + $isGlobalProduct = false;
252 + if ( $product instanceof WC_Product ) {
253 + $isGlobalProduct = $product;
254 + }
255 +
256 + foreach ( $products as $_product ) {
242 257 $i++;
243 - $GLOBALS['product'] = $product;
258 + $GLOBALS['product'] = $_product;
259 + $layout = RenderHelpers::filter_layout( esc_html( $settings['layout'] ), $template );
244 260
245 261 /**
246 262 * Before product template render hook.
247 263 */
@@ -247,12 +263,12 @@
247 263 */
248 264 do_action( 'rtsb_before_product_template_render' );
249 265
250 266 // Loop arg.
251 - $arg = $this->arg_dataset( $settings, $product, $settings['lazy_load'], $i );
267 + $arg = $this->arg_dataset( $settings, $_product, $settings['lazy_load'], $i );
252 268
253 269 // Get template.
254 - $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
270 + $html .= Fns::load_template( $template . $layout, $arg, true );
255 271
256 272 /**
257 273 * After product template render hook.
258 274 */
@@ -259,9 +275,11 @@
259 275 do_action( 'rtsb_after_product_template_render' );
260 276
261 277 unset( $GLOBALS['product'] );
262 278 }
263 -
279 + if ( $isGlobalProduct ) {
280 + $GLOBALS['product'] = $isGlobalProduct;
281 + }
264 282 return $html;
265 283 }
266 284
267 285 /**
@@ -368,10 +386,16 @@
368 386 do_action( 'rtsb/elements/render/before_query', $settings, $args );
369 387
370 388 // Query.
371 389 $product_query = new WC_Product_Query( $args );
372 - $products = $pagination ? $product_query->get_products()->products : $product_query->get_products();
373 390
391 + /**
392 + * Product query hook.
393 + */
394 + do_action( 'rtsb/elements/render/product_query', $product_query, $this );
395 +
396 + $products = $pagination ? $product_query->get_products()->products : $product_query->get_products();
397 +
374 398 if ( ! empty( $products ) ) {
375 399 // Start rendering.
376 400 $hook_html .= $this->render_start( $metas, $settings, $temp_args );
377 401
@@ -477,9 +501,9 @@
477 501 // Pagination.
478 502 $this->html .= '<div class="rtsb-archive-pagination-wrap">';
479 503
480 504 if ( $pagination ) {
481 - if ( Fns::product_filters_has_ajax( 'shop' ) || Fns::product_filters_has_ajax( 'archive' ) ) {
505 + if ( Fns::product_filters_has_ajax( apply_filters( 'rtsb/builder/set/current/page/type', '' ) ) ) {
482 506 if ( $wp_query->max_num_pages > 1 ) {
483 507 $this->add_attribute(
484 508 'rtsb_load_more_btn_attr_' . $rand,
485 509 [
@@ -489,9 +513,9 @@
489 513 );
490 514
491 515 $this->html .=
492 516 "<div class='rtsb-load-more rtsb-pos-r'>
493 - <button '{$this->get_attribute_string( 'rtsb_load_more_btn_attr_' . $rand )}'>
517 + <button {$this->get_attribute_string( 'rtsb_load_more_btn_attr_' . $rand )}>
494 518 <span>" . esc_html__( 'Load More', 'shopbuilder' ) . "</span>
495 519 </button>
496 520 <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
497 521 </div>";
@@ -788,9 +812,13 @@
788 812 $arg['image_link'] = $meta['image_link'];
789 813 $arg['grid'] .= 'rtsb-col-grid ';
790 814
791 815 if ( ! $fullwidth ) {
792 - $arg['class'] .= ' even-grid-item ';
816 + if ( 'masonry' === $meta['grid_type'] ) {
817 + $arg['class'] .= 'masonry-grid-item ';
818 + } else {
819 + $arg['class'] .= 'even-grid-item ';
820 + }
793 821 }
794 822
795 823 if ( ! empty( $meta['active_cat_slider'] ) ) {
796 824 $arg['class'] .= ' rtsb-slide-item swiper-slide animated rtFadeIn ';
@@ -864,8 +892,9 @@
864 892 $arg['anchor_class'] = null;
865 893 $arg['hover_img_html'] = null;
866 894 $arg['s_link'] = [];
867 895 $arg['add_to_cart'] = '';
896 + $arg['p_counter'] = absint( $i );
868 897 $arg['p_id'] = $post_id;
869 898 $arg['product'] = $product;
870 899 $arg['p_link'] = $product->get_permalink();
871 900 $arg['p_sale'] = '';
@@ -896,10 +925,15 @@
896 925 $is_list = preg_match( '/list/', $layout );
897 926 $is_carousel = preg_match( '/slider/', $layout );
898 927
899 928 if ( ! $is_carousel ) {
900 - $arg['grid'] .= 'rtsb-col-grid ';
901 - $arg['class'] .= ' even-grid-item ';
929 + $arg['grid'] .= 'rtsb-col-grid ';
930 +
931 + if ( 'masonry' === $meta['grid_type'] ) {
932 + $arg['class'] .= 'masonry-grid-item ';
933 + } else {
934 + $arg['class'] .= 'even-grid-item ';
935 + }
902 936 } else {
903 937 $arg['grid'] .= 'rtsb-col-grid rtsb-col-full rtsb-slide-item swiper-slide ';
904 938 }
905 939
@@ -924,14 +958,16 @@
924 958 $arg['p_sale'] = Fns::is_module_active( 'product_badges' ) && $badge_module ? 'rtsb_yes' : Fns::get_promo_badge(
925 959 $product,
926 960 $meta['sale_badge_type'],
927 961 $meta['sale_badge_text'],
928 - $meta['out_of_stock_badge_text']
962 + apply_filters( 'rtsb/elementor/render/out_of_stock_badge_text', $meta['out_of_stock_badge_text'] )
929 963 );
930 964 }
931 965
932 966 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
933 967
968 + $meta['add_to_cart_text'] = apply_filters( 'rtsb/elementor/render/add_to_cart_text', $meta['add_to_cart_text'], $product );
969 +
934 970 if ( ! $meta['show_cart_text'] ) {
935 971 $meta['add_to_cart_text'] = '';
936 972 $meta['add_to_cart_success_text'] = '';
937 973 }
@@ -957,8 +993,9 @@
957 993 'text' => $meta['add_to_cart_text'],
958 994 'success' => $meta['add_to_cart_success_text'],
959 995 'icon_html' => $cart_icon,
960 996 'alignment' => $meta['add_to_cart_alignment'],
997 + 'product' => $product,
961 998 ]
962 999 );
963 1000 }
964 1001 }
@@ -1043,9 +1080,10 @@
1043 1080 'type' => $type,
1044 1081 'text' => $text,
1045 1082 'success' => $success,
1046 1083 'icon_html' => $icon_html,
1047 - 'alignment' => $alignment
1084 + 'alignment' => $alignment,
1085 + 'product' => $product
1048 1086 ) = $args;
1049 1087
1050 1088 $content = null;
1051 1089 $rand = wp_rand();
@@ -1078,8 +1116,10 @@
1078 1116
1079 1117 $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
1080 1118
1081 1119 if ( 'variable' === $type || 'grouped' === $type ) {
1120 + $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1121 +
1082 1122 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1083 1123
1084 1124 $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
1085 1125
@@ -1102,8 +1142,9 @@
1102 1142 } else {
1103 1143 $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1104 1144 $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1105 1145 $cart_attr['data-type'] = $type;
1146 + $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1106 1147
1107 1148 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1108 1149
1109 1150 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
@@ -1371,8 +1412,46 @@
1371 1412 return $this;
1372 1413 }
1373 1414
1374 1415 /**
1416 + * Add link render attributes.
1417 + *
1418 + * @param array|string $element The HTML element.
1419 + * @param array $url_control Array of link settings.
1420 + * @param bool $overwrite Optional. Whether to overwrite existing
1421 + * attribute. Default is false, not to overwrite.
1422 + *
1423 + * @return Render
1424 + */
1425 + public function add_link_attributes( $element, array $url_control, $overwrite = false ) {
1426 + $attributes = [];
1427 +
1428 + if ( ! empty( $url_control['url'] ) ) {
1429 + $allowed_protocols = array_merge( wp_allowed_protocols(), [ 'skype', 'viber' ] );
1430 +
1431 + $attributes['href'] = esc_url( $url_control['url'], $allowed_protocols );
1432 + }
1433 +
1434 + if ( ! empty( $url_control['is_external'] ) ) {
1435 + $attributes['target'] = '_blank';
1436 + }
1437 +
1438 + if ( ! empty( $url_control['nofollow'] ) ) {
1439 + $attributes['rel'] = 'nofollow';
1440 + }
1441 +
1442 + if ( ! empty( $url_control['custom_attributes'] ) ) {
1443 + $attributes = array_merge( $attributes, Utils::parse_custom_attributes( $url_control['custom_attributes'] ) );
1444 + }
1445 +
1446 + if ( $attributes ) {
1447 + $this->add_attribute( $element, $attributes, null, $overwrite );
1448 + }
1449 +
1450 + return $this;
1451 + }
1452 +
1453 + /**
1375 1454 * Get render attribute string.
1376 1455 *
1377 1456 * @param string $element The element.
1378 1457 *
@@ -1383,6 +1462,27 @@
1383 1462 return '';
1384 1463 }
1385 1464
1386 1465 return Utils::render_html_attributes( $this->attributes[ $element ] );
1466 + }
1467 +
1468 + /**
1469 + * Function to render link attributes.
1470 + *
1471 + * @param string $id Element ID.
1472 + * @param array $control_name Control name.
1473 + * @param string $class_name Class name.
1474 + *
1475 + * @return string
1476 + */
1477 + public function render_link_attributes( $id, $control_name, $class_name = 'logo-img-link' ) {
1478 + $this->add_attribute( $id, 'class', $class_name );
1479 +
1480 + if ( ! empty( $control_name['url'] ) ) {
1481 + $this->add_link_attributes( $id, $control_name );
1482 + } else {
1483 + $this->add_attribute( $id, 'role', 'button' );
1484 + }
1485 +
1486 + return $this->get_attribute_string( $id );
1387 1487 }
1388 1488 }