~ubuntu-branches/debian/jessie/wordpress/jessie

« back to all changes in this revision

Viewing changes to wp-includes/media.php

  • Committer: Package Import Robot
  • Author(s): Craig Small
  • Date: 2014-04-17 20:56:19 UTC
  • mfrom: (1.2.35)
  • Revision ID: package-import@ubuntu.com-20140417205619-nurbet6eho4yvwfv
Tags: 3.9+dfsg-1
* New upstream release
* 3.9 seems to handle different locations for plugins so the
  plugin directory handling patches have been cut back.

Show diffs side-by-side

added added

removed removed

Lines of Context:
78
78
                $max_height = $height;
79
79
        }
80
80
 
 
81
        /**
 
82
         * Filter the maximum image size dimensions for the editor.
 
83
         *
 
84
         * @since 2.5.0
 
85
         *
 
86
         * @param array        $max_image_size An array with the width as the first element,
 
87
         *                                     and the height as the second element.
 
88
         * @param string|array $size           Size of what the result image should be.
 
89
         * @param string       $context        The context the image is being resized for.
 
90
         *                                     Possible values are 'display' (like in a theme)
 
91
         *                                     or 'edit' (like inserting into an editor).
 
92
         */
81
93
        list( $max_width, $max_height ) = apply_filters( 'editor_max_image_size', array( $max_width, $max_height ), $size, $context );
82
94
 
83
95
        return wp_constrain_dimensions( $width, $height, $max_width, $max_height );
126
138
 * to the new image that was resized.
127
139
 *
128
140
 * @since 2.5.0
129
 
 * @uses apply_filters() Calls 'image_downsize' on $id and $size to provide
130
 
 *              resize services.
131
141
 *
132
142
 * @param int $id Attachment ID for image.
133
143
 * @param array|string $size Optional, default is 'medium'. Size of image, either array or string.
138
148
        if ( !wp_attachment_is_image($id) )
139
149
                return false;
140
150
 
141
 
        // plugins can use this to provide resize services
142
 
        if ( $out = apply_filters( 'image_downsize', false, $id, $size ) )
 
151
        /**
 
152
         * Filter whether to preempt the output of image_downsize().
 
153
         *
 
154
         * Passing a truthy value to the filter will effectively short-circuit
 
155
         * down-sizing the image, returning that value as output instead.
 
156
         *
 
157
         * @since 2.5.0
 
158
         *
 
159
         * @param bool         $downsize Whether to short-circuit the image downsize. Default false.
 
160
         * @param int          $id       Attachment ID for image.
 
161
         * @param array|string $size     Size of image, either array or string. Default 'medium'.
 
162
         */
 
163
        if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
143
164
                return $out;
 
165
        }
144
166
 
145
167
        $img_url = wp_get_attachment_url($id);
146
168
        $meta = wp_get_attachment_metadata($id);
181
203
}
182
204
 
183
205
/**
184
 
 * Registers a new image size
 
206
 * Register a new image size.
 
207
 *
 
208
 * Cropping behavior for the image size is dependent on the value of $crop:
 
209
 * 1. If false (default), images will be scaled, not cropped.
 
210
 * 2. If an array in the form of array( x_crop_position, y_crop_position ):
 
211
 *    - x_crop_position accepts 'left' 'center', or 'right'.
 
212
 *    - y_crop_position accepts 'top', 'center', or 'bottom'.
 
213
 *    Images will be cropped to the specified dimensions within the defined crop area.
 
214
 * 3. If true, images will be cropped to the specified dimensions using center positions.
185
215
 *
186
216
 * @since 2.9.0
 
217
 *
 
218
 * @param string     $name   Image size identifier.
 
219
 * @param int        $width  Image width in pixels.
 
220
 * @param int        $height Image height in pixels.
 
221
 * @param bool|array $crop   Optional. Whether to crop images to specified height and width or resize.
 
222
 *                           An array can specify positioning of the crop area. Default false.
 
223
 * @return bool|array False, if no image was created. Metadata array on success.
187
224
 */
188
225
function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
189
226
        global $_wp_additional_image_sizes;
190
 
        $_wp_additional_image_sizes[$name] = array( 'width' => absint( $width ), 'height' => absint( $height ), 'crop' => (bool) $crop );
191
 
}
192
 
 
193
 
/**
194
 
 * Registers an image size for the post thumbnail
 
227
 
 
228
        $_wp_additional_image_sizes[ $name ] = array(
 
229
                'width'  => absint( $width ),
 
230
                'height' => absint( $height ),
 
231
                'crop'   => $crop,
 
232
        );
 
233
}
 
234
 
 
235
/**
 
236
 * Check if an image size exists.
 
237
 *
 
238
 * @since 3.9.0
 
239
 *
 
240
 * @param string $name The image size to check.
 
241
 * @return bool True if the image size exists, false if not.
 
242
 */
 
243
function has_image_size( $name ) {
 
244
        global $_wp_additional_image_sizes;
 
245
 
 
246
        return isset( $_wp_additional_image_sizes[ $name ] );
 
247
}
 
248
 
 
249
/**
 
250
 * Remove a new image size.
 
251
 *
 
252
 * @since 3.9.0
 
253
 *
 
254
 * @param string $name The image size to remove.
 
255
 * @return bool True if the image size was successfully removed, false on failure.
 
256
 */
 
257
function remove_image_size( $name ) {
 
258
        global $_wp_additional_image_sizes;
 
259
 
 
260
        if ( isset( $_wp_additional_image_sizes[ $name ] ) ) {
 
261
                unset( $_wp_additional_image_sizes[ $name ] );
 
262
                return true;
 
263
        }
 
264
 
 
265
        return false;
 
266
}
 
267
 
 
268
/**
 
269
 * Registers an image size for the post thumbnail.
195
270
 *
196
271
 * @since 2.9.0
 
272
 * @see add_image_size() for details on cropping behavior.
 
273
 *
 
274
 * @param int        $width  Image width in pixels.
 
275
 * @param int        $height Image height in pixels.
 
276
 * @param bool|array $crop   Optional. Whether to crop images to specified height and width or resize.
 
277
 *                           An array can specify positioning of the crop area. Default false.
 
278
 * @return bool|array False, if no image was created. Metadata array on success.
197
279
 */
198
280
function set_post_thumbnail_size( $width = 0, $height = 0, $crop = false ) {
199
281
        add_image_size( 'post-thumbnail', $width, $height, $crop );
213
295
 *
214
296
 * @since 2.5.0
215
297
 *
216
 
 * @uses apply_filters() The 'get_image_tag_class' filter is the IMG element
217
 
 *              class attribute.
218
 
 * @uses apply_filters() The 'get_image_tag' filter is the full IMG element with
219
 
 *              all attributes.
220
 
 *
221
298
 * @param int $id Attachment ID.
222
299
 * @param string $alt Image Description for the alt attribute.
223
300
 * @param string $title Image Description for the title attribute.
233
310
        $title = $title ? 'title="' . esc_attr( $title ) . '" ' : '';
234
311
 
235
312
        $class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id;
236
 
        $class = apply_filters('get_image_tag_class', $class, $id, $align, $size);
 
313
 
 
314
        /**
 
315
         * Filter the value of the attachment's image tag class attribute.
 
316
         *
 
317
         * @since 2.6.0
 
318
         *
 
319
         * @param string $class CSS class name or space-separated list of classes.
 
320
         * @param int    $id    Attachment ID.
 
321
         * @param string $align Part of the class name for aligning the image.
 
322
         * @param string $size  Optional. Default is 'medium'.
 
323
         */
 
324
        $class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
237
325
 
238
326
        $html = '<img src="' . esc_attr($img_src) . '" alt="' . esc_attr($alt) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
239
327
 
 
328
        /**
 
329
         * Filter the HTML content for the image tag.
 
330
         *
 
331
         * @since 2.6.0
 
332
         *
 
333
         * @param string $html  HTML content for the image.
 
334
         * @param int    $id    Attachment ID.
 
335
         * @param string $alt   Alternate text.
 
336
         * @param string $title Attachment title.
 
337
         * @param string $align Part of the class name for aligning the image.
 
338
         * @param string $size  Optional. Default is 'medium'.
 
339
         */
240
340
        $html = apply_filters( 'get_image_tag', $html, $id, $alt, $title, $align, $size );
241
341
 
242
342
        return $html;
300
400
}
301
401
 
302
402
/**
303
 
 * Retrieve calculated resized dimensions for use in WP_Image_Editor.
304
 
 *
305
 
 * Calculate dimensions and coordinates for a resized image that fits within a
306
 
 * specified width and height. If $crop is true, the largest matching central
307
 
 * portion of the image will be cropped out and resized to the required size.
 
403
 * Retrieve calculated resize dimensions for use in WP_Image_Editor.
 
404
 *
 
405
 * Calculates dimensions and coordinates for a resized image that fits
 
406
 * within a specified width and height.
 
407
 *
 
408
 * Cropping behavior is dependent on the value of $crop:
 
409
 * 1. If false (default), images will not be cropped.
 
410
 * 2. If an array in the form of array( x_crop_position, y_crop_position ):
 
411
 *    - x_crop_position accepts 'left' 'center', or 'right'.
 
412
 *    - y_crop_position accepts 'top', 'center', or 'bottom'.
 
413
 *    Images will be cropped to the specified dimensions within the defined crop area.
 
414
 * 3. If true, images will be cropped to the specified dimensions using center positions.
308
415
 *
309
416
 * @since 2.5.0
310
 
 * @uses apply_filters() Calls 'image_resize_dimensions' on $orig_w, $orig_h, $dest_w, $dest_h and
311
 
 *              $crop to provide custom resize dimensions.
312
417
 *
313
 
 * @param int $orig_w Original width.
314
 
 * @param int $orig_h Original height.
315
 
 * @param int $dest_w New width.
316
 
 * @param int $dest_h New height.
317
 
 * @param bool $crop Optional, default is false. Whether to crop image or resize.
318
 
 * @return bool|array False on failure. Returned array matches parameters for imagecopyresampled() PHP function.
 
418
 * @param int        $orig_w Original width in pixels.
 
419
 * @param int        $orig_h Original height in pixels.
 
420
 * @param int        $dest_w New width in pixels.
 
421
 * @param int        $dest_h New height in pixels.
 
422
 * @param bool|array $crop   Optional. Whether to crop image to specified height and width or resize.
 
423
 *                           An array can specify positioning of the crop area. Default false.
 
424
 * @return bool|array False on failure. Returned array matches parameters for `imagecopyresampled()`.
319
425
 */
