Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Only update the specified target images when an image is edited. #301

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 86 additions & 20 deletions modules/images/webp-uploads/image-edit.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,41 @@
*/
function webp_uploads_update_sources( $metadata, $valid_mime_transforms, $main_images, $subsized_images ) {
foreach ( $valid_mime_transforms as $targeted_mime ) {
// Make sure the path and file exists as those values are being accessed.
if ( ! isset( $main_images[ $targeted_mime ]['path'], $main_images[ $targeted_mime ]['file'] ) || ! file_exists( $main_images[ $targeted_mime ]['path'] ) ) {
continue;
// Make sure the path and file exists as those values are required.
$image_directory = null;
if ( isset( $main_images[ $targeted_mime ]['path'], $main_images[ $targeted_mime ]['file'] ) && file_exists( $main_images[ $targeted_mime ]['path'] ) ) {
// Add sources to original image metadata.
$metadata['sources'][ $targeted_mime ] = array(
'file' => $main_images[ $targeted_mime ]['file'],
'filesize' => filesize( $main_images[ $targeted_mime ]['path'] ),
);
$image_directory = pathinfo( $main_images[ $targeted_mime ]['path'], PATHINFO_DIRNAME );
}

$image_directory = pathinfo( $main_images[ $targeted_mime ]['path'], PATHINFO_DIRNAME );
/**
* If no original image was provided the image_directory can't be determined, in that scenario try to
* find it from the `file` property.
*
* @see get_attached_file()
*/
if (
null === $image_directory
&& isset( $metadata['file'] )
&& 0 !== strpos( $metadata['file'], '/' )
&& ':\\' !== substr( $metadata['file'], 1, 2 )
) {
$uploads = wp_get_upload_dir();
if ( false === $uploads['error'] && isset( $uploads['basedir'] ) ) {
$file = path_join( $uploads['basedir'], $metadata['file'] );
if ( file_exists( $file ) ) {
$image_directory = pathinfo( $file, PATHINFO_DIRNAME );
}
}
}

// Add sources to original image metadata.
$metadata['sources'][ $targeted_mime ] = array(
'file' => $main_images[ $targeted_mime ]['file'],
'filesize' => filesize( $main_images[ $targeted_mime ]['path'] ),
);
if ( null === $image_directory ) {
continue;
}

foreach ( $metadata['sizes'] as $size_name => $size_details ) {
if ( empty( $subsized_images[ $targeted_mime ][ $size_name ]['file'] ) ) {
Expand All @@ -39,7 +62,6 @@ function webp_uploads_update_sources( $metadata, $valid_mime_transforms, $main_i

// Add sources to resized image metadata.
$subsize_path = path_join( $image_directory, $subsized_images[ $targeted_mime ][ $size_name ]['file'] );

if ( ! file_exists( $subsize_path ) ) {
continue;
}
Expand Down Expand Up @@ -91,15 +113,21 @@ function ( $metadata, $post_meta_id ) use ( $post_id, $file_path, $mime_type, $e
return $metadata;
}
$callback_executed = true;

// No sizes to be created.
if ( empty( $metadata['sizes'] ) ) {
return $metadata;
}

$old_metadata = wp_get_attachment_metadata( $post_id );
$resize_sizes = array();
$target = isset( $_REQUEST['target'] ) ? $_REQUEST['target'] : 'all';

foreach ( $old_metadata['sizes'] as $size_name => $size_details ) {
// If the target is 'nothumb', skip generating the 'thumbnail' size.
if ( 'nothumb' === $target && 'thumbnail' === $size_name ) {
continue;
}

if ( isset( $metadata['sizes'][ $size_name ] ) && ! empty( $metadata['sizes'][ $size_name ] ) &&
$metadata['sizes'][ $size_name ]['file'] !== $old_metadata['sizes'][ $size_name ]['file'] ) {
$resize_sizes[ $size_name ] = $metadata['sizes'][ $size_name ];
Expand All @@ -111,8 +139,18 @@ function ( $metadata, $post_meta_id ) use ( $post_id, $file_path, $mime_type, $e
$filename = pathinfo( $file_path, PATHINFO_FILENAME );
$main_images = array();
$subsized_images = array();

foreach ( $mime_transforms as $targeted_mime ) {
if ( $targeted_mime === $mime_type ) {
// If the target is `thumbnail` make sure it is the only selected size.
if ( 'thumbnail' === $target ) {
if ( isset( $metadata['sizes']['thumbnail'] ) ) {
$subsized_images[ $targeted_mime ] = array( 'thumbnail' => $metadata['sizes']['thumbnail'] );
}
// When the targeted thumbnail is selected no additional size and subsize is set.
continue;
}

$main_images[ $targeted_mime ] = array(
'path' => $file_path,
'file' => pathinfo( $file_path, PATHINFO_BASENAME ),
Expand All @@ -129,16 +167,44 @@ function ( $metadata, $post_meta_id ) use ( $post_id, $file_path, $mime_type, $e
continue;
}

$extension = explode( '|', $allowed_mimes[ $targeted_mime ] );
$destination = trailingslashit( $original_directory ) . "{$filename}.{$extension[0]}";
$result = $editor->save( $destination, $targeted_mime );

if ( is_wp_error( $result ) ) {
continue;
$extension = explode( '|', $allowed_mimes[ $targeted_mime ] );
$extension = $extension[0];

// If the target is `thumbnail` make sure only that size is generated.
if ( 'thumbnail' === $target ) {
if ( ! isset( $subsized_images[ $mime_type ]['thumbnail']['file'] ) ) {
continue;
}
$thumbnail_file = $subsized_images[ $mime_type ]['thumbnail']['file'];
$image_path = path_join( $original_directory, $thumbnail_file );
$editor = wp_get_image_editor( $image_path, array( 'mime_type' => $targeted_mime ) );

if ( is_wp_error( $editor ) ) {
continue;
}

$current_extension = pathinfo( $thumbnail_file, PATHINFO_EXTENSION );
// Create a file with then new extension out of the targeted file.
$target_file_name = preg_replace( "/\.$current_extension$/", ".$extension", $thumbnail_file );
$target_file_location = path_join( $original_directory, $target_file_name );
$result = $editor->save( $target_file_location, $targeted_mime );

if ( is_wp_error( $result ) ) {
continue;
}

$subsized_images[ $targeted_mime ] = array( 'thumbnail' => $result );
} else {
$destination = trailingslashit( $original_directory ) . "{$filename}.{$extension}";
$result = $editor->save( $destination, $targeted_mime );

if ( is_wp_error( $result ) ) {
continue;
}

$main_images[ $targeted_mime ] = $result;
$subsized_images[ $targeted_mime ] = $editor->multi_resize( $resize_sizes );
}

$main_images[ $targeted_mime ] = $result;
$subsized_images[ $targeted_mime ] = $editor->multi_resize( $resize_sizes );
}

return webp_uploads_update_sources( $metadata, $mime_transforms, $main_images, $subsized_images );
Expand Down
79 changes: 72 additions & 7 deletions tests/modules/images/webp-uploads/image-edit-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Tests for webp-uploads module image-edit.php.
*
* @package performance-lab
* @group webp-uploads
* @group image-edit
*/

use PerformanceLab\Tests\TestCase\ImagesTestCase;
Expand Down Expand Up @@ -138,31 +138,38 @@ public function it_should_prevent_to_backup_the_full_size_image_if_only_the_thum
$attachment_id = $this->factory->attachment->create_upload_object( TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg' );
$metadata = wp_get_attachment_metadata( $attachment_id );
$this->assertArrayHasKey( 'sources', $metadata );

$editor = new WP_Image_Edit( $attachment_id );
$editor->flip_vertical()->only_thumbnail()->save();
$this->assertTrue( $editor->success() );

$backup_sources = get_post_meta( $attachment_id, '_wp_attachment_backup_sources', true );
$this->assertEmpty( $backup_sources );

$backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
$this->assertIsArray( $backup_sizes );
$this->assertCount( 1, $backup_sizes );
$this->assertArrayHasKey( 'thumbnail-orig', $backup_sizes );
$this->assertArrayHasKey( 'sources', $backup_sizes['thumbnail-orig'] );

$metadata = wp_get_attachment_metadata( $attachment_id );

$this->assertImageHasSource( $attachment_id, 'image/jpeg' );
$this->assertImageHasSource( $attachment_id, 'image/webp' );

$this->assertImageHasSizeSource( $attachment_id, 'thumbnail', 'image/jpeg' );
$this->assertImageHasSizeSource( $attachment_id, 'thumbnail', 'image/webp' );

$this->assertFileNameIsNotEdited( $metadata['sources']['image/jpeg']['file'] );
$this->assertFileNameIsNotEdited( $metadata['sources']['image/webp']['file'] );

foreach ( $metadata['sizes'] as $size_name => $properties ) {
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/jpeg' );
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/webp' );

if ( 'thumbnail' === $size_name ) {
$this->assertSame( $properties['file'], $properties['sources']['image/jpeg']['file'] );
$this->assertSame( str_replace( '.jpg', '.webp', $properties['file'] ), $properties['sources']['image/webp']['file'] );
$this->assertFileNameIsEdited( $properties['sources']['image/jpeg']['file'] );
$this->assertFileNameIsEdited( $properties['sources']['image/webp']['file'] );
} else {
$this->assertFileNameIsNotEdited( $properties['sources']['image/jpeg']['file'] );
$this->assertFileNameIsNotEdited( $properties['sources']['image/webp']['file'] );
}
}
}

Expand Down Expand Up @@ -191,6 +198,10 @@ public function it_should_backup_the_image_when_all_images_except_the_thumbnail_
$this->assertImageHasSource( $attachment_id, 'image/jpeg' );
$this->assertImageHasSource( $attachment_id, 'image/webp' );

foreach ( $updated_metadata['sources'] as $properties ) {
$this->assertFileNameIsEdited( $properties['file'] );
}

$backup_sizes = get_post_meta( $attachment_id, '_wp_attachment_backup_sizes', true );
$this->assertIsArray( $backup_sizes );
$this->assertArrayNotHasKey( 'thumbnail-orig', $backup_sizes, 'The thumbnail-orig was stored in the back up' );
Expand All @@ -203,6 +214,60 @@ public function it_should_backup_the_image_when_all_images_except_the_thumbnail_
}
}

/**
* Use the attached image when updating subsequent images not the original version
*
* @test
*/
public function it_should_use_the_attached_image_when_updating_subsequent_images_not_the_original_version() {
// The leafs image is 1080 pixels wide with this filter we ensure a -scaled version is created for this test.
add_filter(
'big_image_size_threshold',
function () {
// Due to the largest image size is 1024 and the image is 1080x720, 1050 is a good spot to create a scaled size for all images sizes.
return 1050;
}
);

$attachment_id = $this->factory->attachment->create_upload_object(
TESTS_PLUGIN_DIR . '/tests/testdata/modules/images/leafs.jpg'
);

$this->assertNotSame( wp_get_original_image_path( $attachment_id ), get_attached_file( $attachment_id ) );

$editor = new WP_Image_Edit( $attachment_id );
$editor->flip_right()->all_except_thumbnail()->save();

$this->assertTrue( $editor->success() );

$metadata = wp_get_attachment_metadata( $attachment_id );

$this->assertArrayHasKey( 'original_image', $metadata );
$this->assertArrayHasKey( 'sources', $metadata );
$this->assertImageHasSource( $attachment_id, 'image/jpeg' );
$this->assertImageHasSource( $attachment_id, 'image/webp' );

foreach ( $metadata['sources'] as $properties ) {
$this->assertFileNameIsEdited( $properties['file'] );
$this->assertStringContainsString( '-scaled-', $properties['file'] );
}

$this->assertArrayHasKey( 'sizes', $metadata );
foreach ( $metadata['sizes'] as $size_name => $properties ) {
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/jpeg' );
$this->assertImageHasSizeSource( $attachment_id, $size_name, 'image/webp' );
foreach ( $properties['sources'] as $mime_type => $values ) {
if ( 'thumbnail' === $size_name ) {
$this->assertFileNameIsNotEdited( $values['file'], "'{$size_name}' is not valid." );
$this->assertStringNotContainsString( '-scaled-', $values['file'] );
} else {
$this->assertFileNameIsEdited( $values['file'], "'{$size_name}' is not valid." );
$this->assertStringContainsString( '-scaled-', $values['file'] );
}
}
}
}

/**
* Update source attributes when webp is edited.
*
Expand Down
Loading