PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.0.0
ShopBuilder – WooCommerce Builder For Elementor v3.0.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 +157 -70 2.0.33.0.0 View file →
@@ -6,17 +6,17 @@
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\GeneralList;
13 +use RadiusTheme\SB\Models\ElementList;
13 14 use RadiusTheme\SB\Traits\SingletonTrait;
14 15 use RadiusTheme\SB\Controllers\Builder\BuilderCpt;
15 16 use RadiusTheme\SB\Controllers\Hooks\BuilderHooks;
16 17 use RadiusTheme\SB\Elementor\Controls\ImageSelectorControl;
17 18 use RadiusTheme\SB\Elementor\Controls\Select2AjaxControl;
18 -use RadiusTheme\SB\Models\ElementList;
19 19
20 20 // Do not allow directly accessing this file.
21 21 if ( ! defined( 'ABSPATH' ) ) {
22 22 exit( 'This script cannot be accessed directly.' );
@@ -26,8 +26,13 @@
26 26 * Builder Controller
27 27 */
28 28 class BuilderController {
29 29 /**
30 + * @var array
31 + */
32 + private static $cache = [];
33 +
34 + /**
30 35 * Builder page id.
31 36 *
32 37 * @var integer
33 38 */
@@ -56,19 +61,19 @@
56 61 BuilderHooks::instance();
57 62 }
58 63
59 64 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 -
65 + if ( defined( 'ELEMENTOR_VERSION' ) ) {
66 + $this->elementor_init();
67 + $this->both_builder_frontend();
68 + add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
69 + }
65 70 // 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' ] );
71 + add_action( 'wp_ajax_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
72 + add_action( 'wp_ajax_nopriv_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
68 73 // 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' ] );
74 + add_action( 'wp_ajax_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
75 + add_action( 'wp_ajax_nopriv_rtsb_select2_get_title', [ $this, 'select2_ajax_get_posts_value_titles' ] );
71 76 }
72 77
73 78 /**
74 79 * Apply for frontend.
@@ -85,13 +90,20 @@
85 90 *
86 91 * @return void
87 92 */
88 93 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' ] );
94 + add_action(
95 + 'init',
96 + function () {
97 + if ( Fns::should_load_elementor_scripts() ) {
98 + add_action( 'elementor/elements/categories_registered', [ $this, 'add_elementor_widget_categories' ] );
99 + add_action( 'elementor/widgets/register', [ $this, 'init_widgets' ] );
100 + add_action( 'elementor/controls/register', [ $this, 'init_controls' ] );
101 + add_filter( 'elementor/editor/localize_settings', [ $this, 'promotePremiumWidgets' ] );
102 + add_action( 'elementor/icons_manager/additional_tabs', [ $this, 'rtsb_icons' ] );
103 + }
104 + }
105 + );
94 106 }
95 107
96 108 /**
97 109 * Register Category
@@ -100,21 +112,29 @@
100 112 *
101 113 * @return void
102 114 */
103 115 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 - ];
116 + $categories = [];
117 + $builder_id = get_queried_object_id();
118 + $id = Fns::wpml_object_id( $builder_id, BuilderFns::$post_type_tb, 'default' );
119 + $type = BuilderFns::builder_type( $id );
115 120
116 - $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
121 + if ( $type ) {
122 + $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
123 + $builder_type = str_replace( [ 'My Account - ', 'Endpoint: ' ], '', $builder_type );
124 + $categories['rtsb-shopbuilder'] = [
125 + 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
126 + 'icon' => 'fa fa-plug',
127 + ];
128 + }
129 + if ( 'quick-view' !== $type ) {
130 + $categories['rtsb-shopbuilder-general'] = [
131 + 'title' => esc_html__( 'Shopbuilder - General', 'shopbuilder' ),
132 + 'icon' => 'fa fa-plug',
133 + ];
134 + }
135 + $categories = apply_filters( 'rtsb_elementor_widgets_category_lists', $categories );
136 +
117 137 $other_categories = $elements_manager->get_categories();
118 138 $categories = array_merge(
119 139 array_slice( $other_categories, 0, 1 ),
120 140 $categories,
@@ -120,10 +140,10 @@
120 140 $categories,
121 141 array_slice( $other_categories, 1 )
122 142 );
123 143
124 - $set_categories = function ( $categories ) {
125 - $this->categories = $categories;
144 + $set_categories = function ( $categories ) use ( $elements_manager ) {
145 + $elements_manager->categories = $categories;
126 146 };
127 147
128 148 $set_categories->call( $elements_manager, $categories );
129 149 }
@@ -144,21 +164,20 @@
144 164
145 165 /**
146 166 * Init Widgets
147 167 *
148 - * Include widgets files and register them
168 + * Include widget files and register them
149 169 *
170 + * @param object $widgets_manager Widgets Manager.
171 + *
172 + * @return void
173 + *
150 174 * @since 1.0.0
151 175 */
152 176 public function init_widgets( $widgets_manager ) {
153 - $product = Fns::get_product();
154 177
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 ) {
178 + $get_list = ElementList::instance()->get_list( true, 'active' );
179 + foreach ( $get_list as $element ) {
161 180 if ( isset( $element['active'] ) && 'on' !== $element['active'] ) {
162 181 continue;
163 182 }
164 183
@@ -220,23 +239,10 @@
220 239 *
221 240 * @return array
222 241 */
223 242 public function rtsb_icons( $tabs = [] ) {
224 - $fonts = rtsb()->get_assets_uri( 'fonts/rtsb-icons.json' );
243 + $custom_icons = Fns::get_custom_icon_names();
225 244
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 245 $tabs['shopbuilder-icons'] = [
240 246 'name' => 'rtsb-fonts',
241 247 'label' => esc_html__( 'ShopBuilder Icons', 'shopbuilder' ),
242 248 'labelIcon' => 'fab fa-elementor',
@@ -292,9 +298,9 @@
292 298 *
293 299 * @since 2.0.0
294 300 */
295 301 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
296 - do_action( 'elementor/page_templates/header-footer/before_content' );
302 + do_action( 'elementor/page_templates/header-footer/before_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
297 303 }
298 304
299 305 $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
300 306
@@ -300,8 +306,18 @@
300 306
301 307 if ( BuilderFns::is_product() ) {
302 308 $product_id = Fns::get_prepared_product_id();
303 309 $parent_class = wc_get_product_class( $parent_class, $product_id );
310 + if ( function_exists( 'rtwpvs' ) ) {
311 + $_product = Fns::get_product();
312 + if ( $_product->is_type( 'variable' ) ) {
313 + $parent_class[] = 'rtwpvs-product';
314 + $beside_label = function_exists( 'rtwpvsp' ) && rtwpvs()->get_option( 'attribute_on_click_behavior' );
315 + if ( $beside_label ) {
316 + $parent_class[] = 'rtwpvs-selected-term-beside-label';
317 + }
318 + }
319 + }
304 320 }
305 321
306 322 if ( BuilderFns::is_shop() ) {
307 323 $parent_class[] = 'shop';
@@ -317,9 +333,14 @@
317 333
318 334 ?>
319 335 <!-- Before Content start -->
320 336 <div class="<?php echo esc_attr( implode( ' ', $parent_class ) ); ?>">
321 - <?php if ( BuilderFns::is_checkout() ) { ?>
337 + <?php
338 + if ( BuilderFns::is_checkout() ) {
339 + if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
340 + return;
341 + }
342 + ?>
322 343 <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
323 344 <?php
324 345 }
325 346 }
@@ -337,12 +358,15 @@
337 358 *
338 359 * @since 2.0.0
339 360 */
340 361 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
341 - do_action( 'elementor/page_templates/header-footer/after_content' );
362 + do_action( 'elementor/page_templates/header-footer/after_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
342 363 }
343 364
344 365 if ( BuilderFns::is_checkout() ) {
366 + if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
367 + return;
368 + }
345 369 ?>
346 370 </form>
347 371 <?php
348 372 }
@@ -357,24 +381,28 @@
357 381 *
358 382 * @return void
359 383 */
360 384 public function select2_ajax_posts_filter_autocomplete() {
361 -
385 + if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
386 + wp_send_json_error( [] );
387 + }
362 388 $query_per_page = 15;
363 389 $post_type = 'post';
364 390 $source_name = 'post_type';
365 - $paged = $_POST['page'] ?? 1;
366 -
391 + $paged = absint( $_POST['page'] ?? 1 );
367 392 if ( ! empty( $_POST['post_type'] ) ) {
393 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
368 394 $post_type = sanitize_text_field( $_POST['post_type'] );
369 395 }
370 396
371 397 if ( ! empty( $_POST['source_name'] ) ) {
398 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
372 399 $source_name = sanitize_text_field( $_POST['source_name'] );
373 400 }
374 401
402 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
375 403 $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
376 - $results = $post_list = [];
404 + $results = $post_list = []; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
377 405 switch ( $source_name ) {
378 406 case 'taxonomy':
379 407 $args = [
380 408 'hide_empty' => false,
@@ -383,9 +411,9 @@
383 411 'search' => $search,
384 412 'number' => '5',
385 413 ];
386 414
387 - if ( $post_type !== 'all' ) {
415 + if ( 'all' !== $post_type ) {
388 416 $args['taxonomy'] = $post_type;
389 417 }
390 418
391 419 $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -432,17 +460,22 @@
432 460 * @return void
433 461 */
434 462 public function select2_ajax_get_posts_value_titles() {
435 463
464 + if ( ! wp_verify_nonce( Fns::get_nonce(), rtsb()->nonceText ) ) {
465 + wp_send_json_error( [] );
466 + }
467 +
436 468 if ( empty( $_POST['id'] ) ) {
437 469 wp_send_json_error( [] );
438 470 }
439 471
472 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
440 473 if ( empty( array_filter( $_POST['id'] ) ) ) {
441 474 wp_send_json_error( [] );
442 475 }
443 476 $ids = array_map( 'intval', $_POST['id'] );
444 - $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : '';
477 + $source_name = ! empty( $_POST['source_name'] ) ? sanitize_text_field( $_POST['source_name'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
445 478
446 479 switch ( $source_name ) {
447 480 case 'taxonomy':
448 481 $args = [
@@ -451,9 +484,11 @@
451 484 'order' => 'ASC',
452 485 'include' => implode( ',', $ids ),
453 486 ];
454 487
455 - if ( $_POST['post_type'] !== 'all' ) {
488 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
489 + if ( 'all' !== $_POST['post_type'] ) {
490 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
456 491 $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
457 492 }
458 493
459 494 $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -471,9 +506,9 @@
471 506 break;
472 507 default:
473 508 $post_info = get_posts(
474 509 [
475 - 'post_type' => sanitize_text_field( $_POST['post_type'] ),
510 + 'post_type' => sanitize_text_field( $_POST['post_type'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash, WordPress.Security.ValidatedSanitizedInput.InputNotValidated
476 511 'include' => implode( ',', $ids ),
477 512 ]
478 513 );
479 514 $response = wp_list_pluck( $post_info, 'post_title', 'ID' );
@@ -489,12 +524,12 @@
489 524
490 525 /**
491 526 * Ajax callback for rt-select2
492 527 *
493 - * @param $post_type
494 - * @param $limit
495 - * @param $search
496 - * @param $paged
528 + * @param string $post_type Post type.
529 + * @param int $limit Limit.
530 + * @param string $search Search.
531 + * @param int $paged Paged.
497 532 *
498 533 * @return array
499 534 */
500 535 public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
@@ -531,10 +566,19 @@
531 566 if ( ! empty( $search ) ) {
532 567 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
533 568 }
534 569
570 + // Add a query for shop_coupon post-type to check 'show on frontend' meta.
571 + if ( 'shop_coupon' === $post_type ) {
572 + $where .= " AND {$wpdb->posts}.ID IN (
573 + SELECT post_id FROM {$wpdb->postmeta}
574 + WHERE meta_key = 'rtsb_show_on_frontend'
575 + AND meta_value = 'on'
576 + )";
577 + }
578 +
535 579 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
536 - $results = $wpdb->get_results( $query );
580 + $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching
537 581
538 582 if ( ! empty( $results ) ) {
539 583 foreach ( $results as $row ) {
540 584 $data[ $row->ID ] = $row->post_title . ' [#' . $row->ID . ']';
@@ -565,10 +609,10 @@
565 609
566 610 $pro_widgets = [
567 611 [
568 612 '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' ),
613 + 'title' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
614 + 'description' => esc_html__( 'Ajax Product Filters', 'shopbuilder' ),
571 615 'icon' => 'rtsb-el-custom rtsb-element icon-rtsb-ajax-product-filters rtsb-promotional-element',
572 616 'categories' => '[ "rtsb-shopbuilder" ]',
573 617 ],
574 618 ];
@@ -579,6 +623,49 @@
579 623 }
580 624 }
581 625
582 626 return $config;
627 + }
628 +
629 + /**
630 + * Get Icons.
631 + *
632 + * @return array
633 + */
634 + public function get_icons() {
635 + return [
636 + 'heart-empty',
637 + 'heart',
638 + 'eye',
639 + 'exchange',
640 + 'plus',
641 + 'minus',
642 + 'avatar',
643 + 'pay',
644 + 'share',
645 + 'clock',
646 + 'check-alt',
647 + 'check',
648 + 'delete',
649 + 'marker',
650 + 'list',
651 + 'list-2',
652 + 'power',
653 + 'cart',
654 + 'cart-2',
655 + 'cart-3',
656 + 'downloads',
657 + 'zoom',
658 + 'user-edit',
659 + 'grid',
660 + 'filter',
661 + 'billing',
662 + 'login',
663 + 'payment',
664 + 'search',
665 + 'edit',
666 + 'coupon',
667 + 'arrows-cw',
668 + 'trash-empty',
669 + ];
583 670 }
584 671 }