¿Cómo encontrar un archivo adjunto por su nombre?
¿Es posible obtener el ID de un archivo adjunto por su nombre? Y de una vez, ¿es posible obtener la publicación principal a la que está asignado este archivo adjunto?

Tienes que escribir código personalizado para obtener el ID del adjunto y el post_parent por nombre/slug o nombre del archivo (si no ha sido cambiado durante la subida de archivos).
Coloca el siguiente código en el archivo functions.php de tu tema:
if( ! ( function_exists( 'wp_get_attachment_by_post_name' ) ) ) {
function wp_get_attachment_by_post_name( $post_name ) {
$args = array(
'posts_per_page' => 1,
'post_type' => 'attachment',
'name' => trim( $post_name ),
);
$get_attachment = new WP_Query( $args );
if ( ! $get_attachment || ! isset( $get_attachment->posts, $get_attachment->posts[0] ) ) {
return false;
}
return $get_attachment->posts[0];
}
}
Luego puedes llamar a la función donde la necesites de la siguiente manera:
$attachment = wp_get_attachment_by_post_name( $post_name );
// Reemplaza post_name por el nombre/slug del adjunto
// Te dará un objeto, el cual puedes usar como se muestra a continuación para obtener el ID y post_parent
if ( $attachment ) {
echo $attachment->ID; // Devuelve el ID del adjunto
echo $attachment->post_parent; // Devuelve el ID del post_parent
echo $attachment->post_title; // Devuelve el título del adjunto.
}

Puedes intentar usar el nombre del archivo en lugar del post_name como parámetro, ya que WordPress crea el slug para el adjunto con el nombre del archivo a menos que sea modificado.

@user1692333 ¿Podrías explicar tu situación donde este fragmento no funciona? y hagamos que funcione

lo hice de una manera más simple, solo usé wp_query con búsqueda y obtuve de ahí el ID del post.

Otro enfoque posible es usar directamente $wpdb para realizar una consulta SQL, en la tabla de posts, con el título del post buscado y con post_type "attachment".
function get_attachment_url_by_title( $title ) {
global $wpdb;
$attachments = $wpdb->get_results( "SELECT * FROM $wpdb->posts WHERE post_title = '$title' AND post_type = 'attachment' ", OBJECT );
//print_r($attachments);
if ( $attachments ){
$attachment_url = $attachments[0]->guid;
}else{
return 'image-not-found';
}
return $attachment_url;
}
// uso:
get_attachment_url_by_title('tu_titulo_de_imagen');
Ten en cuenta que este código devolverá el primer adjunto con este título.
Forma alternativa, sin consulta SQL. Mejor en la mayoría de los casos:
function get_attachment_url_by_title( $title ) {
$attachment = get_page_by_title($title, OBJECT, 'attachment');
//print_r($attachment);
if ( $attachment ){
$attachment_url = $attachment->guid;
}else{
return 'image-not-found';
}
return $attachment_url;
}
echo get_attachment_url_by_title('tu_titulo_de_imagen');

Basado en el Código de WordPress,
'attachment' - un adjunto. Mientras que el post_status predeterminado de WP_Query es 'publish', los adjuntos tienen un post_status predeterminado de 'inherit'. Esto significa que no se devolverán adjuntos a menos que también establezca explícitamente post_status como 'inherit' o 'any'. (Ver post_status, abajo)

Acabo de pasar un par de horas intentando resolver este mismo problema. Había un nombre de archivo que get_page_by_title no podía encontrar. Adapté la respuesta de @Snade para mis propósitos.
Solo tengo el nombre del archivo y necesito obtener la URL de la imagen desde la biblioteca de medios. Snade estuvo muy cerca, pero incluso así su función no funcionó en mis circunstancias. La función que proporcionó me llevó en la dirección correcta.
Esta solución que estaré probando, parece funcionar. Básicamente todo lo que necesito es encontrar el nombre del archivo en el guid. Como el título eliminó la extensión y añadió espacios, no pude encontrar esta imagen de otra manera.
A hacer más pruebas...
function get_attachment_url_by_guid( $filename ) {
global $wpdb;
$ext = array(".png", ".jpg", ".gif", ".jpeg");
$filename = str_replace($ext, "", $filename);
$clean_filename = trim(html_entity_decode(sanitize_title($filename)));
$attachments = $wpdb->get_results( "SELECT guid FROM $wpdb->posts WHERE guid LIKE '%$clean_filename%' AND post_type = 'attachment' ", OBJECT );
//print_r($attachments);
if ( $attachments ){
$attachment_url = $attachments[0]->guid;
}else{
return 'image-not-found';
}
return $attachment_url;
}

¡Tienes toda la razón! @Tami Pero este código solo está dentro de un plugin que no se distribuye. Solo es un plugin personalizado para mi sitio. Lo actualizaré en el futuro. Buen apunte.

He tenido que dedicar demasiado tiempo a esto ya que algunas de las soluciones anteriores funcionan en ciertos casos pero no en otros. El punto clave es para archivos adjuntos subidos con una resolución mayor a 2560px. WordPress añade '-scaled' al nombre de archivo devuelto por get_attached_file(), pero esto no se refleja en la columna 'guid' de la base de datos.
Al final, analicé el código de get_attached_file() y desarrollé la siguiente solución:
/**
* Obtiene el ID de un adjunto por su nombre de archivo
*
* @param string $filename Nombre del archivo a buscar
* @return int|false ID del adjunto o false si no se encuentra
*/
function get_attachment_id_by_filename($filename) {
global $wpdb;
$attachments = $wpdb->get_results("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wp_attached_file' AND meta_value like'%$filename'", OBJECT);
return $attachments[0]->post_id ?? false;
}
