PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.6.0
ShopBuilder – WooCommerce Builder For Elementor v2.6.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 +49 -163 3.4.02.6.0 View file →
@@ -8,9 +8,8 @@
8 8 */
9 9
10 10 namespace RadiusTheme\SB\Elementor\Render;
11 11
12 -use RadiusTheme\SBPRO\Modules\CatalogMode\CatalogModeFns;
13 12 use WC_Query;
14 13 use WP_Query;
15 14 use WC_Product;
16 15 use Elementor\Utils;
@@ -125,14 +124,8 @@
125 124 if ( ! empty( $pagination_attributes ) ) {
126 125 $container_attributes['data-rtsb-ajax'] = $pagination_attributes;
127 126 }
128 127
129 - // Opt-out of the scroll-to-top behaviour on Ajax filter/pagination when
130 - // the "Enable Scroll To Top?" switch is turned off.
131 - if ( isset( $settings['enable_ajax_scroll'] ) && empty( $settings['enable_ajax_scroll'] ) ) {
132 - $container_attributes['data-rtsb-disable-scroll'] = '1';
133 - }
134 -
135 128 // Adding render attributes.
136 129 $this->add_attribute( 'rtsb_container_attr_' . $rand, $container_attributes );
137 130
138 131 // Start rendering.
@@ -254,20 +247,18 @@
254 247
255 248 $i = 0;
256 249
257 250 global $product;
258 -
259 251 $isGlobalProduct = false;
260 -
261 252 if ( $product instanceof WC_Product ) {
262 253 $isGlobalProduct = $product;
263 254 }
264 255
265 - $layout = RenderHelpers::filter_layout( esc_html( $settings['layout'] ), $template );
266 -
267 256 foreach ( $products as $_product ) {
268 257 $i++;
269 - $GLOBALS['product'] = $_product; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Global variable is intentionally used to share the current product context with hooks and templates during rendering.
258 + $GLOBALS['product'] = $_product;
259 + $layout = RenderHelpers::filter_layout( esc_html( $settings['layout'] ), $template );
260 +
270 261 /**
271 262 * Before product template render hook.
272 263 */
273 264 do_action( 'rtsb_before_product_template_render' );
@@ -285,9 +276,9 @@
285 276
286 277 unset( $GLOBALS['product'] );
287 278 }
288 279 if ( $isGlobalProduct ) {
289 - $GLOBALS['product'] = $isGlobalProduct; // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Global variable is intentionally used to share the current product context with hooks and templates during rendering.
280 + $GLOBALS['product'] = $isGlobalProduct;
290 281 }
291 282 return $html;
292 283 }
293 284
@@ -306,20 +297,19 @@
306 297 if ( empty( $query ) ) {
307 298 return null;
308 299 }
309 300
310 - $i = 0;
311 - $layout = RenderHelpers::filter_layout( esc_html( $settings['layout'] ), $template );
301 + $i = 0;
312 302
313 303 while ( $query->have_posts() ) {
314 304 $query->the_post();
315 305 $i++;
316 - global $product;
306 +
317 307 // Loop arg.
318 - $arg = $this->arg_dataset( $settings, $product, $settings['lazy_load'], $i );
308 + $arg = $this->arg_dataset( $settings, wc_get_product( get_the_ID() ), $settings['lazy_load'], $i );
319 309
320 310 // Get template.
321 - $html .= Fns::load_template( $template . $layout, $arg, true );
311 + $html .= Fns::load_template( $template . $settings['layout'], $arg, true );
322 312 }
323 313
324 314 return $html;
325 315 }
@@ -392,10 +382,10 @@
392 382 * Before Product query hook.
393 383 *
394 384 * @hooked RadiusTheme\SB\Controllers\Hooks\ActionHooks::modify_wc_query_args 10
395 385 */
386 + do_action( 'rtsb/elements/render/before_query', $settings, $args );
396 387
397 - do_action( 'rtsb/elements/render/before_query', $settings, $args );
398 388 // Query.
399 389 $product_query = new WC_Product_Query( $args );
400 390
401 391 /**
@@ -462,21 +452,17 @@
462 452 $this->get_settings = $settings;
463 453 $rand = wp_rand();
464 454 $metas = RenderHelpers::meta_dataset( $settings, $template, $widget->get_settings_for_display() );
465 455
466 - $order = strtoupper( $wp_query->query_vars['order'] ?? 'ASC' );
467 - $settings['rtsb_orderby'] = RenderHelpers::escaping_product_orderby( $wp_query->query_vars['orderby'] ?? 'menu_order' );
468 - $settings['rtsb_order'] = in_array( $order, [ 'ASC','DESC' ], true ) ? $order : 'ASC';
456 + $settings['rtsb_order'] = ! empty( $wp_query->query_vars['order'] ) ? $wp_query->query_vars['order'] : 'ASC';
457 + $settings['rtsb_orderby'] = ! empty( $wp_query->query_vars['orderby'] ) ? $wp_query->query_vars['orderby'] : 'menu_order';
469 458
470 459 $pagination = $metas['pagination'];
471 460
472 - $page_type = BuilderFns::builder_type( get_the_ID() );
473 - $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
474 - $raw_settings = $widget->get_settings_for_display();
475 - $widget_per_page = ! empty( $raw_settings['posts_per_page'] ) ? absint( $raw_settings['posts_per_page'] ) : 0;
476 - $wc_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
477 - $posts_per_page = $widget_per_page ? $widget_per_page : apply_filters( 'loop_shop_per_page', $wc_per_page ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- woocommerce default hooks used.
478 - $restore_query = false;
461 + $page_type = BuilderFns::builder_type( get_the_ID() );
462 + $is_preview = BuilderFns::is_builder_preview() && array_key_exists( $page_type, BuilderFns::builder_page_types() );
463 + $posts_per_page = wc_get_default_products_per_row() * wc_get_default_product_rows_per_page();
464 +
479 465 if ( $is_preview ) {
480 466 $main_query = clone $wp_query;
481 467 $main_post = clone $post;
482 468
@@ -497,30 +483,12 @@
497 483 $wp_query = new WP_Query( $wp_query_args ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
498 484
499 485 wc_set_loop_prop( 'total', $wp_query->found_posts );
500 486 wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
501 - } elseif ( ! is_admin() && ( is_shop() || is_product_taxonomy() ) && absint( $wp_query->get( 'posts_per_page' ) ) !== $posts_per_page ) {
502 - // Apply widget's posts_per_page to the main query on the live frontend.
503 - $main_query = clone $wp_query;
504 - $main_post = clone $post;
505 -
506 - $query_vars = $wp_query->query_vars;
507 - $query_vars['posts_per_page'] = $posts_per_page;
508 -
509 - $wp_query = new WP_Query( $query_vars ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
510 -
511 - wc_set_loop_prop( 'total', $wp_query->found_posts );
512 - wc_set_loop_prop( 'total_pages', $wp_query->max_num_pages );
513 -
514 - $restore_query = true;
515 487 }
516 488
517 - if ( rtsb()->has_pro() && ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) ) {
518 - $rtsb_active_filters_html = Fns::get_active_filters_html();
519 - $rtsb_wrapper_style = '' !== $rtsb_active_filters_html ? ' style="' . esc_attr( 'display:block;' ) . '"' : '';
520 - echo '<div class="rtsb-active-filters-wrapper"' . $rtsb_wrapper_style . '>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Style value is escaped above.
521 - Fns::print_html( $rtsb_active_filters_html, true );
522 - echo '</div>';
489 + if ( Fns::product_has_applied_filters( 'shop' ) || Fns::product_has_applied_filters( 'archive' ) || 'rtsb_builder' === get_post_type( get_the_ID() ) ) {
490 + echo '<div class="rtsb-active-filters-wrapper"></div>';
523 491 }
524 492
525 493 // column_per_row.
526 494 if ( woocommerce_product_loop() ) {
@@ -530,44 +498,28 @@
530 498 $this->row( $this->wc_product_loop( $wp_query, $metas, $template ), $metas, '', $settings );
531 499 }
532 500
533 501 // Pagination.
534 - $this->html .= '<div class="rtsb-archive-pagination-wrap" data-per-page="' . absint( $posts_per_page ) . '">';
502 + $this->html .= '<div class="rtsb-archive-pagination-wrap">';
535 503
536 504 if ( $pagination ) {
537 505 if ( Fns::product_filters_has_ajax( apply_filters( 'rtsb/builder/set/current/page/type', '' ) ) ) {
538 506 if ( $wp_query->max_num_pages > 1 ) {
539 - $posts_loading_type = ! empty( $metas['posts_loading_type'] ) ? $metas['posts_loading_type'] : 'pagination';
507 + $this->add_attribute(
508 + 'rtsb_load_more_btn_attr_' . $rand,
509 + [
510 + 'data-paged' => '2',
511 + 'data-max-page' => $wp_query->max_num_pages,
512 + ]
513 + );
540 514
541 - if ( 'pagination_ajax' === $posts_loading_type ) {
542 - $this->html .= Fns::custom_pagination( $wp_query->max_num_pages, $posts_per_page, true );
543 - } elseif ( 'pagination' === $posts_loading_type ) {
544 - $this->html .= Fns::custom_pagination( $wp_query->max_num_pages, $posts_per_page, false );
545 - } elseif ( 'load_on_scroll' === $posts_loading_type ) {
546 - $this->html .= "<div class='rtsb-infinite-scroll' data-trigger='1' data-paged='2' data-max-page='{$wp_query->max_num_pages}'>
547 - <div class='rtsb-infinite-action'>
548 - <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
549 - </div>
550 - </div>";
551 - } else {
552 - $load_more_text = ! empty( $metas['load_more_text'] ) ? $metas['load_more_text'] : esc_html__( 'Load More', 'shopbuilder' );
553 -
554 - $this->add_attribute(
555 - 'rtsb_load_more_btn_attr_' . $rand,
556 - [
557 - 'data-paged' => '2',
558 - 'data-max-page' => $wp_query->max_num_pages,
559 - ]
560 - );
561 -
562 - $this->html .=
563 - "<div class='rtsb-load-more rtsb-pos-r'>
564 - <button {$this->get_attribute_string( 'rtsb_load_more_btn_attr_' . $rand )}>
565 - <span>" . esc_html( $load_more_text ) . "</span>
566 - </button>
567 - <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
568 - </div>";
569 - }
515 + $this->html .=
516 + "<div class='rtsb-load-more rtsb-pos-r'>
517 + <button {$this->get_attribute_string( 'rtsb_load_more_btn_attr_' . $rand )}>
518 + <span>" . esc_html__( 'Load More', 'shopbuilder' ) . "</span>
519 + </button>
520 + <div class='rtsb-loadmore-loading rtsb-ball-clip-rotate'><div></div></div>
521 + </div>";
570 522 }
571 523 } else {
572 524 $pagination_args = [
573 525 'query' => $wp_query,
@@ -584,9 +536,9 @@
584 536 } else {
585 537 $this->no_products_msg( $metas );
586 538 }
587 539
588 - if ( $is_preview || ! empty( $restore_query ) ) {
540 + if ( $is_preview ) {
589 541 // phpcs:disable
590 542 $wp_query = $main_query;
591 543 $post = $main_post;
592 544
@@ -594,11 +546,8 @@
594 546 wp_reset_postdata();
595 547 // phpcs:enable
596 548 }
597 549
598 - // Ensure the container's data-rtsb-ajax uses the same posts_per_page as the initial render.
599 - $settings['pagination_per_page'] = $posts_per_page;
600 -
601 550 // Container.
602 551 $this->container( $this->html, $settings, 'rtsb-products-container', $template );
603 552
604 553 return $this->html;
@@ -652,13 +601,8 @@
652 601 *
653 602 * @return string
654 603 */
655 604 public function category_view( $template, $settings, $is_single = false ) {
656 - // Reset the shared singleton's html buffer so leftover markup from a
657 - // previously rendered widget (e.g. a products grid that ran earlier
658 - // in the same request) doesn't get folded into the categories
659 - // container by container() below.
660 - $this->html = '';
661 605 $this->get_settings = $settings;
662 606
663 607 $metas = RenderHelpers::meta_dataset( $settings, $template, $this->get_settings_for_display() );
664 608 $taxonomy = $metas['category_source'];
@@ -666,11 +610,8 @@
666 610
667 611 if ( rtsb()->has_pro() && ( ! empty( $metas['tag_term'] ) ) ) {
668 612 $term = $metas['tag_term'];
669 613 }
670 - if ( rtsb()->has_pro() && ( ! empty( $metas['brand_term'] ) ) ) {
671 - $term = $metas['brand_term'];
672 - }
673 614
674 615 // Query.
675 616 if ( $is_single ) {
676 617 if ( empty( $term ) ) {
@@ -688,9 +629,9 @@
688 629 if ( ! is_wp_error( $taxonomy_query ) && ! empty( $taxonomy_query ) ) {
689 630 // Row.
690 631 $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
691 632 } else {
692 - $this->html = '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
633 + $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
693 634 }
694 635
695 636 // Container.
696 637 $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
@@ -771,9 +712,8 @@
771 712 *
772 713 * @return array
773 714 */
774 715 public function wp_arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
775 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
776 716 if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
777 717 return [];
778 718 }
779 719
@@ -779,9 +719,9 @@
779 719
780 720 global $product;
781 721
782 722 if ( ! $product instanceof WC_Product && $post_id ) {
783 - $product = wc_get_product( $post_id ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound -- Global variable is intentionally used to share the current product context with hooks and templates during rendering.
723 + $product = wc_get_product( $post_id );
784 724 }
785 725
786 726 $post_id = $product->get_id();
787 727 $arg = $this->build_product_arg(
@@ -1058,23 +998,8 @@
1058 998 ]
1059 999 );
1060 1000 }
1061 1001 }
1062 - if ( Fns::is_catalog_mode() && empty( $arg['add_to_cart'] ) ) {
1063 - if ( ! empty( $meta['add_to_cart_icon'] ) ) {
1064 - $cart_icon_html = Fns::icons_manager( $meta['add_to_cart_icon'], 'cart-icon' );
1065 - }
1066 - $cart_icon = ! empty( $cart_icon_html ) ? '<span class="icon">' . $cart_icon_html . '</span>' : '';
1067 - $arg['add_to_cart'] = CatalogModeFns::render_elementor_widget_catalog_mode_button(
1068 - [
1069 - 'id' => $post_id,
1070 - 'type' => $p_type,
1071 - 'text' => $meta['add_to_cart_text'],
1072 - 'icon_html' => $cart_icon,
1073 - 'alignment' => $meta['add_to_cart_alignment'],
1074 - ]
1075 - );
1076 - }
1077 1002 }
1078 1003
1079 1004 if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
1080 1005 add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
@@ -1139,8 +1064,9 @@
1139 1064 ];
1140 1065
1141 1066 return $arg;
1142 1067 }
1068 +
1143 1069 /**
1144 1070 * Renders add to cart button.
1145 1071 *
1146 1072 * @param array $args Cart args.
@@ -1170,8 +1096,9 @@
1170 1096
1171 1097 $cart_attr = [
1172 1098 'class' => 'rtsb-action-btn ' . $type . '-product tipsy icon-' . $alignment . ' ' . ( empty( $text ) ? 'no-text' : 'has-text' ),
1173 1099 'href' => esc_url( $link ),
1100 + 'rel' => 'nofollow',
1174 1101 'data-quantity' => '1',
1175 1102 'data-product_id' => absint( $id ),
1176 1103 'data-id' => absint( $id ),
1177 1104 ];
@@ -1177,13 +1104,12 @@
1177 1104 ];
1178 1105
1179 1106 if ( empty( $text ) ) {
1180 1107 $tooltip_mapping = [
1181 - 'simple' => esc_attr__( 'Add to Cart', 'shopbuilder' ),
1182 - 'variable' => esc_attr__( 'Select Options', 'shopbuilder' ),
1183 - 'grouped' => esc_attr__( 'View Products', 'shopbuilder' ),
1184 - 'external' => ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
1185 - 'rtsb-gift-card' => esc_attr__( 'Select Gift Card', 'shopbuilder' ),
1108 + 'simple' => esc_attr__( 'Add to Cart', 'shopbuilder' ),
1109 + 'variable' => esc_attr__( 'Select Options', 'shopbuilder' ),
1110 + 'grouped' => esc_attr__( 'View Products', 'shopbuilder' ),
1111 + 'external' => ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ),
1186 1112 ];
1187 1113
1188 1114 $cart_attr['title'] = $tooltip_mapping[ $type ];
1189 1115 }
@@ -1188,26 +1114,20 @@
1188 1114 $cart_attr['title'] = $tooltip_mapping[ $type ];
1189 1115 }
1190 1116
1191 1117 $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
1192 - if ( 'variable' === $type ) {
1193 - $cart_attr['class'] = $cart_attr['class'] . ' rtsb_vs_add_to_cart ';
1194 - }
1118 +
1195 1119 if ( 'variable' === $type || 'grouped' === $type ) {
1196 1120 $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1197 1121
1198 1122 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1199 1123
1200 - $text_btn = apply_filters(
1201 - 'rtsb/elementor/render/add_to_cart_text',
1202 - 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' ),
1203 - $product,
1204 - $type
1205 - );
1124 + $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
1206 1125
1207 1126 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1208 1127 $content .= $icon_html;
1209 - $content .= '<span class="button-text 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>';
1128 + $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>';
1129 + $content .= '<span></span>';
1210 1130 } elseif ( 'external' === $type ) {
1211 1131 if ( ! empty( $ext_link ) ) {
1212 1132 $cart_attr['target'] = '_blank';
1213 1133 }
@@ -1217,9 +1137,9 @@
1217 1137 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1218 1138
1219 1139 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1220 1140 $content .= $icon_html;
1221 - $content .= '<span class="button-text text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1141 + $content .= '<span class="text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1222 1142 } else {
1223 1143 $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1224 1144 $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1225 1145 $cart_attr['data-type'] = $type;
@@ -1228,9 +1148,10 @@
1228 1148 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1229 1149
1230 1150 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1231 1151 $content .= $icon_html;
1232 - $content .= '<span class="button-text text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1152 + $content .= '<span class="text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1153 + $content .= '<span></span>';
1233 1154 }
1234 1155
1235 1156 $content .= '</a>';
1236 1157 $content .= '</div>';
@@ -1334,17 +1255,8 @@
1334 1255 $total_page,
1335 1256 'wc' === $query_type ? $per_page : $posts_per_page
1336 1257 );
1337 1258 }
1338 - } elseif ( 'pagination_ajax' === $meta['posts_loading_type'] && ! rtsb()->has_pro() ) {
1339 - // Free version fallback: render non-AJAX number pagination so filter
1340 - // params in the URL are preserved via get_pagenum_link().
1341 - if ( $is_grid ) {
1342 - $html_utility .= Fns::custom_pagination(
1343 - $total_page,
1344 - 'wc' === $query_type ? $per_page : $posts_per_page
1345 - );
1346 - }
1347 1259 } else {
1348 1260 ob_start();
1349 1261 do_action( 'rtsb/elementor/render/pagination', $meta, $query, $args );
1350 1262 $html_utility .= ob_get_clean();
@@ -1549,14 +1461,9 @@
1549 1461 if ( empty( $this->attributes[ $element ] ) ) {
1550 1462 return '';
1551 1463 }
1552 1464
1553 - if ( class_exists( '\Elementor\Utils' ) ) {
1554 - return Utils::render_html_attributes( $this->attributes[ $element ] );
1555 - }
1556 -
1557 - // Fallback.
1558 - return $this->render_fallback_attributes( $this->attributes[ $element ] );
1465 + return Utils::render_html_attributes( $this->attributes[ $element ] );
1559 1466 }
1560 1467
1561 1468 /**
1562 1469 * Function to render link attributes.
@@ -1576,27 +1483,6 @@
1576 1483 $this->add_attribute( $id, 'role', 'button' );
1577 1484 }
1578 1485
1579 1486 return $this->get_attribute_string( $id );
1580 - }
1581 -
1582 - /**
1583 - * Render fallback attributes.
1584 - *
1585 - * @param array $attributes The attributes.
1586 - *
1587 - * @return string
1588 - */
1589 - private function render_fallback_attributes( $attributes ) {
1590 - $rendered_attributes = [];
1591 -
1592 - foreach ( $attributes as $attribute_key => $attribute_values ) {
1593 - if ( is_array( $attribute_values ) ) {
1594 - $attribute_values = implode( ' ', $attribute_values );
1595 - }
1596 -
1597 - $rendered_attributes[] = sprintf( '%1$s="%2$s"', $attribute_key, esc_attr( $attribute_values ) );
1598 - }
1599 -
1600 - return implode( ' ', $rendered_attributes );
1601 1487 }
1602 1488 }