Как создать автоматическое решение для удаления старых медиафайлов в WordPress

Иногда на WordPress-сайте накапливаются неиспользуемые или устаревшие медиафайлы, которые занимают лишнее место на сервере и замедляют работу сайта. В этой статье мы рассмотрим, как создать собственное автоматическое решение для поиска и удаления таких медиафайлов с помощью кода и популярных плагинов.

Проблема старых медиафайлов и зачем их удалять

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

Ручное удаление медиафайлов — утомительная и рискованная задача. Поэтому имеет смысл автоматизировать этот процесс с помощью кастомного кода и/или специализированных плагинов.

Использование плагинов для удаления неиспользуемых медиафайлов

Рассмотрим несколько популярных плагинов, которые помогут найти и удалить устаревшие медиафайлы:

  • Media Cleaner – мощный инструмент, который сканирует медиатеку и выявляет неиспользуемые файлы. Поддерживает работу с классическими и кастомными типами записей.
  • WP Sweep – плагин для оптимизации базы данных, который также умеет очищать медиатеку от мусора.
  • Clearfy Pro – комплексный плагин для оптимизации WordPress, включает функцию очистки медиатеки от неиспользуемых файлов. Подробнее на wpshop.ru.

Однако, если нужны гибкие настройки и автоматизация по расписанию, лучше создать собственное решение с помощью WP Cron и пользовательских функций.

Создаем автоматическое удаление старых медиафайлов с помощью кода

Ниже приведен пример кода, который находит медиафайлы, не привязанные к записям и не обновлявшиеся более 180 дней, а затем удаляет их. Код подключается к планировщику WP Cron и запускается раз в сутки.

function wpedu_find_and_delete_old_unused_media() {
    global $wpdb;
    $days_old = 180; // Период в днях
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_old . ' days'));

    // Получаем ID вложений, не привязанных к записям и старше даты
    $query = $wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_wp_attached_file' WHERE p.post_type = 'attachment' AND p.post_parent = 0 AND p.post_modified < %s",
        $date_threshold
    );

    $attachment_ids = $wpdb->get_col($query);

    foreach ($attachment_ids as $attachment_id) {
        // Проверяем, используется ли файл где-либо ещё (например, в постах)
        $file_url = wp_get_attachment_url($attachment_id);
        $args = array(
            'post_type' => 'any',
            'post_status' => 'publish',
            's' => basename($file_url),
            'fields' => 'ids',
            'posts_per_page' => 1
        );
        $posts_with_file = get_posts($args);

        if (empty($posts_with_file)) {
            // Удаляем вложение без возможности восстановления
            wp_delete_attachment($attachment_id, true);
        }
    }
}

// Создаем событие в WP Cron
if (!wp_next_scheduled('wpedu_daily_delete_old_media')) {
    wp_schedule_event(time(), 'daily', 'wpedu_daily_delete_old_media');
}
add_action('wpedu_daily_delete_old_media', 'wpedu_find_and_delete_old_unused_media');

Этот код:

  • Ищет вложения с post_parent = 0 (то есть не привязанные к постам), которые не обновлялись более 180 дней.
  • Дополнительно проверяет, что файл не встречается в тексте публикаций.
  • Автоматически удаляет файлы с помощью wp_delete_attachment без возможности восстановления.
  • Запускается автоматически раз в сутки через WP Cron.

Настройка и тестирование

Перед включением автоматического удаления настоятельно рекомендуем:

  • Создать резервную копию базы и файлов сайта.
  • Запустить функцию вручную, вызвав wpedu_find_and_delete_old_unused_media() через админ-панель или WP CLI, чтобы проверить список удаляемых файлов.
  • При необходимости изменить период (переменная $days_old) под свои задачи.

Дополнительные идеи по улучшению решения

Вы можете расширить функционал, добавив:

  • Отправку отчета на email после каждого запуска с перечнем удаленных файлов.
  • Интеграцию с плагином Clearfy Pro для более глубокой оптимизации.
  • Добавление настроек в админ-панель для управления периодом и включением/отключением задачи.

Пример отправки отчета по email

Добавим простую отправку письма с количеством удаленных файлов:

function wpedu_find_and_delete_old_unused_media_with_report() {
    global $wpdb;
    $days_old = 180;
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_old . ' days'));
    $deleted_count = 0;

    $query = $wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} p LEFT JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = '_wp_attached_file' WHERE p.post_type = 'attachment' AND p.post_parent = 0 AND p.post_modified < %s",
        $date_threshold
    );

    $attachment_ids = $wpdb->get_col($query);

    foreach ($attachment_ids as $attachment_id) {
        $file_url = wp_get_attachment_url($attachment_id);
        $args = array(
            'post_type' => 'any',
            'post_status' => 'publish',
            's' => basename($file_url),
            'fields' => 'ids',
            'posts_per_page' => 1
        );
        $posts_with_file = get_posts($args);

        if (empty($posts_with_file)) {
            if (wp_delete_attachment($attachment_id, true)) {
                $deleted_count++;
            }
        }
    }

    $to = get_option('admin_email');
    $subject = 'Отчет по удалению старых медиафайлов на сайте';
    $message = "Удалено файлов: " . $deleted_count;
    wp_mail($to, $subject, $message);
}

add_action('wpedu_daily_delete_old_media', 'wpedu_find_and_delete_old_unused_media_with_report');

Таким образом, вы получите уведомления о работе скрипта и сможете контролировать процесс.

Заключение

Регулярное удаление устаревших медиафайлов помогает уменьшить размер базы данных и папки uploads, повысить производительность и управляемость сайта. Используя приведенный пример и плагины, вы сможете настроить эту задачу под свои нужды и автоматизировать процесс без постоянного ручного контроля.

⭐⭐⭐⭐⭐