Нумератор
Нумератор генерирует уникальные номера по заданному шаблону. В шаблоне используются служебные слова: {NUMBER}, {YEAR}, {RANDOM} и другие.
Нумератор обеспечивает уникальность порядковых номеров даже при одновременных запросах.
Логика работы
Нумератор состоит из генераторов — классов, которые подставляют значения вместо служебных слов.
Каждый генератор работает только с определенными типами нумераторов. Список доступных слов зависит от типа. Получить список можно с помощью метода getTemplateWordsForType.
use Bitrix\Main\Numerator\Numerator;
$templateWords = Numerator::getTemplateWordsForType('DOCUMENT');
// Или 'ALL', чтобы получить слова для всех типов
Результат с базовым набором:
[
'Bitrix_Main_Numerator_Generator_SequentNumberGenerator' => [
'{NUMBER}',
],
'Bitrix_Main_Numerator_Generator_DateNumberGenerator' => [
'{DAY}',
'{MONTH}',
'{YEAR}',
],
'Bitrix_Main_Numerator_Generator_RandomNumberGenerator' => [
'{RANDOM}',
],
'Bitrix_Main_Numerator_Generator_PrefixNumberGenerator' => [
'{PREFIX}',
],
];
Базовые генераторы
Для всех типов нумераторов доступно четыре базовых генератора.
|
Генератор |
Служебные слова |
|
|
|
|
|
|
|
|
|
|
|
|
Пример преобразования:
Шаблон: {PREFIX}__{YEAR}/{NUMBER}—{RANDOM}
↓ ↓ ↓ ↓
Генераторы: Prefix Date Sequent Random
↓ ↓ ↓ ↓
Значения: 'DOC' '2025' '007' 'A3F9K2'
Готовый номер: DOC__2025/007—A3F9K2
Дополнительные генераторы
|
Тип нумератора |
Служебные слова |
|
|
|
|
|
|
|
|
|
|
|
|
Как получить настройки нумератора
Чтобы получить настройки нумератора, используйте метод getSettingsFields.
use Bitrix\Main\Numerator\Numerator;
$settings = Numerator::getSettingsFields('DOCUMENT');
Метод возвращает два массива:
-
settingsFields— описывает интерфейс настроек: типы полей, заголовки, значения по умолчанию, -
settingsWords— связывает служебные слова с названиями в интерфейсе.
Пример результата:
[
'settingsFields' => [
'Bitrix_Main_Numerator_Numerator' => [
['settingName' => 'name', 'type' => 'string', 'default' => 'Нумератор 1', 'title' => 'Название нумератора', ],
['settingName' => 'template', 'type' => 'string', 'title' => 'Шаблон номера',],
],
'Bitrix_Main_Numerator_Generator_SequentNumberGenerator' => [
['settingName' => 'start', 'type' => 'int', 'default' => 1, 'title' => 'Начинать последовательный номер с',],
['settingName' => 'step', 'type' => 'int', 'default' => 1, 'title' => 'Увеличивать последовательный номер на',],
['settingName' => 'periodicBy', 'type' => 'array', 'title' => 'Период работы нумератора', 'values' => [
['settingName' => 'default', 'value' => '', 'title' => 'Постоянно',],
['settingName' => 'day', 'value' => 'day', 'title' => 'В пределах дня',],
['settingName' => 'month', 'value' => 'month', 'title' => 'В пределах месяца',],
['settingName' => 'year', 'value' => 'year', 'title' => 'В пределах года',],],
],
['settingName' => 'timezone', 'type' => 'array', 'values' => [...]],
...,
],
...,
],
'settingsWords' => [
'Bitrix_Main_Numerator_Generator_SequentNumberGenerator' => ['{NUMBER}' => 'Последовательный номер',],
'Bitrix_Main_Numerator_Generator_DateNumberGenerator' => ['{DAY}' => 'Текущий день', '{MONTH}' => 'Текущий месяц', '{YEAR}' => 'Текущий год',],
'Bitrix_Main_Numerator_Generator_RandomNumberGenerator' => ['{RANDOM}' => 'Случайный номер',],
'Bitrix_Main_Numerator_Generator_PrefixNumberGenerator' => ['{PREFIX}' => 'Префикс',],
]
];
Как добавить генератор
Генератор регистрируют в событии onNumberGeneratorsClassesCollect, потому что нумератор формирует динамически список доступных генераторов при инициализации.
Например, добавьте генератор TimeNumberGenerator и служебное слово {TIME}.
Зарегистрировать класс в событии
Зарегистрируйте класс генератора в событии onNumberGeneratorsClassesCollect. Достаточно указать имя класса — TimeNumberGenerator. Метод onGeneratorClassesCollect реализован в базовом классе \Bitrix\Main\Numerator\Generator\NumberGenerator.
RegisterModuleDependences(
'main',
'onNumberGeneratorsClassesCollect',
'mymodule',
'TimeNumberGenerator',
'onGeneratorClassesCollect'
);
Создать класс генератора
-
Унаследуйте класс
TimeNumberGeneratorотNumberGenerator. -
В класс добавьте методы:
-
getConfig— возвращает текущие настройки. Например, формат времени. -
setConfig— устанавливает настройки при инициализации из базы. -
getSettingsFields— описывает поля настроек для интерфейса. -
getTemplateWordsForParse— перечисляет служебные слова, которые генератор может обработать. В примере —{TIME}. -
getTemplateWordsSettings— сопоставляет служебные слова с названиями. Используется для подписей на кнопках в интерфейсе. В примере — кнопкаtime. -
getAvailableForType— возвращает типы нумераторов, с которыми работает генератор. В примере — все типыNUMERATOR_DEFAULT_TYPE. -
parseTemplate— подставляет значение вместо служебного слова. Остальные слова оставляет без изменений, их обработают другие генераторы. -
validateConfig— проверяет корректность настроек.
-
<?php
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Numerator\Generator\NumberGenerator;
use Bitrix\Main\Numerator\Generator\Contract\UserConfigurable;
use Bitrix\Main\Numerator\Numerator;
class TimeNumberGenerator extends NumberGenerator implements UserConfigurable
{
const TEMPLATE_WORD_TIME = "TIME";
protected $format;
/** @inheritdoc */
public function getConfig()
{
return ['format' => $this->format];
}
/** @inheritdoc */
public function setConfig($config)
{
$this->setFromArrayOrDefault('format', $config, 'H:i:s', 'string');
}
/** @inheritdoc */
public static function getSettingsFields()
{
return [
[
'settingName' => 'format',
'type' => 'string',
'default' => 'H:i:s',
'title' => 'Формат времени',
],
];
}
/** @inheritdoc */
public static function getTemplateWordsForParse()
{
return [static::getPatternFor(static::TEMPLATE_WORD_TIME)];
}
/** @inheritdoc */
public static function getTemplateWordsSettings()
{
return [static::getTemplateFor(static::TEMPLATE_WORD_TIME) => 'time'];
}
/** @inheritdoc */
public static function getAvailableForType()
{
return Numerator::NUMERATOR_DEFAULT_TYPE;
}
/** @inheritdoc */
public function parseTemplate($template)
{
return str_replace(
static::getPatternFor(static::TEMPLATE_WORD_TIME),
date($this->format, time()),
$template
);
}
/** @inheritdoc */
public function validateConfig($config)
{
$result = new \Bitrix\Main\Result();
return $result;
}
}
После подключения класса в интерфейсе отображается кнопка time. Клик по кнопке вставляет слово {TIME} в шаблон.

