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

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