besnovatyj / yii2-cms-documents
Модуль управления документами для Yii2 CMS
Package info
github.com/besnovatyj/yii2-cms-documents
Type:yii2-extension
pkg:composer/besnovatyj/yii2-cms-documents
Requires
- php: >=8.4
- ext-mbstring: *
- ext-zip: *
- besnovatyj/yii2-cms-backend-widgets: ^1.0
- besnovatyj/yii2-cms-contracts: ^1.0
- besnovatyj/yii2-cms-forms: ^1.0
- besnovatyj/yii2-cms-helpers: ^1.0
- besnovatyj/yii2-cms-kernel: ^1.0
- besnovatyj/yii2-cms-meta: ^1.0
- besnovatyj/yii2-cms-tree-manager: ^1.0
- besnovatyj/yii2-cms-upload: ^1.0
- besnovatyj/yii2-cms-validators: ^1.0
- yiisoft/yii2: ~2.0.0
- yiisoft/yii2-bootstrap5: ~2.0.0
Requires (Dev)
- roave/security-advisories: dev-latest
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
Модуль публикации документов для ознакомления: карточка документа с описанием, скачиванием и предпросмотром, списки по категориям с фильтром и сортировкой.
Что показывается на странице документа
Виджет Besnovatyj\Documents\widgets\preview\DocumentPreviewWidget выбирает вид предпросмотра по расширению
загруженного файла:
| Файл | Что видит посетитель |
|---|---|
| jpg, jpeg, png, gif | картинка на странице, по клику — полный размер с домена статики |
| встроенный просмотрщик, постранично | |
| zip | список файлов внутри архива, каждый можно скачать отдельно |
| прочее, внешняя ссылка | только кнопка скачивания |
Виджет самодостаточен и подключается одной строкой:
<?= DocumentPreviewWidget::widget(['document' => $document]) ?>
Просмотр PDF
Используется pdf.js 6.3.289 — файлы библиотеки лежат в пакете
(src/widgets/preview/media/pdfjs), сборки и npm не требуется. Просмотрщик показывает по одной странице,
подгоняя её под ширину контейнера, и работает во всех браузерах одинаково, включая мобильные — в отличие
от штатного просмотра PDF во фрейме, которого в Chrome на Android нет.
Сам файл отдаётся действием Documents/document/preview с основного домена, а не с домена статики:
просмотрщику пришлось бы читать чужой домен, а домен статики запрещает встраивание и не разрешает
межсайтовые запросы. Настройки веб-сервера при этом менять не нужно.
Отдаются inline только типы из Document::PREVIEW_MIME_TYPES — картинки и PDF. Показать под видом
документа что-то исполняемое браузером (HTML, SVG) нельзя.
Обновление pdf.js
V=<новая версия> B=https://cdn.jsdelivr.net/npm/pdfjs-dist@$V curl -sS -o src/widgets/preview/media/pdfjs/pdf.min.js $B/build/pdf.min.mjs curl -sS -o src/widgets/preview/media/pdfjs/pdf.worker.min.js $B/build/pdf.worker.min.mjs
Библиотека распространяется в формате ES-модулей с расширением .mjs; в пакете файлы лежат под именами
.js, чтобы веб-сервер отдавал их как обычные скрипты — для модуля важен атрибут type, а не расширение.
Шрифты из standard_fonts/ обновляются оттуда же и нужны для PDF, в которых базовые шрифты не встроены.
Просмотр архивов
Список файлов снимается один раз при загрузке документа и хранится в колонке manifest_json, поэтому
показ страницы архив не открывает. В список попадают имя, размер, дата и признак защиты паролем;
зашифрованные файлы показываются с замком и не выдаются.
- Поддерживается только ZIP: расширений PHP для RAR и 7z на сервере нет, такой документ остаётся обычным файлом на скачивание.
- В манифест попадает не более
ZipReader::DEFAULT_LIMITзаписей, остальные доступны после скачивания архива. - Кодировка имён не угадывается. Архив, упакованный без пометки UTF-8, покажет нечитаемые имена в карточке документа в админке — такой архив нужно переупаковать в ZIP заново.
- Отдельный файл извлекается по номеру записи из манифеста, потоком, без распаковки архива на диск.
Даты
uploaded_at— дата загрузки на сайт. Проставляется автоматически при создании, редактируется вручную. Хранится в UTC, показывается и вводится в часовом поясе приложения.document_date— дата самого документа (приказа, письма). Заполняется вручную, хранится как дата без времени и часового пояса.created_at/updated_at— служебные отметки записи, как и прежде.
Оба поля участвуют в фильтре и сортировке на фронтенде (DocumentFilterForm).
Установка на существующую базу
Модуль ставится миграциями, но таблица documents_documents могла быть создана прежней версией.
Тогда новые колонки добавляются вручную, а дата загрузки заполняется по дате создания записи:
ALTER TABLE `documents_documents` ADD COLUMN `manifest_json` TEXT NULL COMMENT 'JSON-манифест содержимого архива' AFTER `file_size`, ADD COLUMN `uploaded_at` DATETIME NULL COMMENT 'Дата загрузки документа в UTC' AFTER `category_id`, ADD COLUMN `document_date` DATE NULL COMMENT 'Дата создания самого документа' AFTER `uploaded_at`, ADD INDEX `idx-documents_documents-title` (`title`), ADD INDEX `idx-documents_documents-uploaded_at` (`uploaded_at`), ADD INDEX `idx-documents_documents-document_date` (`document_date`); UPDATE `documents_documents` SET `uploaded_at` = `created_at` WHERE `uploaded_at` IS NULL;
Манифесты у ранее загруженных архивов остаются пустыми: список содержимого появится после того, как файл документа будет загружен заново.
Требования
ext-zip и ext-mbstring — для чтения архивов. В dev-контейнере и на production-сервере оба уже есть.