Дисковое пространство на портале Битрикс24 заканчивается всегда одинаково: несколько человек годами хранят на диске всё подряд, а расширять тариф приходится всей компании. Квоты решают вопрос на входе — но только если назначаются автоматически, потому что вручную про нового сотрудника вспомнят не всегда.
Задача
При создании нового сотрудника в Битрикс24 автоматически назначать ему дисковую квоту определённого размера. Это позволяет контролировать использование дискового пространства на портале.
Предварительная настройка
Прежде всего активируйте функцию квот в модуле Диск:
- Перейдите в Настройки → Настройки модулей → Диск
- Включите опцию "Устанавливать квоту для дисков сотрудников"
Без активации этой опции методы API для работы с квотами не будут работать — причём тихо: вызов отработает без ошибки, а лимит не установится. Проверяйте результат, а не факт выполнения кода.
Реализация
Класс обработчика
Создайте файл /local/php_interface/classes/UserDiskQuotaHandler.php:
<?php
namespace Local\Handlers;
use Bitrix\Main\Loader;
use Bitrix\Disk\Driver;
class UserDiskQuotaHandler
{
/**
* Размер квоты по умолчанию (в байтах)
* 100 MB = 100 * 1024 * 1024
*/
private const DEFAULT_QUOTA_SIZE = 104857600;
/**
* Квоты для разных отделов (в байтах)
*/
private const DEPARTMENT_QUOTAS = [
1 => 524288000, // Руководство: 500 MB
5 => 209715200, // Разработка: 200 MB
10 => 104857600, // Продажи: 100 MB
];
/**
* Обработчик события создания пользователя
*/
public static function onAfterUserAdd(array &$fields): void
{
if (empty($fields['ID']) || (int)$fields['ID'] <= 0) {
return;
}
$userId = (int)$fields['ID'];
// Определяем размер квоты
$quotaSize = self::getQuotaForUser($fields);
// Устанавливаем квоту
self::setDiskQuota($userId, $quotaSize);
// Логируем
self::logQuotaAssignment($userId, $quotaSize);
}
/**
* Определение квоты на основе отдела пользователя
*/
private static function getQuotaForUser(array $fields): int
{
// Если указаны отделы, проверяем наличие специальной квоты
if (!empty($fields['UF_DEPARTMENT']) && is_array($fields['UF_DEPARTMENT'])) {
foreach ($fields['UF_DEPARTMENT'] as $departmentId) {
if (isset(self::DEPARTMENT_QUOTAS[$departmentId])) {
return self::DEPARTMENT_QUOTAS[$departmentId];
}
}
}
return self::DEFAULT_QUOTA_SIZE;
}
/**
* Установка дисковой квоты
*/
private static function setDiskQuota(int $userId, int $quotaSize): bool
{
if (!Loader::includeModule('disk')) {
return false;
}
try {
$storage = Driver::getInstance()->getStorageByUserId($userId);
if ($storage) {
$storage->setSizeLimit($quotaSize);
return true;
}
} catch (\Exception $e) {
// Логируем ошибку
AddMessage2Log(
"Ошибка установки квоты для пользователя {$userId}: " . $e->getMessage(),
"disk_quota"
);
}
return false;
}
/**
* Логирование назначения квоты
*/
private static function logQuotaAssignment(int $userId, int $quotaSize): void
{
$quotaMb = round($quotaSize / 1024 / 1024, 2);
AddMessage2Log(
"Пользователю ID={$userId} назначена дисковая квота: {$quotaMb} MB",
"disk_quota"
);
}
/**
* Форматирование размера для отображения
*/
public static function formatSize(int $bytes): string
{
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
while ($bytes >= 1024 && $i < count($units) - 1) {
$bytes /= 1024;
$i++;
}
return round($bytes, 2) . ' ' . $units[$i];
}
}Регистрация обработчика
В файле /local/php_interface/init.php:
<?php
// Автозагрузка классов
spl_autoload_register(function ($class) {
$prefix = 'Local\\';
$baseDir = __DIR__ . '/classes/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relativeClass = substr($class, $len);
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
});
// Регистрация обработчика события
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'main',
'OnAfterUserAdd',
['\\Local\\Handlers\\UserDiskQuotaHandler', 'onAfterUserAdd'],
false,
9999 // Высокий приоритет — выполняется после создания диска
);Важно: Параметр приоритета 9999 критически важен. Он гарантирует, что установка квоты произойдёт после инициализации диска пользователя системой.
Проверка установленной квоты
<?php
use Bitrix\Main\Loader;
use Bitrix\Disk\Driver;
Loader::includeModule('disk');
$userId = 123;
$storage = Driver::getInstance()->getStorageByUserId($userId);
if ($storage) {
$sizeLimit = $storage->getSizeLimit();
$usedSize = $storage->getUsedSize();
echo "Квота: " . \Local\Handlers\UserDiskQuotaHandler::formatSize($sizeLimit) . "\n";
echo "Использовано: " . \Local\Handlers\UserDiskQuotaHandler::formatSize($usedSize) . "\n";
echo "Свободно: " . \Local\Handlers\UserDiskQuotaHandler::formatSize($sizeLimit - $usedSize) . "\n";
}Массовое назначение квот существующим пользователям
<?php
use Bitrix\Main\Loader;
use Bitrix\Main\UserTable;
use Bitrix\Disk\Driver;
Loader::includeModule('disk');
Loader::includeModule('main');
$quotaSize = 100 * 1024 * 1024; // 100 MB
$users = UserTable::getList([
'filter' => ['ACTIVE' => 'Y'],
'select' => ['ID'],
]);
while ($user = $users->fetch()) {
$storage = Driver::getInstance()->getStorageByUserId($user['ID']);
if ($storage && $storage->getSizeLimit() === null) {
$storage->setSizeLimit($quotaSize);
echo "Установлена квота для пользователя {$user['ID']}\n";
}
}Квота меньше уже занятого объёма — это заблокированный диск. Если сотрудник хранит 12 ГБ, а вы назначаете лимит 10 ГБ, он не сможет загрузить ни одного файла, пока не удалит лишнее. Массовое назначение квоты без проверки текущего занятого объёма превращается в поток обращений в поддержку на следующее утро.
Перед массовым назначением соберите статистику: сколько сотрудников уже превышают планируемый лимит. Если таких единицы — предупредите их лично. Если это половина компании — лимит выбран неверно.
Обратите внимание, что в скрипте выше квота ставится только тем, у кого её нет (getSizeLimit() === null). Это правильное поведение: индивидуально настроенные лимиты не должны затираться массовой операцией.
Итоги
Квота на новых сотрудников — обработчик события, квота на существующих — разовый скрипт. Это две разные задачи, и вторая требует предварительного анализа занятого места.
Проверяйте результат установки, а не факт вызова метода: при выключенной опции модуля код отработает молча.
Не затирайте индивидуальные лимиты. Кому-то по работе действительно нужно больше, и это решение руководителя, а не скрипта.
Предупреждайте до того, как ограничение сработает. Уведомление «занято 90% квоты» решает проблему заранее; сообщение «файл не загружен» в момент срочной работы — нет.
Квота — инструмент планирования, а не наказания. Прежде чем ограничивать, стоит посмотреть, чем занято место: обычно значительная часть — это старые версии файлов и содержимое корзины, которые чистятся настройками хранения версий без всяких квот и без разговоров с сотрудниками.
Комментарии
Система комментариев скоро будет подключена. А пока вы можете написать мне в Telegram или на email.