| @@ -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 | } |