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 +45 -181 3.4.2 → 2.6.5 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,10 +297,9 @@
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++;
@@ -317,9 +307,9 @@
317 307 // Loop arg.
318 308 $arg = $this->arg_dataset( $settings, $product, $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, $metas['visible_range'] ?? null );
543 - } elseif ( 'pagination' === $posts_loading_type ) {
544 - $this->html .= Fns::custom_pagination( $wp_query->max_num_pages, $posts_per_page, false, $metas['visible_range'] ?? null );
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'];
@@ -688,9 +632,9 @@
688 632 if ( ! is_wp_error( $taxonomy_query ) && ! empty( $taxonomy_query ) ) {
689 633 // Row.
690 634 $this->row( $this->category_loop( $taxonomy_query, $metas, $template, $is_single ), $metas );
691 635 } else {
692 - $this->html = '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
636 + $this->html .= '<p>' . esc_html__( 'No categories found', 'shopbuilder' ) . '</p>';
693 637 }
694 638
695 639 // Container.
696 640 $this->container( $this->html, $settings, 'rtsb-categories-container', $is_single );
@@ -771,9 +715,8 @@
771 715 *
772 716 * @return array
773 717 */
774 718 public function wp_arg_dataset( array $meta, int $post_id, bool $lazy_load = false, $i = 0 ) {
775 - // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
776 719 if ( ( empty( $meta ) && ! $post_id ) || ! in_array( get_post_type( $post_id ), [ 'product_variation', 'product' ] ) ) {
777 720 return [];
778 721 }
779 722
@@ -779,9 +722,9 @@
779 722
780 723 global $product;
781 724
782 725 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.
726 + $product = wc_get_product( $post_id );
784 727 }
785 728
786 729 $post_id = $product->get_id();
787 730 $arg = $this->build_product_arg(
@@ -1058,23 +1001,8 @@
1058 1001 ]
1059 1002 );
1060 1003 }
1061 1004 }
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 1005 }
1078 1006
1079 1007 if ( in_array( 'quick_view', $meta['visibility'], true ) ) {
1080 1008 add_filter( 'rtsb/module/quick_view/button_params', [ $this, 'button_classes' ] );
@@ -1090,26 +1018,8 @@
1090 1018 add_filter( 'rtsb/module/wishlist/button_params', [ $this, 'button_classes' ] );
1091 1019 add_filter( 'rtsb/module/wishlist/icon_html', [ $this, 'wishlist_icon' ] );
1092 1020 }
1093 1021
1094 - // Eager-load the above-the-fold product images so the LCP candidate is
1095 - // fetched immediately instead of being lazy-loaded after render-blocking
1096 - // CSS and layout. Defaults to the mobile viewport row count (Lighthouse
1097 - // scores mobile); eagering below-the-fold images would only steal
1098 - // bandwidth from the visible ones. Filterable per layout.
1099 - $eager_count = (int) apply_filters( 'rtsb/loop/eager_image_count', 6, $meta );
1100 -
1101 - // The mobile LCP is often NOT the first card but the top-right one in a
1102 - // 2-column grid, so the first *row* of images gets fetchpriority=high to
1103 - // promote the real LCP candidate ahead of render-blocking CSS. Kept small
1104 - // (default 2 = one mobile row) to avoid competing high-priority requests.
1105 - $high_count = (int) apply_filters( 'rtsb/loop/fetchpriority_high_count', 2, $meta );
1106 - $img_priority = false;
1107 -
1108 - if ( $i <= $eager_count ) {
1109 - $img_priority = $i <= $high_count ? 'high' : 'eager';
1110 - }
1111 -
1112 1022 $arg['img_html'] = $meta['f_img'] ? Fns::get_product_image_html(
1113 1023 'product',
1114 1024 $post_id,
1115 1025 $meta['f_img_size'],
@@ -1114,13 +1024,9 @@
1114 1024 $post_id,
1115 1025 $meta['f_img_size'],
1116 1026 $meta['default_img_id'],
1117 1027 $meta['custom_img_size'],
1118 - $lazy_load,
1119 - false,
1120 - false,
1121 - 0,
1122 - $img_priority
1028 + $lazy_load
1123 1029 ) : null;
1124 1030
1125 1031 if ( ! ( function_exists( 'rtwpvsp' ) && $product->is_type( 'variable' ) && $product->get_attributes() ) ) {
1126 1032 $gallery_ids = $product->get_gallery_image_ids();
@@ -1161,8 +1067,9 @@
1161 1067 ];
1162 1068
1163 1069 return $arg;
1164 1070 }
1071 +
1165 1072 /**
1166 1073 * Renders add to cart button.
1167 1074 *
1168 1075 * @param array $args Cart args.
@@ -1192,8 +1099,9 @@
1192 1099
1193 1100 $cart_attr = [
1194 1101 'class' => 'rtsb-action-btn ' . $type . '-product tipsy icon-' . $alignment . ' ' . ( empty( $text ) ? 'no-text' : 'has-text' ),
1195 1102 'href' => esc_url( $link ),
1103 + 'rel' => 'nofollow',
1196 1104 'data-quantity' => '1',
1197 1105 'data-product_id' => absint( $id ),
1198 1106 'data-id' => absint( $id ),
1199 1107 ];
@@ -1210,26 +1118,20 @@
1210 1118 $cart_attr['title'] = $tooltip_mapping[ $type ];
1211 1119 }
1212 1120
1213 1121 $content .= '<div class="rtsb-wc-add-to-cart-wrap">';
1214 - if ( 'variable' === $type ) {
1215 - $cart_attr['class'] = $cart_attr['class'] . ' rtsb_vs_add_to_cart ';
1216 - }
1122 +
1217 1123 if ( 'variable' === $type || 'grouped' === $type ) {
1218 1124 $cart_attr = apply_filters( 'rtsb/elementor/render/cart_attributes', $cart_attr, $product );
1219 1125
1220 1126 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1221 1127
1222 - $text_btn = apply_filters(
1223 - 'rtsb/elementor/render/add_to_cart_text',
1224 - 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' ),
1225 - $product,
1226 - $type
1227 - );
1128 + $text_btn = 'grouped' === $type ? __( 'View Products', 'shopbuilder' ) : __( 'Select Options', 'shopbuilder' );
1228 1129
1229 1130 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1230 1131 $content .= $icon_html;
1231 - $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>';
1132 + $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>';
1133 + $content .= '<span></span>';
1232 1134 } elseif ( 'external' === $type ) {
1233 1135 if ( ! empty( $ext_link ) ) {
1234 1136 $cart_attr['target'] = '_blank';
1235 1137 }
@@ -1239,9 +1141,9 @@
1239 1141 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1240 1142
1241 1143 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1242 1144 $content .= $icon_html;
1243 - $content .= '<span class="button-text text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1145 + $content .= '<span class="text">' . ( ! empty( $btn_txt ) ? esc_html( $btn_txt ) : esc_html__( 'Buy Product', 'shopbuilder' ) ) . '</span>';
1244 1146 } else {
1245 1147 $cart_attr['href'] = $cart_attr['href'] . '?add-to-cart=' . absint( $id );
1246 1148 $cart_attr['class'] .= ' rtsb-add-to-cart-btn';
1247 1149 $cart_attr['data-type'] = $type;
@@ -1250,9 +1152,10 @@
1250 1152 $this->add_attribute( 'rtsb_add_to_cart_button_' . $id . $rand, $cart_attr );
1251 1153
1252 1154 $content .= '<a ' . $this->get_attribute_string( 'rtsb_add_to_cart_button_' . $id . $rand ) . '>';
1253 1155 $content .= $icon_html;
1254 - $content .= '<span class="button-text text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1156 + $content .= '<span class="text ' . ( ! empty( $success ) ? 'has-success-text' : 'no-success-text' ) . '" data-success="' . esc_html( $success ) . '">' . esc_html( $text ) . '</span>';
1157 + $content .= '<span></span>';
1255 1158 }
1256 1159
1257 1160 $content .= '</a>';
1258 1161 $content .= '</div>';
@@ -1353,24 +1256,11 @@
1353 1256 if ( 'pagination' === $meta['posts_loading_type'] ) {
1354 1257 if ( $is_grid ) {
1355 1258 $html_utility .= Fns::custom_pagination(
1356 1259 $total_page,
1357 - 'wc' === $query_type ? $per_page : $posts_per_page,
1358 - false,
1359 - $meta['visible_range'] ?? null
1260 + 'wc' === $query_type ? $per_page : $posts_per_page
1360 1261 );
1361 1262 }
1362 - } elseif ( 'pagination_ajax' === $meta['posts_loading_type'] && ! rtsb()->has_pro() ) {
1363 - // Free version fallback: render non-AJAX number pagination so filter
1364 - // params in the URL are preserved via get_pagenum_link().
1365 - if ( $is_grid ) {
1366 - $html_utility .= Fns::custom_pagination(
1367 - $total_page,
1368 - 'wc' === $query_type ? $per_page : $posts_per_page,
1369 - false,
1370 - $meta['visible_range'] ?? null
1371 - );
1372 - }
1373 1263 } else {
1374 1264 ob_start();
1375 1265 do_action( 'rtsb/elementor/render/pagination', $meta, $query, $args );
1376 1266 $html_utility .= ob_get_clean();
@@ -1575,14 +1465,9 @@
1575 1465 if ( empty( $this->attributes[ $element ] ) ) {
1576 1466 return '';
1577 1467 }
1578 1468
1579 - if ( class_exists( '\Elementor\Utils' ) ) {
1580 - return Utils::render_html_attributes( $this->attributes[ $element ] );
1581 - }
1582 -
1583 - // Fallback.
1584 - return $this->render_fallback_attributes( $this->attributes[ $element ] );
1469 + return Utils::render_html_attributes( $this->attributes[ $element ] );
1585 1470 }
1586 1471
1587 1472 /**
1588 1473 * Function to render link attributes.
@@ -1602,27 +1487,6 @@
1602 1487 $this->add_attribute( $id, 'role', 'button' );
1603 1488 }
1604 1489
1605 1490 return $this->get_attribute_string( $id );
1606 - }
1607 -
1608 - /**
1609 - * Render fallback attributes.
1610 - *
1611 - * @param array $attributes The attributes.
1612 - *
1613 - * @return string
1614 - */
1615 - private function render_fallback_attributes( $attributes ) {
1616 - $rendered_attributes = [];
1617 -
1618 - foreach ( $attributes as $attribute_key => $attribute_values ) {
1619 - if ( is_array( $attribute_values ) ) {
1620 - $attribute_values = implode( ' ', $attribute_values );
1621 - }
1622 -
1623 - $rendered_attributes[] = sprintf( '%1$s="%2$s"', $attribute_key, esc_attr( $attribute_values ) );
1624 - }
1625 -
1626 - return implode( ' ', $rendered_attributes );
1627 1491 }
1628 1492 }