320
426
function image_resize_dimensions($orig_w, $orig_h, $dest_w, $dest_h, $crop = false) {
321
427
 
325
431
        if ($dest_w <= 0 && $dest_h <= 0)
326
432
                return false;
327
433
 
328
 
        // plugins can use this to provide custom resize dimensions
 
434
        /**
 
435
         * Filter whether to preempt calculating the image resize dimensions.
 
436
         *
 
437
         * Passing a non-null value to the filter will effectively short-circuit
 
438
         * image_resize_dimensions(), returning that value instead.
 
439
         *
 
440
         * @since 3.4.0
 
441
         *
 
442
         * @param null|mixed $null   Whether to preempt output of the resize dimensions.
 
443
         * @param int        $orig_w Original width in pixels.
 
444
         * @param int        $orig_h Original height in pixels.
 
445
         * @param int        $dest_w New width in pixels.
 
446
         * @param int        $dest_h New height in pixels.
 
447
         * @param bool|array $crop   Whether to crop image to specified height and width or resize.
 
448
         *                           An array can specify positioning of the crop area. Default false.
 
449
         */
329
450
        $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );
330
451
        if ( null !== $output )
331
452
                return $output;
349
470
                $crop_w = round($new_w / $size_ratio);
350
471
                $crop_h = round($new_h / $size_ratio);
351
472
 
352
 
                $s_x = floor( ($orig_w - $crop_w) / 2 );
353
 
                $s_y = floor( ($orig_h - $crop_h) / 2 );
 
473
                if ( ! is_array( $crop ) || count( $crop ) !== 2 ) {
 
474
                        $crop = array( 'center', 'center' );
 
475
                }
 
476
 
 
477
                list( $x, $y ) = $crop;
 
478
 
 
479
                if ( 'left' === $x ) {
 
480
                        $s_x = 0;
 
481
                } elseif ( 'right' === $x ) {
 
482
                        $s_x = $orig_w - $crop_w;
 
483
                } else {
 
484
                        $s_x = floor( ( $orig_w - $crop_w ) / 2 );
 
485
                }
 
486
 
 
487
                if ( 'top' === $y ) {
 
488
                        $s_y = 0;
 
489
                } elseif ( 'bottom' === $y ) {
 
490
                        $s_y = $orig_h - $crop_h;
 
491
                } else {
 
492
                        $s_y = floor( ( $orig_h - $crop_h ) / 2 );
 
493
                }
354
494
        } else {
355
495
                // don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
356
496
                $crop_w = $orig_w;
491
631
        if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) )
492
632
                $image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
493
633
 
 
634
        /**
 
635
         * Filter the list of intermediate image sizes.
 
636
         *
 
637
         * @since 2.5.0
 
638
         *
 
639
         * @param array $image_sizes An array of intermediate image sizes. Defaults
 
640
         *                           are 'thumbnail', 'medium', 'large'.
 
641
         */
494
642
        return apply_filters( 'intermediate_image_sizes', $image_sizes );
495
643
}
496
644
 
515
663
        $src = false;
516
664
 
517
665
        if ( $icon && $src = wp_mime_type_icon($attachment_id) ) {
518
 
                $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/crystal' );
 
666
                /** This filter is documented in wp-includes/post.php */
 
667
                $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
519
668
                $src_file = $icon_dir . '/' . wp_basename($src);
520
669
                @list($width, $height) = getimagesize($src_file);
521
670
        }
532
681
 * efficient than having to find the closest-sized image and then having the
533
682
 * browser scale down the image.
534
683
 *
 
684
 * @since 2.5.0
 
685
 *
535
686
 * @see add_image_size()
536
 
 * @uses apply_filters() Calls 'wp_get_attachment_image_attributes' hook on attributes array
537
687
 * @uses wp_get_attachment_image_src() Gets attachment file URL and dimensions
538
 
 * @since 2.5.0
539
688
 *
540
689
 * @param int $attachment_id Image attachment ID.
541
690
 * @param string $size Optional, default is 'thumbnail'.
564
713
                        $default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title
565
714
 
566
715
                $attr = wp_parse_args($attr, $default_attr);
 
716
 
 
717
                /**
 
718
                 * Filter the list of attachment image attributes.
 
719
                 *
 
720
                 * @since 2.8.0
 
721
                 *
 
722
                 * @param mixed $attr          Attributes for the image markup.
 
723
                 * @param int   $attachment_id Image attachment ID.
 
724
                 */
567
725
                $attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment );
568
726
                $attr = array_map( 'esc_attr', $attr );
569
727
                $html = rtrim("<img $hwstring");
623
781
 *
624
782
 * @since 2.6.0
625
783
 *
626
 
 * @param array $attr Attributes attributed to the shortcode.
 
784
 * @param array $attr {
 
785
 *     Attributes of the caption shortcode.
 
786
 *
 
787
 *     @type string $id      ID of the div element for the caption.
 
788
 *     @type string $align   Class name that aligns the caption. Default 'alignnone'. Accepts 'alignleft',
 
789
 *                           'aligncenter', alignright', 'alignnone'.
 
790
 *     @type int    $width   The width of the caption, in pixels.
 
791
 *     @type string $caption The caption text.
 
792
 *     @type string $class   Additional class name(s) added to the caption container.
 
793
 * }
627
794
 * @param string $content Optional. Shortcode content.
628
 
 * @return string
 
795
 * @return string HTML content to display the caption.
629
796
 */
630
 
function img_caption_shortcode($attr, $content = null) {
 
797
function img_caption_shortcode( $attr, $content = null ) {
631
798
        // New-style shortcode with the caption inside the shortcode with the link and image tags.
632
799
        if ( ! isset( $attr['caption'] ) ) {
633
800
                if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
636
803
                }
637
804
        }
638
805
 
639
 
        // Allow plugins/themes to override the default caption template.
640
 
        $output = apply_filters('img_caption_shortcode', '', $attr, $content);
 
806
        /**
 
807
         * Filter the default caption shortcode output.
 
808
         *
 
809
         * If the filtered output isn't empty, it will be used instead of generating
 
810
         * the default caption template.
 
811
         *
 
812
         * @since 2.6.0
 
813
         *
 
814
         * @see img_caption_shortcode()
 
815
         *
 
816
         * @param string $output  The caption output. Default empty.
 
817
         * @param array  $attr    Attributes of the caption shortcode.
 
818
         * @param string $content The image element, possibly wrapped in a hyperlink.
 
819
         */
 
820
        $output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
641
821
        if ( $output != '' )
642
822
                return $output;
643
823
 
645
825
                'id'      => '',
646
826
                'align'   => 'alignnone',
647
827
                'width'   => '',
648
 
                'caption' => ''
 
828
                'caption' => '',
 
829
                'class'   => '',
649
830
        ), $attr, 'caption' );
650
831
 
651
832
        $atts['width'] = (int) $atts['width'];
655
836
        if ( ! empty( $atts['id'] ) )
656
837
                $atts['id'] = 'id="' . esc_attr( $atts['id'] ) . '" ';
657
838
 
 
839
        $class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] );
 
840
 
 
841
        if ( current_theme_supports( 'html5', 'caption' ) ) {
 
842
                return '<figure ' . $atts['id'] . 'style="width: ' . (int) $atts['width'] . 'px;" class="' . esc_attr( $class ) . '">'
 
843
                . do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $atts['caption'] . '</figcaption></figure>';
 
844
        }
 
845
 
658
846
        $caption_width = 10 + $atts['width'];
659
847
 
660
848
        /**
665
853
         *
666
854
         * @since 3.7.0
667
855
         *
668
 
         * @param int $caption_width Width in pixels. To remove this inline style, return zero.
669
 
         * @param array $atts {
670
 
         *     The attributes of the caption shortcode.
 
856
         * @see img_caption_shortcode()
671
857
         *
672
 
         *     @type string 'id'      The ID of the div element for the caption.
673
 
         *     @type string 'align'   The class name that aligns the caption. Default 'alignnone'.
674
 
         *     @type int    'width'   The width of the image being captioned.
675
 
         *     @type string 'caption' The image's caption.
676
 
         * }
677
 
         * @param string $content The image element, possibly wrapped in a hyperlink.
 
858
         * @param int    $caption_width Width of the caption in pixels. To remove this inline style,
 
859
         *                              return zero.
 
860
         * @param array  $atts          Attributes of the caption shortcode.
 
861
         * @param string $content       The image element, possibly wrapped in a hyperlink.
678
862
         */
679
863
        $caption_width = apply_filters( 'img_caption_shortcode_width', $caption_width, $atts, $content );
680
864
 
682
866
        if ( $caption_width )
683
867
                $style = 'style="width: ' . (int) $caption_width . 'px" ';
684
868
 
685
 
        return '<div ' . $atts['id'] . $style . 'class="wp-caption ' . esc_attr( $atts['align'] ) . '">'
 
869
        return '<div ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
686
870
        . do_shortcode( $content ) . '<p class="wp-caption-text">' . $atts['caption'] . '</p></div>';
687
871
}
688
872
 
696
880
 *
697
881
 * @since 2.5.0
698
882
 *
699
 
 * @param array $attr Attributes of the shortcode.
 
883
 * @param array $attr {
 
884
 *     Attributes of the gallery shortcode.
 
885
 *
 
886
 *     @type string $order      Order of the images in the gallery. Default 'ASC'. Accepts 'ASC', 'DESC'.
 
887
 *     @type string $orderby    The field to use when ordering the images. Default 'menu_order ID'.
 
888
 *                              Accepts any valid SQL ORDERBY statement.
 
889
 *     @type int    $id         Post ID.
 
890
 *     @type string $itemtag    HTML tag to use for each image in the gallery.
 
891
 *                              Default 'dl', or 'figure' when the theme registers HTML5 gallery support.
 
892
 *     @type string $icontag    HTML tag to use for each image's icon.
 
893
 *                              Default 'dt', or 'div' when the theme registers HTML5 gallery support.
 
894
 *     @type string $captiontag HTML tag to use for each image's caption.
 
895
 *                              Default 'dd', or 'figcaption' when the theme registers HTML5 gallery support.
 
896
 *     @type int    $columns    Number of columns of images to display. Default 3.
 
897
 *     @type string $size       Size of the images to display. Default 'thumbnail'.
 
898
 *     @type string $ids        A comma-separated list of IDs of attachments to display. Default empty.
 
899
 *     @type string $include    A comma-separated list of IDs of attachments to include. Default empty.
 
900
 *     @type string $exclude    A comma-separated list of IDs of attachments to exclude. Default empty.
 
901
 *     @type string $link       What to link each image to. Default empty (links to the attachment page).
 
902
 *                              Accepts 'file', 'none'.
 
903
 * }
