PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 6.0.4
Jetpack – WP Security, Backup, Speed, & Growth v6.0.4
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.0.4, at modules/shortcodes/soundcloud.php

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