@@ -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