700
904
 * @return string HTML content to display gallery.
701
905
 */
702
 
function gallery_shortcode($attr) {
 
906
function gallery_shortcode( $attr ) {
703
907
        $post = get_post();
704
908
 
705
909
        static $instance = 0;
712
916
                $attr['include'] = $attr['ids'];
713
917
        }
714
918
 
715
 
        // Allow plugins/themes to override the default gallery template.
716
 
        $output = apply_filters('post_gallery', '', $attr);
 
919
        /**
 
920
         * Filter the default gallery shortcode output.
 
921
         *
 
922
         * If the filtered output isn't empty, it will be used instead of generating
 
923
         * the default gallery template.
 
924
         *
 
925
         * @since 2.5.0
 
926
         *
 
927
         * @see gallery_shortcode()
 
928
         *
 
929
         * @param string $output The gallery output. Default empty.
 
930
         * @param array  $attr   Attributes of the gallery shortcode.
 
931
         */
 
932
        $output = apply_filters( 'post_gallery', '', $attr );
717
933
        if ( $output != '' )
718
934
                return $output;
719
935
 
724
940
                        unset( $attr['orderby'] );
725
941
        }
726
942
 
 
943
        $html5 = current_theme_supports( 'html5', 'gallery' );
727
944
        extract(shortcode_atts(array(
728
945
                'order'      => 'ASC',
729
946
                'orderby'    => 'menu_order ID',
730
947
                'id'         => $post ? $post->ID : 0,
731
 
                'itemtag'    => 'dl',
732
 
                'icontag'    => 'dt',
733
 
                'captiontag' => 'dd',
 
948
                'itemtag'    => $html5 ? 'figure'     : 'dl',
 
949
                'icontag'    => $html5 ? 'div'        : 'dt',
 
950
                'captiontag' => $html5 ? 'figcaption' : 'dd',
734
951
                'columns'    => 3,
735
952
                'size'       => 'thumbnail',
736
953
                'include'    => '',
783
1000
        $selector = "gallery-{$instance}";
784
1001
 
785
1002
        $gallery_style = $gallery_div = '';
786
 
        if ( apply_filters( 'use_default_gallery_style', true ) )
 
1003
 
 
1004
        /**
 
1005
         * Filter whether to print default gallery styles.
 
1006
         *
 
1007
         * @since 3.1.0
 
1008
         *
 
1009
         * @param bool $print Whether to print default gallery styles.
 
1010
         *                    Defaults to false if the theme supports HTML5 galleries.
 
1011
         *                    Otherwise, defaults to true.
 
1012
         */
 
1013
        if ( apply_filters( 'use_default_gallery_style', ! $html5 ) ) {
787
1014
                $gallery_style = "
788
1015
                <style type='text/css'>
789
1016
                        #{$selector} {
802
1029
                                margin-left: 0;
803
1030
                        }
804
1031
                        /* see gallery_shortcode() in wp-includes/media.php */
805
 
                </style>";
 
1032
                </style>\n\t\t";
 
1033
        }
 
1034
 
806
1035
        $size_class = sanitize_html_class( $size );
807
1036
        $gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
808
 
        $output = apply_filters( 'gallery_style', $gallery_style . "\n\t\t" . $gallery_div );
 
1037
 
 
1038
        /**
 
1039
         * Filter the default gallery shortcode CSS styles.
 
1040
         *
 
1041
         * @since 2.5.0
 
1042
         *
 
1043
         * @param string $gallery_style Default gallery shortcode CSS styles.
 
1044
         * @param string $gallery_div   Opening HTML div container for the gallery shortcode output.
 
1045
         */
 
1046
        $output = apply_filters( 'gallery_style', $gallery_style . $gallery_div );
809
1047
 
810
1048
        $i = 0;
811
1049
        foreach ( $attachments as $id => $attachment ) {
834
1072
                                </{$captiontag}>";
835
1073
                }
836
1074
                $output .= "</{$itemtag}>";
837
 
                if ( $columns > 0 && ++$i % $columns == 0 )
 
1075
                if ( ! $html5 && $columns > 0 && ++$i % $columns == 0 ) {
838
1076
                        $output .= '<br style="clear: both" />';
 
1077
                }
 
1078
        }
 
1079
 
 
1080
        if ( ! $html5 && $columns > 0 && $i % $columns !== 0 ) {
 
1081
                $output .= "
 
1082
                        <br style='clear: both' />";
839
1083
        }
840
1084
 
841
1085
        $output .= "
842
 
                        <br style='clear: both;' />
843
1086
                </div>\n";
844
1087
 
845
1088
        return $output;
846
1089
}
847
1090
 
848
1091
/**
 
1092
 * Output the templates used by playlists.
 
1093
 *
 
1094
 * @since 3.9.0
 
1095
 */
 
1096
function wp_underscore_playlist_templates() {
 
1097
?>
 
1098
<script type="text/html" id="tmpl-wp-playlist-current-item">
 
1099
        <# if ( data.image ) { #>
 
1100
        <img src="{{ data.thumb.src }}"/>
 
1101
        <# } #>
 
1102
        <div class="wp-playlist-caption">
 
1103
                <span class="wp-playlist-item-meta wp-playlist-item-title">&#8220;{{ data.title }}&#8221;</span>
 
1104
                <# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #>
 
1105
                <# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #>
 
1106
        </div>
 
1107
</script>
 
1108
<script type="text/html" id="tmpl-wp-playlist-item">
 
1109
        <div class="wp-playlist-item">
 
1110
                <a class="wp-playlist-caption" href="{{ data.src }}">
 
1111
                        {{ data.index ? ( data.index + '. ' ) : '' }}
 
1112
                        <# if ( data.caption ) { #>
 
1113
                                {{ data.caption }}
 
1114
                        <# } else { #>
 
1115
                                <span class="wp-playlist-item-title">&#8220;{{{ data.title }}}&#8221;</span>
 
1116
                                <# if ( data.artists && data.meta.artist ) { #>
 
1117
                                <span class="wp-playlist-item-artist"> &mdash; {{ data.meta.artist }}</span>
 
1118
                                <# } #>
 
1119
                        <# } #>
 
1120
                </a>
 
1121
                <# if ( data.meta.length_formatted ) { #>
 
1122
                <div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div>
 
1123
                <# } #>
 
1124
        </div>
 
1125
</script>
 
1126
<?php
 
1127
}
 
1128
 
 
1129
/**
 
1130
 * Output and enqueue default scripts and styles for playlists.
 
1131
 *
 
1132
 * @since 3.9.0
 
1133
 *
 
1134
 * @param string $type Type of playlist. Accepts 'audio' or 'video'.
 
1135
 */
 
1136
function wp_playlist_scripts( $type ) {
 
1137
        wp_enqueue_style( 'wp-mediaelement' );
 
1138
        wp_enqueue_script( 'wp-playlist' );
 
1139
?>
 
1140
<!--[if lt IE 9]><script>document.createElement('<?php echo esc_js( $type ) ?>');</script><![endif]-->
 
1141
<?php
 
1142
        add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 );
 
1143
        add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 );
 
1144
}
 
1145
add_action( 'wp_playlist_scripts', 'wp_playlist_scripts' );
 
1146
 
 
1147
/**
 
1148
 * The playlist shortcode.
 
1149
 *
 
1150
 * This implements the functionality of the playlist shortcode for displaying
 
1151
 * a collection of WordPress audio or video files in a post.
 
1152
 *
 
1153
 * @since 3.9.0
 
1154
 *
 
1155
 * @param array $attr Playlist shortcode attributes.
 
1156
 * @return string Playlist output. Empty string if the passed type is unsupported.
 
1157
 */
 
1158
function wp_playlist_shortcode( $attr ) {
 
1159
        global $content_width;
 
1160
        $post = get_post();
 
1161
 
 
1162
        static $instance = 0;
 
1163
        $instance++;
 
1164
 
 
1165
        if ( ! empty( $attr['ids'] ) ) {
 
1166
                // 'ids' is explicitly ordered, unless you specify otherwise.
 
1167
                if ( empty( $attr['orderby'] ) ) {
 
1168
                        $attr['orderby'] = 'post__in';
 
1169
                }
 
1170
                $attr['include'] = $attr['ids'];
 
1171
        }
 
1172
 
 
1173
        /**
 
1174
         * Filter the playlist output.
 
1175
         *
 
1176
         * Passing a non-empty value to the filter will short-circuit generation
 
1177
         * of the default playlist output, returning the passed value instead.
 
1178
         *
 
1179
         * @since 3.9.0
 
1180
         *
 
1181
         * @param string $output Playlist output. Default empty.
 
1182
         * @param array  $attr   An array of shortcode attributes.
 
1183
         */
 
1184
        $output = apply_filters( 'post_playlist', '', $attr );
 
1185
        if ( $output != '' ) {
 
1186
                return $output;
 
1187
        }
 
1188
 
 
1189
        /*
 
1190
         * We're trusting author input, so let's at least make sure it looks
 
1191
         * like a valid orderby statement.
 
1192
         */
 
1193
        if ( isset( $attr['orderby'] ) ) {
 
1194
                $attr['orderby'] = sanitize_sql_orderby( $attr['orderby'] );
 
1195
                if ( ! $attr['orderby'] )
 
1196
                        unset( $attr['orderby'] );
 
1197
        }
 
1198
 
 
1199
        extract( shortcode_atts( array(
 
1200
                'type'          => 'audio',
 
1201
                'order'         => 'ASC',
 
1202
                'orderby'       => 'menu_order ID',
 
1203
                'id'            => $post ? $post->ID : 0,
 
1204
                'include'       => '',
 
1205
                'exclude'   => '',
 
1206
                'style'         => 'light',
 
1207
                'tracklist' => true,
 
1208
                'tracknumbers' => true,
 
1209
                'images'        => true,
 
1210
                'artists'       => true
 
1211
        ), $attr, 'playlist' ) );
 
1212
 
 
1213
        $id = intval( $id );
 
1214
        if ( 'RAND' == $order ) {
 
1215
                $orderby = 'none';
 
1216
        }
 
1217
 
 
1218
        $args = array(
 
1219
                'post_status' => 'inherit',
 
1220
                'post_type' => 'attachment',
 
1221
                'post_mime_type' => $type,
 
1222
                'order' => $order,
 
1223
                'orderby' => $orderby
 
1224
        );
 
1225
 
 
1226
        if ( ! empty( $include ) ) {
 
1227
                $args['include'] = $include;
 
1228
                $_attachments = get_posts( $args );
 
1229
 
 
1230
                $attachments = array();
 
1231
                foreach ( $_attachments as $key => $val ) {
 
1232
                        $attachments[$val->ID] = $_attachments[$key];
 
1233
                }
 
1234
        } elseif ( ! empty( $exclude ) ) {
 
1235
                $args['post_parent'] = $id;
 
1236
                $args['exclude'] = $exclude;
 
1237
                $attachments = get_children( $args );
 
1238
        } else {
 
1239
                $args['post_parent'] = $id;
 
1240
                $attachments = get_children( $args );
 
1241
        }
 
1242
 
 
1243
        if ( empty( $attachments ) ) {
 
1244
                return '';
 
1245
        }
 
1246
 
 
1247
        if ( is_feed() ) {
 
1248
                $output = "\n";
 
1249
                foreach ( $attachments as $att_id => $attachment ) {
 
1250
                        $output .= wp_get_attachment_link( $att_id ) . "\n";
 
1251
                }
 
1252
                return $output;
 
1253
        }
 
1254
 
 
1255
        $outer = 22; // default padding and border of wrapper
 
1256
 
 
1257
        $default_width = 640;
 
1258
        $default_height = 360;
 
1259
 
 
1260
        $theme_width = empty( $content_width ) ? $default_width : ( $content_width - $outer );
 
1261
        $theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width );
 
