PluginProbe
Elementor Website Builder – more than just a page builder / 3.32.4
Elementor Website Builder – more than just a page builder v3.32.4
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 / widgets / social-icons.php

social-icons.php in Elementor Website Builder – more than just a page builder 3.32.4, at includes/widgets/social-icons.php

720 lines 17.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 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 /**
9 * Elementor social icons widget.
10 *
11 * Elementor widget that displays icons to social pages like Facebook and Twitter.
12 *
13 * @since 1.0.0
14 */
15 class Widget_Social_Icons extends Widget_Base {
16
17 /**
18 * Get widget name.
19 *
20 * Retrieve social icons widget name.
21 *
22 * @since 1.0.0
23 * @access public
24 *
25 * @return string Widget name.
26 */
27 public function get_name() {
28 return 'social-icons';
29 }
30
31 /**
32 * Get widget title.
33 *
34 * Retrieve social icons widget title.
35 *
36 * @since 1.0.0
37 * @access public
38 *
39 * @return string Widget title.
40 */
41 public function get_title() {
42 return esc_html__( 'Social Icons', 'elementor' );
43 }
44
45 /**
46 * Get widget icon.
47 *
48 * Retrieve social icons widget icon.
49 *
50 * @since 1.0.0
51 * @access public
52 *
53 * @return string Widget icon.
54 */
55 public function get_icon() {
56 return 'eicon-social-icons';
57 }
58
59 /**
60 * Get widget keywords.
61 *
62 * Retrieve the list of keywords the widget belongs to.
63 *
64 * @since 2.1.0
65 * @access public
66 *
67 * @return array Widget keywords.
68 */
69 public function get_keywords() {
70 return [ 'social', 'icon', 'link' ];
71 }
72
73 protected function is_dynamic_content(): bool {
74 return false;
75 }
76
77 /**
78 * Get style dependencies.
79 *
80 * Retrieve the list of style dependencies the widget requires.
81 *
82 * @since 3.24.0
83 * @access public
84 *
85 * @return array Widget style dependencies.
86 */
87 public function get_style_depends(): array {
88 return [ 'widget-social-icons', 'e-apple-webkit' ];
89 }
90
91 public function has_widget_inner_wrapper(): bool {
92 return ! Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' );
93 }
94
95 /**
96 * Register social icons widget controls.
97 *
98 * Adds different input fields to allow the user to change and customize the widget settings.
99 *
100 * @since 3.1.0
101 * @access protected
102 */
103 protected function register_controls() {
104 $this->start_controls_section(
105 'section_social_icon',
106 [
107 'label' => esc_html__( 'Social Icons', 'elementor' ),
108 ]
109 );
110
111 $repeater = new Repeater();
112
113 $repeater->add_control(
114 'social_icon',
115 [
116 'label' => esc_html__( 'Icon', 'elementor' ),
117 'type' => Controls_Manager::ICONS,
118 'fa4compatibility' => 'social',
119 'default' => [
120 'value' => 'fab fa-wordpress',
121 'library' => 'fa-brands',
122 ],
123 'recommended' => [
124 'fa-brands' => [
125 'android',
126 'apple',
127 'behance',
128 'bitbucket',
129 'codepen',
130 'delicious',
131 'deviantart',
132 'digg',
133 'dribbble',
134 'elementor',
135 'facebook',
136 'flickr',
137 'foursquare',
138 'free-code-camp',
139 'github',
140 'gitlab',
141 'globe',
142 'houzz',
143 'instagram',
144 'jsfiddle',
145 'linkedin',
146 'medium',
147 'meetup',
148 'mix',
149 'mixcloud',
150 'odnoklassniki',
151 'pinterest',
152 'product-hunt',
153 'reddit',
154 'shopping-cart',
155 'skype',
156 'slideshare',
157 'snapchat',
158 'soundcloud',
159 'spotify',
160 'stack-overflow',
161 'steam',
162 'telegram',
163 'thumb-tack',
164 'threads',
165 'tripadvisor',
166 'tumblr',
167 'twitch',
168 'twitter',
169 'viber',
170 'vimeo',
171 'vk',
172 'weibo',
173 'weixin',
174 'whatsapp',
175 'wordpress',
176 'xing',
177 'x-twitter',
178 'yelp',
179 'youtube',
180 '500px',
181 ],
182 'fa-solid' => [
183 'envelope',
184 'link',
185 'rss',
186 ],
187 ],
188 ]
189 );
190
191 $repeater->add_control(
192 'link',
193 [
194 'label' => esc_html__( 'Link', 'elementor' ),
195 'type' => Controls_Manager::URL,
196 'default' => [
197 'is_external' => 'true',
198 ],
199 'dynamic' => [
200 'active' => true,
201 ],
202 ]
203 );
204
205 $repeater->add_control(
206 'item_icon_color',
207 [
208 'label' => esc_html__( 'Color', 'elementor' ),
209 'type' => Controls_Manager::SELECT,
210 'default' => 'default',
211 'options' => [
212 'default' => esc_html__( 'Official Color', 'elementor' ),
213 'custom' => esc_html__( 'Custom', 'elementor' ),
214 ],
215 ]
216 );
217
218 $repeater->add_control(
219 'item_icon_primary_color',
220 [
221 'label' => esc_html__( 'Primary Color', 'elementor' ),
222 'type' => Controls_Manager::COLOR,
223 'condition' => [
224 'item_icon_color' => 'custom',
225 ],
226 'selectors' => [
227 '{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon' => 'background-color: {{VALUE}};',
228 ],
229 ]
230 );
231
232 $repeater->add_control(
233 'item_icon_secondary_color',
234 [
235 'label' => esc_html__( 'Secondary Color', 'elementor' ),
236 'type' => Controls_Manager::COLOR,
237 'condition' => [
238 'item_icon_color' => 'custom',
239 ],
240 'selectors' => [
241 '{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon i' => 'color: {{VALUE}};',
242 '{{WRAPPER}} {{CURRENT_ITEM}}.elementor-social-icon svg' => 'fill: {{VALUE}};',
243 ],
244 ]
245 );
246
247 $this->add_control(
248 'social_icon_list',
249 [
250 'label' => esc_html__( 'Social Icons', 'elementor' ),
251 'type' => Controls_Manager::REPEATER,
252 'fields' => $repeater->get_controls(),
253 'default' => [
254 [
255 'social_icon' => [
256 'value' => 'fab fa-facebook',
257 'library' => 'fa-brands',
258 ],
259 ],
260 [
261 'social_icon' => [
262 'value' => 'fab fa-twitter',
263 'library' => 'fa-brands',
264 ],
265 ],
266 [
267 'social_icon' => [
268 'value' => 'fab fa-youtube',
269 'library' => 'fa-brands',
270 ],
271 ],
272 ],
273 'title_field' => '<# var migrated = "undefined" !== typeof __fa4_migrated, social = ( "undefined" === typeof social ) ? false : social; #>{{{ elementor.helpers.getSocialNetworkNameFromIcon( social_icon, social, true, migrated, true ) }}}',
274 ]
275 );
276
277 $this->add_control(
278 'shape',
279 [
280 'label' => esc_html__( 'Shape', 'elementor' ),
281 'type' => Controls_Manager::SELECT,
282 'default' => 'rounded',
283 'options' => [
284 'square' => esc_html__( 'Square', 'elementor' ),
285 'rounded' => esc_html__( 'Rounded', 'elementor' ),
286 'circle' => esc_html__( 'Circle', 'elementor' ),
287 ],
288 'prefix_class' => 'elementor-shape-',
289 ]
290 );
291
292 $this->add_responsive_control(
293 'columns',
294 [
295 'label' => esc_html__( 'Columns', 'elementor' ),
296 'type' => Controls_Manager::SELECT,
297 'default' => '0',
298 'options' => [
299 '0' => esc_html__( 'Auto', 'elementor' ),
300 '1' => '1',
301 '2' => '2',
302 '3' => '3',
303 '4' => '4',
304 '5' => '5',
305 '6' => '6',
306 ],
307 'prefix_class' => 'elementor-grid%s-',
308 'selectors' => [
309 '{{WRAPPER}}' => '--grid-template-columns: repeat({{VALUE}}, auto);',
310 ],
311 ]
312 );
313
314 $start = is_rtl() ? 'end' : 'start';
315 $end = is_rtl() ? 'start' : 'end';
316
317 $align_selector = Plugin::$instance->experiments->is_feature_active( 'e_optimized_markup' ) && ! $this->has_widget_inner_wrapper()
318 ? '{{WRAPPER}}'
319 : '{{WRAPPER}} .elementor-widget-container';
320
321 $this->add_responsive_control(
322 'align',
323 [
324 'label' => esc_html__( 'Alignment', 'elementor' ),
325 'type' => Controls_Manager::CHOOSE,
326 'options' => [
327 'left' => [
328 'title' => esc_html__( 'Left', 'elementor' ),
329 'icon' => 'eicon-text-align-left',
330 ],
331 'center' => [
332 'title' => esc_html__( 'Center', 'elementor' ),
333 'icon' => 'eicon-text-align-center',
334 ],
335 'right' => [
336 'title' => esc_html__( 'Right', 'elementor' ),
337 'icon' => 'eicon-text-align-right',
338 ],
339 ],
340 'prefix_class' => 'e-grid-align%s-',
341 'default' => 'center',
342 'selectors' => [
343 $align_selector => 'text-align: {{VALUE}}',
344 ],
345 ]
346 );
347
348 $this->end_controls_section();
349
350 $this->start_controls_section(
351 'section_social_style',
352 [
353 'label' => esc_html__( 'Icon', 'elementor' ),
354 'tab' => Controls_Manager::TAB_STYLE,
355 ]
356 );
357
358 $this->add_control(
359 'icon_color',
360 [
361 'label' => esc_html__( 'Color', 'elementor' ),
362 'type' => Controls_Manager::SELECT,
363 'default' => 'default',
364 'options' => [
365 'default' => esc_html__( 'Official Color', 'elementor' ),
366 'custom' => esc_html__( 'Custom', 'elementor' ),
367 ],
368 ]
369 );
370
371 $this->add_control(
372 'icon_primary_color',
373 [
374 'label' => esc_html__( 'Primary Color', 'elementor' ),
375 'type' => Controls_Manager::COLOR,
376 'condition' => [
377 'icon_color' => 'custom',
378 ],
379 'selectors' => [
380 '{{WRAPPER}} .elementor-social-icon' => 'background-color: {{VALUE}};',
381 ],
382 ]
383 );
384
385 $this->add_control(
386 'icon_secondary_color',
387 [
388 'label' => esc_html__( 'Secondary Color', 'elementor' ),
389 'type' => Controls_Manager::COLOR,
390 'condition' => [
391 'icon_color' => 'custom',
392 ],
393 'selectors' => [
394 '{{WRAPPER}} .elementor-social-icon i' => 'color: {{VALUE}};',
395 '{{WRAPPER}} .elementor-social-icon svg' => 'fill: {{VALUE}};',
396 ],
397 ]
398 );
399
400 $this->add_responsive_control(
401 'icon_size',
402 [
403 'label' => esc_html__( 'Size', 'elementor' ),
404 'type' => Controls_Manager::SLIDER,
405 // The `%' and `em` units are not supported as the widget implements icons differently then other icons.
406 'size_units' => [ 'px', 'rem', 'vw', 'custom' ],
407 'range' => [
408 'px' => [
409 'min' => 6,
410 'max' => 300,
411 ],
412 ],
413 'selectors' => [
414 '{{WRAPPER}}' => '--icon-size: {{SIZE}}{{UNIT}}',
415 ],
416 ]
417 );
418
419 $this->add_responsive_control(
420 'icon_padding',
421 [
422 'label' => esc_html__( 'Padding', 'elementor' ),
423 'type' => Controls_Manager::SLIDER,
424 // The `%' unit is not supported.
425 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
426 'selectors' => [
427 '{{WRAPPER}} .elementor-social-icon' => '--icon-padding: {{SIZE}}{{UNIT}}',
428 ],
429 'default' => [
430 'unit' => 'em',
431 ],
432 'tablet_default' => [
433 'unit' => 'em',
434 ],
435 'mobile_default' => [
436 'unit' => 'em',
437 ],
438 'range' => [
439 'px' => [
440 'max' => 50,
441 ],
442 'em' => [
443 'min' => 0,
444 'max' => 5,
445 ],
446 'rem' => [
447 'min' => 0,
448 'max' => 5,
449 ],
450 ],
451 ]
452 );
453
454 $this->add_responsive_control(
455 'icon_spacing',
456 [
457 'label' => esc_html__( 'Spacing', 'elementor' ),
458 'type' => Controls_Manager::SLIDER,
459 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
460 'range' => [
461 'px' => [
462 'max' => 100,
463 ],
464 'em' => [
465 'min' => 0,
466 'max' => 10,
467 ],
468 'rem' => [
469 'min' => 0,
470 'max' => 10,
471 ],
472 ],
473 'default' => [
474 'size' => 5,
475 ],
476 'selectors' => [
477 '{{WRAPPER}}' => '--grid-column-gap: {{SIZE}}{{UNIT}}',
478 ],
479 ]
480 );
481
482 $this->add_responsive_control(
483 'row_gap',
484 [
485 'label' => esc_html__( 'Rows Gap', 'elementor' ),
486 'type' => Controls_Manager::SLIDER,
487 'size_units' => [ 'px', 'em', 'rem', 'custom' ],
488 'default' => [
489 'size' => 0,
490 ],
491 'selectors' => [
492 '{{WRAPPER}}' => '--grid-row-gap: {{SIZE}}{{UNIT}}',
493 ],
494 ]
495 );
496
497 $this->add_group_control(
498 Group_Control_Border::get_type(),
499 [
500 'name' => 'image_border', // We know this mistake - TODO: 'icon_border' (for hover control condition also)
501 'selector' => '{{WRAPPER}} .elementor-social-icon',
502 'separator' => 'before',
503 ]
504 );
505
506 $this->add_responsive_control(
507 'border_radius',
508 [
509 'label' => esc_html__( 'Border Radius', 'elementor' ),
510 'type' => Controls_Manager::DIMENSIONS,
511 'size_units' => [ 'px', '%', 'em', 'rem', 'custom' ],
512 'selectors' => [
513 '{{WRAPPER}} .elementor-icon' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
514 ],
515 ]
516 );
517
518 $this->end_controls_section();
519
520 $this->start_controls_section(
521 'section_social_hover',
522 [
523 'label' => esc_html__( 'Icon Hover', 'elementor' ),
524 'tab' => Controls_Manager::TAB_STYLE,
525 ]
526 );
527
528 $this->add_control(
529 'hover_primary_color',
530 [
531 'label' => esc_html__( 'Primary Color', 'elementor' ),
532 'type' => Controls_Manager::COLOR,
533 'default' => '',
534 'condition' => [
535 'icon_color' => 'custom',
536 ],
537 'selectors' => [
538 '{{WRAPPER}} .elementor-social-icon:hover' => 'background-color: {{VALUE}};',
539 ],
540 ]
541 );
542
543 $this->add_control(
544 'hover_secondary_color',
545 [
546 'label' => esc_html__( 'Secondary Color', 'elementor' ),
547 'type' => Controls_Manager::COLOR,
548 'default' => '',
549 'condition' => [
550 'icon_color' => 'custom',
551 ],
552 'selectors' => [
553 '{{WRAPPER}} .elementor-social-icon:hover i' => 'color: {{VALUE}};',
554 '{{WRAPPER}} .elementor-social-icon:hover svg' => 'fill: {{VALUE}};',
555 ],
556 ]
557 );
558
559 $this->add_control(
560 'hover_border_color',
561 [
562 'label' => esc_html__( 'Border Color', 'elementor' ),
563 'type' => Controls_Manager::COLOR,
564 'default' => '',
565 'condition' => [
566 'image_border_border!' => '',
567 ],
568 'selectors' => [
569 '{{WRAPPER}} .elementor-social-icon:hover' => 'border-color: {{VALUE}};',
570 ],
571 ]
572 );
573
574 $this->add_control(
575 'hover_animation',
576 [
577 'label' => esc_html__( 'Hover Animation', 'elementor' ),
578 'type' => Controls_Manager::HOVER_ANIMATION,
579 ]
580 );
581
582 $this->end_controls_section();
583 }
584
585 /**
586 * Render social icons widget output on the frontend.
587 *
588 * Written in PHP and used to generate the final HTML.
589 *
590 * @since 1.0.0
591 * @access protected
592 */
593 protected function render() {
594 $settings = $this->get_settings_for_display();
595
596 $this->add_render_attribute( 'wrapper', 'class', [ 'elementor-social-icons-wrapper', 'elementor-grid' ] );
597 $this->add_render_attribute( 'item_wrapper', 'class', 'elementor-grid-item' );
598
599 if ( count( $settings['social_icon_list'] ) > 1 ) {
600 $this->add_render_attribute( 'wrapper', 'role', 'list' );
601 $this->add_render_attribute( 'item_wrapper', 'role', 'listitem' );
602 }
603
604 $fallback_defaults = [
605 'fa fa-facebook',
606 'fa fa-twitter',
607 'fa fa-google-plus',
608 ];
609
610 $class_animation = '';
611
612 if ( ! empty( $settings['hover_animation'] ) ) {
613 $class_animation = ' elementor-animation-' . $settings['hover_animation'];
614 }
615
616 $migration_allowed = Icons_Manager::is_migration_allowed();
617
618 ?>
619 <div <?php $this->print_render_attribute_string( 'wrapper' ); ?>>
620 <?php
621 foreach ( $settings['social_icon_list'] as $index => $item ) {
622 $migrated = isset( $item['__fa4_migrated']['social_icon'] );
623 $is_new = empty( $item['social'] ) && $migration_allowed;
624 $social = '';
625
626 // add old default
627 if ( empty( $item['social'] ) && ! $migration_allowed ) {
628 $item['social'] = isset( $fallback_defaults[ $index ] ) ? $fallback_defaults[ $index ] : 'fa fa-wordpress';
629 }
630
631 if ( ! empty( $item['social'] ) ) {
632 $social = str_replace( 'fa fa-', '', $item['social'] );
633 }
634
635 if ( ( $is_new || $migrated ) && 'svg' !== $item['social_icon']['library'] ) {
636 $social = explode( ' ', $item['social_icon']['value'], 2 );
637 if ( empty( $social[1] ) ) {
638 $social = '';
639 } else {
640 $social = str_replace( 'fa-', '', $social[1] );
641 }
642 }
643 if ( 'svg' === $item['social_icon']['library'] ) {
644 $social = get_post_meta( $item['social_icon']['value']['id'], '_wp_attachment_image_alt', true );
645 }
646
647 $link_key = 'link_' . $index;
648
649 $this->add_render_attribute( $link_key, 'class', [
650 'elementor-icon',
651 'elementor-social-icon',
652 'elementor-social-icon-' . $social . $class_animation,
653 'elementor-repeater-item-' . $item['_id'],
654 ] );
655
656 $this->add_link_attributes( $link_key, $item['link'] );
657
658 ?>
659 <span <?php $this->print_render_attribute_string( 'item_wrapper' ); ?>>
660 <a <?php $this->print_render_attribute_string( $link_key ); ?>>
661 <span class="elementor-screen-only"><?php echo esc_html( ucwords( $social ) ); ?></span>
662 <?php
663 if ( $is_new || $migrated ) {
664 Icons_Manager::render_icon( $item['social_icon'], [ 'aria-hidden' => 'true' ] );
665 } else { ?>
666 <i class="<?php echo esc_attr( $item['social'] ); ?>" aria-hidden="true"></i>
667 <?php } ?>
668 </a>
669 </span>
670 <?php } ?>
671 </div>
672 <?php
673 }
674
675 /**
676 * Render social icons widget output in the editor.
677 *
678 * Written as a Backbone JavaScript template and used to generate the live preview.
679 *
680 * @since 2.9.0
681 * @access protected
682 */
683 protected function content_template() {
684 ?>
685 <#
686 view.addRenderAttribute( 'wrapper', 'class', [ 'elementor-social-icons-wrapper', 'elementor-grid' ] );
687 view.addRenderAttribute( 'item_wrapper', 'class', 'elementor-grid-item' );
688
689 if ( settings.social_icon_list.length > 1 ) {
690 view.addRenderAttribute( 'wrapper', 'role', 'list' );
691 view.addRenderAttribute( 'item_wrapper', 'role', 'listitem' );
692 }
693
694 var iconsHTML = {};
695 #>
696 <div {{{ view.getRenderAttributeString( 'wrapper' ) }}}>
697 <# _.each( settings.social_icon_list, function( item, index ) {
698 var link = item.link ? item.link.url : '',
699 migrated = elementor.helpers.isIconMigrated( item, 'social_icon' );
700 social = elementor.helpers.getSocialNetworkNameFromIcon( item.social_icon, item.social, false, migrated );
701 #>
702 <span {{{ view.getRenderAttributeString( 'item_wrapper' ) }}}>
703 <a class="elementor-icon elementor-social-icon elementor-social-icon-{{ social }} elementor-animation-{{ settings.hover_animation }} elementor-repeater-item-{{item._id}}" href="{{ elementor.helpers.sanitizeUrl( link ) }}">
704 <span class="elementor-screen-only">{{{ social }}}</span>
705 <#
706 iconsHTML[ index ] = elementor.helpers.renderIcon( view, item.social_icon, {}, 'i', 'object' );
707 if ( ( ! item.social || migrated ) && iconsHTML[ index ] && iconsHTML[ index ].rendered ) { #>
708 {{{ iconsHTML[ index ].value }}}
709 <# } else { #>
710 <i class="{{ item.social }}"></i>
711 <# }
712 #>
713 </a>
714 </span>
715 <# } ); #>
716 </div>
717 <?php
718 }
719 }
720