Skip to content

Commit 6c4e9a0

Browse files
Copilotswissspidy
andcommitted
Add --update-attachment-refs flag to wp media regenerate
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 5c80fcf commit 6c4e9a0

2 files changed

Lines changed: 170 additions & 3 deletions

File tree

features/media-regenerate.feature

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1933,3 +1933,103 @@ Feature: Regenerate WordPress attachments
19331933
"""
19341934
site_icon-270
19351935
"""
1936+
1937+
Scenario: Update post content references when regenerating a specific image size
1938+
Given download:
1939+
| path | url |
1940+
| {CACHE_DIR}/canola.jpg | http://wp-cli.org/behat-data/canola.jpg |
1941+
And a wp-content/mu-plugins/media-settings.php file:
1942+
"""
1943+
<?php
1944+
add_action( 'after_setup_theme', function(){
1945+
add_image_size( 'test1', 400, 400, true );
1946+
});
1947+
"""
1948+
And I run `wp option update uploads_use_yearmonth_folders 0`
1949+
1950+
When I run `wp media import {CACHE_DIR}/canola.jpg --title="My imported attachment" --porcelain`
1951+
Then save STDOUT as {ATTACHMENT_ID}
1952+
And the wp-content/uploads/canola-400x400.jpg file should exist
1953+
1954+
# Get the full URL of the test1 thumbnail.
1955+
When I run `wp eval "echo wp_get_attachment_image_src( {ATTACHMENT_ID}, 'test1' )[0];"`
1956+
Then save STDOUT as {OLD_THUMBNAIL_URL}
1957+
1958+
# Create a post referencing the old thumbnail URL in post content.
1959+
When I run `wp post create --post_title="Test Post" --post_status=publish --post_content="{OLD_THUMBNAIL_URL}" --porcelain`
1960+
Then save STDOUT as {POST_ID}
1961+
1962+
# Confirm the old URL is in post content before regeneration.
1963+
When I run `wp post get {POST_ID} --field=post_content`
1964+
Then STDOUT should contain:
1965+
"""
1966+
canola-400x400.jpg
1967+
"""
1968+
1969+
# Change "test1" image size dimensions.
1970+
Given a wp-content/mu-plugins/media-settings.php file:
1971+
"""
1972+
<?php
1973+
add_action( 'after_setup_theme', function(){
1974+
add_image_size( 'test1', 350, 350, true );
1975+
});
1976+
"""
1977+
1978+
# Regenerate "test1" without --update-attachment-refs - post content should be unchanged.
1979+
When I run `wp media regenerate {ATTACHMENT_ID} --image_size=test1 --yes`
1980+
Then STDOUT should contain:
1981+
"""
1982+
1/1 Regenerated "test1" thumbnail for "My imported attachment"
1983+
"""
1984+
And the wp-content/uploads/canola-350x350.jpg file should exist
1985+
1986+
When I run `wp post get {POST_ID} --field=post_content`
1987+
Then STDOUT should contain:
1988+
"""
1989+
canola-400x400.jpg
1990+
"""
1991+
1992+
# Change "test1" back to 400x400 so we can test --update-attachment-refs.
1993+
Given a wp-content/mu-plugins/media-settings.php file:
1994+
"""
1995+
<?php
1996+
add_action( 'after_setup_theme', function(){
1997+
add_image_size( 'test1', 400, 400, true );
1998+
});
1999+
"""
2000+
When I run `wp media regenerate {ATTACHMENT_ID} --image_size=test1 --yes`
2001+
Then STDOUT should contain:
2002+
"""
2003+
1/1 Regenerated "test1" thumbnail for "My imported attachment"
2004+
"""
2005+
And the wp-content/uploads/canola-400x400.jpg file should exist
2006+
2007+
# Change "test1" to 350x350 and regenerate with --update-attachment-refs.
2008+
Given a wp-content/mu-plugins/media-settings.php file:
2009+
"""
2010+
<?php
2011+
add_action( 'after_setup_theme', function(){
2012+
add_image_size( 'test1', 350, 350, true );
2013+
});
2014+
"""
2015+
When I run `wp media regenerate {ATTACHMENT_ID} --image_size=test1 --update-attachment-refs --yes`
2016+
Then STDOUT should contain:
2017+
"""
2018+
1/1 Regenerated "test1" thumbnail for "My imported attachment"
2019+
"""
2020+
And STDOUT should contain:
2021+
"""
2022+
Success: Regenerated 1 of 1 images.
2023+
"""
2024+
And the wp-content/uploads/canola-350x350.jpg file should exist
2025+
2026+
# Confirm the post content was updated to use the new thumbnail URL.
2027+
When I run `wp post get {POST_ID} --field=post_content`
2028+
Then STDOUT should contain:
2029+
"""
2030+
canola-350x350.jpg
2031+
"""
2032+
And STDOUT should not contain:
2033+
"""
2034+
canola-400x400.jpg
2035+
"""

