Make WordPress Core


Ignore:
Timestamp:
06/15/2019 01:01:48 AM (6 years ago)
Author:
azaozz
Message:

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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-image-editor-imagick.php

    r42746 r45538  
    109109        // setIteratorIndex is optional unless mime is an animated format.
    110110        // Here, we just say no if you are missing it and aren't loading a jpeg.
    111         if ( ! method_exists( 'Imagick', 'setIteratorIndex' ) && $mime_type != 'image/jpeg' ) {
     111        if ( ! method_exists( 'Imagick', 'setIteratorIndex' ) && $mime_type !== 'image/jpeg' ) {
    112112                return false;
    113113        }
     
    147147            $filename       = $this->file;
    148148
    149             if ( 'pdf' == $file_extension ) {
     149            if ( 'pdf' === $file_extension ) {
    150150                $filename = $this->pdf_setup();
    151151            }
     
    194194
    195195        try {
    196             if ( 'image/jpeg' == $this->mime_type ) {
     196            if ( 'image/jpeg' === $this->mime_type ) {
    197197                $this->image->setImageCompressionQuality( $quality );
    198198                $this->image->setImageCompression( imagick::COMPRESSION_JPEG );
     
    261261            return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ) );
    262262        }
     263
    263264        list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
    264265
     
    313314         * Imagick constant is defined or fall back to our default filter.
    314315         */
    315         if ( in_array( $filter_name, $allowed_filters ) && defined( 'Imagick::' . $filter_name ) ) {
     316        if ( in_array( $filter_name, $allowed_filters, true ) && defined( 'Imagick::' . $filter_name ) ) {
    316317            $filter = constant( 'Imagick::' . $filter_name );
    317318        } else {
     
    362363
    363364            // Set appropriate quality settings after resizing.
    364             if ( 'image/jpeg' == $this->mime_type ) {
     365            if ( 'image/jpeg' === $this->mime_type ) {
    365366                if ( is_callable( array( $this->image, 'unsharpMaskImage' ) ) ) {
    366367                    $this->image->unsharpMaskImage( 0.25, 0.25, 8, 0.065 );
     
    414415     *
    415416     * @param array $sizes {
    416      *     An array of image size arrays. Default sizes are 'small', 'medium', 'medium_large', 'large'.
     417     *     An array of image size arrays. Default sizes are 'thumbnail', 'medium', 'medium_large', 'large'.
    417418     *
    418419     *     Either a height or width must be provided.
     
    431432     */
    432433    public function multi_resize( $sizes ) {
    433         $metadata   = array();
     434        $metadata = array();
     435
     436        foreach ( $sizes as $size => $size_data ) {
     437            $meta = $this->make_subsize( $size_data );
     438
     439            if ( ! is_wp_error( $meta ) ) {
     440                $metadata[ $size ] = $meta;
     441            }
     442        }
     443
     444        return $metadata;
     445    }
     446
     447    /**
     448     * Create an image sub-size and return the image meta data value for it.
     449     *
     450     * @since 5.3.0
     451     *
     452     * @param array $size_data Array of width, height, and whether to crop.
     453     * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta.
     454     */
     455    public function make_subsize( $size_data ) {
     456        if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
     457            return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) );
     458        }
     459
    434460        $orig_size  = $this->size;
    435461        $orig_image = $this->image->getImage();
    436462
    437         foreach ( $sizes as $size => $size_data ) {
    438             if ( ! $this->image ) {
    439                 $this->image = $orig_image->getImage();
    440             }
    441 
    442             if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
    443                 continue;
    444             }
    445 
    446             if ( ! isset( $size_data['width'] ) ) {
    447                 $size_data['width'] = null;
    448             }
    449             if ( ! isset( $size_data['height'] ) ) {
    450                 $size_data['height'] = null;
    451             }
    452 
    453             if ( ! isset( $size_data['crop'] ) ) {
    454                 $size_data['crop'] = false;
    455             }
    456 
    457             $resize_result = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
    458             $duplicate     = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) );
    459 
    460             if ( ! is_wp_error( $resize_result ) && ! $duplicate ) {
    461                 $resized = $this->_save( $this->image );
    462 
    463                 $this->image->clear();
    464                 $this->image->destroy();
    465                 $this->image = null;
    466 
    467                 if ( ! is_wp_error( $resized ) && $resized ) {
    468                     unset( $resized['path'] );
    469                     $metadata[ $size ] = $resized;
    470                 }
    471             }
    472 
    473             $this->size = $orig_size;
    474         }
    475 
     463        if ( ! isset( $size_data['width'] ) ) {
     464            $size_data['width'] = null;
     465        }
     466
     467        if ( ! isset( $size_data['height'] ) ) {
     468            $size_data['height'] = null;
     469        }
     470
     471        if ( ! isset( $size_data['crop'] ) ) {
     472            $size_data['crop'] = false;
     473        }
     474
     475        $resized = $this->resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
     476
     477        if ( is_wp_error( $resized ) ) {
     478            $saved = $resized;
     479        } else {
     480            $saved = $this->_save( $this->image );
     481
     482            $this->image->clear();
     483            $this->image->destroy();
     484            $this->image = null;
     485        }
     486
     487        $this->size  = $orig_size;
    476488        $this->image = $orig_image;
    477489
    478         return $metadata;
     490        if ( ! is_wp_error( $saved ) ) {
     491            unset( $saved['path'] );
     492        }
     493
     494        return $saved;
    479495    }
    480496
     
    718734            // Strip profiles.
    719735            foreach ( $this->image->getImageProfiles( '*', true ) as $key => $value ) {
    720                 if ( ! in_array( $key, $protected_profiles ) ) {
     736                if ( ! in_array( $key, $protected_profiles, true ) ) {
    721737                    $this->image->removeImageProfile( $key );
    722738                }
Note: See TracChangeset for help on using the changeset viewer.