floor12/yii2-module-files Удобная работа с файлами ваших ActiveRecord-моделей Yii2.
Информация о модуле
Это модуль разработан для того, чтобы решить проблему создание полей с файлами в ActiveRecord моделях фреймворка Yii2. Основными компонентами модуля являются:
floor12\files\components\FileBehaviour
- поведение, которое необходимо подключить к ActiveRecord модели;floor12\files\components\FileInputWidget
- виджет для формы, позволяющий добавлять, редактировать и в целом работать с добавленными файлами;floor12\files\components\FileListWidget
- дополнительный виджет для вывода списка файлов с возможностями просмотра изображений в галереи Lightbox2, загрузке всех файлов текущего поля в формате zip, а так же просмотром Word и Excel файлов с помощью онлайн офиса от Microsoft.
Основные функции модуля
- добавление одного и более полей с файлами к ActiveRecord модели;
- настройка валидация этих полей при помощи стандартного
FileValidator
, указанного в секцииrules()
; - в случае работы с изображениями - возможность сконфигурировать пропорции изображения (в этом случае при загрузке изображения через
FileInputWidget
виджет автоматически откроет окно для обрезки изображения с нужными пропорциями); - возможность создания миниатюр для использования в различных местах шаблонов изображений оптимальных размеров. Так же эти миниатюры могут поддерживают формат WEBP;
- возможность скачивания всех добавленных в одно поле файлов в виде ZIP-архива
- при загрузке изображений через
FileInputWidget
имеется возможность изменять порядок объектов драг-н-дропом, изменять размер и имя; - при загрузке файлов драг-н-дропом порядок файлов сохраняется тем же, что и был в момент выделения файлов на компьютере (это очень удобно, если необходимо добавить к модели, к примеру, 50 изображений в строгом порядке);
- при загрузке изображений автоматическое определение горизонта по EXIF-метке;
- при необходимости добавления изображений к модели не через веб-интерфейс сайта, а при помощь консольных парсеров и других похожих случаев - такая возможность имеется. Для этого в системе предусмотрено два класса:
FileCreateFromInstance.php
иFileCreateFromPath.php
. - при работе с видео файлами - перекодировка их в h264 при помощи утилиты ffmpeg;
Интернационализация
На данный этап модуль поддерживает следующие языки:
- Английский
- Русский
Принцип работы
Информация о файлах хранится в таблице file
и содержит связи с моделью через три поля:
class
- полное имя класса связанной моделиfield
- имя поля моделиobject_id
- primary key модели
При работе с виджетом добавления файлов, во время добавления файла в форму происходит его фоновая загрузка и обработка. В результате этой обработки он записывается на диск и для него создается запись в таблице file
, где поля class
и field
заполнены данными из модели, а object_id
присваивается только после сохранения модели ActiveRecord, к которой подключено поведение.
При удалении файла из формы он не удаляется с диска и из таблицы file
, а просто его object_id будет обращен в 0. Для периодической очистки такого рода бесхозных файлов можно периодически использоваться консольную команду files/console/clean
.
Установка и настройка
Устанавливаем модуль через composer: Выполняем команду
$ composer require floor12/yii2-module-files
или добавляем в секцию "requred" файла composer.json
"floor12/yii2-module-files": "dev-master"
Далее выполняем миграцию для создания таблицы file
$ ./yii migrate --migrationPath=@vendor/floor12/yii2-module-files/src/migrations/
Так как для работы модуля требуются контроллеры, прописываем модуль в конфигурации Yii2 приложения:
'modules' => [
'files' => [
'class' => 'floor12\files\Module',
'storage' => '@app/storage',
'cache' => '@app/storage_cache',
'token_salt' => 'some_token_salt',
],
],
...
Параметры:
storage
- алиас пути к хранилищу файлов и исходников изображений на диске, по умолчанию располагается в папке storage в корне проекта;cache
- алиас пути к хранилищу миниатюр изображений, которые модуль создает "на лету" по запросу и кеширует;token_salt
- уникальная соль для безопасной работы виджета загрузки файлов.
Использование
Настройка модели ActiveRecord
Для добавление к модели ActiveRecord одного или нескольких полей с файлами, необходимо подключить к ней floor12\files\components\FileBehaviour'
и перечислить названия полей, которые будут хранить файлы. Например, для модели User здесь будут определены 2 поля для хранения файлов: avatar
и documents
:
public function behaviors()
{
return [
'files' => [
'class' => 'floor12\files\components\FileBehaviour',
'attributes' => [
'avatar',
'documents'
],
],
...
Чтобы отобразить красивые названия для полей, прописываем для них лейблы, как будто это обычные поля модели:
public function attributeLabels()
{
return [
...
'avatar' => 'Аватар',
'documents' => 'Документы',
...
];
}
В методе rules()
описываем правила валидации для наших файловых полей:
public function rules()
{
return [
//Аватар является обязательным полем
['avatar', 'required'],
//В поле Аватар можно поместить 1 файл с разрешением 'jpg', 'png', 'jpeg', 'gif'
['avatar', 'file', 'extensions' => ['jpg', 'png', 'jpeg', 'gif'], 'maxFiles' => 1],
//А в поле documents можно помещать несколько документов в формате MS Word или Excel
['documents', 'file', 'extensions' => ['docx', 'xlsx'], 'maxFiles' => 10],
...
Обращение к файлам
Если maxFiles
в FIleValidator
будет равен единице, то поле модели будет хранить экземпляр класса floor12\files\models\File
. Например:
// Поле href хранит в себе ссылку на исходник файла или картинки
echo Html::img($model->avatar->href)
//Такая запись равнозначна, так как объект File при приведении к строке возвращает href
echo Html::img($model->avatar)
Если файл является изображением, то можно запросить его миниатюру, передав в специальный метод ширину, высоту и флаг конвертации в WEBP:
File::getPreviewWebPath(int $width = 0, int $height = 0 ,bool $webp = false)
Пример использования:
//Запрашиваем миниатюру аватара пользователя шириной 200 пикселей
echo Html::img($model->avatar->getPreviewWebPath(200))
//Запрашиваем миниатюру аватара пользователя шириной 200 пикселей и в формате WEBP
echo Html::img($model->avatar->getPreviewWebPath(200, 0, true))
//Запрашиваем миниатюру аватара пользователя шириной высотой 300 и в формате WEBP
echo Html::img($model->avatar->getPreviewWebPath(0, 300, true))
В случае, если maxFiles
> 1 и файлов можно загрузить несколько, то поле с файлами будет содержать не экземпляр объекта floor12\files\models\File
, а массив объектов:
foreach ($model->docs as $doc}
Html::a($doc->title, $doc->href);
Вот еще один пример продвинутого использования миниатюр. В данном варианте мы используем современные теги picture
и source
, а так же медиа-запросы. В результате, у нас имеется 8 миниатюр, 4 в формате webp для тех браузерв, которые поддерживают этот формат, а 4 в формате jpeg. Кроме того, устройствам с ретиной будут показывать изображения с двойным разрешением. а обычным экранам - картинки обычного размера. Так же в примере используется разделение на разные изображения при разной ширине экрана:
<picture>
<source type="image/webp" media='(min-width: 500px)' srcset="
<?= $model->poster->getPreviewWebPath(150, 0, 1) ?> 1x,
<?= $model->poster->getPreviewWebPath(300, 0, 1) ?> 2x">
<source type="image/webp" media='(max-width: 500px)' srcset="
<?= $model->poster->getPreviewWebPath(350, 0, 1) ?> 1x,
<?= $model->poster->getPreviewWebPath(700, 0, 1) ?> 2x">
<source type="image/jpeg" media='(min-width: 500px)' srcset="
<?= $model->poster->getPreviewWebPath(150, 0, 0) ?> 1x,
<?= $model->poster->getPreviewWebPath(300, 0, 0) ?> 2x">
<img src="<?= $model->poster->getPreviewWebPath(150) ?>"
srcset="
<?= $model->poster->getPreviewWebPath(350) ?> 1x,
<?= $model->poster->getPreviewWebPath(700) ?> 2x"
alt="<?= $model->title ?>">
</picture>
Виджет для списка файлов
В поставке модуля, есть виджет для вывода всех файлов, который дает возможность просматривать список файлов конкретного поля, подключая для его отображения галерею Lightbox2 если в списке есть картинки, осуществлять предпросмотр файлов MS Office, а так же имеется возможно скачать все приложенные к модели файлы ZIP-архивом.
echo \floor12\files\components\FileListWidget::widget([
'files' => $model->docs,
'downloadAll' => true,
'zipTitle' => "Документы пользователя {$model->fullname}"
])
В виджет необходимо передать массив объектов File
, а так же можно задать дополнительные параметры:
title
- опционально задать заголовок блока (по-умолчанию берется из AttributeLabels)",downloadAll
- показать кнопку "скачать все файлы",zipTitle
- задать название файла для zip-архива,passFirst
- пропустить при выводе первый файл (часто бывает необходимо вывести галерею без первой картинки, например, в новости, так как первая картинка "ушла" на обложку самой новости - как пример).
Виджет для ActiveForm
Во время редактирования модели, необходимо использовать виджет floor12\files\components\FileInputWidget
:
<?= $form->field($model, 'avatar')->widget(FileInputWidget::class) ?>
При этом, в зависимости того. установлен ли параметр maxFiles
в FileValidator
равный единицы или более, FileInputWidget
примет необходимый вид, для загрузки одного файла или сразу нескольких. При необходимости можно передать в виджет текст и для кнопки и класс для кнопки загрузки через параметры uploadButtonText
и uploadButtonClass
.
Участие в разработке
Буду рад любой помощи в разработке, поддержке и баг-репортах на этот модуль.