PluginProbe
Elementor Website Builder – more than just a page builder / 3.8.0-beta1
Elementor Website Builder – more than just a page builder v3.8.0-beta1
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 / widgets.php

widgets.php in Elementor Website Builder – more than just a page builder 3.8.0-beta1, at includes/managers/widgets.php

634 lines 14.1 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\Core\Common\Modules\Ajax\Module as Ajax;
5 use Elementor\Core\Utils\Collection;
6 use Elementor\Core\Utils\Exceptions;
7 use Elementor\Core\Utils\Force_Locale;
8
9 if ( ! defined( 'ABSPATH' ) ) {
10 exit; // Exit if accessed directly.
11 }
12
13 /**
14 * Elementor widgets manager.
15 *
16 * Elementor widgets manager handler class is responsible for registering and
17 * initializing all the supported Elementor widgets.
18 *
19 * @since 1.0.0
20 */
21 class Widgets_Manager {
22
23 /**
24 * Widget types.
25 *
26 * Holds the list of all the widget types.
27 *
28 * @since 1.0.0
29 * @access private
30 *
31 * @var Widget_Base[]
32 */
33 private $_widget_types = null;
34
35 /**
36 * Init widgets.
37 *
38 * Initialize Elementor widgets manager. Include all the the widgets files
39 * and register each Elementor and WordPress widget.
40 *
41 * @since 2.0.0
42 * @access private
43 */
44 private function init_widgets() {
45 $build_widgets_filename = [
46 'common',
47 'inner-section',
48 'heading',
49 'image',
50 'text-editor',
51 'video',
52 'button',
53 'divider',
54 'spacer',
55 'image-box',
56 'google-maps',
57 'icon',
58 'icon-box',
59 'star-rating',
60 'image-carousel',
61 'image-gallery',
62 'icon-list',
63 'counter',
64 'progress',
65 'testimonial',
66 'tabs',
67 'accordion',
68 'toggle',
69 'social-icons',
70 'alert',
71 'audio',
72 'shortcode',
73 'html',
74 'menu-anchor',
75 'sidebar',
76 'read-more',
77 ];
78
79 $this->_widget_types = [];
80
81 foreach ( $build_widgets_filename as $widget_filename ) {
82 include( ELEMENTOR_PATH . 'includes/widgets/' . $widget_filename . '.php' );
83
84 $class_name = str_replace( '-', '_', $widget_filename );
85
86 $class_name = __NAMESPACE__ . '\Widget_' . $class_name;
87
88 $this->register( new $class_name() );
89 }
90
91 $this->register_wp_widgets();
92
93 /**
94 * After widgets registered.
95 *
96 * Fires after Elementor widgets are registered.
97 *
98 * @since 1.0.0
99 * @deprecated 3.5.0 Use `elementor/widgets/register` hook instead.
100 *
101 * @param Widgets_Manager $this The widgets manager.
102 */
103 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->do_deprecated_action(
104 'elementor/widgets/widgets_registered',
105 [ $this ],
106 '3.5.0',
107 'elementor/widgets/register'
108 );
109
110 /**
111 * After widgets registered.
112 *
113 * Fires after Elementor widgets are registered.
114 *
115 * @since 3.5.0
116 *
117 * @param Widgets_Manager $this The widgets manager.
118 */
119 do_action( 'elementor/widgets/register', $this );
120 }
121
122 /**
123 * Register WordPress widgets.
124 *
125 * Add native WordPress widget to the list of registered widget types.
126 *
127 * Exclude the widgets that are in Elementor widgets black list. Theme and
128 * plugin authors can filter the black list.
129 *
130 * @since 2.0.0
131 * @access private
132 */
133 private function register_wp_widgets() {
134 global $wp_widget_factory;
135
136 // Skip Pojo widgets.
137 $pojo_allowed_widgets = [
138 'Pojo_Widget_Recent_Posts',
139 'Pojo_Widget_Posts_Group',
140 'Pojo_Widget_Gallery',
141 'Pojo_Widget_Recent_Galleries',
142 'Pojo_Slideshow_Widget',
143 'Pojo_Forms_Widget',
144 'Pojo_Widget_News_Ticker',
145
146 'Pojo_Widget_WC_Products',
147 'Pojo_Widget_WC_Products_Category',
148 'Pojo_Widget_WC_Product_Categories',
149 ];
150
151 // Allow themes/plugins to filter out their widgets.
152 $black_list = [];
153
154 /**
155 * Elementor widgets black list.
156 *
157 * Filters the widgets black list that won't be displayed in the panel.
158 *
159 * @since 1.0.0
160 *
161 * @param array $black_list A black list of widgets. Default is an empty array.
162 */
163 $black_list = apply_filters( 'elementor/widgets/black_list', $black_list );
164
165 foreach ( $wp_widget_factory->widgets as $widget_class => $widget_obj ) {
166
167 if ( in_array( $widget_class, $black_list ) ) {
168 continue;
169 }
170
171 if ( $widget_obj instanceof \Pojo_Widget_Base && ! in_array( $widget_class, $pojo_allowed_widgets ) ) {
172 continue;
173 }
174
175 $elementor_widget_class = __NAMESPACE__ . '\Widget_WordPress';
176
177 $this->register(
178 new $elementor_widget_class( [], [
179 'widget_name' => $widget_class,
180 ] )
181 );
182 }
183 }
184
185 /**
186 * Require files.
187 *
188 * Require Elementor widget base class.
189 *
190 * @since 2.0.0
191 * @access private
192 */
193 private function require_files() {
194 require ELEMENTOR_PATH . 'includes/base/widget-base.php';
195 }
196
197 private function pluck_default_controls( $controls ) {
198 return ( new Collection( $controls ) )
199 ->reduce( function ( $controls_defaults, $control, $control_key ) {
200 if ( ! empty( $control['default'] ) ) {
201 $controls_defaults[ $control_key ]['default'] = $control['default'];
202 }
203
204 return $controls_defaults;
205 }, [] );
206 }
207
208 /**
209 * Register widget type.
210 *
211 * Add a new widget type to the list of registered widget types.
212 *
213 * @since 1.0.0
214 * @access public
215 * @deprecated 3.5.0 Use `$this->register()` instead.
216 *
217 * @param Widget_Base $widget Elementor widget.
218 *
219 * @return true True if the widget was registered.
220 */
221 public function register_widget_type( Widget_Base $widget ) {
222 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function(
223 __METHOD__,
224 '3.5.0',
225 'register'
226 );
227
228 return $this->register( $widget );
229 }
230
231 /**
232 * Register a new widget type.
233 *
234 * @param \Elementor\Widget_Base $widget_instance Elementor Widget.
235 *
236 * @return true True if the widget was registered.
237 * @since 3.5.0
238 * @access public
239 *
240 */
241 public function register( Widget_Base $widget_instance ) {
242 if ( is_null( $this->_widget_types ) ) {
243 $this->init_widgets();
244 }
245
246 $this->_widget_types[ $widget_instance->get_name() ] = $widget_instance;
247
248 return true;
249 }
250
251 /**
252 * Unregister widget type.
253 *
254 * Removes widget type from the list of registered widget types.
255 *
256 * @since 1.0.0
257 * @access public
258 * @deprecated 3.5.0 Use `$this->unregister()` instead.
259 *
260 * @param string $name Widget name.
261 *
262 * @return true True if the widget was unregistered, False otherwise.
263 */
264 public function unregister_widget_type( $name ) {
265 Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function(
266 __METHOD__,
267 '3.5.0',
268 'unregister'
269 );
270
271 return $this->unregister( $name );
272 }
273
274 /**
275 * Unregister widget type.
276 *
277 * Removes widget type from the list of registered widget types.
278 *
279 * @since 3.5.0
280 * @access public
281 *
282 * @param string $name Widget name.
283 *
284 * @return boolean Whether the widget was unregistered.
285 */
286 public function unregister( $name ) {
287 if ( ! isset( $this->_widget_types[ $name ] ) ) {
288 return false;
289 }
290
291 unset( $this->_widget_types[ $name ] );
292
293 return true;
294 }
295
296 /**
297 * Get widget types.
298 *
299 * Retrieve the registered widget types list.
300 *
301 * @since 1.0.0
302 * @access public
303 *
304 * @param string $widget_name Optional. Widget name. Default is null.
305 *
306 * @return Widget_Base|Widget_Base[]|null Registered widget types.
307 */
308 public function get_widget_types( $widget_name = null ) {
309 if ( is_null( $this->_widget_types ) ) {
310 $this->init_widgets();
311 }
312
313 if ( null !== $widget_name ) {
314 return isset( $this->_widget_types[ $widget_name ] ) ? $this->_widget_types[ $widget_name ] : null;
315 }
316
317 return $this->_widget_types;
318 }
319
320 /**
321 * Get widget types config.
322 *
323 * Retrieve all the registered widgets with config for each widgets.
324 *
325 * @since 1.0.0
326 * @access public
327 *
328 * @return array Registered widget types with each widget config.
329 */
330 public function get_widget_types_config() {
331 $config = [];
332
333 foreach ( $this->get_widget_types() as $widget_key => $widget ) {
334 $config[ $widget_key ] = $widget->get_config();
335 }
336
337 return $config;
338 }
339
340 public function ajax_get_widget_types_controls_config( array $data ) {
341 wp_raise_memory_limit( 'admin' );
342
343 $config = [];
344
345 foreach ( $this->get_widget_types() as $widget_key => $widget ) {
346 if ( isset( $data['exclude'][ $widget_key ] ) ) {
347 continue;
348 }
349
350 $config[ $widget_key ] = [
351 'controls' => $widget->get_stack( false )['controls'],
352 'tabs_controls' => $widget->get_tabs_controls(),
353 ];
354 }
355
356 return $config;
357 }
358
359 public function ajax_get_widgets_default_value_translations( array $data = [] ) {
360 $locale = empty( $data['locale'] )
361 ? get_locale()
362 : $data['locale'];
363
364 $force_locale = new Force_Locale( $locale );
365 $force_locale->force();
366
367 $controls = ( new Collection( $this->get_widget_types() ) )
368 ->map( function ( Widget_Base $widget ) {
369 $controls = $widget->get_stack( false )['controls'];
370
371 return [
372 'controls' => $this->pluck_default_controls( $controls ),
373 ];
374 } )
375 ->filter( function ( $widget ) {
376 return ! empty( $widget['controls'] );
377 } )
378 ->all();
379
380 $force_locale->restore();
381
382 return $controls;
383 }
384
385 /**
386 * Ajax render widget.
387 *
388 * Ajax handler for Elementor render_widget.
389 *
390 * Fired by `wp_ajax_elementor_render_widget` action.
391 *
392 * @since 1.0.0
393 * @access public
394 *
395 * @throws \Exception If current user don't have permissions to edit the post.
396 *
397 * @param array $request Ajax request.
398 *
399 * @return array {
400 * Rendered widget.
401 *
402 * @type string $render The rendered HTML.
403 * }
404 */
405 public function ajax_render_widget( $request ) {
406 $document = Plugin::$instance->documents->get( $request['editor_post_id'] );
407
408 if ( ! $document->is_editable_by_current_user() ) {
409 throw new \Exception( 'Access denied.', Exceptions::FORBIDDEN );
410 }
411
412 // Override the global $post for the render.
413 query_posts(
414 [
415 'p' => $request['editor_post_id'],
416 'post_type' => 'any',
417 ]
418 );
419
420 $editor = Plugin::$instance->editor;
421 $is_edit_mode = $editor->is_edit_mode();
422 $editor->set_edit_mode( true );
423
424 Plugin::$instance->documents->switch_to_document( $document );
425
426 $render_html = $document->render_element( $request['data'] );
427
428 $editor->set_edit_mode( $is_edit_mode );
429
430 return [
431 'render' => $render_html,
432 ];
433 }
434
435 /**
436 * Ajax get WordPress widget form.
437 *
438 * Ajax handler for Elementor editor get_wp_widget_form.
439 *
440 * Fired by `wp_ajax_elementor_editor_get_wp_widget_form` action.
441 *
442 * @since 1.0.0
443 * @access public
444 *
445 * @param array $request Ajax request.
446 *
447 * @return bool|string Rendered widget form.
448 */
449 public function ajax_get_wp_widget_form( $request ) {
450 if ( empty( $request['widget_type'] ) ) {
451 return false;
452 }
453
454 if ( empty( $request['data'] ) ) {
455 $request['data'] = [];
456 }
457
458 $element_data = [
459 'id' => $request['id'],
460 'elType' => 'widget',
461 'widgetType' => $request['widget_type'],
462 'settings' => $request['data'],
463 ];
464
465 /**
466 * @var $widget_obj Widget_WordPress
467 */
468 $widget_obj = Plugin::$instance->elements_manager->create_element_instance( $element_data );
469
470 if ( ! $widget_obj ) {
471 return false;
472 }
473
474 return $widget_obj->get_form();
475 }
476
477 /**
478 * Render widgets content.
479 *
480 * Used to generate the widget templates on the editor using Underscore JS
481 * template, for all the registered widget types.
482 *
483 * @since 1.0.0
484 * @access public
485 */
486 public function render_widgets_content() {
487 foreach ( $this->get_widget_types() as $widget ) {
488 $widget->print_template();
489 }
490 }
491
492 /**
493 * Get widgets frontend settings keys.
494 *
495 * Retrieve frontend controls settings keys for all the registered widget
496 * types.
497 *
498 * @since 1.3.0
499 * @access public
500 *
501 * @return array Registered widget types with settings keys for each widget.
502 */
503 public function get_widgets_frontend_settings_keys() {
504 $keys = [];
505
506 foreach ( $this->get_widget_types() as $widget_type_name => $widget_type ) {
507 $widget_type_keys = $widget_type->get_frontend_settings_keys();
508
509 if ( $widget_type_keys ) {
510 $keys[ $widget_type_name ] = $widget_type_keys;
511 }
512 }
513
514 return $keys;
515 }
516
517 /**
518 * Enqueue widgets scripts.
519 *
520 * Enqueue all the scripts defined as a dependency for each widget.
521 *
522 * @since 1.3.0
523 * @access public
524 */
525 public function enqueue_widgets_scripts() {
526 foreach ( $this->get_widget_types() as $widget ) {
527 $widget->enqueue_scripts();
528 }
529 }
530
531 /**
532 * Enqueue widgets styles
533 *
534 * Enqueue all the styles defined as a dependency for each widget
535 *
536 * @access public
537 */
538 public function enqueue_widgets_styles() {
539 foreach ( $this->get_widget_types() as $widget ) {
540 $widget->enqueue_styles();
541 }
542 }
543
544 /**
545 * Retrieve inline editing configuration.
546 *
547 * Returns general inline editing configurations like toolbar types etc.
548 *
549 * @access public
550 * @since 1.8.0
551 *
552 * @return array {
553 * Inline editing configuration.
554 *
555 * @type array $toolbar {
556 * Toolbar types and the actions each toolbar includes.
557 * Note: Wysiwyg controls uses the advanced toolbar, textarea controls
558 * uses the basic toolbar and text controls has no toolbar.
559 *
560 * @type array $basic Basic actions included in the edit tool.
561 * @type array $advanced Advanced actions included in the edit tool.
562 * }
563 * }
564 */
565 public function get_inline_editing_config() {
566 $basic_tools = [
567 'bold',
568 'underline',
569 'italic',
570 ];
571
572 $advanced_tools = array_merge( $basic_tools, [
573 'createlink',
574 'unlink',
575 'h1' => [
576 'h1',
577 'h2',
578 'h3',
579 'h4',
580 'h5',
581 'h6',
582 'p',
583 'blockquote',
584 'pre',
585 ],
586 'list' => [
587 'insertOrderedList',
588 'insertUnorderedList',
589 ],
590 ] );
591
592 return [
593 'toolbar' => [
594 'basic' => $basic_tools,
595 'advanced' => $advanced_tools,
596 ],
597 ];
598 }
599
600 /**
601 * Widgets manager constructor.
602 *
603 * Initializing Elementor widgets manager.
604 *
605 * @since 1.0.0
606 * @access public
607 */
608 public function __construct() {
609 $this->require_files();
610
611 add_action( 'elementor/ajax/register_actions', [ $this, 'register_ajax_actions' ] );
612 }
613
614 /**
615 * Register ajax actions.
616 *
617 * Add new actions to handle data after an ajax requests returned.
618 *
619 * @since 2.0.0
620 * @access public
621 *
622 * @param Ajax $ajax_manager
623 */
624 public function register_ajax_actions( Ajax $ajax_manager ) {
625 $ajax_manager->register_ajax_action( 'render_widget', [ $this, 'ajax_render_widget' ] );
626 $ajax_manager->register_ajax_action( 'editor_get_wp_widget_form', [ $this, 'ajax_get_wp_widget_form' ] );
627 $ajax_manager->register_ajax_action( 'get_widgets_config', [ $this, 'ajax_get_widget_types_controls_config' ] );
628
629 $ajax_manager->register_ajax_action( 'get_widgets_default_value_translations', function ( array $data ) {
630 return $this->ajax_get_widgets_default_value_translations( $data );
631 } );
632 }
633 }
634