Как создать нумератор
Чтобы создать нумератор, используйте класс \Bitrix\Main\Numerator\Numerator.
Получить экземпляр
Вызовите метод create. Он возвращает пустой объект нумератора без имени и шаблона.
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::create();
Передать конфигурацию
Конфигурация нумератора — ассоциативный массив. Ключ — тип класса генератора, значение — параметры.
|
Генератор |
Параметры |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Без параметров |
use Bitrix\Main\Numerator\Generator;
$config = [
Numerator::getType() => [
'name' => 'Мой нумератор',
'template' => '{PREFIX}__{YEAR}/{NUMBER}—{RANDOM}',
],
Generator\RandomNumberGenerator::getType() => [
'length' => 6,
],
Generator\SequentNumberGenerator::getType() => [
'start' => 3,
'step' => 2,
],
Generator\PrefixNumberGenerator::getType() => [
'prefix' => 'DOC',
],
];
$numerator->setConfig($config);
Сохранить нумератор
Метод save возвращает объект результата. При успехе $result->getId() содержит идентификатор нового нумератора.
$result = $numerator->save(); // \Bitrix\Main\Entity\AddResult
Как получить нумератор
Нумератор можно загрузить по идентификатору или по типу. После загрузки вызовите метод getNext, чтобы получить следующий номер.
Получить по идентификатору
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::load($numeratorId);
Получить по типу
Первый нумератор указанного типа:
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::getOneByType('ORDER');
Список всех нумераторов указанного типа:
use Bitrix\Main\Numerator\Numerator;
$numerators = Numerator::getListByType('CRM_INVOICE');
Получить следующий номер
$number = $numerator->getNext();
Изменить настройки нумератора
Измените конфигурацию и сохраните с помощью метода update:
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::load($numeratorId);
$config = $numerator->getConfig();
$config[Numerator::getType()]['name'] = 'Обновленный нумератор';
$result = Numerator::update($id, $config);
Для существующих нумераторов не вызывайте метод save. Используйте update, чтобы избежать конфликтов при параллельных запросах.
Передать контекст
В нумератор передают дополнительные данные, если генератор реализует интерфейс DynamicConfigurable.
Контекст или источник данных можно передать двумя способами.
-
При загрузке нумератора методом
load.$numerator = Numerator::load($id, $source); -
Через метод
setDynamicConfig.$numerator->setDynamicConfig($config);
Как использовать хеш
Нумератор с {NUMBER} может отвечать за несколько последовательных номеров и иметь несколько независимых счетчиков.
Если запросить следующий номер у нумератора, получите последовательно увеличивающееся число.
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::create();
$numerator->setConfig([
Numerator::getType() => [
'name' => 'test sequence',
'template' => '{NUMBER}',
],
]);
$result = $numerator->save();
$numerator = Numerator::load($result->getId());
echo $numerator->getNext() . PHP_EOL;
$numerator = Numerator::load($result->getId());
echo $numerator->getNext() . PHP_EOL;
$numerator = Numerator::load($result->getId());
echo $numerator->getNext() . PHP_EOL;
// Получим
// 1
// 2
// 3
Если задать хеш и запросить номер для разного хеша, получите независимые счетчики.
use Bitrix\Main\Numerator\Numerator;
$numerator = Numerator::create();
$numerator->setConfig([
Numerator::getType() => [
'name' => 'sequence',
'template' => '{NUMBER}',
],
]);
$result = $numerator->save();
$numerator = Numerator::load($result->getId());
echo $numerator->getNext('A') . PHP_EOL;
$numerator = Numerator::load($result->getId());
echo $numerator->getNext('B') . PHP_EOL;
$numerator = Numerator::load($result->getId());
echo $numerator->getNext('A') . PHP_EOL;
// Получим
// 1
// 1
// 2
Хеш можно установить тремя способами.
-
В методе
loadвторым параметром в виде объекта, который реализует интерфейсHashable.use Bitrix\Main\Numerator\Numerator; Numerator::load($numeratorId, $hashable); -
В
setHashчерез сеттер в виде объектаHashable.$numerator->setHash($hashable); -
В методе
getNextв виде строки.$hash = 'MANAGER_42'; $numerator->getNext($hash);