Plugin Directory

Changeset 2704546 for performance-lab


Ignore:
Timestamp:
04/04/2022 05:12:28 PM (4 years ago)
Author:
performanceteam
Message:

Update to version 1.0.0-rc.1 from GitHub

Location:
performance-lab
Files:
4 added
8 edited
1 copied

Legend:

Unmodified
Added
Removed
  • performance-lab/tags/1.0.0-rc.1/load.php

    r2697868 r2704546  
    66 * Requires at least: 5.8
    77 * Requires PHP: 5.6
    8  * Version: 1.0.0-beta.3
     8 * Version: 1.0.0-rc.1
    99 * Author: WordPress Performance Group
    1010 * Author URI: https://make.wordpress.org/core/tag/performance/
  • performance-lab/tags/1.0.0-rc.1/module-i18n.php

    r2697195 r2704546  
    88    _x( 'Audit Autoloaded Options', 'module name', 'performance-lab' ),
    99    _x( 'Adds a check for autoloaded options in Site Health status.', 'module description', 'performance-lab' ),
     10    _x( 'WebP Support', 'module name', 'performance-lab' ),
     11    _x( 'Adds a WebP support check in Site Health status.', 'module description', 'performance-lab' ),
    1012    _x( 'Audit Enqueued Assets', 'module name', 'performance-lab' ),
    1113    _x( 'Adds a CSS and JS resource check in Site Health status.', 'module description', 'performance-lab' ),
    12     _x( 'WebP Support', 'module name', 'performance-lab' ),
    13     _x( 'Adds a WebP support check in Site Health status.', 'module description', 'performance-lab' ),
    1414);
    1515/* THIS IS THE END OF THE GENERATED FILE */
  • performance-lab/tags/1.0.0-rc.1/modules/images/webp-uploads/load.php

    r2697195 r2704546  
    305305 */
    306306function webp_uploads_generate_additional_image_source( $attachment_id, array $size_data, $mime, $destination_file_name = null ) {
     307    $allowed_mimes = array_flip( wp_get_mime_types() );
     308    if ( ! isset( $allowed_mimes[ $mime ] ) || ! is_string( $allowed_mimes[ $mime ] ) ) {
     309        return new WP_Error( 'image_mime_type_invalid', __( 'The provided mime type is not allowed.', 'performance-lab' ) );
     310    }
     311
     312    if ( ! wp_image_editor_supports( array( 'mime_type' => $mime ) ) ) {
     313        return new WP_Error( 'image_mime_type_not_supported', __( 'The provided mime type is not supported.', 'performance-lab' ) );
     314    }
     315
    307316    $image_path = wp_get_original_image_path( $attachment_id );
    308317
     
    312321    }
    313322
    314     $editor = wp_get_image_editor( $image_path );
     323    $editor = wp_get_image_editor( $image_path, array( 'mime_type' => $mime ) );
    315324
    316325    if ( is_wp_error( $editor ) ) {
    317326        return $editor;
    318     }
    319 
    320     $allowed_mimes = array_flip( wp_get_mime_types() );
    321     if ( ! isset( $allowed_mimes[ $mime ] ) || ! is_string( $allowed_mimes[ $mime ] ) ) {
    322         return new WP_Error( 'image_mime_type_invalid', __( 'The provided mime type is not allowed.', 'performance-lab' ) );
    323     }
    324 
    325     if ( ! wp_image_editor_supports( array( 'mime_type' => $mime ) ) ) {
    326         return new WP_Error( 'image_mime_type_not_supported', __( 'The provided mime type is not supported.', 'performance-lab' ) );
    327327    }
    328328
     
    588588    }
    589589
    590     // TODO: Add a filterable option to determine image extensions, see https://github.com/WordPress/performance/issues/187 for more details.
    591     $target_image_extensions = array(
    592         'jpg',
    593         'jpeg',
    594     );
    595 
    596     // Creates a regular extension to find all the URLS with the provided extension for img tag.
    597     preg_match_all( '/[^\s"]+\.(?:' . implode( '|', $target_image_extensions ) . ')/i', $image, $matches );
    598     if ( empty( $matches ) ) {
    599         return $image;
    600     }
    601 
    602590    /**
    603591     * Filters mime types that should be used to update all images in the content. The order of
    604      * mime types matters. The last mime type in the list will be used if it is supported by an image.
     592     * mime types matters. The first mime type in the list will be used if it is supported by an image.
    605593     *
    606594     * @since 1.0.0
     
    610598     * @param string $context       The current context.
    611599     */
    612     $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', array( 'image/jpeg', 'image/webp' ), $attachment_id, $context );
     600    $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', array( 'image/webp', 'image/jpeg' ), $attachment_id, $context );
    613601
    614602    $target_mime = null;
    615     // Look for the most progressive image format first.
    616     $target_mimes = array_reverse( $target_mimes );
    617603    foreach ( $target_mimes as $mime ) {
    618604        if ( isset( $metadata['sources'][ $mime ] ) ) {
     
    626612    }
    627613
    628     $basename = wp_basename( $metadata['file'] );
    629     $urls     = $matches[0];
    630     foreach ( $urls as $url ) {
    631         $src_filename = wp_basename( $url );
    632 
    633         // Replace the full size image if present.
    634         if ( isset( $metadata['sources'][ $target_mime ]['file'] ) && strpos( $url, $basename ) !== false ) {
    635             $image = str_replace( $src_filename, $metadata['sources'][ $target_mime ]['file'], $image );
    636             continue;
    637         }
    638 
    639         if ( empty( $metadata['sizes'] ) ) {
    640             continue;
    641         }
    642 
    643         $extension = wp_check_filetype( $src_filename );
    644         // Extension was not set properly no action possible or extension is already in the expected mime.
    645         if ( empty( $extension['type'] ) || $extension['type'] === $target_mime ) {
    646             continue;
    647         }
    648 
    649         // Find the appropriate size for the provided URL.
    650         foreach ( $metadata['sizes'] as $name => $size_data ) {
    651             // Not the size we are looking for.
    652             if ( empty( $size_data['file'] ) || $src_filename !== $size_data['file'] ) {
    653                 continue;
    654             }
    655 
    656             if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
    657                 continue;
    658             }
    659 
    660             // This is the same as the file we want to replace nothing to do here.
    661             if ( $size_data['sources'][ $target_mime ]['file'] === $src_filename ) {
    662                 continue;
    663             }
    664 
    665             $image = str_replace( $src_filename, $size_data['sources'][ $target_mime ]['file'], $image );
    666             break;
    667         }
     614    // Replace the full size image if present.
     615    if ( isset( $metadata['sources'][ $target_mime ]['file'] ) ) {
     616        $basename = wp_basename( $metadata['file'] );
     617        if ( $basename !== $metadata['sources'][ $target_mime ]['file'] ) {
     618            $image = str_replace(
     619                $basename,
     620                $metadata['sources'][ $target_mime ]['file'],
     621                $image
     622            );
     623        }
     624    }
     625
     626    // Replace sub sizes for the image if present.
     627    foreach ( $metadata['sizes'] as $name => $size_data ) {
     628        if ( empty( $size_data['file'] ) ) {
     629            continue;
     630        }
     631
     632        if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
     633            continue;
     634        }
     635
     636        if ( $size_data['file'] === $size_data['sources'][ $target_mime ]['file'] ) {
     637            continue;
     638        }
     639
     640        $image = str_replace(
     641            $size_data['file'],
     642            $size_data['sources'][ $target_mime ]['file'],
     643            $image
     644        );
    668645    }
    669646
     
    707684}
    708685add_filter( 'rest_prepare_attachment', 'webp_uploads_update_rest_attachment', 10, 3 );
     686
     687/**
     688 * Inspect if the current call to `wp_update_attachment_metadata()` was done from within the context
     689 * of an edit to an attachment either restore or other type of edit, in that case we perform operations
     690 * to save the sources properties, specifically for the `full` size image due this is a virtual image size.
     691 *
     692 * @since 1.0.0
     693 *
     694 * @see wp_update_attachment_metadata()
     695 *
     696 * @param array $data          The current metadata of the attachment.
     697 * @param int   $attachment_id The ID of the current attachment.
     698 * @return array The updated metadata for the attachment to be stored in the meta table.
     699 */
     700function webp_uploads_update_attachment_metadata( $data, $attachment_id ) {
     701    $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 10 );
     702
     703    foreach ( $trace as $element ) {
     704        if ( ! isset( $element['function'] ) ) {
     705            continue;
     706        }
     707
     708        switch ( $element['function'] ) {
     709            case 'wp_save_image':
     710                // Right after an image has been edited.
     711                return webp_uploads_backup_sources( $attachment_id, $data );
     712            case 'wp_restore_image':
     713                // When an image has been restored.
     714                return webp_uploads_restore_image( $attachment_id, $data );
     715        }
     716    }
     717
     718    return $data;
     719}
     720add_filter( 'wp_update_attachment_metadata', 'webp_uploads_update_attachment_metadata', 10, 2 );
     721
     722/**
     723 * Before saving the metadata of the image store a backup values for the sources and file property
     724 * those files would be used and deleted by the backup mechanism, right after the metadata has
     725 * been updated. It removes the current sources property due once this function is executed
     726 * right after an edit has taken place and the current sources are no longer accurate.
     727 *
     728 * @since 1.0.0
     729 *
     730 * @param int   $attachment_id The ID representing the attachment.
     731 * @param array $data          The current metadata of the attachment.
     732 * @return array The updated metadata for the attachment.
     733 */
     734function webp_uploads_backup_sources( $attachment_id, $data ) {
     735    $target = isset( $_REQUEST['target'] ) ? $_REQUEST['target'] : 'all';
     736
     737    // When an edit to an image is only applied to a thumbnail there's nothing we need to back up.
     738    if ( 'thumbnail' === $target ) {
     739        return $data;
     740    }
     741
     742    $metadata = wp_get_attachment_metadata( $attachment_id );
     743    // Nothing to back up.
     744    if ( ! isset( $metadata['sources'] ) ) {
     745        return $data;
     746    }
     747
     748    $sources = $metadata['sources'];
     749    // Prevent execution of the callbacks more than once if the callback was already executed.
     750    $has_been_processed = false;
     751
     752    $hook = function ( $meta_id, $post_id, $meta_name ) use ( $attachment_id, $sources, &$has_been_processed ) {
     753        // Make sure this hook is only executed in the same context for the provided $attachment_id.
     754        if ( $post_id !== $attachment_id ) {
     755            return;
     756        }
     757
     758        // This logic should work only if we are looking at the meta key: `_wp_attachment_backup_sizes`.
     759        if ( '_wp_attachment_backup_sizes' !== $meta_name ) {
     760            return;
     761        }
     762
     763        if ( $has_been_processed ) {
     764            return;
     765        }
     766
     767        $has_been_processed = true;
     768        webp_uploads_backup_full_image_sources( $post_id, $sources );
     769    };
     770
     771    add_action( 'added_post_meta', $hook, 10, 3 );
     772    add_action( 'updated_post_meta', $hook, 10, 3 );
     773
     774    // Remove the current sources as at this point the current values are no longer accurate.
     775    // TODO: Requires to be updated from https://github.com/WordPress/performance/issues/158.
     776    unset( $data['sources'] );
     777
     778    return $data;
     779}
     780
     781/**
     782 * Stores the provided sources for the attachment ID in the `_wp_attachment_backup_sources`  with
     783 * the next available target if target is `null` no source would be stored.
     784 *
     785 * @since 1.0.0
     786 *
     787 * @param int   $attachment_id The ID of the attachment.
     788 * @param array $sources       An array with the full sources to be stored on the next available key.
     789 */
     790function webp_uploads_backup_full_image_sources( $attachment_id, $sources ) {
     791    if ( empty( $sources ) ) {
     792        return;
     793    }
     794
     795    $target = webp_uploads_get_next_full_size_key_from_backup( $attachment_id );
     796    if ( null === $target ) {
     797        return;
     798    }
     799
     800    $backup_sources            = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     801    $backup_sources            = is_array( $backup_sources ) ? $backup_sources : array();
     802    $backup_sources[ $target ] = $sources;
     803    // Store the `sources` property into the full size if present.
     804    update_post_meta( $attachment_id, '_wp_attachment_backup_sources', $backup_sources );
     805}
     806
     807/**
     808 * It finds the next available `full-{orig or hash}` key on the images if the name
     809 * has not been used as part of the backup sources it would be used if no size is
     810 * found or backup exists `null` would be returned instead.
     811 *
     812 * @since 1.0.0
     813 *
     814 * @param int $attachment_id The ID of the attachment.
     815 * @return null|string The next available full size name.
     816 */
     817function webp_uploads_get_next_full_size_key_from_backup( $attachment_id ) {
     818    $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
     819    $backup_sizes = is_array( $backup_sizes ) ? $backup_sizes : array();
     820
     821    if ( empty( $backup_sizes ) ) {
     822        return null;
     823    }
     824
     825    $backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     826    $backup_sources = is_array( $backup_sources ) ? $backup_sources : array();
     827    foreach ( array_keys( $backup_sizes ) as $size_name ) {
     828        // If the target already has the sources attributes find the next one.
     829        if ( isset( $backup_sources[ $size_name ] ) ) {
     830            continue;
     831        }
     832
     833        // We are only interested in the `full-` sizes.
     834        if ( strpos( $size_name, 'full-' ) === false ) {
     835            continue;
     836        }
     837
     838        return $size_name;
     839    }
     840
     841    return null;
     842}
     843
     844/**
     845 * Restore an image from the backup sizes, the current hook moves the `sources` from the `full-orig` key into
     846 * the top level `sources` into the metadata, in order to ensure the restore process has a reference to the right
     847 * images.
     848 *
     849 * @since 1.0.0
     850 *
     851 * @param int   $attachment_id The ID of the attachment.
     852 * @param array $data          The current metadata to be stored in the attachment.
     853 * @return array The updated metadata of the attachment.
     854 */
     855function webp_uploads_restore_image( $attachment_id, $data ) {
     856    $backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     857
     858    if ( ! is_array( $backup_sources ) ) {
     859        return $data;
     860    }
     861
     862    if ( ! isset( $backup_sources['full-orig'] ) || ! is_array( $backup_sources['full-orig'] ) ) {
     863        return $data;
     864    }
     865
     866    // TODO: Handle the case If `IMAGE_EDIT_OVERWRITE` is defined and is truthy remove any edited images if present before replacing the metadata.
     867    // See: https://github.com/WordPress/performance/issues/158.
     868    $data['sources'] = $backup_sources['full-orig'];
     869
     870    return $data;
     871}
  • performance-lab/tags/1.0.0-rc.1/readme.txt

    r2697868 r2704546  
    55Tested up to:      5.9
    66Requires PHP:      5.6
    7 Stable tag:        1.0.0-beta.3
     7Stable tag:        1.0.0-rc.1
    88License:           GPLv2 or later
    99License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     
    1919
    2020* **WebP Uploads:** Creates WebP versions for new JPEG image uploads if supported by the server.
     21* **Persistent Object Cache Health Check:** Adds a persistent object cache check for sites with non-trivial amounts of data in Site Health status.
     22* **Audit Autoloaded Options:** Adds a check for autoloaded options in Site Health status.
     23* **Audit Enqueued Assets:** Adds a CSS and JS resource check in Site Health status.
    2124* **WebP Support:** Adds a WebP support check in Site Health status.
    22 * **Persistent Object Cache Health Check:** Adds a persistent object cache check for sites with non-trivial amounts of data in Site Health status.
    23 * **Audit Enqueued Assets:** Adds a CSS and JS resource check in Site Health status.
    24 * **Audit Autoloaded Options:** Adds a check for autoloaded options in Site Health status.
    2525
    2626== Installation ==
     
    6666
    6767== Changelog ==
     68
     69= 1.0.0-rc.1 =
     70
     71**Enhancements**
     72
     73* Images: Change expected order of items in the `webp_uploads_content_image_mimes` filter. ([250](https://github.com/WordPress/performance/pull/250))
     74* Images: Replace images in frontend content without using an additional regular expression. ([262](https://github.com/WordPress/performance/pull/262))
     75* Images: Restore and backup image sizes alongside the sources properties. ([242](https://github.com/WordPress/performance/pull/242))
     76
     77**Bug Fixes**
     78
     79* Images: Select image editor based on WebP support instead of always using the default one. ([259](https://github.com/WordPress/performance/pull/259))
    6880
    6981= 1.0.0-beta.3 =
  • performance-lab/trunk/load.php

    r2697868 r2704546  
    66 * Requires at least: 5.8
    77 * Requires PHP: 5.6
    8  * Version: 1.0.0-beta.3
     8 * Version: 1.0.0-rc.1
    99 * Author: WordPress Performance Group
    1010 * Author URI: https://make.wordpress.org/core/tag/performance/
  • performance-lab/trunk/module-i18n.php

    r2697195 r2704546  
    88    _x( 'Audit Autoloaded Options', 'module name', 'performance-lab' ),
    99    _x( 'Adds a check for autoloaded options in Site Health status.', 'module description', 'performance-lab' ),
     10    _x( 'WebP Support', 'module name', 'performance-lab' ),
     11    _x( 'Adds a WebP support check in Site Health status.', 'module description', 'performance-lab' ),
    1012    _x( 'Audit Enqueued Assets', 'module name', 'performance-lab' ),
    1113    _x( 'Adds a CSS and JS resource check in Site Health status.', 'module description', 'performance-lab' ),
    12     _x( 'WebP Support', 'module name', 'performance-lab' ),
    13     _x( 'Adds a WebP support check in Site Health status.', 'module description', 'performance-lab' ),
    1414);
    1515/* THIS IS THE END OF THE GENERATED FILE */
  • performance-lab/trunk/modules/images/webp-uploads/load.php

    r2697195 r2704546  
    305305 */
    306306function webp_uploads_generate_additional_image_source( $attachment_id, array $size_data, $mime, $destination_file_name = null ) {
     307    $allowed_mimes = array_flip( wp_get_mime_types() );
     308    if ( ! isset( $allowed_mimes[ $mime ] ) || ! is_string( $allowed_mimes[ $mime ] ) ) {
     309        return new WP_Error( 'image_mime_type_invalid', __( 'The provided mime type is not allowed.', 'performance-lab' ) );
     310    }
     311
     312    if ( ! wp_image_editor_supports( array( 'mime_type' => $mime ) ) ) {
     313        return new WP_Error( 'image_mime_type_not_supported', __( 'The provided mime type is not supported.', 'performance-lab' ) );
     314    }
     315
    307316    $image_path = wp_get_original_image_path( $attachment_id );
    308317
     
    312321    }
    313322
    314     $editor = wp_get_image_editor( $image_path );
     323    $editor = wp_get_image_editor( $image_path, array( 'mime_type' => $mime ) );
    315324
    316325    if ( is_wp_error( $editor ) ) {
    317326        return $editor;
    318     }
    319 
    320     $allowed_mimes = array_flip( wp_get_mime_types() );
    321     if ( ! isset( $allowed_mimes[ $mime ] ) || ! is_string( $allowed_mimes[ $mime ] ) ) {
    322         return new WP_Error( 'image_mime_type_invalid', __( 'The provided mime type is not allowed.', 'performance-lab' ) );
    323     }
    324 
    325     if ( ! wp_image_editor_supports( array( 'mime_type' => $mime ) ) ) {
    326         return new WP_Error( 'image_mime_type_not_supported', __( 'The provided mime type is not supported.', 'performance-lab' ) );
    327327    }
    328328
     
    588588    }
    589589
    590     // TODO: Add a filterable option to determine image extensions, see https://github.com/WordPress/performance/issues/187 for more details.
    591     $target_image_extensions = array(
    592         'jpg',
    593         'jpeg',
    594     );
    595 
    596     // Creates a regular extension to find all the URLS with the provided extension for img tag.
    597     preg_match_all( '/[^\s"]+\.(?:' . implode( '|', $target_image_extensions ) . ')/i', $image, $matches );
    598     if ( empty( $matches ) ) {
    599         return $image;
    600     }
    601 
    602590    /**
    603591     * Filters mime types that should be used to update all images in the content. The order of
    604      * mime types matters. The last mime type in the list will be used if it is supported by an image.
     592     * mime types matters. The first mime type in the list will be used if it is supported by an image.
    605593     *
    606594     * @since 1.0.0
     
    610598     * @param string $context       The current context.
    611599     */
    612     $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', array( 'image/jpeg', 'image/webp' ), $attachment_id, $context );
     600    $target_mimes = apply_filters( 'webp_uploads_content_image_mimes', array( 'image/webp', 'image/jpeg' ), $attachment_id, $context );
    613601
    614602    $target_mime = null;
    615     // Look for the most progressive image format first.
    616     $target_mimes = array_reverse( $target_mimes );
    617603    foreach ( $target_mimes as $mime ) {
    618604        if ( isset( $metadata['sources'][ $mime ] ) ) {
     
    626612    }
    627613
    628     $basename = wp_basename( $metadata['file'] );
    629     $urls     = $matches[0];
    630     foreach ( $urls as $url ) {
    631         $src_filename = wp_basename( $url );
    632 
    633         // Replace the full size image if present.
    634         if ( isset( $metadata['sources'][ $target_mime ]['file'] ) && strpos( $url, $basename ) !== false ) {
    635             $image = str_replace( $src_filename, $metadata['sources'][ $target_mime ]['file'], $image );
    636             continue;
    637         }
    638 
    639         if ( empty( $metadata['sizes'] ) ) {
    640             continue;
    641         }
    642 
    643         $extension = wp_check_filetype( $src_filename );
    644         // Extension was not set properly no action possible or extension is already in the expected mime.
    645         if ( empty( $extension['type'] ) || $extension['type'] === $target_mime ) {
    646             continue;
    647         }
    648 
    649         // Find the appropriate size for the provided URL.
    650         foreach ( $metadata['sizes'] as $name => $size_data ) {
    651             // Not the size we are looking for.
    652             if ( empty( $size_data['file'] ) || $src_filename !== $size_data['file'] ) {
    653                 continue;
    654             }
    655 
    656             if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
    657                 continue;
    658             }
    659 
    660             // This is the same as the file we want to replace nothing to do here.
    661             if ( $size_data['sources'][ $target_mime ]['file'] === $src_filename ) {
    662                 continue;
    663             }
    664 
    665             $image = str_replace( $src_filename, $size_data['sources'][ $target_mime ]['file'], $image );
    666             break;
    667         }
     614    // Replace the full size image if present.
     615    if ( isset( $metadata['sources'][ $target_mime ]['file'] ) ) {
     616        $basename = wp_basename( $metadata['file'] );
     617        if ( $basename !== $metadata['sources'][ $target_mime ]['file'] ) {
     618            $image = str_replace(
     619                $basename,
     620                $metadata['sources'][ $target_mime ]['file'],
     621                $image
     622            );
     623        }
     624    }
     625
     626    // Replace sub sizes for the image if present.
     627    foreach ( $metadata['sizes'] as $name => $size_data ) {
     628        if ( empty( $size_data['file'] ) ) {
     629            continue;
     630        }
     631
     632        if ( empty( $size_data['sources'][ $target_mime ]['file'] ) ) {
     633            continue;
     634        }
     635
     636        if ( $size_data['file'] === $size_data['sources'][ $target_mime ]['file'] ) {
     637            continue;
     638        }
     639
     640        $image = str_replace(
     641            $size_data['file'],
     642            $size_data['sources'][ $target_mime ]['file'],
     643            $image
     644        );
    668645    }
    669646
     
    707684}
    708685add_filter( 'rest_prepare_attachment', 'webp_uploads_update_rest_attachment', 10, 3 );
     686
     687/**
     688 * Inspect if the current call to `wp_update_attachment_metadata()` was done from within the context
     689 * of an edit to an attachment either restore or other type of edit, in that case we perform operations
     690 * to save the sources properties, specifically for the `full` size image due this is a virtual image size.
     691 *
     692 * @since 1.0.0
     693 *
     694 * @see wp_update_attachment_metadata()
     695 *
     696 * @param array $data          The current metadata of the attachment.
     697 * @param int   $attachment_id The ID of the current attachment.
     698 * @return array The updated metadata for the attachment to be stored in the meta table.
     699 */
     700function webp_uploads_update_attachment_metadata( $data, $attachment_id ) {
     701    $trace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS, 10 );
     702
     703    foreach ( $trace as $element ) {
     704        if ( ! isset( $element['function'] ) ) {
     705            continue;
     706        }
     707
     708        switch ( $element['function'] ) {
     709            case 'wp_save_image':
     710                // Right after an image has been edited.
     711                return webp_uploads_backup_sources( $attachment_id, $data );
     712            case 'wp_restore_image':
     713                // When an image has been restored.
     714                return webp_uploads_restore_image( $attachment_id, $data );
     715        }
     716    }
     717
     718    return $data;
     719}
     720add_filter( 'wp_update_attachment_metadata', 'webp_uploads_update_attachment_metadata', 10, 2 );
     721
     722/**
     723 * Before saving the metadata of the image store a backup values for the sources and file property
     724 * those files would be used and deleted by the backup mechanism, right after the metadata has
     725 * been updated. It removes the current sources property due once this function is executed
     726 * right after an edit has taken place and the current sources are no longer accurate.
     727 *
     728 * @since 1.0.0
     729 *
     730 * @param int   $attachment_id The ID representing the attachment.
     731 * @param array $data          The current metadata of the attachment.
     732 * @return array The updated metadata for the attachment.
     733 */
     734function webp_uploads_backup_sources( $attachment_id, $data ) {
     735    $target = isset( $_REQUEST['target'] ) ? $_REQUEST['target'] : 'all';
     736
     737    // When an edit to an image is only applied to a thumbnail there's nothing we need to back up.
     738    if ( 'thumbnail' === $target ) {
     739        return $data;
     740    }
     741
     742    $metadata = wp_get_attachment_metadata( $attachment_id );
     743    // Nothing to back up.
     744    if ( ! isset( $metadata['sources'] ) ) {
     745        return $data;
     746    }
     747
     748    $sources = $metadata['sources'];
     749    // Prevent execution of the callbacks more than once if the callback was already executed.
     750    $has_been_processed = false;
     751
     752    $hook = function ( $meta_id, $post_id, $meta_name ) use ( $attachment_id, $sources, &$has_been_processed ) {
     753        // Make sure this hook is only executed in the same context for the provided $attachment_id.
     754        if ( $post_id !== $attachment_id ) {
     755            return;
     756        }
     757
     758        // This logic should work only if we are looking at the meta key: `_wp_attachment_backup_sizes`.
     759        if ( '_wp_attachment_backup_sizes' !== $meta_name ) {
     760            return;
     761        }
     762
     763        if ( $has_been_processed ) {
     764            return;
     765        }
     766
     767        $has_been_processed = true;
     768        webp_uploads_backup_full_image_sources( $post_id, $sources );
     769    };
     770
     771    add_action( 'added_post_meta', $hook, 10, 3 );
     772    add_action( 'updated_post_meta', $hook, 10, 3 );
     773
     774    // Remove the current sources as at this point the current values are no longer accurate.
     775    // TODO: Requires to be updated from https://github.com/WordPress/performance/issues/158.
     776    unset( $data['sources'] );
     777
     778    return $data;
     779}
     780
     781/**
     782 * Stores the provided sources for the attachment ID in the `_wp_attachment_backup_sources`  with
     783 * the next available target if target is `null` no source would be stored.
     784 *
     785 * @since 1.0.0
     786 *
     787 * @param int   $attachment_id The ID of the attachment.
     788 * @param array $sources       An array with the full sources to be stored on the next available key.
     789 */
     790function webp_uploads_backup_full_image_sources( $attachment_id, $sources ) {
     791    if ( empty( $sources ) ) {
     792        return;
     793    }
     794
     795    $target = webp_uploads_get_next_full_size_key_from_backup( $attachment_id );
     796    if ( null === $target ) {
     797        return;
     798    }
     799
     800    $backup_sources            = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     801    $backup_sources            = is_array( $backup_sources ) ? $backup_sources : array();
     802    $backup_sources[ $target ] = $sources;
     803    // Store the `sources` property into the full size if present.
     804    update_post_meta( $attachment_id, '_wp_attachment_backup_sources', $backup_sources );
     805}
     806
     807/**
     808 * It finds the next available `full-{orig or hash}` key on the images if the name
     809 * has not been used as part of the backup sources it would be used if no size is
     810 * found or backup exists `null` would be returned instead.
     811 *
     812 * @since 1.0.0
     813 *
     814 * @param int $attachment_id The ID of the attachment.
     815 * @return null|string The next available full size name.
     816 */
     817function webp_uploads_get_next_full_size_key_from_backup( $attachment_id ) {
     818    $backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
     819    $backup_sizes = is_array( $backup_sizes ) ? $backup_sizes : array();
     820
     821    if ( empty( $backup_sizes ) ) {
     822        return null;
     823    }
     824
     825    $backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     826    $backup_sources = is_array( $backup_sources ) ? $backup_sources : array();
     827    foreach ( array_keys( $backup_sizes ) as $size_name ) {
     828        // If the target already has the sources attributes find the next one.
     829        if ( isset( $backup_sources[ $size_name ] ) ) {
     830            continue;
     831        }
     832
     833        // We are only interested in the `full-` sizes.
     834        if ( strpos( $size_name, 'full-' ) === false ) {
     835            continue;
     836        }
     837
     838        return $size_name;
     839    }
     840
     841    return null;
     842}
     843
     844/**
     845 * Restore an image from the backup sizes, the current hook moves the `sources` from the `full-orig` key into
     846 * the top level `sources` into the metadata, in order to ensure the restore process has a reference to the right
     847 * images.
     848 *
     849 * @since 1.0.0
     850 *
     851 * @param int   $attachment_id The ID of the attachment.
     852 * @param array $data          The current metadata to be stored in the attachment.
     853 * @return array The updated metadata of the attachment.
     854 */
     855function webp_uploads_restore_image( $attachment_id, $data ) {
     856    $backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
     857
     858    if ( ! is_array( $backup_sources ) ) {
     859        return $data;
     860    }
     861
     862    if ( ! isset( $backup_sources['full-orig'] ) || ! is_array( $backup_sources['full-orig'] ) ) {
     863        return $data;
     864    }
     865
     866    // TODO: Handle the case If `IMAGE_EDIT_OVERWRITE` is defined and is truthy remove any edited images if present before replacing the metadata.
     867    // See: https://github.com/WordPress/performance/issues/158.
     868    $data['sources'] = $backup_sources['full-orig'];
     869
     870    return $data;
     871}
  • performance-lab/trunk/readme.txt

    r2697868 r2704546  
    55Tested up to:      5.9
    66Requires PHP:      5.6
    7 Stable tag:        1.0.0-beta.3
     7Stable tag:        1.0.0-rc.1
    88License:           GPLv2 or later
    99License URI:       https://www.gnu.org/licenses/gpl-2.0.html
     
    1919
    2020* **WebP Uploads:** Creates WebP versions for new JPEG image uploads if supported by the server.
     21* **Persistent Object Cache Health Check:** Adds a persistent object cache check for sites with non-trivial amounts of data in Site Health status.
     22* **Audit Autoloaded Options:** Adds a check for autoloaded options in Site Health status.
     23* **Audit Enqueued Assets:** Adds a CSS and JS resource check in Site Health status.
    2124* **WebP Support:** Adds a WebP support check in Site Health status.
    22 * **Persistent Object Cache Health Check:** Adds a persistent object cache check for sites with non-trivial amounts of data in Site Health status.
    23 * **Audit Enqueued Assets:** Adds a CSS and JS resource check in Site Health status.
    24 * **Audit Autoloaded Options:** Adds a check for autoloaded options in Site Health status.
    2525
    2626== Installation ==
     
    6666
    6767== Changelog ==
     68
     69= 1.0.0-rc.1 =
     70
     71**Enhancements**
     72
     73* Images: Change expected order of items in the `webp_uploads_content_image_mimes` filter. ([250](https://github.com/WordPress/performance/pull/250))
     74* Images: Replace images in frontend content without using an additional regular expression. ([262](https://github.com/WordPress/performance/pull/262))
     75* Images: Restore and backup image sizes alongside the sources properties. ([242](https://github.com/WordPress/performance/pull/242))
     76
     77**Bug Fixes**
     78
     79* Images: Select image editor based on WebP support instead of always using the default one. ([259](https://github.com/WordPress/performance/pull/259))
    6880
    6981= 1.0.0-beta.3 =
Note: See TracChangeset for help on using the changeset viewer.