PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.7
Jetpack – WP Security, Backup, Speed, & Growth v6.7
16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 13.9.2 14.0.1 14.1.1 14.2.2 14.3.1 All 501 releases
jetpack / modules / shortcodes / soundcloud.php

soundcloud.php in Jetpack – WP Security, Backup, Speed, & Growth 6.7, at modules/shortcodes/soundcloud.php

328 lines 10.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: SoundCloud Shortcode
4 Plugin URI: https://wordpress.org/extend/plugins/soundcloud-shortcode/
5 Description: Converts SoundCloud WordPress shortcodes to a SoundCloud widget. Example: [soundcloud]http://soundcloud.com/forss/flickermood[/soundcloud]
6 Version: 2.3
7 Author: SoundCloud Inc., simplified for Jetpack by Automattic, Inc.
8 Author URI: http://soundcloud.com
9 License: GPLv2
10
11 Original version: Johannes Wagener <johannes@soundcloud.com>
12 Options support: Tiffany Conroy <tiffany@soundcloud.com>
13 HTML5 & oEmbed support: Tim Bormans <tim@soundcloud.com>
14 */
15
16 /*
17 A8C: Taken from http://plugins.svn.wordpress.org/soundcloud-shortcode/trunk/
18 at revision 664386.
19
20 Commenting out (instead of removing) and replacing code with custom modifs
21 so it's eqsy to see what differs from the standard DOTORG version.
22
23 All custom modifs are annoted with "A8C" keyword in comment.
24 */
25
26 /**
27 * Register oEmbed provider
28 */
29
30 /*
31 A8C: oEmbed is handled now in core; see wp-includes/class-oembed.php
32 wp_oembed_add_provider( '#https?://(?:api\.)?soundcloud\.com/.*#i', 'http://soundcloud.com/oembed', true );
33 */
34
35
36 /**
37 * Register SoundCloud shortcode
38 */
39
40 add_shortcode( 'soundcloud', 'soundcloud_shortcode' );
41
42 /**
43 * SoundCloud shortcode handler
44 *
45 * @param string|array $atts The attributes passed to the shortcode like [soundcloud attr1="value" /].
46 * Is an empty string when no arguments are given.
47 * @param string $content The content between non-self closing [soundcloud]...[/soundcloud] tags.
48 *
49 * @return string Widget embed code HTML
50 */
51 function soundcloud_shortcode( $atts, $content = null ) {
52
53 // Custom shortcode options
54 $shortcode_options = array_merge( array( 'url' => trim( $content ) ), is_array( $atts ) ? $atts : array() );
55
56 // Turn shortcode option "param" (param=value&param2=value) into array
57 $shortcode_params = array();
58 if ( isset( $shortcode_options['params'] ) ) {
59 parse_str( html_entity_decode( $shortcode_options['params'] ), $shortcode_params );
60 }
61 $shortcode_options['params'] = $shortcode_params;
62
63 /*
64 A8C: The original plugin exposes options we don't. SoundCloud omits "visual" shortcode
65 option when false, so if logic here remains, impossible to have non-visual shortcode.
66 $player_type = soundcloud_get_option( 'player_type', 'visual' );
67 $isIframe = $player_type !== 'flash';
68 $isVisual = ! $player_type || $player_type === 'visual' || $shortcode_options['visual'];
69 */
70
71 // User preference options
72 $plugin_options = array_filter(
73 array(
74 'iframe' => true, // A8C: See above comment; flash is not a supported option
75 'width' => soundcloud_get_option( 'player_width' ),
76 'height' => soundcloud_url_has_tracklist( $shortcode_options['url'] ) ? soundcloud_get_option( 'player_height_multi' ) : soundcloud_get_option( 'player_height' ),
77 'params' => array_filter(
78 array(
79 'auto_play' => soundcloud_get_option( 'auto_play' ),
80 'show_comments' => soundcloud_get_option( 'show_comments' ),
81 'color' => soundcloud_get_option( 'color' ),
82 'visual' => 'false', // A8C: Merged with params below at $options assignment
83 )
84 ),
85 )
86 );
87
88 // Needs to be an array
89 if ( ! isset( $plugin_options['params'] ) ) {
90 $plugin_options['params'] = array();
91 }
92
93 // plugin options < shortcode options
94 $options = array_merge(
95 $plugin_options,
96 $shortcode_options
97 );
98
99 // plugin params < shortcode params
100 $options['params'] = array_merge(
101 $plugin_options['params'],
102 $shortcode_options['params']
103 );
104
105 // The "url" option is required
106 if ( ! isset( $options['url'] ) ) {
107 return '';
108 } else {
109 $options['url'] = trim( $options['url'] );
110 }
111
112 // Both "width" and "height" need to be integers
113 if ( isset( $options['width'] ) && ! preg_match( '/^\d+$/', $options['width'] ) ) {
114 // set to 0 so oEmbed will use the default 100% and WordPress themes will leave it alone
115 $options['width'] = 0;
116 }
117 if ( isset( $options['height'] ) && ! preg_match( '/^\d+$/', $options['height'] ) ) {
118 unset( $options['height'] );
119 }
120
121 // The "iframe" option must be true to load the iframe widget
122 $iframe = soundcloud_booleanize( $options['iframe'] );
123
124 // Remove visual parameter from Flash widget, when it's false because that's the default, or when displaying the smallest player
125 if ( $options['params']['visual'] && ( ! $iframe || ! soundcloud_booleanize( $options['params']['visual'] ) || ( isset( $options['height'] ) && '20' == $options['height'] ) ) ) {
126 unset( $options['params']['visual'] );
127 }
128
129 // Merge in "url" value
130 $options['params'] = array_merge(
131 array(
132 'url' => $options['url'],
133 ),
134 $options['params']
135 );
136
137 // Return html embed code
138 if ( $iframe ) {
139 return soundcloud_iframe_widget( $options );
140 } else {
141 return soundcloud_flash_widget( $options );
142 }
143 }
144
145 /**
146 * Plugin options getter
147 *
148 * @param string|array $option Option name
149 * @param mixed $default Default value
150 *
151 * @return mixed Option value
152 */
153 function soundcloud_get_option( $option, $default = false ) {
154 $value = get_option( 'soundcloud_' . $option );
155
156 return $value === '' ? $default : $value;
157 }
158
159 /**
160 * Booleanize a value
161 *
162 * @param boolean|string $value
163 *
164 * @return boolean
165 */
166 function soundcloud_booleanize( $value ) {
167 return is_bool( $value ) ? $value : $value === 'true' ? true : false;
168 }
169
170 /**
171 * Decide if a url has a tracklist
172 *
173 * @param string $url
174 *
175 * @return boolean
176 */
177 function soundcloud_url_has_tracklist( $url ) {
178 return preg_match( '/^(.+?)\/(sets|groups|playlists)\/(.+?)$/', $url );
179 }
180
181 /**
182 * Parameterize url
183 *
184 * @param array $match Matched regex
185 *
186 * @return string Parameterized url
187 */
188 function soundcloud_oembed_params_callback( $match ) {
189 global $soundcloud_oembed_params;
190
191 // Convert URL to array
192 $url = parse_url( urldecode( $match[1] ) );
193 // Convert URL query to array
194 parse_str( $url['query'], $query_array );
195 // Build new query string
196 $query = http_build_query( array_merge( $query_array, $soundcloud_oembed_params ) );
197
198 return 'src="' . $url['scheme'] . '://' . $url['host'] . $url['path'] . '?' . $query;
199 }
200
201 /**
202 * Iframe widget embed code
203 *
204 * @param array $options Parameters
205 *
206 * @return string Iframe embed code
207 */
208 function soundcloud_iframe_widget( $options ) {
209
210 // Build URL
211 $url = set_url_scheme( 'https://w.soundcloud.com/player/?' . http_build_query( $options['params'] ) );
212 // Set default width if not defined
213 $width = isset( $options['width'] ) && $options['width'] !== 0 ? $options['width'] : '100%';
214 // Set default height if not defined
215 $height = isset( $options['height'] ) && $options['height'] !== 0
216 ? $options['height']
217 : ( soundcloud_url_has_tracklist( $options['url'] ) || ( isset( $options['params']['visual'] ) && soundcloud_booleanize( $options['params']['visual'] ) ) ? '450' : '166' );
218
219 return sprintf( '<iframe width="%s" height="%s" scrolling="no" frameborder="no" src="%s"></iframe>', $width, $height, $url );
220 }
221
222 /**
223 * Legacy Flash widget embed code
224 *
225 * @param array $options Parameters
226 *
227 * @return string Flash embed code
228 */
229 function soundcloud_flash_widget( $options ) {
230 // Build URL
231 $url = set_url_scheme( 'https://player.soundcloud.com/player.swf?' . http_build_query( $options['params'] ) );
232 // Set default width if not defined
233 $width = isset( $options['width'] ) && $options['width'] !== 0 ? $options['width'] : '100%';
234 // Set default height if not defined
235 $height = isset( $options['height'] ) && $options['height'] !== 0 ? $options['height'] : ( soundcloud_url_has_tracklist( $options['url'] ) ? '255' : '81' );
236
237 return preg_replace(
238 '/\s\s+/',
239 '',
240 sprintf(
241 '<object width="%s" height="%s">
242 <param name="movie" value="%s" />
243 <param name="allowscriptaccess" value="always" />
244 <embed width="%s" height="%s" src="%s" allowscriptaccess="always" type="application/x-shockwave-flash"></embed>
245 </object>',
246 $width,
247 $height,
248 $url,
249 $width,
250 $height,
251 $url
252 )
253 );
254 }
255
256 /**
257 * SoundCloud Embed Reversal
258 *
259 * Converts a generic HTML embed code from SoundClound into a
260 * WordPress.com-compatibly shortcode.
261 *
262 * @param string $content HTML content.
263 *
264 * @return string Parsed content.
265 */
266 function jetpack_soundcloud_embed_reversal( $content ) {
267 if ( ! is_string( $content ) || false === stripos( $content, 'w.soundcloud.com/player' ) ) {
268 return $content;
269 }
270
271 /*
272 Sample embed code:
273
274 <iframe width="100%" height="450" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=https%3A//api.soundcloud.com/tracks/150745932&amp;auto_play=false&amp;hide_related=false&amp;show_comments=true&amp;show_user=true&amp;show_reposts=false&amp;visual=true"></iframe>
275 */
276
277 $regexes = array();
278
279 $regexes[] = '#<iframe[^>]+?src="((?:https?:)?//w\.soundcloud\.com/player/[^"\']++)"[^>]*+>\s*?</iframe>#i';
280 $regexes[] = '#&lt;iframe(?:[^&]|&(?!gt;))+?src="((?:https?:)?//w\.soundcloud\.com/player/[^"\']++)"(?:[^&]|&(?!gt;))*+&gt;\s*?&lt;/iframe&gt;#i';
281
282 foreach ( $regexes as $regex ) {
283 if ( ! preg_match_all( $regex, $content, $matches, PREG_SET_ORDER ) ) {
284 continue;
285 }
286
287 foreach ( $matches as $match ) {
288
289 // if pasted from the visual editor - prevent double encoding
290 $match[1] = str_replace( '&amp;amp;', '&amp;', $match[1] );
291
292 $args = parse_url( html_entity_decode( $match[1] ), PHP_URL_QUERY );
293 $args = wp_parse_args( $args );
294
295 if ( ! preg_match( '#^(?:https?:)?//api\.soundcloud\.com/.+$#i', $args['url'], $url_matches ) ) {
296 continue;
297 }
298
299 if ( ! preg_match( '#height="(\d+)"#i', $match[0], $hmatch ) ) {
300 $height = '';
301 } else {
302 $height = ' height="' . intval( $hmatch[1] ) . '"';
303 }
304
305 unset( $args['url'] );
306 $params = 'params="';
307 if ( count( $args ) > 0 ) {
308 foreach ( $args as $key => $value ) {
309 $params .= esc_html( $key ) . '=' . esc_html( $value ) . '&amp;';
310 }
311 $params = substr( $params, 0, -5 );
312 }
313 $params .= '"';
314
315 $shortcode = '[soundcloud url="' . esc_url( $url_matches[0] ) . '" ' . $params . ' width="100%"' . $height . ' iframe="true" /]';
316
317 $replace_regex = sprintf( '#\s*%s\s*#', preg_quote( $match[0], '#' ) );
318 $content = preg_replace( $replace_regex, sprintf( "\n\n%s\n\n", $shortcode ), $content );
319 /** This action is documented in modules/shortcodes/youtube.php */
320 do_action( 'jetpack_embed_to_shortcode', 'soundcloud', $url_matches[0] );
321 }
322 }
323
324 return $content;
325 }
326
327 add_filter( 'pre_kses', 'jetpack_soundcloud_embed_reversal' );
328