Налаштування версіонування медіафайлів 1С-Бітрікс
Версіонування медіафайлів — можливість зберігати історію змін файлу, відкочуватись до попередньої версії та відстежувати, хто і коли вносив правки. У Бітрікс такий механізм не вбудований у модуль fileman за замовчуванням. З коробки при перезапису файлу стара версія безповоротно видаляється.
Як влаштоване зберігання файлів у Бітрікс
Усі файли реєструються в таблиці b_file. При «оновленні» файлу через стандартний інтерфейс Бітрікс створює новий запис у b_file з новим ID, а старий файл фізично видаляється з диска через CFile::Delete(). Посилання на старий FILE_ID в інших таблицях оновлюються по ланцюжку — цим і пояснюється відсутність історії.
Архітектура версіонування
Для версіонування потрібна додаткова таблиця історії:
CREATE TABLE bl_file_versions (
id INT AUTO_INCREMENT PRIMARY KEY,
medialib_id INT NOT NULL, -- ID елемента b_medialib_item
file_id INT NOT NULL, -- ID у b_file (стара версія)
version INT NOT NULL DEFAULT 1,
created_by INT NOT NULL, -- b_user.ID
created_at DATETIME NOT NULL,
comment VARCHAR(500),
INDEX idx_medialib (medialib_id, version)
);
Логіка: при кожному оновленні файлу в медіабібліотеці не видаляємо старий запис з b_file і фізичний файл, а записуємо його FILE_ID у bl_file_versions. Поточна версія залишається в b_medialib_item.FILE_ID, усі попередні — в таблиці історії.
Перехоплення події оновлення
Обробник події реєструється в init.php або в модулі:
AddEventHandler('fileman', 'OnMedialibItemUpdate', 'SaveFileVersion');
function SaveFileVersion(int $itemId, array $oldFields): void {
if (empty($oldFields['FILE_ID'])) return;
global $USER;
$DB->Query("INSERT INTO bl_file_versions
(medialib_id, file_id, version, created_by, created_at)
SELECT " . intval($itemId) . ", " . intval($oldFields['FILE_ID']) . ",
COALESCE(MAX(version), 0) + 1, " . (int)$USER->GetID() . ", NOW()
FROM bl_file_versions WHERE medialib_id = " . intval($itemId));
}
Подія OnMedialibItemUpdate спрацьовує до запису нових даних, що дозволяє зберегти FILE_ID старої версії.
Зберігання фізичних файлів версій
Файли версій зберігаються в /upload/fileman/versions/{item_id}/v{N}/. При відкаті створюється новий запис у b_file, а шлях до файлу відновлюється. Фізичне видалення старих версій відбувається тільки при явному «Очистити історію» — не автоматично.
Для економії дискового простору можна зберігати лише останні N версій. Агент раз на добу перевіряє таблицю bl_file_versions і видаляє версії старші за поріг:
$maxVersions = COption::GetOptionInt('mymodule', 'max_file_versions', 10);
Інтерфейс перегляду та відкату
В адміністративному інтерфейсі медіабібліотеки додається кнопка «Історія версій», що відкриває список з датою, автором і кнопкою «Відновити». Відкат — це створення нового b_file на основі файлу версії та оновлення b_medialib_item.FILE_ID.
| Операція | Метод |
|---|---|
| Зберегти версію | подія OnMedialibItemUpdate |
| Отримати історію | SELECT з bl_file_versions |
| Відкатити версію | CMedialibItem::Update() + CFile::MakeFileArray() |
| Видалити версію | CFile::Delete() + DELETE з bl_file_versions |
Що входить у налаштування
- Створення таблиці
bl_file_versionsта індексів - Написання обробника події
OnMedialibItemUpdate - Налаштування зберігання фізичних файлів версій
- Адміністративний інтерфейс перегляду історії та відкату
- Агент для очищення старих версій за налаштованим лімітом







