PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 8.6
Jetpack – WP Security, Backup, Speed, & Growth v8.6
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 / vimeo.php

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

405 lines 10.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Vimeo Shortcode.
4 *
5 * Examples:
6 * [vimeo 141358]
7 * [vimeo http://vimeo.com/141358]
8 * [vimeo 141358 h=500&w=350]
9 * [vimeo 141358 h=500 w=350]
10 * [vimeo id=141358 width=350 height=500]
11 *
12 * <iframe src="http://player.vimeo.com/video/18427511" width="400" height="225" frameborder="0"></iframe><p><a href="http://vimeo.com/18427511">Eskmo 'We Got More' (Official Video)</a> from <a href="http://vimeo.com/ninjatune">Ninja Tune</a> on <a href="http://vimeo.com">Vimeo</a>.</p>
13 *
14 * @package Jetpack
15 */
16
17 /**
18 * Extract Vimeo ID from shortcode.
19 *
20 * @param array $atts Shortcode attributes.
21 */
22 function jetpack_shortcode_get_vimeo_id( $atts ) {
23 if ( isset( $atts[0] ) ) {
24 $atts[0] = trim( $atts[0], '=' );
25 $id = false;
26 if ( is_numeric( $atts[0] ) ) {
27 $id = (int) $atts[0];
28 } elseif ( preg_match( '|vimeo\.com/(\d+)/?$|i', $atts[0], $match ) ) {
29 $id = (int) $match[1];
30 } elseif ( preg_match( '|player\.vimeo\.com/video/(\d+)/?$|i', $atts[0], $match ) ) {
31 $id = (int) $match[1];
32 }
33
34 return $id;
35 }
36
37 return 0;
38 }
39
40 /**
41 * Get video dimensions.
42 *
43 * @since 8.0.0
44 *
45 * @param array $attr The attributes of the shortcode.
46 * @param array $old_attr Optional array of attributes from the old shortcode format.
47 *
48 * @return array Width and height.
49 */
50 function jetpack_shortcode_get_vimeo_dimensions( $attr, $old_attr = array() ) {
51 global $content_width;
52
53 $default_width = 600;
54 $default_height = 338;
55 $aspect_ratio = $default_height / $default_width;
56
57 /*
58 * For width and height, we want to support both formats
59 * that can be provided in the new shortcode format:
60 * - for width: width or w
61 * - for height: height or h
62 *
63 * For each variation, the full word takes priority.
64 *
65 * If no variation is set, we default to the default width and height values set above.
66 */
67 if ( ! empty( $attr['width'] ) ) {
68 $width = absint( $attr['width'] );
69 } elseif ( ! empty( $attr['w'] ) ) {
70 $width = absint( $attr['w'] );
71 } else {
72 $width = $default_width;
73 }
74
75 if ( ! empty( $attr['height'] ) ) {
76 $height = absint( $attr['height'] );
77 } elseif ( ! empty( $attr['h'] ) ) {
78 $height = absint( $attr['h'] );
79 } else {
80 $height = $default_height;
81 }
82
83 /*
84 * Support w and h argument as fallbacks in old shortcode format.
85 */
86 if (
87 $default_width === $width
88 && ! empty( $old_attr['w'] )
89 ) {
90 $width = absint( $old_attr['w'] );
91
92 if (
93 $default_width === $width
94 && empty( $old_attr['h'] )
95 ) {
96 $height = round( $width * $aspect_ratio );
97 }
98 }
99
100 if (
101 $default_height === $height
102 && ! empty( $old_attr['h'] )
103 ) {
104 $height = absint( $old_attr['h'] );
105
106 if ( empty( $old_attr['w'] ) ) {
107 $width = round( $height * $aspect_ratio );
108 }
109 }
110
111 /*
112 * If we have a content width defined, let it be the new default.
113 */
114 if (
115 $default_width === $width
116 && ! empty( $content_width )
117 ) {
118 $width = absint( $content_width );
119 }
120
121 /*
122 * If we have a custom width, we need a custom height as well
123 * to maintain aspect ratio.
124 */
125 if (
126 $default_width !== $width
127 && $default_height === $height
128 ) {
129 $height = round( ( $width / 640 ) * 360 );
130 }
131
132 /**
133 * Filter the Vimeo player width.
134 *
135 * @module shortcodes
136 *
137 * @since 3.4.0
138 *
139 * @param int $width Width of the Vimeo player in pixels.
140 */
141 $width = (int) apply_filters( 'vimeo_width', $width );
142
143 /**
144 * Filter the Vimeo player height.
145 *
146 * @module shortcodes
147 *
148 * @since 3.4.0
149 *
150 * @param int $height Height of the Vimeo player in pixels.
151 */
152 $height = (int) apply_filters( 'vimeo_height', $height );
153
154 return array( $width, $height );
155 }
156
157 /**
158 * Convert a Vimeo shortcode into an embed code.
159 *
160 * @param array $atts An array of shortcode attributes.
161 *
162 * @return string The embed code for the Vimeo video.
163 */
164 function vimeo_shortcode( $atts ) {
165 $attr = array_map(
166 'intval',
167 shortcode_atts(
168 array(
169 'id' => 0,
170 'width' => 0,
171 'height' => 0,
172 'autoplay' => 0,
173 'loop' => 0,
174 'w' => 0,
175 'h' => 0,
176 ),
177 $atts
178 )
179 );
180
181 if ( isset( $atts[0] ) ) {
182 $attr['id'] = jetpack_shortcode_get_vimeo_id( $atts );
183 }
184
185 if ( ! $attr['id'] ) {
186 return '<!-- vimeo error: not a vimeo video -->';
187 }
188
189 // Handle old shortcode params such as h=500&w=350.
190 $params = shortcode_new_to_old_params( $atts );
191 $params = str_replace( array( '&amp;', '&#038;' ), '&', $params );
192 parse_str( $params, $args );
193
194 list( $width, $height ) = jetpack_shortcode_get_vimeo_dimensions( $attr, $args );
195
196 $url = esc_url( 'https://player.vimeo.com/video/' . $attr['id'] );
197
198 // Handle autoplay and loop arguments.
199 if (
200 isset( $args['autoplay'] ) && '1' === $args['autoplay'] // Parsed from the embedded URL.
201 || $attr['autoplay'] // Parsed from shortcode arguments.
202 || in_array( 'autoplay', $atts, true ) // Catch the argument passed without a value.
203 ) {
204 $url = add_query_arg( 'autoplay', 1, $url );
205 }
206
207 if (
208 isset( $args['loop'] ) && '1' === $args['loop'] // Parsed from the embedded URL.
209 || $attr['loop'] // Parsed from shortcode arguments.
210 || in_array( 'loop', $atts, true ) // Catch the argument passed without a value.
211 ) {
212 $url = add_query_arg( 'loop', 1, $url );
213 }
214
215 if (
216 class_exists( 'Jetpack_AMP_Support' )
217 && Jetpack_AMP_Support::is_amp_request()
218 ) {
219 $html = sprintf(
220 '<amp-vimeo data-videoid="%1$s" layout="responsive" width="%2$d" height="%3$d"></amp-vimeo>',
221 esc_attr( $attr['id'] ),
222 absint( $width ),
223 absint( $height )
224 );
225 } else {
226 $html = sprintf(
227 '<div class="embed-vimeo" style="text-align: center;"><iframe src="%1$s" width="%2$u" height="%3$u" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>',
228 esc_url( $url ),
229 esc_attr( $width ),
230 esc_attr( $height )
231 );
232 }
233
234 /**
235 * Filter the Vimeo player HTML.
236 *
237 * @module shortcodes
238 *
239 * @since 1.2.3
240 *
241 * @param string $html Embedded Vimeo player HTML.
242 */
243 $html = apply_filters( 'video_embed_html', $html );
244
245 return $html;
246 }
247 add_shortcode( 'vimeo', 'vimeo_shortcode' );
248
249 /**
250 * Callback to modify output of embedded Vimeo video using Jetpack's shortcode.
251 *
252 * @since 3.9
253 *
254 * @param array $matches Regex partial matches against the URL passed.
255 * @param array $attr Attributes received in embed response.
256 * @param array $url Requested URL to be embedded.
257 *
258 * @return string Return output of Vimeo shortcode with the proper markup.
259 */
260 function wpcom_vimeo_embed_url( $matches, $attr, $url ) {
261 return vimeo_shortcode( array( $url ) );
262 }
263
264 /**
265 * For bare URLs on their own line of the form
266 * http://vimeo.com/12345
267 *
268 * @since 3.9
269 *
270 * @uses wpcom_vimeo_embed_url
271 */
272 function wpcom_vimeo_embed_url_init() {
273 wp_embed_register_handler( 'wpcom_vimeo_embed_url', '#https?://(.+\.)?vimeo\.com/#i', 'wpcom_vimeo_embed_url' );
274 }
275
276 /*
277 * Register handler to modify Vimeo embeds using Jetpack's shortcode output.
278 * This does not happen on WordPress.com, since embeds are handled by core there.
279 */
280 if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) {
281 add_action( 'init', 'wpcom_vimeo_embed_url_init' );
282 }
283
284 /**
285 * Transform a Vimeo embed iFrame into a Vimeo shortcode.
286 *
287 * @param string $content Post content.
288 */
289 function vimeo_embed_to_shortcode( $content ) {
290 if ( ! is_string( $content ) || false === stripos( $content, 'player.vimeo.com/video/' ) ) {
291 return $content;
292 }
293
294 $regexp = '!<iframe\s+src=[\'"](https?:)?//player\.vimeo\.com/video/(\d+)[\w=&;?]*[\'"]((?:\s+\w+=[\'"][^\'"]*[\'"])*)((?:[\s\w]*))></iframe>!i';
295 $regexp_ent = str_replace( '&amp;#0*58;', '&amp;#0*58;|&#0*58;', htmlspecialchars( $regexp, ENT_NOQUOTES ) );
296
297 foreach ( compact( 'regexp', 'regexp_ent' ) as $reg => $regexp ) {
298 if ( ! preg_match_all( $regexp, $content, $matches, PREG_SET_ORDER ) ) {
299 continue;
300 }
301
302 foreach ( $matches as $match ) {
303 $id = (int) $match[2];
304
305 $params = $match[3];
306
307 if ( 'regexp_ent' === $reg ) {
308 $params = html_entity_decode( $params );
309 }
310
311 $params = wp_kses_hair( $params, array( 'http' ) );
312
313 $width = isset( $params['width'] ) ? (int) $params['width']['value'] : 0;
314 $height = isset( $params['height'] ) ? (int) $params['height']['value'] : 0;
315
316 $wh = '';
317 if ( $width && $height ) {
318 $wh = ' w=' . $width . ' h=' . $height;
319 }
320
321 $shortcode = '[vimeo ' . $id . $wh . ']';
322 $content = str_replace( $match[0], $shortcode, $content );
323 }
324 }
325
326 return $content;
327 }
328 add_filter( 'pre_kses', 'vimeo_embed_to_shortcode' );
329
330 /**
331 * Replaces shortcodes and plain-text URLs to Vimeo videos with Vimeo embeds.
332 * Covers shortcode usage [vimeo 1234] | [vimeo https://vimeo.com/1234] | [vimeo http://vimeo.com/1234]
333 * Or plain text URLs https://vimeo.com/1234 | vimeo.com/1234 | //vimeo.com/1234
334 * Links are left intact.
335 *
336 * @since 3.7.0
337 * @since 3.9.5 One regular expression matches shortcodes and plain URLs.
338 *
339 * @param string $content HTML content.
340 *
341 * @return string The content with embeds instead of URLs
342 */
343 function vimeo_link( $content ) {
344 /**
345 * [vimeo 12345]
346 * [vimeo http://vimeo.com/12345]
347 */
348 $shortcode = '(?:\[vimeo\s+[^0-9]*)([0-9]+)(?:\])';
349
350 /**
351 * Regex to look for a Vimeo link.
352 *
353 * - http://vimeo.com/12345
354 * - https://vimeo.com/12345
355 * - //vimeo.com/12345
356 * - vimeo.com/some/descender/12345
357 *
358 * Should not capture inside HTML attributes
359 * [Not] <a href="vimeo.com/12345">Cool Video</a>
360 * [Not] <a href="https://vimeo.com/12345">vimeo.com/12345</a>
361 *
362 * Could erroneously capture:
363 * <a href="some.link/maybe/even/vimeo">This video (vimeo.com/12345) is teh cat's meow!</a>
364 */
365 $plain_url = "(?:[^'\">]?\/?(?:https?:\/\/)?vimeo\.com[^0-9]+)([0-9]+)(?:[^'\"0-9<]|$)";
366
367 return jetpack_preg_replace_callback_outside_tags(
368 sprintf( '#%s|%s#i', $shortcode, $plain_url ),
369 'vimeo_link_callback',
370 $content,
371 'vimeo'
372 );
373 }
374
375 /**
376 * Callback function for the regex that replaces Vimeo URLs with Vimeo embeds.
377 *
378 * @since 3.7.0
379 *
380 * @param array $matches An array containing a Vimeo URL.
381 * @return string The Vimeo HTML embed code.
382 */
383 function vimeo_link_callback( $matches ) {
384 $id = isset( $matches[2] ) ? $matches[2] : $matches[1];
385 if ( isset( $id ) && ctype_digit( $id ) ) {
386 return "\n" . vimeo_shortcode( array( 'id' => $id ) ) . "\n";
387 }
388 return $matches[0];
389 }
390
391 if (
392 ! is_admin()
393 /** This filter is documented in modules/shortcodes/youtube.php */
394 && apply_filters( 'jetpack_comments_allow_oembed', true )
395 // No need for this on WordPress.com, this is done for multiple shortcodes at a time there.
396 && ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM )
397 ) {
398 /*
399 * We attach wp_kses_post to comment_text in default-filters.php with priority of 10 anyway,
400 * so the iframe gets filtered out.
401 * Higher priority because we need it before auto-link and autop get to it
402 */
403 add_filter( 'comment_text', 'vimeo_link', 1 );
404 }
405