Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
71.77% covered (warning)
71.77%
389 / 542
15.38% covered (danger)
15.38%
2 / 13
CRAP
0.00% covered (danger)
0.00%
0 / 1
jetpack_widget_social_icons_load
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
Jetpack_Widget_Social_Icons
72.30% covered (warning)
72.30%
389 / 538
16.67% covered (danger)
16.67%
2 / 12
90.95
0.00% covered (danger)
0.00%
0 / 1
 __construct
92.00% covered (success)
92.00%
23 / 25
0.00% covered (danger)
0.00%
0 / 1
3.00
 hide_widget_in_block_editor
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 enqueue_admin_scripts
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 enqueue_icon_scripts
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 render_admin_js
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 include_svg_icons
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
56
 widget
76.09% covered (warning)
76.09%
35 / 46
0.00% covered (danger)
0.00%
0 / 1
15.31
 update
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
56
 form
0.00% covered (danger)
0.00%
0 / 52
0.00% covered (danger)
0.00%
0 / 1
56
 render_icons_template
0.00% covered (danger)
0.00%
0 / 22
0.00% covered (danger)
0.00%
0 / 1
2
 get_svg_icon
84.62% covered (warning)
84.62%
11 / 13
0.00% covered (danger)
0.00%
0 / 1
3.03
 get_supported_icons
