wp/wp-includes/media.php
changeset 9 177826044cd9
parent 7 cf61fcea0001
child 16 a86126ab1dd4
equal deleted inserted replaced
8:c7c34916027a 9:177826044cd9
    57 function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) {
    57 function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) {
    58 	global $content_width;
    58 	global $content_width;
    59 
    59 
    60 	$_wp_additional_image_sizes = wp_get_additional_image_sizes();
    60 	$_wp_additional_image_sizes = wp_get_additional_image_sizes();
    61 
    61 
    62 	if ( ! $context )
    62 	if ( ! $context ) {
    63 		$context = is_admin() ? 'edit' : 'display';
    63 		$context = is_admin() ? 'edit' : 'display';
    64 
    64 	}
    65 	if ( is_array($size) ) {
    65 
    66 		$max_width = $size[0];
    66 	if ( is_array( $size ) ) {
       
    67 		$max_width  = $size[0];
    67 		$max_height = $size[1];
    68 		$max_height = $size[1];
    68 	}
    69 	} elseif ( $size == 'thumb' || $size == 'thumbnail' ) {
    69 	elseif ( $size == 'thumb' || $size == 'thumbnail' ) {
    70 		$max_width  = intval( get_option( 'thumbnail_size_w' ) );
    70 		$max_width = intval(get_option('thumbnail_size_w'));
    71 		$max_height = intval( get_option( 'thumbnail_size_h' ) );
    71 		$max_height = intval(get_option('thumbnail_size_h'));
       
    72 		// last chance thumbnail size defaults
    72 		// last chance thumbnail size defaults
    73 		if ( !$max_width && !$max_height ) {
    73 		if ( ! $max_width && ! $max_height ) {
    74 			$max_width = 128;
    74 			$max_width  = 128;
    75 			$max_height = 96;
    75 			$max_height = 96;
    76 		}
    76 		}
    77 	}
    77 	} elseif ( $size == 'medium' ) {
    78 	elseif ( $size == 'medium' ) {
    78 		$max_width  = intval( get_option( 'medium_size_w' ) );
    79 		$max_width = intval(get_option('medium_size_w'));
    79 		$max_height = intval( get_option( 'medium_size_h' ) );
    80 		$max_height = intval(get_option('medium_size_h'));
    80 
    81 
    81 	} elseif ( $size == 'medium_large' ) {
    82 	}
    82 		$max_width  = intval( get_option( 'medium_large_size_w' ) );
    83 	elseif ( $size == 'medium_large' ) {
       
    84 		$max_width = intval( get_option( 'medium_large_size_w' ) );
       
    85 		$max_height = intval( get_option( 'medium_large_size_h' ) );
    83 		$max_height = intval( get_option( 'medium_large_size_h' ) );
    86 
    84 
    87 		if ( intval( $content_width ) > 0 ) {
    85 		if ( intval( $content_width ) > 0 ) {
    88 			$max_width = min( intval( $content_width ), $max_width );
    86 			$max_width = min( intval( $content_width ), $max_width );
    89 		}
    87 		}
    90 	}
    88 	} elseif ( $size == 'large' ) {
    91 	elseif ( $size == 'large' ) {
       
    92 		/*
    89 		/*
    93 		 * We're inserting a large size image into the editor. If it's a really
    90 		 * We're inserting a large size image into the editor. If it's a really
    94 		 * big image we'll scale it down to fit reasonably within the editor
    91 		 * big image we'll scale it down to fit reasonably within the editor
    95 		 * itself, and within the theme's content width if it's known. The user
    92 		 * itself, and within the theme's content width if it's known. The user
    96 		 * can resize it in the editor if they wish.
    93 		 * can resize it in the editor if they wish.
    97 		 */
    94 		 */
    98 		$max_width = intval(get_option('large_size_w'));
    95 		$max_width  = intval( get_option( 'large_size_w' ) );
    99 		$max_height = intval(get_option('large_size_h'));
    96 		$max_height = intval( get_option( 'large_size_h' ) );
   100 		if ( intval($content_width) > 0 ) {
    97 		if ( intval( $content_width ) > 0 ) {
   101 			$max_width = min( intval($content_width), $max_width );
    98 			$max_width = min( intval( $content_width ), $max_width );
   102 		}
    99 		}
   103 	} elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
   100 	} elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
   104 		$max_width = intval( $_wp_additional_image_sizes[$size]['width'] );
   101 		$max_width  = intval( $_wp_additional_image_sizes[ $size ]['width'] );
   105 		$max_height = intval( $_wp_additional_image_sizes[$size]['height'] );
   102 		$max_height = intval( $_wp_additional_image_sizes[ $size ]['height'] );
   106 		// Only in admin. Assume that theme authors know what they're doing.
   103 		// Only in admin. Assume that theme authors know what they're doing.
   107 		if ( intval( $content_width ) > 0 && 'edit' === $context ) {
   104 		if ( intval( $content_width ) > 0 && 'edit' === $context ) {
   108 			$max_width = min( intval( $content_width ), $max_width );
   105 			$max_width = min( intval( $content_width ), $max_width );
   109 		}
   106 		}
   110 	}
   107 	} else { // $size == 'full' has no constraint
   111 	// $size == 'full' has no constraint
   108 		$max_width  = $width;
   112 	else {
       
   113 		$max_width = $width;
       
   114 		$max_height = $height;
   109 		$max_height = $height;
   115 	}
   110 	}
   116 
   111 
   117 	/**
   112 	/**
   118 	 * Filters the maximum image size dimensions for the editor.
   113 	 * Filters the maximum image size dimensions for the editor.
   148  * @param int|string $height Image height in pixels.
   143  * @param int|string $height Image height in pixels.
   149  * @return string HTML attributes for width and, or height.
   144  * @return string HTML attributes for width and, or height.
   150  */
   145  */
   151 function image_hwstring( $width, $height ) {
   146 function image_hwstring( $width, $height ) {
   152 	$out = '';
   147 	$out = '';
   153 	if ($width)
   148 	if ( $width ) {
   154 		$out .= 'width="'.intval($width).'" ';
   149 		$out .= 'width="' . intval( $width ) . '" ';
   155 	if ($height)
   150 	}
   156 		$out .= 'height="'.intval($height).'" ';
   151 	if ( $height ) {
       
   152 		$out .= 'height="' . intval( $height ) . '" ';
       
   153 	}
   157 	return $out;
   154 	return $out;
   158 }
   155 }
   159 
   156 
   160 /**
   157 /**
   161  * Scale an image to fit a particular size (such as 'thumb' or 'medium').
   158  * Scale an image to fit a particular size (such as 'thumb' or 'medium').
   200 	 */
   197 	 */
   201 	if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
   198 	if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) {
   202 		return $out;
   199 		return $out;
   203 	}
   200 	}
   204 
   201 
   205 	$img_url = wp_get_attachment_url($id);
   202 	$img_url          = wp_get_attachment_url( $id );
   206 	$meta = wp_get_attachment_metadata($id);
   203 	$meta             = wp_get_attachment_metadata( $id );
   207 	$width = $height = 0;
   204 	$width            = $height = 0;
   208 	$is_intermediate = false;
   205 	$is_intermediate  = false;
   209 	$img_url_basename = wp_basename($img_url);
   206 	$img_url_basename = wp_basename( $img_url );
   210 
   207 
   211 	// If the file isn't an image, attempt to replace its URL with a rendered image from its meta.
   208 	// If the file isn't an image, attempt to replace its URL with a rendered image from its meta.
   212 	// Otherwise, a non-image type could be returned.
   209 	// Otherwise, a non-image type could be returned.
   213 	if ( ! $is_image ) {
   210 	if ( ! $is_image ) {
   214 		if ( ! empty( $meta['sizes'] ) ) {
   211 		if ( ! empty( $meta['sizes'] ) ) {
   215 			$img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
   212 			$img_url          = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
   216 			$img_url_basename = $meta['sizes']['full']['file'];
   213 			$img_url_basename = $meta['sizes']['full']['file'];
   217 			$width = $meta['sizes']['full']['width'];
   214 			$width            = $meta['sizes']['full']['width'];
   218 			$height = $meta['sizes']['full']['height'];
   215 			$height           = $meta['sizes']['full']['height'];
   219 		} else {
   216 		} else {
   220 			return false;
   217 			return false;
   221 		}
   218 		}
   222 	}
   219 	}
   223 
   220 
   224 	// try for a new style intermediate size
   221 	// try for a new style intermediate size
   225 	if ( $intermediate = image_get_intermediate_size($id, $size) ) {
   222 	if ( $intermediate = image_get_intermediate_size( $id, $size ) ) {
   226 		$img_url = str_replace($img_url_basename, $intermediate['file'], $img_url);
   223 		$img_url         = str_replace( $img_url_basename, $intermediate['file'], $img_url );
   227 		$width = $intermediate['width'];
   224 		$width           = $intermediate['width'];
   228 		$height = $intermediate['height'];
   225 		$height          = $intermediate['height'];
   229 		$is_intermediate = true;
   226 		$is_intermediate = true;
   230 	}
   227 	} elseif ( $size == 'thumbnail' ) {
   231 	elseif ( $size == 'thumbnail' ) {
       
   232 		// fall back to the old thumbnail
   228 		// fall back to the old thumbnail
   233 		if ( ($thumb_file = wp_get_attachment_thumb_file($id)) && $info = getimagesize($thumb_file) ) {
   229 		if ( ( $thumb_file = wp_get_attachment_thumb_file( $id ) ) && $info = getimagesize( $thumb_file ) ) {
   234 			$img_url = str_replace($img_url_basename, wp_basename($thumb_file), $img_url);
   230 			$img_url         = str_replace( $img_url_basename, wp_basename( $thumb_file ), $img_url );
   235 			$width = $info[0];
   231 			$width           = $info[0];
   236 			$height = $info[1];
   232 			$height          = $info[1];
   237 			$is_intermediate = true;
   233 			$is_intermediate = true;
   238 		}
   234 		}
   239 	}
   235 	}
   240 	if ( !$width && !$height && isset( $meta['width'], $meta['height'] ) ) {
   236 	if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) {
   241 		// any other type: use the real image
   237 		// any other type: use the real image
   242 		$width = $meta['width'];
   238 		$width  = $meta['width'];
   243 		$height = $meta['height'];
   239 		$height = $meta['height'];
   244 	}
   240 	}
   245 
   241 
   246 	if ( $img_url) {
   242 	if ( $img_url ) {
   247 		// we have the actual image size, but might need to further constrain it if content_width is narrower
   243 		// we have the actual image size, but might need to further constrain it if content_width is narrower
   248 		list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
   244 		list( $width, $height ) = image_constrain_size_for_editor( $width, $height, $size );
   249 
   245 
   250 		return array( $img_url, $width, $height, $is_intermediate );
   246 		return array( $img_url, $width, $height, $is_intermediate );
   251 	}
   247 	}
   267  * @since 2.9.0
   263  * @since 2.9.0
   268  *
   264  *
   269  * @global array $_wp_additional_image_sizes Associative array of additional image sizes.
   265  * @global array $_wp_additional_image_sizes Associative array of additional image sizes.
   270  *
   266  *
   271  * @param string     $name   Image size identifier.
   267  * @param string     $name   Image size identifier.
   272  * @param int        $width  Image width in pixels.
   268  * @param int        $width  Optional. Image width in pixels. Default 0.
   273  * @param int        $height Image height in pixels.
   269  * @param int        $height Optional. Image height in pixels. Default 0.
   274  * @param bool|array $crop   Optional. Whether to crop images to specified width and height or resize.
   270  * @param bool|array $crop   Optional. Whether to crop images to specified width and height or resize.
   275  *                           An array can specify positioning of the crop area. Default false.
   271  *                           An array can specify positioning of the crop area. Default false.
   276  */
   272  */
   277 function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
   273 function add_image_size( $name, $width = 0, $height = 0, $crop = false ) {
   278 	global $_wp_additional_image_sizes;
   274 	global $_wp_additional_image_sizes;
   357  *                            (in that order). Default 'medium'.
   353  *                            (in that order). Default 'medium'.
   358  * @return string HTML IMG element for given image attachment
   354  * @return string HTML IMG element for given image attachment
   359  */
   355  */
   360 function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) {
   356 function get_image_tag( $id, $alt, $title, $align, $size = 'medium' ) {
   361 
   357 
   362 	list( $img_src, $width, $height ) = image_downsize($id, $size);
   358 	list( $img_src, $width, $height ) = image_downsize( $id, $size );
   363 	$hwstring = image_hwstring($width, $height);
   359 	$hwstring                         = image_hwstring( $width, $height );
   364 
   360 
   365 	$title = $title ? 'title="' . esc_attr( $title ) . '" ' : '';
   361 	$title = $title ? 'title="' . esc_attr( $title ) . '" ' : '';
   366 
   362 
   367 	$class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id;
   363 	$class = 'align' . esc_attr( $align ) . ' size-' . esc_attr( $size ) . ' wp-image-' . $id;
   368 
   364 
   369 	/**
   365 	/**
   370 	 * Filters the value of the attachment's image tag class attribute.
   366 	 * Filters the value of the attachment's image tag class attribute.
   371 	 *
   367 	 *
   372 	 * @since 2.6.0
   368 	 * @since 2.6.0
   377 	 * @param string|array $size  Size of image. Image size or array of width and height values (in that order).
   373 	 * @param string|array $size  Size of image. Image size or array of width and height values (in that order).
   378 	 *                            Default 'medium'.
   374 	 *                            Default 'medium'.
   379 	 */
   375 	 */
   380 	$class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
   376 	$class = apply_filters( 'get_image_tag_class', $class, $id, $align, $size );
   381 
   377 
   382 	$html = '<img src="' . esc_attr($img_src) . '" alt="' . esc_attr($alt) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
   378 	$html = '<img src="' . esc_attr( $img_src ) . '" alt="' . esc_attr( $alt ) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
   383 
   379 
   384 	/**
   380 	/**
   385 	 * Filters the HTML content for the image tag.
   381 	 * Filters the HTML content for the image tag.
   386 	 *
   382 	 *
   387 	 * @since 2.6.0
   383 	 * @since 2.6.0
   410  * @param int $max_width      Optional. Max width in pixels to constrain to. Default 0.
   406  * @param int $max_width      Optional. Max width in pixels to constrain to. Default 0.
   411  * @param int $max_height     Optional. Max height in pixels to constrain to. Default 0.
   407  * @param int $max_height     Optional. Max height in pixels to constrain to. Default 0.
   412  * @return array First item is the width, the second item is the height.
   408  * @return array First item is the width, the second item is the height.
   413  */
   409  */
   414 function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) {
   410 function wp_constrain_dimensions( $current_width, $current_height, $max_width = 0, $max_height = 0 ) {
   415 	if ( !$max_width && !$max_height )
   411 	if ( ! $max_width && ! $max_height ) {
   416 		return array( $current_width, $current_height );
   412 		return array( $current_width, $current_height );
       
   413 	}
   417 
   414 
   418 	$width_ratio = $height_ratio = 1.0;
   415 	$width_ratio = $height_ratio = 1.0;
   419 	$did_width = $did_height = false;
   416 	$did_width   = $did_height = false;
   420 
   417 
   421 	if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
   418 	if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
   422 		$width_ratio = $max_width / $current_width;
   419 		$width_ratio = $max_width / $current_width;
   423 		$did_width = true;
   420 		$did_width   = true;
   424 	}
   421 	}
   425 
   422 
   426 	if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
   423 	if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
   427 		$height_ratio = $max_height / $current_height;
   424 		$height_ratio = $max_height / $current_height;
   428 		$did_height = true;
   425 		$did_height   = true;
   429 	}
   426 	}
   430 
   427 
   431 	// Calculate the larger/smaller ratios
   428 	// Calculate the larger/smaller ratios
   432 	$smaller_ratio = min( $width_ratio, $height_ratio );
   429 	$smaller_ratio = min( $width_ratio, $height_ratio );
   433 	$larger_ratio  = max( $width_ratio, $height_ratio );
   430 	$larger_ratio  = max( $width_ratio, $height_ratio );
   434 
   431 
   435 	if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) {
   432 	if ( (int) round( $current_width * $larger_ratio ) > $max_width || (int) round( $current_height * $larger_ratio ) > $max_height ) {
   436  		// The larger ratio is too big. It would result in an overflow.
   433 		// The larger ratio is too big. It would result in an overflow.
   437 		$ratio = $smaller_ratio;
   434 		$ratio = $smaller_ratio;
   438 	} else {
   435 	} else {
   439 		// The larger ratio fits, and is likely to be a more "snug" fit.
   436 		// The larger ratio fits, and is likely to be a more "snug" fit.
   440 		$ratio = $larger_ratio;
   437 		$ratio = $larger_ratio;
   441 	}
   438 	}
   442 
   439 
   443 	// Very small dimensions may result in 0, 1 should be the minimum.
   440 	// Very small dimensions may result in 0, 1 should be the minimum.
   444 	$w = max ( 1, (int) round( $current_width  * $ratio ) );
   441 	$w = max( 1, (int) round( $current_width * $ratio ) );
   445 	$h = max ( 1, (int) round( $current_height * $ratio ) );
   442 	$h = max( 1, (int) round( $current_height * $ratio ) );
   446 
   443 
   447 	// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
   444 	// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
   448 	// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
   445 	// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
   449 	// Thus we look for dimensions that are one pixel shy of the max value and bump them up
   446 	// Thus we look for dimensions that are one pixel shy of the max value and bump them up
   450 
   447 
   462 	 * Filters dimensions to constrain down-sampled images to.
   459 	 * Filters dimensions to constrain down-sampled images to.
   463 	 *
   460 	 *
   464 	 * @since 4.1.0
   461 	 * @since 4.1.0
   465 	 *
   462 	 *
   466 	 * @param array $dimensions     The image width and height.
   463 	 * @param array $dimensions     The image width and height.
   467 	 * @param int 	$current_width  The current width of the image.
   464 	 * @param int   $current_width  The current width of the image.
   468 	 * @param int 	$current_height The current height of the image.
   465 	 * @param int   $current_height The current height of the image.
   469 	 * @param int 	$max_width      The maximum width permitted.
   466 	 * @param int   $max_width      The maximum width permitted.
   470 	 * @param int 	$max_height     The maximum height permitted.
   467 	 * @param int   $max_height     The maximum height permitted.
   471 	 */
   468 	 */
   472 	return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height );
   469 	return apply_filters( 'wp_constrain_dimensions', array( $w, $h ), $current_width, $current_height, $max_width, $max_height );
   473 }
   470 }
   474 
   471 
   475 /**
   472 /**
   496  *                           An array can specify positioning of the crop area. Default false.
   493  *                           An array can specify positioning of the crop area. Default false.
   497  * @return false|array False on failure. Returned array matches parameters for `imagecopyresampled()`.
   494  * @return false|array False on failure. Returned array matches parameters for `imagecopyresampled()`.
   498  */
   495  */
   499 function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {
   496 function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = false ) {
   500 
   497 
   501 	if ($orig_w <= 0 || $orig_h <= 0)
   498 	if ( $orig_w <= 0 || $orig_h <= 0 ) {
   502 		return false;
   499 		return false;
       
   500 	}
   503 	// at least one of dest_w or dest_h must be specific
   501 	// at least one of dest_w or dest_h must be specific
   504 	if ($dest_w <= 0 && $dest_h <= 0)
   502 	if ( $dest_w <= 0 && $dest_h <= 0 ) {
   505 		return false;
   503 		return false;
       
   504 	}
   506 
   505 
   507 	/**
   506 	/**
   508 	 * Filters whether to preempt calculating the image resize dimensions.
   507 	 * Filters whether to preempt calculating the image resize dimensions.
   509 	 *
   508 	 *
   510 	 * Passing a non-null value to the filter will effectively short-circuit
   509 	 * Passing a non-null value to the filter will effectively short-circuit
   519 	 * @param int        $dest_h New height in pixels.
   518 	 * @param int        $dest_h New height in pixels.
   520 	 * @param bool|array $crop   Whether to crop image to specified width and height or resize.
   519 	 * @param bool|array $crop   Whether to crop image to specified width and height or resize.
   521 	 *                           An array can specify positioning of the crop area. Default false.
   520 	 *                           An array can specify positioning of the crop area. Default false.
   522 	 */
   521 	 */
   523 	$output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );
   522 	$output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop );
   524 	if ( null !== $output )
   523 	if ( null !== $output ) {
   525 		return $output;
   524 		return $output;
       
   525 	}
   526 
   526 
   527 	if ( $crop ) {
   527 	if ( $crop ) {
   528 		// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
   528 		// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
   529 		$aspect_ratio = $orig_w / $orig_h;
   529 		$aspect_ratio = $orig_w / $orig_h;
   530 		$new_w = min($dest_w, $orig_w);
   530 		$new_w        = min( $dest_w, $orig_w );
   531 		$new_h = min($dest_h, $orig_h);
   531 		$new_h        = min( $dest_h, $orig_h );
   532 
   532 
   533 		if ( ! $new_w ) {
   533 		if ( ! $new_w ) {
   534 			$new_w = (int) round( $new_h * $aspect_ratio );
   534 			$new_w = (int) round( $new_h * $aspect_ratio );
   535 		}
   535 		}
   536 
   536 
   537 		if ( ! $new_h ) {
   537 		if ( ! $new_h ) {
   538 			$new_h = (int) round( $new_w / $aspect_ratio );
   538 			$new_h = (int) round( $new_w / $aspect_ratio );
   539 		}
   539 		}
   540 
   540 
   541 		$size_ratio = max($new_w / $orig_w, $new_h / $orig_h);
   541 		$size_ratio = max( $new_w / $orig_w, $new_h / $orig_h );
   542 
   542 
   543 		$crop_w = round($new_w / $size_ratio);
   543 		$crop_w = round( $new_w / $size_ratio );
   544 		$crop_h = round($new_h / $size_ratio);
   544 		$crop_h = round( $new_h / $size_ratio );
   545 
   545 
   546 		if ( ! is_array( $crop ) || count( $crop ) !== 2 ) {
   546 		if ( ! is_array( $crop ) || count( $crop ) !== 2 ) {
   547 			$crop = array( 'center', 'center' );
   547 			$crop = array( 'center', 'center' );
   548 		}
   548 		}
   549 
   549 
   604  */
   604  */
   605 function image_make_intermediate_size( $file, $width, $height, $crop = false ) {
   605 function image_make_intermediate_size( $file, $width, $height, $crop = false ) {
   606 	if ( $width || $height ) {
   606 	if ( $width || $height ) {
   607 		$editor = wp_get_image_editor( $file );
   607 		$editor = wp_get_image_editor( $file );
   608 
   608 
   609 		if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) )
   609 		if ( is_wp_error( $editor ) || is_wp_error( $editor->resize( $width, $height, $crop ) ) ) {
   610 			return false;
   610 			return false;
       
   611 		}
   611 
   612 
   612 		$resized_file = $editor->save();
   613 		$resized_file = $editor->save();
   613 
   614 
   614 		if ( ! is_wp_error( $resized_file ) && $resized_file ) {
   615 		if ( ! is_wp_error( $resized_file ) && $resized_file ) {
   615 			unset( $resized_file['path'] );
   616 			unset( $resized_file['path'] );
   635 	 * To test for varying crops, we constrain the dimensions of the larger image
   636 	 * To test for varying crops, we constrain the dimensions of the larger image
   636 	 * to the dimensions of the smaller image and see if they match.
   637 	 * to the dimensions of the smaller image and see if they match.
   637 	 */
   638 	 */
   638 	if ( $source_width > $target_width ) {
   639 	if ( $source_width > $target_width ) {
   639 		$constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width );
   640 		$constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width );
   640 		$expected_size = array( $target_width, $target_height );
   641 		$expected_size    = array( $target_width, $target_height );
   641 	} else {
   642 	} else {
   642 		$constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width );
   643 		$constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width );
   643 		$expected_size = array( $source_width, $source_height );
   644 		$expected_size    = array( $source_width, $source_height );
   644 	}
   645 	}
   645 
   646 
   646 	// If the image dimensions are within 1px of the expected size, we consider it a match.
   647 	// If the image dimensions are within 1px of the expected size, we consider it a match.
   647 	$matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 );
   648 	$matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 );
   648 
   649 
   684  *     @type string $path   Image's absolute filesystem path.
   685  *     @type string $path   Image's absolute filesystem path.
   685  *     @type string $url    Image's URL.
   686  *     @type string $url    Image's URL.
   686  * }
   687  * }
   687  */
   688  */
   688 function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) {
   689 function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) {
   689 	if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] )  ) {
   690 	if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] ) ) {
   690 		return false;
   691 		return false;
   691 	}
   692 	}
   692 
   693 
   693 	$data = array();
   694 	$data = array();
   694 
   695 
   728 			if ( 1 < count( $candidates ) ) {
   729 			if ( 1 < count( $candidates ) ) {
   729 				ksort( $candidates );
   730 				ksort( $candidates );
   730 			}
   731 			}
   731 
   732 
   732 			$data = array_shift( $candidates );
   733 			$data = array_shift( $candidates );
   733 		/*
   734 			/*
   734 		 * When the size requested is smaller than the thumbnail dimensions, we
   735 			* When the size requested is smaller than the thumbnail dimensions, we
   735 		 * fall back to the thumbnail size to maintain backwards compatibility with
   736 			* fall back to the thumbnail size to maintain backward compatibility with
   736 		 * pre 4.6 versions of WordPress.
   737 			* pre 4.6 versions of WordPress.
   737 		 */
   738 			*/
   738 		} elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) {
   739 		} elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) {
   739 			$data = $imagedata['sizes']['thumbnail'];
   740 			$data = $imagedata['sizes']['thumbnail'];
   740 		} else {
   741 		} else {
   741 			return false;
   742 			return false;
   742 		}
   743 		}
   753 		return false;
   754 		return false;
   754 	}
   755 	}
   755 
   756 
   756 	// include the full filesystem path of the intermediate file
   757 	// include the full filesystem path of the intermediate file
   757 	if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) {
   758 	if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) {
   758 		$file_url = wp_get_attachment_url($post_id);
   759 		$file_url     = wp_get_attachment_url( $post_id );
   759 		$data['path'] = path_join( dirname($imagedata['file']), $data['file'] );
   760 		$data['path'] = path_join( dirname( $imagedata['file'] ), $data['file'] );
   760 		$data['url'] = path_join( dirname($file_url), $data['file'] );
   761 		$data['url']  = path_join( dirname( $file_url ), $data['file'] );
   761 	}
   762 	}
   762 
   763 
   763 	/**
   764 	/**
   764 	 * Filters the output of image_get_intermediate_size()
   765 	 * Filters the output of image_get_intermediate_size()
   765 	 *
   766 	 *
   783  *
   784  *
   784  * @return array Returns a filtered array of image size strings.
   785  * @return array Returns a filtered array of image size strings.
   785  */
   786  */
   786 function get_intermediate_image_sizes() {
   787 function get_intermediate_image_sizes() {
   787 	$_wp_additional_image_sizes = wp_get_additional_image_sizes();
   788 	$_wp_additional_image_sizes = wp_get_additional_image_sizes();
   788 	$image_sizes = array('thumbnail', 'medium', 'medium_large', 'large'); // Standard sizes
   789 	$image_sizes                = array( 'thumbnail', 'medium', 'medium_large', 'large' ); // Standard sizes
   789 	if ( ! empty( $_wp_additional_image_sizes ) ) {
   790 	if ( ! empty( $_wp_additional_image_sizes ) ) {
   790 		$image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
   791 		$image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
   791 	}
   792 	}
   792 
   793 
   793 	/**
   794 	/**
   827 
   828 
   828 		if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) {
   829 		if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) {
   829 			/** This filter is documented in wp-includes/post.php */
   830 			/** This filter is documented in wp-includes/post.php */
   830 			$icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
   831 			$icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' );
   831 
   832 
   832 			$src_file = $icon_dir . '/' . wp_basename( $src );
   833 			$src_file                = $icon_dir . '/' . wp_basename( $src );
   833 			@list( $width, $height ) = getimagesize( $src_file );
   834 			@list( $width, $height ) = getimagesize( $src_file );
   834 		}
   835 		}
   835 
   836 
   836 		if ( $src && $width && $height ) {
   837 		if ( $src && $width && $height ) {
   837 			$image = array( $src, $width, $height );
   838 			$image = array( $src, $width, $height );
   866  *                                    and height values in pixels (in that order). Default 'thumbnail'.
   867  *                                    and height values in pixels (in that order). Default 'thumbnail'.
   867  * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
   868  * @param bool         $icon          Optional. Whether the image should be treated as an icon. Default false.
   868  * @param string|array $attr          Optional. Attributes for the image markup. Default empty.
   869  * @param string|array $attr          Optional. Attributes for the image markup. Default empty.
   869  * @return string HTML img element or empty string on failure.
   870  * @return string HTML img element or empty string on failure.
   870  */
   871  */
   871 function wp_get_attachment_image($attachment_id, $size = 'thumbnail', $icon = false, $attr = '') {
   872 function wp_get_attachment_image( $attachment_id, $size = 'thumbnail', $icon = false, $attr = '' ) {
   872 	$html = '';
   873 	$html  = '';
   873 	$image = wp_get_attachment_image_src($attachment_id, $size, $icon);
   874 	$image = wp_get_attachment_image_src( $attachment_id, $size, $icon );
   874 	if ( $image ) {
   875 	if ( $image ) {
   875 		list($src, $width, $height) = $image;
   876 		list($src, $width, $height) = $image;
   876 		$hwstring = image_hwstring($width, $height);
   877 		$hwstring                   = image_hwstring( $width, $height );
   877 		$size_class = $size;
   878 		$size_class                 = $size;
   878 		if ( is_array( $size_class ) ) {
   879 		if ( is_array( $size_class ) ) {
   879 			$size_class = join( 'x', $size_class );
   880 			$size_class = join( 'x', $size_class );
   880 		}
   881 		}
   881 		$attachment = get_post($attachment_id);
   882 		$attachment   = get_post( $attachment_id );
   882 		$default_attr = array(
   883 		$default_attr = array(
   883 			'src'	=> $src,
   884 			'src'   => $src,
   884 			'class'	=> "attachment-$size_class size-$size_class",
   885 			'class' => "attachment-$size_class size-$size_class",
   885 			'alt'	=> trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
   886 			'alt'   => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
   886 		);
   887 		);
   887 
   888 
   888 		$attr = wp_parse_args( $attr, $default_attr );
   889 		$attr = wp_parse_args( $attr, $default_attr );
   889 
   890 
   890 		// Generate 'srcset' and 'sizes' if not already present.
   891 		// Generate 'srcset' and 'sizes' if not already present.
   891 		if ( empty( $attr['srcset'] ) ) {
   892 		if ( empty( $attr['srcset'] ) ) {
   892 			$image_meta = wp_get_attachment_metadata( $attachment_id );
   893 			$image_meta = wp_get_attachment_metadata( $attachment_id );
   893 
   894 
   894 			if ( is_array( $image_meta ) ) {
   895 			if ( is_array( $image_meta ) ) {
   895 				$size_array = array( absint( $width ), absint( $height ) );
   896 				$size_array = array( absint( $width ), absint( $height ) );
   896 				$srcset = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );
   897 				$srcset     = wp_calculate_image_srcset( $size_array, $src, $image_meta, $attachment_id );
   897 				$sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );
   898 				$sizes      = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id );
   898 
   899 
   899 				if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) {
   900 				if ( $srcset && ( $sizes || ! empty( $attr['sizes'] ) ) ) {
   900 					$attr['srcset'] = $srcset;
   901 					$attr['srcset'] = $srcset;
   901 
   902 
   902 					if ( empty( $attr['sizes'] ) ) {
   903 					if ( empty( $attr['sizes'] ) ) {
   916 		 * @param string|array $size       Requested size. Image size or array of width and height values
   917 		 * @param string|array $size       Requested size. Image size or array of width and height values
   917 		 *                                 (in that order). Default 'thumbnail'.
   918 		 *                                 (in that order). Default 'thumbnail'.
   918 		 */
   919 		 */
   919 		$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
   920 		$attr = apply_filters( 'wp_get_attachment_image_attributes', $attr, $attachment, $size );
   920 		$attr = array_map( 'esc_attr', $attr );
   921 		$attr = array_map( 'esc_attr', $attr );
   921 		$html = rtrim("<img $hwstring");
   922 		$html = rtrim( "<img $hwstring" );
   922 		foreach ( $attr as $name => $value ) {
   923 		foreach ( $attr as $name => $value ) {
   923 			$html .= " $name=" . '"' . $value . '"';
   924 			$html .= " $name=" . '"' . $value . '"';
   924 		}
   925 		}
   925 		$html .= ' />';
   926 		$html .= ' />';
   926 	}
   927 	}
   986 	if ( $size_name === 'full' ) {
   987 	if ( $size_name === 'full' ) {
   987 		return array(
   988 		return array(
   988 			absint( $image_meta['width'] ),
   989 			absint( $image_meta['width'] ),
   989 			absint( $image_meta['height'] ),
   990 			absint( $image_meta['height'] ),
   990 		);
   991 		);
   991 	} elseif ( ! empty( $image_meta['sizes'][$size_name] ) ) {
   992 	} elseif ( ! empty( $image_meta['sizes'][ $size_name ] ) ) {
   992 		return array(
   993 		return array(
   993 			absint( $image_meta['sizes'][$size_name]['width'] ),
   994 			absint( $image_meta['sizes'][ $size_name ]['width'] ),
   994 			absint( $image_meta['sizes'][$size_name]['height'] ),
   995 			absint( $image_meta['sizes'][ $size_name ]['height'] ),
   995 		);
   996 		);
   996 	}
   997 	}
   997 
   998 
   998 	return false;
   999 	return false;
   999 }
  1000 }
  1019 
  1020 
  1020 	if ( ! is_array( $image_meta ) ) {
  1021 	if ( ! is_array( $image_meta ) ) {
  1021 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1022 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1022 	}
  1023 	}
  1023 
  1024 
  1024 	$image_src = $image[0];
  1025 	$image_src  = $image[0];
  1025 	$size_array = array(
  1026 	$size_array = array(
  1026 		absint( $image[1] ),
  1027 		absint( $image[1] ),
  1027 		absint( $image[2] )
  1028 		absint( $image[2] ),
  1028 	);
  1029 	);
  1029 
  1030 
  1030 	return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );
  1031 	return wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );
  1031 }
  1032 }
  1032 
  1033 
  1059 	}
  1060 	}
  1060 
  1061 
  1061 	$image_sizes = $image_meta['sizes'];
  1062 	$image_sizes = $image_meta['sizes'];
  1062 
  1063 
  1063 	// Get the width and height of the image.
  1064 	// Get the width and height of the image.
  1064 	$image_width = (int) $size_array[0];
  1065 	$image_width  = (int) $size_array[0];
  1065 	$image_height = (int) $size_array[1];
  1066 	$image_height = (int) $size_array[1];
  1066 
  1067 
  1067 	// Bail early if error/no width.
  1068 	// Bail early if error/no width.
  1068 	if ( $image_width < 1 ) {
  1069 	if ( $image_width < 1 ) {
  1069 		return false;
  1070 		return false;
  1091 
  1092 
  1092 	if ( $dirname ) {
  1093 	if ( $dirname ) {
  1093 		$dirname = trailingslashit( $dirname );
  1094 		$dirname = trailingslashit( $dirname );
  1094 	}
  1095 	}
  1095 
  1096 
  1096 	$upload_dir = wp_get_upload_dir();
  1097 	$upload_dir    = wp_get_upload_dir();
  1097 	$image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname;
  1098 	$image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname;
  1098 
  1099 
  1099 	/*
  1100 	/*
  1100 	 * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain
  1101 	 * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain
  1101 	 * (which is to say, when they share the domain name of the current request).
  1102 	 * (which is to say, when they share the domain name of the current request).
  1237 
  1238 
  1238 	if ( ! is_array( $image_meta ) ) {
  1239 	if ( ! is_array( $image_meta ) ) {
  1239 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1240 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1240 	}
  1241 	}
  1241 
  1242 
  1242 	$image_src = $image[0];
  1243 	$image_src  = $image[0];
  1243 	$size_array = array(
  1244 	$size_array = array(
  1244 		absint( $image[1] ),
  1245 		absint( $image[1] ),
  1245 		absint( $image[2] )
  1246 		absint( $image[2] ),
  1246 	);
  1247 	);
  1247 
  1248 
  1248 	return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id );
  1249 	return wp_calculate_image_sizes( $size_array, $image_src, $image_meta, $attachment_id );
  1249 }
  1250 }
  1250 
  1251 
  1317 		return $content;
  1318 		return $content;
  1318 	}
  1319 	}
  1319 
  1320 
  1320 	$selected_images = $attachment_ids = array();
  1321 	$selected_images = $attachment_ids = array();
  1321 
  1322 
  1322 	foreach( $matches[0] as $image ) {
  1323 	foreach ( $matches[0] as $image ) {
  1323 		if ( false === strpos( $image, ' srcset=' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
  1324 		if ( false === strpos( $image, ' srcset=' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) &&
  1324 			( $attachment_id = absint( $class_id[1] ) ) ) {
  1325 			( $attachment_id = absint( $class_id[1] ) ) ) {
  1325 
  1326 
  1326 			/*
  1327 			/*
  1327 			 * If exactly the same image tag is used more than once, overwrite it.
  1328 			 * If exactly the same image tag is used more than once, overwrite it.
  1341 		_prime_post_caches( array_keys( $attachment_ids ), false, true );
  1342 		_prime_post_caches( array_keys( $attachment_ids ), false, true );
  1342 	}
  1343 	}
  1343 
  1344 
  1344 	foreach ( $selected_images as $image => $attachment_id ) {
  1345 	foreach ( $selected_images as $image => $attachment_id ) {
  1345 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1346 		$image_meta = wp_get_attachment_metadata( $attachment_id );
  1346 		$content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
  1347 		$content    = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
  1347 	}
  1348 	}
  1348 
  1349 
  1349 	return $content;
  1350 	return $content;
  1350 }
  1351 }
  1351 
  1352 
  1366 	// Ensure the image meta exists.
  1367 	// Ensure the image meta exists.
  1367 	if ( empty( $image_meta['sizes'] ) ) {
  1368 	if ( empty( $image_meta['sizes'] ) ) {
  1368 		return $image;
  1369 		return $image;
  1369 	}
  1370 	}
  1370 
  1371 
  1371 	$image_src = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
  1372 	$image_src         = preg_match( '/src="([^"]+)"/', $image, $match_src ) ? $match_src[1] : '';
  1372 	list( $image_src ) = explode( '?', $image_src );
  1373 	list( $image_src ) = explode( '?', $image_src );
  1373 
  1374 
  1374 	// Return early if we couldn't get the image source.
  1375 	// Return early if we couldn't get the image source.
  1375 	if ( ! $image_src ) {
  1376 	if ( ! $image_src ) {
  1376 		return $image;
  1377 		return $image;
  1381 		strpos( wp_basename( $image_src ), $img_edit_hash[0] ) === false ) {
  1382 		strpos( wp_basename( $image_src ), $img_edit_hash[0] ) === false ) {
  1382 
  1383 
  1383 		return $image;
  1384 		return $image;
  1384 	}
  1385 	}
  1385 
  1386 
  1386 	$width  = preg_match( '/ width="([0-9]+)"/',  $image, $match_width  ) ? (int) $match_width[1]  : 0;
  1387 	$width  = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0;
  1387 	$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
  1388 	$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
  1388 
  1389 
  1389 	if ( ! $width || ! $height ) {
  1390 	if ( ! $width || ! $height ) {
  1390 		/*
  1391 		/*
  1391 		 * If attempts to parse the size value failed, attempt to use the image meta data to match
  1392 		 * If attempts to parse the size value failed, attempt to use the image meta data to match
  1392 		 * the image file name from 'src' against the available sizes for an attachment.
  1393 		 * the image file name from 'src' against the available sizes for an attachment.
  1393 		 */
  1394 		 */
  1394 		$image_filename = wp_basename( $image_src );
  1395 		$image_filename = wp_basename( $image_src );
  1395 
  1396 
  1396 		if ( $image_filename === wp_basename( $image_meta['file'] ) ) {
  1397 		if ( $image_filename === wp_basename( $image_meta['file'] ) ) {
  1397 			$width = (int) $image_meta['width'];
  1398 			$width  = (int) $image_meta['width'];
  1398 			$height = (int) $image_meta['height'];
  1399 			$height = (int) $image_meta['height'];
  1399 		} else {
  1400 		} else {
  1400 			foreach( $image_meta['sizes'] as $image_size_data ) {
  1401 			foreach ( $image_meta['sizes'] as $image_size_data ) {
  1401 				if ( $image_filename === $image_size_data['file'] ) {
  1402 				if ( $image_filename === $image_size_data['file'] ) {
  1402 					$width = (int) $image_size_data['width'];
  1403 					$width  = (int) $image_size_data['width'];
  1403 					$height = (int) $image_size_data['height'];
  1404 					$height = (int) $image_size_data['height'];
  1404 					break;
  1405 					break;
  1405 				}
  1406 				}
  1406 			}
  1407 			}
  1407 		}
  1408 		}
  1410 	if ( ! $width || ! $height ) {
  1411 	if ( ! $width || ! $height ) {
  1411 		return $image;
  1412 		return $image;
  1412 	}
  1413 	}
  1413 
  1414 
  1414 	$size_array = array( $width, $height );
  1415 	$size_array = array( $width, $height );
  1415 	$srcset = wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );
  1416 	$srcset     = wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id );
  1416 
  1417 
  1417 	if ( $srcset ) {
  1418 	if ( $srcset ) {
  1418 		// Check if there is already a 'sizes' attribute.
  1419 		// Check if there is already a 'sizes' attribute.
  1419 		$sizes = strpos( $image, ' sizes=' );
  1420 		$sizes = strpos( $image, ' sizes=' );
  1420 
  1421 
  1479  */
  1480  */
  1480 function _wp_post_thumbnail_class_filter_remove( $attr ) {
  1481 function _wp_post_thumbnail_class_filter_remove( $attr ) {
  1481 	remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
  1482 	remove_filter( 'wp_get_attachment_image_attributes', '_wp_post_thumbnail_class_filter' );
  1482 }
  1483 }
  1483 
  1484 
  1484 add_shortcode('wp_caption', 'img_caption_shortcode');
  1485 add_shortcode( 'wp_caption', 'img_caption_shortcode' );
  1485 add_shortcode('caption', 'img_caption_shortcode');
  1486 add_shortcode( 'caption', 'img_caption_shortcode' );
  1486 
  1487 
  1487 /**
  1488 /**
  1488  * Builds the Caption shortcode output.
  1489  * Builds the Caption shortcode output.
  1489  *
  1490  *
  1490  * Allows a plugin to replace the content that would otherwise be returned. The
  1491  * Allows a plugin to replace the content that would otherwise be returned. The
  1491  * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr
  1492  * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr
  1492  * parameter and the content parameter values.
  1493  * parameter and the content parameter values.
  1493  *
  1494  *
  1494  * The supported attributes for the shortcode are 'id', 'align', 'width', and
  1495  * The supported attributes for the shortcode are 'id', 'caption_id', 'align',
  1495  * 'caption'.
  1496  * 'width', 'caption', and 'class'.
  1496  *
  1497  *
  1497  * @since 2.6.0
  1498  * @since 2.6.0
       
  1499  * @since 3.9.0 The `class` attribute was added.
       
  1500  * @since 5.1.0 The `caption_id` attribute was added.
  1498  *
  1501  *
  1499  * @param array  $attr {
  1502  * @param array  $attr {
  1500  *     Attributes of the caption shortcode.
  1503  *     Attributes of the caption shortcode.
  1501  *
  1504  *
  1502  *     @type string $id      ID of the div element for the caption.
  1505  *     @type string $id         ID of the image and caption container element, i.e. `<figure>` or `<div>`.
  1503  *     @type string $align   Class name that aligns the caption. Default 'alignnone'. Accepts 'alignleft',
  1506  *     @type string $caption_id ID of the caption element, i.e. `<figcaption>` or `<p>`.
  1504  *                           'aligncenter', alignright', 'alignnone'.
  1507  *     @type string $align      Class name that aligns the caption. Default 'alignnone'. Accepts 'alignleft',
  1505  *     @type int    $width   The width of the caption, in pixels.
  1508  *                              'aligncenter', alignright', 'alignnone'.
  1506  *     @type string $caption The caption text.
  1509  *     @type int    $width      The width of the caption, in pixels.
  1507  *     @type string $class   Additional class name(s) added to the caption container.
  1510  *     @type string $caption    The caption text.
       
  1511  *     @type string $class      Additional class name(s) added to the caption container.
  1508  * }
  1512  * }
  1509  * @param string $content Shortcode content.
  1513  * @param string $content Shortcode content.
  1510  * @return string HTML content to display the caption.
  1514  * @return string HTML content to display the caption.
  1511  */
  1515  */
  1512 function img_caption_shortcode( $attr, $content = null ) {
  1516 function img_caption_shortcode( $attr, $content = null ) {
  1513 	// New-style shortcode with the caption inside the shortcode with the link and image tags.
  1517 	// New-style shortcode with the caption inside the shortcode with the link and image tags.
  1514 	if ( ! isset( $attr['caption'] ) ) {
  1518 	if ( ! isset( $attr['caption'] ) ) {
  1515 		if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
  1519 		if ( preg_match( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is', $content, $matches ) ) {
  1516 			$content = $matches[1];
  1520 			$content         = $matches[1];
  1517 			$attr['caption'] = trim( $matches[2] );
  1521 			$attr['caption'] = trim( $matches[2] );
  1518 		}
  1522 		}
  1519 	} elseif ( strpos( $attr['caption'], '<' ) !== false ) {
  1523 	} elseif ( strpos( $attr['caption'], '<' ) !== false ) {
  1520 		$attr['caption'] = wp_kses( $attr['caption'], 'post' );
  1524 		$attr['caption'] = wp_kses( $attr['caption'], 'post' );
  1521 	}
  1525 	}
  1533 	 * @param string $output  The caption output. Default empty.
  1537 	 * @param string $output  The caption output. Default empty.
  1534 	 * @param array  $attr    Attributes of the caption shortcode.
  1538 	 * @param array  $attr    Attributes of the caption shortcode.
  1535 	 * @param string $content The image element, possibly wrapped in a hyperlink.
  1539 	 * @param string $content The image element, possibly wrapped in a hyperlink.
  1536 	 */
  1540 	 */
  1537 	$output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
  1541 	$output = apply_filters( 'img_caption_shortcode', '', $attr, $content );
  1538 	if ( $output != '' )
  1542 	if ( $output != '' ) {
  1539 		return $output;
  1543 		return $output;
  1540 
  1544 	}
  1541 	$atts = shortcode_atts( array(
  1545 
  1542 		'id'	  => '',
  1546 	$atts = shortcode_atts(
  1543 		'align'	  => 'alignnone',
  1547 		array(
  1544 		'width'	  => '',
  1548 			'id'         => '',
  1545 		'caption' => '',
  1549 			'caption_id' => '',
  1546 		'class'   => '',
  1550 			'align'      => 'alignnone',
  1547 	), $attr, 'caption' );
  1551 			'width'      => '',
       
  1552 			'caption'    => '',
       
  1553 			'class'      => '',
       
  1554 		),
       
  1555 		$attr,
       
  1556 		'caption'
       
  1557 	);
  1548 
  1558 
  1549 	$atts['width'] = (int) $atts['width'];
  1559 	$atts['width'] = (int) $atts['width'];
  1550 	if ( $atts['width'] < 1 || empty( $atts['caption'] ) )
  1560 	if ( $atts['width'] < 1 || empty( $atts['caption'] ) ) {
  1551 		return $content;
  1561 		return $content;
  1552 
  1562 	}
  1553 	if ( ! empty( $atts['id'] ) )
  1563 
  1554 		$atts['id'] = 'id="' . esc_attr( sanitize_html_class( $atts['id'] ) ) . '" ';
  1564 	$id = $caption_id = $describedby = '';
       
  1565 
       
  1566 	if ( $atts['id'] ) {
       
  1567 		$atts['id'] = sanitize_html_class( $atts['id'] );
       
  1568 		$id         = 'id="' . esc_attr( $atts['id'] ) . '" ';
       
  1569 	}
       
  1570 
       
  1571 	if ( $atts['caption_id'] ) {
       
  1572 		$atts['caption_id'] = sanitize_html_class( $atts['caption_id'] );
       
  1573 	} elseif ( $atts['id'] ) {
       
  1574 		$atts['caption_id'] = 'caption-' . str_replace( '_', '-', $atts['id'] );
       
  1575 	}
       
  1576 
       
  1577 	if ( $atts['caption_id'] ) {
       
  1578 		$caption_id  = 'id="' . esc_attr( $atts['caption_id'] ) . '" ';
       
  1579 		$describedby = 'aria-describedby="' . esc_attr( $atts['caption_id'] ) . '" ';
       
  1580 	}
  1555 
  1581 
  1556 	$class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] );
  1582 	$class = trim( 'wp-caption ' . $atts['align'] . ' ' . $atts['class'] );
  1557 
  1583 
  1558 	$html5 = current_theme_supports( 'html5', 'caption' );
  1584 	$html5 = current_theme_supports( 'html5', 'caption' );
  1559 	// HTML5 captions never added the extra 10px to the image width
  1585 	// HTML5 captions never added the extra 10px to the image width
  1580 	if ( $caption_width ) {
  1606 	if ( $caption_width ) {
  1581 		$style = 'style="width: ' . (int) $caption_width . 'px" ';
  1607 		$style = 'style="width: ' . (int) $caption_width . 'px" ';
  1582 	}
  1608 	}
  1583 
  1609 
  1584 	if ( $html5 ) {
  1610 	if ( $html5 ) {
  1585 		$html = '<figure ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
  1611 		$html = sprintf(
  1586 		. do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $atts['caption'] . '</figcaption></figure>';
  1612 			'<figure %s%s%sclass="%s">%s%s</figure>',
       
  1613 			$id,
       
  1614 			$describedby,
       
  1615 			$style,
       
  1616 			esc_attr( $class ),
       
  1617 			do_shortcode( $content ),
       
  1618 			sprintf(
       
  1619 				'<figcaption %sclass="wp-caption-text">%s</figcaption>',
       
  1620 				$caption_id,
       
  1621 				$atts['caption']
       
  1622 			)
       
  1623 		);
  1587 	} else {
  1624 	} else {
  1588 		$html = '<div ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
  1625 		$html = sprintf(
  1589 		. do_shortcode( $content ) . '<p class="wp-caption-text">' . $atts['caption'] . '</p></div>';
  1626 			'<div %s%sclass="%s">%s%s</div>',
       
  1627 			$id,
       
  1628 			$style,
       
  1629 			esc_attr( $class ),
       
  1630 			str_replace( '<img ', '<img ' . $describedby, do_shortcode( $content ) ),
       
  1631 			sprintf(
       
  1632 				'<p %sclass="wp-caption-text">%s</p>',
       
  1633 				$caption_id,
       
  1634 				$atts['caption']
       
  1635 			)
       
  1636 		);
  1590 	}
  1637 	}
  1591 
  1638 
  1592 	return $html;
  1639 	return $html;
  1593 }
  1640 }
  1594 
  1641 
  1595 add_shortcode('gallery', 'gallery_shortcode');
  1642 add_shortcode( 'gallery', 'gallery_shortcode' );
  1596 
  1643 
  1597 /**
  1644 /**
  1598  * Builds the Gallery shortcode output.
  1645  * Builds the Gallery shortcode output.
  1599  *
  1646  *
  1600  * This implements the functionality of the Gallery Shortcode for displaying
  1647  * This implements the functionality of the Gallery Shortcode for displaying
  1661 	if ( $output != '' ) {
  1708 	if ( $output != '' ) {
  1662 		return $output;
  1709 		return $output;
  1663 	}
  1710 	}
  1664 
  1711 
  1665 	$html5 = current_theme_supports( 'html5', 'gallery' );
  1712 	$html5 = current_theme_supports( 'html5', 'gallery' );
  1666 	$atts = shortcode_atts( array(
  1713 	$atts  = shortcode_atts(
  1667 		'order'      => 'ASC',
  1714 		array(
  1668 		'orderby'    => 'menu_order ID',
  1715 			'order'      => 'ASC',
  1669 		'id'         => $post ? $post->ID : 0,
  1716 			'orderby'    => 'menu_order ID',
  1670 		'itemtag'    => $html5 ? 'figure'     : 'dl',
  1717 			'id'         => $post ? $post->ID : 0,
  1671 		'icontag'    => $html5 ? 'div'        : 'dt',
  1718 			'itemtag'    => $html5 ? 'figure' : 'dl',
  1672 		'captiontag' => $html5 ? 'figcaption' : 'dd',
  1719 			'icontag'    => $html5 ? 'div' : 'dt',
  1673 		'columns'    => 3,
  1720 			'captiontag' => $html5 ? 'figcaption' : 'dd',
  1674 		'size'       => 'thumbnail',
  1721 			'columns'    => 3,
  1675 		'include'    => '',
  1722 			'size'       => 'thumbnail',
  1676 		'exclude'    => '',
  1723 			'include'    => '',
  1677 		'link'       => ''
  1724 			'exclude'    => '',
  1678 	), $attr, 'gallery' );
  1725 			'link'       => '',
       
  1726 		),
       
  1727 		$attr,
       
  1728 		'gallery'
       
  1729 	);
  1679 
  1730 
  1680 	$id = intval( $atts['id'] );
  1731 	$id = intval( $atts['id'] );
  1681 
  1732 
  1682 	if ( ! empty( $atts['include'] ) ) {
  1733 	if ( ! empty( $atts['include'] ) ) {
  1683 		$_attachments = get_posts( array( 'include' => $atts['include'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
  1734 		$_attachments = get_posts(
       
  1735 			array(
       
  1736 				'include'        => $atts['include'],
       
  1737 				'post_status'    => 'inherit',
       
  1738 				'post_type'      => 'attachment',
       
  1739 				'post_mime_type' => 'image',
       
  1740 				'order'          => $atts['order'],
       
  1741 				'orderby'        => $atts['orderby'],
       
  1742 			)
       
  1743 		);
  1684 
  1744 
  1685 		$attachments = array();
  1745 		$attachments = array();
  1686 		foreach ( $_attachments as $key => $val ) {
  1746 		foreach ( $_attachments as $key => $val ) {
  1687 			$attachments[$val->ID] = $_attachments[$key];
  1747 			$attachments[ $val->ID ] = $_attachments[ $key ];
  1688 		}
  1748 		}
  1689 	} elseif ( ! empty( $atts['exclude'] ) ) {
  1749 	} elseif ( ! empty( $atts['exclude'] ) ) {
  1690 		$attachments = get_children( array( 'post_parent' => $id, 'exclude' => $atts['exclude'], 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
  1750 		$attachments = get_children(
       
  1751 			array(
       
  1752 				'post_parent'    => $id,
       
  1753 				'exclude'        => $atts['exclude'],
       
  1754 				'post_status'    => 'inherit',
       
  1755 				'post_type'      => 'attachment',
       
  1756 				'post_mime_type' => 'image',
       
  1757 				'order'          => $atts['order'],
       
  1758 				'orderby'        => $atts['orderby'],
       
  1759 			)
       
  1760 		);
  1691 	} else {
  1761 	} else {
  1692 		$attachments = get_children( array( 'post_parent' => $id, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => $atts['order'], 'orderby' => $atts['orderby'] ) );
  1762 		$attachments = get_children(
       
  1763 			array(
       
  1764 				'post_parent'    => $id,
       
  1765 				'post_status'    => 'inherit',
       
  1766 				'post_type'      => 'attachment',
       
  1767 				'post_mime_type' => 'image',
       
  1768 				'order'          => $atts['order'],
       
  1769 				'orderby'        => $atts['orderby'],
       
  1770 			)
       
  1771 		);
  1693 	}
  1772 	}
  1694 
  1773 
  1695 	if ( empty( $attachments ) ) {
  1774 	if ( empty( $attachments ) ) {
  1696 		return '';
  1775 		return '';
  1697 	}
  1776 	}
  1702 			$output .= wp_get_attachment_link( $att_id, $atts['size'], true ) . "\n";
  1781 			$output .= wp_get_attachment_link( $att_id, $atts['size'], true ) . "\n";
  1703 		}
  1782 		}
  1704 		return $output;
  1783 		return $output;
  1705 	}
  1784 	}
  1706 
  1785 
  1707 	$itemtag = tag_escape( $atts['itemtag'] );
  1786 	$itemtag    = tag_escape( $atts['itemtag'] );
  1708 	$captiontag = tag_escape( $atts['captiontag'] );
  1787 	$captiontag = tag_escape( $atts['captiontag'] );
  1709 	$icontag = tag_escape( $atts['icontag'] );
  1788 	$icontag    = tag_escape( $atts['icontag'] );
  1710 	$valid_tags = wp_kses_allowed_html( 'post' );
  1789 	$valid_tags = wp_kses_allowed_html( 'post' );
  1711 	if ( ! isset( $valid_tags[ $itemtag ] ) ) {
  1790 	if ( ! isset( $valid_tags[ $itemtag ] ) ) {
  1712 		$itemtag = 'dl';
  1791 		$itemtag = 'dl';
  1713 	}
  1792 	}
  1714 	if ( ! isset( $valid_tags[ $captiontag ] ) ) {
  1793 	if ( ! isset( $valid_tags[ $captiontag ] ) ) {
  1716 	}
  1795 	}
  1717 	if ( ! isset( $valid_tags[ $icontag ] ) ) {
  1796 	if ( ! isset( $valid_tags[ $icontag ] ) ) {
  1718 		$icontag = 'dt';
  1797 		$icontag = 'dt';
  1719 	}
  1798 	}
  1720 
  1799 
  1721 	$columns = intval( $atts['columns'] );
  1800 	$columns   = intval( $atts['columns'] );
  1722 	$itemwidth = $columns > 0 ? floor(100/$columns) : 100;
  1801 	$itemwidth = $columns > 0 ? floor( 100 / $columns ) : 100;
  1723 	$float = is_rtl() ? 'right' : 'left';
  1802 	$float     = is_rtl() ? 'right' : 'left';
  1724 
  1803 
  1725 	$selector = "gallery-{$instance}";
  1804 	$selector = "gallery-{$instance}";
  1726 
  1805 
  1727 	$gallery_style = '';
  1806 	$gallery_style = '';
  1728 
  1807 
  1755 			}
  1834 			}
  1756 			/* see gallery_shortcode() in wp-includes/media.php */
  1835 			/* see gallery_shortcode() in wp-includes/media.php */
  1757 		</style>\n\t\t";
  1836 		</style>\n\t\t";
  1758 	}
  1837 	}
  1759 
  1838 
  1760 	$size_class = sanitize_html_class( $atts['size'] );
  1839 	$size_class  = sanitize_html_class( $atts['size'] );
  1761 	$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
  1840 	$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
  1762 
  1841 
  1763 	/**
  1842 	/**
  1764 	 * Filters the default gallery shortcode CSS styles.
  1843 	 * Filters the default gallery shortcode CSS styles.
  1765 	 *
  1844 	 *
  1779 		} elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) {
  1858 		} elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) {
  1780 			$image_output = wp_get_attachment_image( $id, $atts['size'], false, $attr );
  1859 			$image_output = wp_get_attachment_image( $id, $atts['size'], false, $attr );
  1781 		} else {
  1860 		} else {
  1782 			$image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr );
  1861 			$image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr );
  1783 		}
  1862 		}
  1784 		$image_meta  = wp_get_attachment_metadata( $id );
  1863 		$image_meta = wp_get_attachment_metadata( $id );
  1785 
  1864 
  1786 		$orientation = '';
  1865 		$orientation = '';
  1787 		if ( isset( $image_meta['height'], $image_meta['width'] ) ) {
  1866 		if ( isset( $image_meta['height'], $image_meta['width'] ) ) {
  1788 			$orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape';
  1867 			$orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape';
  1789 		}
  1868 		}
  1790 		$output .= "<{$itemtag} class='gallery-item'>";
  1869 		$output .= "<{$itemtag} class='gallery-item'>";
  1791 		$output .= "
  1870 		$output .= "
  1792 			<{$icontag} class='gallery-icon {$orientation}'>
  1871 			<{$icontag} class='gallery-icon {$orientation}'>
  1793 				$image_output
  1872 				$image_output
  1794 			</{$icontag}>";
  1873 			</{$icontag}>";
  1795 		if ( $captiontag && trim($attachment->post_excerpt) ) {
  1874 		if ( $captiontag && trim( $attachment->post_excerpt ) ) {
  1796 			$output .= "
  1875 			$output .= "
  1797 				<{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'>
  1876 				<{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'>
  1798 				" . wptexturize($attachment->post_excerpt) . "
  1877 				" . wptexturize( $attachment->post_excerpt ) . "
  1799 				</{$captiontag}>";
  1878 				</{$captiontag}>";
  1800 		}
  1879 		}
  1801 		$output .= "</{$itemtag}>";
  1880 		$output .= "</{$itemtag}>";
  1802 		if ( ! $html5 && $columns > 0 && ++$i % $columns == 0 ) {
  1881 		if ( ! $html5 && $columns > 0 && ++$i % $columns == 0 ) {
  1803 			$output .= '<br style="clear: both" />';
  1882 			$output .= '<br style="clear: both" />';
  1819  * Outputs the templates used by playlists.
  1898  * Outputs the templates used by playlists.
  1820  *
  1899  *
  1821  * @since 3.9.0
  1900  * @since 3.9.0
  1822  */
  1901  */
  1823 function wp_underscore_playlist_templates() {
  1902 function wp_underscore_playlist_templates() {
  1824 ?>
  1903 	?>
  1825 <script type="text/html" id="tmpl-wp-playlist-current-item">
  1904 <script type="text/html" id="tmpl-wp-playlist-current-item">
  1826 	<# if ( data.image ) { #>
  1905 	<# if ( data.image ) { #>
  1827 	<img src="{{ data.thumb.src }}" alt="" />
  1906 	<img src="{{ data.thumb.src }}" alt="" />
  1828 	<# } #>
  1907 	<# } #>
  1829 	<div class="wp-playlist-caption">
  1908 	<div class="wp-playlist-caption">
  1830 		<span class="wp-playlist-item-meta wp-playlist-item-title"><?php
  1909 		<span class="wp-playlist-item-meta wp-playlist-item-title">
       
  1910 		<?php
  1831 			/* translators: playlist item title */
  1911 			/* translators: playlist item title */
  1832 			printf( _x( '&#8220;%s&#8221;', 'playlist item title' ), '{{ data.title }}' );
  1912 			printf( _x( '&#8220;%s&#8221;', 'playlist item title' ), '{{ data.title }}' );
  1833 		?></span>
  1913 		?>
       
  1914 		</span>
  1834 		<# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #>
  1915 		<# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #>
  1835 		<# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #>
  1916 		<# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #>
  1836 	</div>
  1917 	</div>
  1837 </script>
  1918 </script>
  1838 <script type="text/html" id="tmpl-wp-playlist-item">
  1919 <script type="text/html" id="tmpl-wp-playlist-item">
  1840 		<a class="wp-playlist-caption" href="{{ data.src }}">
  1921 		<a class="wp-playlist-caption" href="{{ data.src }}">
  1841 			{{ data.index ? ( data.index + '. ' ) : '' }}
  1922 			{{ data.index ? ( data.index + '. ' ) : '' }}
  1842 			<# if ( data.caption ) { #>
  1923 			<# if ( data.caption ) { #>
  1843 				{{ data.caption }}
  1924 				{{ data.caption }}
  1844 			<# } else { #>
  1925 			<# } else { #>
  1845 				<span class="wp-playlist-item-title"><?php
  1926 				<span class="wp-playlist-item-title">
       
  1927 				<?php
  1846 					/* translators: playlist item title */
  1928 					/* translators: playlist item title */
  1847 					printf( _x( '&#8220;%s&#8221;', 'playlist item title' ), '{{{ data.title }}}' );
  1929 					printf( _x( '&#8220;%s&#8221;', 'playlist item title' ), '{{{ data.title }}}' );
  1848 				?></span>
  1930 				?>
       
  1931 				</span>
  1849 				<# if ( data.artists && data.meta.artist ) { #>
  1932 				<# if ( data.artists && data.meta.artist ) { #>
  1850 				<span class="wp-playlist-item-artist"> &mdash; {{ data.meta.artist }}</span>
  1933 				<span class="wp-playlist-item-artist"> &mdash; {{ data.meta.artist }}</span>
  1851 				<# } #>
  1934 				<# } #>
  1852 			<# } #>
  1935 			<# } #>
  1853 		</a>
  1936 		</a>
  1854 		<# if ( data.meta.length_formatted ) { #>
  1937 		<# if ( data.meta.length_formatted ) { #>
  1855 		<div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div>
  1938 		<div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div>
  1856 		<# } #>
  1939 		<# } #>
  1857 	</div>
  1940 	</div>
  1858 </script>
  1941 </script>
  1859 <?php
  1942 	<?php
  1860 }
  1943 }
  1861 
  1944 
  1862 /**
  1945 /**
  1863  * Outputs and enqueue default scripts and styles for playlists.
  1946  * Outputs and enqueue default scripts and styles for playlists.
  1864  *
  1947  *
  1867  * @param string $type Type of playlist. Accepts 'audio' or 'video'.
  1950  * @param string $type Type of playlist. Accepts 'audio' or 'video'.
  1868  */
  1951  */
  1869 function wp_playlist_scripts( $type ) {
  1952 function wp_playlist_scripts( $type ) {
  1870 	wp_enqueue_style( 'wp-mediaelement' );
  1953 	wp_enqueue_style( 'wp-mediaelement' );
  1871 	wp_enqueue_script( 'wp-playlist' );
  1954 	wp_enqueue_script( 'wp-playlist' );
  1872 ?>
  1955 	?>
  1873 <!--[if lt IE 9]><script>document.createElement('<?php echo esc_js( $type ) ?>');</script><![endif]-->
  1956 <!--[if lt IE 9]><script>document.createElement('<?php echo esc_js( $type ); ?>');</script><![endif]-->
  1874 <?php
  1957 	<?php
  1875 	add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 );
  1958 	add_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 );
  1876 	add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 );
  1959 	add_action( 'admin_footer', 'wp_underscore_playlist_templates', 0 );
  1877 }
  1960 }
  1878 
  1961 
  1879 /**
  1962 /**
  1944 	$output = apply_filters( 'post_playlist', '', $attr, $instance );
  2027 	$output = apply_filters( 'post_playlist', '', $attr, $instance );
  1945 	if ( $output != '' ) {
  2028 	if ( $output != '' ) {
  1946 		return $output;
  2029 		return $output;
  1947 	}
  2030 	}
  1948 
  2031 
  1949 	$atts = shortcode_atts( array(
  2032 	$atts = shortcode_atts(
  1950 		'type'		=> 'audio',
  2033 		array(
  1951 		'order'		=> 'ASC',
  2034 			'type'         => 'audio',
  1952 		'orderby'	=> 'menu_order ID',
  2035 			'order'        => 'ASC',
  1953 		'id'		=> $post ? $post->ID : 0,
  2036 			'orderby'      => 'menu_order ID',
  1954 		'include'	=> '',
  2037 			'id'           => $post ? $post->ID : 0,
  1955 		'exclude'   => '',
  2038 			'include'      => '',
  1956 		'style'		=> 'light',
  2039 			'exclude'      => '',
  1957 		'tracklist' => true,
  2040 			'style'        => 'light',
  1958 		'tracknumbers' => true,
  2041 			'tracklist'    => true,
  1959 		'images'	=> true,
  2042 			'tracknumbers' => true,
  1960 		'artists'	=> true
  2043 			'images'       => true,
  1961 	), $attr, 'playlist' );
  2044 			'artists'      => true,
       
  2045 		),
       
  2046 		$attr,
       
  2047 		'playlist'
       
  2048 	);
  1962 
  2049 
  1963 	$id = intval( $atts['id'] );
  2050 	$id = intval( $atts['id'] );
  1964 
  2051 
  1965 	if ( $atts['type'] !== 'audio' ) {
  2052 	if ( $atts['type'] !== 'audio' ) {
  1966 		$atts['type'] = 'video';
  2053 		$atts['type'] = 'video';
  1967 	}
  2054 	}
  1968 
  2055 
  1969 	$args = array(
  2056 	$args = array(
  1970 		'post_status' => 'inherit',
  2057 		'post_status'    => 'inherit',
  1971 		'post_type' => 'attachment',
  2058 		'post_type'      => 'attachment',
  1972 		'post_mime_type' => $atts['type'],
  2059 		'post_mime_type' => $atts['type'],
  1973 		'order' => $atts['order'],
  2060 		'order'          => $atts['order'],
  1974 		'orderby' => $atts['orderby']
  2061 		'orderby'        => $atts['orderby'],
  1975 	);
  2062 	);
  1976 
  2063 
  1977 	if ( ! empty( $atts['include'] ) ) {
  2064 	if ( ! empty( $atts['include'] ) ) {
  1978 		$args['include'] = $atts['include'];
  2065 		$args['include'] = $atts['include'];
  1979 		$_attachments = get_posts( $args );
  2066 		$_attachments    = get_posts( $args );
  1980 
  2067 
  1981 		$attachments = array();
  2068 		$attachments = array();
  1982 		foreach ( $_attachments as $key => $val ) {
  2069 		foreach ( $_attachments as $key => $val ) {
  1983 			$attachments[$val->ID] = $_attachments[$key];
  2070 			$attachments[ $val->ID ] = $_attachments[ $key ];
  1984 		}
  2071 		}
  1985 	} elseif ( ! empty( $atts['exclude'] ) ) {
  2072 	} elseif ( ! empty( $atts['exclude'] ) ) {
  1986 		$args['post_parent'] = $id;
  2073 		$args['post_parent'] = $id;
  1987 		$args['exclude'] = $atts['exclude'];
  2074 		$args['exclude']     = $atts['exclude'];
  1988 		$attachments = get_children( $args );
  2075 		$attachments         = get_children( $args );
  1989 	} else {
  2076 	} else {
  1990 		$args['post_parent'] = $id;
  2077 		$args['post_parent'] = $id;
  1991 		$attachments = get_children( $args );
  2078 		$attachments         = get_children( $args );
  1992 	}
  2079 	}
  1993 
  2080 
  1994 	if ( empty( $attachments ) ) {
  2081 	if ( empty( $attachments ) ) {
  1995 		return '';
  2082 		return '';
  1996 	}
  2083 	}
  2003 		return $output;
  2090 		return $output;
  2004 	}
  2091 	}
  2005 
  2092 
  2006 	$outer = 22; // default padding and border of wrapper
  2093 	$outer = 22; // default padding and border of wrapper
  2007 
  2094 
  2008 	$default_width = 640;
  2095 	$default_width  = 640;
  2009 	$default_height = 360;
  2096 	$default_height = 360;
  2010 
  2097 
  2011 	$theme_width = empty( $content_width ) ? $default_width : ( $content_width - $outer );
  2098 	$theme_width  = empty( $content_width ) ? $default_width : ( $content_width - $outer );
  2012 	$theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width );
  2099 	$theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width );
  2013 
  2100 
  2014 	$data = array(
  2101 	$data = array(
  2015 		'type' => $atts['type'],
  2102 		'type'         => $atts['type'],
  2016 		// don't pass strings to JSON, will be truthy in JS
  2103 		// don't pass strings to JSON, will be truthy in JS
  2017 		'tracklist' => wp_validate_boolean( $atts['tracklist'] ),
  2104 		'tracklist'    => wp_validate_boolean( $atts['tracklist'] ),
  2018 		'tracknumbers' => wp_validate_boolean( $atts['tracknumbers'] ),
  2105 		'tracknumbers' => wp_validate_boolean( $atts['tracknumbers'] ),
  2019 		'images' => wp_validate_boolean( $atts['images'] ),
  2106 		'images'       => wp_validate_boolean( $atts['images'] ),
  2020 		'artists' => wp_validate_boolean( $atts['artists'] ),
  2107 		'artists'      => wp_validate_boolean( $atts['artists'] ),
  2021 	);
  2108 	);
  2022 
  2109 
  2023 	$tracks = array();
  2110 	$tracks = array();
  2024 	foreach ( $attachments as $attachment ) {
  2111 	foreach ( $attachments as $attachment ) {
  2025 		$url = wp_get_attachment_url( $attachment->ID );
  2112 		$url   = wp_get_attachment_url( $attachment->ID );
  2026 		$ftype = wp_check_filetype( $url, wp_get_mime_types() );
  2113 		$ftype = wp_check_filetype( $url, wp_get_mime_types() );
  2027 		$track = array(
  2114 		$track = array(
  2028 			'src' => $url,
  2115 			'src'         => $url,
  2029 			'type' => $ftype['type'],
  2116 			'type'        => $ftype['type'],
  2030 			'title' => $attachment->post_title,
  2117 			'title'       => $attachment->post_title,
  2031 			'caption' => $attachment->post_excerpt,
  2118 			'caption'     => $attachment->post_excerpt,
  2032 			'description' => $attachment->post_content
  2119 			'description' => $attachment->post_content,
  2033 		);
  2120 		);
  2034 
  2121 
  2035 		$track['meta'] = array();
  2122 		$track['meta'] = array();
  2036 		$meta = wp_get_attachment_metadata( $attachment->ID );
  2123 		$meta          = wp_get_attachment_metadata( $attachment->ID );
  2037 		if ( ! empty( $meta ) ) {
  2124 		if ( ! empty( $meta ) ) {
  2038 
  2125 
  2039 			foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) {
  2126 			foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) {
  2040 				if ( ! empty( $meta[ $key ] ) ) {
  2127 				if ( ! empty( $meta[ $key ] ) ) {
  2041 					$track['meta'][ $key ] = $meta[ $key ];
  2128 					$track['meta'][ $key ] = $meta[ $key ];
  2042 				}
  2129 				}
  2043 			}
  2130 			}
  2044 
  2131 
  2045 			if ( 'video' === $atts['type'] ) {
  2132 			if ( 'video' === $atts['type'] ) {
  2046 				if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
  2133 				if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
  2047 					$width = $meta['width'];
  2134 					$width        = $meta['width'];
  2048 					$height = $meta['height'];
  2135 					$height       = $meta['height'];
  2049 					$theme_height = round( ( $height * $theme_width ) / $width );
  2136 					$theme_height = round( ( $height * $theme_width ) / $width );
  2050 				} else {
  2137 				} else {
  2051 					$width = $default_width;
  2138 					$width  = $default_width;
  2052 					$height = $default_height;
  2139 					$height = $default_height;
  2053 				}
  2140 				}
  2054 
  2141 
  2055 				$track['dimensions'] = array(
  2142 				$track['dimensions'] = array(
  2056 					'original' => compact( 'width', 'height' ),
  2143 					'original' => compact( 'width', 'height' ),
  2057 					'resized' => array(
  2144 					'resized'  => array(
  2058 						'width' => $theme_width,
  2145 						'width'  => $theme_width,
  2059 						'height' => $theme_height
  2146 						'height' => $theme_height,
  2060 					)
  2147 					),
  2061 				);
  2148 				);
  2062 			}
  2149 			}
  2063 		}
  2150 		}
  2064 
  2151 
  2065 		if ( $atts['images'] ) {
  2152 		if ( $atts['images'] ) {
  2066 			$thumb_id = get_post_thumbnail_id( $attachment->ID );
  2153 			$thumb_id = get_post_thumbnail_id( $attachment->ID );
  2067 			if ( ! empty( $thumb_id ) ) {
  2154 			if ( ! empty( $thumb_id ) ) {
  2068 				list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' );
  2155 				list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' );
  2069 				$track['image'] = compact( 'src', 'width', 'height' );
  2156 				$track['image']               = compact( 'src', 'width', 'height' );
  2070 				list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' );
  2157 				list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' );
  2071 				$track['thumb'] = compact( 'src', 'width', 'height' );
  2158 				$track['thumb']               = compact( 'src', 'width', 'height' );
  2072 			} else {
  2159 			} else {
  2073 				$src = wp_mime_type_icon( $attachment->ID );
  2160 				$src            = wp_mime_type_icon( $attachment->ID );
  2074 				$width = 48;
  2161 				$width          = 48;
  2075 				$height = 64;
  2162 				$height         = 64;
  2076 				$track['image'] = compact( 'src', 'width', 'height' );
  2163 				$track['image'] = compact( 'src', 'width', 'height' );
  2077 				$track['thumb'] = compact( 'src', 'width', 'height' );
  2164 				$track['thumb'] = compact( 'src', 'width', 'height' );
  2078 			}
  2165 			}
  2079 		}
  2166 		}
  2080 
  2167 
  2081 		$tracks[] = $track;
  2168 		$tracks[] = $track;
  2082 	}
  2169 	}
  2083 	$data['tracks'] = $tracks;
  2170 	$data['tracks'] = $tracks;
  2084 
  2171 
  2085 	$safe_type = esc_attr( $atts['type'] );
  2172 	$safe_type  = esc_attr( $atts['type'] );
  2086 	$safe_style = esc_attr( $atts['style'] );
  2173 	$safe_style = esc_attr( $atts['style'] );
  2087 
  2174 
  2088 	ob_start();
  2175 	ob_start();
  2089 
  2176 
  2090 	if ( 1 === $instance ) {
  2177 	if ( 1 === $instance ) {
  2095 		 *
  2182 		 *
  2096 		 * @param string $type  Type of playlist. Possible values are 'audio' or 'video'.
  2183 		 * @param string $type  Type of playlist. Possible values are 'audio' or 'video'.
  2097 		 * @param string $style The 'theme' for the playlist. Core provides 'light' and 'dark'.
  2184 		 * @param string $style The 'theme' for the playlist. Core provides 'light' and 'dark'.
  2098 		 */
  2185 		 */
  2099 		do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] );
  2186 		do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] );
  2100 	} ?>
  2187 	}
  2101 <div class="wp-playlist wp-<?php echo $safe_type ?>-playlist wp-playlist-<?php echo $safe_style ?>">
  2188 	?>
  2102 	<?php if ( 'audio' === $atts['type'] ): ?>
  2189 <div class="wp-playlist wp-<?php echo $safe_type; ?>-playlist wp-playlist-<?php echo $safe_style; ?>">
       
  2190 	<?php if ( 'audio' === $atts['type'] ) : ?>
  2103 	<div class="wp-playlist-current-item"></div>
  2191 	<div class="wp-playlist-current-item"></div>
  2104 	<?php endif ?>
  2192 	<?php endif ?>
  2105 	<<?php echo $safe_type ?> controls="controls" preload="none" width="<?php
  2193 	<<?php echo $safe_type; ?> controls="controls" preload="none" width="
  2106 		echo (int) $theme_width;
  2194 				<?php
  2107 	?>"<?php if ( 'video' === $safe_type ):
  2195 				echo (int) $theme_width;
       
  2196 				?>
       
  2197 	"
       
  2198 	<?php
       
  2199 	if ( 'video' === $safe_type ) :
  2108 		echo ' height="', (int) $theme_height, '"';
  2200 		echo ' height="', (int) $theme_height, '"';
  2109 	endif; ?>></<?php echo $safe_type ?>>
  2201 	endif;
       
  2202 	?>
       
  2203 	></<?php echo $safe_type; ?>>
  2110 	<div class="wp-playlist-next"></div>
  2204 	<div class="wp-playlist-next"></div>
  2111 	<div class="wp-playlist-prev"></div>
  2205 	<div class="wp-playlist-prev"></div>
  2112 	<noscript>
  2206 	<noscript>
  2113 	<ol><?php
  2207 	<ol>
       
  2208 	<?php
  2114 	foreach ( $attachments as $att_id => $attachment ) {
  2209 	foreach ( $attachments as $att_id => $attachment ) {
  2115 		printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) );
  2210 		printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) );
  2116 	}
  2211 	}
  2117 	?></ol>
  2212 	?>
       
  2213 	</ol>
  2118 	</noscript>
  2214 	</noscript>
  2119 	<script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data ) ?></script>
  2215 	<script type="application/json" class="wp-playlist-script"><?php echo wp_json_encode( $data ); ?></script>
  2120 </div>
  2216 </div>
  2121 	<?php
  2217 	<?php
  2122 	return ob_get_clean();
  2218 	return ob_get_clean();
  2123 }
  2219 }
  2124 add_shortcode( 'playlist', 'wp_playlist_shortcode' );
  2220 add_shortcode( 'playlist', 'wp_playlist_shortcode' );
  2154 	/**
  2250 	/**
  2155 	 * Filters the list of supported audio formats.
  2251 	 * Filters the list of supported audio formats.
  2156 	 *
  2252 	 *
  2157 	 * @since 3.6.0
  2253 	 * @since 3.6.0
  2158 	 *
  2254 	 *
  2159 	 * @param array $extensions An array of support audio formats. Defaults are
  2255 	 * @param array $extensions An array of supported audio formats. Defaults are
  2160 	 *                          'mp3', 'ogg', 'flac', 'm4a', 'wav'.
  2256 	 *                          'mp3', 'ogg', 'flac', 'm4a', 'wav'.
  2161 	 */
  2257 	 */
  2162 	return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'flac', 'm4a', 'wav' ) );
  2258 	return apply_filters( 'wp_audio_extensions', array( 'mp3', 'ogg', 'flac', 'm4a', 'wav' ) );
  2163 }
  2259 }
  2164 
  2260 
  2172  * @return array Key/value pairs of field keys to labels.
  2268  * @return array Key/value pairs of field keys to labels.
  2173  */
  2269  */
  2174 function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) {
  2270 function wp_get_attachment_id3_keys( $attachment, $context = 'display' ) {
  2175 	$fields = array(
  2271 	$fields = array(
  2176 		'artist' => __( 'Artist' ),
  2272 		'artist' => __( 'Artist' ),
  2177 		'album' => __( 'Album' ),
  2273 		'album'  => __( 'Album' ),
  2178 	);
  2274 	);
  2179 
  2275 
  2180 	if ( 'display' === $context ) {
  2276 	if ( 'display' === $context ) {
  2181 		$fields['genre']            = __( 'Genre' );
  2277 		$fields['genre']            = __( 'Genre' );
  2182 		$fields['year']             = __( 'Year' );
  2278 		$fields['year']             = __( 'Year' );
  2183 		$fields['length_formatted'] = _x( 'Length', 'video or audio' );
  2279 		$fields['length_formatted'] = _x( 'Length', 'video or audio' );
  2184 	} elseif ( 'js' === $context ) {
  2280 	} elseif ( 'js' === $context ) {
  2185 		$fields['bitrate']          = __( 'Bitrate' );
  2281 		$fields['bitrate']      = __( 'Bitrate' );
  2186 		$fields['bitrate_mode']     = __( 'Bitrate Mode' );
  2282 		$fields['bitrate_mode'] = __( 'Bitrate Mode' );
  2187 	}
  2283 	}
  2188 
  2284 
  2189 	/**
  2285 	/**
  2190 	 * Filters the editable list of keys to look up data from an attachment's metadata.
  2286 	 * Filters the editable list of keys to look up data from an attachment's metadata.
  2191 	 *
  2287 	 *
  2250 		'src'      => '',
  2346 		'src'      => '',
  2251 		'loop'     => '',
  2347 		'loop'     => '',
  2252 		'autoplay' => '',
  2348 		'autoplay' => '',
  2253 		'preload'  => 'none',
  2349 		'preload'  => 'none',
  2254 		'class'    => 'wp-audio-shortcode',
  2350 		'class'    => 'wp-audio-shortcode',
  2255 		'style'    => 'width: 100%;'
  2351 		'style'    => 'width: 100%;',
  2256 	);
  2352 	);
  2257 	foreach ( $default_types as $type ) {
  2353 	foreach ( $default_types as $type ) {
  2258 		$defaults_atts[$type] = '';
  2354 		$defaults_atts[ $type ] = '';
  2259 	}
  2355 	}
  2260 
  2356 
  2261 	$atts = shortcode_atts( $defaults_atts, $attr, 'audio' );
  2357 	$atts = shortcode_atts( $defaults_atts, $attr, 'audio' );
  2262 
  2358 
  2263 	$primary = false;
  2359 	$primary = false;
  2283 		$audios = get_attached_media( 'audio', $post_id );
  2379 		$audios = get_attached_media( 'audio', $post_id );
  2284 		if ( empty( $audios ) ) {
  2380 		if ( empty( $audios ) ) {
  2285 			return;
  2381 			return;
  2286 		}
  2382 		}
  2287 
  2383 
  2288 		$audio = reset( $audios );
  2384 		$audio       = reset( $audios );
  2289 		$atts['src'] = wp_get_attachment_url( $audio->ID );
  2385 		$atts['src'] = wp_get_attachment_url( $audio->ID );
  2290 		if ( empty( $atts['src'] ) ) {
  2386 		if ( empty( $atts['src'] ) ) {
  2291 			return;
  2387 			return;
  2292 		}
  2388 		}
  2293 
  2389 
  2327 		'style'    => $atts['style'],
  2423 		'style'    => $atts['style'],
  2328 	);
  2424 	);
  2329 
  2425 
  2330 	// These ones should just be omitted altogether if they are blank
  2426 	// These ones should just be omitted altogether if they are blank
  2331 	foreach ( array( 'loop', 'autoplay', 'preload' ) as $a ) {
  2427 	foreach ( array( 'loop', 'autoplay', 'preload' ) as $a ) {
  2332 		if ( empty( $html_atts[$a] ) ) {
  2428 		if ( empty( $html_atts[ $a ] ) ) {
  2333 			unset( $html_atts[$a] );
  2429 			unset( $html_atts[ $a ] );
  2334 		}
  2430 		}
  2335 	}
  2431 	}
  2336 
  2432 
  2337 	$attr_strings = array();
  2433 	$attr_strings = array();
  2338 	foreach ( $html_atts as $k => $v ) {
  2434 	foreach ( $html_atts as $k => $v ) {
  2344 		$html .= "<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->\n";
  2440 		$html .= "<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->\n";
  2345 	}
  2441 	}
  2346 	$html .= sprintf( '<audio %s controls="controls">', join( ' ', $attr_strings ) );
  2442 	$html .= sprintf( '<audio %s controls="controls">', join( ' ', $attr_strings ) );
  2347 
  2443 
  2348 	$fileurl = '';
  2444 	$fileurl = '';
  2349 	$source = '<source type="%s" src="%s" />';
  2445 	$source  = '<source type="%s" src="%s" />';
  2350 	foreach ( $default_types as $fallback ) {
  2446 	foreach ( $default_types as $fallback ) {
  2351 		if ( ! empty( $atts[ $fallback ] ) ) {
  2447 		if ( ! empty( $atts[ $fallback ] ) ) {
  2352 			if ( empty( $fileurl ) ) {
  2448 			if ( empty( $fileurl ) ) {
  2353 				$fileurl = $atts[ $fallback ];
  2449 				$fileurl = $atts[ $fallback ];
  2354 			}
  2450 			}
  2355 			$type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
  2451 			$type  = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
  2356 			$url = add_query_arg( '_', $instance, $atts[ $fallback ] );
  2452 			$url   = add_query_arg( '_', $instance, $atts[ $fallback ] );
  2357 			$html .= sprintf( $source, $type['type'], esc_url( $url ) );
  2453 			$html .= sprintf( $source, $type['type'], esc_url( $url ) );
  2358 		}
  2454 		}
  2359 	}
  2455 	}
  2360 
  2456 
  2361 	if ( 'mediaelement' === $library ) {
  2457 	if ( 'mediaelement' === $library ) {
  2389 	/**
  2485 	/**
  2390 	 * Filters the list of supported video formats.
  2486 	 * Filters the list of supported video formats.
  2391 	 *
  2487 	 *
  2392 	 * @since 3.6.0
  2488 	 * @since 3.6.0
  2393 	 *
  2489 	 *
  2394 	 * @param array $extensions An array of support video formats. Defaults are
  2490 	 * @param array $extensions An array of supported video formats. Defaults are
  2395 	 *                          'mp4', 'm4v', 'webm', 'ogv', 'flv'.
  2491 	 *                          'mp4', 'm4v', 'webm', 'ogv', 'flv'.
  2396 	 */
  2492 	 */
  2397 	return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'flv' ) );
  2493 	return apply_filters( 'wp_video_extensions', array( 'mp4', 'm4v', 'webm', 'ogv', 'flv' ) );
  2398 }
  2494 }
  2399 
  2495 
  2465 		'height'   => 360,
  2561 		'height'   => 360,
  2466 		'class'    => 'wp-video-shortcode',
  2562 		'class'    => 'wp-video-shortcode',
  2467 	);
  2563 	);
  2468 
  2564 
  2469 	foreach ( $default_types as $type ) {
  2565 	foreach ( $default_types as $type ) {
  2470 		$defaults_atts[$type] = '';
  2566 		$defaults_atts[ $type ] = '';
  2471 	}
  2567 	}
  2472 
  2568 
  2473 	$atts = shortcode_atts( $defaults_atts, $attr, 'video' );
  2569 	$atts = shortcode_atts( $defaults_atts, $attr, 'video' );
  2474 
  2570 
  2475 	if ( is_admin() ) {
  2571 	if ( is_admin() ) {
  2476 		// shrink the video so it isn't huge in the admin
  2572 		// shrink the video so it isn't huge in the admin
  2477 		if ( $atts['width'] > $defaults_atts['width'] ) {
  2573 		if ( $atts['width'] > $defaults_atts['width'] ) {
  2478 			$atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] );
  2574 			$atts['height'] = round( ( $atts['height'] * $defaults_atts['width'] ) / $atts['width'] );
  2479 			$atts['width'] = $defaults_atts['width'];
  2575 			$atts['width']  = $defaults_atts['width'];
  2480 		}
  2576 		}
  2481 	} else {
  2577 	} else {
  2482 		// if the video is bigger than the theme
  2578 		// if the video is bigger than the theme
  2483 		if ( ! empty( $content_width ) && $atts['width'] > $content_width ) {
  2579 		if ( ! empty( $content_width ) && $atts['width'] > $content_width ) {
  2484 			$atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] );
  2580 			$atts['height'] = round( ( $atts['height'] * $content_width ) / $atts['width'] );
  2485 			$atts['width'] = $content_width;
  2581 			$atts['width']  = $content_width;
  2486 		}
  2582 		}
  2487 	}
  2583 	}
  2488 
  2584 
  2489 	$is_vimeo = $is_youtube = false;
  2585 	$is_vimeo      = $is_youtube = false;
  2490 	$yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
  2586 	$yt_pattern    = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#';
  2491 	$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
  2587 	$vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#';
  2492 
  2588 
  2493 	$primary = false;
  2589 	$primary = false;
  2494 	if ( ! empty( $atts['src'] ) ) {
  2590 	if ( ! empty( $atts['src'] ) ) {
  2495 		$is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) );
  2591 		$is_vimeo   = ( preg_match( $vimeo_pattern, $atts['src'] ) );
  2496 		$is_youtube = (  preg_match( $yt_pattern, $atts['src'] ) );
  2592 		$is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) );
  2497 		if ( ! $is_youtube && ! $is_vimeo ) {
  2593 		if ( ! $is_youtube && ! $is_vimeo ) {
  2498 			$type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
  2594 			$type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
  2499 			if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) {
  2595 			if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) {
  2500 				return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
  2596 				return sprintf( '<a class="wp-embedded-video" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
  2501 			}
  2597 			}
  2502 		}
  2598 		}
  2503 
  2599 
  2504 		if ( $is_vimeo ) {
  2600 		if ( $is_vimeo ) {
  2505 		    wp_enqueue_script( 'mediaelement-vimeo' );
  2601 			wp_enqueue_script( 'mediaelement-vimeo' );
  2506 		}
  2602 		}
  2507 
  2603 
  2508 		$primary = true;
  2604 		$primary = true;
  2509 		array_unshift( $default_types, 'src' );
  2605 		array_unshift( $default_types, 'src' );
  2510 	} else {
  2606 	} else {
  2522 		$videos = get_attached_media( 'video', $post_id );
  2618 		$videos = get_attached_media( 'video', $post_id );
  2523 		if ( empty( $videos ) ) {
  2619 		if ( empty( $videos ) ) {
  2524 			return;
  2620 			return;
  2525 		}
  2621 		}
  2526 
  2622 
  2527 		$video = reset( $videos );
  2623 		$video       = reset( $videos );
  2528 		$atts['src'] = wp_get_attachment_url( $video->ID );
  2624 		$atts['src'] = wp_get_attachment_url( $video->ID );
  2529 		if ( empty( $atts['src'] ) ) {
  2625 		if ( empty( $atts['src'] ) ) {
  2530 			return;
  2626 			return;
  2531 		}
  2627 		}
  2532 
  2628 
  2555 			$atts['src'] = remove_query_arg( 'feature', $atts['src'] );
  2651 			$atts['src'] = remove_query_arg( 'feature', $atts['src'] );
  2556 			$atts['src'] = set_url_scheme( $atts['src'], 'https' );
  2652 			$atts['src'] = set_url_scheme( $atts['src'], 'https' );
  2557 		} elseif ( $is_vimeo ) {
  2653 		} elseif ( $is_vimeo ) {
  2558 			// Remove all query arguments and force SSL - see #40866.
  2654 			// Remove all query arguments and force SSL - see #40866.
  2559 			$parsed_vimeo_url = wp_parse_url( $atts['src'] );
  2655 			$parsed_vimeo_url = wp_parse_url( $atts['src'] );
  2560 			$vimeo_src = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path'];
  2656 			$vimeo_src        = 'https://' . $parsed_vimeo_url['host'] . $parsed_vimeo_url['path'];
  2561 
  2657 
  2562 			// Add loop param for mejs bug - see #40977, not needed after #39686.
  2658 			// Add loop param for mejs bug - see #40977, not needed after #39686.
  2563 			$loop = $atts['loop'] ? '1' : '0';
  2659 			$loop        = $atts['loop'] ? '1' : '0';
  2564 			$atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src );
  2660 			$atts['src'] = add_query_arg( 'loop', $loop, $vimeo_src );
  2565 		}
  2661 		}
  2566 	}
  2662 	}
  2567 
  2663 
  2568 	/**
  2664 	/**
  2587 		'preload'  => $atts['preload'],
  2683 		'preload'  => $atts['preload'],
  2588 	);
  2684 	);
  2589 
  2685 
  2590 	// These ones should just be omitted altogether if they are blank
  2686 	// These ones should just be omitted altogether if they are blank
  2591 	foreach ( array( 'poster', 'loop', 'autoplay', 'preload' ) as $a ) {
  2687 	foreach ( array( 'poster', 'loop', 'autoplay', 'preload' ) as $a ) {
  2592 		if ( empty( $html_atts[$a] ) ) {
  2688 		if ( empty( $html_atts[ $a ] ) ) {
  2593 			unset( $html_atts[$a] );
  2689 			unset( $html_atts[ $a ] );
  2594 		}
  2690 		}
  2595 	}
  2691 	}
  2596 
  2692 
  2597 	$attr_strings = array();
  2693 	$attr_strings = array();
  2598 	foreach ( $html_atts as $k => $v ) {
  2694 	foreach ( $html_atts as $k => $v ) {
  2604 		$html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n";
  2700 		$html .= "<!--[if lt IE 9]><script>document.createElement('video');</script><![endif]-->\n";
  2605 	}
  2701 	}
  2606 	$html .= sprintf( '<video %s controls="controls">', join( ' ', $attr_strings ) );
  2702 	$html .= sprintf( '<video %s controls="controls">', join( ' ', $attr_strings ) );
  2607 
  2703 
  2608 	$fileurl = '';
  2704 	$fileurl = '';
  2609 	$source = '<source type="%s" src="%s" />';
  2705 	$source  = '<source type="%s" src="%s" />';
  2610 	foreach ( $default_types as $fallback ) {
  2706 	foreach ( $default_types as $fallback ) {
  2611 		if ( ! empty( $atts[ $fallback ] ) ) {
  2707 		if ( ! empty( $atts[ $fallback ] ) ) {
  2612 			if ( empty( $fileurl ) ) {
  2708 			if ( empty( $fileurl ) ) {
  2613 				$fileurl = $atts[ $fallback ];
  2709 				$fileurl = $atts[ $fallback ];
  2614 			}
  2710 			}
  2617 			} elseif ( 'src' === $fallback && $is_vimeo ) {
  2713 			} elseif ( 'src' === $fallback && $is_vimeo ) {
  2618 				$type = array( 'type' => 'video/vimeo' );
  2714 				$type = array( 'type' => 'video/vimeo' );
  2619 			} else {
  2715 			} else {
  2620 				$type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
  2716 				$type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
  2621 			}
  2717 			}
  2622 			$url = add_query_arg( '_', $instance, $atts[ $fallback ] );
  2718 			$url   = add_query_arg( '_', $instance, $atts[ $fallback ] );
  2623 			$html .= sprintf( $source, $type['type'], esc_url( $url ) );
  2719 			$html .= sprintf( $source, $type['type'], esc_url( $url ) );
  2624 		}
  2720 		}
  2625 	}
  2721 	}
  2626 
  2722 
  2627 	if ( ! empty( $content ) ) {
  2723 	if ( ! empty( $content ) ) {
  2668  *                           height values in pixels (in that order), 0, or 'none'. 0 or 'none' will
  2764  *                           height values in pixels (in that order), 0, or 'none'. 0 or 'none' will
  2669  *                           default to 'post_title' or `$text`. Default 'thumbnail'.
  2765  *                           default to 'post_title' or `$text`. Default 'thumbnail'.
  2670  * @param string       $text Optional. Link text. Default false.
  2766  * @param string       $text Optional. Link text. Default false.
  2671  */
  2767  */
  2672 function previous_image_link( $size = 'thumbnail', $text = false ) {
  2768 function previous_image_link( $size = 'thumbnail', $text = false ) {
  2673 	adjacent_image_link(true, $size, $text);
  2769 	adjacent_image_link( true, $size, $text );
  2674 }
  2770 }
  2675 
  2771 
  2676 /**
  2772 /**
  2677  * Displays next image link that has the same post parent.
  2773  * Displays next image link that has the same post parent.
  2678  *
  2774  *
  2684  *                           height values in pixels (in that order), 0, or 'none'. 0 or 'none' will
  2780  *                           height values in pixels (in that order), 0, or 'none'. 0 or 'none' will
  2685  *                           default to 'post_title' or `$text`. Default 'thumbnail'.
  2781  *                           default to 'post_title' or `$text`. Default 'thumbnail'.
  2686  * @param string       $text Optional. Link text. Default false.
  2782  * @param string       $text Optional. Link text. Default false.
  2687  */
  2783  */
  2688 function next_image_link( $size = 'thumbnail', $text = false ) {
  2784 function next_image_link( $size = 'thumbnail', $text = false ) {
  2689 	adjacent_image_link(false, $size, $text);
  2785 	adjacent_image_link( false, $size, $text );
  2690 }
  2786 }
  2691 
  2787 
  2692 /**
  2788 /**
  2693  * Displays next or previous image link that has the same post parent.
  2789  * Displays next or previous image link that has the same post parent.
  2694  *
  2790  *
  2700  * @param string|array $size Optional. Image size. Accepts any valid image size, or an array of width and height
  2796  * @param string|array $size Optional. Image size. Accepts any valid image size, or an array of width and height
  2701  *                           values in pixels (in that order). Default 'thumbnail'.
  2797  *                           values in pixels (in that order). Default 'thumbnail'.
  2702  * @param bool         $text Optional. Link text. Default false.
  2798  * @param bool         $text Optional. Link text. Default false.
  2703  */
  2799  */
  2704 function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) {
  2800 function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) {
  2705 	$post = get_post();
  2801 	$post        = get_post();
  2706 	$attachments = array_values( get_children( array( 'post_parent' => $post->post_parent, 'post_status' => 'inherit', 'post_type' => 'attachment', 'post_mime_type' => 'image', 'order' => 'ASC', 'orderby' => 'menu_order ID' ) ) );
  2802 	$attachments = array_values(
       
  2803 		get_children(
       
  2804 			array(
       
  2805 				'post_parent'    => $post->post_parent,
       
  2806 				'post_status'    => 'inherit',
       
  2807 				'post_type'      => 'attachment',
       
  2808 				'post_mime_type' => 'image',
       
  2809 				'order'          => 'ASC',
       
  2810 				'orderby'        => 'menu_order ID',
       
  2811 			)
       
  2812 		)
       
  2813 	);
  2707 
  2814 
  2708 	foreach ( $attachments as $k => $attachment ) {
  2815 	foreach ( $attachments as $k => $attachment ) {
  2709 		if ( $attachment->ID == $post->ID ) {
  2816 		if ( $attachment->ID == $post->ID ) {
  2710 			break;
  2817 			break;
  2711 		}
  2818 		}
  2712 	}
  2819 	}
  2713 
  2820 
  2714 	$output = '';
  2821 	$output        = '';
  2715 	$attachment_id = 0;
  2822 	$attachment_id = 0;
  2716 
  2823 
  2717 	if ( $attachments ) {
  2824 	if ( $attachments ) {
  2718 		$k = $prev ? $k - 1 : $k + 1;
  2825 		$k = $prev ? $k - 1 : $k + 1;
  2719 
  2826 
  2720 		if ( isset( $attachments[ $k ] ) ) {
  2827 		if ( isset( $attachments[ $k ] ) ) {
  2721 			$attachment_id = $attachments[ $k ]->ID;
  2828 			$attachment_id = $attachments[ $k ]->ID;
  2722 			$output = wp_get_attachment_link( $attachment_id, $size, true, false, $text );
  2829 			$output        = wp_get_attachment_link( $attachment_id, $size, true, false, $text );
  2723 		}
  2830 		}
  2724 	}
  2831 	}
  2725 
  2832 
  2726 	$adjacent = $prev ? 'previous' : 'next';
  2833 	$adjacent = $prev ? 'previous' : 'next';
  2727 
  2834 
  2757 	if ( is_int( $attachment ) ) {
  2864 	if ( is_int( $attachment ) ) {
  2758 		$attachment = get_post( $attachment );
  2865 		$attachment = get_post( $attachment );
  2759 	} elseif ( is_array( $attachment ) ) {
  2866 	} elseif ( is_array( $attachment ) ) {
  2760 		$attachment = (object) $attachment;
  2867 		$attachment = (object) $attachment;
  2761 	}
  2868 	}
  2762 	if ( ! is_object($attachment) )
  2869 	if ( ! is_object( $attachment ) ) {
  2763 		return array();
  2870 		return array();
  2764 
  2871 	}
  2765 	$file = get_attached_file( $attachment->ID );
  2872 
  2766 	$filename = basename( $file );
  2873 	$file     = get_attached_file( $attachment->ID );
  2767 
  2874 	$filename = wp_basename( $file );
  2768 	$objects = array('attachment');
  2875 
  2769 
  2876 	$objects = array( 'attachment' );
  2770 	if ( false !== strpos($filename, '.') )
  2877 
  2771 		$objects[] = 'attachment:' . substr($filename, strrpos($filename, '.') + 1);
  2878 	if ( false !== strpos( $filename, '.' ) ) {
  2772 	if ( !empty($attachment->post_mime_type) ) {
  2879 		$objects[] = 'attachment:' . substr( $filename, strrpos( $filename, '.' ) + 1 );
       
  2880 	}
       
  2881 	if ( ! empty( $attachment->post_mime_type ) ) {
  2773 		$objects[] = 'attachment:' . $attachment->post_mime_type;
  2882 		$objects[] = 'attachment:' . $attachment->post_mime_type;
  2774 		if ( false !== strpos($attachment->post_mime_type, '/') )
  2883 		if ( false !== strpos( $attachment->post_mime_type, '/' ) ) {
  2775 			foreach ( explode('/', $attachment->post_mime_type) as $token )
  2884 			foreach ( explode( '/', $attachment->post_mime_type ) as $token ) {
  2776 				if ( !empty($token) )
  2885 				if ( ! empty( $token ) ) {
  2777 					$objects[] = "attachment:$token";
  2886 					$objects[] = "attachment:$token";
       
  2887 				}
       
  2888 			}
       
  2889 		}
  2778 	}
  2890 	}
  2779 
  2891 
  2780 	$taxonomies = array();
  2892 	$taxonomies = array();
  2781 	foreach ( $objects as $object ) {
  2893 	foreach ( $objects as $object ) {
  2782 		if ( $taxes = get_object_taxonomies( $object, $output ) ) {
  2894 		if ( $taxes = get_object_taxonomies( $object, $output ) ) {
  2790 
  2902 
  2791 	return $taxonomies;
  2903 	return $taxonomies;
  2792 }
  2904 }
  2793 
  2905 
  2794 /**
  2906 /**
  2795  * Retrieves all of the taxonomy names that are registered for attachments.
  2907  * Retrieves all of the taxonomies that are registered for attachments.
  2796  *
  2908  *
  2797  * Handles mime-type-specific taxonomies such as attachment:image and attachment:video.
  2909  * Handles mime-type-specific taxonomies such as attachment:image and attachment:video.
  2798  *
  2910  *
  2799  * @since 3.5.0
  2911  * @since 3.5.0
  2800  *
       
  2801  * @see get_taxonomies()
  2912  * @see get_taxonomies()
  2802  *
  2913  *
  2803  * @param string $output Optional. The type of taxonomy output to return. Accepts 'names' or 'objects'.
  2914  * @param string $output Optional. The type of taxonomy output to return. Accepts 'names' or 'objects'.
  2804  *                       Default 'names'.
  2915  *                       Default 'names'.
  2805  * @return array The names of all taxonomy of $object_type.
  2916  * @return string[]|WP_Taxonomy[] Array of names or objects of registered taxonomies for attachments.
  2806  */
  2917  */
  2807 function get_taxonomies_for_attachments( $output = 'names' ) {
  2918 function get_taxonomies_for_attachments( $output = 'names' ) {
  2808 	$taxonomies = array();
  2919 	$taxonomies = array();
  2809 	foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) {
  2920 	foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) {
  2810 		foreach ( $taxonomy->object_type as $object_type ) {
  2921 		foreach ( $taxonomy->object_type as $object_type ) {
  2811 			if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) {
  2922 			if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) {
  2812 				if ( 'names' == $output )
  2923 				if ( 'names' == $output ) {
  2813 					$taxonomies[] = $taxonomy->name;
  2924 					$taxonomies[] = $taxonomy->name;
  2814 				else
  2925 				} else {
  2815 					$taxonomies[ $taxonomy->name ] = $taxonomy;
  2926 					$taxonomies[ $taxonomy->name ] = $taxonomy;
       
  2927 				}
  2816 				break;
  2928 				break;
  2817 			}
  2929 			}
  2818 		}
  2930 		}
  2819 	}
  2931 	}
  2820 
  2932 
  2830  *
  2942  *
  2831  * @param int $width  Image width in pixels.
  2943  * @param int $width  Image width in pixels.
  2832  * @param int $height Image height in pixels..
  2944  * @param int $height Image height in pixels..
  2833  * @return resource The GD image resource.
  2945  * @return resource The GD image resource.
  2834  */
  2946  */
  2835 function wp_imagecreatetruecolor($width, $height) {
  2947 function wp_imagecreatetruecolor( $width, $height ) {
  2836 	$img = imagecreatetruecolor($width, $height);
  2948 	$img = imagecreatetruecolor( $width, $height );
  2837 	if ( is_resource($img) && function_exists('imagealphablending') && function_exists('imagesavealpha') ) {
  2949 	if ( is_resource( $img ) && function_exists( 'imagealphablending' ) && function_exists( 'imagesavealpha' ) ) {
  2838 		imagealphablending($img, false);
  2950 		imagealphablending( $img, false );
  2839 		imagesavealpha($img, true);
  2951 		imagesavealpha( $img, true );
  2840 	}
  2952 	}
  2841 	return $img;
  2953 	return $img;
  2842 }
  2954 }
  2843 
  2955 
  2844 /**
  2956 /**
  2903 	if ( ! isset( $args['mime_type'] ) ) {
  3015 	if ( ! isset( $args['mime_type'] ) ) {
  2904 		$file_info = wp_check_filetype( $args['path'] );
  3016 		$file_info = wp_check_filetype( $args['path'] );
  2905 
  3017 
  2906 		// If $file_info['type'] is false, then we let the editor attempt to
  3018 		// If $file_info['type'] is false, then we let the editor attempt to
  2907 		// figure out the file type, rather than forcing a failure based on extension.
  3019 		// figure out the file type, rather than forcing a failure based on extension.
  2908 		if ( isset( $file_info ) && $file_info['type'] )
  3020 		if ( isset( $file_info ) && $file_info['type'] ) {
  2909 			$args['mime_type'] = $file_info['type'];
  3021 			$args['mime_type'] = $file_info['type'];
       
  3022 		}
  2910 	}
  3023 	}
  2911 
  3024 
  2912 	$implementation = _wp_image_editor_choose( $args );
  3025 	$implementation = _wp_image_editor_choose( $args );
  2913 
  3026 
  2914 	if ( $implementation ) {
  3027 	if ( $implementation ) {
  2915 		$editor = new $implementation( $path );
  3028 		$editor = new $implementation( $path );
  2916 		$loaded = $editor->load();
  3029 		$loaded = $editor->load();
  2917 
  3030 
  2918 		if ( is_wp_error( $loaded ) )
  3031 		if ( is_wp_error( $loaded ) ) {
  2919 			return $loaded;
  3032 			return $loaded;
       
  3033 		}
  2920 
  3034 
  2921 		return $editor;
  3035 		return $editor;
  2922 	}
  3036 	}
  2923 
  3037 
  2924 	return new WP_Error( 'image_no_editor', __('No editor could be selected.') );
  3038 	return new WP_Error( 'image_no_editor', __( 'No editor could be selected.' ) );
  2925 }
  3039 }
  2926 
  3040 
  2927 /**
  3041 /**
  2928  * Tests whether there is an editor that supports a given mime type or methods.
  3042  * Tests whether there is an editor that supports a given mime type or methods.
  2929  *
  3043  *
  2960 	 *                             'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'.
  3074 	 *                             'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD'.
  2961 	 */
  3075 	 */
  2962 	$implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
  3076 	$implementations = apply_filters( 'wp_image_editors', array( 'WP_Image_Editor_Imagick', 'WP_Image_Editor_GD' ) );
  2963 
  3077 
  2964 	foreach ( $implementations as $implementation ) {
  3078 	foreach ( $implementations as $implementation ) {
  2965 		if ( ! call_user_func( array( $implementation, 'test' ), $args ) )
  3079 		if ( ! call_user_func( array( $implementation, 'test' ), $args ) ) {
  2966 			continue;
  3080 			continue;
       
  3081 		}
  2967 
  3082 
  2968 		if ( isset( $args['mime_type'] ) &&
  3083 		if ( isset( $args['mime_type'] ) &&
  2969 			! call_user_func(
  3084 			! call_user_func(
  2970 				array( $implementation, 'supports_mime_type' ),
  3085 				array( $implementation, 'supports_mime_type' ),
  2971 				$args['mime_type'] ) ) {
  3086 				$args['mime_type']
       
  3087 			) ) {
  2972 			continue;
  3088 			continue;
  2973 		}
  3089 		}
  2974 
  3090 
  2975 		if ( isset( $args['methods'] ) &&
  3091 		if ( isset( $args['methods'] ) &&
  2976 			 array_diff( $args['methods'], get_class_methods( $implementation ) ) ) {
  3092 			array_diff( $args['methods'], get_class_methods( $implementation ) ) ) {
       
  3093 
  2977 			continue;
  3094 			continue;
  2978 		}
  3095 		}
  2979 
  3096 
  2980 		return $implementation;
  3097 		return $implementation;
  2981 	}
  3098 	}
  2990  */
  3107  */
  2991 function wp_plupload_default_settings() {
  3108 function wp_plupload_default_settings() {
  2992 	$wp_scripts = wp_scripts();
  3109 	$wp_scripts = wp_scripts();
  2993 
  3110 
  2994 	$data = $wp_scripts->get_data( 'wp-plupload', 'data' );
  3111 	$data = $wp_scripts->get_data( 'wp-plupload', 'data' );
  2995 	if ( $data && false !== strpos( $data, '_wpPluploadSettings' ) )
  3112 	if ( $data && false !== strpos( $data, '_wpPluploadSettings' ) ) {
  2996 		return;
  3113 		return;
  2997 
  3114 	}
  2998 	$max_upload_size = wp_max_upload_size();
  3115 
       
  3116 	$max_upload_size    = wp_max_upload_size();
  2999 	$allowed_extensions = array_keys( get_allowed_mime_types() );
  3117 	$allowed_extensions = array_keys( get_allowed_mime_types() );
  3000 	$extensions = array();
  3118 	$extensions         = array();
  3001 	foreach ( $allowed_extensions as $extension ) {
  3119 	foreach ( $allowed_extensions as $extension ) {
  3002 		$extensions = array_merge( $extensions, explode( '|', $extension ) );
  3120 		$extensions = array_merge( $extensions, explode( '|', $extension ) );
  3003 	}
  3121 	}
  3004 
  3122 
  3005 	/*
  3123 	/*
  3006 	 * Since 4.9 the `runtimes` setting is hardcoded in our version of Plupload to `html5,html4`,
  3124 	 * Since 4.9 the `runtimes` setting is hardcoded in our version of Plupload to `html5,html4`,
  3007 	 * and the `flash_swf_url` and `silverlight_xap_url` are not used.
  3125 	 * and the `flash_swf_url` and `silverlight_xap_url` are not used.
  3008 	 */
  3126 	 */
  3009 	$defaults = array(
  3127 	$defaults = array(
  3010 		'file_data_name'      => 'async-upload', // key passed to $_FILE.
  3128 		'file_data_name' => 'async-upload', // key passed to $_FILE.
  3011 		'url'                 => admin_url( 'async-upload.php', 'relative' ),
  3129 		'url'            => admin_url( 'async-upload.php', 'relative' ),
  3012 		'filters' => array(
  3130 		'filters'        => array(
  3013 			'max_file_size'   => $max_upload_size . 'b',
  3131 			'max_file_size' => $max_upload_size . 'b',
  3014 			'mime_types'      => array( array( 'extensions' => implode( ',', $extensions ) ) ),
  3132 			'mime_types'    => array( array( 'extensions' => implode( ',', $extensions ) ) ),
  3015 		),
  3133 		),
  3016 	);
  3134 	);
  3017 
  3135 
  3018 	// Currently only iOS Safari supports multiple files uploading but iOS 7.x has a bug that prevents uploading of videos
  3136 	// Currently only iOS Safari supports multiple files uploading but iOS 7.x has a bug that prevents uploading of videos
  3019 	// when enabled. See #29602.
  3137 	// when enabled. See #29602.
  3041 	 *
  3159 	 *
  3042 	 * @since 3.4.0
  3160 	 * @since 3.4.0
  3043 	 *
  3161 	 *
  3044 	 * @param array $params Default Plupload parameters array.
  3162 	 * @param array $params Default Plupload parameters array.
  3045 	 */
  3163 	 */
  3046 	$params = apply_filters( 'plupload_default_params', $params );
  3164 	$params                       = apply_filters( 'plupload_default_params', $params );
  3047 	$params['_wpnonce'] = wp_create_nonce( 'media-form' );
  3165 	$params['_wpnonce']           = wp_create_nonce( 'media-form' );
  3048 	$defaults['multipart_params'] = $params;
  3166 	$defaults['multipart_params'] = $params;
  3049 
  3167 
  3050 	$settings = array(
  3168 	$settings = array(
  3051 		'defaults' => $defaults,
  3169 		'defaults'      => $defaults,
  3052 		'browser'  => array(
  3170 		'browser'       => array(
  3053 			'mobile'    => wp_is_mobile(),
  3171 			'mobile'    => wp_is_mobile(),
  3054 			'supported' => _device_can_upload(),
  3172 			'supported' => _device_can_upload(),
  3055 		),
  3173 		),
  3056 		'limitExceeded' => is_multisite() && ! is_upload_space_available()
  3174 		'limitExceeded' => is_multisite() && ! is_upload_space_available(),
  3057 	);
  3175 	);
  3058 
  3176 
  3059 	$script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings ) . ';';
  3177 	$script = 'var _wpPluploadSettings = ' . wp_json_encode( $settings ) . ';';
  3060 
  3178 
  3061 	if ( $data )
  3179 	if ( $data ) {
  3062 		$script = "$data\n$script";
  3180 		$script = "$data\n$script";
       
  3181 	}
  3063 
  3182 
  3064 	$wp_scripts->add_data( 'wp-plupload', 'data', $script );
  3183 	$wp_scripts->add_data( 'wp-plupload', 'data', $script );
  3065 }
  3184 }
  3066 
  3185 
  3067 /**
  3186 /**
  3068  * Prepares an attachment post object for JS, where it is expected
  3187  * Prepares an attachment post object for JS, where it is expected
  3069  * to be JSON-encoded and fit into an Attachment model.
  3188  * to be JSON-encoded and fit into an Attachment model.
  3070  *
  3189  *
  3071  * @since 3.5.0
  3190  * @since 3.5.0
  3072  *
  3191  *
  3073  * @param mixed $attachment Attachment ID or object.
  3192  * @param int|WP_Post $attachment Attachment ID or object.
  3074  * @return array|void Array of attachment details.
  3193  * @return array|void Array of attachment details.
  3075  */
  3194  */
  3076 function wp_prepare_attachment_for_js( $attachment ) {
  3195 function wp_prepare_attachment_for_js( $attachment ) {
  3077 	if ( ! $attachment = get_post( $attachment ) )
  3196 	if ( ! $attachment = get_post( $attachment ) ) {
  3078 		return;
  3197 		return;
  3079 
  3198 	}
  3080 	if ( 'attachment' != $attachment->post_type )
  3199 
       
  3200 	if ( 'attachment' != $attachment->post_type ) {
  3081 		return;
  3201 		return;
       
  3202 	}
  3082 
  3203 
  3083 	$meta = wp_get_attachment_metadata( $attachment->ID );
  3204 	$meta = wp_get_attachment_metadata( $attachment->ID );
  3084 	if ( false !== strpos( $attachment->post_mime_type, '/' ) )
  3205 	if ( false !== strpos( $attachment->post_mime_type, '/' ) ) {
  3085 		list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
  3206 		list( $type, $subtype ) = explode( '/', $attachment->post_mime_type );
  3086 	else
  3207 	} else {
  3087 		list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
  3208 		list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
       
  3209 	}
  3088 
  3210 
  3089 	$attachment_url = wp_get_attachment_url( $attachment->ID );
  3211 	$attachment_url = wp_get_attachment_url( $attachment->ID );
  3090 	$base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
  3212 	$base_url       = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
  3091 
  3213 
  3092 	$response = array(
  3214 	$response = array(
  3093 		'id'          => $attachment->ID,
  3215 		'id'            => $attachment->ID,
  3094 		'title'       => $attachment->post_title,
  3216 		'title'         => $attachment->post_title,
  3095 		'filename'    => wp_basename( get_attached_file( $attachment->ID ) ),
  3217 		'filename'      => wp_basename( get_attached_file( $attachment->ID ) ),
  3096 		'url'         => $attachment_url,
  3218 		'url'           => $attachment_url,
  3097 		'link'        => get_attachment_link( $attachment->ID ),
  3219 		'link'          => get_attachment_link( $attachment->ID ),
  3098 		'alt'         => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
  3220 		'alt'           => get_post_meta( $attachment->ID, '_wp_attachment_image_alt', true ),
  3099 		'author'      => $attachment->post_author,
  3221 		'author'        => $attachment->post_author,
  3100 		'description' => $attachment->post_content,
  3222 		'description'   => $attachment->post_content,
  3101 		'caption'     => $attachment->post_excerpt,
  3223 		'caption'       => $attachment->post_excerpt,
  3102 		'name'        => $attachment->post_name,
  3224 		'name'          => $attachment->post_name,
  3103 		'status'      => $attachment->post_status,
  3225 		'status'        => $attachment->post_status,
  3104 		'uploadedTo'  => $attachment->post_parent,
  3226 		'uploadedTo'    => $attachment->post_parent,
  3105 		'date'        => strtotime( $attachment->post_date_gmt ) * 1000,
  3227 		'date'          => strtotime( $attachment->post_date_gmt ) * 1000,
  3106 		'modified'    => strtotime( $attachment->post_modified_gmt ) * 1000,
  3228 		'modified'      => strtotime( $attachment->post_modified_gmt ) * 1000,
  3107 		'menuOrder'   => $attachment->menu_order,
  3229 		'menuOrder'     => $attachment->menu_order,
  3108 		'mime'        => $attachment->post_mime_type,
  3230 		'mime'          => $attachment->post_mime_type,
  3109 		'type'        => $type,
  3231 		'type'          => $type,
  3110 		'subtype'     => $subtype,
  3232 		'subtype'       => $subtype,
  3111 		'icon'        => wp_mime_type_icon( $attachment->ID ),
  3233 		'icon'          => wp_mime_type_icon( $attachment->ID ),
  3112 		'dateFormatted' => mysql2date( __( 'F j, Y' ), $attachment->post_date ),
  3234 		'dateFormatted' => mysql2date( __( 'F j, Y' ), $attachment->post_date ),
  3113 		'nonces'      => array(
  3235 		'nonces'        => array(
  3114 			'update' => false,
  3236 			'update' => false,
  3115 			'delete' => false,
  3237 			'delete' => false,
  3116 			'edit'   => false
  3238 			'edit'   => false,
  3117 		),
  3239 		),
  3118 		'editLink'   => false,
  3240 		'editLink'      => false,
  3119 		'meta'       => false,
  3241 		'meta'          => false,
  3120 	);
  3242 	);
  3121 
  3243 
  3122 	$author = new WP_User( $attachment->post_author );
  3244 	$author = new WP_User( $attachment->post_author );
  3123 	if ( $author->exists() ) {
  3245 	if ( $author->exists() ) {
  3124 		$response['authorName'] = html_entity_decode( $author->display_name, ENT_QUOTES, get_bloginfo( 'charset' ) );
  3246 		$response['authorName'] = html_entity_decode( $author->display_name, ENT_QUOTES, get_bloginfo( 'charset' ) );
  3153 	} else {
  3275 	} else {
  3154 		$bytes = '';
  3276 		$bytes = '';
  3155 	}
  3277 	}
  3156 
  3278 
  3157 	if ( $bytes ) {
  3279 	if ( $bytes ) {
  3158 		$response['filesizeInBytes'] = $bytes;
  3280 		$response['filesizeInBytes']       = $bytes;
  3159 		$response['filesizeHumanReadable'] = size_format( $bytes );
  3281 		$response['filesizeHumanReadable'] = size_format( $bytes );
  3160 	}
  3282 	}
  3161 
  3283 
  3162 	$context = get_post_meta( $attachment->ID, '_wp_attachment_context', true );
  3284 	$context             = get_post_meta( $attachment->ID, '_wp_attachment_context', true );
  3163 	$response['context'] = ( $context ) ? $context : '';
  3285 	$response['context'] = ( $context ) ? $context : '';
  3164 
  3286 
  3165 	if ( current_user_can( 'edit_post', $attachment->ID ) ) {
  3287 	if ( current_user_can( 'edit_post', $attachment->ID ) ) {
  3166 		$response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
  3288 		$response['nonces']['update'] = wp_create_nonce( 'update-post_' . $attachment->ID );
  3167 		$response['nonces']['edit'] = wp_create_nonce( 'image_editor-' . $attachment->ID );
  3289 		$response['nonces']['edit']   = wp_create_nonce( 'image_editor-' . $attachment->ID );
  3168 		$response['editLink'] = get_edit_post_link( $attachment->ID, 'raw' );
  3290 		$response['editLink']         = get_edit_post_link( $attachment->ID, 'raw' );
  3169 	}
  3291 	}
  3170 
  3292 
  3171 	if ( current_user_can( 'delete_post', $attachment->ID ) )
  3293 	if ( current_user_can( 'delete_post', $attachment->ID ) ) {
  3172 		$response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
  3294 		$response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
       
  3295 	}
  3173 
  3296 
  3174 	if ( $meta && ( 'image' === $type || ! empty( $meta['sizes'] ) ) ) {
  3297 	if ( $meta && ( 'image' === $type || ! empty( $meta['sizes'] ) ) ) {
  3175 		$sizes = array();
  3298 		$sizes = array();
  3176 
  3299 
  3177 		/** This filter is documented in wp-admin/includes/media.php */
  3300 		/** This filter is documented in wp-admin/includes/media.php */
  3178 		$possible_sizes = apply_filters( 'image_size_names_choose', array(
  3301 		$possible_sizes = apply_filters(
  3179 			'thumbnail' => __('Thumbnail'),
  3302 			'image_size_names_choose',
  3180 			'medium'    => __('Medium'),
  3303 			array(
  3181 			'large'     => __('Large'),
  3304 				'thumbnail' => __( 'Thumbnail' ),
  3182 			'full'      => __('Full Size'),
  3305 				'medium'    => __( 'Medium' ),
  3183 		) );
  3306 				'large'     => __( 'Large' ),
       
  3307 				'full'      => __( 'Full Size' ),
       
  3308 			)
       
  3309 		);
  3184 		unset( $possible_sizes['full'] );
  3310 		unset( $possible_sizes['full'] );
  3185 
  3311 
  3186 		// Loop through all potential sizes that may be chosen. Try to do this with some efficiency.
  3312 		// Loop through all potential sizes that may be chosen. Try to do this with some efficiency.
  3187 		// First: run the image_downsize filter. If it returns something, we can use its data.
  3313 		// First: run the image_downsize filter. If it returns something, we can use its data.
  3188 		// If the filter does not return something, then image_downsize() is just an expensive
  3314 		// If the filter does not return something, then image_downsize() is just an expensive
  3220 
  3346 
  3221 		if ( 'image' === $type ) {
  3347 		if ( 'image' === $type ) {
  3222 			$sizes['full'] = array( 'url' => $attachment_url );
  3348 			$sizes['full'] = array( 'url' => $attachment_url );
  3223 
  3349 
  3224 			if ( isset( $meta['height'], $meta['width'] ) ) {
  3350 			if ( isset( $meta['height'], $meta['width'] ) ) {
  3225 				$sizes['full']['height'] = $meta['height'];
  3351 				$sizes['full']['height']      = $meta['height'];
  3226 				$sizes['full']['width'] = $meta['width'];
  3352 				$sizes['full']['width']       = $meta['width'];
  3227 				$sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
  3353 				$sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
  3228 			}
  3354 			}
  3229 
  3355 
  3230 			$response = array_merge( $response, $sizes['full'] );
  3356 			$response = array_merge( $response, $sizes['full'] );
  3231 		} elseif ( $meta['sizes']['full']['file'] ) {
  3357 		} elseif ( $meta['sizes']['full']['file'] ) {
  3232 			$sizes['full'] = array(
  3358 			$sizes['full'] = array(
  3233 				'url'         => $base_url . $meta['sizes']['full']['file'],
  3359 				'url'         => $base_url . $meta['sizes']['full']['file'],
  3234 				'height'      => $meta['sizes']['full']['height'],
  3360 				'height'      => $meta['sizes']['full']['height'],
  3235 				'width'       => $meta['sizes']['full']['width'],
  3361 				'width'       => $meta['sizes']['full']['width'],
  3236 				'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape'
  3362 				'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape',
  3237 			);
  3363 			);
  3238 		}
  3364 		}
  3239 
  3365 
  3240 		$response = array_merge( $response, array( 'sizes' => $sizes ) );
  3366 		$response = array_merge( $response, array( 'sizes' => $sizes ) );
  3241 	}
  3367 	}
  3242 
  3368 
  3243 	if ( $meta && 'video' === $type ) {
  3369 	if ( $meta && 'video' === $type ) {
  3244 		if ( isset( $meta['width'] ) )
  3370 		if ( isset( $meta['width'] ) ) {
  3245 			$response['width'] = (int) $meta['width'];
  3371 			$response['width'] = (int) $meta['width'];
  3246 		if ( isset( $meta['height'] ) )
  3372 		}
       
  3373 		if ( isset( $meta['height'] ) ) {
  3247 			$response['height'] = (int) $meta['height'];
  3374 			$response['height'] = (int) $meta['height'];
       
  3375 		}
  3248 	}
  3376 	}
  3249 
  3377 
  3250 	if ( $meta && ( 'audio' === $type || 'video' === $type ) ) {
  3378 	if ( $meta && ( 'audio' === $type || 'video' === $type ) ) {
  3251 		if ( isset( $meta['length_formatted'] ) )
  3379 		if ( isset( $meta['length_formatted'] ) ) {
  3252 			$response['fileLength'] = $meta['length_formatted'];
  3380 			$response['fileLength']              = $meta['length_formatted'];
       
  3381 			$response['fileLengthHumanReadable'] = human_readable_duration( $meta['length_formatted'] );
       
  3382 		}
  3253 
  3383 
  3254 		$response['meta'] = array();
  3384 		$response['meta'] = array();
  3255 		foreach ( wp_get_attachment_id3_keys( $attachment, 'js' ) as $key => $label ) {
  3385 		foreach ( wp_get_attachment_id3_keys( $attachment, 'js' ) as $key => $label ) {
  3256 			$response['meta'][ $key ] = false;
  3386 			$response['meta'][ $key ] = false;
  3257 
  3387 
  3261 		}
  3391 		}
  3262 
  3392 
  3263 		$id = get_post_thumbnail_id( $attachment->ID );
  3393 		$id = get_post_thumbnail_id( $attachment->ID );
  3264 		if ( ! empty( $id ) ) {
  3394 		if ( ! empty( $id ) ) {
  3265 			list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' );
  3395 			list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'full' );
  3266 			$response['image'] = compact( 'src', 'width', 'height' );
  3396 			$response['image']            = compact( 'src', 'width', 'height' );
  3267 			list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' );
  3397 			list( $src, $width, $height ) = wp_get_attachment_image_src( $id, 'thumbnail' );
  3268 			$response['thumb'] = compact( 'src', 'width', 'height' );
  3398 			$response['thumb']            = compact( 'src', 'width', 'height' );
  3269 		} else {
  3399 		} else {
  3270 			$src = wp_mime_type_icon( $attachment->ID );
  3400 			$src               = wp_mime_type_icon( $attachment->ID );
  3271 			$width = 48;
  3401 			$width             = 48;
  3272 			$height = 64;
  3402 			$height            = 64;
  3273 			$response['image'] = compact( 'src', 'width', 'height' );
  3403 			$response['image'] = compact( 'src', 'width', 'height' );
  3274 			$response['thumb'] = compact( 'src', 'width', 'height' );
  3404 			$response['thumb'] = compact( 'src', 'width', 'height' );
  3275 		}
  3405 		}
  3276 	}
  3406 	}
  3277 
  3407 
  3278 	if ( function_exists('get_compat_media_markup') )
  3408 	if ( function_exists( 'get_compat_media_markup' ) ) {
  3279 		$response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) );
  3409 		$response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) );
       
  3410 	}
  3280 
  3411 
  3281 	/**
  3412 	/**
  3282 	 * Filters the attachment data prepared for JavaScript.
  3413 	 * Filters the attachment data prepared for JavaScript.
  3283 	 *
  3414 	 *
  3284 	 * @since 3.5.0
  3415 	 * @since 3.5.0
  3285 	 *
  3416 	 *
  3286 	 * @param array      $response   Array of prepared attachment data.
  3417 	 * @param array       $response   Array of prepared attachment data.
  3287 	 * @param int|object $attachment Attachment ID or object.
  3418 	 * @param WP_Post     $attachment Attachment object.
  3288 	 * @param array      $meta       Array of attachment meta data.
  3419 	 * @param array|false $meta       Array of attachment meta data, or false if there is none.
  3289 	 */
  3420 	 */
  3290 	return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta );
  3421 	return apply_filters( 'wp_prepare_attachment_for_js', $response, $attachment, $meta );
  3291 }
  3422 }
  3292 
  3423 
  3293 /**
  3424 /**
  3306  *     @type int|WP_Post A post object or ID.
  3437  *     @type int|WP_Post A post object or ID.
  3307  * }
  3438  * }
  3308  */
  3439  */
  3309 function wp_enqueue_media( $args = array() ) {
  3440 function wp_enqueue_media( $args = array() ) {
  3310 	// Enqueue me just once per page, please.
  3441 	// Enqueue me just once per page, please.
  3311 	if ( did_action( 'wp_enqueue_media' ) )
  3442 	if ( did_action( 'wp_enqueue_media' ) ) {
  3312 		return;
  3443 		return;
       
  3444 	}
  3313 
  3445 
  3314 	global $content_width, $wpdb, $wp_locale;
  3446 	global $content_width, $wpdb, $wp_locale;
  3315 
  3447 
  3316 	$defaults = array(
  3448 	$defaults = array(
  3317 		'post' => null,
  3449 		'post' => null,
  3318 	);
  3450 	);
  3319 	$args = wp_parse_args( $args, $defaults );
  3451 	$args     = wp_parse_args( $args, $defaults );
  3320 
  3452 
  3321 	// We're going to pass the old thickbox media tabs to `media_upload_tabs`
  3453 	// We're going to pass the old thickbox media tabs to `media_upload_tabs`
  3322 	// to ensure plugins will work. We will then unset those tabs.
  3454 	// to ensure plugins will work. We will then unset those tabs.
  3323 	$tabs = array(
  3455 	$tabs = array(
  3324 		// handler action suffix => tab label
  3456 		// handler action suffix => tab label
  3336 		'link'  => get_option( 'image_default_link_type' ), // db default is 'file'
  3468 		'link'  => get_option( 'image_default_link_type' ), // db default is 'file'
  3337 		'align' => get_option( 'image_default_align' ), // empty default
  3469 		'align' => get_option( 'image_default_align' ), // empty default
  3338 		'size'  => get_option( 'image_default_size' ),  // empty default
  3470 		'size'  => get_option( 'image_default_size' ),  // empty default
  3339 	);
  3471 	);
  3340 
  3472 
  3341 	$exts = array_merge( wp_get_audio_extensions(), wp_get_video_extensions() );
  3473 	$exts      = array_merge( wp_get_audio_extensions(), wp_get_video_extensions() );
  3342 	$mimes = get_allowed_mime_types();
  3474 	$mimes     = get_allowed_mime_types();
  3343 	$ext_mimes = array();
  3475 	$ext_mimes = array();
  3344 	foreach ( $exts as $ext ) {
  3476 	foreach ( $exts as $ext ) {
  3345 		foreach ( $mimes as $ext_preg => $mime_match ) {
  3477 		foreach ( $mimes as $ext_preg => $mime_match ) {
  3346 			if ( preg_match( '#' . $ext . '#i', $ext_preg ) ) {
  3478 			if ( preg_match( '#' . $ext . '#i', $ext_preg ) ) {
  3347 				$ext_mimes[ $ext ] = $mime_match;
  3479 				$ext_mimes[ $ext ] = $mime_match;
  3367 	 * @param bool|null Whether to show the button, or `null` to decide based
  3499 	 * @param bool|null Whether to show the button, or `null` to decide based
  3368 	 *                  on whether any audio files exist in the media library.
  3500 	 *                  on whether any audio files exist in the media library.
  3369 	 */
  3501 	 */
  3370 	$show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true );
  3502 	$show_audio_playlist = apply_filters( 'media_library_show_audio_playlist', true );
  3371 	if ( null === $show_audio_playlist ) {
  3503 	if ( null === $show_audio_playlist ) {
  3372 		$show_audio_playlist = $wpdb->get_var( "
  3504 		$show_audio_playlist = $wpdb->get_var(
       
  3505 			"
  3373 			SELECT ID
  3506 			SELECT ID
  3374 			FROM $wpdb->posts
  3507 			FROM $wpdb->posts
  3375 			WHERE post_type = 'attachment'
  3508 			WHERE post_type = 'attachment'
  3376 			AND post_mime_type LIKE 'audio%'
  3509 			AND post_mime_type LIKE 'audio%'
  3377 			LIMIT 1
  3510 			LIMIT 1
  3378 		" );
  3511 		"
       
  3512 		);
  3379 	}
  3513 	}
  3380 
  3514 
  3381 	/**
  3515 	/**
  3382 	 * Allows showing or hiding the "Create Video Playlist" button in the media library.
  3516 	 * Allows showing or hiding the "Create Video Playlist" button in the media library.
  3383 	 *
  3517 	 *
  3395 	 * @param bool|null Whether to show the button, or `null` to decide based
  3529 	 * @param bool|null Whether to show the button, or `null` to decide based
  3396 	 *                  on whether any video files exist in the media library.
  3530 	 *                  on whether any video files exist in the media library.
  3397 	 */
  3531 	 */
  3398 	$show_video_playlist = apply_filters( 'media_library_show_video_playlist', true );
  3532 	$show_video_playlist = apply_filters( 'media_library_show_video_playlist', true );
  3399 	if ( null === $show_video_playlist ) {
  3533 	if ( null === $show_video_playlist ) {
  3400 		$show_video_playlist = $wpdb->get_var( "
  3534 		$show_video_playlist = $wpdb->get_var(
       
  3535 			"
  3401 			SELECT ID
  3536 			SELECT ID
  3402 			FROM $wpdb->posts
  3537 			FROM $wpdb->posts
  3403 			WHERE post_type = 'attachment'
  3538 			WHERE post_type = 'attachment'
  3404 			AND post_mime_type LIKE 'video%'
  3539 			AND post_mime_type LIKE 'video%'
  3405 			LIMIT 1
  3540 			LIMIT 1
  3406 		" );
  3541 		"
       
  3542 		);
  3407 	}
  3543 	}
  3408 
  3544 
  3409 	/**
  3545 	/**
  3410 	 * Allows overriding the list of months displayed in the media library.
  3546 	 * Allows overriding the list of months displayed in the media library.
  3411 	 *
  3547 	 *
  3422 	 *                   properties, or `null` (or any other non-array value)
  3558 	 *                   properties, or `null` (or any other non-array value)
  3423 	 *                   for default behavior.
  3559 	 *                   for default behavior.
  3424 	 */
  3560 	 */
  3425 	$months = apply_filters( 'media_library_months_with_files', null );
  3561 	$months = apply_filters( 'media_library_months_with_files', null );
  3426 	if ( ! is_array( $months ) ) {
  3562 	if ( ! is_array( $months ) ) {
  3427 		$months = $wpdb->get_results( $wpdb->prepare( "
  3563 		$months = $wpdb->get_results(
       
  3564 			$wpdb->prepare(
       
  3565 				"
  3428 			SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
  3566 			SELECT DISTINCT YEAR( post_date ) AS year, MONTH( post_date ) AS month
  3429 			FROM $wpdb->posts
  3567 			FROM $wpdb->posts
  3430 			WHERE post_type = %s
  3568 			WHERE post_type = %s
  3431 			ORDER BY post_date DESC
  3569 			ORDER BY post_date DESC
  3432 		", 'attachment' ) );
  3570 		",
       
  3571 				'attachment'
       
  3572 			)
       
  3573 		);
  3433 	}
  3574 	}
  3434 	foreach ( $months as $month_year ) {
  3575 	foreach ( $months as $month_year ) {
  3435 		$month_year->text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month_year->month ), $month_year->year );
  3576 		$month_year->text = sprintf( __( '%1$s %2$d' ), $wp_locale->get_month( $month_year->month ), $month_year->year );
  3436 	}
  3577 	}
  3437 
  3578 
  3438 	$settings = array(
  3579 	$settings = array(
  3439 		'tabs'      => $tabs,
  3580 		'tabs'             => $tabs,
  3440 		'tabUrl'    => add_query_arg( array( 'chromeless' => true ), admin_url('media-upload.php') ),
  3581 		'tabUrl'           => add_query_arg( array( 'chromeless' => true ), admin_url( 'media-upload.php' ) ),
  3441 		'mimeTypes' => wp_list_pluck( get_post_mime_types(), 0 ),
  3582 		'mimeTypes'        => wp_list_pluck( get_post_mime_types(), 0 ),
  3442 		/** This filter is documented in wp-admin/includes/media.php */
  3583 		/** This filter is documented in wp-admin/includes/media.php */
  3443 		'captions'  => ! apply_filters( 'disable_captions', '' ),
  3584 		'captions'         => ! apply_filters( 'disable_captions', '' ),
  3444 		'nonce'     => array(
  3585 		'nonce'            => array(
  3445 			'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
  3586 			'sendToEditor' => wp_create_nonce( 'media-send-to-editor' ),
  3446 		),
  3587 		),
  3447 		'post'    => array(
  3588 		'post'             => array(
  3448 			'id' => 0,
  3589 			'id' => 0,
  3449 		),
  3590 		),
  3450 		'defaultProps' => $props,
  3591 		'defaultProps'     => $props,
  3451 		'attachmentCounts' => array(
  3592 		'attachmentCounts' => array(
  3452 			'audio' => ( $show_audio_playlist ) ? 1 : 0,
  3593 			'audio' => ( $show_audio_playlist ) ? 1 : 0,
  3453 			'video' => ( $show_video_playlist ) ? 1 : 0,
  3594 			'video' => ( $show_video_playlist ) ? 1 : 0,
  3454 		),
  3595 		),
  3455 		'oEmbedProxyUrl' => rest_url( 'oembed/1.0/proxy' ),
  3596 		'oEmbedProxyUrl'   => rest_url( 'oembed/1.0/proxy' ),
  3456 		'embedExts'    => $exts,
  3597 		'embedExts'        => $exts,
  3457 		'embedMimes'   => $ext_mimes,
  3598 		'embedMimes'       => $ext_mimes,
  3458 		'contentWidth' => $content_width,
  3599 		'contentWidth'     => $content_width,
  3459 		'months'       => $months,
  3600 		'months'           => $months,
  3460 		'mediaTrash'   => MEDIA_TRASH ? 1 : 0,
  3601 		'mediaTrash'       => MEDIA_TRASH ? 1 : 0,
  3461 	);
  3602 	);
  3462 
  3603 
  3463 	$post = null;
  3604 	$post = null;
  3464 	if ( isset( $args['post'] ) ) {
  3605 	if ( isset( $args['post'] ) ) {
  3465 		$post = get_post( $args['post'] );
  3606 		$post             = get_post( $args['post'] );
  3466 		$settings['post'] = array(
  3607 		$settings['post'] = array(
  3467 			'id' => $post->ID,
  3608 			'id'    => $post->ID,
  3468 			'nonce' => wp_create_nonce( 'update-post_' . $post->ID ),
  3609 			'nonce' => wp_create_nonce( 'update-post_' . $post->ID ),
  3469 		);
  3610 		);
  3470 
  3611 
  3471 		$thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' );
  3612 		$thumbnail_support = current_theme_supports( 'post-thumbnails', $post->post_type ) && post_type_supports( $post->post_type, 'thumbnail' );
  3472 		if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) {
  3613 		if ( ! $thumbnail_support && 'attachment' === $post->post_type && $post->post_mime_type ) {
  3476 				$thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
  3617 				$thumbnail_support = post_type_supports( 'attachment:video', 'thumbnail' ) || current_theme_supports( 'post-thumbnails', 'attachment:video' );
  3477 			}
  3618 			}
  3478 		}
  3619 		}
  3479 
  3620 
  3480 		if ( $thumbnail_support ) {
  3621 		if ( $thumbnail_support ) {
  3481 			$featured_image_id = get_post_meta( $post->ID, '_thumbnail_id', true );
  3622 			$featured_image_id                   = get_post_meta( $post->ID, '_thumbnail_id', true );
  3482 			$settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1;
  3623 			$settings['post']['featuredImageId'] = $featured_image_id ? $featured_image_id : -1;
  3483 		}
  3624 		}
  3484 	}
  3625 	}
  3485 
  3626 
  3486 	if ( $post ) {
  3627 	if ( $post ) {
  3489 		$post_type_object = get_post_type_object( 'post' );
  3630 		$post_type_object = get_post_type_object( 'post' );
  3490 	}
  3631 	}
  3491 
  3632 
  3492 	$strings = array(
  3633 	$strings = array(
  3493 		// Generic
  3634 		// Generic
  3494 		'url'         => __( 'URL' ),
  3635 		'url'                         => __( 'URL' ),
  3495 		'addMedia'    => __( 'Add Media' ),
  3636 		'addMedia'                    => __( 'Add Media' ),
  3496 		'search'      => __( 'Search' ),
  3637 		'search'                      => __( 'Search' ),
  3497 		'select'      => __( 'Select' ),
  3638 		'select'                      => __( 'Select' ),
  3498 		'cancel'      => __( 'Cancel' ),
  3639 		'cancel'                      => __( 'Cancel' ),
  3499 		'update'      => __( 'Update' ),
  3640 		'update'                      => __( 'Update' ),
  3500 		'replace'     => __( 'Replace' ),
  3641 		'replace'                     => __( 'Replace' ),
  3501 		'remove'      => __( 'Remove' ),
  3642 		'remove'                      => __( 'Remove' ),
  3502 		'back'        => __( 'Back' ),
  3643 		'back'                        => __( 'Back' ),
  3503 		/* translators: This is a would-be plural string used in the media manager.
  3644 		/*
  3504 		   If there is not a word you can use in your language to avoid issues with the
  3645 		 * translators: This is a would-be plural string used in the media manager.
  3505 		   lack of plural support here, turn it into "selected: %d" then translate it.
  3646 		 * If there is not a word you can use in your language to avoid issues with the
       
  3647 		 * lack of plural support here, turn it into "selected: %d" then translate it.
  3506 		 */
  3648 		 */
  3507 		'selected'    => __( '%d selected' ),
  3649 		'selected'                    => __( '%d selected' ),
  3508 		'dragInfo'    => __( 'Drag and drop to reorder media files.' ),
  3650 		'dragInfo'                    => __( 'Drag and drop to reorder media files.' ),
  3509 
  3651 
  3510 		// Upload
  3652 		// Upload
  3511 		'uploadFilesTitle'  => __( 'Upload Files' ),
  3653 		'uploadFilesTitle'            => __( 'Upload Files' ),
  3512 		'uploadImagesTitle' => __( 'Upload Images' ),
  3654 		'uploadImagesTitle'           => __( 'Upload Images' ),
  3513 
  3655 
  3514 		// Library
  3656 		// Library
  3515 		'mediaLibraryTitle'      => __( 'Media Library' ),
  3657 		'mediaLibraryTitle'           => __( 'Media Library' ),
  3516 		'insertMediaTitle'       => __( 'Add Media' ),
  3658 		'insertMediaTitle'            => __( 'Add Media' ),
  3517 		'createNewGallery'       => __( 'Create a new gallery' ),
  3659 		'createNewGallery'            => __( 'Create a new gallery' ),
  3518 		'createNewPlaylist'      => __( 'Create a new playlist' ),
  3660 		'createNewPlaylist'           => __( 'Create a new playlist' ),
  3519 		'createNewVideoPlaylist' => __( 'Create a new video playlist' ),
  3661 		'createNewVideoPlaylist'      => __( 'Create a new video playlist' ),
  3520 		'returnToLibrary'        => __( '&#8592; Return to library' ),
  3662 		'returnToLibrary'             => __( '&#8592; Return to library' ),
  3521 		'allMediaItems'          => __( 'All media items' ),
  3663 		'allMediaItems'               => __( 'All media items' ),
  3522 		'allDates'               => __( 'All dates' ),
  3664 		'allDates'                    => __( 'All dates' ),
  3523 		'noItemsFound'           => __( 'No items found.' ),
  3665 		'noItemsFound'                => __( 'No items found.' ),
  3524 		'insertIntoPost'         => $post_type_object->labels->insert_into_item,
  3666 		'insertIntoPost'              => $post_type_object->labels->insert_into_item,
  3525 		'unattached'             => __( 'Unattached' ),
  3667 		'unattached'                  => __( 'Unattached' ),
  3526 		'mine'                   => _x( 'Mine', 'media items' ),
  3668 		'mine'                        => _x( 'Mine', 'media items' ),
  3527 		'trash'                  => _x( 'Trash', 'noun' ),
  3669 		'trash'                       => _x( 'Trash', 'noun' ),
  3528 		'uploadedToThisPost'     => $post_type_object->labels->uploaded_to_this_item,
  3670 		'uploadedToThisPost'          => $post_type_object->labels->uploaded_to_this_item,
  3529 		'warnDelete'             => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  3671 		'warnDelete'                  => __( "You are about to permanently delete this item from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  3530 		'warnBulkDelete'         => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  3672 		'warnBulkDelete'              => __( "You are about to permanently delete these items from your site.\nThis action cannot be undone.\n 'Cancel' to stop, 'OK' to delete." ),
  3531 		'warnBulkTrash'          => __( "You are about to trash these items.\n  'Cancel' to stop, 'OK' to delete." ),
  3673 		'warnBulkTrash'               => __( "You are about to trash these items.\n  'Cancel' to stop, 'OK' to delete." ),
  3532 		'bulkSelect'             => __( 'Bulk Select' ),
  3674 		'bulkSelect'                  => __( 'Bulk Select' ),
  3533 		'cancelSelection'        => __( 'Cancel Selection' ),
  3675 		'trashSelected'               => __( 'Move to Trash' ),
  3534 		'trashSelected'          => __( 'Trash Selected' ),
  3676 		'restoreSelected'             => __( 'Restore from Trash' ),
  3535 		'untrashSelected'        => __( 'Untrash Selected' ),
  3677 		'deletePermanently'           => __( 'Delete Permanently' ),
  3536 		'deleteSelected'         => __( 'Delete Selected' ),
  3678 		'apply'                       => __( 'Apply' ),
  3537 		'deletePermanently'      => __( 'Delete Permanently' ),
  3679 		'filterByDate'                => __( 'Filter by date' ),
  3538 		'apply'                  => __( 'Apply' ),
  3680 		'filterByType'                => __( 'Filter by type' ),
  3539 		'filterByDate'           => __( 'Filter by date' ),
  3681 		'searchMediaLabel'            => __( 'Search Media' ),
  3540 		'filterByType'           => __( 'Filter by type' ),
  3682 		'searchMediaPlaceholder'      => __( 'Search media items...' ), // placeholder (no ellipsis)
  3541 		'searchMediaLabel'       => __( 'Search Media' ),
  3683 		'noMedia'                     => __( 'No media files found.' ),
  3542 		'searchMediaPlaceholder' => __( 'Search media items...' ), // placeholder (no ellipsis)
       
  3543 		'noMedia'                => __( 'No media files found.' ),
       
  3544 
  3684 
  3545 		// Library Details
  3685 		// Library Details
  3546 		'attachmentDetails'  => __( 'Attachment Details' ),
  3686 		'attachmentDetails'           => __( 'Attachment Details' ),
  3547 
  3687 
  3548 		// From URL
  3688 		// From URL
  3549 		'insertFromUrlTitle' => __( 'Insert from URL' ),
  3689 		'insertFromUrlTitle'          => __( 'Insert from URL' ),
  3550 
  3690 
  3551 		// Featured Images
  3691 		// Featured Images
  3552 		'setFeaturedImageTitle' => $post_type_object->labels->featured_image,
  3692 		'setFeaturedImageTitle'       => $post_type_object->labels->featured_image,
  3553 		'setFeaturedImage'      => $post_type_object->labels->set_featured_image,
  3693 		'setFeaturedImage'            => $post_type_object->labels->set_featured_image,
  3554 
  3694 
  3555 		// Gallery
  3695 		// Gallery
  3556 		'createGalleryTitle' => __( 'Create Gallery' ),
  3696 		'createGalleryTitle'          => __( 'Create Gallery' ),
  3557 		'editGalleryTitle'   => __( 'Edit Gallery' ),
  3697 		'editGalleryTitle'            => __( 'Edit Gallery' ),
  3558 		'cancelGalleryTitle' => __( '&#8592; Cancel Gallery' ),
  3698 		'cancelGalleryTitle'          => __( '&#8592; Cancel Gallery' ),
  3559 		'insertGallery'      => __( 'Insert gallery' ),
  3699 		'insertGallery'               => __( 'Insert gallery' ),
  3560 		'updateGallery'      => __( 'Update gallery' ),
  3700 		'updateGallery'               => __( 'Update gallery' ),
  3561 		'addToGallery'       => __( 'Add to gallery' ),
  3701 		'addToGallery'                => __( 'Add to gallery' ),
  3562 		'addToGalleryTitle'  => __( 'Add to Gallery' ),
  3702 		'addToGalleryTitle'           => __( 'Add to Gallery' ),
  3563 		'reverseOrder'       => __( 'Reverse order' ),
  3703 		'reverseOrder'                => __( 'Reverse order' ),
  3564 
  3704 
  3565 		// Edit Image
  3705 		// Edit Image
  3566 		'imageDetailsTitle'     => __( 'Image Details' ),
  3706 		'imageDetailsTitle'           => __( 'Image Details' ),
  3567 		'imageReplaceTitle'     => __( 'Replace Image' ),
  3707 		'imageReplaceTitle'           => __( 'Replace Image' ),
  3568 		'imageDetailsCancel'    => __( 'Cancel Edit' ),
  3708 		'imageDetailsCancel'          => __( 'Cancel Edit' ),
  3569 		'editImage'             => __( 'Edit Image' ),
  3709 		'editImage'                   => __( 'Edit Image' ),
  3570 
  3710 
  3571 		// Crop Image
  3711 		// Crop Image
  3572 		'chooseImage' => __( 'Choose Image' ),
  3712 		'chooseImage'                 => __( 'Choose Image' ),
  3573 		'selectAndCrop' => __( 'Select and Crop' ),
  3713 		'selectAndCrop'               => __( 'Select and Crop' ),
  3574 		'skipCropping' => __( 'Skip Cropping' ),
  3714 		'skipCropping'                => __( 'Skip Cropping' ),
  3575 		'cropImage' => __( 'Crop Image' ),
  3715 		'cropImage'                   => __( 'Crop Image' ),
  3576 		'cropYourImage' => __( 'Crop your image' ),
  3716 		'cropYourImage'               => __( 'Crop your image' ),
  3577 		'cropping' => __( 'Cropping&hellip;' ),
  3717 		'cropping'                    => __( 'Cropping&hellip;' ),
  3578 		/* translators: 1: suggested width number, 2: suggested height number. */
  3718 		/* translators: 1: suggested width number, 2: suggested height number. */
  3579 		'suggestedDimensions' => __( 'Suggested image dimensions: %1$s by %2$s pixels.' ),
  3719 		'suggestedDimensions'         => __( 'Suggested image dimensions: %1$s by %2$s pixels.' ),
  3580 		'cropError' => __( 'There has been an error cropping your image.' ),
  3720 		'cropError'                   => __( 'There has been an error cropping your image.' ),
  3581 
  3721 
  3582 		// Edit Audio
  3722 		// Edit Audio
  3583 		'audioDetailsTitle'     => __( 'Audio Details' ),
  3723 		'audioDetailsTitle'           => __( 'Audio Details' ),
  3584 		'audioReplaceTitle'     => __( 'Replace Audio' ),
  3724 		'audioReplaceTitle'           => __( 'Replace Audio' ),
  3585 		'audioAddSourceTitle'   => __( 'Add Audio Source' ),
  3725 		'audioAddSourceTitle'         => __( 'Add Audio Source' ),
  3586 		'audioDetailsCancel'    => __( 'Cancel Edit' ),
  3726 		'audioDetailsCancel'          => __( 'Cancel Edit' ),
  3587 
  3727 
  3588 		// Edit Video
  3728 		// Edit Video
  3589 		'videoDetailsTitle'     => __( 'Video Details' ),
  3729 		'videoDetailsTitle'           => __( 'Video Details' ),
  3590 		'videoReplaceTitle'     => __( 'Replace Video' ),
  3730 		'videoReplaceTitle'           => __( 'Replace Video' ),
  3591 		'videoAddSourceTitle'   => __( 'Add Video Source' ),
  3731 		'videoAddSourceTitle'         => __( 'Add Video Source' ),
  3592 		'videoDetailsCancel'    => __( 'Cancel Edit' ),
  3732 		'videoDetailsCancel'          => __( 'Cancel Edit' ),
  3593 		'videoSelectPosterImageTitle' => __( 'Select Poster Image' ),
  3733 		'videoSelectPosterImageTitle' => __( 'Select Poster Image' ),
  3594 		'videoAddTrackTitle'	=> __( 'Add Subtitles' ),
  3734 		'videoAddTrackTitle'          => __( 'Add Subtitles' ),
  3595 
  3735 
  3596  		// Playlist
  3736 		// Playlist
  3597  		'playlistDragInfo'    => __( 'Drag and drop to reorder tracks.' ),
  3737 		'playlistDragInfo'            => __( 'Drag and drop to reorder tracks.' ),
  3598  		'createPlaylistTitle' => __( 'Create Audio Playlist' ),
  3738 		'createPlaylistTitle'         => __( 'Create Audio Playlist' ),
  3599  		'editPlaylistTitle'   => __( 'Edit Audio Playlist' ),
  3739 		'editPlaylistTitle'           => __( 'Edit Audio Playlist' ),
  3600  		'cancelPlaylistTitle' => __( '&#8592; Cancel Audio Playlist' ),
  3740 		'cancelPlaylistTitle'         => __( '&#8592; Cancel Audio Playlist' ),
  3601  		'insertPlaylist'      => __( 'Insert audio playlist' ),
  3741 		'insertPlaylist'              => __( 'Insert audio playlist' ),
  3602  		'updatePlaylist'      => __( 'Update audio playlist' ),
  3742 		'updatePlaylist'              => __( 'Update audio playlist' ),
  3603  		'addToPlaylist'       => __( 'Add to audio playlist' ),
  3743 		'addToPlaylist'               => __( 'Add to audio playlist' ),
  3604  		'addToPlaylistTitle'  => __( 'Add to Audio Playlist' ),
  3744 		'addToPlaylistTitle'          => __( 'Add to Audio Playlist' ),
  3605 
  3745 
  3606  		// Video Playlist
  3746 		// Video Playlist
  3607  		'videoPlaylistDragInfo'    => __( 'Drag and drop to reorder videos.' ),
  3747 		'videoPlaylistDragInfo'       => __( 'Drag and drop to reorder videos.' ),
  3608  		'createVideoPlaylistTitle' => __( 'Create Video Playlist' ),
  3748 		'createVideoPlaylistTitle'    => __( 'Create Video Playlist' ),
  3609  		'editVideoPlaylistTitle'   => __( 'Edit Video Playlist' ),
  3749 		'editVideoPlaylistTitle'      => __( 'Edit Video Playlist' ),
  3610  		'cancelVideoPlaylistTitle' => __( '&#8592; Cancel Video Playlist' ),
  3750 		'cancelVideoPlaylistTitle'    => __( '&#8592; Cancel Video Playlist' ),
  3611  		'insertVideoPlaylist'      => __( 'Insert video playlist' ),
  3751 		'insertVideoPlaylist'         => __( 'Insert video playlist' ),
  3612  		'updateVideoPlaylist'      => __( 'Update video playlist' ),
  3752 		'updateVideoPlaylist'         => __( 'Update video playlist' ),
  3613  		'addToVideoPlaylist'       => __( 'Add to video playlist' ),
  3753 		'addToVideoPlaylist'          => __( 'Add to video playlist' ),
  3614  		'addToVideoPlaylistTitle'  => __( 'Add to Video Playlist' ),
  3754 		'addToVideoPlaylistTitle'     => __( 'Add to Video Playlist' ),
       
  3755 
       
  3756 		// Headings
       
  3757 		'attachmentsList'             => __( 'Attachments list' ),
  3615 	);
  3758 	);
  3616 
  3759 
  3617 	/**
  3760 	/**
  3618 	 * Filters the media view settings.
  3761 	 * Filters the media view settings.
  3619 	 *
  3762 	 *
  3630 	 * @since 3.5.0
  3773 	 * @since 3.5.0
  3631 	 *
  3774 	 *
  3632 	 * @param array   $strings List of media view strings.
  3775 	 * @param array   $strings List of media view strings.
  3633 	 * @param WP_Post $post    Post object.
  3776 	 * @param WP_Post $post    Post object.
  3634 	 */
  3777 	 */
  3635 	$strings = apply_filters( 'media_view_strings', $strings,  $post );
  3778 	$strings = apply_filters( 'media_view_strings', $strings, $post );
  3636 
  3779 
  3637 	$strings['settings'] = $settings;
  3780 	$strings['settings'] = $settings;
  3638 
  3781 
  3639 	// Ensure we enqueue media-editor first, that way media-views is
  3782 	// Ensure we enqueue media-editor first, that way media-views is
  3640 	// registered internally before we try to localize it. see #24724.
  3783 	// registered internally before we try to localize it. see #24724.
  3671  * @param string      $type Mime type.
  3814  * @param string      $type Mime type.
  3672  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
  3815  * @param int|WP_Post $post Optional. Post ID or WP_Post object. Default is global $post.
  3673  * @return array Found attachments.
  3816  * @return array Found attachments.
  3674  */
  3817  */
  3675 function get_attached_media( $type, $post = 0 ) {
  3818 function get_attached_media( $type, $post = 0 ) {
  3676 	if ( ! $post = get_post( $post ) )
  3819 	if ( ! $post = get_post( $post ) ) {
  3677 		return array();
  3820 		return array();
       
  3821 	}
  3678 
  3822 
  3679 	$args = array(
  3823 	$args = array(
  3680 		'post_parent' => $post->ID,
  3824 		'post_parent'    => $post->ID,
  3681 		'post_type' => 'attachment',
  3825 		'post_type'      => 'attachment',
  3682 		'post_mime_type' => $type,
  3826 		'post_mime_type' => $type,
  3683 		'posts_per_page' => -1,
  3827 		'posts_per_page' => -1,
  3684 		'orderby' => 'menu_order',
  3828 		'orderby'        => 'menu_order',
  3685 		'order' => 'ASC',
  3829 		'order'          => 'ASC',
  3686 	);
  3830 	);
  3687 
  3831 
  3688 	/**
  3832 	/**
  3689 	 * Filters arguments used to retrieve media attached to the given post.
  3833 	 * Filters arguments used to retrieve media attached to the given post.
  3690 	 *
  3834 	 *
  3760  * @param bool        $html Optional. Whether to return HTML or data in the array. Default true.
  3904  * @param bool        $html Optional. Whether to return HTML or data in the array. Default true.
  3761  * @return array A list of arrays, each containing gallery data and srcs parsed
  3905  * @return array A list of arrays, each containing gallery data and srcs parsed
  3762  *               from the expanded shortcode.
  3906  *               from the expanded shortcode.
  3763  */
  3907  */
  3764 function get_post_galleries( $post, $html = true ) {
  3908 function get_post_galleries( $post, $html = true ) {
  3765 	if ( ! $post = get_post( $post ) )
  3909 	if ( ! $post = get_post( $post ) ) {
  3766 		return array();
  3910 		return array();
  3767 
  3911 	}
  3768 	if ( ! has_shortcode( $post->post_content, 'gallery' ) )
  3912 
       
  3913 	if ( ! has_shortcode( $post->post_content, 'gallery' ) ) {
  3769 		return array();
  3914 		return array();
       
  3915 	}
  3770 
  3916 
  3771 	$galleries = array();
  3917 	$galleries = array();
  3772 	if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) {
  3918 	if ( preg_match_all( '/' . get_shortcode_regex() . '/s', $post->post_content, $matches, PREG_SET_ORDER ) ) {
  3773 		foreach ( $matches as $shortcode ) {
  3919 		foreach ( $matches as $shortcode ) {
  3774 			if ( 'gallery' === $shortcode[2] ) {
  3920 			if ( 'gallery' === $shortcode[2] ) {
  3796 					}
  3942 					}
  3797 
  3943 
  3798 					$galleries[] = array_merge(
  3944 					$galleries[] = array_merge(
  3799 						$shortcode_attrs,
  3945 						$shortcode_attrs,
  3800 						array(
  3946 						array(
  3801 							'src' => array_values( array_unique( $srcs ) )
  3947 							'src' => array_values( array_unique( $srcs ) ),
  3802 						)
  3948 						)
  3803 					);
  3949 					);
  3804 				}
  3950 				}
  3805 			}
  3951 			}
  3806 		}
  3952 		}
  3826  * @param bool        $html Optional. Whether to return HTML or data. Default is true.
  3972  * @param bool        $html Optional. Whether to return HTML or data. Default is true.
  3827  * @return string|array Gallery data and srcs parsed from the expanded shortcode.
  3973  * @return string|array Gallery data and srcs parsed from the expanded shortcode.
  3828  */
  3974  */
  3829 function get_post_gallery( $post = 0, $html = true ) {
  3975 function get_post_gallery( $post = 0, $html = true ) {
  3830 	$galleries = get_post_galleries( $post, $html );
  3976 	$galleries = get_post_galleries( $post, $html );
  3831 	$gallery = reset( $galleries );
  3977 	$gallery   = reset( $galleries );
  3832 
  3978 
  3833 	/**
  3979 	/**
  3834 	 * Filters the first-found post gallery.
  3980 	 * Filters the first-found post gallery.
  3835 	 *
  3981 	 *
  3836 	 * @since 3.6.0
  3982 	 * @since 3.6.0
  3886 	}
  4032 	}
  3887 
  4033 
  3888 	$file = get_attached_file( $attachment_id );
  4034 	$file = get_attached_file( $attachment_id );
  3889 	$meta = wp_get_attachment_metadata( $attachment_id );
  4035 	$meta = wp_get_attachment_metadata( $attachment_id );
  3890 	if ( empty( $meta ) && file_exists( $file ) ) {
  4036 	if ( empty( $meta ) && file_exists( $file ) ) {
  3891 		$_meta = get_post_meta( $attachment_id );
  4037 		$_meta             = get_post_meta( $attachment_id );
  3892 		$regeneration_lock = 'wp_generating_att_' . $attachment_id;
  4038 		$regeneration_lock = 'wp_generating_att_' . $attachment_id;
  3893 		if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $regeneration_lock ) ) {
  4039 		if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $regeneration_lock ) ) {
  3894 			set_transient( $regeneration_lock, $file );
  4040 			set_transient( $regeneration_lock, $file );
  3895 			wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
  4041 			wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) );
  3896 			delete_transient( $regeneration_lock );
  4042 			delete_transient( $regeneration_lock );
  3909  * @return int The found post ID, or 0 on failure.
  4055  * @return int The found post ID, or 0 on failure.
  3910  */
  4056  */
  3911 function attachment_url_to_postid( $url ) {
  4057 function attachment_url_to_postid( $url ) {
  3912 	global $wpdb;
  4058 	global $wpdb;
  3913 
  4059 
  3914 	$dir = wp_get_upload_dir();
  4060 	$dir  = wp_get_upload_dir();
  3915 	$path = $url;
  4061 	$path = $url;
  3916 
  4062 
  3917 	$site_url = parse_url( $dir['url'] );
  4063 	$site_url   = parse_url( $dir['url'] );
  3918 	$image_path = parse_url( $path );
  4064 	$image_path = parse_url( $path );
  3919 
  4065 
  3920 	//force the protocols to match if needed
  4066 	//force the protocols to match if needed
  3921 	if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
  4067 	if ( isset( $image_path['scheme'] ) && ( $image_path['scheme'] !== $site_url['scheme'] ) ) {
  3922 		$path = str_replace( $image_path['scheme'], $site_url['scheme'], $path );
  4068 		$path = str_replace( $image_path['scheme'], $site_url['scheme'], $path );
  3924 
  4070 
  3925 	if ( 0 === strpos( $path, $dir['baseurl'] . '/' ) ) {
  4071 	if ( 0 === strpos( $path, $dir['baseurl'] . '/' ) ) {
  3926 		$path = substr( $path, strlen( $dir['baseurl'] . '/' ) );
  4072 		$path = substr( $path, strlen( $dir['baseurl'] . '/' ) );
  3927 	}
  4073 	}
  3928 
  4074 
  3929 	$sql = $wpdb->prepare(
  4075 	$sql     = $wpdb->prepare(
  3930 		"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
  4076 		"SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s",
  3931 		$path
  4077 		$path
  3932 	);
  4078 	);
  3933 	$post_id = $wpdb->get_var( $sql );
  4079 	$post_id = $wpdb->get_var( $sql );
  3934 
  4080 
  3949  * @since 4.0.0
  4095  * @since 4.0.0
  3950  *
  4096  *
  3951  * @return array The relevant CSS file URLs.
  4097  * @return array The relevant CSS file URLs.
  3952  */
  4098  */
  3953 function wpview_media_sandbox_styles() {
  4099 function wpview_media_sandbox_styles() {
  3954  	$version = 'ver=' . get_bloginfo( 'version' );
  4100 	$version        = 'ver=' . get_bloginfo( 'version' );
  3955  	$mediaelement = includes_url( "js/mediaelement/mediaelementplayer-legacy.min.css?$version" );
  4101 	$mediaelement   = includes_url( "js/mediaelement/mediaelementplayer-legacy.min.css?$version" );
  3956  	$wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" );
  4102 	$wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" );
  3957 
  4103 
  3958 	return array( $mediaelement, $wpmediaelement );
  4104 	return array( $mediaelement, $wpmediaelement );
  3959 }
  4105 }
  3960 
  4106 
  3961 /**
  4107 /**
  3987 	$number = 50;
  4133 	$number = 50;
  3988 	$page   = (int) $page;
  4134 	$page   = (int) $page;
  3989 
  4135 
  3990 	$data_to_export = array();
  4136 	$data_to_export = array();
  3991 
  4137 
  3992 	$user = get_user_by( 'email' , $email_address );
  4138 	$user = get_user_by( 'email', $email_address );
  3993 	if ( false === $user ) {
  4139 	if ( false === $user ) {
  3994 		return array(
  4140 		return array(
  3995 			'data' => $data_to_export,
  4141 			'data' => $data_to_export,
  3996 			'done' => true,
  4142 			'done' => true,
  3997 		);
  4143 		);
  4012 	foreach ( (array) $post_query->posts as $post ) {
  4158 	foreach ( (array) $post_query->posts as $post ) {
  4013 		$attachment_url = wp_get_attachment_url( $post->ID );
  4159 		$attachment_url = wp_get_attachment_url( $post->ID );
  4014 
  4160 
  4015 		if ( $attachment_url ) {
  4161 		if ( $attachment_url ) {
  4016 			$post_data_to_export = array(
  4162 			$post_data_to_export = array(
  4017 				array( 'name'  => __( 'URL' ), 'value' => $attachment_url ),
  4163 				array(
       
  4164 					'name'  => __( 'URL' ),
       
  4165 					'value' => $attachment_url,
       
  4166 				),
  4018 			);
  4167 			);
  4019 
  4168 
  4020 			$data_to_export[] = array(
  4169 			$data_to_export[] = array(
  4021 				'group_id'    => 'media',
  4170 				'group_id'    => 'media',
  4022 				'group_label' => __( 'Media' ),
  4171 				'group_label' => __( 'Media' ),