1262
 
 
1263
        $data = compact( 'type' );
 
1264
 
 
1265
        // don't pass strings to JSON, will be truthy in JS
 
1266
        foreach ( array( 'tracklist', 'tracknumbers', 'images', 'artists' ) as $key ) {
 
1267
                $data[$key] = filter_var( $$key, FILTER_VALIDATE_BOOLEAN );
 
1268
        }
 
1269
 
 
1270
        $tracks = array();
 
1271
        foreach ( $attachments as $attachment ) {
 
1272
                $url = wp_get_attachment_url( $attachment->ID );
 
1273
                $ftype = wp_check_filetype( $url, wp_get_mime_types() );
 
1274
                $track = array(
 
1275
                        'src' => $url,
 
1276
                        'type' => $ftype['type'],
 
1277
                        'title' => $attachment->post_title,
 
1278
                        'caption' => $attachment->post_excerpt,
 
1279
                        'description' => $attachment->post_content
 
1280
                );
 
1281
 
 
1282
                $track['meta'] = array();
 
1283
                $meta = wp_get_attachment_metadata( $attachment->ID );
 
1284
                if ( ! empty( $meta ) ) {
 
1285
 
 
1286
                        foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) {
 
1287
                                if ( ! empty( $meta[ $key ] ) ) {
 
1288
                                        $track['meta'][ $key ] = $meta[ $key ];
 
1289
                                }
 
1290
                        }
 
1291
 
 
1292
                        if ( 'video' === $type ) {
 
1293
                                if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
 
1294
                                        $width = $meta['width'];
 
1295
                                        $height = $meta['height'];
 
1296
                                        $theme_height = round( ( $height * $theme_width ) / $width );
 
1297
                                } else {
 
1298
                                        $width = $default_width;
 
1299
                                        $height = $default_height;
 
1300
                                }
 
1301
 
 
1302
                                $track['dimensions'] = array(
 
1303
                                        'original' => compact( 'width', 'height' ),
 
1304
                                        'resized' => array(
 
1305
                                                'width' => $theme_width,
 
1306
                                                'height' => $theme_height
 
1307
                                        )
 
1308
                                );
 
1309
                        }
 
1310
                }
 
1311
 
 
1312
                if ( $images ) {
 
1313
                        $id = get_post_thumbnail_id( $attachment->ID );
 
1314
                        if ( ! empty( $id ) ) {
 
1315
                                list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' );
 
1316
                                $track['image'] = compact( 'src', 'width', 'height' );
 
1317
                                list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' );
 
1318
                                $track['thumb'] = compact( 'src', 'width', 'height' );
 
1319
                        } else {
 
1320
                                $src = wp_mime_type_icon( $attachment->ID );
 
1321
                                $width = 48;
 
1322
                                $height = 64;
 
1323
                                $track['image'] = compact( 'src', 'width', 'height' );
 
1324
                                $track['thumb'] = compact( 'src', 'width', 'height' );
 
1325
                        }
 
1326
                }
 
1327
 
 
1328
                $tracks[] = $track;
 
1329
        }
 
1330
        $data['tracks'] = $tracks;
 
1331
 
 
1332
        $safe_type = esc_attr( $type );
 
1333
        $safe_style = esc_attr( $style );
 
1334
 
 
1335
        ob_start();
 
1336
 
 
1337
        if ( 1 === $instance ) {
 
1338
                /**
 
1339
                 * Print and enqueue playlist scripts, styles, and JavaScript templates.
 
1340
                 *
 
1341
                 * @since 3.9.0
 
1342
                 *
 
1343
                 * @param string $type  Type of playlist. Possible values are 'audio' or 'video'.
 
1344
                 * @param string $style The 'theme' for the playlist. Core provides 'light' and 'dark'.
 
1345
                 */
 
1346
                do_action( 'wp_playlist_scripts', $type, $style );
 
1347
        } ?>
 
1348
<div class="wp-playlist wp-<?php echo $safe_type ?>-playlist wp-playlist-<?php echo $safe_style ?>">
 
1349
        <?php if ( 'audio' === $type ): ?>
 
1350
        <div class="wp-playlist-current-item"></div>
 
1351
        <?php endif ?>
 
1352
        <<?php echo $safe_type ?> controls="controls" preload="none" width="<?php
 
1353
                echo (int) $theme_width;
 
1354
        ?>"<?php if ( 'video' === $safe_type ):
 
1355
                echo ' height="', (int) $theme_height, '"';
 
1356
        endif; ?>></<?php echo $safe_type ?>>
 
1357
        <div class="wp-playlist-next"></div>
 
1358
        <div class="wp-playlist-prev"></div>
 
1359
        <noscript>
 
1360
        <ol><?php
 
1361
        foreach ( $attachments as $att_id => $attachment ) {
 
1362
                printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) );
 
1363
        }
 
1364
        ?></ol>
 
1365
        </noscript>
 
1366
        <script type="application/json"><?php echo json_encode( $data ) ?></script>
 
1367
</div>
 
1368
        <?php
 
1369
        return ob_get_clean();
 
1370
}
 
1371
add_shortcode( 'playlist', 'wp_playlist_shortcode' );
 
1372
 
 
1373
/**
849
1374
 * Provide a No-JS Flash fallback as a last resort for audio / video
850
1375
 *
851
1376
 * @since 3.6.0
854
1379
 * @return string Fallback HTML
855
1380
 */
856
1381
function wp_mediaelement_fallback( $url ) {
 
1382
        /**
 
1383
         * Filter the Mediaelement fallback output for no-JS.
 
1384
         *
 
1385
         * @since 3.6.0
 
1386
         *
 
1387
         * @param string $output Fallback output for no-JS.
 
1388
         * @param string $url    Media file URL.
 
1389
         */
857
1390
        return apply_filters( 'wp_mediaelement_fallback', sprintf( '<a href="%1$s">%1$s</a>', esc_url( $url ) ), $url );
858
1391
}
859
1392
 
860
1393
/**
861
 
 * Return a filtered list of WP-supported audio formats
 
1394
 * Return a filtered list of WP-supported audio formats.
862
1395
 *
863
1396
 * @since 3.6.0
864
1397
 * @return array
865
1398
 */
866
1399
function wp_get_audio_extensions() {
 
1400
        /**
 
1401
         * Filter the list of supported audio formats.
 
1402
         *
 
1403
         * @since 3.6.0
 
1404
         *
 
1405
         * @param array $extensions An array of support audio formats. Defaults are
 
1406
         *                          'mp3', 'ogg', 'wma', 'm4a', 'wav'.
 
1407
         */
867
1408
        return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'wma', 'm4a', 'wav' ) );
868
1409
}
869
1410
 
870
1411
/**
 
1412
 * Return useful keys to use to lookup data from an attachment's stored metadata.
 
1413
 *
 
1414
 * @since 3.9.0
 
1415
 *
 
1416
 * @param WP_Post $attachment The current attachment, provided for context.
 
1417
 * @param string  $context    The context. Accepts 'edit', 'display'. Default 'display'.
 
1418
 * @return array Key/value pairs of field keys to labels.
 
1419
 */
 
1420
function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) {
 
1421
        $fields = array(
 
1422
                'artist' => __( 'Artist' ),
 
1423
                'album' => __( 'Album' ),
 
1424
        );
 
1425
 
 
1426
        if ( 'display' === $context ) {
 
1427
                $fields['genre']            = __( 'Genre' );
 
1428
                $fields['year']             = __( 'Year' );
 
1429
                $fields['length_formatted'] = _x( 'Length', 'video or audio' );
 
1430
        }
 
1431
 
 
1432
        /**
 
1433
         * Filter the editable list of keys to look up data from an attachment's metadata.
 
1434
         *
 
1435
         * @since 3.9.0
 
1436
         *
 
1437
         * @param array   $fields     Key/value pairs of field keys to labels.
 
1438
         * @param WP_Post $attachment Attachment object.
 
1439
         * @param string  $context    The context. Accepts 'edit', 'display'. Default 'display'.
 
1440
         */
 
1441
        return apply_filters( 'wp_get_attachment_id3_keys', $fields, $attachment, $context );
 
1442
}
 
