PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.6.5
ShopBuilder – WooCommerce Builder For Elementor v2.6.5
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 +126 -22 2.1.112.6.5 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 /**
@@ -284,11 +302,11 @@
284 302
285 303 while ( $query->have_posts() ) {
286 304 $query->the_post();
287 305 $i++;
288 -
306 + global $product;
289 307 // Loop arg.
290 - $arg = $this->arg_dataset( $settings, wc_get_product( get_the_ID() ), $settings['lazy_load'], $i );
308 + $arg = $this->arg_dataset( $settings, $product, $settings['lazy_load'], $i );
291 309
292 310 // Get template.
293 311 $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
294 312 }
@@ -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
@@ -586,8 +610,11 @@
586 610
587 611 if ( rtsb()->has_pro() && ( ! empty( $metas['tag_term'] ) ) ) {
588 612 $term = $metas['tag_term'];
589 613 }
614 + if ( rtsb()->has_pro() && ( ! empty( $metas['brand_term'] ) ) ) {
615 + $term = $metas['brand_term'];
616 + }
590 617
591 618 // Query.
592 619 if ( $is_single ) {
593 620 if ( empty( $term ) ) {
@@ -788,9 +815,13 @@
788 815 $arg['image_link'] = $meta['image_link'];
789 816 $arg['grid'] .= 'rtsb-col-grid ';
790 817
791 818 if ( ! $fullwidth ) {
792 - $arg['class'] .= ' even-grid-item ';
819 + if ( 'masonry' === $meta['grid_type'] ) {
820 + $arg['class'] .= 'masonry-grid-item ';
821 + } else {
822 + $arg['class'] .= 'even-grid-item ';
823 + }
793 824 }
794 825
795 826 if ( ! empty( $meta['active_cat_slider'] ) ) {
796 827 $arg['class'] .= ' rtsb-slide-item swiper-slide animated rtFadeIn ';
@@ -864,8 +895,9 @@
864 895 $arg['anchor_class'] = null;
865 896 $arg['hover_img_html'] = null;
866 897 $arg['s_link'] = [];
867 898 $arg['add_to_cart'] = '';
899 + $arg['p_counter'] = absint( $i );
868 900 $arg['p_id'] = $post_id;
869 901 $arg['product'] = $product;
870 902 $arg['p_link'] = $product->get_permalink();
871 903 $arg['p_sale'] = '';
@@ -896,10 +928,15 @@
896 928 $is_list = preg_match( '/list/', $layout );
897 929 $is_carousel = preg_match( '/slider/', $layout );
898 930
899 931 if ( ! $is_carousel ) {
900 - $arg['grid'] .= 'rtsb-col-grid ';
901 - $arg['class'] .= ' even-grid-item ';
932 + $arg['grid'] .= 'rtsb-col-grid ';
933 +
934 + if ( 'masonry' === $meta['grid_type'] ) {
935 + $arg['class'] .= 'masonry-grid-item ';
936 + } else {
937 + $arg['class'] .= 'even-grid-item ';
938 + }
902 939 } else {
903 940 $arg['grid'] .= 'rtsb-col-grid rtsb-col-full rtsb-slide-item swiper-slide ';
904 941 }
905 942
@@ -930,8 +967,10 @@
930 967 }
931 968
932 969 $arg['badge_class'] = RenderHelpers::badge_class( $meta['badge_preset'] );
933 970
971 + $meta['add_to_cart_text'] = apply_filters( 'rtsb/elementor/render/add_to_cart_text', $meta['add_to_cart_text'], $product );
972 +
934 973 if ( ! $meta['show_cart_text'] ) {
935 974 $meta['add_to_cart_text'] = '';
936 975 $meta['add_to_cart_success_text'] = '';
937 976 }
@@ -957,8 +996,9 @@
957 996 'text' => $meta['add_to_cart_text'],
958 997 'success' => $meta['add_to_cart_success_text'],
959 998 'icon_html' => $cart_icon,
960 999 'alignment' => $meta['add_to_cart_alignment'],
1000 + 'product' => $product,
961 1001 ]
962 1002 );
963 1003 }
964 1004 }
@@ -1043,9 +1083,10 @@
1043 1083 'type' => $type,
1044 1084 'text' => $text,
1045 1085 'success' => $success,
1046 1086 'icon_html' => $icon_html,
1047 - 'alignment' => $alignment
1087 + 'alignment' => $alignment,
1088 + 'product' => $product
1048 1089 ) = $args;
1049 1090
1050 1091 $content = null;
1051 1092 $rand = wp_rand();
@@ -1066,12 +1107,13 @@
1066 1107 ];
1067 1108
1068 1109 if ( empty( $text ) ) {
1069 1110 $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' ),
1111 + 'simple' => esc_attr__( 'Add to Cart', 'shopbuilder' ),
1112 + 'variable' => esc_attr__( 'Select Options', 'shopbuilder' ),
1113 + 'grouped' => esc_attr__( 'View Products', 'shopbuilder' ),
1114 + 'external' => ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
1115 + 'rtsb-gift-card' => esc_attr__( 'Select Gift Card', 'shopbuilder' ),
1074 1116 ];
1075 1117
1076 1118 $cart_attr['title'] = $tooltip_mapping[ $type ];
1077 1119 }
@@ -1078,8 +1120,10 @@
1078 1120
1079 1121 $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
1080 1122
1081 1123 if ( 'variable' === $type || 'grouped' === $type ) {
1124 + $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1125 +
1082 1126 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1083 1127
1084 1128 $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
1085 1129
@@ -1102,8 +1146,9 @@
1102 1146 } else {
1103 1147 $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1104 1148 $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1105 1149 $cart_attr['data-type'] = $type;
1150 + $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1106 1151
1107 1152 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1108 1153
1109 1154 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
@@ -1371,8 +1416,46 @@
1371 1416 return $this;
1372 1417 }
1373 1418
1374 1419 /**
1420 + * Add link render attributes.
1421 + *
1422 + * @param array|string $element The HTML element.
1423 + * @param array $url_control Array of link settings.
1424 + * @param bool $overwrite Optional. Whether to overwrite existing
1425 + * attribute. Default is false, not to overwrite.
1426 + *
1427 + * @return Render
1428 + */
1429 + public function add_link_attributes( $element, array $url_control, $overwrite = false ) {
1430 + $attributes = [];
1431 +
1432 + if ( ! empty( $url_control['url'] ) ) {
1433 + $allowed_protocols = array_merge( wp_allowed_protocols(), [ 'skype', 'viber' ] );
1434 +
1435 + $attributes['href'] = esc_url( $url_control['url'], $allowed_protocols );
1436 + }
1437 +
1438 + if ( ! empty( $url_control['is_external'] ) ) {
1439 + $attributes['target'] = '_blank';
1440 + }
1441 +
1442 + if ( ! empty( $url_control['nofollow'] ) ) {
1443 + $attributes['rel'] = 'nofollow';
1444 + }
1445 +
1446 + if ( ! empty( $url_control['custom_attributes'] ) ) {
1447 + $attributes = array_merge( $attributes, Utils::parse_custom_attributes( $url_control['custom_attributes'] ) );
1448 + }
1449 +
1450 + if ( $attributes ) {
1451 + $this->add_attribute( $element, $attributes, null, $overwrite );
1452 + }
1453 +
1454 + return $this;
1455 + }
1456 +
1457 + /**
1375 1458 * Get render attribute string.
1376 1459 *
1377 1460 * @param string $element The element.
1378 1461 *
@@ -1383,6 +1466,27 @@
1383 1466 return '';
1384 1467 }
1385 1468
1386 1469 return Utils::render_html_attributes( $this->attributes[ $element ] );
1470 + }
1471 +
1472 + /**
1473 + * Function to render link attributes.
1474 + *
1475 + * @param string $id Element ID.
1476 + * @param array $control_name Control name.
1477 + * @param string $class_name Class name.
1478 + *
1479 + * @return string
1480 + */
1481 + public function render_link_attributes( $id, $control_name, $class_name = 'logo-img-link' ) {
1482 + $this->add_attribute( $id, 'class', $class_name );
1483 +
1484 + if ( ! empty( $control_name['url'] ) ) {
1485 + $this->add_link_attributes( $id, $control_name );
1486 + } else {
1487 + $this->add_attribute( $id, 'role', 'button' );
1488 + }
1489 +
1490 + return $this->get_attribute_string( $id );
1387 1491 }
1388 1492 }