src/Media_Command.php

Lines changed: 70 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ class Media_Command extends WP_CLI_Command {
7474
* [--delete-unknown]
7575
* : Only delete thumbnails for old unregistered image sizes.
7676
*
77+
* [--update-attachment-refs]
78+
* : Update references to regenerated thumbnails in post content.
79+
*
7780
* [--yes]
7881
* : Answer yes to the confirmation message. Confirmation only shows when no IDs passed as arguments.
7982
*
@@ -123,7 +126,7 @@ class Media_Command extends WP_CLI_Command {
123126
* Success: Regenerated 3 of 3 images.
124127
*
125128
* @param string[] $args Positional arguments.
126-
* @param array{image_size?: string|string[], 'skip-delete'?: bool, 'only-missing'?: bool, 'delete-unknown'?: bool, yes?: bool} $assoc_args Associative arguments.
129+
* @param array{image_size?: string|string[], 'skip-delete'?: bool, 'only-missing'?: bool, 'delete-unknown'?: bool, 'update-attachment-refs'?: bool, yes?: bool} $assoc_args Associative arguments.
127130
* @return void
128131
*/
129132
public function regenerate( $args, $assoc_args = array() ) {
@@ -172,6 +175,8 @@ public function regenerate( $args, $assoc_args = array() ) {
172175
$skip_delete = false;
173176
}
174177

178+
$update_attachment_refs = Utils\get_flag_value( $assoc_args, 'update-attachment-refs' );
179+
175180
$additional_mime_types = array();
176181

177182
if ( Utils\wp_version_compare( '4.7', '>=' ) ) {
@@ -212,7 +217,7 @@ public function regenerate( $args, $assoc_args = array() ) {
212217
// @phpstan-ignore function.deprecated
213218
Utils\wp_clear_object_cache();
214219
}
215-
$this->process_regeneration( $post_id, $skip_delete, $only_missing, $delete_unknown, $image_sizes, $number . '/' . $count, $successes, $errors, $skips );
220+
$this->process_regeneration( $post_id, $skip_delete, $only_missing, $delete_unknown, $image_sizes, $update_attachment_refs, $number . '/' . $count, $successes, $errors, $skips );
216221
}
217222

218223
if ( isset( $image_size_filters ) ) {
@@ -715,6 +720,7 @@ private function get_image_sizes_description( array $sizes, $noun, $default_if_e
715720
* @param bool $only_missing
716721
* @param bool $delete_unknown
717722
* @param string[] $image_sizes
723+
* @param bool $update_attachment_refs
718724
* @param string $progress
719725
* @param int $successes
720726
* @param int $errors
@@ -724,7 +730,7 @@ private function get_image_sizes_description( array $sizes, $noun, $default_if_e
724730
* @param-out int $skips
725731
* @return void
726732
*/
727-
private function process_regeneration( $id, $skip_delete, $only_missing, $delete_unknown, $image_sizes, $progress, &$successes, &$errors, &$skips ) {
733+
private function process_regeneration( $id, $skip_delete, $only_missing, $delete_unknown, $image_sizes, $update_attachment_refs, $progress, &$successes, &$errors, &$skips ) {
728734

729735
$title = get_the_title( $id );
730736
if ( '' === $title ) {
@@ -752,6 +758,20 @@ private function process_regeneration( $id, $skip_delete, $only_missing, $delete
752758

753759
$original_meta = wp_get_attachment_metadata( $id );
754760

761+
$old_size_urls = array();
762+
if ( $update_attachment_refs && is_array( $original_meta ) && ! empty( $original_meta['sizes'] ) ) {
763+
$attachment_url = wp_get_attachment_url( $id );
764+
if ( $attachment_url ) {
765+
$dir_url = trailingslashit( dirname( $attachment_url ) );
766+
$sizes_to_track = $image_sizes ?: array_keys( $original_meta['sizes'] );
767+
foreach ( $sizes_to_track as $size ) {
768+
if ( ! empty( $original_meta['sizes'][ $size ]['file'] ) ) {
769+
$old_size_urls[ $size ] = $dir_url . $original_meta['sizes'][ $size ]['file'];
770+
}
771+
}
772+
}
773+
}
774+
755775
if ( $delete_unknown ) {
756776
$this->delete_unknown_image_sizes( $id, $fullsizepath );
757777

@@ -846,6 +866,31 @@ private function process_regeneration( $id, $skip_delete, $only_missing, $delete
846866

847867
WP_CLI::log( "$progress Regenerated thumbnails for $att_desc." );
848868
}
869+
870+
if ( $update_attachment_refs && ! empty( $old_size_urls ) && is_array( $metadata ) && ! empty( $metadata['sizes'] ) ) {
871+
$attachment_url = wp_get_attachment_url( $id );
872+
if ( $attachment_url ) {
873+
$dir_url = trailingslashit( dirname( $attachment_url ) );
874+
/**
875+
* @var array<string, array<string, mixed>> $new_sizes
876+
*/
877+
$new_sizes = is_array( $metadata['sizes'] ) ? $metadata['sizes'] : array();
878+
foreach ( $old_size_urls as $size => $old_url ) {
879+
$size_data = $new_sizes[ $size ] ?? null;
880+
if ( ! is_array( $size_data ) || empty( $size_data['file'] ) ) {
881+
continue;
882+
}
883+
/**
884+
* @var array{file: string} $size_data
885+
*/
886+
$new_url = $dir_url . $size_data['file'];
887+
if ( $old_url !== $new_url ) {
888+
$this->update_post_content_for_attachment( $old_url, $new_url );
889+
}
890+
}
891+
}
892+
}
893+
849894
++$successes;
850895
}
851896

@@ -1762,4 +1807,26 @@ private function delete_unknown_image_sizes( $id, $fullsizepath ) {
17621807
// @phpstan-ignore argument.type
17631808
wp_update_attachment_metadata( $id, $original_meta );
17641809
}
1810+
1811+
/**
1812+
* Updates post content replacing an old attachment URL with a new one.
1813+
*
1814+
* @param string $old_url Old thumbnail URL to search for.
1815+
* @param string $new_url New thumbnail URL to replace with.
1816+
* @return void
1817+
*/
1818+
private function update_post_content_for_attachment( $old_url, $new_url ) {
1819+
global $wpdb;
1820+
$result = $wpdb->query(
1821+
$wpdb->prepare(
1822+
"UPDATE {$wpdb->posts} SET post_content = REPLACE(post_content, %s, %s) WHERE post_content LIKE %s",
1823+
$old_url,
1824+
$new_url,
1825+
'%' . $wpdb->esc_like( $old_url ) . '%'
1826+
)
1827+
);
1828+
if ( false === $result ) {
1829+
WP_CLI::warning( sprintf( 'Failed to update post content references from "%s" to "%s".', $old_url, $new_url ) );
1830+
}
1831+
}
17651832
}

0 commit comments

Comments
 (0)