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
shopbuilder / app / Abstracts / ElementorWidgetBase.php

ElementorWidgetBase.php in ShopBuilder – WooCommerce Builder For Elementor 3.3.0, at app/Abstracts/ElementorWidgetBase.php

835 lines 20.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Main ElementorWidgetBase class.
4 *
5 * @package RadiusTheme\SB
6 */
7
8 namespace RadiusTheme\SB\Abstracts;
9
10 use Elementor\Group_Control_Css_Filter;
11 use Elementor\Plugin;
12 use Elementor\Repeater;
13 use Elementor\Widget_Base;
14 use Elementor\Controls_Manager;
15 use Elementor\Group_Control_Border;
16 use RadiusTheme\SB\Controllers\Hooks\FilterHooks;
17 use RadiusTheme\SB\Helpers\BuilderFns;
18 use Elementor\Group_Control_Typography;
19 use Elementor\Group_Control_Background;
20 use Elementor\Group_Control_Box_Shadow;
21 use Elementor\Group_Control_Text_Shadow;
22 use Elementor\Group_Control_Text_Stroke;
23 use RadiusTheme\SB\Elementor\Helper\ControlSelectors;
24 use RadiusTheme\SB\Helpers\Fns;
25
26
27 // Do not allow directly accessing this file.
28 if ( ! defined( 'ABSPATH' ) ) {
29 exit( 'This script cannot be accessed directly.' );
30 }
31
32 /**
33 * Abstract ElementorWidgetBase Class
34 *
35 * Implemented by classes for elementor addons development.
36 *
37 * @version 1.0.0
38 * @package RadiusTheme\SB
39 */
40 abstract class ElementorWidgetBase extends Widget_Base {
41
42 /**
43 * Widget Title.
44 *
45 * @var String
46 */
47 public $rtsb_name;
48
49 /**
50 * Widget name.
51 *
52 * @var String
53 */
54 public $rtsb_base;
55
56 /**
57 * Widget categories.
58 *
59 * @var String
60 */
61 public $rtsb_category;
62
63 /**
64 * Widget icon class
65 *
66 * @var String
67 */
68 public $rtsb_icon;
69
70 /**
71 * PRO Label HTML.
72 *
73 * @var String
74 */
75 public $pro_label = '';
76
77 /**
78 * PRO content tab.
79 *
80 * @var String
81 */
82 public $pro_tab;
83
84 /**
85 * Widget prefix.
86 *
87 * @var String
88 */
89 public $el_prefix;
90
91 /**
92 * Widget controls.
93 *
94 * @var array
95 */
96 public $selectors = [];
97
98 /**
99 * Class Constructor
100 *
101 * @param array $data default data.
102 * @param array $args default arg.
103 */
104 public function __construct( $data = [], $args = null ) {
105 $this->apply_hooks_before_render();
106 parent::__construct( $data, $args );
107 $this->rtsb_category = 'rtsb-shopbuilder';
108 $this->rtsb_icon = 'rtsb-el-custom rtsb-element icon-' . $this->rtsb_base;
109 $this->el_prefix = 'rtsb_el_';
110 $this->pro_label = sprintf(
111 '<span class="rtsb-pro-label">%s</span>',
112 esc_html__( 'Pro', 'shopbuilder' )
113 );
114 $this->selectors = ControlSelectors::get_widget_selectors( $this );
115 }
116
117
118 /**
119 * Elementor controls marge all settings
120 *
121 * @return array
122 */
123 abstract public function widget_fields();
124
125 /**
126 * Get widget name.
127 *
128 * Retrieve widget name.
129 *
130 * @access public
131 *
132 * @return string Widget name.
133 */
134 public function get_name() {
135 return $this->rtsb_base;
136 }
137
138 /**
139 * Set Widget Keyword.
140 *
141 * @return array
142 */
143 public function get_keywords() {
144 return [ 'woocommerce', 'shopbuilder' ];
145 }
146
147 /**
148 * Get widget title.
149 *
150 * Retrieve widget title.
151 *
152 * @access public
153 *
154 * @return string Widget title.
155 */
156 public function get_title() {
157 return $this->rtsb_name;
158 }
159
160 /**
161 * Get widget icon.
162 *
163 * Retrieve widget icon.
164 *
165 * @return string Widget icon.
166 * @since 1.0.0
167 * @access public
168 */
169 public function get_icon() {
170 return $this->rtsb_icon;
171 }
172
173 /**
174 * Get widget categories.
175 *
176 * Retrieve the list of categories widget belongs to.
177 *
178 * @return array Widget categories.
179 * @since 1.0.0
180 * @access public
181 */
182 public function get_categories() {
183 return [ $this->rtsb_category ];
184 }
185
186 /**
187 * Elementor Promotional section controls.
188 *
189 * @return array
190 */
191 public function promo_content() {
192 if ( rtsb()->has_pro() || $this->widget_exceptions() ) {
193 return [];
194 }
195
196 $promo_fields = [];
197
198 $promo_fields['pro_alert'] = [
199 'mode' => 'section_start',
200 'label' => sprintf(
201 '<span style="color: #f54">%s</span>',
202 esc_html__( 'Go Premium for More Features', 'shopbuilder' )
203 ),
204 ];
205
206 if ( $this->pro_tab ) {
207 $promo_fields['pro_alert']['tab'] = $this->pro_tab;
208 }
209
210 $promo_fields['get_pro'] = [
211 'type' => 'html',
212 'raw' => '<div class="elementor-nerd-box rtsb-promo"><div class="elementor-nerd-box-title" style="margin-top: 0; margin-bottom: 20px;">Unlock more possibilities</div><div class="elementor-nerd-box-message"><span class="pro-feature" style="font-size: 13px;"> Get the <a href="' . esc_url( rtsb()->pro_version_link() ) . '" target="_blank" style="color: #f54">Pro version</a> for more stunning layouts and customization options.</span></div><a class="elementor-nerd-box-link elementor-button elementor-button-default elementor-button-go-pro" href="' . esc_url( rtsb()->pro_version_link() ) . '" target="_blank">Get Pro</a></div>',
213 'separator' => 'default',
214 ];
215
216 $promo_fields['pro_alert_end'] = [
217 'mode' => 'section_end',
218 ];
219
220 return $promo_fields;
221 }
222
223 /**
224 * Register widget controls.
225 *
226 * Adds different input fields to allow the user to change and customize the widget settings.
227 *
228 * @since 1.0.0
229 * @access protected
230 */
231 protected function register_controls() {
232 $this->theme_support( 'widget_controls' );
233 $the_widget = $this->widget_fields();
234 if ( ! is_array( $the_widget ) ) {
235 return;
236 }
237 $fields = array_merge( $the_widget, $this->promo_content() );
238
239 $fields = apply_filters( 'rtsb/elements/elementor/widgets/controls/' . $this->rtsb_base, $fields, $this );
240
241 foreach ( $fields as $id => $field ) {
242 $field['classes'] = ! empty( $field['classes'] ) ? $field['classes'] . ' elementor-control-rtsb_el' : ' elementor-control-rtsb_el';
243
244 if ( ! empty( $field['type'] ) ) {
245 $field['type'] = self::el_fields( $field['type'] );
246 }
247
248 if ( ! empty( $field['tab'] ) ) {
249 $field['tab'] = self::el_tabs( $field['tab'] );
250 }
251
252 if ( isset( $field['mode'] ) && 'section_start' === $field['mode'] ) {
253 unset( $field['mode'] );
254 unset( $field['separator'] );
255
256 $this->start_controls_section( $id, $field );
257 } elseif ( isset( $field['mode'] ) && 'section_end' === $field['mode'] ) {
258 $this->end_controls_section();
259 } elseif ( isset( $field['mode'] ) && 'tabs_start' === $field['mode'] ) {
260 unset( $field['mode'] );
261 unset( $field['separator'] );
262
263 $this->start_controls_tabs( $id );
264 } elseif ( isset( $field['mode'] ) && 'tabs_end' === $field['mode'] ) {
265 $this->end_controls_tabs();
266 } elseif ( isset( $field['mode'] ) && 'tab_start' === $field['mode'] ) {
267 unset( $field['mode'] );
268 unset( $field['separator'] );
269
270 $this->start_controls_tab( $id, $field );
271 } elseif ( isset( $field['mode'] ) && 'tab_end' === $field['mode'] ) {
272 $this->end_controls_tab();
273 } elseif ( isset( $field['mode'] ) && 'group' === $field['mode'] ) {
274 $type = $field['type'];
275 $field['name'] = $id;
276 unset( $field['mode'] );
277 unset( $field['type'] );
278 $this->add_group_control( $type, $field );
279 } elseif ( isset( $field['mode'] ) && 'responsive' === $field['mode'] ) {
280 unset( $field['mode'] );
281
282 $this->add_responsive_control( $id, $field );
283 } elseif ( isset( $field['mode'] ) && 'popover_start' === $field['mode'] ) {
284 unset( $field['mode'] );
285 unset( $field['separator'] );
286
287 $this->add_control( $id, $field );
288 $this->start_popover();
289 } elseif ( isset( $field['mode'] ) && 'popover_end' === $field['mode'] ) {
290 $this->end_popover();
291 } elseif ( isset( $field['mode'] ) && 'repeater' === $field['mode'] ) {
292 $repeater = new Repeater();
293 $repeater_fields = $field['fields'];
294
295 foreach ( $repeater_fields as $rf_id => $value ) {
296 if ( ! empty( $value['type'] ) ) {
297 $value['type'] = self::el_fields( $value['type'] );
298 }
299 if ( isset( $value['mode'] ) && 'responsive' === $value['mode'] ) {
300 unset( $value['mode'] );
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 );
308 } else {
309 $repeater->add_control( $rf_id, $value );
310 }
311 }
312
313 $field['fields'] = $repeater->get_controls();
314
315 $this->add_control( $id, $field );
316 } else {
317 $this->add_control( $id, $field );
318 }
319 }
320
321 do_action( 'rtsb/after/register/controls' );
322 }
323
324 /**
325 * Elementor Edit mode.
326 *
327 * @return mixed
328 */
329 public function is_edit_mode() {
330 return Plugin::$instance->preview->is_preview_mode() || Plugin::$instance->editor->is_edit_mode();
331 }
332
333 /**
334 * Elementor Edit preview.
335 *
336 * @return mixed
337 */
338 public function is_builder_mode() {
339 return BuilderFns::is_builder_preview() || $this->is_edit_mode();
340 }
341
342 /**
343 * Elementor Edit mode need some extra js for isotop reinitialize
344 *
345 * @return void
346 */
347 public function editor_slider_script() {
348 if ( ! empty( \Elementor\Plugin::$instance->editor ) && \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
349 $selector = $this->get_unique_selector() . ' .rtsb-carousel-slider';
350 ?>
351 <script>
352 jQuery('<?php echo esc_attr( $selector ); ?>').rtsb_slider();
353 </script>
354 <?php
355 }
356 }
357
358 /**
359 * Elementor Edit mode need some extra js for isotop reinitialize
360 *
361 * @return void
362 */
363 public function editor_cart_icon_script() {
364 if ( $this->is_edit_mode() ) {
365 $selector = $this->get_unique_selector() . ' .has-cart-button';
366 ?>
367 <script type="text/javascript">
368 // Product Archive Catelog
369 (function ($) {
370 setTimeout( function (){
371 var cartWrpper = $('body').find('<?php echo esc_attr( $selector ); ?>');
372 var cartIcon = cartWrpper.attr('data-cart-icon');
373 var cartButton = cartWrpper.find(
374 '.product_type_grouped, .add_to_cart_button, .single_add_to_cart_button '
375 );
376 if (cartIcon) {
377 cartButton.find('i').remove();
378 cartButton.find('svg').remove();
379 cartButton.find('img').remove();
380 cartButton.prepend(cartIcon);
381 }
382 }, 2000);
383 })(jQuery);
384 </script>
385 <?php
386 }
387 }
388
389 /**
390 * Elementor Edit mode script
391 *
392 * @return void
393 */
394 public function edit_mode_script() {
395 if ( ! $this->is_edit_mode() ) {
396 return;
397 }
398 $ajaxurl = admin_url( 'admin-ajax.php' );
399
400 // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
401 if ( in_array( 'sitepress-multilingual-cms/sitepress.php', get_option( 'active_plugins' ) ) ) {
402 $ajaxurl = admin_url( 'admin-ajax.php?lang=' . ICL_LANGUAGE_CODE );
403 }
404 ?>
405 <script>
406 var rtsb = {
407 ajaxurl: '<?php echo esc_url( $ajaxurl ); ?>',
408 nonce: '<?php echo esc_attr( wp_create_nonce( rtsb()->nonceId ) ); ?>',
409 is_pro: '<?php echo esc_attr( rtsb()->has_pro() ? 'true' : 'false' ); ?>',
410 isOptimizationEnabled: '<?php echo esc_attr( Fns::is_optimization_enabled() ); ?>'
411 };
412
413 if (!rtsb.isOptimizationEnabled) {
414 rtsbElFrontend();
415
416 setTimeout(function() {
417 rtsbProductPageInit();
418 }, 1000);
419 } else {
420 if (typeof elementorFrontend !== 'undefined') {
421 window.waitForRTSB((RTSB) => {
422 RTSB.modules.get('elementorInit')?.refresh();
423 RTSB.modules.get('singleProductTabs')?.refresh();
424 RTSB.modules.get('reviewFormStar')?.refresh();
425 RTSB.modules.get('addCartIcon')?.refresh();
426 RTSB.modules.get('productImage')?.refresh();
427 RTSB.modules.get('CartQuantityHandler')?.refresh();
428 });
429 }
430 }
431
432 <?php if ( rtsb()->has_pro() ) { ?>
433 var isMasonry = jQuery('.rtsb-elementor-container .rtsb-masonry');
434
435 if(isMasonry.length > 0) {
436 isMasonry.masonry();
437 }
438
439 if (!'<?php echo esc_attr( Fns::is_optimization_enabled() ); ?>') {
440 <?php if ( 'rtsb-ajax-product-filters' === $this->rtsb_base ) { ?>
441 if (typeof rtsbFilters === 'function') {
442 rtsbFilters();
443 }
444 <?php } ?>
445
446 setTimeout( function (){
447 window.rtsbCountdownApply();
448 }, 1000 );
449 } else {
450 if (typeof elementorFrontend !== 'undefined') {
451 window.waitForRTSB((RTSB) => {
452 RTSB.modules.get('countdownPro')?.refresh();
453 RTSB.modules.get('elementorInitPro')?.refresh();
454 <?php if ( 'rtsb-ajax-product-filters' === $this->rtsb_base ) { ?>
455 RTSB.modules.get('ajaxProductFiltersPro')?.refresh();
456 <?php } ?>
457 });
458 }
459 }
460 <?php } ?>
461 </script>
462
463 <?php
464 }
465
466 /**
467 * Starts an Elementor Section
468 *
469 * @param string $label Section label.
470 * @param object $tab Tab ID.
471 * @param array $conditions Section Condition.
472 * @param array $condition Section Conditions.
473 * @return array
474 */
475 public function start_section( $label, $tab, $conditions = [], $condition = [] ) {
476 $start = [
477 'mode' => 'section_start',
478 'tab' => $tab,
479 'label' => $label,
480 ];
481 if ( ! empty( $condition ) ) {
482 $start['condition'] = $condition;
483 }
484 if ( ! empty( $conditions ) ) {
485 $start['conditions'] = $conditions;
486 }
487 return $start;
488 }
489
490 /**
491 * Ends an Elementor Section
492 *
493 * @return array
494 */
495 public function end_section() {
496 return [
497 'mode' => 'section_end',
498 ];
499 }
500
501 /**
502 * Theme Support for render/widget_controls
503 *
504 * @param string $support Support for render/widget_controls.
505 * @return void
506 */
507 public function theme_support( $support = 'render' ) {
508
509 if ( empty( $support ) ) {
510 return;
511 }
512 $theme = ucwords( str_replace( [ '_', '-', ' ' ], '', rtsb()->current_theme ) );
513
514 $supportClass = apply_filters(
515 'radiustheme/sb/widgetsupport/class',
516 [
517 'ShopbuilderPlugin' => 'RadiusTheme\SB\Controllers\ThemesSupport\\' . $theme . '\\WidgetsSupport',
518 'TheTheme' => \WidgetSupport::class,
519 ]
520 );
521
522 foreach ( $supportClass as $key => $theClass ) {
523 $themeWidgetSupport = get_theme_file_path( '/shopbuilder/WidgetSupport.php' );
524 if ( 'TheTheme' === $key && file_exists( $themeWidgetSupport ) ) {
525 require_once $themeWidgetSupport;
526 }
527 if ( class_exists( $theClass ) ) {
528 $method = $support . '_' . str_replace( [ '-', ' ' ], '_', $this->rtsb_base );
529 if ( method_exists( $theClass, $method ) ) {
530 $theClass::instance( $this )->$method();
531 }
532 }
533 }
534 }
535
536 /**
537 * Starts an Elementor tab group.
538 *
539 * @param array $conditions Tab condition.
540 * @param array $condition Tab condition.
541 * @return array
542 */
543 public function start_tab_group( $conditions = [], $condition = [] ) {
544 return [
545 'mode' => 'tabs_start',
546 'conditions' => $conditions,
547 'condition' => $condition,
548 ];
549 }
550
551 /**
552 * Ends an Elementor tab group.
553 *
554 * @param array $conditions Tab condition.
555 * @param array $condition Tab condition.
556 * @return array
557 */
558 public function end_tab_group( $conditions = [], $condition = [] ) {
559 return [
560 'mode' => 'tabs_end',
561 'conditions' => $conditions,
562 'condition' => $condition,
563 ];
564 }
565
566 /**
567 * Starts an Elementor tab
568 *
569 * @param string $label Section label.
570 * @param array $conditions Tab condition.
571 * @param array $condition Tab condition.
572 * @return array
573 */
574 public function start_tab( $label, $conditions = [], $condition = [] ) {
575 return [
576 'mode' => 'tab_start',
577 'label' => $label,
578 'conditions' => $conditions,
579 'condition' => $condition,
580 ];
581 }
582
583 /**
584 * Ends an Elementor tab.
585 *
586 * @param array $conditions Tab condition.
587 * @param array $condition Tab condition.
588 * @return array
589 */
590 public function end_tab( $conditions = [], $condition = [] ) {
591 return [
592 'mode' => 'tab_end',
593 'conditions' => $conditions,
594 'condition' => $condition,
595 ];
596 }
597
598 /**
599 * Starts an Elementor Section Heading
600 *
601 * @param string $label Heading label.
602 * @param string $separator Section separator.
603 * @param array $conditions Section Condition.
604 * @param array $condition Section Conditions.
605 * @return array
606 */
607 public function el_heading( $label, $separator = null, $conditions = [], $condition = [] ) {
608 return [
609 'type' => 'html',
610 'raw' => sprintf(
611 '<h3 class="rtsb-elementor-group-heading">%s</h3>',
612 $label
613 ),
614 'separator' => $separator,
615 'content_classes' => 'elementor-panel-heading-title',
616 'conditions' => $conditions,
617 'condition' => $condition,
618 ];
619 }
620
621 /**
622 * Prints a control notification.
623 *
624 * @param string $label Field label.
625 * @return string
626 */
627 public function is_pro_control( $label ) {
628 if ( rtsb()->has_pro() ) {
629 return $label;
630 }
631
632 return $label . $this->pro_label;
633 }
634
635 /**
636 * Adds a class.
637 *
638 * @return string
639 */
640 public function pro_class() {
641 return ! rtsb()->has_pro() ? 'rtsb-pro-field' : '';
642 }
643
644 /**
645 * Elementor Fields.
646 *
647 * @param string $type Control type.
648 *
649 * @return string
650 */
651 private static function el_fields( $type ) {
652
653 $controls = Controls_Manager::class;
654
655 switch ( $type ) {
656 case 'link':
657 $type = $controls::URL;
658 break;
659
660 case 'image-dimensions':
661 $type = $controls::IMAGE_DIMENSIONS;
662 break;
663
664 case 'html':
665 $type = $controls::RAW_HTML;
666 break;
667
668 case 'switch':
669 $type = $controls::SWITCHER;
670 break;
671
672 case 'popover':
673 $type = $controls::POPOVER_TOGGLE;
674 break;
675
676 case 'rtsb-image-selector':
677 $type = \RadiusTheme\SB\Elementor\Controls\ImageSelectorControl::$controlName;
678 break;
679
680 case 'rt-select2':
681 $type = \RadiusTheme\SB\Elementor\Controls\Select2AjaxControl::$controlName;
682 break;
683
684 case 'typography':
685 $type = Group_Control_Typography::get_type();
686 break;
687
688 case 'border':
689 $type = Group_Control_Border::get_type();
690 break;
691
692 case 'background':
693 $type = Group_Control_Background::get_type();
694 break;
695
696 case 'box-shadow':
697 $type = Group_Control_Box_Shadow::get_type();
698 break;
699
700 case 'text-shadow':
701 $type = Group_Control_Text_Shadow::get_type();
702 break;
703
704 case 'text-stroke':
705 $type = Group_Control_Text_Stroke::get_type();
706 break;
707
708 case 'css-filter':
709 $type = Group_Control_Css_Filter::get_type();
710 break;
711 default:
712 $type = constant( 'Elementor\Controls_Manager::' . strtoupper( $type ) );
713
714 }
715 return $type;
716 }
717
718 /**
719 * Elementor Fields.
720 *
721 * @param string $tab Tab.
722 *
723 * @return string
724 */
725 private static function el_tabs( $tab ) {
726 return constant( 'Elementor\Controls_Manager::TAB_' . strtoupper( $tab ) );
727 }
728
729
730 /**
731 * Init render hooks & functions.
732 *
733 * @return void
734 */
735 protected function render_start() {
736 add_filter( 'rtsb/countdown/campaign/parent/class', [ $this, 'countdown_campaign_parent_class' ], 15 );
737 do_action( 'rtsb/custom/products/before/template/load', $this );
738 $this->theme_support();
739
740 if ( $this->is_builder_mode() ) {
741 add_filter( 'wp_kses_allowed_html', [ FilterHooks::class, 'custom_wpkses_post_tags' ], 10, 2 );
742 }
743 }
744 /**
745 * Archive Custom Layout Widget Rendering.
746 *
747 * @param array $classes class list.
748 *
749 * @return array
750 */
751 public function countdown_campaign_parent_class( $classes ) {
752 $settings = $this->get_settings_for_display();
753 $layout = $settings['countdown_layout'] ?? 'horizontal';
754 $v_position = $settings['countdown_vertical_position'] ?? '';
755 $countdown_preset = $settings['countdown_preset'] ?? '';
756 $vertical_center = $settings['countdown_vertical_center'] ?? false;
757
758 $remove = [
759 'rtsb-countdown-horizontal',
760 'rtsb-countdown-vertical',
761 'rtsb-vertical-position-top-left',
762 'rtsb-vertical-position-top-right',
763 ];
764 $classes = array_filter(
765 $classes,
766 function ( $item ) use ( $remove ) {
767 return ! in_array( $item, $remove ); // phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
768 }
769 );
770 $new_class = 'rtsb-countdown-' . esc_attr( $countdown_preset );
771 $new_class .= ' rtsb-countdown-' . esc_attr( $layout );
772
773 if ( $v_position && 'horizontal' !== $layout ) {
774 $vertical_class = 'rtsb-vertical-position-top-' . esc_attr( $v_position );
775 $classes[] = $vertical_class;
776 if ( 'yes' === $vertical_center ) {
777 $classes[] = 'rtsb-countdown-vertical-middle';
778 }
779 }
780
781 $classes[] = $new_class;
782
783 return $classes;
784 }
785 /**
786 * End render hooks & functions.
787 *
788 * @return void
789 */
790 protected function render_end() {
791 $this->edit_mode_script();
792 do_action( 'rtsb/custom/products/after/template/load', $this );
793 $this->theme_support( 'render_reset' );
794 remove_filter( 'rtsb/countdown/campaign/parent/class', [ $this, 'countdown_campaign_parent_class' ], 15 );
795 }
796
797 /**
798 * Elementor controls marge all settings
799 *
800 * @return void
801 */
802 protected function apply_hooks_before_render() {
803 if ( $this->is_edit_mode() ) {
804 add_filter( 'wp_calculate_image_srcset_meta', '__return_null' );
805 }
806 }
807
808 /**
809 * If checkout registration is disabled and not logged in,
810 * the user cannot check out.
811 *
812 * @return bool
813 */
814 protected function has_checkout_restriction() {
815 $checkout = WC()->checkout();
816
817 return ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in();
818 }
819
820 /**
821 * Widget Exceptions.
822 *
823 * @return bool
824 */
825 private function widget_exceptions() {
826 $exceptions = [
827 'rtsb-product-filters',
828 'rtsb-wishlist',
829 'rtsb-product-breadcrumbs',
830 ];
831
832 return in_array( $this->rtsb_base, $exceptions, true );
833 }
834 }
835