PluginProbe
Elementor Website Builder – more than just a page builder / 3.5.6
Elementor Website Builder – more than just a page builder v3.5.6
4.3.0-beta2 4.3.0-beta1 4.2.4 4.2.3 4.2.2 4.2.1 4.2.0 4.1.5 4.2.0-beta2 4.2.0-dev2 4.2.0-beta1 4.1.4 4.1.3 4.1.2 4.1.1 4.1.0 4.1.0-beta3 4.1.0-dev3 4.0.9 4.1.0-beta2 4.1.0-dev2 4.0.8 4.1.0-beta1 4.1.0-dev1 4.0.7 All 451 releases
elementor / includes / managers / controls.php

controls.php in Elementor Website Builder – more than just a page builder 3.5.6, at includes/managers/controls.php

1,106 lines 24.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace Elementor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 /**
9 * Elementor controls manager.
10 *
11 * Elementor controls manager handler class is responsible for registering and
12 * initializing all the supported controls, both regular controls and the group
13 * controls.
14 *
15 * @since 1.0.0
16 */
17 class Controls_Manager {
18
19 /**
20 * Content tab.
21 */
22 const TAB_CONTENT = 'content';
23
24 /**
25 * Style tab.
26 */
27 const TAB_STYLE = 'style';
28
29 /**
30 * Advanced tab.
31 */
32 const TAB_ADVANCED = 'advanced';
33
34 /**
35 * Responsive tab.
36 */
37 const TAB_RESPONSIVE = 'responsive';
38
39 /**
40 * Layout tab.
41 */
42 const TAB_LAYOUT = 'layout';
43
44 /**
45 * Settings tab.
46 */
47 const TAB_SETTINGS = 'settings';
48
49 /**
50 * Text control.
51 */
52 const TEXT = 'text';
53
54 /**
55 * Number control.
56 */
57 const NUMBER = 'number';
58
59 /**
60 * Textarea control.
61 */
62 const TEXTAREA = 'textarea';
63
64 /**
65 * Select control.
66 */
67 const SELECT = 'select';
68
69 /**
70 * Switcher control.
71 */
72 const SWITCHER = 'switcher';
73
74 /**
75 * Button control.
76 */
77 const BUTTON = 'button';
78
79 /**
80 * Hidden control.
81 */
82 const HIDDEN = 'hidden';
83
84 /**
85 * Heading control.
86 */
87 const HEADING = 'heading';
88
89 /**
90 * Raw HTML control.
91 */
92 const RAW_HTML = 'raw_html';
93
94 /**
95 * Deprecated Notice control.
96 */
97 const DEPRECATED_NOTICE = 'deprecated_notice';
98
99 /**
100 * Popover Toggle control.
101 */
102 const POPOVER_TOGGLE = 'popover_toggle';
103
104 /**
105 * Section control.
106 */
107 const SECTION = 'section';
108
109 /**
110 * Tab control.
111 */
112 const TAB = 'tab';
113
114 /**
115 * Tabs control.
116 */
117 const TABS = 'tabs';
118
119 /**
120 * Divider control.
121 */
122 const DIVIDER = 'divider';
123
124 /**
125 * Color control.
126 */
127 const COLOR = 'color';
128
129 /**
130 * Media control.
131 */
132 const MEDIA = 'media';
133
134 /**
135 * Slider control.
136 */
137 const SLIDER = 'slider';
138
139 /**
140 * Dimensions control.
141 */
142 const DIMENSIONS = 'dimensions';
143
144 /**
145 * Choose control.
146 */
147 const CHOOSE = 'choose';
148
149 /**
150 * WYSIWYG control.
151 */
152 const WYSIWYG = 'wysiwyg';
153
154 /**
155 * Code control.
156 */
157 const CODE = 'code';
158
159 /**
160 * Font control.
161 */
162 const FONT = 'font';
163
164 /**
165 * Image dimensions control.
166 */
167 const IMAGE_DIMENSIONS = 'image_dimensions';
168
169 /**
170 * WordPress widget control.
171 */
172 const WP_WIDGET = 'wp_widget';
173
174 /**
175 * URL control.
176 */
177 const URL = 'url';
178
179 /**
180 * Repeater control.
181 */
182 const REPEATER = 'repeater';
183
184 /**
185 * Icon control.
186 */
187 const ICON = 'icon';
188
189 /**
190 * Icons control.
191 */
192 const ICONS = 'icons';
193
194 /**
195 * Gallery control.
196 */
197 const GALLERY = 'gallery';
198
199 /**
200 * Structure control.
201 */
202 const STRUCTURE = 'structure';
203
204 /**
205 * Select2 control.
206 */
207 const SELECT2 = 'select2';
208
209 /**
210 * Date/Time control.
211 */
212 const DATE_TIME = 'date_time';
213
214 /**
215 * Box shadow control.
216 */
217 const BOX_SHADOW = 'box_shadow';
218
219 /**
220 * Text shadow control.
221 */
222 const TEXT_SHADOW = 'text_shadow';
223
224 /**
225 * Entrance animation control.
226 */
227 const ANIMATION = 'animation';
228
229 /**
230 * Hover animation control.
231 */
232 const HOVER_ANIMATION = 'hover_animation';
233
234 /**
235 * Exit animation control.
236 */
237 const EXIT_ANIMATION = 'exit_animation';
238
239 /**
240 * Controls.
241 *
242 * Holds the list of all the controls. Default is `null`.
243 *
244 * @since 1.0.0
245 * @access private
246 *
247 * @var Base_Control[]
248 */
249 private $controls = null;
250
251 /**
252 * Control groups.
253 *
254 * Holds the list of all the control groups. Default is an empty array.
255 *
256 * @since 1.0.0
257 * @access private
258 *
259 * @var Group_Control_Base[]
260 */
261 private $control_groups = [];
262
263 /**
264 * Control stacks.
265 *
266 * Holds the list of all the control stacks. Default is an empty array.
267 *
268 * @since 1.0.0
269 * @access private
270 *
271 * @var array
272 */
273 private $stacks = [];
274
275 /**
276 * Tabs.
277 *
278 * Holds the list of all the tabs.
279 *
280 * @since 1.0.0
281 * @access private
282 * @static
283 *
284 * @var array
285 */
286 private static $tabs;
287
288 /**
289 * Init tabs.
290 *
291 * Initialize control tabs.
292 *
293 * @since 1.6.0
294 * @access private
295 * @static
296 */
297 private static function init_tabs() {
298 self::$tabs = [
299 self::TAB_CONTENT => esc_html__( 'Content', 'elementor' ),
300 self::TAB_STYLE => esc_html__( 'Style', 'elementor' ),
301 self::TAB_ADVANCED => esc_html__( 'Advanced', 'elementor' ),
302 self::TAB_RESPONSIVE => esc_html__( 'Responsive', 'elementor' ),
303 self::TAB_LAYOUT => esc_html__( 'Layout', 'elementor' ),
304 self::TAB_SETTINGS => esc_html__( 'Settings', 'elementor' ),
305 ];
306 }
307
308 /**
309 * Get tabs.
310 *
311 * Retrieve the tabs of the current control.
312 *
313 * @since 1.6.0
314 * @access public
315 * @static
316 *
317 * @return array Control tabs.
318 */
319 public static function get_tabs() {
320 if ( ! self::$tabs ) {
321 self::init_tabs();
322 }
323
324 return self::$tabs;
325 }
326
327 /**
328 * Add tab.
329 *
330 * This method adds a new tab to the current control.
331 *
332 * @since 1.6.0
333 * @access public
334 * @static
335 *
336 * @param string $tab_name Tab name.
337 * @param string $tab_label Tab label.
338 */
339 public static function add_tab( $tab_name, $tab_label = '' ) {
340 if ( ! self::$tabs ) {
341 self::init_tabs();
342 }
343
344 if ( isset( self::$tabs[ $tab_name ] ) ) {
345 return;
346 }
347
348 self::$tabs[ $tab_name ] = $tab_label;
349 }
350
351 public static function get_groups_names() {
352 // Group name must use "-" instead of "_"
353 return [
354 'background',
355 'border',
356 'typography',
357 'image-size',
358 'box-shadow',
359 'css-filter',
360 'text-shadow',
361 'text-stroke',
362 ];
363 }
364
365 public static function get_controls_names() {
366 return [
367 self::TEXT,
368 self::NUMBER,
369 self::TEXTAREA,
370 self::SELECT,
371 self::SWITCHER,
372
373 self::BUTTON,
374 self::HIDDEN,
375 self::HEADING,
376 self::RAW_HTML,
377 self::POPOVER_TOGGLE,
378 self::SECTION,
379 self::TAB,
380 self::TABS,
381 self::DIVIDER,
382 self::DEPRECATED_NOTICE,
383
384 self::COLOR,
385 self::MEDIA,
386 self::SLIDER,
387 self::DIMENSIONS,
388 self::CHOOSE,
389 self::WYSIWYG,
390 self::CODE,
391 self::FONT,
392 self::IMAGE_DIMENSIONS,
393
394 self::WP_WIDGET,
395
396 self::URL,
397 self::REPEATER,
398 self::ICON,
399 self::ICONS,
400 self::GALLERY,
401 self::STRUCTURE,
402 self::SELECT2,
403 self::DATE_TIME,
404 self::BOX_SHADOW,
405 self::TEXT_SHADOW,
406 self::ANIMATION,
407 self::HOVER_ANIMATION,
408 self::EXIT_ANIMATION,
409 ];
410 }
411
412 /**
413 * Register controls.
414 *
415 * This method creates a list of all the supported controls by requiring the
416 * control files and initializing each one of them.
417 *
418 * The list of supported controls includes the regular controls and the group
419 * controls.
420 *
421 * External developers can register new controls by hooking to the
422 * `elementor/controls/controls_registered` action.
423 *
424 * @since 3.1.0
425 * @access private
426 */
427 private function register_controls() {
428 $this->controls = [];
429
430 foreach ( self::get_controls_names() as $control_id ) {
431 $control_class_id = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $control_id ) ) );
432 $class_name = __NAMESPACE__ . '\Control_' . $control_class_id;
433
434 $this->register( new $class_name() );
435 }
436
437 // Group Controls
438 foreach ( self::get_groups_names() as $group_name ) {
439 $group_class_id = str_replace( ' ', '_', ucwords( str_replace( '-', ' ', $group_name ) ) );
440 $class_name = __NAMESPACE__ . '\Group_Control_' . $group_class_id;
441
442 $this->control_groups[ $group_name ] = new $class_name();
443 }
444
445 /**
446 * After controls registered.
447 *
448 * Fires after Elementor controls are registered.
449 *
450 * @since 1.0.0
451 * @deprecated 3.5.0 Use `elementor/controls/register` hook instead.
452 *
453 * @param Controls_Manager $this The controls manager.
454 */
455 // TODO: Uncomment when Pro uses the new hook.
456 //Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->do_deprecated_action(
457 // 'elementor/controls/controls_registered',
458 // [ $this ],
459 // '3.5.0',
460 // 'elementor/controls/register'
461 //);
462
463 do_action( 'elementor/controls/controls_registered', $this );
464
465 /**
466 * After controls registered.
467 *
468 * Fires after Elementor controls are registered.
469 *
470 * @since 3.5.0
471 *
472 * @param Controls_Manager $this The controls manager.
473 */
474 do_action( 'elementor/controls/register', $this );
475 }
476
477 /**
478 * Register control.
479 *
480 * This method adds a new control to the controls list. It adds any given
481 * control to any given control instance.
482 *
483 * @since 1.0.0
484 * @access public
485 * @deprecated 3.5.0 Use `$this->register()` instead.
486 *
487 * @param string $control_id Control ID.
488 * @param Base_Control $control_instance Control instance, usually the
489 * current instance.
490 */
491 public function register_control( $control_id, Base_Control $control_instance ) {
492 // TODO: Uncomment when Pro uses the new hook.
493 //Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function(
494 // __METHOD__,
495 // '3.5.0',
496 // 'register'
497 //);
498
499 $this->register( $control_instance, $control_id );
500 }
501
502 /**
503 * Register control.
504 *
505 * This method adds a new control to the controls list. It adds any given
506 * control to any given control instance.
507 *
508 * @since 3.5.0
509 * @access public
510 *
511 * @param Base_Control $control_instance Control instance, usually the current instance.
512 * @param string $control_id Control ID. Deprecated parameter.
513 *
514 * @return void
515 */
516 public function register( Base_Control $control_instance, $control_id = null ) {
517 // TODO: Uncomment when Pro uses the new hook.
518
519 // TODO: For BC. Remove in the future.
520 //if ( $control_id ) {
521 // Plugin::instance()->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_argument(
522 // '$control_id', '3.5.0'
523 // );
524 //} else {
525 //}
526
527 $control_id = $control_instance->get_type();
528
529 $this->controls[ $control_id ] = $control_instance;
530 }
531
532 /**
533 * Unregister control.
534 *
535 * This method removes control from the controls list.
536 *
537 * @since 1.0.0
538 * @access public
539 * @deprecated 3.5.0 Use `$this->unregister()` instead.
540 *
541 * @param string $control_id Control ID.
542 *
543 * @return bool True if the control was removed, False otherwise.
544 */
545 public function unregister_control( $control_id ) {
546 // TODO: Uncomment when Pro uses the new hook.
547 //Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function(
548 // __METHOD__,
549 // '3.5.0',
550 // 'unregister'
551 //);
552
553 return $this->unregister( $control_id );
554 }
555
556 /**
557 * Unregister control.
558 *
559 * This method removes control from the controls list.
560 *
561 * @since 3.5.0
562 * @access public
563 *
564 * @param string $control_id Control ID.
565 *
566 * @return bool Whether the controls has been unregistered.
567 */
568 public function unregister( $control_id ) {
569 if ( ! isset( $this->controls[ $control_id ] ) ) {
570 return false;
571 }
572
573 unset( $this->controls[ $control_id ] );
574
575 return true;
576 }
577
578 /**
579 * Get controls.
580 *
581 * Retrieve the controls list from the current instance.
582 *
583 * @since 1.0.0
584 * @access public
585 *
586 * @return Base_Control[] Controls list.
587 */
588 public function get_controls() {
589 if ( null === $this->controls ) {
590 $this->register_controls();
591 }
592
593 return $this->controls;
594 }
595
596 /**
597 * Get control.
598 *
599 * Retrieve a specific control from the current controls instance.
600 *
601 * @since 1.0.0
602 * @access public
603 *
604 * @param string $control_id Control ID.
605 *
606 * @return bool|Base_Control Control instance, or False otherwise.
607 */
608 public function get_control( $control_id ) {
609 $controls = $this->get_controls();
610
611 return isset( $controls[ $control_id ] ) ? $controls[ $control_id ] : false;
612 }
613
614 /**
615 * Get controls data.
616 *
617 * Retrieve all the registered controls and all the data for each control.
618 *
619 * @since 1.0.0
620 * @access public
621 *
622 * @return array {
623 * Control data.
624 *
625 * @type array $name Control data.
626 * }
627 */
628 public function get_controls_data() {
629 $controls_data = [];
630
631 foreach ( $this->get_controls() as $name => $control ) {
632 $controls_data[ $name ] = $control->get_settings();
633 }
634
635 return $controls_data;
636 }
637
638 /**
639 * Render controls.
640 *
641 * Generate the final HTML for all the registered controls using the element
642 * template.
643 *
644 * @since 1.0.0
645 * @access public
646 */
647 public function render_controls() {
648 foreach ( $this->get_controls() as $control ) {
649 $control->print_template();
650 }
651 }
652
653 /**
654 * Get control groups.
655 *
656 * Retrieve a specific group for a given ID, or a list of all the control
657 * groups.
658 *
659 * If the given group ID is wrong, it will return `null`. When the ID valid,
660 * it will return the group control instance. When no ID was given, it will
661 * return all the control groups.
662 *
663 * @since 1.0.10
664 * @access public
665 *
666 * @param string $id Optional. Group ID. Default is null.
667 *
668 * @return null|Group_Control_Base|Group_Control_Base[]
669 */
670 public function get_control_groups( $id = null ) {
671 if ( $id ) {
672 return isset( $this->control_groups[ $id ] ) ? $this->control_groups[ $id ] : null;
673 }
674
675 return $this->control_groups;
676 }
677
678 /**
679 * Add group control.
680 *
681 * This method adds a new group control to the control groups list. It adds
682 * any given group control to any given group control instance.
683 *
684 * @since 1.0.0
685 * @access public
686 *
687 * @param string $id Group control ID.
688 * @param Group_Control_Base $instance Group control instance, usually the
689 * current instance.
690 *
691 * @return Group_Control_Base Group control instance.
692 */
693 public function add_group_control( $id, $instance ) {
694 $this->control_groups[ $id ] = $instance;
695
696 return $instance;
697 }
698
699 /**
700 * Enqueue control scripts and styles.
701 *
702 * Used to register and enqueue custom scripts and styles used by the control.
703 *
704 * @since 1.0.0
705 * @access public
706 */
707 public function enqueue_control_scripts() {
708 foreach ( $this->get_controls() as $control ) {
709 $control->enqueue();
710 }
711 }
712
713 /**
714 * Open new stack.
715 *
716 * This method adds a new stack to the control stacks list. It adds any
717 * given stack to the current control instance.
718 *
719 * @since 1.0.0
720 * @access public
721 *
722 * @param Controls_Stack $controls_stack Controls stack.
723 */
724 public function open_stack( Controls_Stack $controls_stack ) {
725 $stack_id = $controls_stack->get_unique_name();
726
727 $this->stacks[ $stack_id ] = [
728 'tabs' => [],
729 'controls' => [],
730 ];
731 }
732
733 /**
734 * Add control to stack.
735 *
736 * This method adds a new control to the stack.
737 *
738 * @since 1.0.0
739 * @access public
740 *
741 * @param Controls_Stack $element Element stack.
742 * @param string $control_id Control ID.
743 * @param array $control_data Control data.
744 * @param array $options Optional. Control additional options.
745 * Default is an empty array.
746 *
747 * @return bool True if control added, False otherwise.
748 */
749 public function add_control_to_stack( Controls_Stack $element, $control_id, $control_data, $options = [] ) {
750 $default_options = [
751 'overwrite' => false,
752 'index' => null,
753 ];
754
755 $options = array_merge( $default_options, $options );
756
757 $default_args = [
758 'type' => self::TEXT,
759 'tab' => self::TAB_CONTENT,
760 ];
761
762 $control_data['name'] = $control_id;
763
764 $control_data = array_merge( $default_args, $control_data );
765
766 $control_type_instance = $this->get_control( $control_data['type'] );
767
768 if ( ! $control_type_instance ) {
769 _doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Control type "%s" not found.', esc_html( $control_data['type'] ) ), '1.0.0' );
770 return false;
771 }
772
773 if ( $control_type_instance instanceof Base_Data_Control ) {
774 $control_default_value = $control_type_instance->get_default_value();
775
776 if ( is_array( $control_default_value ) ) {
777 $control_data['default'] = isset( $control_data['default'] ) ? array_merge( $control_default_value, $control_data['default'] ) : $control_default_value;
778 } else {
779 $control_data['default'] = isset( $control_data['default'] ) ? $control_data['default'] : $control_default_value;
780 }
781 }
782
783 $stack_id = $element->get_unique_name();
784
785 if ( ! $options['overwrite'] && isset( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
786 _doing_it_wrong( sprintf( '%1$s::%2$s', __CLASS__, __FUNCTION__ ), sprintf( 'Cannot redeclare control with same name "%s".', esc_html( $control_id ) ), '1.0.0' );
787
788 return false;
789 }
790
791 $tabs = self::get_tabs();
792
793 if ( ! isset( $tabs[ $control_data['tab'] ] ) ) {
794 $control_data['tab'] = $default_args['tab'];
795 }
796
797 $this->stacks[ $stack_id ]['tabs'][ $control_data['tab'] ] = $tabs[ $control_data['tab'] ];
798
799 $this->stacks[ $stack_id ]['controls'][ $control_id ] = $control_data;
800
801 if ( null !== $options['index'] ) {
802 $controls = $this->stacks[ $stack_id ]['controls'];
803
804 $controls_keys = array_keys( $controls );
805
806 array_splice( $controls_keys, $options['index'], 0, $control_id );
807
808 $this->stacks[ $stack_id ]['controls'] = array_merge( array_flip( $controls_keys ), $controls );
809 }
810
811 return true;
812 }
813
814 /**
815 * Remove control from stack.
816 *
817 * This method removes a control a the stack.
818 *
819 * @since 1.0.0
820 * @access public
821 *
822 * @param string $stack_id Stack ID.
823 * @param array|string $control_id The ID of the control to remove.
824 *
825 * @return bool|\WP_Error True if the stack was removed, False otherwise.
826 */
827 public function remove_control_from_stack( $stack_id, $control_id ) {
828 if ( is_array( $control_id ) ) {
829 foreach ( $control_id as $id ) {
830 $this->remove_control_from_stack( $stack_id, $id );
831 }
832
833 return true;
834 }
835
836 if ( empty( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
837 return new \WP_Error( 'Cannot remove not-exists control.' );
838 }
839
840 unset( $this->stacks[ $stack_id ]['controls'][ $control_id ] );
841
842 return true;
843 }
844
845 /**
846 * Get control from stack.
847 *
848 * Retrieve a specific control for a given a specific stack.
849 *
850 * If the given control does not exist in the stack, or the stack does not
851 * exist, it will return `WP_Error`. Otherwise, it will retrieve the control
852 * from the stack.
853 *
854 * @since 1.1.0
855 * @access public
856 *
857 * @param string $stack_id Stack ID.
858 * @param string $control_id Control ID.
859 *
860 * @return array|\WP_Error The control, or an error.
861 */
862 public function get_control_from_stack( $stack_id, $control_id ) {
863 if ( empty( $this->stacks[ $stack_id ]['controls'][ $control_id ] ) ) {
864 return new \WP_Error( 'Cannot get a not-exists control.' );
865 }
866
867 return $this->stacks[ $stack_id ]['controls'][ $control_id ];
868 }
869
870 /**
871 * Update control in stack.
872 *
873 * This method updates the control data for a given stack.
874 *
875 * @since 1.1.0
876 * @access public
877 *
878 * @param Controls_Stack $element Element stack.
879 * @param string $control_id Control ID.
880 * @param array $control_data Control data.
881 * @param array $options Optional. Control additional options.
882 * Default is an empty array.
883 *
884 * @return bool True if control updated, False otherwise.
885 */
886 public function update_control_in_stack( Controls_Stack $element, $control_id, $control_data, array $options = [] ) {
887 $old_control_data = $this->get_control_from_stack( $element->get_unique_name(), $control_id );
888
889 if ( is_wp_error( $old_control_data ) ) {
890 return false;
891 }
892
893 if ( ! empty( $options['recursive'] ) ) {
894 $control_data = array_replace_recursive( $old_control_data, $control_data );
895 } else {
896 $control_data = array_merge( $old_control_data, $control_data );
897 }
898
899 return $this->add_control_to_stack( $element, $control_id, $control_data, [
900 'overwrite' => true,
901 ] );
902 }
903
904 /**
905 * Get stacks.
906 *
907 * Retrieve a specific stack for the list of stacks.
908 *
909 * If the given stack is wrong, it will return `null`. When the stack valid,
910 * it will return the the specific stack. When no stack was given, it will
911 * return all the stacks.
912 *
913 * @since 1.7.1
914 * @access public
915 *
916 * @param string $stack_id Optional. stack ID. Default is null.
917 *
918 * @return null|array A list of stacks.
919 */
920 public function get_stacks( $stack_id = null ) {
921 if ( $stack_id ) {
922 if ( isset( $this->stacks[ $stack_id ] ) ) {
923 return $this->stacks[ $stack_id ];
924 }
925
926 return null;
927 }
928
929 return $this->stacks;
930 }
931
932 /**
933 * Get element stack.
934 *
935 * Retrieve a specific stack for the list of stacks from the current instance.
936 *
937 * @since 1.0.0
938 * @access public
939 *
940 * @param Controls_Stack $controls_stack Controls stack.
941 *
942 * @return null|array Stack data if it exist, `null` otherwise.
943 */
944 public function get_element_stack( Controls_Stack $controls_stack ) {
945 $stack_id = $controls_stack->get_unique_name();
946
947 if ( ! isset( $this->stacks[ $stack_id ] ) ) {
948 return null;
949 }
950
951 return $this->stacks[ $stack_id ];
952 }
953
954 /**
955 * Add custom CSS controls.
956 *
957 * This method adds a new control for the "Custom CSS" feature. The free
958 * version of elementor uses this method to display an upgrade message to
959 * Elementor Pro.
960 *
961 * @since 1.0.0
962 * @access public
963 *
964 * @param Controls_Stack $controls_stack .
965 * @param string $tab
966 * @param array $additional_messages
967 *
968 */
969 public function add_custom_css_controls( Controls_Stack $controls_stack, $tab = self::TAB_ADVANCED, $additional_messages = [] ) {
970 $controls_stack->start_controls_section(
971 'section_custom_css_pro',
972 [
973 'label' => esc_html__( 'Custom CSS', 'elementor' ),
974 'tab' => $tab,
975 ]
976 );
977
978 $messages = [
979 esc_html__( 'Custom CSS lets you add CSS code to any widget, and see it render live right in the editor.', 'elementor' ),
980 ];
981
982 if ( $additional_messages ) {
983 $messages = array_merge( $messages, $additional_messages );
984 }
985
986 $controls_stack->add_control(
987 'custom_css_pro',
988 [
989 'type' => self::RAW_HTML,
990 'raw' => $this->get_teaser_template( [
991 'title' => esc_html__( 'Meet Our Custom CSS', 'elementor' ),
992 'messages' => $messages,
993 'link' => 'https://elementor.com/pro/?utm_source=panel-custom-css&utm_campaign=gopro&utm_medium=wp-dash',
994 ] ),
995 ]
996 );
997
998 $controls_stack->end_controls_section();
999 }
1000
1001 /**
1002 * Add Page Transitions controls.
1003 *
1004 * This method adds a new control for the "Page Transitions" feature. The Core
1005 * version of elementor uses this method to display an upgrade message to
1006 * Elementor Pro.
1007 *
1008 * @param Controls_Stack $controls_stack .
1009 * @param string $tab
1010 * @param array $additional_messages
1011 *
1012 * @return void
1013 */
1014 public function add_page_transitions_controls( Controls_Stack $controls_stack, $tab = self::TAB_ADVANCED, $additional_messages = [] ) {
1015 $controls_stack->start_controls_section(
1016 'section_page_transitions_teaser',
1017 [
1018 'label' => esc_html__( 'Page Transitions', 'elementor' ),
1019 'tab' => $tab,
1020 ]
1021 );
1022
1023 $messages = [
1024 esc_html__( 'Page Transitions let you style entrance and exit animations between pages as well as display loader until your page assets load.', 'elementor' ),
1025 ];
1026
1027 if ( $additional_messages ) {
1028 $messages = array_merge( $messages, $additional_messages );
1029 }
1030
1031 $controls_stack->add_control(
1032 'page_transitions_teaser',
1033 [
1034 'type' => self::RAW_HTML,
1035 'raw' => $this->get_teaser_template( [
1036 'title' => esc_html__( 'Meet Page Transitions', 'elementor' ),
1037 'messages' => $messages,
1038 'link' => 'https://elementor.com/pro/?utm_source=panel-page-transitions&utm_campaign=gopro&utm_medium=wp-dash',
1039 ] ),
1040 ]
1041 );
1042
1043 $controls_stack->end_controls_section();
1044 }
1045
1046 public function get_teaser_template( $texts ) {
1047 ob_start();
1048 ?>
1049 <div class="elementor-nerd-box">
1050 <img class="elementor-nerd-box-icon" src="<?php echo esc_url( ELEMENTOR_ASSETS_URL . 'images/go-pro.svg' ); ?>" />
1051 <div class="elementor-nerd-box-title"><?php Utils::print_unescaped_internal_string( $texts['title'] ); ?></div>
1052 <?php foreach ( $texts['messages'] as $message ) { ?>
1053 <div class="elementor-nerd-box-message"><?php Utils::print_unescaped_internal_string( $message ); ?></div>
1054 <?php }
1055
1056 // Show a `Go Pro` button only if the user doesn't have Pro.
1057 if ( $texts['link'] && ! Utils::has_pro() ) { ?>
1058 <a class="elementor-nerd-box-link elementor-button elementor-button-default elementor-button-go-pro" href="<?php echo esc_url( Utils::get_pro_link( $texts['link'] ) ); ?>" target="_blank">
1059 <?php echo esc_html__( 'Go Pro', 'elementor' ); ?>
1060 </a>
1061 <?php } ?>
1062 </div>
1063 <?php
1064
1065 return ob_get_clean();
1066 }
1067
1068 /**
1069 * Add custom attributes controls.
1070 *
1071 * This method adds a new control for the "Custom Attributes" feature. The free
1072 * version of elementor uses this method to display an upgrade message to
1073 * Elementor Pro.
1074 *
1075 * @since 2.8.3
1076 * @access public
1077 *
1078 * @param Controls_Stack $controls_stack.
1079 */
1080 public function add_custom_attributes_controls( Controls_Stack $controls_stack ) {
1081 $controls_stack->start_controls_section(
1082 'section_custom_attributes_pro',
1083 [
1084 'label' => esc_html__( 'Attributes', 'elementor' ),
1085 'tab' => self::TAB_ADVANCED,
1086 ]
1087 );
1088
1089 $controls_stack->add_control(
1090 'custom_attributes_pro',
1091 [
1092 'type' => self::RAW_HTML,
1093 'raw' => $this->get_teaser_template( [
1094 'title' => esc_html__( 'Meet Our Attributes', 'elementor' ),
1095 'messages' => [
1096 esc_html__( 'Attributes lets you add custom HTML attributes to any element.', 'elementor' ),
1097 ],
1098 'link' => 'https://elementor.com/pro/?utm_source=panel-custom-attributes&utm_campaign=gopro&utm_medium=wp-dash',
1099 ] ),
1100 ]
1101 );
1102
1103 $controls_stack->end_controls_section();
1104 }
1105 }
1106