Make WordPress Core


Ignore:
Timestamp:
06/15/2019 01:01:48 AM (7 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-gd.php

    r44550 r45538  
    4444                // On some setups GD library does not provide imagerotate() - Ticket #11536
    4545                if ( isset( $args['methods'] ) &&
    46                         in_array( 'rotate', $args['methods'] ) &&
     46                        in_array( 'rotate', $args['methods'], true ) &&
    4747                        ! function_exists( 'imagerotate' ) ) {
    4848
     
    179179        protected function _resize( $max_w, $max_h, $crop = false ) {
    180180                $dims = image_resize_dimensions( $this->size['width'], $this->size['height'], $max_w, $max_h, $crop );
     181
    181182                if ( ! $dims ) {
    182183                        return new WP_Error( 'error_getting_dimensions', __( 'Could not calculate resized image dimensions' ), $this->file );
    183184                }
     185
    184186                list( $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h ) = $dims;
    185187
     
    218220         */
    219221        public function multi_resize( $sizes ) {
    220                 $metadata  = array();
     222                $metadata = array();
     223
     224                foreach ( $sizes as $size => $size_data ) {
     225                        $meta = $this->make_subsize( $size_data );
     226
     227                        if ( ! is_wp_error( $meta ) ) {
     228                                $metadata[ $size ] = $meta;
     229                        }
     230                }
     231
     232                return $metadata;
     233        }
     234
     235        /**
     236         * Create an image sub-size and return the image meta data value for it.
     237         *
     238         * @since 5.3.0
     239         *
     240         * @param array $size_data Array of width, height, and whether to crop.
     241         * @return WP_Error|array WP_Error on error, or the image data array for inclusion in the `sizes` array in the image meta.
     242         */
     243        public function make_subsize( $size_data ) {
     244                if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
     245                        return new WP_Error( 'image_subsize_create_error', __( 'Cannot resize the image. Both width and height are not set.' ) );
     246                }
     247
    221248                $orig_size = $this->size;
    222249
    223                 foreach ( $sizes as $size => $size_data ) {
    224                         if ( ! isset( $size_data['width'] ) && ! isset( $size_data['height'] ) ) {
    225                                 continue;
    226                         }
    227 
    228                         if ( ! isset( $size_data['width'] ) ) {
    229                                 $size_data['width'] = null;
    230                         }
    231                         if ( ! isset( $size_data['height'] ) ) {
    232                                 $size_data['height'] = null;
    233                         }
    234 
    235                         if ( ! isset( $size_data['crop'] ) ) {
    236                                 $size_data['crop'] = false;
    237                         }
    238 
    239                         $image     = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
    240                         $duplicate = ( ( $orig_size['width'] == $size_data['width'] ) && ( $orig_size['height'] == $size_data['height'] ) );
    241 
    242                         if ( ! is_wp_error( $image ) && ! $duplicate ) {
    243                                 $resized = $this->_save( $image );
    244 
    245                                 imagedestroy( $image );
    246 
    247                                 if ( ! is_wp_error( $resized ) && $resized ) {
    248                                         unset( $resized['path'] );
    249                                         $metadata[ $size ] = $resized;
    250                                 }
    251                         }
    252 
    253                         $this->size = $orig_size;
    254                 }
    255 
    256                 return $metadata;
     250                if ( ! isset( $size_data['width'] ) ) {
     251                        $size_data['width'] = null;
     252                }
     253
     254                if ( ! isset( $size_data['height'] ) ) {
     255                        $size_data['height'] = null;
     256                }
     257
     258                if ( ! isset( $size_data['crop'] ) ) {
     259                        $size_data['crop'] = false;
     260                }
     261
     262                $resized = $this->_resize( $size_data['width'], $size_data['height'], $size_data['crop'] );
     263
     264                if ( is_wp_error( $resized ) ) {
     265                        $saved = $resized;
     266                } else {
     267                        $saved = $this->_save( $resized );
     268                        imagedestroy( $resized );
     269                }
     270
     271                $this->size = $orig_size;
     272
     273                if ( ! is_wp_error( $saved ) ) {
     274                        unset( $saved['path'] );
     275                }
     276
     277                return $saved;
    257278        }
    258279
     
    392413                }
    393414
    394                 if ( 'image/gif' == $mime_type ) {
     415                if ( 'image/gif' === $mime_type ) {
    395416                        if ( ! $this->make_image( $filename, 'imagegif', array( $image, $filename ) ) ) {
    396417                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    397418                        }
    398                 } elseif ( 'image/png' == $mime_type ) {
     419                } elseif ( 'image/png' === $mime_type ) {
    399420                        // convert from full colors to index colors, like original PNG.
    400421                        if ( function_exists( 'imageistruecolor' ) && ! imageistruecolor( $image ) ) {
     
    405426                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
    406427                        }
    407                 } elseif ( 'image/jpeg' == $mime_type ) {
     428                } elseif ( 'image/jpeg' === $mime_type ) {
    408429                        if ( ! $this->make_image( $filename, 'imagejpeg', array( $image, $filename, $this->get_quality() ) ) ) {
    409430                                return new WP_Error( 'image_save_error', __( 'Image Editor Save Failed' ) );
Note: See TracChangeset for help on using the changeset viewer.