Публикация в группе: Плагин WP-Recall - Личный кабинет на WordPress

Категории группы: Полезное

Всем привет!

В заметке к недавнему обновлению плагина 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, с его помощью мы теперь можем легко создавать загрузчик файлов практически любой сложности под любую задачу.

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

Задавайте вопросы или предложения по развитию в комментариях ниже, буду рад ответить.

Всем хорошего дня.

 

3

Автор публикации

не в сети 3 часа

Андрей CS

12K
занят
Комментарии: 2763Публикации: 492Регистрация: 30-11--0001Продаж/Покупок: 0/0