WordPress. Загрузка медиа-файлов
Давайте создадим плагин, который позволит зарегистрированным пользователям загружать медиа файлы. Чтобы не создавать свой загрузчик файлов, будем использовать файл async-upload.php
, расположенный в папке wp-admin
. Это стандартный скрипт WordPress для AJAX-загрузки медиа файлов, в нем есть все необходимые проверки прав доступа, так что нам не придется делать это самостоятельно.
Для использования файла async-upload.php
, нам нужно выполнить следующие условия:
- Установить значение атрибута
name
поля для загрузки файла в значениеasync-upload
- В post-запросе отправить ключ
_wpnonce
со значением, которе возвращает функцияwp_create_nonce()
с аргументомmedia-form
- В post-запросе отправить ключ
action
со значениемupload-attachment
, чтобы была вызвана функцияwp_ajax_upload_attachment()
Возможности плагина будут довольно скромные — добавление шорткода, чтобы загружать медиа файлы с любой страницы сайта. И отправка на почту администратора сообщения о загрузке нового файла.
Плагин загрузки медиа-файлов
Итак, создаем директорию tokmakov-upload-media
, а внутри нее — три файла: tokmakov-upload-media.php
, script.js
и style.js
.
Файл tokmakov-upload-media.php
<?php /* Plugin Name: Загрузка файлов Plugin URI: https://tokmakov.msk.ru Description: Позволяет загружать файлы зарегистрированным пользователям. Version: 1.0 Author: Евгений Токмаков Author URI: https://tokmakov.msk.ru */ register_activation_hook(__FILE__, function() { // проверяем права пользователя на активацию плагинов if (!current_user_can('activate_plugins')) { return; } // для загрузки файлов из публичной части у всех // пользователей должны быть права на это $subscriber = get_role('subscriber'); if (!$subscriber->has_cap('upload_files')) { $subscriber->add_cap('upload_files'); } }); register_deactivation_hook(__FILE__, function() { // проверяем права пользователя на деактивацию плагинов if (!current_user_can('deactivate_plugins')) { return; } // удаляем права на загрузку файлов, которую // предоставили на этапе активации плагина $subscriber = get_role('subscriber'); if ($subscriber->has_cap('upload_files')) { $subscriber->remove_cap('upload_files'); } });
Предоставляя всем зарегистрированным пользователям возможность загрузки файлов, мы тем самым предоставляем доступ к медиабиблиотеке — пользователи смогут загружать файлы в админ-панели сайта. А мы добавим возможность загрузки файлов в публичной части сайта — там, где будет размещен шорткод.
Смысла в этом плагине немного, это скорее исследование возможностей WordPress. Но можно доработать плагин, чтобы он стал реально полезен. Например, прикреплять загруженные файлы к той записи, где размещен шорткод, объединять их в галерею и показывать на странице и т.п. Потому как неприкрепленные вложения будут только захламлять медиабиблиотеку.
/* * Подключаем js-файл, который будет загружать файлы с использованием AJAX */ add_action('wp_enqueue_scripts', function () { wp_enqueue_script( 'tokmakov-upload-media-js', // будет зарегистрирован под этим именем plugin_dir_url( __FILE__ ) . 'script.js', ['jquery'], // должен быть подключен после jquery null, // версии нет, поэтому null true // подключаем перед закрывающим тегом body ); // передаем на сторону клиента объект tokmakov_upload_media, // который содержит все необходимое для работы js-кода $config = array( 'upload_url' => admin_url('async-upload.php'), 'ajax_url' => admin_url('admin-ajax.php'), 'nonce_upload' => wp_create_nonce('media-form'), 'nonce_remove' => wp_create_nonce('remove-media'), 'nonce_message' => wp_create_nonce('admin-message'), ); wp_localize_script( 'tokmakov-upload-media-js', 'tokmakov_upload_media', $config ); // подключаем файл стилей, чтобы красиво оформить наш блок загрузки wp_enqueue_style( 'tokmakov-upload-media-css', // будет зарегистрирован под этим именем plugin_dir_url(__FILE__) . 'style.css' ); });
/* * Регистрируем шорткод [tokmakov-upload-media], который позволит вставить форму * загрузки файлов в любое место */ add_shortcode('tokmakov-upload-media', function () { $html = ''; if (is_user_logged_in()) { $html = <<<HTML <div class="tokmakov-upload-media"> <span class="loader"></span> <span class="result"></span> <span class="preview"></span> <span class="upload"> <input type="file" accept="image/*,audio/*,video/*"> <button>Загрузить</button> </span> </div> HTML; } return $html; });
/* * Удаляем ранее загруженный файл, если пользователь передумал */ add_action('wp_ajax_tokmakov_remove_media', function () { check_ajax_referer('remove-media'); $file_id = filter_var($_POST['file_id'], FILTER_VALIDATE_INT); if (!$file_id) { wp_send_json_error( ['message' => 'Некорректный идентификатор файла'] ); } if (false === wp_delete_attachment($file_id, true)) { wp_send_json_error( ['message' => 'Ошибка при удалении'] ); } else { wp_send_json_success( ['message' => 'Файл успешно удален'] ); } });
/* * Отправляем почтовое сообщение администратору о загрузке файла */ add_action('wp_ajax_tokmakov_upload_media', function () { check_ajax_referer('admin-message'); $file_id = filter_var($_POST['file_id'], FILTER_VALIDATE_INT); $author_id = filter_var($_POST['author_id'], FILTER_VALIDATE_INT); if ( ! ($file_id && $author_id)) { wp_send_json_error( ['message' => 'Некорректные данные файла или пользователя'] ); } $email= get_option('admin_email'); $subject = 'Загружен новый файл'; $user = get_user_by('id', $author_id); $user_name = $user->data->user_nicename; $user_mail = $user->data->user_email; $message = sprintf( 'Загружен новый файл пользователем %s (%s). Ссылка на файл: %s', $user_name, $user_mail, wp_get_attachment_url($file_id) ); $result = wp_mail($email, $subject, $message); if ($result) { wp_send_json_success( ['message' => 'Сообщение администратору успешно отправлено'] ); } else { wp_send_json_error( ['message' => 'Ошибка при отправке сообщения администратору'] ); } });
В результате работы шорткода на страницу будет добавлен html-код:
<div class="tokmakov-upload-media"> <span class="loader"></span> <span class="result"></span> <span class="preview"></span> <span class="upload"> <input type="file" accept="image/*,audio/*,video/*"> <button>Загрузить</button> </span> </div>
Если медиа-файл был успешно загружен, с сервера будет получен ответ в формате JSON, который будет содержать всю информацию о загруженном файле. Так что на клиенте мы можем предоставить возможность этот файл посмотреть или удалить.
{ "success":true, "data": { "id":2342, "title":"sunrise", "filename":"sunrise.jpg", "url":"http://www.serever.com/wp-content/uploads/2019/07/sunrise.jpg", "link":"http://www.serever.com/sunrise/", "alt":"", "author":"1", "description":"", "caption":"", "name":"sunrise", "status":"inherit", "uploadedTo":0, "date":1564148014000, "modified":1564148014000, "menuOrder":0, "mime":"image/jpeg", "type":"image", "subtype":"jpeg", "icon":"http://www.serever.com/wp-includes/images/media/default.png", "dateFormatted":"26.07.2019", "nonces": { "update":"3a9155cf5a", "delete":"3c232c8759", "edit":"9153475dbb" }, "editLink":"http://www.serever.com/wp-admin/post.php?post=2342&action=edit", "meta":false, "authorName":"admin", "filesizeInBytes":207875, "filesizeHumanReadable":"203 KB", "context":"", "height":1080, "width":1920, "orientation":"landscape", "sizes": { "thumbnail": { "height":150, "width":150, "url":"http://www.serever.com/wp-content\/uploads/2019/07/sunrise-150x150.jpg", "orientation":"landscape" }, "medium": { "height":113, "width":200, "url":"http://www.serever.com/wp-content/uploads/2019/07/sunrise-200x113.jpg", "orientation":"landscape" }, "large": { "height":563, "width":1000, "url":"http://www.serever.com/wp-content/uploads/2019/07/sunrise-1000x563.jpg", "orientation":"landscape" }, "full": { "url":"http://www.serever.com/wp-content/uploads/2019/07/sunrise.jpg", "height":1080, "width":1920, "orientation":"landscape" } }, "compat": { "item":"", "meta":"" } } }
Файл script.js
jQuery(document).ready(function($) { // при клике на кнопке отправляем ajax-запрос $('.tokmakov-upload-media button').on('click', function() { var $button = $(this); var $block = $button.parent().parent(); var $upload = $block.children('span.upload'); var $input = $upload.children('input[type="file"]'); var $preview = $block.children('span.preview'); var $result = $block.children('span.result'); // очищаем сообщение о предыдущих загрузках $result.empty(); // если файл был выбран — загружаем его на сервер if ($input.prop('files').length) { // данные, которые будем отправлять на сервер var data = new FormData(); data.append('action', 'upload-attachment'); data.append('async-upload', $input.prop('files')[0]); data.append('_wpnonce', tokmakov_upload_media.nonce_upload); // отправляем ajax-запрос $.ajax({ url: tokmakov_upload_media.upload_url, type: 'POST', data: data, processData: false, contentType: false, dataType: 'json', beforeSend: function() { // перед отправкой запроса скрываем поле выбора // файла и кнопку отправки $upload.hide(); // показываем сообщение, что идет загрузка; это // нужно для больших файлов $result.html('Загрузка файла …'); }, success: function(response) { if (response.success) { $result.html('Файл успешно загружен'); // показываем ссылку для просмотра файла var attr = {href: response.data.url, target: '_blank'}; $('<a>', attr).text('Открыть файл').appendTo($preview); $preview.append(' '); // пробел между ссылками // показываем ссылку для удаления файла... var $remove = $('<a>', {href: '#'}).text('Удалить файл').appendTo($preview); // ...и назначаем для нее обработчик события $remove.on('click', function (e) { e.preventDefault(); var data = new FormData(); data.append('action', 'tokmakov_remove_media'); data.append('file_id', response.data.id); data.append('_wpnonce', tokmakov_upload_media.nonce_remove); $.ajax({ url: tokmakov_upload_media.ajax_url, type: 'POST', data: data, processData: false, contentType: false, dataType: 'json', success: function(response) { $result.html(response.data.message); if (response.success) { $preview.empty(); // предлагаем загрузить другой файл $input.val(''); $upload.show(); } } }); }); // отправляем сообщение администратору о загрузке файла var data = new FormData(); data.append('action', 'tokmakov_upload_media'); data.append('file_id', response.data.id); data.append('author_id', response.data.author); data.append('_wpnonce', tokmakov_upload_media.nonce_message); $.ajax({ url: tokmakov_upload_media.ajax_url, type: 'POST', data: data, processData: false, contentType: false, dataType: 'json', }); } else { $result.html('Ошибка при загрузке файла'); // предлагаем загрузить еще раз $input.val(''); $upload.show(); } }, error: function () { $result.html('Обратитесь к администратору'); } }); } else { $result.text('Выберите файл для загрузки'); } }); });
Файл style.css
.tokmakov-upload-media {
padding: 10px;
margin: 10px 0;
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
}
.tokmakov-upload-media input, .tokmakov-upload-media button {
display: inline-block;
padding: 5px;
background-color: #e3e3e3;
border: none;
}
- WordPress. Загрузка файлов. Часть 3 из 3
- WordPress. Фильтр записей по произвольным полям. Часть 3 из 3
- WordPress. Фильтр записей по произвольным полям. Часть 2 из 3
- WordPress. Обработка POST-запросов. Часть 2
- WordPress. Обработка POST-запросов. Часть 1
- WordPress. Загрузка файлов. Часть 2 из 3
- WordPress. Загрузка файлов. Часть 1 из 3
Поиск: AJAX • FormData • Web-разработка • WordPress • Плагин • Файл • Форма • Загрузка • Upload