| 1 | diff --git wp-admin/includes/ajax-actions.php wp-admin/includes/ajax-actions.php |
|---|
| 2 | index 0fabe2a..cf6d80b 100644 |
|---|
| 3 | --- wp-admin/includes/ajax-actions.php |
|---|
| 4 | +++ wp-admin/includes/ajax-actions.php |
|---|
| 5 | @@ -2030,6 +2030,8 @@ function wp_ajax_send_attachment_to_editor() { |
|---|
| 6 | $caption = isset( $attachment['post_excerpt'] ) ? $attachment['post_excerpt'] : ''; |
|---|
| 7 | $title = ''; // We no longer insert title tags into <img> tags, as they are redundant. |
|---|
| 8 | $html = get_image_send_to_editor( $id, $caption, $title, $align, $url, (bool) $rel, $size, $alt ); |
|---|
| 9 | + } elseif ( 'video' === substr( $post->post_mime_type, 0, 5 ) || 'audio' === substr( $post->post_mime_type, 0, 5 ) ) { |
|---|
| 10 | + $html = stripslashes_deep( $_POST['html'] ); |
|---|
| 11 | } |
|---|
| 12 | |
|---|
| 13 | $html = apply_filters( 'media_send_to_editor', $html, $id, $attachment ); |
|---|
| 14 | diff --git wp-includes/functions.php wp-includes/functions.php |
|---|
| 15 | index cbd7925..5ac68c7 100644 |
|---|
| 16 | --- wp-includes/functions.php |
|---|
| 17 | +++ wp-includes/functions.php |
|---|
| 18 | @@ -3883,4 +3883,24 @@ function wp_is_stream( $path ) { |
|---|
| 19 | */ |
|---|
| 20 | function wp_checkdate( $month, $day, $year, $source_date ) { |
|---|
| 21 | return apply_filters( 'wp_checkdate', checkdate( $month, $day, $year ), $source_date ); |
|---|
| 22 | +} |
|---|
| 23 | + |
|---|
| 24 | +/** |
|---|
| 25 | + * Return RegEx body to liberally match an opening HTML tag that: |
|---|
| 26 | + * 1. Is self-closing or |
|---|
| 27 | + * 2. Has no body but has a closing tag of the same name or |
|---|
| 28 | + * 3. Contains a body and a closing tag of the same name |
|---|
| 29 | + * |
|---|
| 30 | + * Note: this RegEx does not balance inner tags and does not attempt to produce valid HTML |
|---|
| 31 | + * |
|---|
| 32 | + * @since 3.6.0 |
|---|
| 33 | + * |
|---|
| 34 | + * @param string $tag An HTML tag name. Example: 'video' |
|---|
| 35 | + * @return string |
|---|
| 36 | + */ |
|---|
| 37 | +function get_tag_regex( $tag ) { |
|---|
| 38 | + if ( empty( $tag ) ) |
|---|
| 39 | + return; |
|---|
| 40 | + |
|---|
| 41 | + return sprintf( '(<%1$s[^>]*(?:/?>$|>[\s\S]*?</%1$s>))', tag_escape( $tag ) ); |
|---|
| 42 | } |
|---|
| 43 | \ No newline at end of file |
|---|
| 44 | diff --git wp-includes/js/media-editor.js wp-includes/js/media-editor.js |
|---|
| 45 | index 15eff8d..1b5f844 100644 |
|---|
| 46 | --- wp-includes/js/media-editor.js |
|---|
| 47 | +++ wp-includes/js/media-editor.js |
|---|
| 48 | @@ -66,7 +66,8 @@ |
|---|
| 49 | src: size.url, |
|---|
| 50 | captionId: 'attachment_' + attachment.id |
|---|
| 51 | }); |
|---|
| 52 | - |
|---|
| 53 | + } else if ( 'video' === attachment.type || 'audio' === attachment.type ) { |
|---|
| 54 | + _.extend( props, _.pick( attachment, 'title', 'type', 'icon', 'mime' ) ); |
|---|
| 55 | // Format properties for non-images. |
|---|
| 56 | } else { |
|---|
| 57 | props.title = props.title || attachment.filename; |
|---|
| 58 | @@ -95,6 +96,70 @@ |
|---|
| 59 | return wp.html.string( options ); |
|---|
| 60 | }, |
|---|
| 61 | |
|---|
| 62 | + audio: function( props, attachment ) { |
|---|
| 63 | + var shortcode, html; |
|---|
| 64 | + |
|---|
| 65 | + props = wp.media.string.props( props, attachment ); |
|---|
| 66 | + |
|---|
| 67 | + shortcode = {}; |
|---|
| 68 | + |
|---|
| 69 | + if ( props.mime ) { |
|---|
| 70 | + switch ( props.mime ) { |
|---|
| 71 | + case 'audio/mpeg': |
|---|
| 72 | + shortcode.mp3 = props.linkUrl; |
|---|
| 73 | + break; |
|---|
| 74 | + case 'audio/ogg': |
|---|
| 75 | + shortcode.ogg = props.linkUrl; |
|---|
| 76 | + break; |
|---|
| 77 | + case 'audio/wma': |
|---|
| 78 | + shortcode.wma = props.linkUrl; |
|---|
| 79 | + break; |
|---|
| 80 | + } |
|---|
| 81 | + } |
|---|
| 82 | + |
|---|
| 83 | + html = wp.shortcode.string({ |
|---|
| 84 | + tag: 'audio', |
|---|
| 85 | + attrs: shortcode |
|---|
| 86 | + }); |
|---|
| 87 | + |
|---|
| 88 | + return html; |
|---|
| 89 | + }, |
|---|
| 90 | + |
|---|
| 91 | + video: function( props, attachment ) { |
|---|
| 92 | + var shortcode, html; |
|---|
| 93 | + |
|---|
| 94 | + props = wp.media.string.props( props, attachment ); |
|---|
| 95 | + |
|---|
| 96 | + shortcode = {}; |
|---|
| 97 | + |
|---|
| 98 | + if ( props.mime ) { |
|---|
| 99 | + switch ( props.mime ) { |
|---|
| 100 | + case 'video/mp4': |
|---|
| 101 | + shortcode.mp4 = props.linkUrl; |
|---|
| 102 | + break; |
|---|
| 103 | + case 'video/webm': |
|---|
| 104 | + shortcode.webm = props.linkUrl; |
|---|
| 105 | + break; |
|---|
| 106 | + case 'video/ogg': |
|---|
| 107 | + shortcode.ogv = props.linkUrl; |
|---|
| 108 | + break; |
|---|
| 109 | + case 'video/asf': |
|---|
| 110 | + shortcode.wmv = props.linkUrl; |
|---|
| 111 | + break; |
|---|
| 112 | + case 'video/x-flv': |
|---|
| 113 | + shortcode.flv = props.linkUrl; |
|---|
| 114 | + break; |
|---|
| 115 | + } |
|---|
| 116 | + } |
|---|
| 117 | + |
|---|
| 118 | + html = wp.shortcode.string({ |
|---|
| 119 | + tag: 'video', |
|---|
| 120 | + attrs: shortcode |
|---|
| 121 | + }); |
|---|
| 122 | + |
|---|
| 123 | + return html; |
|---|
| 124 | + }, |
|---|
| 125 | + |
|---|
| 126 | image: function( props, attachment ) { |
|---|
| 127 | var img = {}, |
|---|
| 128 | options, classes, shortcode, html; |
|---|
| 129 | @@ -575,7 +640,10 @@ |
|---|
| 130 | if ( props[ prop ] ) |
|---|
| 131 | options[ option ] = props[ prop ]; |
|---|
| 132 | }); |
|---|
| 133 | - |
|---|
| 134 | + } else if ( 'video' === attachment.type ) { |
|---|
| 135 | + html = wp.media.string.video( props ); |
|---|
| 136 | + } else if ( 'audio' === attachment.type ) { |
|---|
| 137 | + html = wp.media.string.audio( props ); |
|---|
| 138 | } else { |
|---|
| 139 | html = wp.media.string.link( props ); |
|---|
| 140 | options.post_title = props.title; |
|---|
| 141 | diff --git wp-includes/media.php wp-includes/media.php |
|---|
| 142 | index f1f3737..87df77f 100644 |
|---|
| 143 | --- wp-includes/media.php |
|---|
| 144 | +++ wp-includes/media.php |
|---|
| 145 | @@ -803,6 +803,201 @@ function gallery_shortcode($attr) { |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | /** |
|---|
| 149 | + * Return a filtered list of WP-supported audio formats |
|---|
| 150 | + * |
|---|
| 151 | + * @since 3.6.0 |
|---|
| 152 | + * @return array |
|---|
| 153 | + */ |
|---|
| 154 | +function wp_get_audio_extensions() { |
|---|
| 155 | + return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'wma' ) ); |
|---|
| 156 | +} |
|---|
| 157 | + |
|---|
| 158 | +/** |
|---|
| 159 | + * The Audio shortcode. |
|---|
| 160 | + * |
|---|
| 161 | + * This implements the functionality of the Audio Shortcode for displaying |
|---|
| 162 | + * WordPress mp3s in a post. |
|---|
| 163 | + * |
|---|
| 164 | + * @since 3.6.0 |
|---|
| 165 | + * |
|---|
| 166 | + * @param array $attr Attributes of the shortcode. |
|---|
| 167 | + * @return string HTML content to display audio. |
|---|
| 168 | + */ |
|---|
| 169 | +function wp_audio_shortcode( $attr ) { |
|---|
| 170 | + $post_id = get_post() ? get_the_ID() : 0; |
|---|
| 171 | + |
|---|
| 172 | + static $instances = 0; |
|---|
| 173 | + $instances++; |
|---|
| 174 | + |
|---|
| 175 | + $audio = null; |
|---|
| 176 | + |
|---|
| 177 | + $default_types = wp_get_audio_extensions(); |
|---|
| 178 | + $defaults_atts = array( 'src' => '' ); |
|---|
| 179 | + foreach ( $default_types as $type ) |
|---|
| 180 | + $defaults_atts[$type] = ''; |
|---|
| 181 | + |
|---|
| 182 | + extract( shortcode_atts( $defaults_atts, $attr ) ); |
|---|
| 183 | + |
|---|
| 184 | + $primary = false; |
|---|
| 185 | + if ( ! empty( $src ) ) { |
|---|
| 186 | + $type = wp_check_filetype( $src ); |
|---|
| 187 | + if ( ! in_array( $type['ext'], $default_types ) ) { |
|---|
| 188 | + printf( '<a class="wp-post-format-link-audio" href="%1$s">%1$s</a>', $src ); |
|---|
| 189 | + return; |
|---|
| 190 | + } |
|---|
| 191 | + $primary = true; |
|---|
| 192 | + array_unshift( $default_types, 'src' ); |
|---|
| 193 | + } else { |
|---|
| 194 | + foreach ( $default_types as $ext ) { |
|---|
| 195 | + if ( ! empty( $$ext ) ) { |
|---|
| 196 | + $type = wp_check_filetype( $$ext ); |
|---|
| 197 | + if ( $type['ext'] === $ext ) |
|---|
| 198 | + $primary = true; |
|---|
| 199 | + } |
|---|
| 200 | + } |
|---|
| 201 | + } |
|---|
| 202 | + |
|---|
| 203 | + if ( ! $primary ) { |
|---|
| 204 | + $audios = get_post_audio( $post_id ); |
|---|
| 205 | + if ( empty( $audios ) ) |
|---|
| 206 | + return; |
|---|
| 207 | + |
|---|
| 208 | + $audio = reset( $audios ); |
|---|
| 209 | + $src = wp_get_attachment_url( $audio->ID ); |
|---|
| 210 | + if ( empty( $src ) ) |
|---|
| 211 | + return; |
|---|
| 212 | + |
|---|
| 213 | + array_unshift( $default_types, 'src' ); |
|---|
| 214 | + } |
|---|
| 215 | + |
|---|
| 216 | + wp_enqueue_style( 'wp-mediaelement' ); |
|---|
| 217 | + wp_enqueue_script( 'wp-mediaelement' ); |
|---|
| 218 | + |
|---|
| 219 | + $atts = array( |
|---|
| 220 | + sprintf( 'class="%s"', apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ) ), |
|---|
| 221 | + sprintf( 'id="audio-%d-%d"', $post_id, $instances ), |
|---|
| 222 | + ); |
|---|
| 223 | + |
|---|
| 224 | + $html = sprintf( '<audio %s controls="controls" preload="none">', join( ' ', $atts ) ); |
|---|
| 225 | + |
|---|
| 226 | + $source = '<source type="%s" src="%s" />'; |
|---|
| 227 | + foreach ( $default_types as $fallback ) { |
|---|
| 228 | + if ( ! empty( $$fallback ) ) { |
|---|
| 229 | + $type = wp_check_filetype( $$fallback ); |
|---|
| 230 | + $html .= sprintf( $source, $type['type'], $$fallback ); |
|---|
| 231 | + } |
|---|
| 232 | + } |
|---|
| 233 | + |
|---|
| 234 | + $html .= '</audio>'; |
|---|
| 235 | + |
|---|
| 236 | + return apply_filters( 'wp_audio_shortcode', $html, $src, $audio, $post_id ); |
|---|
| 237 | +} |
|---|
| 238 | +add_shortcode( 'audio', 'wp_audio_shortcode' ); |
|---|
| 239 | + |
|---|
| 240 | +/** |
|---|
| 241 | + * Return a filtered list of WP-supported video formats |
|---|
| 242 | + * |
|---|
| 243 | + * @since 3.6.0 |
|---|
| 244 | + * @return array |
|---|
| 245 | + */ |
|---|
| 246 | +function wp_get_video_extensions() { |
|---|
| 247 | + return apply_filters( 'wp_video_extensions', array( 'mp4', 'webm', 'ogv', 'wmv', 'flv' ) ); |
|---|
| 248 | +} |
|---|
| 249 | + |
|---|
| 250 | +/** |
|---|
| 251 | + * The Video shortcode. |
|---|
| 252 | + * |
|---|
| 253 | + * This implements the functionality of the Video Shortcode for displaying |
|---|
| 254 | + * WordPress mp4s in a post. |
|---|
| 255 | + * |
|---|
| 256 | + * @since 3.6.0 |
|---|
| 257 | + * |
|---|
| 258 | + * @param array $attr Attributes of the shortcode. |
|---|
| 259 | + * @return string HTML content to display video. |
|---|
| 260 | + */ |
|---|
| 261 | +function wp_video_shortcode( $attr ) { |
|---|
| 262 | + global $content_width; |
|---|
| 263 | + $post_id = get_post() ? get_the_ID() : 0; |
|---|
| 264 | + |
|---|
| 265 | + static $instances = 0; |
|---|
| 266 | + $instances++; |
|---|
| 267 | + |
|---|
| 268 | + $video = null; |
|---|
| 269 | + |
|---|
| 270 | + $default_types = wp_get_video_extensions(); |
|---|
| 271 | + $defaults_atts = array( |
|---|
| 272 | + 'src' => '', |
|---|
| 273 | + 'poster' => '', |
|---|
| 274 | + 'height' => 360, |
|---|
| 275 | + 'width' => empty( $content_width ) ? 640 : $content_width, |
|---|
| 276 | + ); |
|---|
| 277 | + foreach ( $default_types as $type ) |
|---|
| 278 | + $defaults_atts[$type] = ''; |
|---|
| 279 | + |
|---|
| 280 | + extract( shortcode_atts( $defaults_atts, $attr ) ); |
|---|
| 281 | + |
|---|
| 282 | + $primary = false; |
|---|
| 283 | + if ( ! empty( $src ) ) { |
|---|
| 284 | + $type = wp_check_filetype( $src ); |
|---|
| 285 | + if ( ! in_array( $type['ext'], $default_types ) ) { |
|---|
| 286 | + printf( '<a class="wp-post-format-link-video" href="%1$s">%1$s</a>', $src ); |
|---|
| 287 | + return; |
|---|
| 288 | + } |
|---|
| 289 | + $primary = true; |
|---|
| 290 | + array_unshift( $default_types, 'src' ); |
|---|
| 291 | + } else { |
|---|
| 292 | + foreach ( $default_types as $ext ) { |
|---|
| 293 | + if ( ! empty( $$ext ) ) { |
|---|
| 294 | + $type = wp_check_filetype( $$ext ); |
|---|
| 295 | + if ( $type['ext'] === $ext ) |
|---|
| 296 | + $primary = true; |
|---|
| 297 | + } |
|---|
| 298 | + } |
|---|
| 299 | + } |
|---|
| 300 | + |
|---|
| 301 | + if ( ! $primary ) { |
|---|
| 302 | + $videos = get_post_video( $post_id ); |
|---|
| 303 | + if ( empty( $videos ) ) |
|---|
| 304 | + return; |
|---|
| 305 | + |
|---|
| 306 | + $video = reset( $videos ); |
|---|
| 307 | + $src = wp_get_attachment_url( $video->ID ); |
|---|
| 308 | + if ( empty( $src ) ) |
|---|
| 309 | + return; |
|---|
| 310 | + |
|---|
| 311 | + array_unshift( $default_types, 'src' ); |
|---|
| 312 | + } |
|---|
| 313 | + |
|---|
| 314 | + wp_enqueue_style( 'wp-mediaelement' ); |
|---|
| 315 | + wp_enqueue_script( 'wp-mediaelement' ); |
|---|
| 316 | + |
|---|
| 317 | + $atts = array( |
|---|
| 318 | + sprintf( 'class="%s"', apply_filters( 'video_shortcode_class', 'wp-video-shortcode' ) ), |
|---|
| 319 | + sprintf( 'id="video-%d-%d"', $post_id, $instances ), |
|---|
| 320 | + sprintf( 'width="%d"', $width ), |
|---|
| 321 | + sprintf( 'height="%d"', $height ), |
|---|
| 322 | + ); |
|---|
| 323 | + |
|---|
| 324 | + if ( ! empty( $poster ) ) |
|---|
| 325 | + $atts[] = sprintf( 'poster="%s"', esc_url( $poster ) ); |
|---|
| 326 | + |
|---|
| 327 | + $html = sprintf( '<video %s controls="controls" preload="none">', join( ' ', $atts ) ); |
|---|
| 328 | + |
|---|
| 329 | + $source = '<source type="%s" src="%s" />'; |
|---|
| 330 | + foreach ( $default_types as $fallback ) { |
|---|
| 331 | + if ( ! empty( $$fallback ) ) { |
|---|
| 332 | + $type = wp_check_filetype( $$fallback ); |
|---|
| 333 | + $html .= sprintf( $source, $type['type'], $$fallback ); |
|---|
| 334 | + } |
|---|
| 335 | + } |
|---|
| 336 | + |
|---|
| 337 | + $html .= '</video>'; |
|---|
| 338 | + |
|---|
| 339 | + return apply_filters( 'wp_video_shortcode', $html, $src, $video, $post_id ); |
|---|
| 340 | +} |
|---|
| 341 | +add_shortcode( 'video', 'wp_video_shortcode' ); |
|---|
| 342 | + |
|---|
| 343 | +/** |
|---|
| 344 | * Display previous image link that has the same post parent. |
|---|
| 345 | * |
|---|
| 346 | * @since 2.5.0 |
|---|
| 347 | @@ -1542,3 +1737,216 @@ function wp_enqueue_media( $args = array() ) { |
|---|
| 348 | |
|---|
| 349 | do_action( 'wp_enqueue_media' ); |
|---|
| 350 | } |
|---|
| 351 | + |
|---|
| 352 | +/** |
|---|
| 353 | + * Retrieve audio attached to the passed post |
|---|
| 354 | + * |
|---|
| 355 | + * @since 3.6.0 |
|---|
| 356 | + * |
|---|
| 357 | + * @param int $post_id Post ID |
|---|
| 358 | + * @return array Found audio attachments |
|---|
| 359 | + */ |
|---|
| 360 | +function get_post_audio( $post_id = 0 ) { |
|---|
| 361 | + $post = empty( $post_id ) ? get_post() : get_post( $post_id ); |
|---|
| 362 | + if ( empty( $post ) ) |
|---|
| 363 | + return; |
|---|
| 364 | + |
|---|
| 365 | + $children = get_children( array( |
|---|
| 366 | + 'post_parent' => $post->ID, |
|---|
| 367 | + 'post_type' => 'attachment', |
|---|
| 368 | + 'post_mime_type' => 'audio', |
|---|
| 369 | + 'posts_per_page' => -1 |
|---|
| 370 | + ) ); |
|---|
| 371 | + |
|---|
| 372 | + if ( ! empty( $children ) ) |
|---|
| 373 | + return $children; |
|---|
| 374 | +} |
|---|
| 375 | + |
|---|
| 376 | +/** |
|---|
| 377 | + * Check the content blob for an <audio>, <object>, <embed>, or <iframe>, in that order |
|---|
| 378 | + * If no HTML tag is found, check the first line of the post for a URL |
|---|
| 379 | + * |
|---|
| 380 | + * @param string $content A string which might contain audio data. |
|---|
| 381 | + * @param boolean $remove Whether to remove the found URL from the passed content. |
|---|
| 382 | + * @return string The found data |
|---|
| 383 | + */ |
|---|
| 384 | +function get_content_audio( &$content, $remove = false ) { |
|---|
| 385 | + $html = $matches = ''; |
|---|
| 386 | + foreach ( array( 'audio', 'object', 'embed', 'iframe' ) as $tag ) { |
|---|
| 387 | + if ( preg_match( '#' . get_tag_regex( $tag ) . '#i', $content, $matches ) ) { |
|---|
| 388 | + $html = $matches[1]; |
|---|
| 389 | + $count = 1; |
|---|
| 390 | + if ( $remove ) |
|---|
| 391 | + $content = str_replace( $matches[0], '', $content, $count ); |
|---|
| 392 | + |
|---|
| 393 | + return $html; |
|---|
| 394 | + } |
|---|
| 395 | + } |
|---|
| 396 | + |
|---|
| 397 | + $lines = explode( "\n", trim( $content ) ); |
|---|
| 398 | + $line = trim( array_shift( $lines ) ); |
|---|
| 399 | + |
|---|
| 400 | + if ( 0 === stripos( $line, 'http' ) ) { |
|---|
| 401 | + if ( $remove ) |
|---|
| 402 | + $content = join( "\n", $lines ); |
|---|
| 403 | + |
|---|
| 404 | + return $line; |
|---|
| 405 | + } |
|---|
| 406 | +} |
|---|
| 407 | + |
|---|
| 408 | +/** |
|---|
| 409 | + * Return the found audio data for the passed post |
|---|
| 410 | + * |
|---|
| 411 | + * @since 3.6.0 |
|---|
| 412 | + * |
|---|
| 413 | + * @param int $id Optional. Post ID |
|---|
| 414 | + */ |
|---|
| 415 | +function get_the_audio( $id = 0 ) { |
|---|
| 416 | + $post = empty( $id ) ? get_post() : get_post( $id ); |
|---|
| 417 | + if ( empty( $post ) ) |
|---|
| 418 | + return array(); |
|---|
| 419 | + |
|---|
| 420 | + $data = get_content_audio( $post->post_content ); |
|---|
| 421 | + if ( ! empty( $data ) ) |
|---|
| 422 | + return $data; |
|---|
| 423 | + |
|---|
| 424 | + $audios = get_post_audio( $post->ID ); |
|---|
| 425 | + if ( empty( $audios ) ) |
|---|
| 426 | + return array(); |
|---|
| 427 | + |
|---|
| 428 | + $audio = reset( $audios ); |
|---|
| 429 | + return wp_get_attachment_url( $audio->ID ); |
|---|
| 430 | +} |
|---|
| 431 | + |
|---|
| 432 | +/** |
|---|
| 433 | + * Output the found audio data for the current post |
|---|
| 434 | + * |
|---|
| 435 | + * @since 3.6.0 |
|---|
| 436 | + */ |
|---|
| 437 | +function the_audio() { |
|---|
| 438 | + echo apply_filters( 'the_audio', get_the_audio() ); |
|---|
| 439 | +} |
|---|
| 440 | + |
|---|
| 441 | +/** |
|---|
| 442 | + * Retrieve video attached to the passed post |
|---|
| 443 | + * |
|---|
| 444 | + * @since 3.6.0 |
|---|
| 445 | + * |
|---|
| 446 | + * @param int $post_id Post ID |
|---|
| 447 | + * @return array Found video attachments |
|---|
| 448 | + */ |
|---|
| 449 | +function get_post_video( $post_id = 0 ) { |
|---|
| 450 | + $post = empty( $post_id ) ? get_post() : get_post( $post_id ); |
|---|
| 451 | + if ( empty( $post ) ) |
|---|
| 452 | + return; |
|---|
| 453 | + |
|---|
| 454 | + $children = get_children( array( |
|---|
| 455 | + 'post_parent' => $post->ID, |
|---|
| 456 | + 'post_type' => 'attachment', |
|---|
| 457 | + 'post_mime_type' => 'video', |
|---|
| 458 | + 'posts_per_page' => -1 |
|---|
| 459 | + ) ); |
|---|
| 460 | + |
|---|
| 461 | + if ( ! empty( $children ) ) |
|---|
| 462 | + return $children; |
|---|
| 463 | +} |
|---|
| 464 | + |
|---|
| 465 | +/** |
|---|
| 466 | + * Check the content blob for a <video>, <object>, <embed>, or <iframe>, in that order |
|---|
| 467 | + * If no HTML tag is found, check the first line of the post for a URL |
|---|
| 468 | + * |
|---|
| 469 | + * @param string $content A string which might contain video data. |
|---|
| 470 | + * @param boolean $remove Whether to remove the found URL from the passed content. |
|---|
| 471 | + * @return string The found data |
|---|
| 472 | + */ |
|---|
| 473 | +function get_content_video( &$content, $remove = false ) { |
|---|
| 474 | + $html = $matches = ''; |
|---|
| 475 | + foreach ( array( 'video', 'object', 'embed', 'iframe' ) as $tag ) { |
|---|
| 476 | + if ( preg_match( '#' . get_tag_regex( $tag ) . '#i', $content, $matches ) ) { |
|---|
| 477 | + $html = $matches[1]; |
|---|
| 478 | + $count = 1; |
|---|
| 479 | + if ( $remove ) |
|---|
| 480 | + $content = str_replace( $matches[0], '', $content, $count ); |
|---|
| 481 | + |
|---|
| 482 | + return $html; |
|---|
| 483 | + } |
|---|
| 484 | + } |
|---|
| 485 | + |
|---|
| 486 | + $lines = explode( "\n", trim( $content ) ); |
|---|
| 487 | + $line = trim( array_shift( $lines ) ); |
|---|
| 488 | + |
|---|
| 489 | + if ( 0 === stripos( $line, 'http' ) ) { |
|---|
| 490 | + if ( $remove ) |
|---|
| 491 | + $content = join( "\n", $lines ); |
|---|
| 492 | + |
|---|
| 493 | + return $line; |
|---|
| 494 | + } |
|---|
| 495 | +} |
|---|
| 496 | + |
|---|
| 497 | +/** |
|---|
| 498 | + * Return the found video data for the passed post |
|---|
| 499 | + * |
|---|
| 500 | + * @since 3.6.0 |
|---|
| 501 | + * |
|---|
| 502 | + * @param int $id Optional. Post ID |
|---|
| 503 | + */ |
|---|
| 504 | +function get_the_video( $id = 0 ) { |
|---|
| 505 | + $post = empty( $id ) ? get_post() : get_post( $id ); |
|---|
| 506 | + if ( empty( $post ) ) |
|---|
| 507 | + return array(); |
|---|
| 508 | + |
|---|
| 509 | + $data = get_content_video( $post->post_content ); |
|---|
| 510 | + if ( ! empty( $data ) ) |
|---|
| 511 | + return $data; |
|---|
| 512 | + |
|---|
| 513 | + $videos = get_post_video( $post->ID ); |
|---|
| 514 | + if ( empty( $videos ) ) |
|---|
| 515 | + return array(); |
|---|
| 516 | + |
|---|
| 517 | + $video = reset( $videos ); |
|---|
| 518 | + return wp_get_attachment_url( $video->ID ); |
|---|
| 519 | +} |
|---|
| 520 | + |
|---|
| 521 | +/** |
|---|
| 522 | + * Output the found video data for the current post |
|---|
| 523 | + * |
|---|
| 524 | + * @since 3.6.0 |
|---|
| 525 | + */ |
|---|
| 526 | +function the_video() { |
|---|
| 527 | + echo apply_filters( 'the_video', get_the_video() ); |
|---|
| 528 | +} |
|---|
| 529 | + |
|---|
| 530 | +/** |
|---|
| 531 | + * Audio embed handler callback. |
|---|
| 532 | + * |
|---|
| 533 | + * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. |
|---|
| 534 | + * @param array $attr Embed attributes. |
|---|
| 535 | + * @param string $url The original URL that was matched by the regex. |
|---|
| 536 | + * @param array $rawattr The original unmodified attributes. |
|---|
| 537 | + * @return string The embed HTML. |
|---|
| 538 | + */ |
|---|
| 539 | +function wp_audio_embed( $matches, $attr, $url, $rawattr ) { |
|---|
| 540 | + $audio = do_shortcode( '[audio src="' . $url . '" /]' ); |
|---|
| 541 | + return apply_filters( 'wp_audio_embed', $audio, $attr, $url, $rawattr ); |
|---|
| 542 | +} |
|---|
| 543 | +wp_embed_register_handler( 'wp_audio_embed', '#https?://.+?\.(' . join( '|', wp_get_audio_extensions() ) . ')#i', 'wp_audio_embed', 9999 ); |
|---|
| 544 | + |
|---|
| 545 | +/** |
|---|
| 546 | + * Video embed handler callback. |
|---|
| 547 | + * |
|---|
| 548 | + * @param array $matches The regex matches from the provided regex when calling {@link wp_embed_register_handler()}. |
|---|
| 549 | + * @param array $attr Embed attributes. |
|---|
| 550 | + * @param string $url The original URL that was matched by the regex. |
|---|
| 551 | + * @param array $rawattr The original unmodified attributes. |
|---|
| 552 | + * @return string The embed HTML. |
|---|
| 553 | + */ |
|---|
| 554 | +function wp_video_embed( $matches, $attr, $url, $rawattr ) { |
|---|
| 555 | + $dimensions = ''; |
|---|
| 556 | + if ( ! empty( $rawattr['width'] ) && ! empty( $rawattr['height'] ) ) { |
|---|
| 557 | + $dimensions .= sprintf( 'width="%d" ', (int) $rawattr['width'] ); |
|---|
| 558 | + $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] ); |
|---|
| 559 | + } |
|---|
| 560 | + $video = do_shortcode( '[video ' . $dimensions . ' src="' . $url . '" /]' ); |
|---|
| 561 | + return apply_filters( 'wp_video_embed', $video, $attr, $url, $rawattr ); |
|---|
| 562 | +} |
|---|
| 563 | +wp_embed_register_handler( 'wp_video_embed', '#https?://.+?\.(' . join( '|', wp_get_video_extensions() ) . ')#i', 'wp_video_embed', 9999 ); |
|---|
| 564 | \ No newline at end of file |
|---|
| 565 | diff --git wp-includes/post-formats.php wp-includes/post-formats.php |
|---|
| 566 | index 6d32aea..eddcd7f 100644 |
|---|
| 567 | --- wp-includes/post-formats.php |
|---|
| 568 | +++ wp-includes/post-formats.php |
|---|
| 569 | @@ -301,8 +301,8 @@ function post_formats_compat( $content, $id = 0 ) { |
|---|
| 570 | 'link_class' => '', |
|---|
| 571 | 'image_class' => '', |
|---|
| 572 | 'gallery' => '[gallery]', |
|---|
| 573 | - 'audio' => '', |
|---|
| 574 | - 'video' => '' |
|---|
| 575 | + 'audio' => '[audio]', |
|---|
| 576 | + 'video' => '[video]' |
|---|
| 577 | ); |
|---|
| 578 | |
|---|
| 579 | $args = apply_filters( 'post_format_compat', array() ); |
|---|
| 580 | @@ -386,7 +386,8 @@ function post_formats_compat( $content, $id = 0 ) { |
|---|
| 581 | case 'video': |
|---|
| 582 | case 'audio': |
|---|
| 583 | $shortcode_regex = '/' . get_shortcode_regex() . '/s'; |
|---|
| 584 | - $matches = preg_match( $shortcode_regex, $content ); |
|---|
| 585 | + preg_match( $shortcode_regex, $content, $matches ); |
|---|
| 586 | + |
|---|
| 587 | if ( ! $matches || $format !== $matches[2] ) { |
|---|
| 588 | if ( empty( $meta['media'] ) && ! empty( $compat[$format] ) ) { |
|---|
| 589 | $format_output .= $compat[$format]; |
|---|
| 590 | @@ -398,6 +399,50 @@ function post_formats_compat( $content, $id = 0 ) { |
|---|
| 591 | // attempt to embed the URL |
|---|
| 592 | $format_output .= sprintf( '[embed]%s[/embed]', $meta['media'] ); |
|---|
| 593 | } |
|---|
| 594 | + } elseif ( empty( $meta['media'] ) ) { |
|---|
| 595 | + $data = ''; |
|---|
| 596 | + // attempt to grab an embed code or URL from the content |
|---|
| 597 | + if ( 'audio' === $format ) { |
|---|
| 598 | + $data = get_content_audio( $content, true ); |
|---|
| 599 | + } elseif ( 'video' === $format ) { |
|---|
| 600 | + $data = get_content_video( $content, true ); |
|---|
| 601 | + } |
|---|
| 602 | + |
|---|
| 603 | + if ( ! empty( $data ) ) { |
|---|
| 604 | + // attempt to embed the URL |
|---|
| 605 | + if ( 0 === stripos( $data, 'http' ) ) |
|---|
| 606 | + $format_output .= sprintf( '[embed]%s[/embed]', $data ); |
|---|
| 607 | + else // data is probably an embed code |
|---|
| 608 | + $format_output .= $data; |
|---|
| 609 | + } elseif ( 'audio' === $format ) { |
|---|
| 610 | + // get attached audio URL |
|---|
| 611 | + $audios = get_post_audio( $post->ID ); |
|---|
| 612 | + if ( ! empty( $audios ) ) { |
|---|
| 613 | + $audio = reset( $audios ); |
|---|
| 614 | + $url = wp_get_attachment_url( $audio->ID ); |
|---|
| 615 | + // core or plugin support for [audio] |
|---|
| 616 | + if ( shortcode_exists( 'audio' ) ) { |
|---|
| 617 | + $format_output .= sprintf( '[audio src="%s"/]', $url ); |
|---|
| 618 | + } else { |
|---|
| 619 | + // no support detected, just add URL |
|---|
| 620 | + $format_output .= sprintf( '<a class="wp-post-format-link-audio" href="%1$s">%1$s</a>', $url ); |
|---|
| 621 | + } |
|---|
| 622 | + } |
|---|
| 623 | + } elseif ( 'video' === $format ) { |
|---|
| 624 | + // get attached video URL |
|---|
| 625 | + $videos = get_post_video( $post->ID ); |
|---|
| 626 | + if ( ! empty( $videos ) ) { |
|---|
| 627 | + $video = reset( $videos ); |
|---|
| 628 | + $url = wp_get_attachment_url( $video->ID ); |
|---|
| 629 | + // core or plugin support for [video] |
|---|
| 630 | + if ( shortcode_exists( 'video' ) ) { |
|---|
| 631 | + $format_output .= sprintf( '[video src="%s"/]', $url ); |
|---|
| 632 | + } else { |
|---|
| 633 | + // no support detected, just add URL link |
|---|
| 634 | + $format_output .= sprintf( '<a class="wp-post-format-link-video" href="%1$s">%1$s</a>', $url ); |
|---|
| 635 | + } |
|---|
| 636 | + } |
|---|
| 637 | + } |
|---|
| 638 | } |
|---|
| 639 | } |
|---|
| 640 | break; |
|---|
| 641 | diff --git wp-includes/script-loader.php wp-includes/script-loader.php |
|---|
| 642 | index d168c2c..dbe6cc4 100644 |
|---|
| 643 | --- wp-includes/script-loader.php |
|---|
| 644 | +++ wp-includes/script-loader.php |
|---|
| 645 | @@ -274,6 +274,9 @@ function wp_default_scripts( &$scripts ) { |
|---|
| 646 | |
|---|
| 647 | $scripts->add( 'imgareaselect', "/wp-includes/js/imgareaselect/jquery.imgareaselect$suffix.js", array('jquery'), '0.9.8', 1 ); |
|---|
| 648 | |
|---|
| 649 | + $scripts->add( 'mediaelement', "/wp-includes/js/mediaelement/mediaelement-and-player$suffix.js", array('jquery'), '2.10.1', 1 ); |
|---|
| 650 | + $scripts->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement.js", array('mediaelement'), false, 1 ); |
|---|
| 651 | + |
|---|
| 652 | $scripts->add( 'password-strength-meter', "/wp-admin/js/password-strength-meter$suffix.js", array('jquery'), false, 1 ); |
|---|
| 653 | did_action( 'init' ) && $scripts->localize( 'password-strength-meter', 'pwsL10n', array( |
|---|
| 654 | 'empty' => __('Strength indicator'), |
|---|
| 655 | @@ -540,6 +543,9 @@ function wp_default_styles( &$styles ) { |
|---|
| 656 | $styles->add( 'media-views', "/wp-includes/css/media-views$suffix.css", array( 'buttons' ) ); |
|---|
| 657 | $styles->add( 'buttons', "/wp-includes/css/buttons$suffix.css" ); |
|---|
| 658 | |
|---|
| 659 | + $styles->add( 'mediaelement', "/wp-includes/js/mediaelement/mediaelementplayer$suffix.css" ); |
|---|
| 660 | + $styles->add( 'wp-mediaelement', "/wp-includes/js/mediaelement/wp-mediaelement.css", array( 'mediaelement' ) ); |
|---|
| 661 | + |
|---|
| 662 | foreach ( $rtl_styles as $rtl_style ) { |
|---|
| 663 | $styles->add_data( $rtl_style, 'rtl', true ); |
|---|
| 664 | if ( $suffix && ! in_array( $rtl_style, $no_suffix ) ) |
|---|
| 665 | diff --git wp-includes/shortcodes.php wp-includes/shortcodes.php |
|---|
| 666 | index 2dfc277..716dae4 100644 |
|---|
| 667 | --- wp-includes/shortcodes.php |
|---|
| 668 | +++ wp-includes/shortcodes.php |
|---|
| 669 | @@ -128,6 +128,20 @@ function remove_all_shortcodes() { |
|---|
| 670 | } |
|---|
| 671 | |
|---|
| 672 | /** |
|---|
| 673 | + * Whether a registered shortcode exists named $tag |
|---|
| 674 | + * |
|---|
| 675 | + * @since 3.6.0 |
|---|
| 676 | + * |
|---|
| 677 | + * @global array $shortcode_tags |
|---|
| 678 | + * @param string $tag |
|---|
| 679 | + * @return boolean |
|---|
| 680 | + */ |
|---|
| 681 | +function shortcode_exists( $tag ) { |
|---|
| 682 | + global $shortcode_tags; |
|---|
| 683 | + return array_key_exists( $tag, $shortcode_tags ); |
|---|
| 684 | +} |
|---|
| 685 | + |
|---|
| 686 | +/** |
|---|
| 687 | * Search content for shortcodes and filter shortcodes through their hooks. |
|---|
| 688 | * |
|---|
| 689 | * If there are no shortcode tags defined, then the content will be returned |
|---|