PluginProbe
Elementor Website Builder – more than just a page builder / 4.0.9
Elementor Website Builder – more than just a page builder v4.0.9
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 / elements.php

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

466 lines 11.6 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 use Elementor\Includes\Elements\Container;
5
6 if ( ! defined( 'ABSPATH' ) ) {
7 exit; // Exit if accessed directly.
8 }
9
10 /**
11 * Elementor elements manager.
12 *
13 * Elementor elements manager handler class is responsible for registering and
14 * initializing all the supported elements.
15 *
16 * @since 1.0.0
17 */
18 class Elements_Manager {
19
20 const CATEGORY_ATOMIC_ELEMENTS = 'v4-elements';
21 const CATEGORY_ATOMIC_FORM = 'atomic-form';
22 const CATEGORY_FAVORITES = 'favorites';
23 const CATEGORY_ANGIE_WIDGETS = 'angie-widgets';
24 const CATEGORY_CUSTOM_WIDGETS = 'custom-widgets';
25 const CATEGORY_BASIC = 'basic';
26
27 /**
28 * Element types.
29 *
30 * Holds the list of all the element types.
31 *
32 * @access private
33 *
34 * @var Element_Base[]
35 */
36 private $_element_types;
37
38 /**
39 * Element categories.
40 *
41 * Holds the list of all the element categories.
42 *
43 * @access private
44 *
45 * @var $categories
46 */
47 private $categories;
48
49 /**
50 * Elements constructor.
51 *
52 * Initializing Elementor elements manager.
53 *
54 * @since 1.0.0
55 * @access public
56 */
57 public function __construct() {
58 $this->require_files();
59 }
60
61 /**
62 * Create element instance.
63 *
64 * This method creates a new element instance for any given element.
65 *
66 * @since 1.0.0
67 * @access public
68 *
69 * @param array $element_data Element data.
70 * @param array $element_args Optional. Element arguments. Default is
71 * an empty array.
72 * @param Element_Base $element_type Optional. Element type. Default is null.
73 *
74 * @return Element_Base|null Element instance if element created, or null
75 * otherwise.
76 */
77 public function create_element_instance( array $element_data, array $element_args = [], ?Element_Base $element_type = null ) {
78 if ( null === $element_type ) {
79 $element_type = $this->get_element( $element_data['elType'], isset( $element_data['widgetType'] ) ? $element_data['widgetType'] : null );
80 }
81
82 if ( ! $element_type ) {
83 return null;
84 }
85
86 $args = array_merge( $element_type->get_default_args(), $element_args );
87
88 $element_class = $element_type->get_class_name();
89
90 try {
91 $element = new $element_class( $element_data, $args );
92 } catch ( \Exception $e ) {
93 return null;
94 }
95
96 return $element;
97 }
98
99 public function get_element( string $el_type, ?string $widget_type = null ) {
100 $element = null;
101
102 if ( 'widget' === $el_type ) {
103 $element = Plugin::$instance->widgets_manager->get_widget_types( $widget_type );
104 } else {
105 $element = $this->get_element_types( $el_type );
106 }
107
108 return $element;
109 }
110
111 /**
112 * Get element categories.
113 *
114 * Retrieve the list of categories the element belongs to.
115 *
116 * @since 1.0.0
117 * @access public
118 *
119 * @return array Element categories.
120 */
121 public function get_categories() {
122 if ( null === $this->categories ) {
123 $this->init_categories();
124 }
125
126 return $this->categories;
127 }
128
129 /**
130 * Add element category.
131 *
132 * Register new category for the element.
133 *
134 * @since 1.7.12
135 * @access public
136 *
137 * @param string $category_name Category name.
138 * @param array $category_properties Category properties.
139 */
140 public function add_category( $category_name, $category_properties ) {
141 if ( null === $this->categories ) {
142 $this->get_categories();
143 }
144
145 if ( ! isset( $this->categories[ $category_name ] ) ) {
146 $this->categories[ $category_name ] = $category_properties;
147 }
148 }
149
150 /**
151 * Register element type.
152 *
153 * Add new type to the list of registered types.
154 *
155 * @since 1.0.0
156 * @access public
157 *
158 * @param Element_Base $element Element instance.
159 *
160 * @return bool Whether the element type was registered.
161 */
162 public function register_element_type( Element_Base $element ) {
163 $this->_element_types[ $element->get_name() ] = $element;
164
165 return true;
166 }
167
168 /**
169 * Unregister element type.
170 *
171 * Remove element type from the list of registered types.
172 *
173 * @since 1.0.0
174 * @access public
175 *
176 * @param string $name Element name.
177 *
178 * @return bool Whether the element type was unregister, or not.
179 */
180 public function unregister_element_type( $name ) {
181 if ( ! isset( $this->_element_types[ $name ] ) ) {
182 return false;
183 }
184
185 unset( $this->_element_types[ $name ] );
186
187 return true;
188 }
189
190 /**
191 * Get element types.
192 *
193 * Retrieve the list of all the element types, or if a specific element name
194 * was provided retrieve his element types.
195 *
196 * @since 1.0.0
197 * @access public
198 *
199 * @param string $element_name Optional. Element name. Default is null.
200 *
201 * @return null|Element_Base|Element_Base[] Element types, or a list of all the element
202 * types, or null if element does not exist.
203 */
204 public function get_element_types( $element_name = null ) {
205 if ( is_null( $this->_element_types ) ) {
206 $this->init_elements();
207 }
208
209 if ( null !== $element_name ) {
210 return isset( $this->_element_types[ $element_name ] ) ? $this->_element_types[ $element_name ] : null;
211 }
212
213 return $this->_element_types;
214 }
215
216 /**
217 * Get element types config.
218 *
219 * Retrieve the config of all the element types.
220 *
221 * @since 1.0.0
222 * @access public
223 *
224 * @return array Element types config.
225 */
226 public function get_element_types_config() {
227 $config = [];
228
229 foreach ( $this->get_element_types() as $element ) {
230 $config[ $element->get_name() ] = $element->get_config();
231 }
232
233 return $config;
234 }
235
236 /**
237 * Render elements content.
238 *
239 * Used to generate the elements templates on the editor.
240 *
241 * @since 1.0.0
242 * @access public
243 */
244 public function render_elements_content() {
245 foreach ( $this->get_element_types() as $element_type ) {
246 $element_type->print_template();
247 }
248 }
249
250 /**
251 * Init elements.
252 *
253 * Initialize Elementor elements by registering the supported elements.
254 * Elementor supports by default `section` element and `column` element.
255 *
256 * @since 2.0.0
257 * @access private
258 */
259 private function init_elements() {
260 $this->_element_types = [];
261
262 foreach ( [ 'section', 'column' ] as $element_name ) {
263 $class_name = __NAMESPACE__ . '\Element_' . $element_name;
264
265 $this->register_element_type( new $class_name() );
266 }
267
268 $experiments_manager = Plugin::$instance->experiments;
269
270 if ( $experiments_manager->is_feature_active( 'container' ) ) {
271 $this->register_element_type( new Container() );
272 }
273
274 /**
275 * After elements registered.
276 *
277 * Fires after Elementor elements are registered.
278 *
279 * @since 1.0.0
280 */
281 do_action( 'elementor/elements/elements_registered', $this );
282 }
283
284 /**
285 * Init categories.
286 *
287 * Initialize the element categories.
288 *
289 * @since 1.7.12
290 * @access private
291 */
292 private function init_categories() {
293 $this->categories = [
294 self::CATEGORY_ATOMIC_ELEMENTS => [
295 'title' => esc_html__( 'Atomic Elements', 'elementor' ),
296 'hideIfEmpty' => true,
297 ],
298 'layout' => [
299 'title' => esc_html__( 'Layout', 'elementor' ),
300 'hideIfEmpty' => true,
301 ],
302 'basic' => [
303 'title' => esc_html__( 'Basic', 'elementor' ),
304 'icon' => 'eicon-font',
305 ],
306 'pro-elements' => [
307 'title' => esc_html__( 'Pro', 'elementor' ),
308 'promotion' => [
309 'url' => esc_url( 'https://go.elementor.com/go-pro-section-pro-widget-panel/' ),
310 ],
311 ],
312 'helloplus' => [
313 'title' => esc_html__( 'Hello+', 'elementor' ),
314 'hideIfEmpty' => true,
315 ],
316 'general' => [
317 'title' => esc_html__( 'General', 'elementor' ),
318 'icon' => 'eicon-font',
319 ],
320 'link-in-bio' => [
321 'title' => esc_html__( 'Link In Bio', 'elementor' ),
322 'hideIfEmpty' => true,
323 ],
324 'theme-elements' => [
325 'title' => esc_html__( 'Site', 'elementor' ),
326 'active' => false,
327 'promotion' => [
328 'url' => esc_url( 'https://go.elementor.com/go-pro-section-site-widget-panel/' ),
329 ],
330 ],
331 'woocommerce-elements' => [
332 'title' => esc_html__( 'WooCommerce', 'elementor' ),
333 'active' => false,
334 'promotion' => [
335 'url' => esc_url( 'https://go.elementor.com/go-pro-section-woocommerce-widget-panel/' ),
336 ],
337 ],
338 ];
339
340 if ( Plugin::$instance->experiments->is_feature_active( 'e_atomic_elements' ) ) {
341 $atomic_form_category = [
342 'title' => esc_html__( 'Atomic Form', 'elementor' ),
343 ];
344
345 if ( Utils::has_pro() && Plugin::$instance->experiments->is_feature_active( 'e_pro_atomic_form' ) ) {
346 $atomic_form_category['hideIfEmpty'] = true;
347 } elseif ( ! Utils::has_pro() ) {
348 $atomic_form_category['hideIfEmpty'] = false;
349 $atomic_form_category['promotion'] = [
350 'url' => esc_url( 'https://go.elementor.com/go-pro-atomic-form-section/' ),
351 ];
352 } else {
353 $atomic_form_category['hideIfEmpty'] = true;
354 }
355
356 $this->categories = array_merge(
357 [ self::CATEGORY_ATOMIC_ELEMENTS => $this->categories[ self::CATEGORY_ATOMIC_ELEMENTS ] ],
358 [ self::CATEGORY_ATOMIC_FORM => $atomic_form_category ],
359 array_diff_key( $this->categories, [ self::CATEGORY_ATOMIC_ELEMENTS => true ] )
360 );
361 }
362
363 // Not using the `add_category` because it doesn't allow 3rd party to inject a category on top the others.
364 $this->categories = array_merge_recursive( [
365 self::CATEGORY_FAVORITES => [
366 'title' => esc_html__( 'Favorites', 'elementor' ),
367 'icon' => 'eicon-heart',
368 'sort' => 'a-z',
369 'hideIfEmpty' => false,
370 ],
371 ], $this->categories );
372
373 /**
374 * When categories are registered.
375 *
376 * Fires after basic categories are registered, before WordPress
377 * category have been registered.
378 *
379 * This is where categories registered by external developers are
380 * added.
381 *
382 * @since 2.0.0
383 *
384 * @param Elements_Manager $this Elements manager instance.
385 */
386 do_action( 'elementor/elements/categories_registered', $this );
387
388 $after_candidates = Plugin::$instance->experiments->is_feature_active( 'e_atomic_elements' )
389 ? [ self::CATEGORY_ATOMIC_FORM, self::CATEGORY_ATOMIC_ELEMENTS ]
390 : [ self::CATEGORY_BASIC ];
391
392 $this->promote_category_after( self::CATEGORY_ANGIE_WIDGETS, $after_candidates );
393 $this->promote_category_after( self::CATEGORY_CUSTOM_WIDGETS, $after_candidates );
394
395 $this->categories['wordpress'] = [
396 'title' => esc_html__( 'WordPress', 'elementor' ),
397 'icon' => 'eicon-wordpress',
398 'active' => false,
399 ];
400 }
401
402 public function enqueue_elements_styles() {
403 foreach ( $this->get_element_types() as $element ) {
404 $element->enqueue_styles();
405 }
406 }
407
408 public function enqueue_elements_scripts() {
409 foreach ( $this->get_element_types() as $element ) {
410 $element->enqueue_scripts();
411 }
412 }
413
414 public function register_frontend_handlers() {
415 foreach ( $this->get_element_types() as $element ) {
416 $element->register_frontend_handlers();
417 }
418 }
419
420 private function promote_category_after( string $category_name, array $after_candidates ): void {
421 if ( ! isset( $this->categories[ $category_name ] ) ) {
422 return;
423 }
424
425 $after = null;
426
427 foreach ( $after_candidates as $candidate ) {
428 if ( isset( $this->categories[ $candidate ] ) ) {
429 $after = $candidate;
430 break;
431 }
432 }
433
434 if ( ! $after ) {
435 return;
436 }
437
438 $category = $this->categories[ $category_name ];
439 unset( $this->categories[ $category_name ] );
440
441 $position = array_search( $after, array_keys( $this->categories ), true ) + 1;
442 $this->categories = array_merge(
443 array_slice( $this->categories, 0, $position, true ),
444 [ $category_name => $category ],
445 array_slice( $this->categories, $position, null, true )
446 );
447 }
448
449 /**
450 * Require files.
451 *
452 * Require Elementor element base class and column, section and repeater
453 * elements.
454 *
455 * @since 1.0.0
456 * @access private
457 */
458 private function require_files() {
459 require_once ELEMENTOR_PATH . 'includes/base/element-base.php';
460
461 require ELEMENTOR_PATH . 'includes/elements/column.php';
462 require ELEMENTOR_PATH . 'includes/elements/section.php';
463 require ELEMENTOR_PATH . 'includes/elements/repeater.php';
464 }
465 }
466