Skip to content

Commit 7d89a2b

Browse files
Copilotswissspidy
andcommitted
Batch URL replacements into single UPDATE per attachment
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent 6c4e9a0 commit 7d89a2b

1 file changed

Lines changed: 36 additions & 13 deletions

File tree

src/Media_Command.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,8 @@ private function process_regeneration( $id, $skip_delete, $only_missing, $delete
874874
/**
875875
* @var array<string, array<string, mixed>> $new_sizes
876876
*/
877-
$new_sizes = is_array( $metadata['sizes'] ) ? $metadata['sizes'] : array();
877+
$new_sizes = is_array( $metadata['sizes'] ) ? $metadata['sizes'] : array();
878+
$url_replacements = array();
878879
foreach ( $old_size_urls as $size => $old_url ) {
879880
$size_data = $new_sizes[ $size ] ?? null;
880881
if ( ! is_array( $size_data ) || empty( $size_data['file'] ) ) {
@@ -885,9 +886,12 @@ private function process_regeneration( $id, $skip_delete, $only_missing, $delete
885886
*/
886887
$new_url = $dir_url . $size_data['file'];
887888
if ( $old_url !== $new_url ) {
888-
$this->update_post_content_for_attachment( $old_url, $new_url );
889+
$url_replacements[ $old_url ] = $new_url;
889890
}
890891
}
892+
if ( ! empty( $url_replacements ) ) {
893+
$this->update_post_content_for_attachment( $url_replacements );
894+
}
891895
}
892896
}
893897

@@ -1809,24 +1813,43 @@ private function delete_unknown_image_sizes( $id, $fullsizepath ) {
18091813
}
18101814

18111815
/**
1812-
* Updates post content replacing an old attachment URL with a new one.
1816+
* Updates post content replacing old attachment URLs with new ones in a single query.
1817+
*
1818+
* Applies all replacements as nested REPLACE() calls so only one table scan is needed.
18131819
*
1814-
* @param string $old_url Old thumbnail URL to search for.
1815-
* @param string $new_url New thumbnail URL to replace with.
1820+
* @param array<string, string> $url_replacements Map of old URL => new URL.
18161821
* @return void
18171822
*/
1818-
private function update_post_content_for_attachment( $old_url, $new_url ) {
1823+
private function update_post_content_for_attachment( array $url_replacements ) {
18191824
global $wpdb;
1825+
1826+
if ( empty( $url_replacements ) ) {
1827+
return;
1828+
}
1829+
1830+
$replace_expr = 'post_content';
1831+
$replace_args = array();
1832+
$where_clauses = array();
1833+
$where_args = array();
1834+
1835+
foreach ( $url_replacements as $old_url => $new_url ) {
1836+
$replace_expr = "REPLACE($replace_expr, %s, %s)";
1837+
$replace_args[] = $old_url;
1838+
$replace_args[] = $new_url;
1839+
$where_clauses[] = 'post_content LIKE %s';
1840+
$where_args[] = '%' . $wpdb->esc_like( $old_url ) . '%';
1841+
}
1842+
1843+
$where_sql = implode( ' OR ', $where_clauses );
1844+
// phpcs:disable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
18201845
$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-
)
1846+
$wpdb->prepare( "UPDATE {$wpdb->posts} SET post_content = {$replace_expr} WHERE {$where_sql}", ...array_merge( $replace_args, $where_args ) )
18271847
);
1848+
// phpcs:enable WordPress.DB.PreparedSQL.NotPrepared,WordPress.DB.PreparedSQL.InterpolatedNotPrepared,WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
18281849
if ( false === $result ) {
1829-
WP_CLI::warning( sprintf( 'Failed to update post content references from "%s" to "%s".', $old_url, $new_url ) );
1850+
WP_CLI::warning( 'Failed to update post content references for attachment.' );
1851+
} else {
1852+
wp_cache_set( 'last_changed', microtime(), 'posts' );
18301853
}
18311854
}
18321855
}

0 commit comments

Comments
 (0)