Diff: STRATO-apps/wordpress_03/app/wp-content/plugins/elementor/includes/base/widget-base.php
Keine Baseline-Datei – Diff nur gegen leer.
1
-
1
+
<?php
2
+
namespace Elementor;
3
+
4
+
use Elementor\Core\Utils\Promotions\Filtered_Promotions_Manager;
5
+
use Elementor\Utils;
6
+
7
+
if ( ! defined( 'ABSPATH' ) ) {
8
+
exit; // Exit if accessed directly.
9
+
}
10
+
11
+
/**
12
+
* Elementor widget base.
13
+
*
14
+
* An abstract class to register new Elementor widgets. It extended the
15
+
* `Element_Base` class to inherit its properties.
16
+
*
17
+
* This abstract class must be extended in order to register new widgets.
18
+
*
19
+
* @since 1.0.0
20
+
* @abstract
21
+
*/
22
+
abstract class Widget_Base extends Element_Base {
23
+
/**
24
+
* Whether the widget has content.
25
+
*
26
+
* Used in cases where the widget has no content. When widgets uses only
27
+
* skins to display dynamic content generated on the server. For example the
28
+
* posts widget in Elementor Pro. Default is true, the widget has content
29
+
* template.
30
+
*
31
+
* @access protected
32
+
*
33
+
* @var bool
34
+
*/
35
+
protected $_has_template_content = true;
36
+
37
+
private $is_first_section = true;
38
+
39
+
/**
40
+
* Registered Runtime Widgets.
41
+
*
42
+
* Registering in runtime all widgets that are being used on the page.
43
+
*
44
+
* @since 3.3.0
45
+
* @access public
46
+
* @static
47
+
*
48
+
* @var array
49
+
*/
50
+
public static $registered_runtime_widgets = [];
51
+
52
+
/**
53
+
* Get element type.
54
+
*
55
+
* Retrieve the element type, in this case `widget`.
56
+
*
57
+
* @since 1.0.0
58
+
* @access public
59
+
* @static
60
+
*
61
+
* @return string The type.
62
+
*/
63
+
public static function get_type() {
64
+
return 'widget';
65
+
}
66
+
67
+
/**
68
+
* Get widget icon.
69
+
*
70
+
* Retrieve the widget icon.
71
+
*
72
+
* @since 1.0.0
73
+
* @access public
74
+
*
75
+
* @return string Widget icon.
76
+
*/
77
+
public function get_icon() {
78
+
return 'eicon-apps';
79
+
}
80
+
81
+
/**
82
+
* Get widget keywords.
83
+
*
84
+
* Retrieve the widget keywords.
85
+
*
86
+
* @since 1.0.10
87
+
* @access public
88
+
*
89
+
* @return array Widget keywords.
90
+
*/
91
+
public function get_keywords() {
92
+
return [];
93
+
}
94
+
95
+
/**
96
+
* Get widget categories.
97
+
*
98
+
* Retrieve the widget categories.
99
+
*
100
+
* @since 1.0.10
101
+
* @access public
102
+
*
103
+
* @return array Widget categories.
104
+
*/
105
+
public function get_categories() {
106
+
return [ 'general' ];
107
+
}
108
+
109
+
/**
110
+
* Get widget upsale data.
111
+
*
112
+
* Retrieve the widget promotion data.
113
+
*
114
+
* @since 3.18.0
115
+
* @access protected
116
+
*
117
+
* @return array|null Widget promotion data.
118
+
*/
119
+
protected function get_upsale_data() {
120
+
return null;
121
+
}
122
+
123
+
/**
124
+
* Widget base constructor.
125
+
*
126
+
* Initializing the widget base class.
127
+
*
128
+
* @since 1.0.0
129
+
* @access public
130
+
*
131
+
* @throws \Exception If arguments are missing when initializing a full widget
132
+
* instance.
133
+
*
134
+
* @param array $data Widget data. Default is an empty array.
135
+
* @param array|null $args Optional. Widget default arguments. Default is null.
136
+
*/
137
+
public function __construct( $data = [], $args = null ) {
138
+
parent::__construct( $data, $args );
139
+
140
+
$is_type_instance = $this->is_type_instance();
141
+
142
+
if ( ! $is_type_instance && null === $args ) {
143
+
throw new \Exception( 'An `$args` argument is required when initializing a full widget instance.' );
144
+
}
145
+
146
+
if ( $is_type_instance ) {
147
+
if ( $this->has_own_method( '_register_skins', self::class ) ) {
148
+
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( '_register_skins', '3.1.0', __CLASS__ . '::register_skins()' );
149
+
150
+
$this->_register_skins();
151
+
} else {
152
+
$this->register_skins();
153
+
}
154
+
155
+
$widget_name = $this->get_name();
156
+
157
+
/**
158
+
* Widget skin init.
159
+
*
160
+
* Fires when Elementor widget is being initialized.
161
+
*
162
+
* The dynamic portion of the hook name, `$widget_name`, refers to the widget name.
163
+
*
164
+
* @since 1.0.0
165
+
*
166
+
* @param Widget_Base $this The current widget.
167
+
*/
168
+
do_action( "elementor/widget/{$widget_name}/skins_init", $this );
169
+
}
170
+
}
171
+
172
+
/**
173
+
* Get stack.
174
+
*
175
+
* Retrieve the widget stack of controls.
176
+
*
177
+
* @since 1.9.2
178
+
* @access public
179
+
*
180
+
* @param bool $with_common_controls Optional. Whether to include the common controls. Default is true.
181
+
*
182
+
* @return array Widget stack of controls.
183
+
*/
184
+
public function get_stack( $with_common_controls = true ) {
185
+
$stack = parent::get_stack();
186
+
187
+
if ( $with_common_controls && ! $this instanceof Widget_Common_Base ) {
188
+
/** @var Widget_Common_Base $common_widget */
189
+
$common_widget = Plugin::$instance->widgets_manager->get_widget_types( $this->get_common_widget_name() );
190
+
191
+
$stack['controls'] = array_merge( $stack['controls'], $common_widget->get_controls() );
192
+
193
+
$stack['tabs'] = array_merge( $stack['tabs'], $common_widget->get_tabs_controls() );
194
+
}
195
+
196
+
return $stack;
197
+
}
198
+
199
+
private function get_common_widget_name() {
200
+
if ( Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ) ) {
201
+
return $this->has_widget_inner_wrapper() ? 'common' : 'common-optimized';
202
+
}
203
+
204
+
return 'common';
205
+
}
206
+
207
+
/**
208
+
* Get widget controls pointer index.
209
+
*
210
+
* Retrieve widget pointer index where the next control should be added.
211
+
*
212
+
* While using injection point, it will return the injection point index. Otherwise index of the last control of the
213
+
* current widget itself without the common controls, plus one.
214
+
*
215
+
* @since 1.9.2
216
+
* @access public
217
+
*
218
+
* @return int Widget controls pointer index.
219
+
*/
220
+
public function get_pointer_index() {
221
+
$injection_point = $this->get_injection_point();
222
+
223
+
if ( null !== $injection_point ) {
224
+
return $injection_point['index'];
225
+
}
226
+
227
+
return count( $this->get_stack( false )['controls'] );
228
+
}
229
+
230
+
/**
231
+
* Show in panel.
232
+
*
233
+
* Whether to show the widget in the panel or not. By default returns true.
234
+
*
235
+
* @since 1.0.0
236
+
* @access public
237
+
*
238
+
* @return bool Whether to show the widget in the panel or not.
239
+
*/
240
+
public function show_in_panel() {
241
+
return true;
242
+
}
243
+
244
+
/**
245
+
* Hide on search.
246
+
*
247
+
* Whether to hide the widget on search in the panel or not. By default returns false.
248
+
*
249
+
* @access public
250
+
*
251
+
* @return bool Whether to hide the widget when searching for widget or not.
252
+
*/
253
+
public function hide_on_search() {
254
+
return false;
255
+
}
256
+
257
+
/**
258
+
* Start widget controls section.
259
+
*
260
+
* Used to add a new section of controls to the widget. Regular controls and
261
+
* skin controls.
262
+
*
263
+
* Note that when you add new controls to widgets they must be wrapped by
264
+
* `start_controls_section()` and `end_controls_section()`.
265
+
*
266
+
* @since 1.0.0
267
+
* @access public
268
+
*
269
+
* @param string $section_id Section ID.
270
+
* @param array $args Section arguments Optional.
271
+
*/
272
+
public function start_controls_section( $section_id, array $args = [] ) {
273
+
parent::start_controls_section( $section_id, $args );
274
+
275
+
if ( $this->is_first_section ) {
276
+
$this->register_skin_control();
277
+
278
+
$this->is_first_section = false;
279
+
}
280
+
}
281
+
282
+
/**
283
+
* Register the Skin Control if the widget has skins.
284
+
*
285
+
* An internal method that is used to add a skin control to the widget.
286
+
* Added at the top of the controls section.
287
+
*
288
+
* @since 2.0.0
289
+
* @access private
290
+
*/
291
+
private function register_skin_control() {
292
+
$skins = $this->get_skins();
293
+
if ( ! empty( $skins ) ) {
294
+
$skin_options = [];
295
+
296
+
if ( $this->_has_template_content ) {
297
+
$skin_options[''] = esc_html__( 'Default', 'elementor' );
298
+
}
299
+
300
+
foreach ( $skins as $skin_id => $skin ) {
301
+
$skin_options[ $skin_id ] = $skin->get_title();
302
+
}
303
+
304
+
// Get the first item for default value.
305
+
$default_value = array_keys( $skin_options );
306
+
$default_value = array_shift( $default_value );
307
+
308
+
if ( 1 >= count( $skin_options ) ) {
309
+
$this->add_control(
310
+
'_skin',
311
+
[
312
+
'label' => esc_html__( 'Skin', 'elementor' ),
313
+
'type' => Controls_Manager::HIDDEN,
314
+
'default' => $default_value,
315
+
]
316
+
);
317
+
} else {
318
+
$this->add_control(
319
+
'_skin',
320
+
[
321
+
'label' => esc_html__( 'Skin', 'elementor' ),
322
+
'type' => Controls_Manager::SELECT,
323
+
'default' => $default_value,
324
+
'options' => $skin_options,
325
+
]
326
+
);
327
+
}
328
+
}
329
+
}
330
+
331
+
/**
332
+
* Register widget skins - deprecated prefixed method
333
+
*
334
+
* @since 1.7.12
335
+
* @access protected
336
+
* @deprecated 3.1.0 Use `register_skins()` method instead.
337
+
*/
338
+
protected function _register_skins() {
339
+
Plugin::$instance->modules_manager->get_modules( 'dev-tools' )->deprecation->deprecated_function( __METHOD__, '3.1.0', 'register_skins()' );
340
+
341
+
$this->register_skins();
342
+
}
343
+
344
+
/**
345
+
* Register widget skins.
346
+
*
347
+
* This method is activated while initializing the widget base class. It is
348
+
* used to assign skins to widgets with `add_skin()` method.
349
+
*
350
+
* Usage:
351
+
*
352
+
* protected function register_skins() {
353
+
* $this->add_skin( new Skin_Classic( $this ) );
354
+
* }
355
+
*
356
+
* @since 3.1.0
357
+
* @access protected
358
+
*/
359
+
protected function register_skins() {}
360
+
361
+
/**
362
+
* Get initial config.
363
+
*
364
+
* Retrieve the current widget initial configuration.
365
+
*
366
+
* Adds more configuration on top of the controls list, the tabs assigned to
367
+
* the control, element name, type, icon and more. This method also adds
368
+
* widget type, keywords and categories.
369
+
*
370
+
* @since 2.9.0
371
+
* @access protected
372
+
*
373
+
* @return array The initial widget config.
374
+
*/
375
+
protected function get_initial_config() {
376
+
$config = [
377
+
'widget_type' => $this->get_name(),
378
+
'keywords' => $this->get_keywords(),
379
+
'categories' => $this->get_categories(),
380
+
'html_wrapper_class' => $this->get_html_wrapper_class(),
381
+
'show_in_panel' => $this->show_in_panel(),
382
+
'hide_on_search' => $this->hide_on_search(),
383
+
'upsale_data' => $this->get_upsale_data(),
384
+
'is_dynamic_content' => $this->is_dynamic_content(),
385
+
'has_widget_inner_wrapper' => $this->has_widget_inner_wrapper(),
386
+
];
387
+
388
+
if ( isset( $config['upsale_data'] ) && is_array( $config['upsale_data'] ) ) {
389
+
$filter_name = 'elementor/widgets/' . $this->get_name() . '/custom_promotion';
390
+
$config['upsale_data'] = Filtered_Promotions_Manager::get_filtered_promotion_data( $config['upsale_data'], $filter_name, 'upgrade_url' );
391
+
}
392
+
393
+
if ( isset( $config['upsale_data']['image'] ) ) {
394
+
$config['upsale_data']['image'] = esc_url( $config['upsale_data']['image'] );
395
+
}
396
+
397
+
$stack = Plugin::$instance->controls_manager->get_element_stack( $this );
398
+
399
+
if ( $stack ) {
400
+
$config['controls'] = $this->get_stack( false )['controls'];
401
+
$config['tabs_controls'] = $this->get_tabs_controls();
402
+
}
403
+
404
+
return array_replace_recursive( parent::get_initial_config(), $config );
405
+
}
406
+
407
+
/**
408
+
* @since 2.3.1
409
+
* @access protected
410
+
*/
411
+
protected function should_print_empty() {
412
+
return false;
413
+
}
414
+
415
+
/**
416
+
* Print widget content template.
417
+
*
418
+
* Used to generate the widget content template on the editor, using a
419
+
* Backbone JavaScript template.
420
+
*
421
+
* @since 2.0.0
422
+
* @access protected
423
+
*
424
+
* @param string $template_content Template content.
425
+
*/
426
+
protected function print_template_content( $template_content ) {
427
+
if ( $this->has_widget_inner_wrapper() ) : ?>
428
+
<div class="elementor-widget-container">
429
+
<?php endif;
430
+
Utils::print_unescaped_internal_string( $template_content );
431
+
if ( $this->has_widget_inner_wrapper() ) : ?>
432
+
</div>
433
+
<?php endif;
434
+
}
435
+
436
+
/**
437
+
* Parse text editor.
438
+
*
439
+
* Parses the content from rich text editor with shortcodes, oEmbed and
440
+
* filtered data.
441
+
*
442
+
* @since 1.0.0
443
+
* @access protected
444
+
*
445
+
* @param string $content Text editor content.
446
+
*
447
+
* @return string Parsed content.
448
+
*/
449
+
protected function parse_text_editor( $content ) {
450
+
/** This filter is documented in wp-includes/widgets/class-wp-widget-text.php */
451
+
$content = apply_filters( 'widget_text', $content, $this->get_settings() );
452
+
453
+
$content = shortcode_unautop( $content );
454
+
$content = do_shortcode( $content );
455
+
$content = wptexturize( $content );
456
+
457
+
if ( $GLOBALS['wp_embed'] instanceof \WP_Embed ) {
458
+
$content = $GLOBALS['wp_embed']->autoembed( $content );
459
+
}
460
+
461
+
return $content;
462
+
}
463
+
464
+
/**
465
+
* Safe print parsed text editor.
466
+
*
467
+
* @uses static::parse_text_editor.
468
+
*
469
+
* @access protected
470
+
*
471
+
* @param string $content Text editor content.
472
+
*/
473
+
final protected function print_text_editor( $content ) {
474
+
// PHPCS - the method `parse_text_editor` is safe.
475
+
echo static::parse_text_editor( $content ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
476
+
}
477
+
478
+
/**
479
+
* Get HTML wrapper class.
480
+
*
481
+
* Retrieve the widget container class. Can be used to override the
482
+
* container class for specific widgets.
483
+
*
484
+
* @since 2.0.9
485
+
* @access protected
486
+
*/
487
+
protected function get_html_wrapper_class() {
488
+
return 'elementor-widget-' . $this->get_name();
489
+
}
490
+
491
+
/**
492
+
* Add widget render attributes.
493
+
*
494
+
* Used to add attributes to the current widget wrapper HTML tag.
495
+
*
496
+
* @since 1.0.0
497
+
* @access protected
498
+
*/
499
+
protected function add_render_attributes() {
500
+
parent::add_render_attributes();
501
+
502
+
$this->add_render_attribute(
503
+
'_wrapper', 'class', [
504
+
'elementor-widget',
505
+
$this->get_html_wrapper_class(),
506
+
]
507
+
);
508
+
509
+
$settings = $this->get_settings();
510
+
511
+
$this->add_render_attribute( '_wrapper', 'data-widget_type', $this->get_name() . '.' . ( ! empty( $settings['_skin'] ) ? $settings['_skin'] : 'default' ) );
512
+
}
513
+
514
+
/**
515
+
* Add lightbox data to image link.
516
+
*
517
+
* Used to add lightbox data attributes to image link HTML.
518
+
*
519
+
* @since 2.9.1
520
+
* @access public
521
+
*
522
+
* @param string $link_html Image link HTML.
523
+
* @param string $id Attachment id.
524
+
*
525
+
* @return string Image link HTML with lightbox data attributes.
526
+
*/
527
+
public function add_lightbox_data_to_image_link( $link_html, $id ) {
528
+
$settings = $this->get_settings_for_display();
529
+
$open_lightbox = isset( $settings['open_lightbox'] ) ? $settings['open_lightbox'] : null;
530
+
531
+
if ( Plugin::$instance->editor->is_edit_mode() ) {
532
+
$this->add_render_attribute( 'link', 'class', 'elementor-clickable', true );
533
+
}
534
+
535
+
$this->add_lightbox_data_attributes( 'link', $id, $open_lightbox, $this->get_id(), true );
536
+
return preg_replace( '/^<a/', '<a ' . $this->get_render_attribute_string( 'link' ), $link_html );
537
+
}
538
+
539
+
/**
540
+
* Add Light-Box attributes.
541
+
*
542
+
* Used to add Light-Box-related data attributes to links that open media files.
543
+
*
544
+
* @param array|string $element The link HTML element.
545
+
* @param int $id The ID of the image.
546
+
* @param string $lightbox_setting_key The setting key that dictates whether to open the image in a lightbox.
547
+
* @param string $group_id Unique ID for a group of lightbox images.
548
+
* @param bool $overwrite Optional. Whether to overwrite existing
549
+
* attribute. Default is false, not to overwrite.
550
+
*
551
+
* @return Widget_Base Current instance of the widget.
552
+
* @since 2.9.0
553
+
* @access public
554
+
*/
555
+
public function add_lightbox_data_attributes( $element, $id = null, $lightbox_setting_key = null, $group_id = null, $overwrite = false ) {
556
+
$kit = Plugin::$instance->kits_manager->get_active_kit();
557
+
558
+
$is_global_image_lightbox_enabled = 'yes' === $kit->get_settings( 'global_image_lightbox' );
559
+
560
+
if ( 'no' === $lightbox_setting_key ) {
561
+
if ( $is_global_image_lightbox_enabled ) {
562
+
$this->add_render_attribute( $element, 'data-elementor-open-lightbox', 'no', $overwrite );
563
+
}
564
+
565
+
return $this;
566
+
}
567
+
568
+
if ( 'yes' !== $lightbox_setting_key && ! $is_global_image_lightbox_enabled ) {
569
+
return $this;
570
+
}
571
+
572
+
$attributes['data-elementor-open-lightbox'] = 'yes';
573
+
574
+
$action_hash_params = [];
575
+
576
+
if ( $id ) {
577
+
$action_hash_params['id'] = $id;
578
+
$action_hash_params['url'] = wp_get_attachment_url( $id );
579
+
}
580
+
581
+
if ( $group_id ) {
582
+
$attributes['data-elementor-lightbox-slideshow'] = $group_id;
583
+
584
+
$action_hash_params['slideshow'] = $group_id;
585
+
}
586
+
587
+
if ( $id ) {
588
+
$lightbox_image_attributes = Plugin::$instance->images_manager->get_lightbox_image_attributes( $id );
589
+
590
+
if ( isset( $lightbox_image_attributes['title'] ) ) {
591
+
$attributes['data-elementor-lightbox-title'] = $lightbox_image_attributes['title'];
592
+
}
593
+
594
+
if ( isset( $lightbox_image_attributes['description'] ) ) {
595
+
$attributes['data-elementor-lightbox-description'] = $lightbox_image_attributes['description'];
596
+
}
597
+
}
598
+
599
+
$attributes['data-e-action-hash'] = Plugin::instance()->frontend->create_action_hash( 'lightbox', $action_hash_params );
600
+
601
+
$this->add_render_attribute( $element, $attributes, null, $overwrite );
602
+
603
+
return $this;
604
+
}
605
+
606
+
/**
607
+
* Render widget output on the frontend.
608
+
*
609
+
* Used to generate the final HTML displayed on the frontend.
610
+
*
611
+
* Note that if skin is selected, it will be rendered by the skin itself,
612
+
* not the widget.
613
+
*
614
+
* @since 1.0.0
615
+
* @access public
616
+
*/
617
+
public function render_content() {
618
+
/**
619
+
* Before widget render content.
620
+
*
621
+
* Fires before Elementor widget is being rendered.
622
+
*
623
+
* @since 1.0.0
624
+
*
625
+
* @param Widget_Base $this The current widget.
626
+
*/
627
+
do_action( 'elementor/widget/before_render_content', $this );
628
+
629
+
ob_start();
630
+
631
+
$skin = $this->get_current_skin();
632
+
if ( $skin ) {
633
+
$skin->set_parent( $this );
634
+
$skin->render_by_mode();
635
+
} else {
636
+
$this->render_by_mode();
637
+
}
638
+
639
+
$widget_content = ob_get_clean();
640
+
641
+
if ( empty( $widget_content ) ) {
642
+
return;
643
+
}
644
+
if ( $this->has_widget_inner_wrapper() ) : ?>
645
+
<div class="elementor-widget-container">
646
+
<?php endif; ?>
647
+
<?php
648
+
if ( $this->is_widget_first_render( $this->get_group_name() ) ) {
649
+
$this->register_runtime_widget( $this->get_group_name() );
650
+
}
651
+
652
+
/**
653
+
* Render widget content.
654
+
*
655
+
* Filters the widget content before it's rendered.
656
+
*
657
+
* @since 1.0.0
658
+
*
659
+
* @param string $widget_content The content of the widget.
660
+
* @param Widget_Base $this The widget.
661
+
*/
662
+
$widget_content = apply_filters( 'elementor/widget/render_content', $widget_content, $this );
663
+
Utils::print_unescaped_internal_string( $widget_content );
664
+
?>
665
+
<?php if ( $this->has_widget_inner_wrapper() ) : ?>
666
+
</div>
667
+
<?php endif;
668
+
}
669
+
670
+
protected function is_widget_first_render( $widget_name ) {
671
+
return ! in_array( $widget_name, self::$registered_runtime_widgets, true );
672
+
}
673
+
674
+
/**
675
+
* Render widget plain content.
676
+
*
677
+
* Elementor saves the page content in a unique way, but it's not the way
678
+
* WordPress saves data. This method is used to save generated HTML to the
679
+
* database as plain content the WordPress way.
680
+
*
681
+
* When rendering plain content, it allows other WordPress plugins to
682
+
* interact with the content - to search, check SEO and other purposes. It
683
+
* also allows the site to keep working even if Elementor is deactivated.
684
+
*
685
+
* Note that if the widget uses shortcodes to display the data, the best
686
+
* practice is to return the shortcode itself.
687
+
*
688
+
* Also note that if the widget don't display any content it should return
689
+
* an empty string. For example Elementor Pro Form Widget uses this method
690
+
* to return an empty string because there is no content to return. This way
691
+
* if Elementor Pro will be deactivated there won't be any form to display.
692
+
*
693
+
* @since 1.0.0
694
+
* @access public
695
+
*/
696
+
public function render_plain_content() {
697
+
$this->render_content();
698
+
}
699
+
700
+
/**
701
+
* Before widget rendering.
702
+
*
703
+
* Used to add stuff before the widget `_wrapper` element.
704
+
*
705
+
* @since 1.0.0
706
+
* @access public
707
+
*/
708
+
public function before_render() {
709
+
?>
710
+
<div <?php $this->print_render_attribute_string( '_wrapper' ); ?>>
711
+
<?php
712
+
}
713
+
714
+
/**
715
+
* After widget rendering.
716
+
*
717
+
* Used to add stuff after the widget `_wrapper` element.
718
+
*
719
+
* @since 1.0.0
720
+
* @access public
721
+
*/
722
+
public function after_render() {
723
+
?>
724
+
</div>
725
+
<?php
726
+
}
727
+
728
+
/**
729
+
* Get the element raw data.
730
+
*
731
+
* Retrieve the raw element data, including the id, type, settings, child
732
+
* elements and whether it is an inner element.
733
+
*
734
+
* The data with the HTML used always to display the data, but the Elementor
735
+
* editor uses the raw data without the HTML in order not to render the data
736
+
* again.
737
+
*
738
+
* @since 1.0.0
739
+
* @access public
740
+
*
741
+
* @param bool $with_html_content Optional. Whether to return the data with
742
+
* HTML content or without. Used for caching.
743
+
* Default is false, without HTML.
744
+
*
745
+
* @return array Element raw data.
746
+
*/
747
+
public function get_raw_data( $with_html_content = false ) {
748
+
$data = parent::get_raw_data( $with_html_content );
749
+
750
+
unset( $data['isInner'] );
751
+
752
+
$data['widgetType'] = $this->get_data( 'widgetType' );
753
+
754
+
if ( $with_html_content ) {
755
+
ob_start();
756
+
757
+
$this->render_content();
758
+
759
+
$data['htmlCache'] = ob_get_clean();
760
+
}
761
+
762
+
return $data;
763
+
}
764
+
765
+
/**
766
+
* Print widget content.
767
+
*
768
+
* Output the widget final HTML on the frontend.
769
+
*
770
+
* @since 1.0.0
771
+
* @access protected
772
+
*/
773
+
protected function print_content() {
774
+
$this->render_content();
775
+
}
776
+
777
+
/**
778
+
* Print a setting content without escaping.
779
+
*
780
+
* Script tags are allowed on frontend according to the WP theme securing policy.
781
+
*
782
+
* @param string $setting
783
+
* @param null $repeater_name
784
+
* @param null $index
785
+
*/
786
+
final public function print_unescaped_setting( $setting, $repeater_name = null, $index = null ) {
787
+
if ( $repeater_name ) {
788
+
$repeater = $this->get_settings_for_display( $repeater_name );
789
+
$output = $repeater[ $index ][ $setting ];
790
+
} else {
791
+
$output = $this->get_settings_for_display( $setting );
792
+
}
793
+
794
+
echo $output; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
795
+
}
796
+
797
+
/**
798
+
* Get default data.
799
+
*
800
+
* Retrieve the default widget data. Used to reset the data on initialization.
801
+
*
802
+
* @since 1.0.0
803
+
* @access protected
804
+
*
805
+
* @return array Default data.
806
+
*/
807
+
protected function get_default_data() {
808
+
$data = parent::get_default_data();
809
+
810
+
$data['widgetType'] = '';
811
+
812
+
return $data;
813
+
}
814
+
815
+
/**
816
+
* Get default child type.
817
+
*
818
+
* Retrieve the widget child type based on element data.
819
+
*
820
+
* @since 1.0.0
821
+
* @access protected
822
+
*
823
+
* @param array $element_data Widget ID.
824
+
*
825
+
* @return array|false Child type or false if it's not a valid widget.
826
+
*/
827
+
protected function _get_default_child_type( array $element_data ) {
828
+
return Plugin::$instance->elements_manager->get_element_types( 'section' );
829
+
}
830
+
831
+
/**
832
+
* Get repeater setting key.
833
+
*
834
+
* Retrieve the unique setting key for the current repeater item. Used to connect the current element in the
835
+
* repeater to it's settings model and it's control in the panel.
836
+
*
837
+
* PHP usage (inside `Widget_Base::render()` method):
838
+
*
839
+
* $tabs = $this->get_settings( 'tabs' );
840
+
* foreach ( $tabs as $index => $item ) {
841
+
* $tab_title_setting_key = $this->get_repeater_setting_key( 'tab_title', 'tabs', $index );
842
+
* $this->add_inline_editing_attributes( $tab_title_setting_key, 'none' );
843
+
* echo '<div ' . $this->get_render_attribute_string( $tab_title_setting_key ) . '>' . $item['tab_title'] . '</div>';
844
+
* }
845
+
*
846
+
* @since 1.8.0
847
+
* @access protected
848
+
*
849
+
* @param string $setting_key The current setting key inside the repeater item (e.g. `tab_title`).
850
+
* @param string $repeater_key The repeater key containing the array of all the items in the repeater (e.g. `tabs`).
851
+
* @param int $repeater_item_index The current item index in the repeater array (e.g. `3`).
852
+
*
853
+
* @return string The repeater setting key (e.g. `tabs.3.tab_title`).
854
+
*/
855
+
protected function get_repeater_setting_key( $setting_key, $repeater_key, $repeater_item_index ) {
856
+
return implode( '.', [ $repeater_key, $repeater_item_index, $setting_key ] );
857
+
}
858
+
859
+
/**
860
+
* Add inline editing attributes.
861
+
*
862
+
* Define specific area in the element to be editable inline. The element can have several areas, with this method
863
+
* you can set the area inside the element that can be edited inline. You can also define the type of toolbar the
864
+
* user will see, whether it will be a basic toolbar or an advanced one.
865
+
*
866
+
* Note: When you use wysiwyg control use the advanced toolbar, with textarea control use the basic toolbar. Text
867
+
* control should not have toolbar.
868
+
*
869
+
* PHP usage (inside `Widget_Base::render()` method):
870
+
*
871
+
* $this->add_inline_editing_attributes( 'text', 'advanced' );
872
+
* echo '<div ' . $this->get_render_attribute_string( 'text' ) . '>' . $this->get_settings( 'text' ) . '</div>';
873
+
*
874
+
* @since 1.8.0
875
+
* @access protected
876
+
*
877
+
* @param string $key Element key.
878
+
* @param string $toolbar Optional. Toolbar type. Accepted values are `advanced`, `basic` or `none`. Default is
879
+
* `basic`.
880
+
*/
881
+
protected function add_inline_editing_attributes( $key, $toolbar = 'basic' ) {
882
+
if ( ! Plugin::$instance->editor->is_edit_mode() ) {
883
+
return;
884
+
}
885
+
886
+
$this->add_render_attribute( $key, [
887
+
'class' => 'elementor-inline-editing',
888
+
'data-elementor-setting-key' => $key,
889
+
] );
890
+
891
+
if ( 'basic' !== $toolbar ) {
892
+
$this->add_render_attribute( $key, [
893
+
'data-elementor-inline-editing-toolbar' => $toolbar,
894
+
] );
895
+
}
896
+
}
897
+
898
+
/**
899
+
* Add new skin.
900
+
*
901
+
* Register new widget skin to allow the user to set custom designs. Must be
902
+
* called inside the `register_skins()` method.
903
+
*
904
+
* @since 1.0.0
905
+
* @access public
906
+
*
907
+
* @param Skin_Base $skin Skin instance.
908
+
*/
909
+
public function add_skin( Skin_Base $skin ) {
910
+
Plugin::$instance->skins_manager->add_skin( $this, $skin );
911
+
}
912
+
913
+
/**
914
+
* Get single skin.
915
+
*
916
+
* Retrieve a single skin based on skin ID, from all the skin assigned to
917
+
* the widget. If the skin does not exist or not assigned to the widget,
918
+
* return false.
919
+
*
920
+
* @since 1.0.0
921
+
* @access public
922
+
*
923
+
* @param string $skin_id Skin ID.
924
+
*
925
+
* @return string|false Single skin, or false.
926
+
*/
927
+
public function get_skin( $skin_id ) {
928
+
$skins = $this->get_skins();
929
+
if ( isset( $skins[ $skin_id ] ) ) {
930
+
return $skins[ $skin_id ];
931
+
}
932
+
933
+
return false;
934
+
}
935
+
936
+
/**
937
+
* Get current skin ID.
938
+
*
939
+
* Retrieve the ID of the current skin.
940
+
*
941
+
* @since 1.0.0
942
+
* @access public
943
+
*
944
+
* @return string Current skin.
945
+
*/
946
+
public function get_current_skin_id() {
947
+
return $this->get_settings( '_skin' );
948
+
}
949
+
950
+
/**
951
+
* Get current skin.
952
+
*
953
+
* Retrieve the current skin, or if non exist return false.
954
+
*
955
+
* @since 1.0.0
956
+
* @access public
957
+
*
958
+
* @return Skin_Base|false Current skin or false.
959
+
*/
960
+
public function get_current_skin() {
961
+
return $this->get_skin( $this->get_current_skin_id() );
962
+
}
963
+
964
+
/**
965
+
* Remove widget skin.
966
+
*
967
+
* Unregister an existing skin and remove it from the widget.
968
+
*
969
+
* @since 1.0.0
970
+
* @access public
971
+
*
972
+
* @param string $skin_id Skin ID.
973
+
*
974
+
* @return \WP_Error|true Whether the skin was removed successfully from the widget.
975
+
*/
976
+
public function remove_skin( $skin_id ) {
977
+
return Plugin::$instance->skins_manager->remove_skin( $this, $skin_id );
978
+
}
979
+
980
+
/**
981
+
* Get widget skins.
982
+
*
983
+
* Retrieve all the skin assigned to the widget.
984
+
*
985
+
* @since 1.0.0
986
+
* @access public
987
+
*
988
+
* @return Skin_Base[]
989
+
*/
990
+
public function get_skins() {
991
+
return Plugin::$instance->skins_manager->get_skins( $this );
992
+
}
993
+
994
+
/**
995
+
* Get group name.
996
+
*
997
+
* Some widgets need to use group names, this method allows you to create them.
998
+
* By default it retrieves the regular name.
999
+
*
1000
+
* @since 3.3.0
1001
+
* @access public
1002
+
*
1003
+
* @return string Unique name.
1004
+
*/
1005
+
public function get_group_name() {
1006
+
return $this->get_name();
1007
+
}
1008
+
1009
+
/**
1010
+
* @param string $plugin_title Plugin's title.
1011
+
* @param string $since Plugin version widget was deprecated.
1012
+
* @param string $last Plugin version in which the widget will be removed.
1013
+
* @param string $replacement Widget replacement.
1014
+
*/
1015
+
protected function deprecated_notice( $plugin_title, $since, $last = '', $replacement = '' ) {
1016
+
$this->start_controls_section(
1017
+
'Deprecated',
1018
+
[
1019
+
'label' => esc_html__( 'Deprecated', 'elementor' ),
1020
+
]
1021
+
);
1022
+
1023
+
$this->add_control(
1024
+
'deprecated_notice',
1025
+
[
1026
+
'type' => Controls_Manager::DEPRECATED_NOTICE,
1027
+
'widget' => $this->get_title(),
1028
+
'since' => $since,
1029
+
'last' => $last,
1030
+
'plugin' => $plugin_title,
1031
+
'replacement' => $replacement,
1032
+
]
1033
+
);
1034
+
1035
+
$this->end_controls_section();
1036
+
}
1037
+
1038
+
/**
1039
+
* Init controls.
1040
+
*
1041
+
* Reset the `is_first_section` flag to true, so when the Stacks are cleared
1042
+
* all the controls will be registered again with their skins and settings.
1043
+
*
1044
+
* @since 3.14.0
1045
+
* @access protected
1046
+
*/
1047
+
protected function init_controls() {
1048
+
$this->is_first_section = true;
1049
+
parent::init_controls();
1050
+
}
1051
+
1052
+
public function register_runtime_widget( $widget_name ) {
1053
+
self::$registered_runtime_widgets[] = $widget_name;
1054
+
}
1055
+
1056
+
/**
1057
+
* Mark widget as deprecated.
1058
+
*
1059
+
* Use `get_deprecation_message()` method to print the message control at specific location in register_controls().
1060
+
*
1061
+
* @param string $version The version of Elementor that deprecated the widget.
1062
+
* @param string $message A message regarding the deprecation.
1063
+
* @param string $replacement The widget that should be used instead.
1064
+
*/
1065
+
protected function add_deprecation_message( $version, $message, $replacement ) {
1066
+
// Expose the config for handling in JS.
1067
+
$this->set_config( 'deprecation', [
1068
+
'version' => $version,
1069
+
'message' => $message,
1070
+
'replacement' => $replacement,
1071
+
] );
1072
+
1073
+
$this->add_control(
1074
+
'deprecation_message',
1075
+
[
1076
+
'type' => Controls_Manager::ALERT,
1077
+
'alert_type' => 'info',
1078
+
'content' => $message,
1079
+
'separator' => 'after',
1080
+
]
1081
+
);
1082
+
}
1083
+
}
1084
+