From ca84ae50302e90ec90251f07e28c56f085116b16 Mon Sep 17 00:00:00 2001 From: Andrew Ozz Date: Sat, 15 Jun 2019 01:01:48 +0000 Subject: [PATCH] Save progress of intermediate image creation after upload. First run. - Introduces `wp_get_missing_image_subsizes()` and `wp_update_image_subsizes()` to generate image sub-sizes that are missing or were not created after the upload. - Adds a way to display errors that happened while creating sub-sizes. - Introduces `wp_create_image_subsizes()` intended for use after an image was uploaded. It saves/updates the image metadata immediately after each sub-size is created. This fixes the (long standing) problem when some of the sub-size image files were created but there was a timeout or an error and the metadata was not saved. Until now such uploads were considered "failed" which usually resulted in the user trying to upload the same image again, creating even more "orphan" image files. Note that the patch also includes some unrelated WPCS fixes. Props mikeschroder, azaozz. See #40439. git-svn-id: https://develop.svn.wordpress.org/trunk@45538 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/image.php | 335 ++++++++++++------ src/wp-includes/class-wp-image-editor-gd.php | 91 +++-- .../class-wp-image-editor-imagick.php | 108 +++--- src/wp-includes/media.php | 270 ++++++++++---- 4 files changed, 553 insertions(+), 251 deletions(-) diff --git a/src/wp-admin/includes/image.php b/src/wp-admin/includes/image.php index d0a2954e5f..0ce97b5f76 100644 --- a/src/wp-admin/includes/image.php +++ b/src/wp-admin/includes/image.php @@ -67,7 +67,220 @@ function wp_crop_image( $src, $src_x, $src_y, $src_w, $src_h, $dst_w, $dst_h, $s } /** - * Generate post thumbnail attachment meta data. + * Compare the existing image sub-sizes (as saved in the attachment meta) + * to the currently registered image sub-sizes, and return the difference. + * + * Registered sub-sizes that are larger than the image are skipped. + * + * @since 5.3.0 + * + * @param int $attachment_id The image attachment post ID. + * @return array An array of the image sub-sizes that are currently defined but don't exist for this image. + */ +function wp_get_missing_image_subsizes( $attachment_id ) { + if ( ! wp_attachment_is_image( $attachment_id ) ) { + return array(); + } + + $registered_sizes = wp_get_registered_image_subsizes(); + $image_meta = wp_get_attachment_metadata( $attachment_id ); + + // Meta error? + if ( empty( $image_meta ) ) { + return $defined_sizes; + } + + $full_width = (int) $image_meta['width']; + $full_height = (int) $image_meta['height']; + $possible_sizes = array(); + + // Skip registered sizes that are too large for the uploaded image. + foreach ( $registered_sizes as $size_name => $size_data ) { + if ( image_resize_dimensions( $full_width, $full_height, $size_data['width'], $size_data['height'], $size_data['crop'] ) ) { + $possible_sizes[ $size_name ] = $size_data; + } + } + + if ( empty( $image_meta['sizes'] ) ) { + $image_meta['sizes'] = array(); + } + + // Remove sizes that already exist. Only checks for matching "size names". + // It is possible that the dimensions for a particular size name have changed. + // For example the user has changed the values on the Settings -> Media screen. + // However we keep the old sub-sizes with the previous dimensions + // as the image may have been used in an older post. + $missing_sizes = array_diff_key( $possible_sizes, $image_meta['sizes'] ); + + /** + * Filters the array of missing image sub-sizes for an uploaded image. + * + * @since 5.3.0 + * + * @param array $missing_sizes Array with the missing image sub-sizes. + * @param array $image_meta The image meta data. + * @param int $attachment_id The image attachment post ID. + */ + return apply_filters( 'wp_get_missing_image_subsizes', $missing_sizes, $image_meta, $attachment_id ); +} + +/** + * If any of the currently registered image sub-sizes are missing, + * create them and update the image meta data. + * + * @since 5.3.0 + * + * @param int $attachment_id The image attachment post ID. + * @return array The updated image meta data array. + */ +function wp_update_image_subsizes( $attachment_id ) { + $missing_sizes = wp_get_missing_image_subsizes( $attachment_id ); + $image_meta = wp_get_attachment_metadata( $attachment_id ); + + if ( empty( $missing_sizes ) ) { + return $image_meta; + } + + $image_file = get_attached_file( $attachment_id ); + + // This also updates the image meta. + return _wp_make_subsizes( $missing_sizes, $image_file, $image_meta, $attachment_id ); +} + +/** + * Creates image sub-sizes, adds the new data to the image meta `sizes` array, and updates the image metadata. + * + * Intended for use after an image is uploaded. Saves/updates the image metadata after each + * sub-size is created. If there was an error, it is added to the returned image metadata array. + * + * @since 5.3.0 + * + * @param string $file Full path to the image file. + * @param array $image_meta The attachment meta data array. + * @param int $attachment_id Attachment Id to process. + * @return array The attachment metadata with updated `sizes` array. Includes an array of errors encountered while resizing. + */ +function wp_create_image_subsizes( $file, $image_meta, $attachment_id ) { + if ( empty( $image_meta ) || ! isset( $image_meta['width'], $image_meta['height'] ) ) { + // New uploaded image. + $imagesize = getimagesize( $file ); + $image_meta['width'] = $imagesize[0]; + $image_meta['height'] = $imagesize[1]; + + // Make the file path relative to the upload dir. + $image_meta['file'] = _wp_relative_upload_path( $file ); + + // Fetch additional metadata from EXIF/IPTC. + $exif_meta = wp_read_image_metadata( $file ); + + if ( $exif_meta ) { + $image_meta['image_meta'] = $exif_meta; + } + } + + $new_sizes = wp_get_registered_image_subsizes(); + + /** + * Filters the image sizes automatically generated when uploading an image. + * + * @since 2.9.0 + * @since 4.4.0 Added the `$image_meta` argument. + * @since 5.3.0 Added the `$attachment_id` argument. + * + * @param array $new_sizes Associative array of image sizes to be created. + * @param array $image_meta The image meta data: width, height, file, sizes, etc. + * @param int $attachment_id The attachment post ID for the image. + */ + $new_sizes = apply_filters( 'intermediate_image_sizes_advanced', $new_sizes, $image_meta, $attachment_id ); + + return _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ); +} + +/** + * Low-level function to create image sub-sizes. + * + * Updates the image meta after each sub-size is created. + * Errors are stored in the returned image metadata array. + * + * @since 5.3.0 + * @access private + * + * $padam array $new_sizes Array defining what sizes to create. + * @param string $file Full path to the image file. + * @param array $image_meta The attachment meta data array. + * @param int $attachment_id Attachment Id to process. + * @return array The attachment meta data with updated `sizes` array. Includes an array of errors encountered while resizing. + */ +function _wp_make_subsizes( $new_sizes, $file, $image_meta, $attachment_id ) { + // Check if any of the new sizes already exist. + if ( isset( $image_meta['sizes'] ) && is_array( $image_meta['sizes'] ) ) { + foreach ( $image_meta['sizes'] as $size_name => $size_meta ) { + // Only checks "size name" so we don't override existing images even if the dimensions + // don't match the currently defined size with the same name. + // To change the behavior, unset changed/mismatched sizes in the `sizes` array in image meta. + if ( array_key_exists( $size_name, $new_sizes ) ) { + unset( $new_sizes[ $size_name ] ); + } + } + } else { + $image_meta['sizes'] = array(); + } + + if ( ! empty( $new_sizes ) ) { + $editor = wp_get_image_editor( $file ); + + if ( ! is_wp_error( $editor ) ) { + if ( method_exists( $editor, 'make_subsize' ) ) { + foreach ( $new_sizes as $new_size_name => $new_size_data ) { + $new_size_meta = $editor->make_subsize( $new_size_data ); + + if ( is_wp_error( $new_size_meta ) ) { + if ( empty( $image_meta['subsize_errors'] ) ) { + $image_meta['subsize_errors'] = array(); + } + + $error = array( + 'error_code' => $new_size_meta->get_error_code(), + 'error_message' => $new_size_meta->get_error_message(), + ); + + // Store the error code and error message for displaying in the UI. + $image_meta['subsize_errors'][ $new_size_name ] = $error; + } else { + // The sub-size was created successfully. + // Clear out previous errors in creating this subsize. + if ( ! empty( $image_meta['subsize_errors'][ $new_size_name ] ) ) { + unset( $image_meta['subsize_errors'][ $new_size_name ] ); + } + + if ( empty( $image_meta['subsize_errors'] ) ) { + unset( $image_meta['subsize_errors'] ); + } + + // Save the size meta value. + $image_meta['sizes'][ $new_size_name ] = $new_size_meta; + } + + wp_update_attachment_metadata( $attachment_id, $image_meta ); + } + } else { + // Fall back to `$editor->multi_resize()`. + $created_sizes = $editor->multi_resize( $new_sizes ); + + if ( ! empty( $created_sizes ) ) { + $image_meta['sizes'] = array_merge( $image_meta['sizes'], $created_sizes ); + unset( $image_meta['subsize_errors'] ); + wp_update_attachment_metadata( $attachment_id, $image_meta ); + } + } + } + } + + return $image_meta; +} + +/** + * Generate attachment meta data and create image sub-sizes for images. * * @since 2.1.0 * @@ -83,76 +296,8 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) { $mime_type = get_post_mime_type( $attachment ); if ( preg_match( '!^image/!', $mime_type ) && file_is_displayable_image( $file ) ) { - $imagesize = getimagesize( $file ); - $metadata['width'] = $imagesize[0]; - $metadata['height'] = $imagesize[1]; - - // Make the file path relative to the upload dir. - $metadata['file'] = _wp_relative_upload_path( $file ); - // Make thumbnails and other intermediate sizes. - $_wp_additional_image_sizes = wp_get_additional_image_sizes(); - - $sizes = array(); - foreach ( get_intermediate_image_sizes() as $s ) { - $sizes[ $s ] = array( - 'width' => '', - 'height' => '', - 'crop' => false, - ); - if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) { - // For theme-added sizes - $sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] ); - } else { - // For default sizes set in options - $sizes[ $s ]['width'] = get_option( "{$s}_size_w" ); - } - - if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) { - // For theme-added sizes - $sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] ); - } else { - // For default sizes set in options - $sizes[ $s ]['height'] = get_option( "{$s}_size_h" ); - } - - if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) { - // For theme-added sizes - $sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop']; - } else { - // For default sizes set in options - $sizes[ $s ]['crop'] = get_option( "{$s}_crop" ); - } - } - - /** - * Filters the image sizes automatically generated when uploading an image. - * - * @since 2.9.0 - * @since 4.4.0 Added the `$metadata` argument. - * @since 5.1.0 Added the `$attachment_id` argument. - * - * @param array $sizes An associative array of image sizes. - * @param array $metadata An associative array of image metadata: width, height, file. - * @param int $attachment_id Current attachment ID. - */ - $sizes = apply_filters( 'intermediate_image_sizes_advanced', $sizes, $metadata, $attachment_id ); - - if ( $sizes ) { - $editor = wp_get_image_editor( $file ); - - if ( ! is_wp_error( $editor ) ) { - $metadata['sizes'] = $editor->multi_resize( $sizes ); - } - } else { - $metadata['sizes'] = array(); - } - - // Fetch additional metadata from EXIF/IPTC. - $image_meta = wp_read_image_metadata( $file ); - if ( $image_meta ) { - $metadata['image_meta'] = $image_meta; - } + $metadata = wp_create_image_subsizes( $file, $metadata, $attachment_id ); } elseif ( wp_attachment_is( 'video', $attachment ) ) { $metadata = wp_read_video_metadata( $file ); $support = current_theme_supports( 'post-thumbnails', 'attachment:video' ) || post_type_supports( 'attachment:video', 'thumbnail' ); @@ -234,34 +379,16 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) { */ $fallback_sizes = apply_filters( 'fallback_intermediate_image_sizes', $fallback_sizes, $metadata ); - $sizes = array(); - $_wp_additional_image_sizes = wp_get_additional_image_sizes(); + $defined_sizes = wp_get_registered_image_subsizes(); + $merged_sizes = array_intersect_key( $defined_sizes, array_flip( $fallback_sizes ) ); - foreach ( $fallback_sizes as $s ) { - if ( isset( $_wp_additional_image_sizes[ $s ]['width'] ) ) { - $sizes[ $s ]['width'] = intval( $_wp_additional_image_sizes[ $s ]['width'] ); - } else { - $sizes[ $s ]['width'] = get_option( "{$s}_size_w" ); - } - - if ( isset( $_wp_additional_image_sizes[ $s ]['height'] ) ) { - $sizes[ $s ]['height'] = intval( $_wp_additional_image_sizes[ $s ]['height'] ); - } else { - $sizes[ $s ]['height'] = get_option( "{$s}_size_h" ); - } - - if ( isset( $_wp_additional_image_sizes[ $s ]['crop'] ) ) { - $sizes[ $s ]['crop'] = $_wp_additional_image_sizes[ $s ]['crop']; - } else { - // Force thumbnails to be soft crops. - if ( 'thumbnail' !== $s ) { - $sizes[ $s ]['crop'] = get_option( "{$s}_crop" ); - } - } + // Force thumbnails to be soft crops. + if ( isset( $merged_sizes['thumbnail'] ) && is_array( $merged_sizes['thumbnail'] ) ) { + $merged_sizes['thumbnail']['crop'] = false; } // Only load PDFs in an image editor if we're processing sizes. - if ( ! empty( $sizes ) ) { + if ( ! empty( $merged_sizes ) ) { $editor = wp_get_image_editor( $file ); if ( ! is_wp_error( $editor ) ) { // No support for this type of file @@ -282,7 +409,7 @@ function wp_generate_attachment_metadata( $attachment_id, $file ) { unset( $uploaded['path'] ); if ( ! is_wp_error( $editor ) ) { - $metadata['sizes'] = $editor->multi_resize( $sizes ); + $metadata['sizes'] = $editor->multi_resize( $merged_sizes ); $metadata['sizes']['full'] = $uploaded; } } @@ -449,7 +576,7 @@ function wp_read_image_metadata( $file ) { */ $exif_image_types = apply_filters( 'wp_read_image_metadata_types', array( IMAGETYPE_JPEG, IMAGETYPE_TIFF_II, IMAGETYPE_TIFF_MM ) ); - if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types ) ) { + if ( is_callable( 'exif_read_data' ) && in_array( $image_type, $exif_image_types, true ) ) { $exif = @exif_read_data( $file ); if ( ! empty( $exif['ImageDescription'] ) ) { @@ -571,7 +698,7 @@ function file_is_displayable_image( $path ) { $info = @getimagesize( $path ); if ( empty( $info ) ) { $result = false; - } elseif ( ! in_array( $info[2], $displayable_image_types ) ) { + } elseif ( ! in_array( $info[2], $displayable_image_types, true ) ) { $result = false; } else { $result = true; @@ -654,7 +781,11 @@ function _load_image_to_edit_path( $attachment_id, $size = 'full' ) { $filepath = get_attached_file( $attachment_id ); if ( $filepath && file_exists( $filepath ) ) { - if ( 'full' != $size && ( $data = image_get_intermediate_size( $attachment_id, $size ) ) ) { + $data = image_get_intermediate_size( $attachment_id, $size ); + + if ( 'full' != $size && $data ) { + $filepath = path_join( dirname( $filepath ), $data['file'] ); + /** * Filters the path to the current image. * @@ -666,9 +797,9 @@ function _load_image_to_edit_path( $attachment_id, $size = 'full' ) { * @param string $attachment_id Attachment ID. * @param string $size Size of the image. */ - $filepath = apply_filters( 'load_image_to_edit_filesystempath', path_join( dirname( $filepath ), $data['file'] ), $attachment_id, $size ); + $filepath = apply_filters( 'load_image_to_edit_filesystempath', $filepath, $attachment_id, $size ); } - } elseif ( function_exists( 'fopen' ) && true == ini_get( 'allow_url_fopen' ) ) { + } elseif ( function_exists( 'fopen' ) && true === ini_get( 'allow_url_fopen' ) ) { /** * Filters the image URL if not in the local filesystem. * @@ -705,7 +836,9 @@ function _load_image_to_edit_path( $attachment_id, $size = 'full' ) { * @return string|false New file path on success, false on failure. */ function _copy_image_file( $attachment_id ) { - $dst_file = $src_file = get_attached_file( $attachment_id ); + $dst_file = get_attached_file( $attachment_id ); + $src_file = $dst_file; + if ( ! file_exists( $src_file ) ) { $src_file = _load_image_to_edit_path( $attachment_id ); } diff --git a/src/wp-includes/class-wp-image-editor-gd.php b/src/wp-includes/class-wp-image-editor-gd.php index 72fb04ee72..182e8e1efe 100644 --- a/src/wp-includes/class-wp-image-editor-gd.php +++ b/src/wp-includes/class-wp-image-editor-gd.php @@ -43,7 +43,7 @@ class WP_Image_Editor_GD extends WP_Image_Editor { // On some setups GD library does not provide imagerotate() - Ticket #11536 if ( isset( $args['methods'] ) && - in_array( 'rotate', $args['methods'] ) && + in_array( 'rotate', $args['methods'], true ) && ! function_exists( 'imagerotate' ) ) { return false; @@ -178,9 +178,11 @@ class WP_Image_Editor_GD extends WP_Image_Editor { */ protected function _resize( $max_w, $max_h, $crop = false ) { $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop ); + if ( ! $dims ) { return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file ); } + list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; $resized = wp_imagecreatetruecolor( $dst_w, $dst_h ); @@ -217,45 +219,64 @@ class WP_Image_Editor_GD extends WP_Image_Editor { * @return array An array of resized images' metadata by size. */ public function multi_resize( $sizes ) { - $metadata = array(); - $orig_size = $this->size; + $metadata = array(); foreach ( $sizes as $size => $size_data ) { - if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { - continue; + $meta = $this->make_subsize( $size_data ); + + if ( ! is_wp_error( $meta ) ) { + $metadata[ $size ] = $meta; } - - if ( ! isset( $size_data['width'] ) ) { - $size_data['width'] = null; - } - if ( ! isset( $size_data['height'] ) ) { - $size_data['height'] = null; - } - - if ( ! isset( $size_data['crop'] ) ) { - $size_data['crop'] = false; - } - - $image = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); - $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); - - if ( ! is_wp_error( $image ) && ! $duplicate ) { - $resized = $this->_save( $image ); - - imagedestroy( $image ); - - if ( ! is_wp_error( $resized ) && $resized ) { - unset( $resized['path'] ); - $metadata[ $size ] = $resized; - } - } - - $this->size = $orig_size; } return $metadata; } + /** + * Create an image sub-size and return the image meta data value for it. + * + * @since 5.3.0 + * + * @param array $size_data Array of width, height, and whether to crop. + * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta. + */ + public function make_subsize( $size_data ) { + if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { + return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) ); + } + + $orig_size = $this->size; + + if ( ! isset( $size_data['width'] ) ) { + $size_data['width'] = null; + } + + if ( ! isset( $size_data['height'] ) ) { + $size_data['height'] = null; + } + + if ( ! isset( $size_data['crop'] ) ) { + $size_data['crop'] = false; + } + + $resized = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); + + if ( is_wp_error( $resized ) ) { + $saved = $resized; + } else { + $saved = $this->_save( $resized ); + imagedestroy( $resized ); + } + + $this->size = $orig_size; + + if ( ! is_wp_error( $saved ) ) { + unset( $saved['path'] ); + } + + return $saved; + } + /** * Crops Image. * @@ -391,11 +412,11 @@ class WP_Image_Editor_GD extends WP_Image_Editor { $filename = $this->generate_filename( null, null, $extension ); } - if ( 'image/gif' == $mime_type ) { + if ( 'image/gif' === $mime_type ) { if ( ! $this->make_image( $filename, 'imagegif', array( $image, $filename ) ) ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); } - } elseif ( 'image/png' == $mime_type ) { + } elseif ( 'image/png' === $mime_type ) { // convert from full colors to index colors, like original PNG. if ( function_exists( 'imageistruecolor' ) && ! imageistruecolor( $image ) ) { imagetruecolortopalette( $image, false, imagecolorstotal( $image ) ); @@ -404,7 +425,7 @@ class WP_Image_Editor_GD extends WP_Image_Editor { if ( ! $this->make_image( $filename, 'imagepng', array( $image, $filename ) ) ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); } - } elseif ( 'image/jpeg' == $mime_type ) { + } elseif ( 'image/jpeg' === $mime_type ) { if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) { return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) ); } diff --git a/src/wp-includes/class-wp-image-editor-imagick.php b/src/wp-includes/class-wp-image-editor-imagick.php index abb215038b..d3ba054b25 100644 --- a/src/wp-includes/class-wp-image-editor-imagick.php +++ b/src/wp-includes/class-wp-image-editor-imagick.php @@ -108,7 +108,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { // setIteratorIndex is optional unless mime is an animated format. // Here, we just say no if you are missing it and aren't loading a jpeg. - if ( ! method_exists( 'Imagick', 'setIteratorIndex' ) && $mime_type != 'image/jpeg' ) { + if ( ! method_exists( 'Imagick', 'setIteratorIndex' ) && $mime_type !== 'image/jpeg' ) { return false; } @@ -146,7 +146,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { $file_extension = strtolower( pathinfo( $this->file, PATHINFO_EXTENSION ) ); $filename = $this->file; - if ( 'pdf' == $file_extension ) { + if ( 'pdf' === $file_extension ) { $filename = $this->pdf_setup(); } @@ -193,7 +193,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { } try { - if ( 'image/jpeg' == $this->mime_type ) { + if ( 'image/jpeg' === $this->mime_type ) { $this->image->setImageCompressionQuality( $quality ); $this->image->setImageCompression( imagick::COMPRESSION_JPEG ); } else { @@ -260,6 +260,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { if ( ! $dims ) { return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ) ); } + list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims; if ( $crop ) { @@ -312,7 +313,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { * Set the filter value if '$filter_name' name is in our whitelist and the related * Imagick constant is defined or fall back to our default filter. */ - if ( in_array( $filter_name, $allowed_filters ) && defined( 'Imagick::' . $filter_name ) ) { + if ( in_array( $filter_name, $allowed_filters, true ) && defined( 'Imagick::' . $filter_name ) ) { $filter = constant( 'Imagick::' . $filter_name ); } else { $filter = defined( 'Imagick::FILTER_TRIANGLE' ) ? Imagick::FILTER_TRIANGLE : false; @@ -361,7 +362,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { } // Set appropriate quality settings after resizing. - if ( 'image/jpeg' == $this->mime_type ) { + if ( 'image/jpeg' === $this->mime_type ) { if ( is_callable( array( $this->image, 'unsharpMaskImage' ) ) ) { $this->image->unsharpMaskImage( 0.25, 0.25, 8, 0.065 ); } @@ -413,7 +414,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { * @since 3.5.0 * * @param array $sizes { - * An array of image size arrays. Default sizes are 'small', 'medium', 'medium_large', 'large'. + * An array of image size arrays. Default sizes are 'thumbnail', 'medium', 'medium_large', 'large'. * * Either a height or width must be provided. * If one of the two is set to null, the resize will @@ -430,52 +431,67 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { * @return array An array of resized images' metadata by size. */ public function multi_resize( $sizes ) { - $metadata = array(); + $metadata = array(); + + foreach ( $sizes as $size => $size_data ) { + $meta = $this->make_subsize( $size_data ); + + if ( ! is_wp_error( $meta ) ) { + $metadata[ $size ] = $meta; + } + } + + return $metadata; + } + + /** + * Create an image sub-size and return the image meta data value for it. + * + * @since 5.3.0 + * + * @param array $size_data Array of width, height, and whether to crop. + * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta. + */ + public function make_subsize( $size_data ) { + if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { + return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) ); + } + $orig_size = $this->size; $orig_image = $this->image->getImage(); - foreach ( $sizes as $size => $size_data ) { - if ( ! $this->image ) { - $this->image = $orig_image->getImage(); - } - - if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) { - continue; - } - - if ( ! isset( $size_data['width'] ) ) { - $size_data['width'] = null; - } - if ( ! isset( $size_data['height'] ) ) { - $size_data['height'] = null; - } - - if ( ! isset( $size_data['crop'] ) ) { - $size_data['crop'] = false; - } - - $resize_result = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); - $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) ); - - if ( ! is_wp_error( $resize_result ) && ! $duplicate ) { - $resized = $this->_save( $this->image ); - - $this->image->clear(); - $this->image->destroy(); - $this->image = null; - - if ( ! is_wp_error( $resized ) && $resized ) { - unset( $resized['path'] ); - $metadata[ $size ] = $resized; - } - } - - $this->size = $orig_size; + if ( ! isset( $size_data['width'] ) ) { + $size_data['width'] = null; } + if ( ! isset( $size_data['height'] ) ) { + $size_data['height'] = null; + } + + if ( ! isset( $size_data['crop'] ) ) { + $size_data['crop'] = false; + } + + $resized = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] ); + + if ( is_wp_error( $resized ) ) { + $saved = $resized; + } else { + $saved = $this->_save( $this->image ); + + $this->image->clear(); + $this->image->destroy(); + $this->image = null; + } + + $this->size = $orig_size; $this->image = $orig_image; - return $metadata; + if ( ! is_wp_error( $saved ) ) { + unset( $saved['path'] ); + } + + return $saved; } /** @@ -717,7 +733,7 @@ class WP_Image_Editor_Imagick extends WP_Image_Editor { try { // Strip profiles. foreach ( $this->image->getImageProfiles( '*', true ) as $key => $value ) { - if ( ! in_array( $key, $protected_profiles ) ) { + if ( ! in_array( $key, $protected_profiles, true ) ) { $this->image->removeImageProfile( $key ); } } diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index 743e8d7e83..20cc1b4261 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -17,9 +17,11 @@ */ 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; } @@ -66,7 +68,7 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co if ( is_array( $size ) ) { $max_width = $size[0]; $max_height = $size[1]; - } elseif ( $size == 'thumb' || $size == 'thumbnail' ) { + } elseif ( $size === 'thumb' || $size === 'thumbnail' ) { $max_width = intval( get_option( 'thumbnail_size_w' ) ); $max_height = intval( get_option( 'thumbnail_size_h' ) ); // last chance thumbnail size defaults @@ -74,18 +76,18 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co $max_width = 128; $max_height = 96; } - } elseif ( $size == 'medium' ) { + } elseif ( $size === 'medium' ) { $max_width = intval( get_option( 'medium_size_w' ) ); $max_height = intval( get_option( 'medium_size_h' ) ); - } elseif ( $size == 'medium_large' ) { + } elseif ( $size === 'medium_large' ) { $max_width = intval( get_option( 'medium_large_size_w' ) ); $max_height = intval( get_option( 'medium_large_size_h' ) ); if ( intval( $content_width ) > 0 ) { $max_width = min( intval( $content_width ), $max_width ); } - } elseif ( $size == 'large' ) { + } elseif ( $size === 'large' ) { /* * We're inserting a large size image into the editor. If it's a really * big image we'll scale it down to fit reasonably within the editor @@ -94,10 +96,11 @@ function image_constrain_size_for_editor( $width, $height, $size = 'medium', $co */ $max_width = intval( get_option( 'large_size_w' ) ); $max_height = intval( get_option( 'large_size_h' ) ); + if ( intval( $content_width ) > 0 ) { $max_width = min( intval( $content_width ), $max_width ); } - } elseif ( ! empty( $_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 ), true ) ) { $max_width = intval( $_wp_additional_image_sizes[ $size ]['width'] ); $max_height = intval( $_wp_additional_image_sizes[ $size ]['height'] ); // Only in admin. Assume that theme authors know what they're doing. @@ -195,13 +198,16 @@ function image_downsize( $id, $size = 'medium' ) { * @param array|string $size Size of image. Image size or array of width and height values (in that order). * Default 'medium'. */ - if ( $out = apply_filters( 'image_downsize', false, $id, $size ) ) { + $out = apply_filters( 'image_downsize', false, $id, $size ); + + if ( $out ) { return $out; } $img_url = wp_get_attachment_url( $id ); $meta = wp_get_attachment_metadata( $id ); - $width = $height = 0; + $width = 0; + $height = 0; $is_intermediate = false; $img_url_basename = wp_basename( $img_url ); @@ -219,20 +225,26 @@ function image_downsize( $id, $size = 'medium' ) { } // try for a new style intermediate size - if ( $intermediate = image_get_intermediate_size( $id, $size ) ) { + $intermediate = image_get_intermediate_size( $id, $size ); + + if ( $intermediate ) { $img_url = str_replace( $img_url_basename, $intermediate['file'], $img_url ); $width = $intermediate['width']; $height = $intermediate['height']; $is_intermediate = true; - } elseif ( $size == 'thumbnail' ) { + } elseif ( $size === 'thumbnail' ) { // fall back to the old thumbnail - if ( ( $thumb_file = wp_get_attachment_thumb_file( $id ) ) && $info = getimagesize( $thumb_file ) ) { + $thumb_file = wp_get_attachment_thumb_file( $id ); + $info = getimagesize( $thumb_file ); + + if ( $thumb_file && $info ) { $img_url = str_replace( $img_url_basename, wp_basename( $thumb_file ), $img_url ); $width = $info[0]; $height = $info[1]; $is_intermediate = true; } } + if ( ! $width && ! $height && isset( $meta['width'], $meta['height'] ) ) { // any other type: use the real image $width = $meta['width']; @@ -245,8 +257,8 @@ function image_downsize( $id, $size = 'medium' ) { return array( $img_url, $width, $height, $is_intermediate ); } - return false; + return false; } /** @@ -412,8 +424,10 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width = return array( $current_width, $current_height ); } - $width_ratio = $height_ratio = 1.0; - $did_width = $did_height = false; + $width_ratio = 1.0; + $height_ratio = 1.0; + $did_width = false; + $did_height = false; if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) { $width_ratio = $max_width / $current_width; @@ -446,12 +460,12 @@ function wp_constrain_dimensions( $current_width, $current_height, $max_width = // Thus we look for dimensions that are one pixel shy of the max value and bump them up // Note: $did_width means it is possible $smaller_ratio == $width_ratio. - if ( $did_width && $w == $max_width - 1 ) { + if ( $did_width && $w === $max_width - 1 ) { $w = $max_width; // Round it up } // Note: $did_height means it is possible $smaller_ratio == $height_ratio. - if ( $did_height && $h == $max_height - 1 ) { + if ( $did_height && $h === $max_height - 1 ) { $h = $max_height; // Round it up } @@ -520,6 +534,7 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa * An array can specify positioning of the crop area. Default false. */ $output = apply_filters( 'image_resize_dimensions', null, $orig_w, $orig_h, $dest_w, $dest_h, $crop ); + if ( null !== $output ) { return $output; } @@ -576,7 +591,7 @@ function image_resize_dimensions( $orig_w, $orig_h, $dest_w, $dest_h, $crop = fa } // if the resulting image would be the same size or larger we don't want to resize it - if ( $new_w >= $orig_w && $new_h >= $orig_h && $dest_w != $orig_w && $dest_h != $orig_h ) { + if ( $new_w >= $orig_w && $new_h >= $orig_h && intval( $dest_w ) !== intval( $orig_w ) && intval( $dest_h ) !== intval( $orig_h ) ) { return false; } @@ -687,7 +702,9 @@ function wp_image_matches_ratio( $source_width, $source_height, $target_width, $ * } */ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { - if ( ! $size || ! is_array( $imagedata = wp_get_attachment_metadata( $post_id ) ) || empty( $imagedata['sizes'] ) ) { + $imagedata = wp_get_attachment_metadata( $post_id ); + + if ( ! $size || ! is_array( $imagedata ) || empty( $imagedata['sizes'] ) ) { return false; } @@ -704,7 +721,7 @@ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { 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] ) { + if ( intval( $data['width'] ) === intval( $size[0] ) && intval( $data['height'] ) === intval( $size[1] ) ) { $candidates[ $data['width'] * $data['height'] ] = $data; break; } @@ -785,10 +802,11 @@ function image_get_intermediate_size( $post_id, $size = 'thumbnail' ) { * @return array Returns a filtered array of image size strings. */ function get_intermediate_image_sizes() { - $_wp_additional_image_sizes = wp_get_additional_image_sizes(); - $image_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' ); // Standard sizes - if ( ! empty( $_wp_additional_image_sizes ) ) { - $image_sizes = array_merge( $image_sizes, array_keys( $_wp_additional_image_sizes ) ); + $default_sizes = array( 'thumbnail', 'medium', 'medium_large', 'large' ); + $additional_sizes = wp_get_additional_image_sizes(); + + if ( ! empty( $additional_sizes ) ) { + $default_sizes = array_merge( $default_sizes, array_keys( $additional_sizes ) ); } /** @@ -796,10 +814,61 @@ function get_intermediate_image_sizes() { * * @since 2.5.0 * - * @param array $image_sizes An array of intermediate image sizes. Defaults - * are 'thumbnail', 'medium', 'medium_large', 'large'. + * @param array $default_sizes An array of intermediate image sizes. Defaults + * are 'thumbnail', 'medium', 'medium_large', 'large'. */ - return apply_filters( 'intermediate_image_sizes', $image_sizes ); + return apply_filters( 'intermediate_image_sizes', $default_sizes ); +} + +/** + * Returns a normalized list of all currently registered image sub-sizes. + * + * @since 5.3.0 + * @uses wp_get_additional_image_sizes() + * @uses get_intermediate_image_sizes() + * + * @return array Associative array of the registered image sub-sizes. + */ +function wp_get_registered_image_subsizes() { + $additional_sizes = wp_get_additional_image_sizes(); + $all_sizes = array(); + + foreach ( get_intermediate_image_sizes() as $size_name ) { + $size_data = array( + 'width' => 0, + 'height' => 0, + 'crop' => false, + ); + + if ( isset( $additional_sizes[ $size_name ]['width'] ) ) { + // For sizes added by plugins and themes. + $size_data['width'] = intval( $additional_sizes[ $size_name ]['width'] ); + } else { + // For default sizes set in options. + $size_data['width'] = intval( get_option( "{$size_name}_size_w" ) ); + } + + if ( isset( $additional_sizes[ $size_name ]['height'] ) ) { + $size_data['height'] = intval( $additional_sizes[ $size_name ]['height'] ); + } else { + $size_data['height'] = intval( get_option( "{$size_name}_size_h" ) ); + } + + if ( empty( $size_data['width'] ) && empty( $size_data['height'] ) ) { + // This size isn't set. + continue; + } + + if ( isset( $additional_sizes[ $size_name ]['crop'] ) ) { + $size_data['crop'] = (bool) $additional_sizes[ $size_name ]['crop']; + } else { + $size_data['crop'] = (bool) get_option( "{$size_name}_crop" ); + } + + $all_sizes[ $size_name ] = $size_data; + } + + return $all_sizes; } /** @@ -826,12 +895,16 @@ function wp_get_attachment_image_src( $attachment_id, $size = 'thumbnail', $icon if ( ! $image ) { $src = false; - if ( $icon && $src = wp_mime_type_icon( $attachment_id ) ) { - /** This filter is documented in wp-includes/post.php */ - $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); + if ( $icon ) { + $src = wp_mime_type_icon( $attachment_id ); - $src_file = $icon_dir . '/' . wp_basename( $src ); - @list( $width, $height ) = getimagesize( $src_file ); + if ( $src ) { + /** This filter is documented in wp-includes/post.php */ + $icon_dir = apply_filters( 'icon_dir', ABSPATH . WPINC . '/images/media' ); + + $src_file = $icon_dir . '/' . wp_basename( $src ); + @list( $width, $height ) = getimagesize( $src_file ); + } } if ( $src && $width && $height ) { @@ -1014,7 +1087,9 @@ function _wp_get_image_size_from_meta( $size_name, $image_meta ) { * @return string|bool A 'srcset' value string or false. */ function wp_get_attachment_image_srcset( $attachment_id, $size = 'medium', $image_meta = null ) { - if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) { + $image = wp_get_attachment_image_src( $attachment_id, $size ); + + if ( ! $image ) { return false; } @@ -1146,7 +1221,8 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac // 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; + $src_matched = true; + $is_src = true; } // Filter out images that are from previous edits. @@ -1232,7 +1308,9 @@ function wp_calculate_image_srcset( $size_array, $image_src, $image_meta, $attac * @return string|bool A valid source size value for use in a 'sizes' attribute or false. */ function wp_get_attachment_image_sizes( $attachment_id, $size = 'medium', $image_meta = null ) { - if ( ! $image = wp_get_attachment_image_src( $attachment_id, $size ) ) { + $image = wp_get_attachment_image_src( $attachment_id, $size ); + + if ( ! $image ) { return false; } @@ -1318,19 +1396,22 @@ function wp_make_content_images_responsive( $content ) { return $content; } - $selected_images = $attachment_ids = array(); + $selected_images = array(); + $attachment_ids = array(); foreach ( $matches[0] as $image ) { - if ( false === strpos( $image, ' srcset=' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) && - ( $attachment_id = absint( $class_id[1] ) ) ) { + if ( false === strpos( $image, ' srcset=' ) && preg_match( '/wp-image-([0-9]+)/i', $image, $class_id ) ) { + $attachment_id = absint( $class_id[1] ); - /* - * If exactly the same image tag is used more than once, overwrite it. - * All identical tags will be replaced later with 'str_replace()'. - */ - $selected_images[ $image ] = $attachment_id; - // Overwrite the ID when the same image is included more than once. - $attachment_ids[ $attachment_id ] = true; + if ( $attachment_id ) { + /* + * If exactly the same image tag is used more than once, overwrite it. + * All identical tags will be replaced later with 'str_replace()'. + */ + $selected_images[ $image ] = $attachment_id; + // Overwrite the ID when the same image is included more than once. + $attachment_ids[ $attachment_id ] = true; + } } } @@ -1539,7 +1620,8 @@ function img_caption_shortcode( $attr, $content = null ) { * @param string $content The image element, possibly wrapped in a hyperlink. */ $output = apply_filters( 'img_caption_shortcode', '', $attr, $content ); - if ( $output != '' ) { + + if ( ! empty( $output ) ) { return $output; } @@ -1557,11 +1639,14 @@ function img_caption_shortcode( $attr, $content = null ) { ); $atts['width'] = (int) $atts['width']; + if ( $atts['width'] < 1 || empty( $atts['caption'] ) ) { return $content; } - $id = $caption_id = $describedby = ''; + $id = ''; + $caption_id = ''; + $describedby = ''; if ( $atts['id'] ) { $atts['id'] = sanitize_html_class( $atts['id'] ); @@ -1603,6 +1688,7 @@ function img_caption_shortcode( $attr, $content = null ) { $caption_width = apply_filters( 'img_caption_shortcode_width', $width, $atts, $content ); $style = ''; + if ( $caption_width ) { $style = 'style="width: ' . (int) $caption_width . 'px" '; } @@ -1705,7 +1791,8 @@ function gallery_shortcode( $attr ) { * @param int $instance Unique numeric ID of this gallery shortcode instance. */ $output = apply_filters( 'post_gallery', '', $attr, $instance ); - if ( $output != '' ) { + + if ( ! empty( $output ) ) { return $output; } @@ -1850,9 +1937,11 @@ function gallery_shortcode( $attr ) { $output = apply_filters( 'gallery_style', $gallery_style . $gallery_div ); $i = 0; + foreach ( $attachments as $id => $attachment ) { $attr = ( trim( $attachment->post_excerpt ) ) ? array( 'aria-describedby' => "$selector-$id" ) : ''; + if ( ! empty( $atts['link'] ) && 'file' === $atts['link'] ) { $image_output = wp_get_attachment_link( $id, $atts['size'], false, false, false, $attr ); } elseif ( ! empty( $atts['link'] ) && 'none' === $atts['link'] ) { @@ -1860,25 +1949,31 @@ function gallery_shortcode( $attr ) { } else { $image_output = wp_get_attachment_link( $id, $atts['size'], true, false, false, $attr ); } + $image_meta = wp_get_attachment_metadata( $id ); $orientation = ''; + if ( isset( $image_meta['height'], $image_meta['width'] ) ) { $orientation = ( $image_meta['height'] > $image_meta['width'] ) ? 'portrait' : 'landscape'; } + $output .= "<{$itemtag} class='gallery-item'>"; $output .= " <{$icontag} class='gallery-icon {$orientation}'> $image_output "; + if ( $captiontag && trim( $attachment->post_excerpt ) ) { $output .= " <{$captiontag} class='wp-caption-text gallery-caption' id='$selector-$id'> " . wptexturize( $attachment->post_excerpt ) . " "; } + $output .= ""; - if ( ! $html5 && $columns > 0 && ++$i % $columns == 0 ) { + + if ( ! $html5 && $columns > 0 && ++$i % $columns === 0 ) { $output .= '
'; } } @@ -2025,7 +2120,8 @@ function wp_playlist_shortcode( $attr ) { * @param int $instance Unique numeric ID of this playlist shortcode instance. */ $output = apply_filters( 'post_playlist', '', $attr, $instance ); - if ( $output != '' ) { + + if ( ! empty( $output ) ) { return $output; } @@ -2335,6 +2431,7 @@ function wp_audio_shortcode( $attr, $content = '' ) { * @param int $instance Unique numeric ID of this audio shortcode instance. */ $override = apply_filters( 'wp_audio_shortcode_override', '', $attr, $content, $instance ); + if ( '' !== $override ) { return $override; } @@ -2359,15 +2456,18 @@ function wp_audio_shortcode( $attr, $content = '' ) { $primary = false; if ( ! empty( $atts['src'] ) ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); - if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) { + + if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '%s', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } + $primary = true; array_unshift( $default_types, 'src' ); } else { foreach ( $default_types as $ext ) { if ( ! empty( $atts[ $ext ] ) ) { $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() ); + if ( strtolower( $type['ext'] ) === $ext ) { $primary = true; } @@ -2377,12 +2477,14 @@ function wp_audio_shortcode( $attr, $content = '' ) { if ( ! $primary ) { $audios = get_attached_media( 'audio', $post_id ); + if ( empty( $audios ) ) { return; } $audio = reset( $audios ); $atts['src'] = wp_get_attachment_url( $audio->ID ); + if ( empty( $atts['src'] ) ) { return; } @@ -2398,6 +2500,7 @@ function wp_audio_shortcode( $attr, $content = '' ) { * @param string $library Media library used for the audio shortcode. */ $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' ); + if ( 'mediaelement' === $library && did_action( 'init' ) ) { wp_enqueue_style( 'wp-mediaelement' ); wp_enqueue_script( 'wp-mediaelement' ); @@ -2431,23 +2534,28 @@ function wp_audio_shortcode( $attr, $content = '' ) { } $attr_strings = array(); + foreach ( $html_atts as $k => $v ) { $attr_strings[] = $k . '="' . esc_attr( $v ) . '"'; } $html = ''; + if ( 'mediaelement' === $library && 1 === $instance ) { $html .= "\n"; } + $html .= sprintf( ''; /** @@ -2544,6 +2653,7 @@ function wp_video_shortcode( $attr, $content = '' ) { * @param int $instance Unique numeric ID of this video shortcode instance. */ $override = apply_filters( 'wp_video_shortcode_override', '', $attr, $content, $instance ); + if ( '' !== $override ) { return $override; } @@ -2582,7 +2692,8 @@ function wp_video_shortcode( $attr, $content = '' ) { } } - $is_vimeo = $is_youtube = false; + $is_vimeo = false; + $is_youtube = false; $yt_pattern = '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#'; $vimeo_pattern = '#^https?://(.+\.)?vimeo\.com/.*#'; @@ -2590,9 +2701,11 @@ function wp_video_shortcode( $attr, $content = '' ) { if ( ! empty( $atts['src'] ) ) { $is_vimeo = ( preg_match( $vimeo_pattern, $atts['src'] ) ); $is_youtube = ( preg_match( $yt_pattern, $atts['src'] ) ); + if ( ! $is_youtube && ! $is_vimeo ) { $type = wp_check_filetype( $atts['src'], wp_get_mime_types() ); - if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) { + + if ( ! in_array( strtolower( $type['ext'] ), $default_types, true ) ) { return sprintf( '%s', esc_url( $atts['src'] ), esc_html( $atts['src'] ) ); } } @@ -2813,7 +2926,7 @@ function adjacent_image_link( $prev = true, $size = 'thumbnail', $text = false ) ); foreach ( $attachments as $k => $attachment ) { - if ( $attachment->ID == $post->ID ) { + if ( intval( $attachment->ID ) === intval( $post->ID ) ) { break; } } @@ -2866,6 +2979,7 @@ function get_attachment_taxonomies( $attachment, $output = 'names' ) { } elseif ( is_array( $attachment ) ) { $attachment = (object) $attachment; } + if ( ! is_object( $attachment ) ) { return array(); } @@ -2878,8 +2992,10 @@ function get_attachment_taxonomies( $attachment, $output = 'names' ) { if ( false !== strpos( $filename, '.' ) ) { $objects[] = 'attachment:' . substr( $filename, strrpos( $filename, '.' ) + 1 ); } + if ( ! empty( $attachment->post_mime_type ) ) { $objects[] = 'attachment:' . $attachment->post_mime_type; + if ( false !== strpos( $attachment->post_mime_type, '/' ) ) { foreach ( explode( '/', $attachment->post_mime_type ) as $token ) { if ( ! empty( $token ) ) { @@ -2890,8 +3006,11 @@ function get_attachment_taxonomies( $attachment, $output = 'names' ) { } $taxonomies = array(); + foreach ( $objects as $object ) { - if ( $taxes = get_object_taxonomies( $object, $output ) ) { + $taxes = get_object_taxonomies( $object, $output ); + + if ( $taxes ) { $taxonomies = array_merge( $taxonomies, $taxes ); } } @@ -2917,10 +3036,11 @@ function get_attachment_taxonomies( $attachment, $output = 'names' ) { */ function get_taxonomies_for_attachments( $output = 'names' ) { $taxonomies = array(); + foreach ( get_taxonomies( array(), 'objects' ) as $taxonomy ) { foreach ( $taxonomy->object_type as $object_type ) { - if ( 'attachment' == $object_type || 0 === strpos( $object_type, 'attachment:' ) ) { - if ( 'names' == $output ) { + if ( 'attachment' === $object_type || 0 === strpos( $object_type, 'attachment:' ) ) { + if ( 'names' === $output ) { $taxonomies[] = $taxonomy->name; } else { $taxonomies[ $taxonomy->name ] = $taxonomy; @@ -3193,11 +3313,13 @@ function wp_plupload_default_settings() { * @return array|void Array of attachment details. */ function wp_prepare_attachment_for_js( $attachment ) { - if ( ! $attachment = get_post( $attachment ) ) { + $attachment = get_post( $attachment ); + + if ( ! $attachment ) { return; } - if ( 'attachment' != $attachment->post_type ) { + if ( 'attachment' !== $attachment->post_type ) { return; } @@ -3316,7 +3438,9 @@ function wp_prepare_attachment_for_js( $attachment ) { foreach ( $possible_sizes as $size => $label ) { /** This filter is documented in wp-includes/media.php */ - if ( $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ) ) { + $downsize = apply_filters( 'image_downsize', false, $attachment->ID, $size ); + + if ( $downsize ) { if ( empty( $downsize[3] ) ) { continue; } @@ -3816,7 +3940,9 @@ function wp_enqueue_media( $args = array() ) { * @return array Found attachments. */ function get_attached_media( $type, $post = 0 ) { - if ( ! $post = get_post( $post ) ) { + $post = get_post( $post ); + + if ( ! $post ) { return array(); } @@ -3906,7 +4032,9 @@ function get_media_embedded_in_content( $content, $types = null ) { * from the expanded shortcode. */ function get_post_galleries( $post, $html = true ) { - if ( ! $post = get_post( $post ) ) { + $post = get_post( $post ); + + if ( ! $post ) { return array(); } @@ -4027,19 +4155,22 @@ function get_post_gallery_images( $post = 0 ) { * @param WP_Post $attachment Attachment object. */ function wp_maybe_generate_attachment_metadata( $attachment ) { - if ( empty( $attachment ) || ( empty( $attachment->ID ) || ! $attachment_id = (int) $attachment->ID ) ) { + if ( empty( $attachment ) || empty( $attachment->ID ) ) { return; } - $file = get_attached_file( $attachment_id ); - $meta = wp_get_attachment_metadata( $attachment_id ); + $attachment_id = (int) $attachment->ID; + $file = get_attached_file( $attachment_id ); + $meta = wp_get_attachment_metadata( $attachment_id ); + if ( empty( $meta ) && file_exists( $file ) ) { - $_meta = get_post_meta( $attachment_id ); - $regeneration_lock = 'wp_generating_att_' . $attachment_id; - if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $regeneration_lock ) ) { - set_transient( $regeneration_lock, $file ); + $_meta = get_post_meta( $attachment_id ); + $_lock = 'wp_generating_att_' . $attachment_id; + + if ( ! array_key_exists( '_wp_attachment_metadata', $_meta ) && ! get_transient( $_lock ) ) { + set_transient( $_lock, $file ); wp_update_attachment_metadata( $attachment_id, wp_generate_attachment_metadata( $attachment_id, $file ) ); - delete_transient( $regeneration_lock ); + delete_transient( $_lock ); } } } @@ -4072,10 +4203,11 @@ function attachment_url_to_postid( $url ) { $path = substr( $path, strlen( $dir['baseurl'] . '/' ) ); } - $sql = $wpdb->prepare( + $sql = $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value = %s", $path ); + $post_id = $wpdb->get_var( $sql ); /**