Настройка версионирования медиафайлов 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 - Настройка хранения физических файлов версий
- Административный интерфейс просмотра истории и отката
- Агент для очистки старых версий по настраиваемому лимиту