1443
/**
871
1444
 * The Audio shortcode.
872
1445
 *
873
1446
 * This implements the functionality of the Audio Shortcode for displaying
875
1448
 *
876
1449
 * @since 3.6.0
877
1450
 *
878
 
 * @param array  $attr    Attributes of the shortcode.
 
1451
 * @param array $attr {
 
1452
 *     Attributes of the audio shortcode.
 
1453
 *
 
1454
 *     @type string $src      URL to the source of the audio file. Default empty.
 
1455
 *     @type string $loop     The 'loop' attribute for the `<audio>` element. Default empty.
 
1456
 *     @type string $autoplay The 'autoplay' attribute for the `<audio>` element. Default empty.
 
1457
 *     @type string $preload  The 'preload' attribute for the `<audio>` element. Default empty.
 
1458
 *     @type string $class    The 'class' attribute for the `<audio>` element. Default 'wp-audio-shortcode'.
 
1459
 *     @type string $id       The 'id' attribute for the `<audio>` element. Default 'audio-{$post_id}-{$instances}'.
 
1460
 *     @type string $style    The 'style' attribute for the `<audio>` element. Default 'width: 100%'.
 
1461
 * }
879
1462
 * @param string $content Optional. Shortcode content.
880
1463
 * @return string HTML content to display audio.
881
1464
 */
886
1469
        $instances++;
887
1470
 
888
1471
        /**
889
 
         * Override the default audio shortcode.
890
 
         *
891
 
         * @since 3.7.0
892
 
         *
893
 
         * @param null              Empty variable to be replaced with shortcode markup.
894
 
         * @param array  $attr      Attributes of the shortcode.
 
1472
         * Filter the default audio shortcode output.
 
1473
         *
 
1474
         * If the filtered output isn't empty, it will be used instead of generating the default audio template.
 
1475
         *
 
1476
         * @since 3.6.0
 
1477
         *
 
1478
         * @param string $html      Empty variable to be replaced with shortcode markup.
 
1479
         * @param array  $attr      Attributes of the shortcode. @see wp_audio_shortcode()
895
1480
         * @param string $content   Shortcode content.
896
1481
         * @param int    $instances Unique numeric ID of this audio shortcode instance.
897
1482
         */
944
1529
                array_unshift( $default_types, 'src' );
945
1530
        }
946
1531
 
 
1532
        /**
 
1533
         * Filter the media library used for the audio shortcode.
 
1534
         *
 
1535
         * @since 3.6.0
 
1536
         *
 
1537
         * @param string $library Media library used for the audio shortcode.
 
1538
         */
947
1539
        $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
948
1540
        if ( 'mediaelement' === $library && did_action( 'init' ) ) {
949
1541
                wp_enqueue_style( 'wp-mediaelement' );
950
1542
                wp_enqueue_script( 'wp-mediaelement' );
951
1543
        }
952
1544
 
 
1545
        /**
 
1546
         * Filter the class attribute for the audio shortcode output container.
 
1547
         *
 
1548
         * @since 3.6.0
 
1549
         *
 
1550
         * @param string $class CSS class or list of space-separated classes.
 
1551
         */
953
1552
        $atts = array(
954
1553
                'class'    => apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ),
955
1554
                'id'       => sprintf( 'audio-%d-%d', $post_id, $instances ),
982
1581
                        if ( empty( $fileurl ) )
983
1582
                                $fileurl = $$fallback;
984
1583
                        $type = wp_check_filetype( $$fallback, wp_get_mime_types() );
985
 
                        $html .= sprintf( $source, $type['type'], esc_url( $$fallback ) );
 
1584
                        $url = add_query_arg( '_', $instances, $$fallback );
 
1585
                        $html .= sprintf( $source, $type['type'], esc_url( $url ) );
986
1586
                }
987
1587
        }
988
1588
 
990
1590
                $html .= wp_mediaelement_fallback( $fileurl );
991
1591
        $html .= '</audio>';
992
1592
 
 
1593
        /**
 
1594
         * Filter the audio shortcode output.
 
1595
         *
 
1596
         * @since 3.6.0
 
1597
         *
 
1598
         * @param string $html    Audio shortcode HTML output.
 
1599
         * @param array  $atts    Array of audio shortcode attributes.
 
1600
         * @param string $audio   Audio file.
 
1601
         * @param int    $post_id Post ID.
 
1602
         * @param string $library Media library used for the audio shortcode.
 
1603
         */
993
1604
        return apply_filters( 'wp_audio_shortcode', $html, $atts, $audio, $post_id, $library );
994
1605
}
995
1606
add_shortcode( 'audio', 'wp_audio_shortcode' );
1001
1612
 * @return array
1002
1613
 */
1003
1614
function wp_get_video_extensions() {
 
1615
        /**
 
1616
         * Filter the list of supported video formats.
 
1617
         *
 
1618
         * @since 3.6.0
 
1619
         *
 
1620
         * @param array $extensions An array of support video formats. Defaults are
 
1621
         *                          'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv'.
 
1622
         */
1004
1623
        return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'wmv', 'flv' ) );
1005
1624
}
1006
1625
 
1012
1631
 *
1013
1632
 * @since 3.6.0
1014
1633
 *
1015
 
 * @param array  $attr    Attributes of the shortcode.
 
1634
 * @param array $attr {
 
1635
 *     Attributes of the shortcode.
 
1636
 *
 
1637
 *     @type string $src      URL to the source of the video file. Default empty.
 
1638
 *     @type int    $height   Height of the video embed in pixels. Default 360.
 
1639
 *     @type int    $width    Width of the video embed in pixels. Default $content_width or 640.
 
1640
 *     @type string $poster   The 'poster' attribute for the `<video>` element. Default empty.
 
1641
 *     @type string $loop     The 'loop' attribute for the `<video>` element. Default empty.
 
1642
 *     @type string $autoplay The 'autoplay' attribute for the `<video>` element. Default empty.
 
1643
 *     @type string $preload  The 'preload' attribute for the `<video>` element.
 
1644
 *                            Default 'metadata'.
 
1645
 *     @type string $class    The 'class' attribute for the `<video>` element.
 
1646
 *                            Default 'wp-video-shortcode'.
 
1647
 *     @type string $id       The 'id' attribute for the `<video>` element.
 
1648
 *                            Default 'video-{$post_id}-{$instances}'.
 
1649
 * }
1016
1650
 * @param string $content Optional. Shortcode content.
1017
1651
 * @return string HTML content to display video.
1018
1652
 */
1024
1658
        $instances++;
1025
1659
 
1026
1660
        /**
1027
 
         * Override the default video shortcode.
1028
 
         *
1029
 
         * @since 3.7.0
1030
 
         *
1031
 
         * @param null              Empty variable to be replaced with shortcode markup.
1032
 
         * @param array  $attr      Attributes of the shortcode.
1033
 
         * @param string $content   Shortcode content.
 
1661
         * Filter the default video shortcode output.
 
1662
         *
 
1663
         * If the filtered output isn't empty, it will be used instead of generating
 
1664
         * the default video template.
 
1665
         *
 
1666
         * @since 3.6.0
 
1667
         *
 
1668
         * @see wp_video_shortcode()
 
1669
         *
 
1670
         * @param string $html      Empty variable to be replaced with shortcode markup.
 
1671
         * @param array  $attr      Attributes of the video shortcode.
 
1672
         * @param string $content   Video shortcode content.
1034
1673
         * @param int    $instances Unique numeric ID of this video shortcode instance.
1035
1674
         */
1036
1675
        $html = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instances );
1046
1685
                'loop'     => '',
1047
1686
                'autoplay' => '',
1048
1687
                'preload'  => 'metadata',
 
1688
                'width'    => 640,
1049
1689
                'height'   => 360,
1050
 
                'width'    => empty( $content_width ) ? 640 : $content_width,
1051
1690
        );
1052
1691
 
1053
1692
        foreach ( $default_types as $type )
1056
1695
        $atts = shortcode_atts( $defaults_atts, $attr, 'video' );
1057
1696
        extract( $atts );
1058
1697
 
1059
 
        $w = $width;
1060
 
        $h = $height;
1061
 
        if ( is_admin() && $width > 600 )
1062
 
                $w = 600;
1063
 
        elseif ( ! is_admin() && $w > $defaults_atts['width'] )
1064
 
                $w = $defaults_atts['width'];
1065
 
 
1066
 
        if ( $w < $width )
1067
 
                $height = round( ( $h * $w ) / $width );
1068
 
 
1069
 
        $width = $w;
 
1698
        if ( is_admin() ) {
 
1699
                // shrink the video so it isn't huge in the admin
 
1700
                if ( $width > $defaults_atts['width'] ) {
 
1701
                        $height = round( ( $height * $defaults_atts['width'] ) / $width );
 
1702
                        $width = $defaults_atts['width'];
 
1703
                }
 
1704
        } else {
 
1705
                // if the video is bigger than the theme
 
1706
                if ( ! empty( $content_width ) && $width > $content_width ) {
 
1707
                        $height = round( ( $height * $content_width ) / $width );
 
1708
                        $width = $content_width;
 
1709
                }
 
1710
        }
 
1711
 
 
1712
        $yt_pattern = '#^https?://(:?www\.)?(:?youtube\.com/watch|youtu\.be/)#';
1070
1713
 
1071
1714
        $primary = false;
1072
1715
        if ( ! empty( $src ) ) {
1073
 
                $type = wp_check_filetype( $src, wp_get_mime_types() );
1074
 
                if ( ! in_array( strtolower( $type['ext'] ), $default_types ) )
1075
 
                        return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $src ), esc_html( $src ) );
 
1716
                if ( ! preg_match( $yt_pattern, $src ) ) {
 
1717
                        $type = wp_check_filetype( $src, wp_get_mime_types() );
 
1718
                        if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) {
 
1719
                                return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $src ), esc_html( $src ) );
 
1720
                        }
 
1721
                }
1076
1722
                $primary = true;
1077
1723
                array_unshift( $default_types, 'src' );
1078
1724
        } else {
1098
1744
                array_unshift( $default_types, 'src' );
1099
1745
        }
1100
1746
 
 
1747
        /**
 
1748
         * Filter the media library used for the video shortcode.
 
1749
         *
 
1750
         * @since 3.6.0
 
1751
         *
 
1752
         * @param string $library Media library used for the video shortcode.
 
1753
         */
1101
1754
        $library = apply_filters( 'wp_video_shortcode_library', 'mediaelement' );
1102
1755
        if ( 'mediaelement' === $library && did_action( 'init' ) ) {
1103
1756
                wp_enqueue_style( 'wp-mediaelement' );
1104
1757
                wp_enqueue_script( 'wp-mediaelement' );
1105
1758
        }
1106
1759
 
 
1760
        /**
 
1761
         * Filter the class attribute for the video shortcode output container.
 
1762
         *
 
1763
         * @since 3.6.0
 
1764
         *
 
1765
         * @param string $class CSS class or list of space-separated classes.
 
1766
         */
