PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.4.0
ShopBuilder – WooCommerce Builder For Elementor v3.4.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/Controllers/BuilderController.php +234 -109 2.0.13.4.0 View file →
@@ -6,17 +6,16 @@
6 6 */
7 7
8 8 namespace RadiusTheme\SB\Controllers;
9 9
10 -use Elementor\Plugin;
11 10 use RadiusTheme\SB\Helpers\Fns;
12 11 use RadiusTheme\SB\Helpers\BuilderFns;
12 +use RadiusTheme\SB\Models\ElementList;
13 13 use RadiusTheme\SB\Traits\SingletonTrait;
14 14 use RadiusTheme\SB\Controllers\Builder\BuilderCpt;
15 15 use RadiusTheme\SB\Controllers\Hooks\BuilderHooks;
16 16 use RadiusTheme\SB\Elementor\Controls\ImageSelectorControl;
17 17 use RadiusTheme\SB\Elementor\Controls\Select2AjaxControl;
18 -use RadiusTheme\SB\Models\ElementList;
19 18
20 19 // Do not allow directly accessing this file.
21 20 if ( ! defined( 'ABSPATH' ) ) {
22 21 exit( 'This script cannot be accessed directly.' );
@@ -26,8 +25,13 @@
26 25 * Builder Controller
27 26 */
28 27 class BuilderController {
29 28 /**
29 + * @var array
30 + */
31 + private static $cache = [];
32 +
33 + /**
30 34 * Builder page id.
31 35 *
32 36 * @var integer
33 37 */
@@ -50,25 +54,24 @@
50 54 */
51 55 private function __construct() {
52 56 $this->builder_page_id = BuilderFns::builder_page_id_by_page();
53 57 $this->page_edit_with = Fns::page_edit_with( $this->builder_page_id );
54 -
55 58 if ( ! is_admin() ) {
56 59 BuilderHooks::instance();
57 60 }
58 61
59 62 BuilderCpt::instance();
60 -
61 - add_action( 'elementor/init', [ $this, 'elementor_init' ] );
62 - add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
63 - add_action( 'template_redirect', [ $this, 'both_builder_frontend' ], 99 );
64 -
63 + if ( defined( 'ELEMENTOR_VERSION' ) ) {
64 + $this->elementor_init();
65 + $this->both_builder_frontend();
66 + add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
67 + }
65 68 // RT Select2 Ajax.
66 - add_action( 'wp_ajax_rt_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
67 - add_action( 'wp_ajax_nopriv_rt_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
69 + add_action( 'wp_ajax_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
70 + add_action( 'wp_ajax_nopriv_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
68 71 // Select2 ajax save data.
69 - add_action( 'wp_ajax_rt_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
70 - add_action( 'wp_ajax_nopriv_rt_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
72 + add_action( 'wp_ajax_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
73 + add_action( 'wp_ajax_nopriv_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
71 74 }
72 75
73 76 /**
74 77 * Apply for frontend.
@@ -85,13 +88,20 @@
85 88 *
86 89 * @return void
87 90 */
88 91 public function elementor_init() {
89 - add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
90 - add_action( 'elementor/widgets/register', [ $this, 'init_widgets' ] );
91 - add_action( 'elementor/controls/register', [ $this, 'init_controls' ] );
92 - add_filter( 'elementor/editor/localize_settings', [ $this, 'promotePremiumWidgets' ] );
93 - add_action( 'elementor/icons_manager/additional_tabs', [ $this, 'rtsb_icons' ] );
92 + add_action(
93 + 'init',
94 + function () {
95 + if ( Fns::should_load_elementor_scripts() ) {
96 + add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
97 + add_action( 'elementor/widgets/register', [ $this, 'init_widgets' ] );
98 + add_action( 'elementor/controls/register', [ $this, 'init_controls' ] );
99 + add_filter( 'elementor/editor/localize_settings', [ $this, 'promotePremiumWidgets' ] );
100 + add_action( 'elementor/icons_manager/additional_tabs', [ $this, 'rtsb_icons' ] );
101 + }
102 + }
103 + );
94 104 }
95 105
96 106 /**
97 107 * Register Category
@@ -100,21 +110,29 @@
100 110 *
101 111 * @return void
102 112 */
103 113 public function add_elementor_widget_categories( $elements_manager ) {
104 - $type = BuilderFns::builder_type( get_the_ID() );
105 - $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
106 - $builder_type = str_replace( 'My Account - ', '', $builder_type );
107 - $categories['rtsb-shopbuilder'] = [
108 - 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
109 - 'icon' => 'fa fa-plug',
110 - ];
111 - $categories['rtsb-shopbuilder-general'] = [
112 - 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
113 - 'icon' => 'fa fa-plug',
114 - ];
114 + $categories = [];
115 + $builder_id = get_queried_object_id();
116 + $id = Fns::wpml_object_id( $builder_id, BuilderFns::$post_type_tb, 'default' );
117 + $type = BuilderFns::builder_type( $id );
115 118
116 - $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
119 + if ( $type && 'popup-builder' !== $type ) {
120 + $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
121 + $builder_type = str_replace( [ 'My Account - ', 'Endpoint: ' ], '', $builder_type );
122 + $categories['rtsb-shopbuilder'] = [
123 + 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
124 + 'icon' => 'fa fa-plug',
125 + ];
126 + }
127 + if ( 'quick-view' !== $type ) {
128 + $categories['rtsb-shopbuilder-general'] = [
129 + 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
130 + 'icon' => 'fa fa-plug',
131 + ];
132 + }
133 + $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
134 +
117 135 $other_categories = $elements_manager->get_categories();
118 136 $categories = array_merge(
119 137 array_slice( $other_categories, 0, 1 ),
120 138 $categories,
@@ -120,10 +138,10 @@
120 138 $categories,
121 139 array_slice( $other_categories, 1 )
122 140 );
123 141
124 - $set_categories = function ( $categories ) {
125 - $this->categories = $categories;
142 + $set_categories = function ( $categories ) use ( $elements_manager ) {
143 + $elements_manager->categories = $categories;
126 144 };
127 145
128 146 $set_categories->call( $elements_manager, $categories );
129 147 }
@@ -144,21 +162,20 @@
144 162
145 163 /**
146 164 * Init Widgets
147 165 *
148 - * Include widgets files and register them
166 + * Include widget files and register them
149 167 *
168 + * @param object $widgets_manager Widgets Manager.
169 + *
170 + * @return void
171 + *
150 172 * @since 1.0.0
151 173 */
152 174 public function init_widgets( $widgets_manager ) {
153 - $product = Fns::get_product();
154 175
155 - // TODO: Need to remove below condition and make compitability in each widgets.
156 - if ( ! $product ) {
157 - return;
158 - }
159 -
160 - foreach ( ElementList::instance()->get_list( true, 'active' ) as $element ) {
176 + $get_list = ElementList::instance()->get_list( true, 'active' );
177 + foreach ( $get_list as $element ) {
161 178 if ( isset( $element['active'] ) && 'on' !== $element['active'] ) {
162 179 continue;
163 180 }
164 181
@@ -170,45 +187,24 @@
170 187 continue;
171 188 }
172 189
173 190 if ( ! empty( $element['category'] ) ) {
174 - $widget = false;
175 - $import = apply_filters( 'rtsb_import_status', false );
176 - switch ( $element['category'] ) {
177 - case 'product':
178 - if ( BuilderFns::is_product() || $import ) {
179 - $widget = new $element['base_class']();
180 - }
181 - break;
182 - case 'shop':
183 - if ( BuilderFns::is_archive() || BuilderFns::is_shop() || $import ) {
184 - $widget = new $element['base_class']();
185 - }
186 - break;
187 - case 'archive':
188 - if ( BuilderFns::is_archive() || $import ) {
189 - $widget = new $element['base_class']();
190 - }
191 - break;
192 - case 'cart':
193 - if ( BuilderFns::is_cart() || $import ) {
194 - $widget = new $element['base_class']();
195 - }
196 - break;
197 - case 'checkout':
198 - if ( BuilderFns::is_checkout() || $import ) {
199 - $widget = new $element['base_class']();
200 - }
201 - break;
202 - case 'general':
191 + try {
192 + $widget = false;
193 + $import = apply_filters( 'rtsb_import_status', false );
194 +
195 + if ( $this->should_register_widget( $element['category'], $import ) ) {
203 196 $widget = new $element['base_class']();
204 - break;
205 - default:
206 - }
207 - $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
197 + }
208 198
209 - if ( $widget && is_object( $widget ) ) {
210 - $widgets_manager->register( $widget );
199 + $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
200 +
201 + if ( $widget && is_object( $widget ) ) {
202 + $widgets_manager->register( $widget );
203 + }
204 + } catch ( \Throwable $e ) {
205 + error_log( 'ShopBuilder widget error (' . $element['base_class'] . '): ' . $e->getMessage() ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
206 + continue;
211 207 }
212 208 }
213 209 }
214 210 }
@@ -213,8 +209,36 @@
213 209 }
214 210 }
215 211
216 212 /**
213 + * Determine whether a widget for the given category should be registered
214 + * in the current request context.
215 + *
216 + * @param string $category Element category.
217 + * @param bool $import Whether an import is in progress.
218 + *
219 + * @return bool
220 + */
221 + protected function should_register_widget( $category, $import ) {
222 + switch ( $category ) {
223 + case 'product':
224 + return BuilderFns::is_product() || $import;
225 + case 'shop':
226 + return BuilderFns::is_archive() || BuilderFns::is_shop() || $import;
227 + case 'archive':
228 + return BuilderFns::is_archive() || $import;
229 + case 'cart':
230 + return BuilderFns::is_cart() || $import;
231 + case 'checkout':
232 + return BuilderFns::is_checkout() || $import;
233 + case 'general':
234 + return true;
235 + default:
236 + return false;
237 + }
238 + }
239 +
240 + /**
217 241 * Adding custom icons in Elementor
218 242 *
219 243 * @param array $tabs Tabs.
220 244 *
@@ -220,23 +244,10 @@
220 244 *
221 245 * @return array
222 246 */
223 247 public function rtsb_icons( $tabs = [] ) {
224 - $fonts = rtsb()->get_assets_uri( 'fonts/rtsb-icons.json' );
248 + $custom_icons = Fns::get_custom_icon_names();
225 249
226 - $response = wp_remote_get( $fonts );
227 -
228 - if ( is_wp_error( $response ) ) {
229 - return $tabs;
230 - }
231 -
232 - $icons_json = wp_remote_retrieve_body( $response );
233 - $custom_icons = json_decode( $icons_json, true );
234 -
235 - if ( null === $custom_icons ) {
236 - return $tabs;
237 - }
238 -
239 250 $tabs['shopbuilder-icons'] = [
240 251 'name' => 'rtsb-fonts',
241 252 'label' => esc_html__( 'ShopBuilder Icons', 'shopbuilder' ),
242 253 'labelIcon' => 'fab fa-elementor',
@@ -292,16 +303,34 @@
292 303 *
293 304 * @since 2.0.0
294 305 */
295 306 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
296 - do_action( 'elementor/page_templates/header-footer/before_content' );
307 + do_action( 'elementor/page_templates/header-footer/before_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
297 308 }
298 309
299 310 $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
300 311
301 312 if ( BuilderFns::is_product() ) {
302 - $product_id = Fns::get_prepared_product_id();
313 + $product_id = Fns::get_prepared_product_id();
314 +
315 + // Ensure the WordPress global $product is a valid WC_Product before
316 + // wc_get_product_class() fires the `woocommerce_post_class` filter.
317 + // Some themes (e.g. Blocksy) read the global $product directly inside
318 + // that filter and call methods like get_type() on it, which throws a
319 + // fatal error when the global is still an unresolved string.
320 + $_product = Fns::get_product();
321 +
303 322 $parent_class = wc_get_product_class( $parent_class, $product_id );
323 +
324 + if ( function_exists( 'rtwpvs' ) && $_product instanceof \WC_Product ) {
325 + if ( $_product->is_type( 'variable' ) ) {
326 + $parent_class[] = 'rtwpvs-product';
327 + $beside_label = function_exists( 'rtwpvsp' ) && rtwpvs()->get_option( 'attribute_on_click_behavior' );
328 + if ( $beside_label ) {
329 + $parent_class[] = 'rtwpvs-selected-term-beside-label';
330 + }
331 + }
332 + }
304 333 }
305 334
306 335 if ( BuilderFns::is_shop() ) {
307 336 $parent_class[] = 'shop';
@@ -317,10 +346,39 @@
317 346
318 347 ?>
319 348 <!-- Before Content start -->
320 349 <div class="<?php echo esc_attr( implode( ' ', $parent_class ) ); ?>">
321 - <?php if ( BuilderFns::is_checkout() ) { ?>
322 - <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
350 + <?php
351 + if ( BuilderFns::is_checkout() ) {
352 + if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
353 + return;
354 + }
355 +
356 + $checkout = WC()->checkout();
357 +
358 + // Temporarily remove callbacks that Elementor checkout
359 + // handles via separate widgets to prevent duplicates.
360 + remove_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_login_form' ], 10 );
361 + remove_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_coupon_form' ], 10 );
362 + remove_action( 'woocommerce_before_checkout_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
363 +
364 + do_action( 'woocommerce_before_checkout_form', $checkout );
365 +
366 + // Restore callbacks for non-Elementor contexts.
367 + add_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_login_form' ], 10 );
368 + add_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_coupon_form' ], 10 );
369 + add_action( 'woocommerce_before_checkout_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
370 +
371 + // If checkout registration is disabled and not logged in, the user cannot checkout.
372 + if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
373 + echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'shopbuilder' ) ) );
374 + return;
375 + }
376 + ?>
377 + <!--
378 + woocommerce-checkout added for fix issue with payment method ( Revolut Pay )
379 + -->
380 + <form name="checkout" method="post" class="rtsb-woocommerce-checkout woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
323 381 <?php
324 382 }
325 383 }
326 384
@@ -337,15 +395,19 @@
337 395 *
338 396 * @since 2.0.0
339 397 */
340 398 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
341 - do_action( 'elementor/page_templates/header-footer/after_content' );
399 + do_action( 'elementor/page_templates/header-footer/after_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
342 400 }
343 401
344 402 if ( BuilderFns::is_checkout() ) {
403 + if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
404 + return;
405 + }
345 406 ?>
346 407 </form>
347 408 <?php
409 + do_action( 'woocommerce_after_checkout_form', WC()->checkout() );
348 410 }
349 411 ?>
350 412 </div>
351 413 <!-- After Content end -->
@@ -357,24 +419,28 @@
357 419 *
358 420 * @return void
359 421 */
360 422 public function select2_ajax_posts_filter_autocomplete() {
361 -
423 + if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
424 + wp_send_json_error( [] );
425 + }
362 426 $query_per_page = 15;
363 427 $post_type = 'post';
364 428 $source_name = 'post_type';
365 - $paged = $_POST['page'] ?? 1;
366 -
429 + $paged = absint( $_POST['page'] ?? 1 );
367 430 if ( ! empty( $_POST['post_type'] ) ) {
431 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
368 432 $post_type = sanitize_text_field( $_POST['post_type'] );
369 433 }
370 434
371 435 if ( ! empty( $_POST['source_name'] ) ) {
436 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
372 437 $source_name = sanitize_text_field( $_POST['source_name'] );
373 438 }
374 439
440 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
375 441 $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
376 - $results = $post_list = [];
442 + $results = $post_list = []; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
377 443 switch ( $source_name ) {
378 444 case 'taxonomy':
379 445 $args = [
380 446 'hide_empty' => false,
@@ -379,13 +445,13 @@
379 445 $args = [
380 446 'hide_empty' => false,
381 447 'orderby' => 'name',
382 448 'order' => 'ASC',
383 - 'search' => $search,
449 + 'name__like' => $search,
384 450 'number' => '5',
385 451 ];
386 452
387 - if ( $post_type !== 'all' ) {
453 + if ( 'all' !== $post_type ) {
388 454 $args['taxonomy'] = $post_type;
389 455 }
390 456
391 457 $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -432,17 +498,22 @@
432 498 * @return void
433 499 */
434 500 public function select2_ajax_get_posts_value_titles() {
435 501
502 + if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
503 + wp_send_json_error( [] );
504 + }
505 +
436 506 if ( empty( $_POST['id'] ) ) {
437 507 wp_send_json_error( [] );
438 508 }
439 509
510 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
440 511 if ( empty( array_filter( $_POST['id'] ) ) ) {
441 512 wp_send_json_error( [] );
442 513 }
443 514 $ids = array_map( 'intval', $_POST['id'] );
444 - $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : '';
515 + $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
445 516
446 517 switch ( $source_name ) {
447 518 case 'taxonomy':
448 519 $args = [
@@ -451,9 +522,11 @@
451 522 'order' => 'ASC',
452 523 'include' => implode( ',', $ids ),
453 524 ];
454 525
455 - if ( $_POST['post_type'] !== 'all' ) {
526 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
527 + if ( 'all' !== $_POST['post_type'] ) {
528 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
456 529 $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
457 530 }
458 531
459 532 $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -471,9 +544,9 @@
471 544 break;
472 545 default:
473 546 $post_info = get_posts(
474 547 [
475 - 'post_type' => sanitize_text_field( $_POST['post_type'] ),
548 + 'post_type' => sanitize_text_field( $_POST['post_type'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
476 549 'include' => implode( ',', $ids ),
477 550 ]
478 551 );
479 552 $response = wp_list_pluck( $post_info, 'post_title', 'ID' );
@@ -489,12 +562,12 @@
489 562
490 563 /**
491 564 * Ajax callback for rt-select2
492 565 *
493 - * @param $post_type
494 - * @param $limit
495 - * @param $search
496 - * @param $paged
566 + * @param string $post_type Post type.
567 + * @param int $limit Limit.
568 + * @param string $search Search.
569 + * @param int $paged Paged.
497 570 *
498 571 * @return array
499 572 */
500 573 public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
@@ -531,10 +604,19 @@
531 604 if ( ! empty( $search ) ) {
532 605 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
533 606 }
534 607
608 + // Add a query for shop_coupon post-type to check 'show on frontend' meta.
609 + if ( 'shop_coupon' === $post_type ) {
610 + $where .= " AND {$wpdb->posts}.ID IN (
611 + SELECT post_id FROM {$wpdb->postmeta}
612 + WHERE meta_key = 'rtsb_show_on_frontend'
613 + AND meta_value = 'on'
614 + )";
615 + }
616 +
535 617 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
536 - $results = $wpdb->get_results( $query );
618 + $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
537 619
538 620 if ( ! empty( $results ) ) {
539 621 foreach ( $results as $row ) {
540 622 $data[ $row->ID ] = $row->post_title . ' [#' . $row->ID . ']';
@@ -565,10 +647,10 @@
565 647
566 648 $pro_widgets = [
567 649 [
568 650 'name' => 'rtsb-ajax-product-filters',
569 - 'title' => esc_html__( 'Ajax Product Filters', 'testimonial-slider-showcase' ),
570 - 'description' => esc_html__( 'Ajax Product Filters', 'testimonial-slider-showcase' ),
651 + 'title' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
652 + 'description' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
571 653 'icon' => 'rtsb-el-custom rtsb-element icon-rtsb-ajax-product-filters rtsb-promotional-element',
572 654 'categories' => '[ "rtsb-shopbuilder" ]',
573 655 ],
574 656 ];
@@ -579,6 +661,49 @@
579 661 }
580 662 }
581 663
582 664 return $config;
665 + }
666 +
667 + /**
668 + * Get Icons.
669 + *
670 + * @return array
671 + */
672 + public function get_icons() {
673 + return [
674 + 'heart-empty',
675 + 'heart',
676 + 'eye',
677 + 'exchange',
678 + 'plus',
679 + 'minus',
680 + 'avatar',
681 + 'pay',
682 + 'share',
683 + 'clock',
684 + 'check-alt',
685 + 'check',
686 + 'delete',
687 + 'marker',
688 + 'list',
689 + 'list-2',
690 + 'power',
691 + 'cart',
692 + 'cart-2',
693 + 'cart-3',
694 + 'downloads',
695 + 'zoom',
696 + 'user-edit',
697 + 'grid',
698 + 'filter',
699 + 'billing',
700 + 'login',
701 + 'payment',
702 + 'search',
703 + 'edit',
704 + 'coupon',
705 + 'arrows-cw',
706 + 'trash-empty',
707 + ];
583 708 }
584 709 }