Загрузка файлов с помощью AJAX для вашего WordPress плагина
Загрузка файлов для плагина WordPress — не самая простая задача. Необходимо предоставить пользователю простой и понятный интерфейс, а также правильно обрабатывать загружаемые файлы, чтобы не создавать уязвимости.
Для того, чтобы не писать полностью собственный загрузчик файлов, мы будем использовать функционал WordPress, а именно файл async-upload.php, расположенный в папке wp-admin.
Используя этот файл мы получаем ряд преимуществ. Во-первых это стандартный файл для загрузки медиа файлов в WordPress, таким образом мы можем быть уверены в том, что код работает правильно. Так же в этом файле проводятся все необходимые проверки прав доступа и нам не придется делать это самостоятельно.
ТребованияЧтобы использовать файл async-upload.php нужно следовать следующим правилам.
- Атрибут name поля для загрузки файла должен быть async-upload
- Защитный ключ, который мы отправляем в AJAX запросе, должен использовать стандартное имя _wpnonce, а значение его — результат работы функции wp_create_nonce(‘media-form’)
- В AJAX запросе мы должны отправить ключ action со значением upload-attachment, таким образом будет вызвана нужная нам функция wp_ajax_upload_attachment
Если мы будем следовать этим правилам, WordPress сможет корректно обработать наш AJAX запрос.
ПлагинЛучший способ продемонстрировать возможность загрузки файлов в WordPress — создать плагин. Мы создадим простой плагин, который позволяет зарегистрированным пользователям загружать изображения.
Так как цель этой статьи — демонстрация загрузки файлов с помощью AJAX, функционал плагина будет довольно скромным, наш плагин будет:
- Позволять администратору вставлять форму загрузки в любую страницу, используя шорткод.
- Показывать зарегистрированным пользователям форму загрузки файла с помощью AJAX.
- Отправлять уведомление о загрузке администратору.
Что можно добавить в плагин:
- Хранить информацию о загрузках в базе данных.
- Показывать список файлов в интерфейсе админа.
- Позволять не зарегистрированным пользователям загружать.
Как обычно, для создания нового WordPress плагина — создайте папку в директории wp-content/plugins. Будем использовать имя my-upload-plugin и префикс mup_ для всех собственных функций.
Далее, создайте главный файл плагина с таким же именем, как у папки. Также создадим папку js, в которой будет храниться файл script.js.
Должна получиться следующая структура:
Напишем заголовок плагина в главном файле my-upload-plugin.php, осле этого можно перейти на страницу с плагинами и активировать его.
Подключение скриптаЧтобы использовать script.js, необходимо подключить скрипт:
Нам нужно будет «локализовать» этот скрипт, так как в нем используются данные, которые могут меняться в зависимости от конкретной сессии. Для этого мы будем использовать функцию wp_localize_script(). Нам нужно изменить три переменные: ссылки на файлы admin-ajax.php и async-upload.php, а также защитный ключ, который генерирует функция wp_create_nonce().
Теперь код для подключения скрипта выглядит так:
Регистрируем шорткод для вывода формыДля вывода формы загрузки файла мы будем использовать шорткод, таким образом мы сможем вставить форму где захотим и нам не придется каждый раз вставлять одну и ту же HTML разметку.
Нашей форме потребуется:
- Текстовое поле для ввода имени.
- Текстовое поля для ввода почты.
- Поле для файла с именем async-upload.
- Несколько div’ов для показа сообщений.
Также, если пользователь не авторизован, вместо формы для загрузки мы будем показывать форму для входа.
Этот код регистрирует новый шорткод image_form. Мы используем функции управления буфером вывода, и можем писать HTML код внутри PHP функции. С помощью атрибута accept мы разрешаем загружать только изображения. В функцию wp_login_url() мы передаем ссылку на текущую страницу (get_permalink()), таким образом пользователь будет перенаправлен обратно в случае успешного входа.
Разрешаем определенным ролям загружать файлыЧтобы наш плагин работал, нам надо разрешить пользователям с ролью subscriber загружать файлы, так как по-умолчанию роль subscriber не имеет прав на загрузку файлов.
Теперь, когда основа плагина готова, мы можем создать новую страницу и вывести на ней нашу форму.
Так форма будет выглядеть на сайте с темой twentysixteen:
Если мы не авторизованы, то мы увидим ссылку на страницу входа:
Загрузка файлов с помощью AJAXТеперь можно заняться реализацией основной задачи плагина.
В файле script.js объявим нужные переменные:
Эти переменные пригодятся нам в дальнейшем.
Мы будем отслеживать событие change у поля для выбора файла и если пользователь выберет файл, мы начнем AJAX загрузку.
Теперь отвлечемся немного от кода и попробуем загрузить файл. Используя инструменты разработчика (зависит от вашего браузера), проверим вывод в консоли. Успешный ответ от файла async-upload.php должен выглядеть примерно так:
Вы так же можете проверить существует ли файл в папке wp-content/uploads. Теперь, когда загрузка работает исправно, можно заняться улучшением нашего плагина:
- Покажем прогресс загрузки или уведомление во время загрузки файла.
- Покажем загруженное изображение в случае успеха или сообщение в случае ошибки.
- Добавим возможность загрузить новое изображение взамен старого.
Чтобы показать сообщение о том, что файл загружается нам достаточно определить событие beforeSend в AJAX запросе:
Мы используем пустой div с классом image-notice для показа сообщения и прячем файловый инпут.
Мы также можем показать процент загрузки файла. Для этого надо переопределить стандартный jQuery объект xhr. Добавьте этот код в объявление $.ajax:
В браузерах, которые поддерживают эту функцию будет показан прогресс загрузки файла, а в тех, которые не поддерживают — ничего не произойдет.
Вывод изображения после успешной загрузкиВ зависимости от ответа, который пришлет файл async-upload.php, мы показываем пользователю разные сообщения. Но если ключ success равен true, то мы можем показать загруженное изображение и спрятать поле выбора файла. Если произошла ошибка мы покажем сообщение об ошибке.
$imgId — скрытый инпут, в который записывается ID загруженного изображения, он пригодится нам дальше.
Заменяем старое изображение новымПредоставим пользователю возможность заменить ранее загруженное изображение новым.
Для этого в случае успеха покажем немного другое сообщение:
Теперь у нас есть ссылка с классом btn-change-image, на которую мы повесим обработчик события click. При нажатии на нее мы удалим текущее изображение, сообщение о загрузке и снова покажем поле для выбора файла.
Нам также необходимо перезаписать значение файлового инпута, чтобы событие change сработало снова.
Завершаем плагинДля полноценной работы формы на нужно отслеживать событие submit и отправлять AJAX запрос:
Этот код использует встроенный в WordPress обработчик AJAX запросов. В случае успешного запроса мы удалим показанную картинку и поменяем цвет уведомления на зеленый. В случае ошибки поменяем цвет на красный.
Теперь откроем главный файл плагина и добавим обработчик для нашего AJAX запроса:
В нашем примере мы просто вышлем, уведомление администратору о новой загрузке.
Для отправки сообщения об успешной или не очень загрузке используются функции wp_send_json_error() и wp_send_json_success().
Для проверки работы плагина попробуйте загрузить файл и проверьте пришло ли вам уведомление на почту.