1107
1767
        $atts = array(
1108
1768
                'class'    => apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ),
1109
1769
                'id'       => sprintf( 'video-%d-%d', $post_id, $instances ),
1137
1797
                if ( ! empty( $$fallback ) ) {
1138
1798
                        if ( empty( $fileurl ) )
1139
1799
                                $fileurl = $$fallback;
1140
 
                        $type = wp_check_filetype( $$fallback, wp_get_mime_types() );
1141
 
                        // m4v sometimes shows up as video/mpeg which collides with mp4
1142
 
                        if ( 'm4v' === $type['ext'] )
1143
 
                                $type['type'] = 'video/m4v';
1144
 
                        $html .= sprintf( $source, $type['type'], esc_url( $$fallback ) );
 
1800
 
 
1801
                        if ( 'src' === $fallback && preg_match( $yt_pattern, $src ) ) {
 
1802
                                $type = array( 'type' => 'video/youtube' );
 
1803
                        } else {
 
1804
                                $type = wp_check_filetype( $$fallback, wp_get_mime_types() );
 
1805
                        }
 
1806
                        $url = add_query_arg( '_', $instances, $$fallback );
 
1807
                        $html .= sprintf( $source, $type['type'], esc_url( $url ) );
1145
1808
                }
1146
1809
        }
 
1810
 
 
1811
        if ( ! empty( $content ) ) {
 
1812
                if ( false !== strpos( $content, "\n" ) )
 
1813
                        $content = str_replace( array( "\r\n", "\n", "\t" ), '', $content );
 
1814
 
 
1815
                $html .= trim( $content );
 
1816
        }
 
1817
 
1147
1818
        if ( 'mediaelement' === $library )
1148
1819
                $html .= wp_mediaelement_fallback( $fileurl );
1149
1820
        $html .= '</video>';
1150
1821
 
1151
1822
        $html = sprintf( '<div style="width: %dpx; max-width: 100%%;" class="wp-video">%s</div>', $width, $html );
 
1823
 
 
1824
        /**
 
1825
         * Filter the output of the video shortcode.
 
1826
         *
 
1827
         * @since 3.6.0
 
1828
         *
 
1829
         * @param string $html    Video shortcode HTML output.
 
1830
         * @param array  $atts    Array of video shortcode attributes.
 
1831
         * @param string $video   Video file.
 
1832
         * @param int    $post_id Post ID.
 
1833
         * @param string $library Media library used for the video shortcode.
 
1834
         */
1152
1835
        return apply_filters( 'wp_video_shortcode', $html, $atts, $video, $post_id, $library );
1153
1836
}
1154
1837
add_shortcode( 'video', 'wp_video_shortcode' );
1203
1886
        }
1204
1887
 
1205
1888
        $adjacent = $prev ? 'previous' : 'next';
 
1889
 
 
1890
        /**
 
1891
         * Filter the adjacent image link.
 
1892
         *
 
1893
         * The dynamic portion of the hook name, $adjacent, refers to the type of adjacency,
 
1894
         * either 'next', or 'previous'.
 
1895
         *
 
1896
         * @since 3.5.0
 
1897
         *
 
1898
         * @param string $output        Adjacent image HTML markup.
 
1899
         * @param int    $attachment_id Attachment ID
 
1900
         * @param string $size          Image size.
 
1901
         * @param string $text          Link text.
 
1902
         */
1206
1903
        echo apply_filters( "{$adjacent}_image_link", $output, $attachment_id, $size, $text );
1207
1904
}
1208
1905
 
1338
2035
 
1339
2036
        $height = min( ceil( $width * 1.5 ), 1000 );
1340
2037
 
 
2038
        /**
 
2039
         * Filter the default array of embed dimensions.
 
2040
         *
 
2041
         * @since 2.9.0
 
2042
         *
 
2043
         * @param int $width  Width of the embed in pixels.
 
2044
         * @param int $height Height of the embed in pixels.
 
2045
         */
1341
2046
        return apply_filters( 'embed_defaults', compact( 'width', 'height' ) );
1342
2047
}
1343
2048
 
1431
2136
 * @since 2.9.0
1432
2137
 */
1433
2138
function wp_maybe_load_embeds() {
1434
 
        if ( ! apply_filters( 'load_default_embeds', true ) )
 
2139
        /**
 
2140
         * Filter whether to load the default embed handlers.
 
2141
         *
 
2142
         * Returning a falsey value will prevent loading the default embed handlers.
 
2143
         *
 
2144
         * @since 2.9.0
 
2145
         *
 
2146
         * @param bool $maybe_load_embeds Whether to load the embeds library. Default true.
 
2147
         */
 
2148
        if ( ! apply_filters( 'load_default_embeds', true ) ) {
1435
2149
                return;
 
2150
        }
 
2151
 
1436
2152
        wp_embed_register_handler( 'googlevideo', '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i', 'wp_embed_handler_googlevideo' );
 
2153
 
 
2154
        /**
 
2155
         * Filter the audio embed handler callback.
 
2156
         *
 
2157
         * @since 3.6.0
 
2158
         *
 
2159
         * @param callback $handler Audio embed handler callback function.
 
2160
         */
1437
2161
        wp_embed_register_handler( 'audio', '#^https?://.+?\.(' . join( '|', wp_get_audio_extensions() ) . ')$#i', apply_filters( 'wp_audio_embed_handler', 'wp_embed_handler_audio' ), 9999 );
 
2162
 
 
2163
        /**
 
2164
         * Filter the video embed handler callback.
 
2165
         *
 
2166
         * @since 3.6.0
 
2167
         *
 
2168
         * @param callback $handler Video embed handler callback function.
 
2169
         */
1438
2170
        wp_embed_register_handler( 'video', '#^https?://.+?\.(' . join( '|', wp_get_video_extensions() ) . ')$#i', apply_filters( 'wp_video_embed_handler', 'wp_embed_handler_video' ), 9999 );
1439
2171
}
1440
2172
 
1459
2191
                list( $width, $height ) = wp_expand_dimensions( 425, 344, $attr['width'], $attr['height'] );
1460
2192
        }
1461
2193
 
 
2194
        /**
 
2195
         * Filter the Google Video embed output.
 
2196
         *
 
2197
         * @since 2.9.0
 
2198
         *
 
2199
         * @param string $html    Google Video HTML embed markup.
 
2200
         * @param array  $matches The regex matches from the provided regex.
 
2201
         * @param array  $attr    An array of embed attributes.
 
2202
         * @param string $url     The original URL that was matched by the regex.
 
2203
         * @param array  $rawattr The original unmodified attributes.
 
2204
         */
1462
2205
        return apply_filters( 'embed_googlevideo', '<embed type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docid=' . esc_attr($matches[2]) . '&amp;hl=en&amp;fs=true" style="width:' . esc_attr($width) . 'px;height:' . esc_attr($height) . 'px" allowFullScreen="true" allowScriptAccess="always" />', $matches, $attr, $url, $rawattr );
1463
2206
}
1464
2207
 
1475
2218
 */
1476
2219
function wp_embed_handler_audio( $matches, $attr, $url, $rawattr ) {
1477
2220
        $audio = sprintf( '[audio src="%s" /]', esc_url( $url ) );
 
2221
 
 
2222
        /**
 
2223
         * Filter the audio embed output.
 
2224
         *
 
2225
         * @since 3.6.0
 
2226
         *
 
2227
         * @param string $audio   Audio embed output.
 
2228
         * @param array  $attr    An array of embed attributes.
 
2229
         * @param string $url     The original URL that was matched by the regex.
 
2230
         * @param array  $rawattr The original unmodified attributes.
 
2231
         */
1478
2232
        return apply_filters( 'wp_embed_handler_audio', $audio, $attr, $url, $rawattr );
1479
2233
}
1480
2234
 
1496
2250
                $dimensions .= sprintf( 'height="%d" ', (int) $rawattr['height'] );
1497
2251
        }
1498
2252
        $video = sprintf( '[video %s src="%s" /]', $dimensions, esc_url( $url ) );
 
2253
 
 
2254
        /**
 
2255
         * Filter the video embed output.
 
2256
         *
 
2257
         * @since 3.6.0
 
2258
         *
 
2259
         * @param string $video   Video embed output.
 
2260
         * @param array  $attr    An array of embed attributes.
 
2261
         * @param string $url     The original URL that was matched by the regex.
 
2262
         * @param array  $rawattr The original unmodified attributes.
 
2263
         */
1499
2264
        return apply_filters( 'wp_embed_handler_video', $video, $attr, $url, $rawattr );
1500
2265
}
1501
2266
 
1529
2294
function wp_max_upload_size() {
1530
2295
        $u_bytes = wp_convert_hr_to_bytes( ini_get( 'upload_max_filesize' ) );
1531
2296
        $p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
1532
 
        $bytes   = apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes );
1533
 
        return $bytes;
 
2297
 
 
2298
        /**
 
2299
         * Filter the maximum upload size allowed in php.ini.
 
2300
         *
 
2301
         * @since 2.5.0
 
2302
         *
 
2303
         * @param int $size    Max upload size limit in bytes.
 
2304
         * @param int $u_bytes Maximum upload filesize in bytes.
 
2305
         * @param int $p_bytes Maximum size of POST data in bytes.
 
2306
         */
 
2307
        return apply_filters( 'upload_size_limit', min( $u_bytes, $p_bytes ), $u_bytes, $p_bytes );
1534
2308
}
1535
2309
 
1536
2310
/**
1597
2371
        require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
1598
2372
        require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
1599
2373
 
1600
 
        $implementations = apply_filters( 'wp_image_editors',
1601
 
                array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
 
2374
        /**
 
2375
         * Filter the list of image editing library classes.
 
2376
         *
 
2377
         * @since 3.5.0
 
2378
         *
 
2379
         * @param array $image_editors List of available image editors. Defaults are
 
2380
         *                             'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'.
 
2381
         */
 
2382
        $implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
1602
2383
 
