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