Всем привет!
В заметке к недавнему обновлению плагина WP-Recall я уже упоминал о появлении нового класса Rcl_Uploader для загрузки файлов, а в этой статье мы более подробно рассмотрим его, научимся приспосабливать под свои задачи, а также рассмотрим некоторую кастомизацию процесса загрузки.
Класс Rcl_Uploader описан в файле '/wp-recall/classes/class-rcl-uploader.php' и представляет из себя конструктор файлового загрузчика, он устанавливает поведение дефолтного функционала загрузчика в зависимости от принимаемых параметров при инициализации.
Свойства класса Rcl_Uploader:
$uploader_id = ''; //идентификатор загрузчика $fix_editor = false; //идентификатор прикрепленного редактора $action = 'rcl_upload'; //наименование php-функции-обработчика $temp_media = false; //вкл/отключение временной библиотеки $input_attach = false; //атрибут name для скрытого поля загруженного файла $user_id = 0; //идентификатор пользователя $input_name = 'rcl-upload'; //атрибут name для поля типа file $dropzone = false; //активация области загрузки $max_files = 10; //максимальное кол-во загружаемых файлов $max_size = 512; //максимальный размер загружаемого файла, Кб $min_width = false; //минимальная ширина загружаемого изображения $min_height = false; //минимальная высота загружаемого изображения $resize = array(); //максимальные размеры до которых будет изменено изображение $file_types = array( 'jpg', 'png', 'jpeg' ); //разрешенные типы файлов $multiple = false; //активация множественной загрузки $crop = false; //активация функционала обрезки изображения $image_sizes = true; //размеры нарезаемых миниатюр $mode_output = 'grid'; //порядок вывода файлов в галерее, может быть grid/list $filename = ''; //наименование сохраняемого файла на сервере $filetitle = ''; //наименование сохраняемого файла в медиабиблиотеке $dir = ''; //путь до произвольной папки сохранения файла
$uploader_id
Идентификатор загрузчика. Указываем строкой при инициализации класса, позже можем по нему отлавливать загрузку нужного загрузчика.
$fix_editor
Если в вашей форме или на странице также присутствует tyniMCE-редактор, то можно указать его идентификатор в этом свойстве. Загрузчик и редактор будут работать вместе, загруженные файлы можно будет перекидывать в редактор по нажатию на специальную кнопку.
$action
Свойство определяет в какую php-функцию будут отправлены данные загружаемого файла. Если переопределяется, то в новой функции будет необходимо описать всю логику проверок и загрузки файла, дефолтный функционал загрузчика перестанет работать.
$temp_media
Если указано true, то все загруженные файлы помечаются как временные и через некоторое время удаляются. Удобно, если загрузчик предлагается для еще неопубликованной записи, гостям сайта и тп, когда сам факт загрузки файла не является конечным результатом. В момент совершения конечного действия, например, при публикации записи, данные о загруженных файлах необходимо удалить из временной таблицы с помощью функции
rcl_delete_temp_media($attachment_id)
$input_attach
Свойство принимает строку, которая будет использоваться для формирования атрибута name скрытого поля содержащего идентификатор загруженного файла. Удобно использовать, если файлы загружаются в форме, которая предполагает последующую обработку данных, в этом случае, идентификаторы загруженных файлов можно будет получить в массиве $_POST или $_GET, в зависимости от свойств формы.
$user_id
Идентификатор пользователя, который будет указан в качестве автора к загружаемым файлам. По-умолчанию, используется идентификатор текущего пользователя, но можно переопределить через это свойство.
$input_name
Строка указывающая атрибут name для поля file, через которое и производится непосредственная загрузка файлов, чтобы затем обратиться к массиву $_FILES по его наименованию. По-умолчанию, 'rcl-uploads'. Не представляю для каких целей может потребоваться указать свое значение.
$dropzone
true/false - управляет выводом области загрузки в которую можно будет накидывать файлы перетаскиванием.
$max_files
Максимальное количество загружаемых файлов.
$max_size
Максимальный размер загружаемых файлов в килобайтах.
$min_width
Минимальная ширина загружаемого изображения.
$min_height
Минимальная высота загружаемого изображения.
$resize
Свойство позволяет указать в массиве максимальные размеры для ширины и высоты изображения к которым будет приведено изображение, если его текущие размеры будут превосходить указанные.
$file_types
Массив разрешенных типов загружаемых файлов.
$multiple
Свойство регулирует возможности при выборе изображения из папки. Если 1 - то можно выбирать сразу несколько файлов за раз, если 0 - можно выбрать за один раз только один файл.
$crop
Свойство указывающее необходимость показа диалогового окна с инструментами для обрезки загружаемого изображения. Может принимать значение 1 и 0, соответственно, включая или отключая указанную функцию. Свойство работает только если multiple находится в значении 0, т.е. изображения загружаются по одному.
$image_sizes
Регулирует нарезание миниатюр при загрузке изображений. Значение может быть true/false/массив. Если указано true - используется нарезка на миниатюры согласно зарегистрированных размеров, если false - миниатюры не нарезаются, сохраняется только оригинал (надо проверить, но кастомные размеры точно выкидываются :/)
В массиве можно указать данные для нарезаемых миниатюр, например:
array( array( 'height' => 150, 'width' => 150, 'crop' => 1 ), array( 'height' => 300, 'width' => 400, 'crop' => 0 ) )
Массив содержит данные о ширине и высоте двух миниатюрах на которые будет нарезано изображение, crop - определяет поведение при изменении размеров изображения, 1 - режет под указанные размеры, 0 - масштабирует изображение подгоняя большую часть под указанные размеры.
$mode_output
Порядок вывод изображений в дефолтной галерее, если используется. Может быть grid - карточками или list - списком.
$filename
Определяет произвольное имя файла на сервере. Если загружается несколько файлов, то к наименованию каждого файла будет добавляться суффикс соответствующий порядку его загрузки.
$filetitle
Тут можно указать наименование медиафайла в медиабиблиотеке WordPress.
$dir
В свойстве можно указать относительный путь до произвольной папки на сервере куда будет сохраняться загружаемый файл. Путь следует указывать относительно папки wp-content, например '/uploads/files/user-1/'
Базовое использование
Итак, давайте создадим пользовательский аплоадер для загрузки изображений.
$uploder = new Rcl_Uploader( 'my_uploader', array( 'multiple' => 1, 'dropzone' => 1, 'max_files' => 5, 'file_types' => ['png', 'jpeg', 'jpg' ], 'resize' => array( 1000, 1000 ), 'min_height' => 300, 'min_width' => 300, 'max_size' => 1024 * 3 ) );
Через атрибуты мы указали возможность загрузки 5-ти изображений разрешенных типов с минимальными размерами - 300 пикселей и максимальным весом 3 мегабайта. При загрузке оригинал изображения большого размера будет уменьшаться до 1000 пикселей.
Теперь выведем само поле загрузки - dropzone и кнопку загрузки:
echo $uploder->get_uploader();
В результате нам будет предложено использовать для загрузки файлов поле и кнопку загрузки, которые будут вполне рабочими и мы сможем начать загружать файлы, вот только они нигде не будут выводиться, так как галерею файлов мы должны будем вывести отдельно кодом:
echo $uploder->get_gallery();
но и этого еще не будет достаточно для вывода загруженных файлов.
Встроенная галерея файлов не будет ничего выводить пока не получит перечень файлов необходимых к выводу, поэтому нам надо будет получить перечень идентификаторов файлов и передать их массивом в галерею, например:
echo $uploder->get_gallery([101, 102, 103]);
Конечно, передаваемый массив нам необходимо будет получить из базы данных по требуемым параметрам.
В результате, мы увидим в галерее три изображения, а каждое последующее загруженное изображение будет дополнять галерею.
Обработка файлов после загрузки
Загруженные файлы попадают в медиабиблиотеку WordPress, но почти всегда этого недостаточно. Часто возникает потребность сохранить загруженные файлы в качестве метаданных пользователя, публикации или другого объекта, для этого нам потребуется использовать хук, который срабатывает сразу после загрузки файлов - rcl_upload:
add_action( 'rcl_upload', 'my_uploader_upload', 10, 2 ); function my_uploader_upload( $uploads, $uploader ) { //делаем проверку на идентификатор своего загрузчика if ( $uploader->uploader_id != 'my_uploader' ) return; //тут мы можем производить какие-либо //действия с загруженными файлами }
Внутри хука мы можем каким-либо образом обработать загруженные изображения получив доступ к массиву с их данными $uploads. В данный момент, данный массив имеет примерно такую структуру:
array( array( 'id' => 10, //идентификатор файла 'src' => [ 'full' => '', //url до оригинала файла 'thumbnail' => '', //url до миниатюры файла ], 'html' => '' //html-представление миниатюры в галерее ), array( 'id' => 11, 'src' => [ 'full' => '', 'thumbnail' => '', ], 'html' => '' ), );
т.е. как можно увидеть $uploads - это массив массивов с данными загруженных файлов. При этом следует знать, что если свойство multiple отключено, то $uploads будет массивом с данными только одного файла:
array( 'id' => 10, //идентификатор файла 'src' => [ 'full' => '', //url до оригинала файла 'thumbnail' => '', //url до миниатюры файла ], 'html' => '' //html-представление миниатюры в галерее )
Итак, если нам, например, необходимо сохранить идентификаторы загруженных файлов файлов в качестве метаданных пользователя, то мы можем сделать это следующим образом:
add_action( 'rcl_upload', 'my_uploader_upload', 10, 2 ); function my_uploader_upload( $uploads, $uploader ) { global $user_ID; if ( $uploader->uploader_id != 'my_uploader' ) return; $ids = []; foreach($uploads as $upload){ $ids[] = $upload['id']; } update_user_meta($user_ID, 'my_uploader', $ids); }
тогда галерею мы можем формировать из изображений сохраненных в этом поле
echo $uploder->get_gallery(get_user_meta($user_ID, 'my_uploader', 1));
Произвольная галерея
Иногда бывает, что дефолтная галерея аплоадера не совсем подходит под проект и от нее приходится отказаться, тогда следует рассмотреть вариант с организацией вывода изображений в своей кастомной галерее. Для этого необходимо сверстать html-структуру галереи, вывести там уже ранее загруженные изображение и позаботиться о добавлении в эту галерею загружаемых изображений.
Для реализации этой задачи нам необходимо обратить внимание на js-функционал загрузчика, а именно, определить нужное нам поведение в методе appendInGallery() на стороне js, которое срабатывает сразу после загрузки файлов и призвано добавлять файл в галерею. Сначала создадим заготовку под наш загрузчик:
jQuery( function( $ ) { //сначала проверяем имеется ли на странице наш загрузчик if ( RclUploaders.isset( 'my_uploader' ) ) { //затем переопределяем нужным метод RclUploaders.get( 'my_uploader' ).appendInGallery = function( file ) { //тут будем производить какие то действия с изображением }; } });
Принимаемый параметр file будет содержать объект с данными об одном из загруженных изображений с той же структурой, что передается в php-хук rcl_uploads:
{ id: int, //идентификатор файла src: { full: '', //url до оригинала файла thumbnail: '' //url до миниатюры файла }, html: '' //html-представление миниатюры в галерее };
И теперь, используя полученные данные, мы можем производить какие-либо действия, например, добавить переданное изображение в кастомную галерею. Допустим наша галерея имеет структуру:
<div id="my-gallery"> <div class="attachment"><img src="/wp-content/uploads/image-1.jpg"></div> <div class="attachment"><img src="/wp-content/uploads/image-2.jpg"></div> <div class="attachment"><img src="/wp-content/uploads/image-3.jpg"></div> </div>
Тогда мы можем добавить оригинал изображения следующим образом:
jQuery( function( $ ) { if ( RclUploaders.isset( 'my_uploader' ) ) { RclUploaders.get( 'my_uploader' ).appendInGallery = function( file ) { jQuery('#my-gallery').append('<div class="attachment"><img src="' + file.src.full + '"></div>'); }; } });
Чтобы не держать html-код в js-методе мы можем изменить соответствующим образом изменить наш php-обработчик, который повесили на хук rcl_upload, дополнив данные изображения структурой миниатюры в нашей галерее и вернув в ответе:
add_action( 'rcl_upload', 'my_uploader_upload', 10, 2 ); function my_uploader_upload( $uploads, $uploader ) { global $user_ID; if ( $uploader->uploader_id != 'my_uploader' ) return; $ids = [ ]; foreach ( $uploads as $k => $upload ) { $ids[] = $upload['id']; //формируем и добавляем миниатюру для нашей галереи $uploads[$k]['gallery_image'] = '<div class="attachment"><img src="' . $upload['src']['full'] . '"></div>'; } update_user_meta( $user_ID, 'my_uploader', $ids ); //возвращаем измененный массив уже из нашей функции wp_send_json($uploads); }
Теперь нужное нам html-представление миниатюры для нашей галереи будет возвращено в js, соответственно изменяем js-метод:
jQuery( function( $ ) { if ( RclUploaders.isset( 'my_uploader' ) ) { RclUploaders.get( 'my_uploader' ).appendInGallery = function( file ) { jQuery('#my-gallery').append(file.gallery_image); }; } });
Кастомизация через дочерний класс
Использование класса Rcl_Uploader напрямую для формирование загрузчика может быть уместным и удобным если нам не требуется кастомизировать поведение внутри класса и его дефолтного поведения будет достаточно. Но случай описанный выше, я считаю, более предпочтительно обернуть в свой класс, через который в дальнейшем можно более тонко оказывать влияние на поведение родительского Rcl_Uploader и использовать или переопределять его методы. Учитывая функционал и код требующийся нам выше, наш класс может выглядеть так:
class MY_Uploader extends Rcl_Uploader{ function __construct($args = array()){ parent::__construct('my_uploader', wp_parse_args($args, array( 'multiple' => 1, 'dropzone' => 1, 'max_files' => 5, 'file_types' => ['png', 'jpeg', 'jpg' ], 'resize' => array( 1000, 1000 ), 'min_height' => 300, 'min_width' => 300, 'max_size' => 1024 * 3 ))); } //тут мы использовали метод родительского класса //который срабатывает сразу после загрузки файлов function after_upload($uploads){ global $user_ID; $ids = []; foreach ( $uploads as $k => $upload ) { $ids[] = $upload['id']; $uploads[$k]['gallery_image'] = '<div class="attachment"><img src="' . $upload['src']['full'] . '"></div>'; } update_user_meta( $user_ID, 'my_uploader', $ids ); wp_send_json($uploads); } //здесь мы переопределили метод родителя для //формирования своей кастомной галереи function get_gallery($unuses = false){ global $user_ID; $ids = get_user_meta( $user_ID, 'my_uploader', 1 ); $thumbs = ''; if($ids){ foreach($ids as $id){ //тут мы использовали полезный метод get_src родителя для //получения url до изображения нужного размера $thumbs .= '<div class="attachment"><img src="'.$this->get_src($id, 'full').'"></div>'; } } $content = '<div id="my-gallery">'; $content .= $thumbs; $content .= '</div>'; return $content; } }
Нам останется только вызывать аплоадер и галерею из нашего нового класса:
$Uploader = new MY_Uploader(); echo $Uploader->get_uploader(); echo $Uploader->get_gallery();
Мы рассмотрели базовое использование такого важного и полезного загрузчика от плагина WP-Recall, с его помощью мы теперь можем легко создавать загрузчик файлов практически любой сложности под любую задачу.
Конечно, данный мануал не является полным и будет лучше ознакомиться с предлагаемыми возможностями класса в файле, где он определен.
Задавайте вопросы или предложения по развитию в комментариях ниже, буду рад ответить.
Всем хорошего дня.
Подскажите пожалуйста.
Какой максимальный размер файла можно загрузить загрузчиком Rcl_Uploader ?
Файл обьемом 500 Мб Rcl_Uploader сможет загрузить при одновременной загрузке нескольких таких файлов от разных пользователей?
Работает ли в Rcl_Uploader асинхронная загрузка файлов?
С уважением,
Виктор.
Максимальный размер файла - 5120 кб.
Тоже интересует вопрос загрузки больших файлов.
Подскажите, пожалуйста, нашли ли Вы решение?