PluginProbe
Elementor Website Builder – more than just a page builder / 3.6.0-dev1
Elementor Website Builder – more than just a page builder v3.6.0-dev1
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.6.0-dev1, at includes/managers/widgets.php

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