Удаление записи со всеми прикрепленными файлами
На моем сайте есть несколько авторов, которые могут добавлять/редактировать/удалять пользовательские записи и загружать (прикреплять) изображения к этим записям. Проблема в том, что когда они удаляют свои записи, вложения остаются на сервере. Поэтому я хотел бы избавиться от всех файлов, прикрепленных к записи, когда она удаляется. Может кто-нибудь поделиться примером, как это сделать?
Я написал следующую функцию, которая использует логику, предложенную @rarst в его ответе.
add_action( 'before_delete_post', function( $id ) {
$attachments = get_attached_media( '', $id );
foreach ($attachments as $attachment) {
wp_delete_attachment( $attachment->ID, 'true' );
}
} );
ВАЖНО: Учтите, эта функция будет вызываться только при постоянном удалении записей из корзины! Если вы хотите изменить это поведение, добавьте следующую строку в ваш файл wp-config.php
:
define('EMPTY_TRASH_DAYS', 0);
Если эта константа установлена в 0, функциональность корзины будет отключена, и вместо кнопки 'В корзину' появится кнопка 'Удалить навсегда'. При нажатии на кнопку 'Удалить навсегда' элемент будет немедленно удалён без какого-либо предупреждающего сообщения.
(Из Кодекса)

Сработало для меня - добавил проверку, чтобы применять это только для определенного типа записи, и все заработало как по волшебству.

WordPress по умолчанию не делает этого, так как нет гарантии, что вложение больше не используется каким-либо другим постом.
Основная логика заключается в подключении к хуку delete_post
, запросе дочерних вложений и запуске wp_delete_attachment()
для каждого из них.
Я быстро проверил репозиторий плагинов и нашел небольшой плагин, который делает именно это (похоже, что он не поддерживается, так что протестируйте перед использованием) - Post Data Delete Advanced.

Отмечу, что следуя вашей базовой логике, у меня получилось успешно использовать before_delete_post
вместо delete_post
. Возможно, к моменту выполнения delete_post
метаданные записи уже удалены (а они необходимы для корректной работы wp_delete_attachment
).

Расширение других ответов для использования с определенным типом записи.
add_action( 'before_delete_post', 'delete_all_attached_media' );
function delete_all_attached_media( $post_id ) {
if( get_post_type($post_id) == "post" ) {
$attachments = get_attached_media( '', $post_id );
foreach ($attachments as $attachment) {
wp_delete_attachment( $attachment->ID, 'true' );
}
}
}
Этот код удалит все прикрепленные медиафайлы при окончательном удалении записи.

Если кто-то все еще ищет простое решение, попробуйте следующий плагин - он работает с обычными записями/страницами и пользовательскими типами записей: Delete Post with Attachments
