PluginProbe
Elementor Website Builder – more than just a page builder / 3.31.2
Elementor Website Builder – more than just a page builder v3.31.2
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 / modules / atomic-widgets / elements / has-atomic-base.php

has-atomic-base.php in Elementor Website Builder – more than just a page builder 3.31.2, at modules/atomic-widgets/elements/has-atomic-base.php

222 lines 5.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Elementor\Modules\AtomicWidgets\Elements;
4
5 use Elementor\Element_Base;
6 use Elementor\Modules\AtomicWidgets\Base\Atomic_Control_Base;
7 use Elementor\Modules\AtomicWidgets\Controls\Section;
8 use Elementor\Modules\AtomicWidgets\PropsResolver\Render_Props_Resolver;
9 use Elementor\Modules\AtomicWidgets\PropTypes\Contracts\Prop_Type;
10 use Elementor\Modules\AtomicWidgets\Styles\Style_Schema;
11 use Elementor\Modules\AtomicWidgets\Parsers\Props_Parser;
12 use Elementor\Modules\AtomicWidgets\Parsers\Style_Parser;
13 use Elementor\Modules\AtomicWidgets\Module;
14 use Elementor\Modules\AtomicWidgets\Controls\Types\Text_Control;
15 use Elementor\Modules\AtomicWidgets\PropTypes\Primitives\String_Prop_Type;
16 use Elementor\Plugin;
17 use Elementor\Utils;
18
19 if ( ! defined( 'ABSPATH' ) ) {
20 exit; // Exit if accessed directly.
21 }
22
23 /**
24 * @mixin Element_Base
25 */
26 trait Has_Atomic_Base {
27 use Has_Base_Styles;
28
29 public function has_widget_inner_wrapper(): bool {
30 return false;
31 }
32
33 abstract public static function get_element_type(): string;
34
35 final public function get_name() {
36 return static::get_element_type();
37 }
38
39 private function get_valid_controls( array $schema, array $controls ): array {
40 $valid_controls = [];
41
42 foreach ( $controls as $control ) {
43 if ( $control instanceof Section ) {
44 $cloned_section = clone $control;
45
46 $cloned_section->set_items(
47 $this->get_valid_controls( $schema, $control->get_items() )
48 );
49
50 $valid_controls[] = $cloned_section;
51 continue;
52 }
53
54 if ( ! ( $control instanceof Atomic_Control_Base ) ) {
55 Utils::safe_throw( 'Control must be an instance of `Atomic_Control_Base`.' );
56 continue;
57 }
58
59 $prop_name = $control->get_bind();
60
61 if ( ! $prop_name ) {
62 Utils::safe_throw( 'Control is missing a bound prop from the schema.' );
63 continue;
64 }
65
66 if ( ! array_key_exists( $prop_name, $schema ) ) {
67 Utils::safe_throw( "Prop `{$prop_name}` is not defined in the schema of `{$this->get_name()}`." );
68 continue;
69 }
70
71 $valid_controls[] = $control;
72 }
73
74 return $valid_controls;
75 }
76
77 private static function validate_schema( array $schema ) {
78 $widget_name = static::class;
79
80 foreach ( $schema as $key => $prop ) {
81 if ( ! ( $prop instanceof Prop_Type ) ) {
82 Utils::safe_throw( "Prop `$key` must be an instance of `Prop_Type` in `{$widget_name}`." );
83 }
84 }
85 }
86
87 private function parse_atomic_styles( array $styles ): array {
88 $style_parser = Style_Parser::make( Style_Schema::get() );
89
90 foreach ( $styles as $style_id => $style ) {
91 $result = $style_parser->parse( $style );
92
93 if ( ! $result->is_valid() ) {
94 throw new \Exception( esc_html( "Styles validation failed for style `$style_id`. " . $result->errors()->to_string() ) );
95 }
96
97 $styles[ $style_id ] = $result->unwrap();
98 }
99
100 return $styles;
101 }
102
103 private function parse_atomic_settings( array $settings ): array {
104 $schema = static::get_props_schema();
105 $props_parser = Props_Parser::make( $schema );
106
107 $result = $props_parser->parse( $settings );
108
109 if ( ! $result->is_valid() ) {
110 throw new \Exception( esc_html( 'Settings validation failed. ' . $result->errors()->to_string() ) );
111 }
112
113 return $result->unwrap();
114 }
115
116 public function get_atomic_controls() {
117 $controls = apply_filters(
118 'elementor/atomic-widgets/controls',
119 $this->combine_controls(),
120 $this
121 );
122
123 $schema = static::get_props_schema();
124
125 // Validate the schema only in the Editor.
126 static::validate_schema( $schema );
127
128 return $this->get_valid_controls( $schema, $controls );
129 }
130
131 protected function combine_controls(): array {
132 $common_settings_controls = [
133 Text_Control::bind_to( '_cssid' )
134 ->set_label( __( 'ID', 'elementor' ) )
135 ->set_meta( $this->get_css_id_control_meta() ),
136 ];
137
138 return array_merge(
139 $this->define_atomic_controls(),
140 [
141 Section::make()
142 ->set_label( __( 'Settings', 'elementor' ) )
143 ->set_id( 'settings' )
144 ->set_items( array_merge( $this->get_settings_controls(), $common_settings_controls ) ),
145 ],
146 );
147 }
148
149 protected function get_css_id_control_meta(): array {
150 return [
151 'layout' => 'two-columns',
152 'topDivider' => true,
153 ];
154 }
155
156 protected function get_settings_controls(): array {
157 return [];
158 }
159
160 final public function get_controls( $control_id = null ) {
161 if ( ! empty( $control_id ) ) {
162 return null;
163 }
164
165 return [];
166 }
167
168 final public function get_data_for_save() {
169 $data = parent::get_data_for_save();
170
171 $data['version'] = $this->version;
172 $data['settings'] = $this->parse_atomic_settings( $data['settings'] );
173 $data['styles'] = $this->parse_atomic_styles( $data['styles'] );
174 $data['editor_settings'] = $this->parse_editor_settings( $data['editor_settings'] );
175
176 return $data;
177 }
178
179 final public function get_raw_data( $with_html_content = false ) {
180 $raw_data = parent::get_raw_data( $with_html_content );
181
182 $raw_data['styles'] = $this->styles;
183 $raw_data['editor_settings'] = $this->editor_settings;
184
185 return $raw_data;
186 }
187
188 final public function get_stack( $with_common_controls = true ) {
189 return [
190 'controls' => [],
191 'tabs' => [],
192 ];
193 }
194
195 public function get_atomic_settings(): array {
196 $schema = static::get_props_schema();
197 $props = $this->get_settings();
198
199 return Render_Props_Resolver::for_settings()->resolve( $schema, $props );
200 }
201
202 private function parse_editor_settings( array $data ): array {
203 $editor_data = [];
204
205 if ( isset( $data['title'] ) && is_string( $data['title'] ) ) {
206 $editor_data['title'] = sanitize_text_field( $data['title'] );
207 }
208
209 return $editor_data;
210 }
211
212 public static function get_props_schema(): array {
213 $schema = static::define_props_schema();
214 $schema['_cssid'] = String_Prop_Type::make();
215
216 return apply_filters(
217 'elementor/atomic-widgets/props-schema',
218 $schema
219 );
220 }
221 }
222