Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
54.35% covered (warning)
54.35%
25 / 46
66.67% covered (warning)
66.67%
2 / 3
CRAP
n/a
0 / 0
jetpack_spotify_shortcode
50.00% covered (danger)
50.00%
16 / 32
0.00% covered (danger)
0.00%
0 / 1
26.12
jetpack_spotify_embed_ids
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
5
jetpack_spotify_embed_ids_callback
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2/**
3 * Spotify shortcode.
4 *
5 * Usage:
6 * [spotify id="spotify:track:4bz7uB4edifWKJXSDxwHcs" width="400" height="100"]
7 *
8 * @package automattic/jetpack
9 */
10
11if ( ! defined( 'ABSPATH' ) ) {
12    exit( 0 );
13}
14
15if ( ! shortcode_exists( 'spotify' ) ) {
16    add_shortcode( 'spotify', 'jetpack_spotify_shortcode' );
17}
18
19/**
20 * Parse shortcode arguments and render its output.
21 *
22 * @since 4.5.0
23 *
24 * @param array  $atts    Shortcode attributes.
25 * @param string $content Post Content.
26 *
27 * @return string
28 */
29function jetpack_spotify_shortcode( $atts = array(), $content = '' ) {
30    if ( ! is_array( $atts ) ) {
31        $atts = array();
32    }
33
34    if ( ! empty( $content ) ) {
35        $id = $content;
36    } elseif ( ! empty( $atts['id'] ) ) {
37        $id = $atts['id'];
38    } elseif ( ! empty( $atts[0] ) ) {
39        $id = $atts[0];
40    } else {
41        return '<!-- Missing Spotify ID -->';
42    }
43
44    if ( empty( $atts['width'] ) ) {
45        $atts['width'] = 300;
46    }
47
48    if ( empty( $atts['height'] ) ) {
49        $atts['height'] = 380;
50    }
51
52    $atts['width']  = (int) $atts['width'];
53    $atts['height'] = (int) $atts['height'];
54
55    // Spotify accepts both URLs and their Spotify ID format, so let them sort it out and validate.
56    $embed_url = add_query_arg( 'uri', rawurlencode( $id ), 'https://embed.spotify.com/' );
57
58    // If the shortcode is displayed in a WPCOM notification, display a simple link only.
59    // When the shortcode is displayed in the WPCOM Reader, use iframe instead.
60    if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) {
61        require_once WP_CONTENT_DIR . '/lib/display-context.php';
62        $context = A8C\Display_Context\get_current_context();
63        if ( A8C\Display_Context\NOTIFICATIONS === $context ) {
64            return sprintf(
65                '<a href="%1$s" target="_blank" rel="noopener noreferrer">%1$s</a>',
66                esc_url( $id )
67            );
68        } elseif ( A8C\Display_Context\READER === $context ) {
69            return sprintf(
70                '<iframe src="%1$s" height="%2$s" width="%3$s"></iframe>',
71                esc_url( $embed_url ),
72                esc_attr( $atts['height'] ),
73                esc_attr( $atts['width'] )
74            );
75        }
76    }
77
78    return '<iframe src="' . esc_url( $embed_url ) . '" style="display:block; margin:0 auto; width:' . esc_attr( $atts['width'] ) . 'px; height:' . esc_attr( $atts['height'] ) . 'px;" frameborder="0" allowtransparency="true" loading="lazy"></iframe>';
79}
80
81/**
82 * Turn text like this on it's own line into an embed: spotify:track:4bz7uB4edifWKJXSDxwHcs
83 * The core WordPress embed functionality only works with URLs
84 * Modified version of WP_Embed::autoembed()
85 *
86 * @since 4.5.0
87 *
88 * @param string $content Post content.
89 *
90 * @return string
91 */
92function jetpack_spotify_embed_ids( $content ) {
93    $textarr = wp_html_split( $content );
94
95    foreach ( $textarr as &$element ) {
96        if ( '' === $element || '<' === $element[0] ) {
97            continue;
98        }
99
100        // If this element does not contain a Spotify embed, continue.
101        if ( ! str_contains( $element, 'spotify:' ) ) {
102            continue;
103        }
104
105        $element = preg_replace_callback( '|^\s*(spotify:[^\s"]+:[^\s"]+)\s*$|im', 'jetpack_spotify_embed_ids_callback', $element );
106    }
107
108    return implode( '', $textarr );
109}
110add_filter( 'the_content', 'jetpack_spotify_embed_ids', 7 );
111
112/**
113 * Call shortcode with ID provided by matching pattern.
114 *
115 * @since 4.5.0
116 *
117 * @param array $matches Array of matches for Spofify links.
118 *
119 * @return string
120 */
121function jetpack_spotify_embed_ids_callback( $matches ) {
122    return "\n" . jetpack_spotify_shortcode( array(), $matches[1] ) . "\n";
123}