Отложенная загрузка файлов — эффективный способ улучшить производительность сайта и снизить нагрузку на сервер. В WordPress это особенно актуально при работе с большим объемом медиафайлов или пользовательскими загрузками. В этой статье мы подробно разберём, как самостоятельно реализовать систему отложенной загрузки файлов, используя возможности ядра WordPress и собственный код.
Что такое отложенная загрузка файлов и зачем она нужна
Отложенная загрузка — это процесс, при котором файлы загружаются не сразу при отправке формы, а с некоторой задержкой или по событию (например, после подтверждения пользователя). Это позволяет разгрузить сервер в пиковые моменты, избежать ошибок из-за превышения лимитов и повысить удобство для пользователя.
Для сайтов с интенсивным обменом файлами, например, на wpupload.ru, такая функциональность позволит:
- Снизить риск таймаутов и ошибок при загрузке больших файлов.
- Организовать очередь загрузок, чтобы сервер обрабатывал файлы последовательно.
- Позволить пользователю отложить загрузку и продолжить её позже.
Примеры плагинов с похожей функциональностью
Существуют плагины, реализующие отложенную загрузку, например, Async Upload, но они зачастую не дают полной свободы и гибкости. Мы же рассмотрим, как сделать это самостоятельно.
Основные этапы создания отложенной загрузки файлов в WordPress
Для реализации нам понадобится:
- Форма для выбора и отправки файлов с фронтенда.
- Обработка загруженных файлов и их временное хранение, например, в отдельной папке или базе данных.
- Механизм запуска фактической загрузки/переноса файлов в медиабиблиотеку WordPress по событию.
- Уведомления пользователя и управление очередью загрузок.
1. Создание формы для выбора файлов
Начнём с простой HTML-формы с поддержкой множественной загрузки:
<form id="wpupload-delayed-upload" enctype="multipart/form-data" method="post">
<input type="file" name="wpupload_files[]" multiple />
<input type="submit" value="Добавить файлы в очередь" />
</form>Форма отправляет файлы на сервер, где мы не будем сразу их сохранять в медиабиблиотеку, а положим во временное хранилище.
2. Обработка и сохранение файлов во временную папку
Создадим функцию для обработки отправленных файлов и сохранения их во временную директорию wp-content/uploads/wpupload-temp:
function wpupload_handle_delayed_upload() {
if (empty($_FILES['wpupload_files'])) {
return;
}
$upload_dir = wp_upload_dir();
$temp_dir = $upload_dir['basedir'] . '/wpupload-temp';
if (!file_exists($temp_dir)) {
wp_mkdir_p($temp_dir);
}
foreach ($_FILES['wpupload_files']['tmp_name'] as $key => $tmp_name) {
$name = sanitize_file_name($_FILES['wpupload_files']['name'][$key]);
$target = $temp_dir . '/' . $name;
if (move_uploaded_file($tmp_name, $target)) {
// Можно сохранять в БД информацию о файле, чтобы потом обработать
wpupload_save_temp_file($name, $target);
}
}
}
add_action('admin_post_nopriv_wpupload_delayed_upload', 'wpupload_handle_delayed_upload');
add_action('admin_post_wpupload_delayed_upload', 'wpupload_handle_delayed_upload');Функция wpupload_save_temp_file должна сохранять информацию в таблицу или опцию для дальнейшей обработки.
3. Реализация очереди и запуск окончательной загрузки
Для загрузки из временного хранилища в медиабиблиотеку используем wp_insert_attachment. Создадим функцию, которая по расписанию (WP-Cron) или по запросу будет обрабатывать файлы из очереди:
function wpupload_process_queue() {
$files = wpupload_get_temp_files(); // Получаем список файлов из БД или опции
$upload_dir = wp_upload_dir();
foreach ($files as $file) {
$file_path = $file['path'];
$filetype = wp_check_filetype(basename($file_path), null);
$attachment = array(
'post_mime_type' => $filetype['type'],
'post_title' => sanitize_file_name(basename($file_path)),
'post_content' => '',
'post_status' => 'inherit'
);
$attach_id = wp_insert_attachment($attachment, $file_path);
if (!is_wp_error($attach_id)) {
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attach_id, $file_path);
wp_update_attachment_metadata($attach_id, $attach_data);
wpupload_remove_temp_file($file['id']); // Удаляем из очереди
}
}
}
// Привяжем к WP-Cron
if (!wp_next_scheduled('wpupload_process_queue_event')) {
wp_schedule_event(time(), 'hourly', 'wpupload_process_queue_event');
}
add_action('wpupload_process_queue_event', 'wpupload_process_queue');Такой механизм позволяет периодически переносить файлы из временного хранилища в медиабиблиотеку WordPress.
Управление очередью и уведомления для пользователя
Чтобы пользователь понимал статус загрузки, можно реализовать:
- Страницу со списком файлов, добавленных в очередь.
- Кнопку для запуска загрузки вручную.
- Уведомления через AJAX при успешной загрузке.
Пример AJAX-запроса для запуска обработки
jQuery(document).ready(function($) {
$('#start-upload').on('click', function() {
$.post(ajaxurl, { action: 'wpupload_start_processing' }, function(response) {
alert('Загрузка файлов началась');
});
});
});На сервере нужно обработать этот запрос:
function wpupload_start_processing_ajax() {
wpupload_process_queue();
wp_send_json_success('Обработка завершена');
}
add_action('wp_ajax_wpupload_start_processing', 'wpupload_start_processing_ajax');Резюме и советы по безопасности
При реализации отложенной загрузки важно:
- Ограничить типы и размеры загружаемых файлов.
- Проверять права пользователя.
- Использовать nonce для защиты форм и AJAX-запросов.
- Периодически очищать временную папку от устаревших файлов.
Для расширенной функциональности можно интегрировать этот механизм с плагином Clearfy Pro, который поможет оптимизировать работу с загрузками и безопасностью.