Модуль публикации документов для ознакомления: карточка документа с описанием, скачиванием и предпросмотром, списки по категориям с фильтром и сортировкой.
Виджет Besnovatyj\Documents\widgets\preview\DocumentPreviewWidget выбирает вид предпросмотра по расширению
загруженного файла:
| Файл | Что видит посетитель |
|---|---|
| jpg, jpeg, png, gif | картинка на странице, по клику — полный размер с домена статики |
| встроенный просмотрщик, постранично | |
| zip | список файлов внутри архива, каждый можно скачать отдельно |
| прочее, внешняя ссылка | только кнопка скачивания |
Виджет самодостаточен и подключается одной строкой:
<?= DocumentPreviewWidget::widget(['document' => $document]) ?>Используется 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) нельзя.
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-сервере оба уже есть.