В этой главе рассматривается Персональная файловая система (PFS) Seditio CMS, структура баз данных для файлов и папок, права доступа к файловому пространству (ACL) и дисковые лимиты, а также низкоуровневый и высокоуровневый программный интерфейс обработки медиа-ресурсов (Image API, ресайз на лету, наложение водяных знаков и асинхронная Drag & Drop загрузка).
11.1. Архитектура PFS на уровне Базы Данных
Персональная файловая система (PFS) является встроенным модулем ядра Seditio. Схемы таблиц PFS регистрируются инсталлятором при активации модуля через файл pfs.install.php.
Данные PFS хранятся в двух связанных системных таблицах базы данных: sed_pfs (файлы) и sed_pfs_folders (виртуальные папки).
11.1.1. Таблица загруженных файлов (sed_pfs)
Каждый файл, загруженный пользователем на сайт через PFS, описывается записью в этой таблице:
| Поле | Тип | Описание |
|---|---|---|
pfs_id | int | Уникальный первичный ключ записи (AUTO_INCREMENT). |
pfs_userid | int | ID пользователя-владельца файла (внешний ключ на sed_users). |
pfs_date | int | UNIX-время загрузки файла. |
pfs_file | varchar(255) | Физическое имя файла на сервере (хранится в каталоге /datas/users/). |
pfs_extension | varchar(8) | Расширение файла в нижнем регистре (например, jpg, zip, pdf). |
pfs_folderid | int | ID виртуальной папки, к которой принадлежит файл (внешний ключ на sed_pfs_folders). Если файл загружен в корень, равен 0. |
pfs_title | varchar(255) | Название файла, заданное пользователем при загрузке. |
pfs_desc | text | Текстовое описание файла. |
pfs_size | int | Размер файла в байтах. |
pfs_count | int | Счетчик обращений (скачиваний/просмотров) файла на сайте. |
11.1.2. Таблица виртуальных папок (sed_pfs_folders)
Пользователи могут группировать свои файлы по виртуальным каталогам. Структура папок описывается следующей схемой:
| Поле | Тип | Описание |
|---|---|---|
pff_id | int | Первичный ключ папки (AUTO_INCREMENT). |
pff_userid | int | ID пользователя-владельца папки. |
pff_parentid | int | ID родительской папки (для поддержки вложенности). По умолчанию равен 0. |
pff_date | int | UNIX-время создания папки. |
pff_updated | int | UNIX-время последнего обновления содержимого папки. |
pff_title | varchar(255) | Название папки. |
pff_desc | text | Описание папки. |
pff_type | tinyint | Флаг приватности папки (0 — публичный доступ, 1 — только для владельца). |
pff_sample | int | ID файла (pfs_id) из этой папки, который служит превью-картинкой (обложкой) папки. |
pff_count | int | Счетчик файлов, содержащихся в данной папке. |
11.2. Права доступа (ACL) и квоты дискового пространства
PFS является контролируемым ресурсом, доступ к которому жестко регламентируется правами ACL и дисковыми квотами групп пользователей.
11.2.1. Контроль доступа (ACL)
Доступ к модулю PFS определяется правами авторизации для кода ресурса pfs (опция a):
- Гости (
SED_GROUP_GUESTS) по умолчанию лишены каких-либо прав (запрещены чтение и запись). - Пользователи (
SED_GROUP_MEMBERS) имеют праваRW(Чтение и Запись собственных файлов). Модифицировать чужие файлы пользователи не могут. - Администраторы (
SED_GROUP_SUPERADMINS) имеют праваRWA12345(полный доступ, включая право просмотра и удаления файлов любых пользователей через Панель управления).
11.2.2. Лимиты и дисковые квоты групп
Для предотвращения переполнения диска сервера в настройках каждой группы пользователей (вкладка «Права/Группы» в админ-панели) задаются индивидуальные дисковые квоты:
grp_pfs_maxfile— максимальный допустимый размер одного загружаемого файла (в КБ). Если файл превышает этот объем, ядро блокирует загрузку.grp_pfs_maxtotal— максимальный суммарный объем файлов (квота дискового пространства на одного пользователя группы в КБ).
При каждой попытке загрузки файла ядро Seditio суммирует размер всех уже загруженных файлов пользователя в БД:
SELECT SUM(pfs_size) FROM sed_pfs WHERE pfs_userid = $userid
И сопоставляет сумму вместе с размером нового файла с лимитом grp_pfs_maxtotal. При превышении лимита загрузка прерывается ошибкой безопасности.
11.3. Встроенная обработка изображений (Image API)
Все функции работы с изображениями сосредоточены в системном файле system/functions.image.php. Seditio поддерживает работу как с расширением GD, так и с ImageMagick (выбор настраивается административно).
11.3.1. Основные функции ресайза и обрезки
Для удобного применения непосредственно внутри HTML-шаблонов в Seditio CMS реализованы две высокоуровневые функции-фильтра:
resize_image($filename, $width, $height, $set_watermark, $use_webp)Масштабирует изображение до указанных ширины и высоты с сохранением исходных пропорций (картинка вписывается в заданные рамки).crop_image($filename, $width, $height, $set_watermark, $use_webp)Обрезает изображение точно под указанные пропорции. Картинка центрируется, лишние края отсекаются.
Параметры функций:
$filename(string) — относительный путь к исходному файлу на диске (например,datas/users/photo.jpg).$width(int) — целевая ширина в пикселях.$height(int) — целевая высота в пикселях.$set_watermark(bool, необязательный) — флаг наложения водяного знака.$use_webp(bool, необязательный) — флаг конвертации изображения в формат WebP для снижения веса.
11.3.2. Концепция отложенного ресайза
Для того чтобы генерация тяжелых изображений не замедляла загрузку основных HTML-страниц сайта, в Seditio применен механизм отложенного ресайза:
- При рендеринге страницы шаблонизатор вызывает функцию
resize_image()илиcrop_image(). - Функция не производит ресайз физически. Она лишь кодирует параметры сжатия (ширину, высоту, режим сжатия) и возвращает виртуальный путь в директорию кэша
$cfg['res_dir'](по умолчанию/datas/resized/): Пример возвращаемого пути:datas/resized/photo.resize.1920.1080.jpg. - Браузер пользователя получает готовый HTML-код с этим виртуальным путем и отправляет GET-запрос к изображению.
- Сервер перенаправляет запросы несуществующих файлов из папки
/datas/resized/на скрипт-обработчик (модульresizer). - Модуль
resizerперехватывает запрос, парсит имя файла, находит оригинал, выполняет его физический ресайз с помощью функцииsed_resize(), сохраняет готовый файл в кэш и отдает браузеру. - При повторных запросах веб-сервер отдает уже готовый сжатый файл с диска напрямую, минуя PHP.
11.3.3. Наложение водяных знаков (sed_image_merge)
Если при ресайзе передан флаг $set_watermark = true, система вызывает функцию sed_image_merge().
- Настройки водяного знака (путь к PNG-файлу с прозрачностью, прозрачность в процентах и позиционирование) считываются из конфигурации ядра.
- Слияние изображений происходит с сохранением альфа-канала с помощью функции
sed_imagecopymerge_alpha(), предотвращающей появление артефактов на стыках полупрозрачности водяного знака.
11.4. Drag & Drop асинхронная загрузка файлов
Для удобной пакетной загрузки медиа-ресурсов Seditio CMS оснащена встроенным асинхронным загрузчиком, функции которого объявлены в system/functions.image.php.
11.4.1. Ключевые функции загрузчика
sed_image_upload_html($name, $options)— генерирует HTML-разметку области загрузки (Drag & Drop дроп-зону), подключает необходимые CSS/JS-библиотеки и регистрирует события.sed_image_upload_save($file_data, $dest_path)— производит низкоуровневую валидацию и сохранение загруженного файла на диске.sed_image_upload_process()— обрабатывает асинхронный POST-запрос с файлами, проверяет права доступа пользователя к PFS и дисковые квоты, сохраняет оригиналы файлов и автоматически создает их эскизы в PFS.
11.4.2. Использование Drag & Drop загрузчика в плагинах
Для интеграции загрузчика в форму создания контента разработчику плагина достаточно вызвать хелпер в PHP-контроллере:
// Генерируем HTML-код дроп-зоны для поля с именем 'album_images'
$uploader_html = sed_image_upload_html('album_images', array(
'max_files' => 10,
'allowed_extensions' => 'jpg,jpeg,png,webp'
));
$t->assign('MYPLUGIN_UPLOADER', $uploader_html);
И вывести тег в TPL-шаблоне:
<div class="form-group">
<label>Загрузить фотографии альбома:</label>
{MYPLUGIN_UPLOADER}
</div>
При отправке формы ядро автоматически обработает переданные файлы, привяжет их к текущему сеансу PFS пользователя и сохранит пути в базу данных.
Комментарии: (0)