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

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