Skip to content

Commit 4a20e61

Browse files
Copilotswissspidy
andcommitted
Fix skip-duplicates: use RIGHT() for detection, restore error messages for non-skip-duplicates paths
Co-authored-by: swissspidy <841956+swissspidy@users.noreply.github.com>
1 parent cd7eb24 commit 4a20e61

1 file changed

Lines changed: 20 additions & 26 deletions

File tree

src/Media_Command.php

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ public function import( $args, $assoc_args = array() ) {
384384
continue;
385385
}
386386
if ( Utils\get_flag_value( $assoc_args, 'skip-duplicates' ) ) {
387-
$existing = $this->find_duplicate_attachment( Utils\basename( $file ), false );
387+
$existing = $this->find_duplicate_attachment( Utils\basename( $file ) );
388388
if ( false !== $existing ) {
389389
if ( ! $porcelain ) {
390390
WP_CLI::log( "Skipped importing file '$orig_filename'. Reason: already exists as attachment ID $existing." );
@@ -405,7 +405,7 @@ public function import( $args, $assoc_args = array() ) {
405405
}
406406
} else {
407407
if ( Utils\get_flag_value( $assoc_args, 'skip-duplicates' ) ) {
408-
$existing = $this->find_duplicate_attachment( $file, true );
408+
$existing = $this->find_duplicate_attachment( (string) explode( '?', Utils\basename( $file ), 2 )[0] );
409409
if ( false !== $existing ) {
410410
if ( ! $porcelain ) {
411411
WP_CLI::log( "Skipped importing file '$orig_filename'. Reason: already exists as attachment ID $existing." );
@@ -566,7 +566,7 @@ public function import( $args, $assoc_args = array() ) {
566566

567567
// Report the result of the operation
568568
if ( ! Utils\get_flag_value( $assoc_args, 'porcelain' ) ) {
569-
Utils\report_batch_operation_results( $noun, 'import', count( $args ), $successes, $errors, $skips );
569+
Utils\report_batch_operation_results( $noun, 'import', count( $args ), $successes, $errors, Utils\get_flag_value( $assoc_args, 'skip-duplicates' ) ? $skips : null );
570570
} elseif ( $errors ) {
571571
WP_CLI::halt( 1 );
572572
}
@@ -717,35 +717,29 @@ private function make_copy( $path ) {
717717
}
718718

719719
/**
720-
* Finds an existing attachment by filename or source URL.
720+
* Finds an existing attachment whose basename matches the given filename.
721721
*
722-
* For local files, matches against the basename of the `_wp_attached_file` meta value.
723-
* This will match the first attachment found when multiple files share the same basename
724-
* in different upload subdirectories.
722+
* Searches the `_wp_attached_file` post meta, which stores the path relative to
723+
* the uploads directory (e.g. '2026/03/image.jpg' or just 'image.jpg'). Matches
724+
* the first attachment found when multiple files share the same basename across
725+
* different upload subdirectories.
725726
*
726-
* @param string $file_or_name Basename of the local file, or full URL for remote files.
727-
* @param bool $is_remote Whether to search by source URL (remote) or by filename (local).
727+
* @param string $basename Filename basename to search for (e.g. 'image.jpg').
728728
* @return int|false Attachment ID if found, false otherwise.
729729
*/
730-
private function find_duplicate_attachment( $file_or_name, $is_remote ) {
730+
private function find_duplicate_attachment( $basename ) {
731731
global $wpdb;
732732

733-
if ( $is_remote ) {
734-
$result = $wpdb->get_var(
735-
$wpdb->prepare(
736-
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_source_url' AND meta_value = %s LIMIT 1",
737-
$file_or_name
738-
)
739-
);
740-
} else {
741-
$result = $wpdb->get_var(
742-
$wpdb->prepare(
743-
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND (meta_value = %s OR meta_value LIKE %s) LIMIT 1",
744-
$file_or_name,
745-
'%/' . $wpdb->esc_like( $file_or_name )
746-
)
747-
);
748-
}
733+
$slash_basename = '/' . $basename;
734+
735+
$result = $wpdb->get_var(
736+
$wpdb->prepare(
737+
"SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_wp_attached_file' AND (meta_value = %s OR RIGHT(meta_value, %d) = %s) LIMIT 1",
738+
$basename,
739+
mb_strlen( $slash_basename, 'UTF-8' ),
740+
$slash_basename
741+
)
742+
);
749743

750744
return $result ? (int) $result : false;
751745
}

0 commit comments

Comments
 (0)