PluginProbe
ShopBuilder – WooCommerce Builder For Elementor / 2.6.0
ShopBuilder – WooCommerce Builder For Elementor v2.6.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 2.6.0, at app/Abstracts/ElementorWidgetBase.php

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