100.00% covered (success)
100.00%
319 / 319
100.00% covered (success)
100.00%
1 / 1
1
1<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3if ( ! defined( 'ABSPATH' ) ) {
4    exit( 0 );
5}
6
7// phpcs:disable Universal.Files.SeparateFunctionsFromOO.Mixed -- TODO: Move classes to appropriately-named class files.
8
9/**
10 * Social Icons Widget.
11 */
12class Jetpack_Widget_Social_Icons extends WP_Widget {
13
14    const ID_BASE = 'jetpack_widget_social_icons';
15
16    /**
17     * Default widget options.
18     *
19     * @var array Default widget options.
20     */
21    protected $defaults;
22
23    /**
24     * Widget constructor.
25     */
26    public function __construct() {
27        global $pagenow;
28
29        $widget_ops = array(
30            'classname'                   => 'jetpack_widget_social_icons',
31            'description'                 => __( 'Add social-media icons to your site.', 'jetpack' ),
32            'show_instance_in_rest'       => true,
33            'customize_selective_refresh' => true,
34        );
35
36        parent::__construct(
37            'jetpack_widget_social_icons',
38            /** This filter is documented in modules/widgets/facebook-likebox.php */
39            apply_filters( 'jetpack_widget_name', __( 'Social Icons', 'jetpack' ) ),
40            $widget_ops
41        );
42
43        $this->defaults = array(
44            'title'     => __( 'Follow Us', 'jetpack' ),
45            'icon-size' => 'medium',
46            'new-tab'   => false,
47            'icons'     => array(
48                array(
49                    'url' => '',
50                ),
51            ),
52        );
53
54        // Enqueue admin scrips and styles, only in the customizer or the old widgets page.
55        if ( is_customize_preview() || 'widgets.php' === $pagenow ) {
56            add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_scripts' ) );
57            add_action( 'admin_print_footer_scripts', array( $this, 'render_admin_js' ) );
58        }
59
60        add_filter( 'widget_types_to_hide_from_legacy_widget_block', array( $this, 'hide_widget_in_block_editor' ) );
61    }
62
63    /**
64     * Remove the "Social Icons" widget from the Legacy Widget block
65     *
66     * @param array $widget_types List of widgets that are currently removed from the Legacy Widget block.
67     * @return array $widget_types New list of widgets that will be removed.
68     */
69    public function hide_widget_in_block_editor( $widget_types ) {
70        $widget_types[] = self::ID_BASE;
71        return $widget_types;
72    }
73
74    /**
75     * Script & styles for admin widget form.
76     */
77    public function enqueue_admin_scripts() {
78        wp_enqueue_script(
79            'jetpack-widget-social-icons-script',
80            plugins_url( 'social-icons/social-icons-admin.js', __FILE__ ),
81            array( 'jquery', 'jquery-ui-sortable' ),
82            '20170506',
83            true
84        );
85        wp_enqueue_style(
86            'jetpack-widget-social-icons-admin',
87            plugins_url( 'social-icons/social-icons-admin.css', __FILE__ ),
88            array(),
89            '20170506'
90        );
91    }
92
93    /**
94     * Styles for front-end widget.
95     */
96    public function enqueue_icon_scripts() {
97        wp_enqueue_style( 'jetpack-widget-social-icons-styles', plugins_url( 'social-icons/social-icons.css', __FILE__ ), array(), '20170506' );
98    }
99
100    /**
101     * JavaScript for admin widget form.
102     */
103    public function render_admin_js() {
104        ?>
105        <script type="text/html" id="tmpl-jetpack-widget-social-icons-template">
106            <?php self::render_icons_template(); ?>
107        </script>
108        <?php
109    }
110
111    /**
112     * Add SVG definitions to the footer.
113     */
114    public function include_svg_icons() {
115        // Define SVG sprite file in Jetpack.
116        $svg_icons = dirname( __DIR__ ) . '/theme-tools/social-menu/social-menu.svg';
117        $svg_icons = class_exists( 'Automattic\Jetpack\Classic_Theme_Helper\Main' ) ? JETPACK__PLUGIN_DIR . 'jetpack_vendor/automattic/jetpack-classic-theme-helper/src/social-menu/social-menu.svg' : dirname( __DIR__ ) . '/theme-tools/social-menu/social-menu.svg';
118        // Define SVG sprite file in WPCOM.
119        if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
120            $svg_icons = class_exists( 'Automattic\Jetpack\Classic_Theme_Helper\Main' ) ? JETPACK__PLUGIN_DIR . 'jetpack_vendor/automattic/jetpack-classic-theme-helper/src/social-menu/social-menu.svg' : dirname( __DIR__ ) . '/social-menu/social-menu.svg';
121        }
122
123        // If it exists, include it.
124        if ( is_file( $svg_icons ) ) {
125            $svg_contents = file_get_contents( $svg_icons ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents -- Only reading a local file.
126        }
127
128        if ( ! empty( $svg_contents ) ) {
129            $allowed_tags = array(
130                'svg'    => array(
131                    'style'       => true,
132                    'version'     => true,
133                    'xmlns'       => true,
134                    'xmlns:xlink' => true,
135                ),
136                'defs'   => array(),
137                'symbol' => array(
138                    'id'      => true,
139                    'viewbox' => true,
140                ),
141                'path'   => array(
142                    'd'     => true,
143                    'style' => true,
144                ),
145            );
146            echo wp_kses( $svg_contents, $allowed_tags );
147        }
148    }
149
150    /**
151     * Front-end display of widget.
152     *
153     * @see WP_Widget::widget()
154     *
155     * @param array $args Widget arguments.
156     * @param array $instance Saved values from database.
157     */
158    public function widget( $args, $instance ) {
159        $instance = wp_parse_args( $instance, $this->defaults );
160
161        // Enqueue front end assets.
162        $this->enqueue_icon_scripts();
163        add_action( 'wp_footer', array( $this, 'include_svg_icons' ), 9999 );
164
165        /** This filter is documented in wp-includes/widgets/class-wp-widget-pages.php */
166        $title = apply_filters( 'widget_title', $instance['title'], $instance, $this->id_base );
167
168        echo $args['before_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
169
170        if ( ! empty( $title ) ) {
171            echo $args['before_title'] . $title . $args['after_title']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
172        }
173
174        if ( ! empty( $instance['icons'] ) ) :
175
176            // Get supported social icons.
177            $social_icons = $this->get_supported_icons();
178            $default_icon = $this->get_svg_icon( array( 'icon' => 'chain' ) );
179
180            ?>
181
182            <ul class="jetpack-social-widget-list size-<?php echo esc_attr( $instance['icon-size'] ); ?>">
183
184                <?php foreach ( $instance['icons'] as $icon ) : ?>
185
186                    <?php if ( ! empty( $icon['url'] ) ) : ?>
187                        <li class="jetpack-social-widget-item">
188                            <?php
189                            printf(
190                                '<a href="%1$s" %2$s>',
191                                esc_url( $icon['url'], array( 'http', 'https', 'mailto', 'sms' ) ),
192                                true === $instance['new-tab'] ?
193                                    'target="_blank" rel="noopener noreferrer"' :
194                                    'target="_self"'
195                            );
196
197                            $found_icon = false;
198
199                            foreach ( $social_icons as $social_icon ) {
200                                foreach ( $social_icon['url'] as $url_fragment ) {
201                                    /*
202                                     * url_fragment can be a URL host, or a regex, starting with #.
203                                     * Let's check for both scenarios.
204                                     */
205                                    if (
206                                        // First Regex.
207                                        (
208                                            str_starts_with( $url_fragment, '#' ) && str_ends_with( $url_fragment, '#' )
209                                            && preg_match( $url_fragment, $icon['url'] )
210                                        )
211                                        // Then, regular host name.
212                                        || str_contains( $icon['url'], $url_fragment )
213                                    ) {
214                                        printf(
215                                            '<span class="screen-reader-text">%1$s</span>%2$s',
216                                            esc_attr( $social_icon['label'] ),
217                                            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
218                                            $this->get_svg_icon(
219                                                array(
220                                                    'icon' => esc_attr( $social_icon['icon'] ),
221                                                )
222                                            )
223                                        );
224                                        $found_icon = true;
225                                        break 2;
226                                    }
227                                }
228                            }
229
230                            if ( ! $found_icon ) {
231                                echo $default_icon; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
232                            }
233                            ?>
234                            </a>
235                        </li>
236                    <?php endif; ?>
237
238                <?php endforeach; ?>
239
240            </ul>
241
242            <?php
243        endif;
244
245        echo $args['after_widget']; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
246
247        /** This action is documented in modules/widgets/gravatar-profile.php */
248        do_action( 'jetpack_stats_extra', 'widget_view', 'social_icons' );
249    }
250
251    /**
252     * Sanitize widget form values as they are saved.
253     *
254     * @see WP_Widget::update()
255     *
256     * @param array $new_instance Values just sent to be saved.
257     * @param array $old_instance Previously saved values from database.
258     *
259     * @return array Updated safe values to be saved.
260     */
261    public function update( $new_instance, $old_instance ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
262        $instance = array();
263
264        $instance['title']     = sanitize_text_field( $new_instance['title'] );
265        $instance['icon-size'] = $this->defaults['icon-size'];
266        $instance['url-icons'] = array_key_exists( 'url-icons', $new_instance ) ? $new_instance['url-icons'] : array();
267
268        if ( in_array( $new_instance['icon-size'], array( 'small', 'medium', 'large' ), true ) ) {
269            $instance['icon-size'] = $new_instance['icon-size'];
270        }
271
272        $instance['new-tab'] = isset( $new_instance['new-tab'] ) ? (bool) $new_instance['new-tab'] : false;
273        $instance['icons']   = array();
274
275        if ( array_key_exists( 'url-icons', $new_instance ) ) {
276            foreach ( $new_instance['url-icons'] as $url ) {
277                $url = filter_var( $url, FILTER_SANITIZE_URL );
278
279                if ( ! empty( $url ) ) {
280                    $instance['icons'][] = array(
281                        'url' => $url,
282                    );
283                }
284            }
285        }
286
287        return $instance;
288    }
289
290    /**
291     * Back-end widget form.
292     *
293     * @see WP_Widget::form()
294     *
295     * @param array $instance Previously saved values from database.
296     *
297     * @return string|void
298     */
299    public function form( $instance ) {
300        $instance = wp_parse_args( $instance, $this->defaults );
301        $title    = sanitize_text_field( $instance['title'] );
302        $sizes    = array(
303            'small'  => __( 'Small', 'jetpack' ),
304            'medium' => __( 'Medium', 'jetpack' ),
305            'large'  => __( 'Large', 'jetpack' ),
306        );
307        $new_tab  = isset( $instance['new-tab'] ) ? (bool) $instance['new-tab'] : false;
308        ?>
309
310        <p>
311            <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_html_e( 'Title:', 'jetpack' ); ?></label>
312            <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" />
313        </p>
314
315        <p>
316            <label for="<?php echo esc_attr( $this->get_field_id( 'icon-size' ) ); ?>"><?php esc_html_e( 'Size:', 'jetpack' ); ?></label>
317            <select class="widefat" name="<?php echo esc_attr( $this->get_field_name( 'icon-size' ) ); ?>">
318                <?php foreach ( $sizes as $value => $label ) : ?>
319                    <option value="<?php echo esc_attr( $value ); ?><?php selected( $value, $instance['icon-size'] ); ?>><?php echo esc_attr( $label ); ?></option>
320                <?php endforeach; ?>
321            </select>
322        </p>
323
324        <div class="jetpack-social-icons-widget-list"
325            data-url-icon-id="<?php echo esc_attr( $this->get_field_id( 'url-icons' ) ); ?>"
326            data-url-icon-name="<?php echo esc_attr( $this->get_field_name( 'url-icons' ) ); ?>"
327        >
328
329            <?php
330            foreach ( $instance['icons'] as $icon ) {
331                self::render_icons_template(
332                    array(
333                        'url-icon-id'   => $this->get_field_id( 'url-icons' ),
334                        'url-icon-name' => $this->get_field_name( 'url-icons' ),
335                        'url-value'     => $icon['url'],
336                    )
337                );
338            }
339            ?>
340
341        </div>
342
343        <p class="jetpack-social-icons-widget add-button">
344            <button type="button" class="button jetpack-social-icons-add-button">
345                <?php esc_html_e( 'Add an icon', 'jetpack' ); ?>
346            </button>
347        </p>
348
349        <?php
350        $lang = strtolower( substr( get_locale(), 0, 2 ) );
351        switch ( $lang ) {
352            case 'es':
353                $support = 'https://wordpress.com/es/support/wordpress-editor/blocks/social-icons-block/display-social-profiles/#iconos-sociales-compatibles';
354                break;
355
356            case 'pt':
357                $support = 'https://wordpress.com/pt-br/support/exibir-perfis-de-redes-sociais/#icones-de-redes-sociais-compativeis';
358                break;
359
360            default:
361                $support = 'https://wordpress.com/support/wordpress-editor/blocks/social-icons-block/display-social-profiles/#supported-social-icons';
362                break;
363        }
364        ?>
365
366        <p>
367            <em><a href="<?php echo esc_url( $support ); ?>" target="_blank" rel="noopener noreferrer">
368                <?php esc_html_e( 'View available icons', 'jetpack' ); ?>
369            </a></em>
370        </p>
371
372        <p>
373            <input type="checkbox" class="checkbox" id="<?php echo esc_attr( $this->get_field_id( 'new-tab' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'new-tab' ) ); ?><?php checked( $new_tab ); ?> />
374            <label for="<?php echo esc_attr( $this->get_field_id( 'new-tab' ) ); ?>"><?php esc_html_e( 'Open link in a new tab', 'jetpack' ); ?></label>
375        </p>
376
377        <?php
378    }
379
380    /**
381     * Generates template to add icons.
382     *
383     * @param array $args Template arguments.
384     */
385    private static function render_icons_template( $args = array() ) {
386        $defaults = array(
387            'url-icon-id'   => '',
388            'url-icon-name' => '',
389            'url-value'     => '',
390        );
391
392        $args = wp_parse_args( $args, $defaults );
393        ?>
394
395        <div class="jetpack-social-icons-widget-item">
396            <div class="jetpack-social-icons-widget-item-wrapper">
397                <div class="handle"></div>
398
399                <p class="jetpack-widget-social-icons-url">
400                    <?php
401                        printf(
402                            '<input class="widefat" id="%1$s" name="%2$s[]" type="text" placeholder="%3$s" value="%4$s"/>',
403                            esc_attr( $args['url-icon-id'] ),
404                            esc_attr( $args['url-icon-name'] ),
405                            esc_attr__( 'Account URL', 'jetpack' ),
406                            esc_url( $args['url-value'], array( 'http', 'https', 'mailto', 'sms' ) )
407                        );
408                    ?>
409                </p>
410
411                <p class="jetpack-widget-social-icons-remove-item">
412                    <a class="jetpack-widget-social-icons-remove-item-button" href="javascript:;">
413                        <?php esc_html_e( 'Remove', 'jetpack' ); ?>
414                    </a>
415                </p>
416            </div>
417        </div>
418
419        <?php
420    }
421
422    /**
423     * Return SVG markup.
424     *
425     * @param array $args {
426     *     Parameters needed to display an SVG.
427     *
428     *     @type string $icon  Required SVG icon filename.
429     * }
430     * @return string SVG markup.
431     */
432    public function get_svg_icon( $args = array() ) {
433        // Make sure $args are an array.
434        if ( empty( $args ) ) {
435            return esc_html__( 'Please define default parameters in the form of an array.', 'jetpack' );
436        }
437
438        // Set defaults.
439        $defaults = array(
440            'icon' => '',
441        );
442
443        // Parse args.
444        $args = wp_parse_args( $args, $defaults );
445
446        // Define an icon.
447        if ( false === array_key_exists( 'icon', $args ) ) {
448            return esc_html__( 'Please define an SVG icon filename.', 'jetpack' );
449        }
450
451        // Set aria hidden.
452        $aria_hidden = ' aria-hidden="true"';
453
454        // Begin SVG markup.
455        $svg = '<svg class="icon icon-' . esc_attr( $args['icon'] ) . '"' . $aria_hidden . ' role="presentation">';
456
457        /*
458         * Display the icon.
459         *
460         * The whitespace around `<use>` is intentional - it is a work around to a keyboard navigation bug in Safari 10.
461         *
462         * See https://core.trac.wordpress.org/ticket/38387.
463         */
464        $svg .= ' <use href="#icon-' . esc_html( $args['icon'] ) . '" xlink:href="#icon-' . esc_html( $args['icon'] ) . '"></use> ';
465
466        $svg .= '</svg>';
467
468        return $svg;
469    }
470
471    /**
472     * Returns an array of supported social links (URL, icon, and label).
473     *
474     * @return array $social_links_icons
475     */
476    public function get_supported_icons() {
477        $social_links_icons = array(
478            array(
479                'url'   => array( '500px.com' ),
480                'icon'  => '500px',
481                'label' => '500px',
482            ),
483            array(
484                'url'   => array(
485                    '#https?:\/\/(www\.)?amazon\.(com|cn|in|fr|de|it|nl|es|co|ca)\/#',
486                ),
487                'icon'  => 'amazon',
488                'label' => 'Amazon',
489            ),
490            array(
491                'url'   => array( 'apple.com' ),
492                'icon'  => 'apple',
493                'label' => 'Apple',
494            ),
495            array(
496                'url'   => array( 'itunes.com' ),
497                'icon'  => 'apple',
498                'label' => 'iTunes',
499            ),
500            array(
501                'url'   => array( 'bandcamp.com' ),
502                'icon'  => 'bandcamp',
503                'label' => 'Bandcamp',
504            ),
505            array(
506                'url'   => array( 'behance.net' ),
507                'icon'  => 'behance',
508                'label' => 'Behance',
509            ),
510            array(
511                'url'   => array(
512                    'blogger.com',
513                    'blogspot.com',
514                ),
515                'icon'  => 'blogger',
516                'label' => 'Blogger',
517            ),
518            array(
519                'url'   => array( 'bsky.app' ),
520                'icon'  => 'bluesky',
521                'label' => 'Bluesky',
522            ),
523            array(
524                'url'   => array( 'codepen.io' ),
525                'icon'  => 'codepen',
526                'label' => 'CodePen',
527            ),
528            array(
529                'url'   => array( 'deviantart.com' ),
530                'icon'  => 'deviantart',
531                'label' => 'DeviantArt',
532            ),
533            array(
534                'url'   => array( 'digg.com' ),
535                'icon'  => 'digg',
536                'label' => 'Digg',
537            ),
538            array(
539                'url'   => array( '#discord\.gg|discordapp\.com#' ),
540                'icon'  => 'discord',
541                'label' => 'Discord',
542            ),
543            array(
544                'url'   => array( 'dribbble.com' ),
545                'icon'  => 'dribbble',
546                'label' => 'Dribbble',
547            ),
548            array(
549                'url'   => array( 'dropbox.com' ),
550                'icon'  => 'dropbox',
551                'label' => 'Dropbox',
552            ),
553            array(
554                'url'   => array( 'etsy.com' ),
555                'icon'  => 'etsy',
556                'label' => 'Etsy',
557            ),
558            array(
559                'url'   => array( 'eventbrite.com' ),
560                'icon'  => 'eventbrite',
561                'label' => 'Eventbrite',
562            ),
563            array(
564                'url'   => array( 'facebook.com' ),
565                'icon'  => 'facebook',
566                'label' => 'Facebook',
567            ),
568            array(
569                'url'   => array( 'flickr.com' ),
570                'icon'  => 'flickr',
571                'label' => 'Flickr',
572            ),
573            array(
574                'url'   => array( 'foursquare.com' ),
575                'icon'  => 'foursquare',
576                'label' => 'Foursquare',
577            ),
578            array(
579                'url'   => array( 'ghost.org' ),
580                'icon'  => 'ghost',
581                'label' => 'Ghost',
582            ),
583            array(
584                'url'   => array( 'goodreads.com' ),
585                'icon'  => 'goodreads',
586                'label' => 'Goodreads',
587            ),
588            array(
589                'url'   => array( '#google\.(com|co\.uk|ca|cn|it)#' ),
590                'icon'  => 'google',
591                'label' => 'Google',
592            ),
593            array(
594                'url'   => array( 'github.com' ),
595                'icon'  => 'github',
596                'label' => 'GitHub',
597            ),
598            array(
599                'url'   => array( 'instagram.com' ),
600                'icon'  => 'instagram',
601                'label' => 'Instagram',
602            ),
603            array(
604                'url'   => array( 'linkedin.com' ),
605                'icon'  => 'linkedin',
606                'label' => 'LinkedIn',
607            ),
608            array(
609                'url'   => array( 'mailto:' ),
610                'icon'  => 'mail',
611                'label' => __( 'Email', 'jetpack' ),
612            ),
613            array(
614                'url'   => jetpack_mastodon_get_instance_list(),
615                'icon'  => 'mastodon',
616                'label' => 'Mastodon',
617            ),
618            array(
619                'url'   => array( 'meetup.com' ),
620                'icon'  => 'meetup',
621                'label' => 'Meetup',
622            ),
623            array(
624                'url'   => array( 'medium.com' ),
625                'icon'  => 'medium',
626                'label' => 'Medium',
627            ),
628            array(
629                'url'   => array( 'nextdoor.com' ),
630                'icon'  => 'nextdoor',
631                'label' => 'Nextdoor',
632            ),
633            array(
634                'url'   => array( 'patreon.com' ),
635                'icon'  => 'patreon',
636                'label' => 'Patreon',
637            ),
638            array(
639                'url'   => array( 'pinterest.' ),
640                'icon'  => 'pinterest',
641                'label' => 'Pinterest',
642            ),
643            array(
644                'url'   => array( 'ravelry.com' ),
645                'icon'  => 'ravelry',
646                'label' => 'Ravelry',
647            ),
648            array(
649                'url'   => array( 'reddit.com' ),
650                'icon'  => 'reddit',
651                'label' => 'Reddit',
652            ),
653            array(
654                'url'   => array( 'slideshare.net' ),
655                'icon'  => 'slideshare',
656                'label' => 'SlideShare',
657            ),
658            array(
659                'url'   => array( 'sms:' ),
660                'icon'  => 'sms',
661                'label' => 'SMS',
662            ),
663            array(
664                'url'   => array( 'snapchat.com' ),
665                'icon'  => 'snapchat',
666                'label' => 'Snapchat',
667            ),
668            array(
669                'url'   => array( 'soundcloud.com' ),
670                'icon'  => 'soundcloud',
671                'label' => 'SoundCloud',
672            ),
673            array(
674                'url'   => array( 'spotify.com' ),
675                'icon'  => 'spotify',
676                'label' => 'Spotify',
677            ),
678            array(
679                'url'   => array( 'stackoverflow.com' ),
680                'icon'  => 'stackoverflow',
681                'label' => 'Stack Overflow',
682            ),
683            array(
684                'url'   => array( 'strava.com' ),
685                'icon'  => 'strava',
686                'label' => 'Strava',
687            ),
688            array(
689                'url'   => array( 'stumbleupon.com' ),
690                'icon'  => 'stumbleupon',
691                'label' => 'StumbleUpon',
692            ),
693            array(
694                'url'   => array( '#https?:\/\/(www\.)?(telegram|t)\.me#' ),
695                'icon'  => 'telegram',
696                'label' => 'Telegram',
697            ),
698            array(
699                'url'   => array( 'threads.net' ),
700                'icon'  => 'threads',
701                'label' => 'Threads',
702            ),
703            array(
704                'url'   => array( 'tiktok.com' ),
705                'icon'  => 'tiktok',
706                'label' => 'TikTok',
707            ),
708            array(
709                'url'   => array( 'tumblr.com' ),
710                'icon'  => 'tumblr',
711                'label' => 'Tumblr',
712            ),
713            array(
714                'url'   => array( 'twitch.tv' ),
715                'icon'  => 'twitch',
716                'label' => 'Twitch',
717            ),
718            array(
719                'url'   => array( 'vimeo.com' ),
720                'icon'  => 'vimeo',
721                'label' => 'Vimeo',
722            ),
723            array(
724                'url'   => array( 'vk.com' ),
725                'icon'  => 'vk',
726                'label' => 'VK',
727            ),
728            array(
729                'url'   => array( 'whatsapp.com' ),
730                'icon'  => 'whatsapp',
731                'label' => 'WhatsApp',
732            ),
733            array(
734                'url'   => array( 'woocommerce.com' ),
735                'icon'  => 'woocommerce',
736                'label' => 'WooCommerce',
737            ),
738            array(
739                'url'   => array( '#wordpress\.(com|org)#' ),
740                'icon'  => 'wordpress',
741                'label' => 'WordPress',
742            ),
743            array(
744                'url'   => array( 'yelp.com' ),
745                'icon'  => 'yelp',
746                'label' => 'Yelp',
747            ),
748            array(
749                'url'   => array( '#^https?:\/\/(www\.)?(twitter|x)\.com#' ),
750                'icon'  => 'x',
751                'label' => 'X',
752            ),
753            array(
754                'url'   => array( 'xanga.com' ),
755                'icon'  => 'xanga',
756                'label' => 'Xanga',
757            ),
758            array(
759                'url'   => array( 'youtube.com' ),
760                'icon'  => 'youtube',
761                'label' => 'YouTube',
762            ),
763
764            // keep feed at the end so that more specific icons can take precedence.
765            array(
766                'url'   => array(
767                    '/feed/',         // WordPress default feed url.
768                    '/feeds/',        // Blogspot and others.
769                    '/blog/feed',     // No trailing slash WordPress feed, could use /feed but may match unexpectedly.
770                    'format=RSS',     // Squarespace and others.
771                    '/rss',           // Tumblr.
772                    '/.rss',          // Reddit.
773                    '/rss.xml',       // Moveable Type, Typepad.
774                    'http://rss.',    // Old custom format.
775                    'https://rss.',   // Old custom format.
776                    'rss=1',
777                    '/feed=rss',      // Catches feed=rss / feed=rss2.
778                    '?feed=rss',      // WordPress non-permalink - Catches feed=rss / feed=rss2.
779                    '?feed=rdf',      // WordPress non-permalink.
780                    '?feed=atom',     // WordPress non-permalink.
781                    'http://feeds.',  // FeedBurner.
782                    'https://feeds.', // FeedBurner.
783                    '/feed.xml',      // Feedburner Alias, and others.
784                    '/index.xml',     // Moveable Type, and others.
785                    '/atom.xml',      // Typepad, Squarespace.
786                    '.atom',          // Shopify blog.
787                    '/atom',          // Some non-WordPress feeds.
788                    'index.rdf',      // Typepad.
789                ),
790                'icon'  => 'feed',
791                'label' => __( 'RSS Feed', 'jetpack' ),
792            ),
793        );
794
795        /**
796         * Filter the list of services matching Social Media Icons available in the Social Icons SVG sprite.
797         *
798         * @since 12.3
799         *
800         * @param array $social_links_icons Array of social links icons.
801         */
802        return apply_filters(
803            'jetpack_social_icons_supported_icons',
804            $social_links_icons
805        );
806    }
807} // Jetpack_Widget_Social_Icons
808
809/**
810 * Register and load the widget.
811 *
812 * @access public
813 * @return void
814 */
815function jetpack_widget_social_icons_load() {
816    register_widget( 'Jetpack_Widget_Social_Icons' );
817}
818add_action( 'widgets_init', 'jetpack_widget_social_icons_load' );