1603
2384
        foreach ( $implementations as $implementation ) {
1604
2385
                if ( ! call_user_func( array( $implementation, 'test' ), $args ) )
1637
2418
        $max_upload_size = wp_max_upload_size();
1638
2419
 
1639
2420
        $defaults = array(
1640
 
                'runtimes'            => 'html5,silverlight,flash,html4',
 
2421
                'runtimes'            => 'html5,flash,silverlight,html4',
1641
2422
                'file_data_name'      => 'async-upload', // key passed to $_FILE.
1642
 
                'multiple_queues'     => true,
1643
 
                'max_file_size'       => $max_upload_size . 'b',
1644
2423
                'url'                 => admin_url( 'async-upload.php', 'relative' ),
1645
2424
                'flash_swf_url'       => includes_url( 'js/plupload/plupload.flash.swf' ),
1646
2425
                'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
1647
 
                'filters'             => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ),
1648
 
                'multipart'           => true,
1649
 
                'urlstream_upload'    => true,
 
2426
                'filters' => array(
 
2427
                        'max_file_size'   => $max_upload_size . 'b',
 
2428
                ),
1650
2429
        );
1651
2430
 
1652
2431
        // Multi-file uploading doesn't currently work in iOS Safari,
1654
2433
        if ( wp_is_mobile() )
1655
2434
                $defaults['multi_selection'] = false;
1656
2435
 
 
2436
        /**
 
2437
         * Filter the Plupload default settings.
 
2438
         *
 
2439
         * @since 3.4.0
 
2440
         *
 
2441
         * @param array $defaults Default Plupload settings array.
 
2442
         */
1657
2443
        $defaults = apply_filters( 'plupload_default_settings', $defaults );
1658
2444
 
1659
2445
        $params = array(
1660
2446
                'action' => 'upload-attachment',
1661
2447
        );
1662
2448
 
 
2449
        /**
 
2450
         * Filter the Plupload default parameters.
 
2451
         *
 
2452
         * @since 3.4.0
 
2453
         *
 
2454
         * @param array $params Default Plupload parameters array.
 
2455
         */
1663
2456
        $params = apply_filters( 'plupload_default_params', $params );
1664
2457
        $params['_wpnonce'] = wp_create_nonce( 'media-form' );
1665
2458
        $defaults['multipart_params'] = $params;
1730
2523
                'nonces'      => array(
1731
2524
                        'update' => false,
1732
2525
                        'delete' => false,
 
2526
                        'edit'   => false
1733
2527
                ),
1734
2528
                'editLink'   => false,
1735
2529
        );
1736
2530
 
1737
2531
        if ( current_user_can( 'edit_post', $attachment->ID ) ) {
1738
2532
                $response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
 
2533
                $response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID );
1739
2534
                $response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' );
1740
2535
        }
1741
2536
 
1744
2539
 
1745
2540
        if ( $meta && 'image' === $type ) {
1746
2541
                $sizes = array();
 
2542
 
1747
2543
                /** This filter is documented in wp-admin/includes/media.php */
1748
2544
                $possible_sizes = apply_filters( 'image_size_names_choose', array(
1749
2545
                        'thumbnail' => __('Thumbnail'),
1758
2554
                // If the filter does not return something, then image_downsize() is just an expensive
1759
2555
                // way to check the image metadata, which we do second.
1760
2556
                foreach ( $possible_sizes as $size => $label ) {
 
2557
 
 
2558
                        /** This filter is documented in wp-includes/media.php */
1761
2559
                        if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) {
1762
2560
                                if ( ! $downsize[3] )
1763
2561
                                        continue;
1806
2604
        if ( $meta && ( 'audio' === $type || 'video' === $type ) ) {
1807
2605
                if ( isset( $meta['length_formatted'] ) )
1808
2606
                        $response['fileLength'] = $meta['length_formatted'];
 
2607
 
 
2608
                $response['meta'] = array();
 
2609
                foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) {
 
2610
                        if ( ! empty( $meta[ $key ] ) ) {
 
2611
                                $response['meta'][ $key ] = $meta[ $key ];
 
2612
                        }
 
2613
                }
 
2614
 
 
2615
                $id = get_post_thumbnail_id( $attachment->ID );
 
2616
                if ( ! empty( $id ) ) {
 
2617
                        list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' );
 
2618
                        $response['image'] = compact( 'src', 'width', 'height' );
 
2619
                        list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' );
 
2620
                        $response['thumb'] = compact( 'src', 'width', 'height' );
 
2621
                } else {
 
2622
                        $src = wp_mime_type_icon( $attachment->ID );
 
2623
                        $width = 48;
 
2624
                        $height = 64;
 
2625
                        $response['image'] = compact( 'src', 'width', 'height' );
 
2626
                        $response['thumb'] = compact( 'src', 'width', 'height' );
 
2627
                }
1809
2628
        }
1810
2629
 
1811
2630
        if ( function_exists('get_compat_media_markup') )
1812
2631
                $response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) );
1813
2632
 
 
2633
        /**
 
2634
         * Filter the attachment data prepared for JavaScript.
 
2635
         *
 
2636
         * @since 3.5.0
 
2637
         *
 
2638
         * @param array      $response   Array of prepared attachment data.
 
2639
         * @param int|object $attachment Attachment ID or object.
 
2640
         * @param array      $meta       Array of attachment meta data.
 
2641
         */
1814
2642
        return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta );
1815
2643
}
1816
2644
 
1826
2654
        if ( did_action( 'wp_enqueue_media' ) )
1827
2655
                return;
1828
2656
 
 
2657
        global $content_width;
 
2658
 
1829
2659
        $defaults = array(
1830
2660
                'post' => null,
1831
2661
        );
1841
2671
                'library'  => '',
1842
2672
        );
1843
2673
 
 
2674
        /** This filter is documented in wp-admin/includes/media.php */
1844
2675
        $tabs = apply_filters( 'media_upload_tabs', $tabs );
1845
2676
        unset( $tabs['type'], $tabs['type_url'], $tabs['gallery'], $tabs['library'] );
1846
2677
 
1850
2681
                'size'  => get_option( 'image_default_size' ),  // empty default
1851
2682
        );
1852
2683
 
 
2684
        $exts = array_merge( wp_get_audio_extensions(), wp_get_video_extensions() );
 
2685
        $mimes = get_allowed_mime_types();
 
2686
        $ext_mimes = array();
 
2687
        foreach ( $exts as $ext ) {
 
2688
                foreach ( $mimes as $ext_preg => $mime_match ) {
 
2689
                        if ( preg_match( '#' . $ext . '#i', $ext_preg ) ) {
 
2690
                                $ext_mimes[ $ext ] = $mime_match;
 
2691
                                break;
 
2692
                        }
 
2693
                }
 
2694
        }
 
2695
 
 
2696
        $audio = $video = 0;
 
2697
        $counts = (array) wp_count_attachments();
 
2698
        foreach ( $counts as $mime => $total ) {
 
2699
                if ( 0 === strpos( $mime, 'audio/' ) ) {
 
2700
                        $audio += (int) $total;
 
2701
                } elseif ( 0 === strpos( $mime, 'video/' ) ) {
 
2702
                        $video += (int) $total;
 
2703
                }
 
2704
        }
 
2705
 
1853
2706
        $settings = array(
1854
2707
                'tabs'      => $tabs,
1855
2708
                'tabUrl'    => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ),
1856
2709
                'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ),
 
2710
                /** This filter is documented in wp-admin/includes/media.php */
1857
2711
                'captions'  => ! apply_filters( 'disable_captions', '' ),
1858
2712
                'nonce'     => array(
1859
2713
                        'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
1862
2716
                        'id' => 0,
1863
2717
                ),
1864
2718
                'defaultProps' => $props,
1865
 
                'embedExts'    => array_merge( wp_get_audio_extensions(), wp_get_video_extensions() ),
 
2719
                'attachmentCounts' => array(
 
2720
                        'audio' => $audio,
 
2721
                        'video' => $video
 
2722
                ),
 
2723
                'embedExts'    => $exts,
 
2724
                'embedMimes'   => $ext_mimes,
 
2725
                'contentWidth' => $content_width,
1866
2726
        );
1867
2727
 
1868
2728
        $post = null;
1873
2733
                        'nonce' => wp_create_nonce( 'update-post_' . $post->ID ),
1874
2734
                );
1875
2735
 
1876
 
                if ( current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' ) ) {
 
2736
                $thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' );
 
2737
                if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) {
 
2738
                        if ( 0 === strpos( $post->post_mime_type, 'audio/' ) ) {
 
2739
                                $thumbnail_support = post_type_supports( 'attachment:audio', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:audio' );
 
2740
                        } elseif ( 0 === strpos( $post->post_mime_type, 'video/' ) ) {
 
2741
                                $thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
 
2742
                        }
 
2743
                }
 
2744
 
 
2745
                if ( $thumbnail_support ) {
1877
2746
                        $featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true );
1878
2747
                        $settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1;
1879
2748
                }
1888
2757
                'search'      => __( 'Search' ),
1889
2758
                'select'      => __( 'Select' ),
1890
2759
                'cancel'      => __( 'Cancel' ),
 
2760
                'update'      => __( 'Update' ),
 
2761
                'replace'     => __( 'Replace' ),
 
2762
                'remove'      => __( 'Remove' ),
 
2763
                'back'        => __( 'Back' ),
