PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 3.4.2
ShopBuilder – WooCommerce Builder For Elementor v3.4.2
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/Abstracts/ElementorWidgetBase.php +172 -16 2.1.23.4.2 View file →
@@ -6,8 +6,9 @@
6 6 */
7 7
8 8 namespace RadiusTheme\SB\Abstracts;
9 9
10 +use Elementor\Group_Control_Css_Filter;
10 11 use Elementor\Plugin;
11 12 use Elementor\Repeater;
12 13 use Elementor\Widget_Base;
13 14 use Elementor\Controls_Manager;
@@ -19,8 +20,9 @@
19 20 use Elementor\Group_Control_Box_Shadow;
20 21 use Elementor\Group_Control_Text_Shadow;
21 22 use Elementor\Group_Control_Text_Stroke;
22 23 use RadiusTheme\SB\Elementor\Helper\ControlSelectors;
24 +use RadiusTheme\SB\Helpers\Fns;
23 25
24 26
25 27 // Do not allow directly accessing this file.
26 28 if ( ! defined( 'ABSPATH' ) ) {
@@ -186,9 +188,9 @@
186 188 *
187 189 * @return array
188 190 */
189 191 public function promo_content() {
190 - if ( rtsb()->has_pro() ) {
192 + if ( rtsb()->has_pro() || $this->widget_exceptions() ) {
191 193 return [];
192 194 }
193 195
194 196 $promo_fields = [];
@@ -296,8 +298,14 @@
296 298 }
297 299 if ( isset( $value['mode'] ) && 'responsive' === $value['mode'] ) {
298 300 unset( $value['mode'] );
299 301 $repeater->add_responsive_control( $rf_id, $value );
302 + } elseif ( isset( $value['mode'] ) && 'group' === $value['mode'] ) {
303 + $type = $value['type'];
304 + $value['name'] = $rf_id;
305 + unset( $value['mode'] );
306 + unset( $value['type'] );
307 + $repeater->add_group_control( $type, $value );
300 308 } else {
301 309 $repeater->add_control( $rf_id, $value );
302 310 }
303 311 }
@@ -331,14 +339,103 @@
331 339 return BuilderFns::is_builder_preview() || $this->is_edit_mode();
332 340 }
333 341
334 342 /**
343 + * Render a shared editor-only notice.
344 + *
345 + * Any widget can surface an editor placeholder (out of stock, no active
346 + * campaign, empty result, etc.) with one consistent design. Renders only in
347 + * edit/preview mode and prints the notice CSS inline once per request.
348 + *
349 + * The notice lives in the Elementor preview iframe, which loads only frontend
350 + * styles — so the rule is printed here instead of the editor panel stylesheet,
351 + * and kept out of the compiled frontend bundle.
352 + *
353 + * @param string $message Notice text (already translated).
354 + * @param string $extra_class Optional extra class for per-widget targeting.
355 + * @param string $title Optional hover tooltip; defaults to the editor-only hint.
356 + * @return void
357 + */
358 + public function editor_notice( $message, $extra_class = '', $title = '' ) {
359 + if ( ! $this->is_edit_mode() || '' === $message ) {
360 + return;
361 + }
362 + $this->editor_notice_style();
363 + $classes = trim( 'rtsb-editor-notice ' . $extra_class );
364 + $title = '' !== $title ? $title : esc_html__( 'This notice is only visible in the Elementor editor.', 'shopbuilder' );
365 + ?>
366 + <div class="<?php echo esc_attr( $classes ); ?>" title="<?php echo esc_attr( $title ); ?>">
367 + <span class="rtsb-editor-notice__label"><?php echo esc_html__( 'Editor Notice:', 'shopbuilder' ); ?></span>
368 + <?php echo esc_html( $message ); ?>
369 + </div>
370 + <?php
371 + }
372 +
373 + /**
374 + * Print the shared editor-notice CSS inline, once per request.
375 + *
376 + * @return void
377 + */
378 + protected function editor_notice_style() {
379 + static $printed = false;
380 + if ( $printed ) {
381 + return;
382 + }
383 + $printed = true;
384 + ?>
385 + <style>
386 + .rtsb-editor-notice {
387 + position: relative;
388 + max-height: 500px;
389 + padding: 12px 16px 12px 44px;
390 + border: 1px solid #f0b849;
391 + border-left: 4px solid #f0b849;
392 + border-radius: 4px;
393 + background: #fff8e5;
394 + color: #8a6d3b;
395 + font-size: 13px;
396 + font-weight: 500;
397 + line-height: 1.5;
398 + box-shadow: 0 1px 4px rgba(138, 109, 59, 0.2);
399 + cursor: help;
400 + overflow: hidden;
401 + opacity: 1;
402 + transition: opacity 0.3s ease, max-height 0.3s ease, margin 0.3s ease, padding 0.3s ease, border-width 0.3s ease;
403 + }
404 + .rtsb-editor-notice::before {
405 + content: "\26A0";
406 + position: absolute;
407 + top: 50%;
408 + left: 16px;
409 + transform: translateY(-50%);
410 + font-size: 18px;
411 + line-height: 1;
412 + }
413 + .rtsb-editor-notice__label {
414 + font-weight: 700;
415 + margin-right: 4px;
416 + }
417 + /* Fade + collapse the notice when the editor panel is hidden (preview toggle). */
418 + .elementor-editor-preview .rtsb-editor-notice {
419 + max-height: 0;
420 + margin-top: 0;
421 + padding-top: 0;
422 + padding-bottom: 0;
423 + border-top-width: 0;
424 + border-bottom-width: 0;
425 + opacity: 0;
426 + }
427 + </style>
428 + <?php
429 + }
430 +
431 + /**
335 432 * Elementor Edit mode need some extra js for isotop reinitialize
336 433 *
337 434 * @return void
338 435 */
339 436 public function editor_slider_script() {
340 - if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
437 + if ( ! empty( \Elementor\Plugin::$instance->editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
341 438 $selector = $this->get_unique_selector() . ' .rtsb-carousel-slider';
342 439 ?>
343 440 <script>
344 441 jQuery('<?php echo esc_attr( $selector ); ?>').rtsb_slider();
@@ -365,9 +462,8 @@
365 462 var cartButton = cartWrpper.find(
366 463 '.product_type_grouped, .add_to_cart_button, .single_add_to_cart_button '
367 464 );
368 465 if (cartIcon) {
369 - console.log( cartButton.find('svg') )
370 466 cartButton.find('i').remove();
371 467 cartButton.find('svg').remove();
372 468 cartButton.find('img').remove();
373 469 cartButton.prepend(cartIcon);
@@ -388,8 +484,10 @@
388 484 if ( ! $this->is_edit_mode() ) {
389 485 return;
390 486 }
391 487 $ajaxurl = admin_url( 'admin-ajax.php' );
488 +
489 + // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
392 490 if ( in_array( 'sitepress-multilingual-cms/sitepress.php', get_option( 'active_plugins' ) ) ) {
393 491 $ajaxurl = admin_url( 'admin-ajax.php?lang=' . ICL_LANGUAGE_CODE );
394 492 }
395 493 ?>
@@ -396,21 +494,59 @@
396 494 <script>
397 495 var rtsb = {
398 496 ajaxurl: '<?php echo esc_url( $ajaxurl ); ?>',
399 497 nonce: '<?php echo esc_attr( wp_create_nonce( rtsb()->nonceId ) ); ?>',
400 - is_pro: '<?php echo esc_attr( rtsb()->has_pro() ? 'true' : 'false' ); ?>'
498 + is_pro: '<?php echo esc_attr( rtsb()->has_pro() ? 'true' : 'false' ); ?>',
499 + isOptimizationEnabled: '<?php echo esc_attr( Fns::is_optimization_enabled() ); ?>'
401 500 };
402 501
403 - rtsbElFrontend();
502 + if (!rtsb.isOptimizationEnabled) {
503 + rtsbElFrontend();
404 504
405 - setTimeout(function() {
406 - rtsbProductPageInit();
407 - }, 1000);
505 + setTimeout(function() {
506 + rtsbProductPageInit();
507 + }, 1000);
508 + } else {
509 + if (typeof elementorFrontend !== 'undefined') {
510 + window.waitForRTSB((RTSB) => {
511 + RTSB.modules.get('elementorInit')?.refresh();
512 + RTSB.modules.get('singleProductTabs')?.refresh();
513 + RTSB.modules.get('reviewFormStar')?.refresh();
514 + RTSB.modules.get('addCartIcon')?.refresh();
515 + RTSB.modules.get('productImage')?.refresh();
516 + RTSB.modules.get('CartQuantityHandler')?.refresh();
517 + });
518 + }
519 + }
520 +
408 521 <?php if ( rtsb()->has_pro() ) { ?>
409 - rtsbFilters();
410 - setTimeout( function (){
411 - window.rtsbCountdownApply();
412 - }, 1000 );
522 + var isMasonry = jQuery('.rtsb-elementor-container .rtsb-masonry');
523 +
524 + if(isMasonry.length > 0) {
525 + isMasonry.masonry();
526 + }
527 +
528 + if (!'<?php echo esc_attr( Fns::is_optimization_enabled() ); ?>') {
529 + <?php if ( 'rtsb-ajax-product-filters' === $this->rtsb_base ) { ?>
530 + if (typeof rtsbFilters === 'function') {
531 + rtsbFilters();
532 + }
533 + <?php } ?>
534 +
535 + setTimeout( function (){
536 + window.rtsbCountdownApply();
537 + }, 1000 );
538 + } else {
539 + if (typeof elementorFrontend !== 'undefined') {
540 + window.waitForRTSB((RTSB) => {
541 + RTSB.modules.get('countdownPro')?.refresh();
542 + RTSB.modules.get('elementorInitPro')?.refresh();
543 + <?php if ( 'rtsb-ajax-product-filters' === $this->rtsb_base ) { ?>
544 + RTSB.modules.get('ajaxProductFiltersPro')?.refresh();
545 + <?php } ?>
546 + });
547 + }
548 + }
413 549 <?php } ?>
414 550 </script>
415 551
416 552 <?php
@@ -656,13 +792,16 @@
656 792
657 793 case 'text-stroke':
658 794 $type = Group_Control_Text_Stroke::get_type();
659 795 break;
796 +
797 + case 'css-filter':
798 + $type = Group_Control_Css_Filter::get_type();
799 + break;
660 800 default:
661 801 $type = constant( 'Elementor\Controls_Manager::' . strtoupper( $type ) );
662 802
663 803 }
664 -
665 804 return $type;
666 805 }
667 806
668 807 /**
@@ -693,9 +832,11 @@
693 832 }
694 833 /**
695 834 * Archive Custom Layout Widget Rendering.
696 835 *
697 - * @return void
836 + * @param array $classes class list.
837 + *
838 + * @return array
698 839 */
699 840 public function countdown_campaign_parent_class( $classes ) {
700 841 $settings = $this->get_settings_for_display();
701 842 $layout = $settings['countdown_layout'] ?? 'horizontal';
@@ -711,9 +852,9 @@
711 852 ];
712 853 $classes = array_filter(
713 854 $classes,
714 855 function ( $item ) use ( $remove ) {
715 - return ! in_array( $item, $remove );
856 + return ! in_array( $item, $remove ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
716 857 }
717 858 );
718 859 $new_class = 'rtsb-countdown-' . esc_attr( $countdown_preset );
719 860 $new_class .= ' rtsb-countdown-' . esc_attr( $layout );
@@ -744,9 +885,9 @@
744 885
745 886 /**
746 887 * Elementor controls marge all settings
747 888 *
748 - * @return array
889 + * @return void
749 890 */
750 891 protected function apply_hooks_before_render() {
751 892 if ( $this->is_edit_mode() ) {
752 893 add_filter( 'wp_calculate_image_srcset_meta', '__return_null' );
@@ -762,6 +903,21 @@
762 903 protected function has_checkout_restriction() {
763 904 $checkout = WC()->checkout();
764 905
765 906 return ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in();
907 + }
908 +
909 + /**
910 + * Widget Exceptions.
911 + *
912 + * @return bool
913 + */
914 + private function widget_exceptions() {
915 + $exceptions = [
916 + 'rtsb-product-filters',
917 + 'rtsb-wishlist',
918 + 'rtsb-product-breadcrumbs',
919 + ];
920 +
921 + return in_array( $this->rtsb_base, $exceptions, true );
766 922 }
767 923 }