PluginProbe
Elementor Website Builder – more than just a page builder / 4.2.4
Elementor Website Builder – more than just a page builder v4.2.4
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.2.4, at includes/managers/elements.php

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