Проверка наличия файла в медиатеке WordPress
Я создаю пользовательские файлы в плагине и добавляю их в медиатеку WordPress, используя код из Codex для функции wp_insert_attachment. Однако мой плагин иногда перезаписывает эти файлы. Мне нужно убедиться, что файлы не добавляются повторно в медиатеку. Вот текущий код:
$wp_filetype = wp_check_filetype(basename($filename), null );
$wp_upload_dir = wp_upload_dir();
$attachment = array(
'guid' => $wp_upload_dir['baseurl'] . '/' . _wp_relative_upload_path( $filename ),
'post_mime_type' => $wp_filetype['type'],
'post_title' => preg_replace('/\.[^.]+$/', '', basename($filename)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment( $attachment, $filename);
// необходимо сначала подключить файл image.php
// для работы функции wp_generate_attachment_metadata()
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
Мне нужно просто проверить, есть ли файл уже в медиатеке, и обновить его, если он существует. У меня нет post_id для работы, только permalink и guid.
Спасибо за помощь.

global $wpdb;
$image_src = wp_upload_dir()['baseurl'] . '/' . _wp_relative_upload_path( $filename );
$query = "SELECT COUNT(*) FROM {$wpdb->posts} WHERE guid='$image_src'";
$count = intval($wpdb->get_var($query));
Этот код можно разместить в начале вашего скрипта. Затем проверьте значение переменной $count
. Если оно равно 0, значит можно продолжать добавление вложения

У меня есть такой метод (спасибо Mridul):
function MediaFileAlreadyExists($filename){
global $wpdb;
$query = "SELECT COUNT(*) FROM {$wpdb->postmeta} WHERE meta_value LIKE '%/$filename'";
return ($wpdb->get_var($query) > 0) ;
}
// MediaFileAlreadyExists("my-image.png");

Я знаю, что это старый вопрос, но мне не понравились ни один из предложенных ответов, поэтому вот мое решение.
Этот код проверяет, существует ли файл. Если файл существует, он обновит существующее вложение; если нет — создаст новое.
// Получаем директорию загрузок
$upload_dir = wp_upload_dir();
$upload_folder = $upload_dir['path'];
// Устанавливаем имя файла, включая путь
$filename = "{$upload_folder}/myfile-{$id}.pdf";
// Проверяем тип файла. Используем его как 'post_mime_type'.
$filetype = wp_check_filetype( basename( $filename ), null );
// Получаем заголовок файла
$title = preg_replace( '/\.[^.]+$/', '', basename( $filename ) );
// Подготавливаем массив данных для вложения
$attachment_data = array(
'guid' => $upload_dir['url'] . '/' . basename( $filename ),
'post_mime_type' => $filetype['type'],
'post_title' => $title,
'post_content' => '',
'post_status' => 'inherit'
);
// Проверяем, существует ли вложение?
if( post_exists( $title ) ){
$attachment = get_page_by_title( $title, OBJECT, 'attachment');
if( !empty( $attachment ) ){
$attachment_data['ID'] = $attachment->ID;
}
}
// Если parent_id не установлен, сбрасываем на значение по умолчанию (0)
if( empty( $parent_id ) ){
$parent_id = 0;
}
// Вставляем вложение
$attach_id = wp_insert_attachment( $attachment_data, $filename, $parent_id );
// Генерируем метаданные для вложения и обновляем запись в базе данных
$attach_data = wp_generate_attachment_metadata( $attach_id, $filename );
wp_update_attachment_metadata( $attach_id, $attach_data );
В примере выше я использую .pdf в переменной $filename, но вы можете заменить это на любое имя файла/тип файла.

Вы можете проверить существование изображения с помощью post_exists($filename)
. Если изображение существует, вы можете обновить его или создать новое.
// если изображение существует - обновляем, иначе создаем
if (post_exists($filename)){
$page = get_page_by_title($filename, OBJECT, 'attachment');
$attach_id = $page->ID;
$attach_data = wp_generate_attachment_metadata( $attach_id, $destination ); // Генерируем метаданные вложения: размер файла, высоту, ширину и т.д.
wp_update_attachment_metadata( $attach_id, $attach_data ); // Добавляем сгенерированные метаданные
add_post_meta($attach_id, '_wp_attachment_image_alt', $filealt); // Добавляем альтернативный текст
}
else{
$attach_id = wp_insert_attachment( $attachment, $destination, $post_id );
$attach_data = wp_generate_attachment_metadata( $attach_id, $destination );
wp_update_attachment_metadata( $attach_id, $attach_data );
add_post_meta($attach_id, '_wp_attachment_image_alt', $filealt);
}

post_exists автоматически возвращает ID записи, если она существует, поэтому нет необходимости использовать get_page_by_title()
https://developer.wordpress.org/reference/functions/post_exists/

Эта функция принимает в качестве параметра имя медиафайла и возвращает meta_id, если он существует, в противном случае возвращает (false).
function MediaFileAlreadyExists($filename){
global $wpdb;
$query = "SELECT meta_id FROM {$wpdb->postmeta} WHERE meta_value LIKE '%/$filename'";
if ( $wpdb->get_var($query) ){
return $wpdb->get_var($query);
}
return false;
}

Мне нравится использование LIKE. Когда WordPress загружает дубликат, он добавляет -x к имени файла. Некоторые плагины добавляют уникальный ключ перед именем, чтобы избежать дубликатов (Media Cloud). post_exists($filename) пропустит это. Модифицирую ваш код для обработки как префиксов, так и суффиксов $basename. Спасибо.