1891
2764
                /* translators: This is a would-be plural string used in the media manager.
1892
2765
                   If there is not a word you can use in your language to avoid issues with the
1893
2766
                   lack of plural support here, turn it into "selected: %d" then translate it.
1903
2776
                'mediaLibraryTitle'  => __( 'Media Library' ),
1904
2777
                'insertMediaTitle'   => __( 'Insert Media' ),
1905
2778
                'createNewGallery'   => __( 'Create a new gallery' ),
 
2779
                'createNewPlaylist'   => __( 'Create a new playlist' ),
 
2780
                'createNewVideoPlaylist'   => __( 'Create a new video playlist' ),
1906
2781
                'returnToLibrary'    => __( '&#8592; Return to library' ),
1907
2782
                'allMediaItems'      => __( 'All media items' ),
1908
2783
                'noItemsFound'       => __( 'No items found.' ),
1926
2801
                'addToGallery'       => __( 'Add to gallery' ),
1927
2802
                'addToGalleryTitle'  => __( 'Add to Gallery' ),
1928
2803
                'reverseOrder'       => __( 'Reverse order' ),
 
2804
 
 
2805
                // Edit Image
 
2806
                'imageDetailsTitle'     => __( 'Image Details' ),
 
2807
                'imageReplaceTitle'     => __( 'Replace Image' ),
 
2808
                'imageDetailsCancel'    => __( 'Cancel Edit' ),
 
2809
                'editImage'             => __( 'Edit Image' ),
 
2810
 
 
2811
                // Crop Image
 
2812
                'chooseImage' => __( 'Choose Image' ),
 
2813
                'selectAndCrop' => __( 'Select and Crop' ),
 
2814
                'skipCropping' => __( 'Skip Cropping' ),
 
2815
                'cropImage' => __( 'Crop Image' ),
 
2816
                'cropYourImage' => __( 'Crop your image' ),
 
2817
                'cropping' => __( 'Cropping&hellip;' ),
 
2818
                'suggestedDimensions' => __( 'Suggested image dimensions:' ),
 
2819
                'cropError' => __( 'There has been an error cropping your image.' ),
 
2820
 
 
2821
                // Edit Audio
 
2822
                'audioDetailsTitle'     => __( 'Audio Details' ),
 
2823
                'audioReplaceTitle'     => __( 'Replace Audio' ),
 
2824
                'audioAddSourceTitle'   => __( 'Add Audio Source' ),
 
2825
                'audioDetailsCancel'    => __( 'Cancel Edit' ),
 
2826
 
 
2827
                // Edit Video
 
2828
                'videoDetailsTitle'     => __( 'Video Details' ),
 
2829
                'videoReplaceTitle'     => __( 'Replace Video' ),
 
2830
                'videoAddSourceTitle'   => __( 'Add Video Source' ),
 
2831
                'videoDetailsCancel'    => __( 'Cancel Edit' ),
 
2832
                'videoSelectPosterImageTitle' => _( 'Select Poster Image' ),
 
2833
                'videoAddTrackTitle'    => __( 'Add Subtitles' ),
 
2834
 
 
2835
                // Playlist
 
2836
                'playlistDragInfo'    => __( 'Drag and drop to reorder tracks.' ),
 
2837
                'createPlaylistTitle' => __( 'Create Audio Playlist' ),
 
2838
                'editPlaylistTitle'   => __( 'Edit Audio Playlist' ),
 
2839
                'cancelPlaylistTitle' => __( '&#8592; Cancel Audio Playlist' ),
 
2840
                'insertPlaylist'      => __( 'Insert audio playlist' ),
 
2841
                'updatePlaylist'      => __( 'Update audio playlist' ),
 
2842
                'addToPlaylist'       => __( 'Add to audio playlist' ),
 
2843
                'addToPlaylistTitle'  => __( 'Add to Audio Playlist' ),
 
2844
 
 
2845
                // Video Playlist
 
2846
                'videoPlaylistDragInfo'    => __( 'Drag and drop to reorder videos.' ),
 
2847
                'createVideoPlaylistTitle' => __( 'Create Video Playlist' ),
 
2848
                'editVideoPlaylistTitle'   => __( 'Edit Video Playlist' ),
 
2849
                'cancelVideoPlaylistTitle' => __( '&#8592; Cancel Video Playlist' ),
 
2850
                'insertVideoPlaylist'      => __( 'Insert video playlist' ),
 
2851
                'updateVideoPlaylist'      => __( 'Update video playlist' ),
 
2852
                'addToVideoPlaylist'       => __( 'Add to video playlist' ),
 
2853
                'addToVideoPlaylistTitle'  => __( 'Add to Video Playlist' ),
1929
2854
        );
1930
2855
 
 
2856
        /**
 
2857
         * Filter the media view settings.
 
2858
         *
 
2859
         * @since 3.5.0
 
2860
         *
 
2861
         * @param array   $settings List of media view settings.
 
2862
         * @param WP_Post $post     Post object.
 
2863
         */
1931
2864
        $settings = apply_filters( 'media_view_settings', $settings, $post );
1932
 
        $strings  = apply_filters( 'media_view_strings',  $strings,  $post );
 
2865
 
 
2866
        /**
 
2867
         * Filter the media view strings.
 
2868
         *
 
2869
         * @since 3.5.0
 
2870
         *
 
2871
         * @param array   $strings List of media view strings.
 
2872
         * @param WP_Post $post    Post object.
 
2873
         */
 
2874
        $strings = apply_filters( 'media_view_strings', $strings,  $post );
1933
2875
 
1934
2876
        $strings['settings'] = $settings;
1935
2877
 
1936
2878
        wp_localize_script( 'media-views', '_wpMediaViewsL10n', $strings );
1937
2879
 
1938
2880
        wp_enqueue_script( 'media-editor' );
 
2881
        wp_enqueue_script( 'media-audiovideo' );
1939
2882
        wp_enqueue_style( 'media-views' );
 
2883
        if ( is_admin() ) {
 
2884
                wp_enqueue_script( 'mce-view' );
 
2885
                wp_enqueue_script( 'image-edit' );
 
2886
        }
 
2887
        wp_enqueue_style( 'imgareaselect' );
1940
2888
        wp_plupload_default_settings();
1941
2889
 
1942
2890
        require_once ABSPATH . WPINC . '/media-template.php';
1944
2892
        add_action( 'wp_footer', 'wp_print_media_templates' );
1945
2893
        add_action( 'customize_controls_print_footer_scripts', 'wp_print_media_templates' );
1946
2894
 
 
2895
        /**
 
2896
         * Fires at the conclusion of wp_enqueue_media().
 
2897
         *
 
2898
         * @since 3.5.0
 
2899
         */
1947
2900
        do_action( 'wp_enqueue_media' );
1948
2901
}
1949
2902
 
1950
2903
/**
1951
 
 * Retrieve media attached to the passed post
 
2904
 * Retrieve media attached to the passed post.
1952
2905
 *
1953
2906
 * @since 3.6.0
1954
2907
 *
1969
2922
                'order' => 'ASC',
1970
2923
        );
1971
2924
 
 
2925
        /**
 
2926
         * Filter arguments used to retrieve media attached to the given post.
 
2927
         *
 
2928
         * @since 3.6.0
 
2929
         *
 
2930
         * @param array  $args Post query arguments.
 
2931
         * @param string $type Mime type of the desired media.
 
2932
         * @param mixed  $post Post ID or object.
 
2933
         */
1972
2934
        $args = apply_filters( 'get_attached_media_args', $args, $type, $post );
1973
2935
 
1974
2936
        $children = get_children( $args );
1975
2937
 
 
2938
        /**
 
2939
         * Filter the
 
2940
         *
 
2941
         * @since 3.6.0
 
2942
         *
 
2943
         * @param array  $children Associative array of media attached to the given post.
 
2944
         * @param string $type     Mime type of the media desired.
 
2945
         * @param mixed  $post     Post ID or object.
 
2946
         */
1976
2947
        return (array) apply_filters( 'get_attached_media', $children, $type, $post );
1977
2948
}
1978
2949
 
2004
2975
}
2005
2976
 
2006
2977
/**
2007
 
 * Retrieve galleries from the passed post's content
 
2978
 * Retrieve galleries from the passed post's content.
2008
2979
 *
2009
2980
 * @since 3.6.0
2010
2981
 *
2011
 
 * @param mixed $post Optional. Post ID or object.
2012
 
 * @param boolean $html Whether to return HTML or data in the array
 
2982
 * @param int|WP_Post $post Optional. Post ID or object.
 
2983
 * @param bool        $html Whether to return HTML or data in the array.
2013
2984
 * @return array A list of arrays, each containing gallery data and srcs parsed
2014
 
 *              from the expanded shortcode
 
2985
 *                       from the expanded shortcode.
2015
2986
 */
2016
2987
function get_post_galleries( $post, $html = true ) {
2017
2988
        if ( ! $post = get_post( $post ) )
2045
3016
                }
2046
3017
        }
2047
3018
 
 
3019
        /**
 
3020
         * Filter the list of all found galleries in the given post.
 
3021
         *
 
3022
         * @since 3.6.0
 
3023
         *
 
3024
         * @param array   $galleries Associative array of all found post galleries.
 
3025
         * @param WP_Post $post      Post object.
 
3026
         */
2048
3027
        return apply_filters( 'get_post_galleries', $galleries, $post );
2049
3028
}
2050
3029
 
2053
3032
 *
2054
3033
 * @since 3.6.0
2055
3034
 *
2056
 
 * @param mixed $post Optional. Post ID or object.
2057
 
 * @param boolean $html Whether to return HTML or data
2058
 
 * @return string|array Gallery data and srcs parsed from the expanded shortcode
 
3035
 * @param int|WP_Post $post Optional. Post ID or object.
 
3036
 * @param bool        $html Whether to return HTML or data.
 
3037
 * @return string|array Gallery data and srcs parsed from the expanded shortcode.
2059
3038
 */
2060
3039
function get_post_gallery( $post = 0, $html = true ) {
2061
3040
        $galleries = get_post_galleries( $post, $html );
2062
3041
        $gallery = reset( $galleries );
2063
3042
 
 
3043
        /**
 
3044
         * Filter the first-found post gallery.
 
3045
         *
 
3046
         * @since 3.6.0
 
3047
         *
 
3048
         * @param array       $gallery   The first-found post gallery.
 
3049
         * @param int|WP_Post $post      Post ID or object.
 
3050
         * @param array       $galleries Associative array of all found post galleries.
 
3051
         */
2064
3052
        return apply_filters( 'get_post_gallery', $gallery, $post, $galleries );
2065
3053
}
2066
3054
 
2090
3078
        $gallery = get_post_gallery( $post, false );
2091
3079
        return empty( $gallery['src'] ) ? array() : $gallery['src'];
2092
3080
}
 
3081
 
 
3082
/**
 
3083
 * Maybe attempt to generate attachment metadata, if missing.
 
3084
 *
 
3085
 * @since 3.9.0
 
3086
 *
 
3087
 * @param WP_Post $attachment Attachment object.
 
3088
 */
 
3089
function wp_maybe_generate_attachment_metadata( $attachment ) {
 
3090
        if ( empty( $attachment ) || ( empty( $attachment->ID ) || ! $attachment_id = (int) $attachment->ID ) ) {
 
3091
                return;
 
3092
        }
 
3093
 
 
3094
        $file = get_attached_file( $attachment_id );
 
3095
        $meta = wp_get_attachment_metadata( $attachment_id );
 
3096
        if ( empty( $meta ) && file_exists( $file ) ) {
 
3097
                $_meta = get_post_meta( $attachment_id );
 
3098
                $regeneration_lock = 'wp_generating_att_' . $attachment_id;
 
3099
                if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $regeneration_lock ) ) {
 
3100
                        set_transient( $regeneration_lock, $file );
 
3101
                        wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
 
3102
                        delete_transient( $regeneration_lock );
 
3103
                }
 
3104
        }
 
3105
}