* @subpackage Media
*/
+/**
+ * Retrieve additional image sizes.
+ *
+ * @since 4.7.0
+ *
+ * @global array $_wp_additional_image_sizes
+ *
+ * @return array Additional images size data.
+ */
+function wp_get_additional_image_sizes() {
+ global $_wp_additional_image_sizes;
+ if ( ! $_wp_additional_image_sizes ) {
+ $_wp_additional_image_sizes = array();
+ }
+ return $_wp_additional_image_sizes;
+}
+
/**
* Scale down the default size of an image.
*
* @since 2.5.0
*
* @global int $content_width
- * @global array $_wp_additional_image_sizes
*
* @param int $width Width of the image in pixels.
* @param int $height Height of the image in pixels.
* @return array Width and height of what the result image should resize to.
*/
function image_constrain_size_for_editor( $width, $height, $size = 'medium', $context = null ) {
- global $content_width, $_wp_additional_image_sizes;
+ global $content_width;
+
+ $_wp_additional_image_sizes = wp_get_additional_image_sizes();
if ( ! $context )
$context = is_admin() ? 'edit' : 'display';
if ( intval($content_width) > 0 ) {
$max_width = min( intval($content_width), $max_width );
}
- } elseif ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
+ } elseif ( ! empty( $_wp_additional_image_sizes ) && in_array( $size, array_keys( $_wp_additional_image_sizes ) ) ) {
$max_width = intval( $_wp_additional_image_sizes[$size]['width'] );
$max_height = intval( $_wp_additional_image_sizes[$size]['height'] );
- if ( intval($content_width) > 0 && 'edit' == $context ) // Only in admin. Assume that theme authors know what they're doing.
- $max_width = min( intval($content_width), $max_width );
+ // Only in admin. Assume that theme authors know what they're doing.
+ if ( intval( $content_width ) > 0 && 'edit' === $context ) {
+ $max_width = min( intval( $content_width ), $max_width );
+ }
}
// $size == 'full' has no constraint
else {
}
/**
- * Filter the maximum image size dimensions for the editor.
+ * Filters the maximum image size dimensions for the editor.
*
* @since 2.5.0
*
* function won't create a new resized copy, it will just return an already
* resized one if it exists.
*
- * A plugin may use the 'image_downsize' filter to hook into and offer image
+ * A plugin may use the {@see 'image_downsize'} filter to hook into and offer image
* resizing services for images. The hook must return an array with the same
* elements that are returned in the function. The first element being the URL
* to the new image that was resized.
* the image is an intermediate size. False on failure.
*/
function image_downsize( $id, $size = 'medium' ) {
-
- if ( !wp_attachment_is_image($id) )
- return false;
+ $is_image = wp_attachment_is_image( $id );
/**
- * Filter whether to preempt the output of image_downsize().
+ * Filters whether to preempt the output of image_downsize().
*
* Passing a truthy value to the filter will effectively short-circuit
* down-sizing the image, returning that value as output instead.
$is_intermediate = false;
$img_url_basename = wp_basename($img_url);
+ // If the file isn't an image, attempt to replace its URL with a rendered image from its meta.
+ // Otherwise, a non-image type could be returned.
+ if ( ! $is_image ) {
+ if ( ! empty( $meta['sizes'] ) ) {
+ $img_url = str_replace( $img_url_basename, $meta['sizes']['full']['file'], $img_url );
+ $img_url_basename = $meta['sizes']['full']['file'];
+ $width = $meta['sizes']['full']['width'];
+ $height = $meta['sizes']['full']['height'];
+ } else {
+ return false;
+ }
+ }
+
// try for a new style intermediate size
if ( $intermediate = image_get_intermediate_size($id, $size) ) {
$img_url = str_replace($img_url_basename, $intermediate['file'], $img_url);
*
* @since 3.9.0
*
- * @global array $_wp_additional_image_sizes
- *
* @param string $name The image size to check.
* @return bool True if the image size exists, false if not.
*/
function has_image_size( $name ) {
- global $_wp_additional_image_sizes;
-
- return isset( $_wp_additional_image_sizes[ $name ] );
+ $sizes = wp_get_additional_image_sizes();
+ return isset( $sizes[ $name ] );
}
/**
/**
* Gets an img tag for an image attachment, scaling it down if requested.
*
- * The filter 'get_image_tag_class' allows for changing the class name for the
+ * The {@see 'get_image_tag_class'} filter allows for changing the class name for the
* image without having to use regular expressions on the HTML content. The
* parameters are: what WordPress will use for the class, the Attachment ID,
* image align value, and the size the image should be.
*
- * The second filter 'get_image_tag' has the HTML content, which can then be
+ * The second filter, {@see 'get_image_tag'}, has the HTML content, which can then be
* further manipulated by a plugin to change all attribute values and even HTML
* content.
*
$class = 'align' . esc_attr($align) .' size-' . esc_attr($size) . ' wp-image-' . $id;
/**
- * Filter the value of the attachment's image tag class attribute.
+ * Filters the value of the attachment's image tag class attribute.
*
* @since 2.6.0
*
$html = '<img src="' . esc_attr($img_src) . '" alt="' . esc_attr($alt) . '" ' . $title . $hwstring . 'class="' . $class . '" />';
/**
- * Filter the HTML content for the image tag.
+ * Filters the HTML content for the image tag.
*
* @since 2.6.0
*
}
/**
- * Filter dimensions to constrain down-sampled images to.
+ * Filters dimensions to constrain down-sampled images to.
*
* @since 4.1.0
*
return false;
/**
- * Filter whether to preempt calculating the image resize dimensions.
+ * Filters whether to preempt calculating the image resize dimensions.
*
* Passing a non-null value to the filter will effectively short-circuit
* image_resize_dimensions(), returning that value instead.
* Resizes an image to make a thumbnail or intermediate size.
*
* The returned array has the file size, the image width, and image height. The
- * filter 'image_make_intermediate_size' can be used to hook in and change the
+ * {@see 'image_make_intermediate_size'} filter can be used to hook in and change the
* values of the returned array. The only parameter is the resized file path.
*
* @since 2.5.0
return false;
}
+/**
+ * Helper function to test if aspect ratios for two images match.
+ *
+ * @since 4.6.0
+ *
+ * @param int $source_width Width of the first image in pixels.
+ * @param int $source_height Height of the first image in pixels.
+ * @param int $target_width Width of the second image in pixels.
+ * @param int $target_height Height of the second image in pixels.
+ * @return bool True if aspect ratios match within 1px. False if not.
+ */
+function wp_image_matches_ratio( $source_width, $source_height, $target_width, $target_height ) {
+ /*
+ * To test for varying crops, we constrain the dimensions of the larger image
+ * to the dimensions of the smaller image and see if they match.
+ */
+ if ( $source_width > $target_width ) {
+ $constrained_size = wp_constrain_dimensions( $source_width, $source_height, $target_width );
+ $expected_size = array( $target_width, $target_height );
+ } else {
+ $constrained_size = wp_constrain_dimensions( $target_width, $target_height, $source_width );
+ $expected_size = array( $source_width, $source_height );
+ }
+
+ // If the image dimensions are within 1px of the expected size, we consider it a match.
+ $matched = ( abs( $constrained_size[0] - $expected_size[0] ) <= 1 && abs( $constrained_size[1] - $expected_size[1] ) <= 1 );
+
+ return $matched;
+}
+
/**
* Retrieves the image's intermediate size (resized) path, width, and height.
*
* @type string $file Image's path relative to uploads directory
* @type int $width Width of image
* @type int $height Height of image
- * @type string $path Optional. Image's absolute filesystem path. Only returned if registered
- * size is passed to `$size` parameter.
- * @type string $url Optional. Image's URL. Only returned if registered size is passed to `$size`
- * parameter.
+ * @type string $path Image's absolute filesystem path.
+ * @type string $url Image's URL.
* }
*/
function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) {
- if ( !is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) )
+ if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] ) ) {
return false;
+ }
+
+ $data = array();
- // get the best one for a specified set of dimensions
- if ( is_array($size) && !empty($imagedata['sizes']) ) {
+ // Find the best match when '$size' is an array.
+ if ( is_array( $size ) ) {
$candidates = array();
+ if ( ! isset( $imagedata['file'] ) && isset( $imagedata['sizes']['full'] ) ) {
+ $imagedata['height'] = $imagedata['sizes']['full']['height'];
+ $imagedata['width'] = $imagedata['sizes']['full']['width'];
+ }
+
foreach ( $imagedata['sizes'] as $_size => $data ) {
// If there's an exact match to an existing image size, short circuit.
if ( $data['width'] == $size[0] && $data['height'] == $size[1] ) {
- list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
-
- /** This filter is documented in wp-includes/media.php */
- return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size );
+ $candidates[ $data['width'] * $data['height'] ] = $data;
+ break;
}
- // If it's not an exact match but it's at least the dimensions requested.
+
+ // If it's not an exact match, consider larger sizes with the same aspect ratio.
if ( $data['width'] >= $size[0] && $data['height'] >= $size[1] ) {
- $candidates[ $data['width'] * $data['height'] ] = $_size;
+ // If '0' is passed to either size, we test ratios against the original file.
+ if ( 0 === $size[0] || 0 === $size[1] ) {
+ $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $imagedata['width'], $imagedata['height'] );
+ } else {
+ $same_ratio = wp_image_matches_ratio( $data['width'], $data['height'], $size[0], $size[1] );
+ }
+
+ if ( $same_ratio ) {
+ $candidates[ $data['width'] * $data['height'] ] = $data;
+ }
}
}
if ( ! empty( $candidates ) ) {
- // find for the smallest image not smaller than the desired size
- ksort( $candidates );
- foreach ( $candidates as $_size ) {
- $data = $imagedata['sizes'][$_size];
-
- // Skip images with unexpectedly divergent aspect ratios (crops)
- // First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
- $maybe_cropped = image_resize_dimensions($imagedata['width'], $imagedata['height'], $data['width'], $data['height'], false );
- // If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size
- if ( 'thumbnail' != $_size &&
- ( ! $maybe_cropped
- || ( $maybe_cropped[4] != $data['width'] && $maybe_cropped[4] + 1 != $data['width'] )
- || ( $maybe_cropped[5] != $data['height'] && $maybe_cropped[5] + 1 != $data['height'] )
- ) ) {
- continue;
- }
- // If we're still here, then we're going to use this size.
- list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
-
- /** This filter is documented in wp-includes/media.php */
- return apply_filters( 'image_get_intermediate_size', $data, $post_id, $size );
+ // Sort the array by size if we have more than one candidate.
+ if ( 1 < count( $candidates ) ) {
+ ksort( $candidates );
}
+
+ $data = array_shift( $candidates );
+ /*
+ * When the size requested is smaller than the thumbnail dimensions, we
+ * fall back to the thumbnail size to maintain backwards compatibility with
+ * pre 4.6 versions of WordPress.
+ */
+ } elseif ( ! empty( $imagedata['sizes']['thumbnail'] ) && $imagedata['sizes']['thumbnail']['width'] >= $size[0] && $imagedata['sizes']['thumbnail']['width'] >= $size[1] ) {
+ $data = $imagedata['sizes']['thumbnail'];
+ } else {
+ return false;
}
+
+ // Constrain the width and height attributes to the requested values.
+ list( $data['width'], $data['height'] ) = image_constrain_size_for_editor( $data['width'], $data['height'], $size );
+
+ } elseif ( ! empty( $imagedata['sizes'][ $size ] ) ) {
+ $data = $imagedata['sizes'][ $size ];
}
- if ( is_array($size) || empty($size) || empty($imagedata['sizes'][$size]) )
+ // If we still don't have a match at this point, return false.
+ if ( empty( $data ) ) {
return false;
+ }
- $data = $imagedata['sizes'][$size];
// include the full filesystem path of the intermediate file
- if ( empty($data['path']) && !empty($data['file']) ) {
+ if ( empty( $data['path'] ) && ! empty( $data['file'] ) && ! empty( $imagedata['file'] ) ) {
$file_url = wp_get_attachment_url($post_id);
$data['path'] = path_join( dirname($imagedata['file']), $data['file'] );
$data['url'] = path_join( dirname($file_url), $data['file'] );
}
/**
- * Filter the output of image_get_intermediate_size()
+ * Filters the output of image_get_intermediate_size()
*
* @since 4.4.0
*
*
* @since 3.0.0
*
- * @global array $_wp_additional_image_sizes
- *
* @return array Returns a filtered array of image size strings.
*/
function get_intermediate_image_sizes() {
- global $_wp_additional_image_sizes;
+ $_wp_additional_image_sizes = wp_get_additional_image_sizes();
$image_sizes = array('thumbnail', 'medium', 'medium_large', 'large'); // Standard sizes
- if ( isset( $_wp_additional_image_sizes ) && count( $_wp_additional_image_sizes ) )
+ if ( ! empty( $_wp_additional_image_sizes ) ) {
$image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) );
+ }
/**
- * Filter the list of intermediate image sizes.
+ * Filters the list of intermediate image sizes.
*
* @since 2.5.0
*
}
}
/**
- * Filter the image src result.
+ * Filters the image src result.
*
* @since 4.3.0
*
$default_attr = array(
'src' => $src,
'class' => "attachment-$size_class size-$size_class",
- 'alt' => trim(strip_tags( get_post_meta($attachment_id, '_wp_attachment_image_alt', true) )), // Use Alt field first
+ 'alt' => trim( strip_tags( get_post_meta( $attachment_id, '_wp_attachment_image_alt', true ) ) ),
);
- if ( empty($default_attr['alt']) )
- $default_attr['alt'] = trim(strip_tags( $attachment->post_excerpt )); // If not, Use the Caption
- if ( empty($default_attr['alt']) )
- $default_attr['alt'] = trim(strip_tags( $attachment->post_title )); // Finally, use the title
$attr = wp_parse_args( $attr, $default_attr );
// Generate 'srcset' and 'sizes' if not already present.
if ( empty( $attr['srcset'] ) ) {
- $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
if ( is_array( $image_meta ) ) {
$size_array = array( absint( $width ), absint( $height ) );
}
/**
- * Filter the list of attachment image attributes.
+ * Filters the list of attachment image attributes.
*
* @since 2.8.0
*
}
/**
- * Caches and returns the base URL of the uploads directory.
+ * Get the attachment path relative to the upload directory.
*
- * @since 4.4.0
+ * @since 4.4.1
* @access private
*
- * @return string The base URL, cached.
+ * @param string $file Attachment file name.
+ * @return string Attachment path relative to the upload directory.
*/
-function _wp_upload_dir_baseurl() {
- static $baseurl = array();
+function _wp_get_attachment_relative_path( $file ) {
+ $dirname = dirname( $file );
- $blog_id = get_current_blog_id();
+ if ( '.' === $dirname ) {
+ return '';
+ }
- if ( empty( $baseurl[$blog_id] ) ) {
- $uploads_dir = wp_upload_dir();
- $baseurl[$blog_id] = $uploads_dir['baseurl'];
+ if ( false !== strpos( $dirname, 'wp-content/uploads' ) ) {
+ // Get the directory name relative to the upload directory (back compat for pre-2.7 uploads)
+ $dirname = substr( $dirname, strpos( $dirname, 'wp-content/uploads' ) + 18 );
+ $dirname = ltrim( $dirname, '/' );
}
- return $baseurl[$blog_id];
+ return $dirname;
}
/**
}
if ( ! is_array( $image_meta ) ) {
- $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
}
$image_src = $image[0];
* @return string|bool The 'srcset' attribute value. False on error or when only one source exists.
*/
function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attachment_id = 0 ) {
- if ( empty( $image_meta['sizes'] ) ) {
+ /**
+ * Let plugins pre-filter the image meta to be able to fix inconsistencies in the stored data.
+ *
+ * @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'.
+ * @param array $size_array Array of width and height values in pixels (in that order).
+ * @param string $image_src The 'src' of the image.
+ * @param int $attachment_id The image attachment ID or 0 if not supplied.
+ */
+ $image_meta = apply_filters( 'wp_calculate_image_srcset_meta', $image_meta, $size_array, $image_src, $attachment_id );
+
+ if ( empty( $image_meta['sizes'] ) || ! isset( $image_meta['file'] ) || strlen( $image_meta['file'] ) < 4 ) {
return false;
}
}
$image_basename = wp_basename( $image_meta['file'] );
- $image_baseurl = _wp_upload_dir_baseurl();
/*
* WordPress flattens animated GIFs into one frame when generating intermediate sizes.
* If src is an intermediate size GIF, the full size is excluded from srcset to keep a flattened GIF from becoming animated.
*/
if ( ! isset( $image_sizes['thumbnail']['mime-type'] ) || 'image/gif' !== $image_sizes['thumbnail']['mime-type'] ) {
- $image_sizes['full'] = array(
+ $image_sizes[] = array(
'width' => $image_meta['width'],
'height' => $image_meta['height'],
'file' => $image_basename,
return false;
}
- // Uploads are (or have been) in year/month sub-directories.
- if ( $image_basename !== $image_meta['file'] ) {
- $dirname = dirname( $image_meta['file'] );
+ // Retrieve the uploads sub-directory from the full size image.
+ $dirname = _wp_get_attachment_relative_path( $image_meta['file'] );
- if ( $dirname !== '.' ) {
- $image_baseurl = trailingslashit( $image_baseurl ) . $dirname;
- }
+ if ( $dirname ) {
+ $dirname = trailingslashit( $dirname );
}
- $image_baseurl = trailingslashit( $image_baseurl );
+ $upload_dir = wp_get_upload_dir();
+ $image_baseurl = trailingslashit( $upload_dir['baseurl'] ) . $dirname;
- // Calculate the image aspect ratio.
- $image_ratio = $image_height / $image_width;
+ /*
+ * If currently on HTTPS, prefer HTTPS URLs when we know they're supported by the domain
+ * (which is to say, when they share the domain name of the current request).
+ */
+ if ( is_ssl() && 'https' !== substr( $image_baseurl, 0, 5 ) && parse_url( $image_baseurl, PHP_URL_HOST ) === $_SERVER['HTTP_HOST'] ) {
+ $image_baseurl = set_url_scheme( $image_baseurl, 'https' );
+ }
/*
* Images that have been edited in WordPress after being uploaded will
$image_edited = preg_match( '/-e[0-9]{13}/', wp_basename( $image_src ), $image_edit_hash );
/**
- * Filter the maximum image width to be included in a 'srcset' attribute.
+ * Filters the maximum image width to be included in a 'srcset' attribute.
*
* @since 4.4.0
*
// Array to hold URL candidates.
$sources = array();
+ /**
+ * To make sure the ID matches our image src, we will check to see if any sizes in our attachment
+ * meta match our $image_src. If no matches are found we don't return a srcset to avoid serving
+ * an incorrect image. See #35045.
+ */
+ $src_matched = false;
+
/*
* Loop through available images. Only use images that are resized
* versions of the same edit.
*/
foreach ( $image_sizes as $image ) {
+ $is_src = false;
- // Filter out images that are from previous edits.
- if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
+ // Check if image meta isn't corrupted.
+ if ( ! is_array( $image ) ) {
continue;
}
- // Filter out images that are wider than '$max_srcset_image_width'.
- if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width ) {
+ // If the file name is part of the `src`, we've confirmed a match.
+ if ( ! $src_matched && false !== strpos( $image_src, $dirname . $image['file'] ) ) {
+ $src_matched = $is_src = true;
+ }
+
+ // Filter out images that are from previous edits.
+ if ( $image_edited && ! strpos( $image['file'], $image_edit_hash[0] ) ) {
continue;
}
- // Calculate the new image ratio.
- if ( $image['width'] ) {
- $image_ratio_compare = $image['height'] / $image['width'];
- } else {
- $image_ratio_compare = 0;
+ /*
+ * Filters out images that are wider than '$max_srcset_image_width' unless
+ * that file is in the 'src' attribute.
+ */
+ if ( $max_srcset_image_width && $image['width'] > $max_srcset_image_width && ! $is_src ) {
+ continue;
}
- // If the new ratio differs by less than 0.002, use it.
- if ( abs( $image_ratio - $image_ratio_compare ) < 0.002 ) {
+ // If the image dimensions are within 1px of the expected size, use it.
+ if ( wp_image_matches_ratio( $image_width, $image_height, $image['width'], $image['height'] ) ) {
// Add the URL, descriptor, and value to the sources array to be returned.
- $sources[ $image['width'] ] = array(
+ $source = array(
'url' => $image_baseurl . $image['file'],
'descriptor' => 'w',
'value' => $image['width'],
);
+
+ // The 'src' image has to be the first in the 'srcset', because of a bug in iOS8. See #35030.
+ if ( $is_src ) {
+ $sources = array( $image['width'] => $source ) + $sources;
+ } else {
+ $sources[ $image['width'] ] = $source;
+ }
}
}
/**
- * Filter an image's 'srcset' sources.
+ * Filters an image's 'srcset' sources.
*
* @since 4.4.0
*
* @param array $size_array Array of width and height values in pixels (in that order).
* @param string $image_src The 'src' of the image.
* @param array $image_meta The image meta data as returned by 'wp_get_attachment_metadata()'.
- * @param int $attachment_id Image attachment ID or 0.
+ * @param int $attachment_id Image attachment ID or 0.
*/
$sources = apply_filters( 'wp_calculate_image_srcset', $sources, $size_array, $image_src, $image_meta, $attachment_id );
// Only return a 'srcset' value if there is more than one source.
- if ( count( $sources ) < 2 ) {
+ if ( ! $src_matched || count( $sources ) < 2 ) {
return false;
}
$srcset = '';
foreach ( $sources as $source ) {
- $srcset .= $source['url'] . ' ' . $source['value'] . $source['descriptor'] . ', ';
+ $srcset .= str_replace( ' ', '%20', $source['url'] ) . ' ' . $source['value'] . $source['descriptor'] . ', ';
}
return rtrim( $srcset, ', ' );
}
if ( ! is_array( $image_meta ) ) {
- $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
}
$image_src = $image[0];
$width = absint( $size[0] );
} elseif ( is_string( $size ) ) {
if ( ! $image_meta && $attachment_id ) {
- $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
}
if ( is_array( $image_meta ) ) {
$sizes = sprintf( '(max-width: %1$dpx) 100vw, %1$dpx', $width );
/**
- * Filter the output of 'wp_calculate_image_sizes()'.
+ * Filters the output of 'wp_calculate_image_sizes()'.
*
* @since 4.4.0
*
}
foreach ( $selected_images as $image => $attachment_id ) {
- $image_meta = get_post_meta( $attachment_id, '_wp_attachment_metadata', true );
+ $image_meta = wp_get_attachment_metadata( $attachment_id );
$content = str_replace( $image, wp_image_add_srcset_and_sizes( $image, $image_meta, $attachment_id ), $content );
}
return $image;
}
- $base_url = trailingslashit( _wp_upload_dir_baseurl() );
- $image_base_url = $base_url;
-
- $dirname = dirname( $image_meta['file'] );
- if ( $dirname !== '.' ) {
- $image_base_url .= trailingslashit( $dirname );
- }
-
- $all_sizes = wp_list_pluck( $image_meta['sizes'], 'file' );
-
- foreach ( $all_sizes as $key => $file ) {
- $all_sizes[ $key ] = $image_base_url . $file;
- }
-
- // Add the original image.
- $all_sizes[] = $base_url . $image_meta['file'];
-
- // Bail early if the image src doesn't match any of the known image sizes.
- if ( ! in_array( $image_src, $all_sizes ) ) {
- return $image;
- }
-
$width = preg_match( '/ width="([0-9]+)"/', $image, $match_width ) ? (int) $match_width[1] : 0;
$height = preg_match( '/ height="([0-9]+)"/', $image, $match_height ) ? (int) $match_height[1] : 0;
/**
* Adds a 'wp-post-image' class to post thumbnails. Internal use only.
*
- * Uses the 'begin_fetch_post_thumbnail_html' and 'end_fetch_post_thumbnail_html' action hooks to
- * dynamically add/remove itself so as to only filter post thumbnails.
+ * Uses the {@see 'begin_fetch_post_thumbnail_html'} and {@see 'end_fetch_post_thumbnail_html'}
+ * action hooks to dynamically add/remove itself so as to only filter post thumbnails.
*
* @ignore
* @since 2.9.0
* Builds the Caption shortcode output.
*
* Allows a plugin to replace the content that would otherwise be returned. The
- * filter is 'img_caption_shortcode' and passes an empty string, the attr
+ * filter is {@see 'img_caption_shortcode'} and passes an empty string, the attr
* parameter and the content parameter values.
*
* The supported attributes for the shortcode are 'id', 'align', 'width', and
}
/**
- * Filter the default caption shortcode output.
+ * Filters the default caption shortcode output.
*
* If the filtered output isn't empty, it will be used instead of generating
* the default caption template.
$width = $html5 ? $atts['width'] : ( 10 + $atts['width'] );
/**
- * Filter the width of an image's caption.
+ * Filters the width of an image's caption.
*
* By default, the caption is 10 pixels greater than the width of the image,
* to prevent post content from running up against a floated image.
$caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content );
$style = '';
- if ( $caption_width )
+ if ( $caption_width ) {
$style = 'style="width: ' . (int) $caption_width . 'px" ';
+ }
- $html = '';
if ( $html5 ) {
$html = '<figure ' . $atts['id'] . $style . 'class="' . esc_attr( $class ) . '">'
. do_shortcode( $content ) . '<figcaption class="wp-caption-text">' . $atts['caption'] . '</figcaption></figure>';
}
/**
- * Filter the default gallery shortcode output.
+ * Filters the default gallery shortcode output.
*
* If the filtered output isn't empty, it will be used instead of generating
* the default gallery template.
$gallery_style = '';
/**
- * Filter whether to print default gallery styles.
+ * Filters whether to print default gallery styles.
*
* @since 3.1.0
*
$gallery_div = "<div id='$selector' class='gallery galleryid-{$id} gallery-columns-{$columns} gallery-size-{$size_class}'>";
/**
- * Filter the default gallery shortcode CSS styles.
+ * Filters the default gallery shortcode CSS styles.
*
* @since 2.5.0
*
}
/**
- * Filter the playlist output.
+ * Filters the playlist output.
*
* Passing a non-empty value to the filter will short-circuit generation
* of the default playlist output, returning the passed value instead.
if ( 1 === $instance ) {
/**
- * Print and enqueue playlist scripts, styles, and JavaScript templates.
+ * Prints and enqueues playlist scripts, styles, and JavaScript templates.
*
* @since 3.9.0
*
echo (int) $theme_width;
?>"<?php if ( 'video' === $safe_type ):
echo ' height="', (int) $theme_height, '"';
- else:
- echo ' style="visibility: hidden"';
endif; ?>></<?php echo $safe_type ?>>
<div class="wp-playlist-next"></div>
<div class="wp-playlist-prev"></div>
*/
function wp_mediaelement_fallback( $url ) {
/**
- * Filter the Mediaelement fallback output for no-JS.
+ * Filters the Mediaelement fallback output for no-JS.
*
* @since 3.6.0
*
*/
function wp_get_audio_extensions() {
/**
- * Filter the list of supported audio formats.
+ * Filters the list of supported audio formats.
*
* @since 3.6.0
*
}
/**
- * Filter the editable list of keys to look up data from an attachment's metadata.
+ * Filters the editable list of keys to look up data from an attachment's metadata.
*
* @since 3.9.0
*
* @type string $src URL to the source of the audio file. Default empty.
* @type string $loop The 'loop' attribute for the `<audio>` element. Default empty.
* @type string $autoplay The 'autoplay' attribute for the `<audio>` element. Default empty.
- * @type string $preload The 'preload' attribute for the `<audio>` element. Default empty.
+ * @type string $preload The 'preload' attribute for the `<audio>` element. Default 'none'.
* @type string $class The 'class' attribute for the `<audio>` element. Default 'wp-audio-shortcode'.
- * @type string $style The 'style' attribute for the `<audio>` element. Default 'width: 100%'.
+ * @type string $style The 'style' attribute for the `<audio>` element. Default 'width: 100%;'.
* }
* @param string $content Shortcode content.
* @return string|void HTML content to display audio.
$instance++;
/**
- * Filter the default audio shortcode output.
+ * Filters the default audio shortcode output.
*
* If the filtered output isn't empty, it will be used instead of generating the default audio template.
*
'src' => '',
'loop' => '',
'autoplay' => '',
- 'preload' => 'none'
+ 'preload' => 'none',
+ 'class' => 'wp-audio-shortcode',
+ 'style' => 'width: 100%;'
);
foreach ( $default_types as $type ) {
$defaults_atts[$type] = '';
}
/**
- * Filter the media library used for the audio shortcode.
+ * Filters the media library used for the audio shortcode.
*
* @since 3.6.0
*
}
/**
- * Filter the class attribute for the audio shortcode output container.
+ * Filters the class attribute for the audio shortcode output container.
*
* @since 3.6.0
*
* @param string $class CSS class or list of space-separated classes.
*/
+ $atts['class'] = apply_filters( 'wp_audio_shortcode_class', $atts['class'] );
+
$html_atts = array(
- 'class' => apply_filters( 'wp_audio_shortcode_class', 'wp-audio-shortcode' ),
+ 'class' => $atts['class'],
'id' => sprintf( 'audio-%d-%d', $post_id, $instance ),
'loop' => wp_validate_boolean( $atts['loop'] ),
'autoplay' => wp_validate_boolean( $atts['autoplay'] ),
'preload' => $atts['preload'],
- 'style' => 'width: 100%; visibility: hidden;',
+ 'style' => $atts['style'],
);
// These ones should just be omitted altogether if they are blank
$html .= '</audio>';
/**
- * Filter the audio shortcode output.
+ * Filters the audio shortcode output.
*
* @since 3.6.0
*
*/
function wp_get_video_extensions() {
/**
- * Filter the list of supported video formats.
+ * Filters the list of supported video formats.
*
* @since 3.6.0
*
$instance++;
/**
- * Filter the default video shortcode output.
+ * Filters the default video shortcode output.
*
* If the filtered output isn't empty, it will be used instead of generating
* the default video template.
'preload' => 'metadata',
'width' => 640,
'height' => 360,
+ 'class' => 'wp-video-shortcode',
);
foreach ( $default_types as $type ) {
}
/**
- * Filter the media library used for the video shortcode.
+ * Filters the media library used for the video shortcode.
*
* @since 3.6.0
*
}
/**
- * Filter the class attribute for the video shortcode output container.
+ * Filters the class attribute for the video shortcode output container.
*
* @since 3.6.0
*
* @param string $class CSS class or list of space-separated classes.
*/
+ $atts['class'] = apply_filters( 'wp_video_shortcode_class', $atts['class'] );
+
$html_atts = array(
- 'class' => apply_filters( 'wp_video_shortcode_class', 'wp-video-shortcode' ),
+ 'class' => $atts['class'],
'id' => sprintf( 'video-%d-%d', $post_id, $instance ),
'width' => absint( $atts['width'] ),
'height' => absint( $atts['height'] ),
$width_rule = '';
if ( ! empty( $atts['width'] ) ) {
- $width_rule = sprintf( 'width: %dpx; ', $atts['width'] );
+ $width_rule = sprintf( 'width: %dpx;', $atts['width'] );
}
$output = sprintf( '<div style="%s" class="wp-video">%s</div>', $width_rule, $html );
/**
- * Filter the output of the video shortcode.
+ * Filters the output of the video shortcode.
*
* @since 3.6.0
*
$adjacent = $prev ? 'previous' : 'next';
/**
- * Filter the adjacent image link.
+ * Filters the adjacent image link.
*
* The dynamic portion of the hook name, `$adjacent`, refers to the type of adjacency,
* either 'next', or 'previous'.
* Retrieves taxonomies attached to given the attachment.
*
* @since 2.5.0
+ * @since 4.7.0 Introduced the `$output` parameter.
*
* @param int|array|object $attachment Attachment ID, data array, or data object.
+ * @param string $output Output type. 'names' to return an array of taxonomy names,
+ * or 'objects' to return an array of taxonomy objects.
+ * Default is 'names'.
* @return array Empty array on failure. List of taxonomies on success.
*/
-function get_attachment_taxonomies( $attachment ) {
+function get_attachment_taxonomies( $attachment, $output = 'names' ) {
if ( is_int( $attachment ) ) {
$attachment = get_post( $attachment );
} elseif ( is_array( $attachment ) ) {
}
$taxonomies = array();
- foreach ( $objects as $object )
- if ( $taxes = get_object_taxonomies($object) )
- $taxonomies = array_merge($taxonomies, $taxes);
+ foreach ( $objects as $object ) {
+ if ( $taxes = get_object_taxonomies( $object, $output ) ) {
+ $taxonomies = array_merge( $taxonomies, $taxes );
+ }
+ }
+
+ if ( 'names' === $output ) {
+ $taxonomies = array_unique( $taxonomies );
+ }
- return array_unique($taxonomies);
+ return $taxonomies;
}
/**
return wp_constrain_dimensions( $example_width * 1000000, $example_height * 1000000, $max_width, $max_height );
}
-/**
- * Converts a shorthand byte value to an integer byte value.
- *
- * @since 2.3.0
- *
- * @param string $size A shorthand byte value.
- * @return int An integer byte value.
- */
-function wp_convert_hr_to_bytes( $size ) {
- $size = strtolower( $size );
- $bytes = (int) $size;
- if ( strpos( $size, 'k' ) !== false )
- $bytes = intval( $size ) * KB_IN_BYTES;
- elseif ( strpos( $size, 'm' ) !== false )
- $bytes = intval($size) * MB_IN_BYTES;
- elseif ( strpos( $size, 'g' ) !== false )
- $bytes = intval( $size ) * GB_IN_BYTES;
- return $bytes;
-}
-
/**
* Determines the maximum upload size allowed in php.ini.
*
$p_bytes = wp_convert_hr_to_bytes( ini_get( 'post_max_size' ) );
/**
- * Filter the maximum upload size allowed in php.ini.
+ * Filters the maximum upload size allowed in php.ini.
*
* @since 2.5.0
*
require_once ABSPATH . WPINC . '/class-wp-image-editor.php';
require_once ABSPATH . WPINC . '/class-wp-image-editor-gd.php';
require_once ABSPATH . WPINC . '/class-wp-image-editor-imagick.php';
-
/**
- * Filter the list of image editing library classes.
+ * Filters the list of image editing library classes.
*
* @since 3.5.0
*
}
/**
- * Prints default plupload arguments.
+ * Prints default Plupload arguments.
*
* @since 3.4.0
*/
return;
$max_upload_size = wp_max_upload_size();
+ $allowed_extensions = array_keys( get_allowed_mime_types() );
+ $extensions = array();
+ foreach ( $allowed_extensions as $extension ) {
+ $extensions = array_merge( $extensions, explode( '|', $extension ) );
+ }
$defaults = array(
'runtimes' => 'html5,flash,silverlight,html4',
'silverlight_xap_url' => includes_url( 'js/plupload/plupload.silverlight.xap' ),
'filters' => array(
'max_file_size' => $max_upload_size . 'b',
+ 'mime_types' => array( array( 'extensions' => implode( ',', $extensions ) ) ),
),
);
}
/**
- * Filter the Plupload default settings.
+ * Filters the Plupload default settings.
*
* @since 3.4.0
*
);
/**
- * Filter the Plupload default parameters.
+ * Filters the Plupload default parameters.
*
* @since 3.4.0
*
list( $type, $subtype ) = array( $attachment->post_mime_type, '' );
$attachment_url = wp_get_attachment_url( $attachment->ID );
+ $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
$response = array(
'id' => $attachment->ID,
'type' => $type,
'subtype' => $subtype,
'icon' => wp_mime_type_icon( $attachment->ID ),
- 'dateFormatted' => mysql2date( get_option('date_format'), $attachment->post_date ),
+ 'dateFormatted' => mysql2date( __( 'F j, Y' ), $attachment->post_date ),
'nonces' => array(
'update' => false,
'delete' => false,
if ( $post_parent ) {
$parent_type = get_post_type_object( $post_parent->post_type );
+
if ( $parent_type && $parent_type->show_ui && current_user_can( 'edit_post', $attachment->post_parent ) ) {
$response['uploadedToLink'] = get_edit_post_link( $attachment->post_parent, 'raw' );
}
- $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
+
+ if ( $parent_type && current_user_can( 'read_post', $attachment->post_parent ) ) {
+ $response['uploadedToTitle'] = $post_parent->post_title ? $post_parent->post_title : __( '(no title)' );
+ }
}
$attached_file = get_attached_file( $attachment->ID );
if ( current_user_can( 'delete_post', $attachment->ID ) )
$response['nonces']['delete'] = wp_create_nonce( 'delete-post_' . $attachment->ID );
- if ( $meta && 'image' === $type ) {
+ if ( $meta && ( 'image' === $type || ! empty( $meta['sizes'] ) ) ) {
$sizes = array();
/** This filter is documented in wp-admin/includes/media.php */
/** This filter is documented in wp-includes/media.php */
if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) {
- if ( ! $downsize[3] )
+ if ( empty( $downsize[3] ) ) {
continue;
+ }
+
$sizes[ $size ] = array(
'height' => $downsize[2],
'width' => $downsize[1],
'orientation' => $downsize[2] > $downsize[1] ? 'portrait' : 'landscape',
);
} elseif ( isset( $meta['sizes'][ $size ] ) ) {
- if ( ! isset( $base_url ) )
- $base_url = str_replace( wp_basename( $attachment_url ), '', $attachment_url );
-
// Nothing from the filter, so consult image metadata if we have it.
$size_meta = $meta['sizes'][ $size ];
}
}
- $sizes['full'] = array( 'url' => $attachment_url );
+ if ( 'image' === $type ) {
+ $sizes['full'] = array( 'url' => $attachment_url );
+
+ if ( isset( $meta['height'], $meta['width'] ) ) {
+ $sizes['full']['height'] = $meta['height'];
+ $sizes['full']['width'] = $meta['width'];
+ $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
+ }
- if ( isset( $meta['height'], $meta['width'] ) ) {
- $sizes['full']['height'] = $meta['height'];
- $sizes['full']['width'] = $meta['width'];
- $sizes['full']['orientation'] = $meta['height'] > $meta['width'] ? 'portrait' : 'landscape';
+ $response = array_merge( $response, $sizes['full'] );
+ } elseif ( $meta['sizes']['full']['file'] ) {
+ $sizes['full'] = array(
+ 'url' => $base_url . $meta['sizes']['full']['file'],
+ 'height' => $meta['sizes']['full']['height'],
+ 'width' => $meta['sizes']['full']['width'],
+ 'orientation' => $meta['sizes']['full']['height'] > $meta['sizes']['full']['width'] ? 'portrait' : 'landscape'
+ );
}
- $response = array_merge( $response, array( 'sizes' => $sizes ), $sizes['full'] );
- } elseif ( $meta && 'video' === $type ) {
+ $response = array_merge( $response, array( 'sizes' => $sizes ) );
+ }
+
+ if ( $meta && 'video' === $type ) {
if ( isset( $meta['width'] ) )
$response['width'] = (int) $meta['width'];
if ( isset( $meta['height'] ) )
$response['compat'] = get_compat_media_markup( $attachment->ID, array( 'in_modal' => true ) );
/**
- * Filter the attachment data prepared for JavaScript.
+ * Filters the attachment data prepared for JavaScript.
*
* @since 3.5.0
*
'filterByDate' => __( 'Filter by date' ),
'filterByType' => __( 'Filter by type' ),
'searchMediaLabel' => __( 'Search Media' ),
- 'noMedia' => __( 'No media attachments found.' ),
+ 'searchMediaPlaceholder' => __( 'Search media items...' ), // placeholder (no ellipsis)
+ 'noMedia' => __( 'No media files found.' ),
// Library Details
'attachmentDetails' => __( 'Attachment Details' ),
);
/**
- * Filter the media view settings.
+ * Filters the media view settings.
*
* @since 3.5.0
*
$settings = apply_filters( 'media_view_settings', $settings, $post );
/**
- * Filter the media view strings.
+ * Filters the media view strings.
*
* @since 3.5.0
*
);
/**
- * Filter arguments used to retrieve media attached to the given post.
+ * Filters arguments used to retrieve media attached to the given post.
*
* @since 3.6.0
*
$children = get_children( $args );
/**
- * Filter the list of media attached to the given post.
+ * Filters the list of media attached to the given post.
*
* @since 3.6.0
*
$html = array();
/**
- * Filter the embedded media types that are allowed to be returned from the content blob.
+ * Filters the embedded media types that are allowed to be returned from the content blob.
*
* @since 4.2.0
*
}
/**
- * Filter the list of all found galleries in the given post.
+ * Filters the list of all found galleries in the given post.
*
* @since 3.6.0
*
$gallery = reset( $galleries );
/**
- * Filter the first-found post gallery.
+ * Filters the first-found post gallery.
*
* @since 3.6.0
*
function attachment_url_to_postid( $url ) {
global $wpdb;
- $dir = wp_upload_dir();
+ $dir = wp_get_upload_dir();
$path = $url;
$site_url = parse_url( $dir['url'] );
$post_id = $wpdb->get_var( $sql );
/**
- * Filter an attachment id found by URL.
+ * Filters an attachment id found by URL.
*
* @since 4.2.0
*
*
* @since 4.0.0
*
- * @global string $wp_version
- *
* @return array The relevant CSS file URLs.
*/
function wpview_media_sandbox_styles() {
- $version = 'ver=' . $GLOBALS['wp_version'];
+ $version = 'ver=' . get_bloginfo( 'version' );
$mediaelement = includes_url( "js/mediaelement/mediaelementplayer.min.css?$version" );
$wpmediaelement = includes_url( "js/mediaelement/wp-mediaelement.css?$version" );