Как найти вложение по его имени?
Возможно ли получить ID вложения по его имени? И сразу же, возможно ли получить родительский пост, к которому это вложение прикреплено?

Вам необходимо написать пользовательский код для получения ID вложения и post_parent по названию/ слагу или имени файла (если оно не изменялось при загрузке файлов).
Поместите следующий код в файл functions.php вашей темы:
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];
}
}
Затем вы можете вызвать эту функцию там, где она вам нужна, следующим образом:
$attachment = wp_get_attachment_by_post_name( $post_name );
// Замените $post_name на название/слаг вложения
// Это вернет объект, который можно использовать, как показано ниже, для получения ID и post_parent
if ( $attachment ) {
echo $attachment->ID; // Возвращает ID вложения
echo $attachment->post_parent; // Возвращает ID родительской записи
echo $attachment->post_title; // Возвращает заголовок вложения.
}

Вы можете попробовать использовать имя файла вместо post_name в качестве параметра, так как WordPress создает ярлык для вложения на основе имени файла, если он не был изменен вручную.

@user1692333 Не могли бы вы объяснить вашу ситуацию, в которой этот сниппет не работает? Давайте сделаем так, чтобы он заработал

я сделал это более простым способом, просто использовал wp_query с поиском и получил оттуда ID поста.

@user1692333 Отлично!!! Почему бы тебе не поделиться тем, что ты сделал?

Другой возможный подход - напрямую использовать $wpdb для SQL-запроса в таблице posts по заголовку вложения и типу записи "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;
}
// использование:
get_attachment_url_by_title('название_вашего_изображения');
Имейте в виду, что этот код вернет первое вложение с таким заголовком.
Альтернативный способ без SQL-запроса. В большинстве случаев лучше:
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('название_вашего_изображения');

get_page_by_title()
отлично подойдет для этой задачи.
Пример с полным URL в качестве заголовка:
get_page_by_title( pathinfo( 'https://www.example.com/file.jpg' )['filename'], "OBJECT", 'attachment' );
Возвращает объект WP_Post или Null, если записи/вложения не были найдены.

Согласно WordPress Codex,
attachment' - вложение. Хотя стандартный post_status в WP_Query - это 'publish', для вложений по умолчанию установлен post_status 'inherit'. Это означает, что вложения не будут возвращены, если вы также явно не укажете post_status как 'inherit' или 'any'. (См. post_status ниже)

Я только что потратил пару часов, пытаясь решить эту проблему. Был файл, который не мог найти get_page_by_title. @Snade Я адаптировал его ответ для своих целей.
У меня есть только имя файла, и мне нужно получить URL изображения из медиатеки. Snade был очень близок, но даже его функция не сработала в моей ситуации. Однако его функция направила меня в правильное русло.
Это решение я буду тестировать, но, кажется, оно работает. По сути, я ищу имя файла в поле guid. Поскольку название файла было очищено от расширения и заменено пробелами, я не смог найти это изображение другим способом.
Продолжаю тестирование...
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;
}

Лучше было бы использовать $wpdb->prepare для запроса get_results @Robbiegod

Ты абсолютно прав! @Tami Но этот код используется только внутри плагина, который не распространяется. Это просто кастомный плагин для моего сайта. Я обновлю его в будущем. Хорошее замечание.

Мне пришлось потратить слишком много времени на это, так как некоторые из вышеперечисленных решений работают в одних ситуациях, но не работают в других. Основная проблема возникает с вложениями, загруженными с разрешением более 2560 пикселей. WordPress добавляет '-scaled' к имени файла, возвращаемому get_attached_file(), но это не отражается в столбце guid базы данных.
В итоге я проанализировал код функции get_attached_file() и создал следующее решение.
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;}
