PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.3.0
ShopBuilder – WooCommerce Builder For Elementor v3.3.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 +110 -64 2.2.23.3.0 View file →
@@ -8,14 +8,14 @@
8 8 namespace RadiusTheme\SB\Controllers;
9 9
10 10 use RadiusTheme\SB\Helpers\Fns;
11 11 use RadiusTheme\SB\Helpers\BuilderFns;
12 +use RadiusTheme\SB\Models\ElementList;
12 13 use RadiusTheme\SB\Traits\SingletonTrait;
13 14 use RadiusTheme\SB\Controllers\Builder\BuilderCpt;
14 15 use RadiusTheme\SB\Controllers\Hooks\BuilderHooks;
15 16 use RadiusTheme\SB\Elementor\Controls\ImageSelectorControl;
16 17 use RadiusTheme\SB\Elementor\Controls\Select2AjaxControl;
17 -use RadiusTheme\SB\Models\ElementList;
18 18
19 19 // Do not allow directly accessing this file.
20 20 if ( ! defined( 'ABSPATH' ) ) {
21 21 exit( 'This script cannot be accessed directly.' );
@@ -54,22 +54,18 @@
54 54 */
55 55 private function __construct() {
56 56 $this->builder_page_id = BuilderFns::builder_page_id_by_page();
57 57 $this->page_edit_with = Fns::page_edit_with( $this->builder_page_id );
58 -
59 58 if ( ! is_admin() ) {
60 59 BuilderHooks::instance();
61 60 }
62 61
63 62 BuilderCpt::instance();
64 -
65 - $this->elementor_init();
66 - $this->both_builder_frontend();
67 -
68 - // add_action( 'elementor/init', [ $this, 'elementor_init' ] );
69 - add_action( 'elementor/editor/before_enqueue_scripts', [ $this, 'editor_scripts' ] );
70 - // add_action( 'template_redirect', [ $this, 'both_builder_frontend' ], 99 );
71 -
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 + }
72 68 // RT Select2 Ajax.
73 69 add_action( 'wp_ajax_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
74 70 add_action( 'wp_ajax_nopriv_rtsb_select2_object_search', [ $this, 'select2_ajax_posts_filter_autocomplete' ] );
75 71 // Select2 ajax save data.
@@ -92,13 +88,20 @@
92 88 *
93 89 * @return void
94 90 */
95 91 public function elementor_init() {
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' ] );
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 + );
101 104 }
102 105
103 106 /**
104 107 * Register Category
@@ -112,9 +115,9 @@
112 115 $builder_id = get_queried_object_id();
113 116 $id = Fns::wpml_object_id( $builder_id, BuilderFns::$post_type_tb, 'default' );
114 117 $type = BuilderFns::builder_type( $id );
115 118
116 - if ( $type ) {
119 + if ( $type && 'popup-builder' !== $type ) {
117 120 $builder_type = ! empty( BuilderFns::builder_page_types()[ $type ] ) ? BuilderFns::builder_page_types()[ $type ] : '';
118 121 $builder_type = str_replace( [ 'My Account - ', 'Endpoint: ' ], '', $builder_type );
119 122 $categories['rtsb-shopbuilder'] = [
120 123 'title' => esc_html__( 'ShopBuilder', 'shopbuilder' ) . ' - ' . ucfirst( $builder_type ),
@@ -159,10 +162,14 @@
159 162
160 163 /**
161 164 * Init Widgets
162 165 *
163 - * Include widgets files and register them
166 + * Include widget files and register them
164 167 *
168 + * @param object $widgets_manager Widgets Manager.
169 + *
170 + * @return void
171 + *
165 172 * @since 1.0.0
166 173 */
167 174 public function init_widgets( $widgets_manager ) {
168 175
@@ -180,45 +187,50 @@
180 187 continue;
181 188 }
182 189
183 190 if ( ! empty( $element['category'] ) ) {
184 - $widget = false;
185 - $import = apply_filters( 'rtsb_import_status', false );
186 - switch ( $element['category'] ) {
187 - case 'product':
188 - if ( BuilderFns::is_product() || $import ) {
191 + try {
192 + $widget = false;
193 + $import = apply_filters( 'rtsb_import_status', false );
194 + switch ( $element['category'] ) {
195 + case 'product':
196 + if ( BuilderFns::is_product() || $import ) {
197 + $widget = new $element['base_class']();
198 + }
199 + break;
200 + case 'shop':
201 + if ( BuilderFns::is_archive() || BuilderFns::is_shop() || $import ) {
202 + $widget = new $element['base_class']();
203 + }
204 + break;
205 + case 'archive':
206 + if ( BuilderFns::is_archive() || $import ) {
207 + $widget = new $element['base_class']();
208 + }
209 + break;
210 + case 'cart':
211 + if ( BuilderFns::is_cart() || $import ) {
212 + $widget = new $element['base_class']();
213 + }
214 + break;
215 + case 'checkout':
216 + if ( BuilderFns::is_checkout() || $import ) {
217 + $widget = new $element['base_class']();
218 + }
219 + break;
220 + case 'general':
189 221 $widget = new $element['base_class']();
190 - }
191 - break;
192 - case 'shop':
193 - if ( BuilderFns::is_archive() || BuilderFns::is_shop() || $import ) {
194 - $widget = new $element['base_class']();
195 - }
196 - break;
197 - case 'archive':
198 - if ( BuilderFns::is_archive() || $import ) {
199 - $widget = new $element['base_class']();
200 - }
201 - break;
202 - case 'cart':
203 - if ( BuilderFns::is_cart() || $import ) {
204 - $widget = new $element['base_class']();
205 - }
206 - break;
207 - case 'checkout':
208 - if ( BuilderFns::is_checkout() || $import ) {
209 - $widget = new $element['base_class']();
210 - }
211 - break;
212 - case 'general':
213 - $widget = new $element['base_class']();
214 - break;
215 - default:
216 - }
217 - $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
222 + break;
223 + default:
224 + }
225 + $widget = apply_filters( 'rtsb/element/list/init/widgets', $widget, $element );
218 226
219 - if ( $widget && is_object( $widget ) ) {
220 - $widgets_manager->register( $widget );
227 + if ( $widget && is_object( $widget ) ) {
228 + $widgets_manager->register( $widget );
229 + }
230 + } catch ( \Throwable $e ) {
231 + error_log( 'ShopBuilder widget error (' . $element['base_class'] . '): ' . $e->getMessage() ); // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
232 + continue;
221 233 }
222 234 }
223 235 }
224 236 }
@@ -289,9 +301,9 @@
289 301 *
290 302 * @since 2.0.0
291 303 */
292 304 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
293 - do_action( 'elementor/page_templates/header-footer/before_content' );
305 + do_action( 'elementor/page_templates/header-footer/before_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
294 306 }
295 307
296 308 $parent_class = apply_filters( 'rtsb/builder/content/parent_class', [] );
297 309
@@ -329,10 +341,34 @@
329 341 if ( BuilderFns::is_checkout() ) {
330 342 if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
331 343 return;
332 344 }
345 +
346 + $checkout = WC()->checkout();
347 +
348 + // Temporarily remove callbacks that Elementor checkout
349 + // handles via separate widgets to prevent duplicates.
350 + remove_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_login_form' ], 10 );
351 + remove_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_coupon_form' ], 10 );
352 + remove_action( 'woocommerce_before_checkout_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
353 +
354 + do_action( 'woocommerce_before_checkout_form', $checkout );
355 +
356 + // Restore callbacks for non-Elementor contexts.
357 + add_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_login_form' ], 10 );
358 + add_action( 'woocommerce_before_checkout_form', [ Hooks\ActionHooks::class, 'woocommerce_checkout_coupon_form' ], 10 );
359 + add_action( 'woocommerce_before_checkout_form', [ Fns::class, 'woocommerce_output_all_notices' ], 10 );
360 +
361 + // If checkout registration is disabled and not logged in, the user cannot checkout.
362 + if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
363 + echo esc_html( apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'shopbuilder' ) ) );
364 + return;
365 + }
333 366 ?>
334 - <form name="checkout" method="post" class="rtsb-woocommerce-checkout checkout" action="<?php echo esc_url( wc_get_checkout_url() ); ?>" enctype="multipart/form-data">
367 + <!--
368 + woocommerce-checkout added for fix issue with payment method ( Revolut Pay )
369 + -->
370 + <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">
335 371 <?php
336 372 }
337 373 }
338 374
@@ -349,9 +385,9 @@
349 385 *
350 386 * @since 2.0.0
351 387 */
352 388 if ( did_action( 'elementor/loaded' ) && 'elementor' === $this->page_edit_with ) {
353 - do_action( 'elementor/page_templates/header-footer/after_content' );
389 + do_action( 'elementor/page_templates/header-footer/after_content' ); // phpcs:ignore WordPress.NamingConventions.ValidHookName.UseUnderscores
354 390 }
355 391
356 392 if ( BuilderFns::is_checkout() ) {
357 393 if ( ! apply_filters( 'rtsb/multi/step/checkout/widget', true ) ) {
@@ -359,8 +395,9 @@
359 395 }
360 396 ?>
361 397 </form>
362 398 <?php
399 + do_action( 'woocommerce_after_checkout_form', WC()->checkout() );
363 400 }
364 401 ?>
365 402 </div>
366 403 <!-- After Content end -->
@@ -391,9 +428,9 @@
391 428 }
392 429
393 430 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash
394 431 $search = ! empty( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '';
395 - $results = $post_list = [];
432 + $results = $post_list = []; // phpcs:ignore Squiz.PHP.DisallowMultipleAssignments.Found
396 433 switch ( $source_name ) {
397 434 case 'taxonomy':
398 435 $args = [
399 436 'hide_empty' => false,
@@ -398,13 +435,13 @@
398 435 $args = [
399 436 'hide_empty' => false,
400 437 'orderby' => 'name',
401 438 'order' => 'ASC',
402 - 'search' => $search,
439 + 'name__like' => $search,
403 440 'number' => '5',
404 441 ];
405 442
406 - if ( $post_type !== 'all' ) {
443 + if ( 'all' !== $post_type ) {
407 444 $args['taxonomy'] = $post_type;
408 445 }
409 446
410 447 $post_list = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -476,10 +513,10 @@
476 513 'include' => implode( ',', $ids ),
477 514 ];
478 515
479 516 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated
480 - if ( $_POST['post_type'] !== 'all' ) {
481 - // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
517 + if ( 'all' !== $_POST['post_type'] ) {
518 + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
482 519 $args['taxonomy'] = sanitize_text_field( $_POST['post_type'] );
483 520 }
484 521
485 522 $response = wp_list_pluck( get_terms( $args ), 'name', 'term_id' );
@@ -515,12 +552,12 @@
515 552
516 553 /**
517 554 * Ajax callback for rt-select2
518 555 *
519 - * @param $post_type
520 - * @param $limit
521 - * @param $search
522 - * @param $paged
556 + * @param string $post_type Post type.
557 + * @param int $limit Limit.
558 + * @param string $search Search.
559 + * @param int $paged Paged.
523 560 *
524 561 * @return array
525 562 */
526 563 public function get_query_data( $post_type = 'any', $limit = 10, $search = '', $paged = 1 ) {
@@ -555,8 +592,17 @@
555 592 }
556 593
557 594 if ( ! empty( $search ) ) {
558 595 $where .= $wpdb->prepare( " AND {$wpdb->posts}.post_title LIKE %s", '%' . esc_sql( $search ) . '%' );
596 + }
597 +
598 + // Add a query for shop_coupon post-type to check 'show on frontend' meta.
599 + if ( 'shop_coupon' === $post_type ) {
600 + $where .= " AND {$wpdb->posts}.ID IN (
601 + SELECT post_id FROM {$wpdb->postmeta}
602 + WHERE meta_key = 'rtsb_show_on_frontend'
603 + AND meta_value = 'on'
604 + )";
559 605 }
560 606
561 607 $query = "select post_title,ID from $wpdb->posts where post_status = 'publish' {$where} {$limit}";
562 608 $results = $wpdb->get_results( $query ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.NoCaching