Нумератор генерирует уникальные номера по заданному шаблону. В шаблоне используются служебные слова: {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}',
],
];
Базовые генераторы
Для всех типов нумераторов доступно четыре базовых генератора.
|
|| Генератор | Служебные слова ||
|| RandomNumberGenerator |{RANDOM} — случайная строка из заглавных латинских букв и цифр ||
|| DateNumberGenerator |{DAY} — день месяца в момент генерации номера с ведущим нулем: 01, 23
{MONTH} — месяц в момент генерации номера с ведущим нулем: 03, 11
{YEAR} — текущий год на момент генерации кода ||
|| SequentNumberGenerator | {NUMBER} — уникальный последовательный номер ||
|| PrefixNumberGenerator | {PREFIX} — фиксированный текст, который задан в настройках ||
|#
Пример преобразования:
Шаблон: {PREFIX}__{YEAR}/{NUMBER}--{RANDOM}
↓ ↓ ↓ ↓
Генераторы: Prefix Date Sequent Random
↓ ↓ ↓ ↓
Значения: 'DOC' '2025' '007' 'A3F9K2'
Готовый номер: DOC__2025/007--A3F9K2
Дополнительные генераторы
|
|| Тип нумератора | Служебные слова ||
|| DOCUMENT | {CLIENT_ID} — идентификатор клиента
{SELF_ID} — идентификатор объекта с данными
{SELF_COMPANY_ID} — идентификатор компании ||
|| CRM_QUOTE |{QUOTE_ID} — номер предложения
{USER_ID_QUOTES_COUNT} — идентификатор пользователя и число его предложений ||
|| CRM_INVOICE |{INVOICE_ID} — номер счета
{USER_ID_INVOICES_COUNT} — идентификатор пользователя и число его счетов ||
|| ORDER | {USER_ID_ORDERS_COUNT} — идентификатор пользователя и число его заказов
{ORDER_ID} — номер заказа ||
|#
Как получить настройки нумератора
Чтобы получить настройки нумератора, используйте метод getSettingsFields.
Метод возвращает два массива:
-
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. Он возвращает пустой объект нумератора без имени и шаблона.
Передать конфигурацию
Конфигурация нумератора — ассоциативный массив. Ключ — тип класса генератора, значение — параметры.
|
|| Генератор | Параметры ||
|| Numerator |name — название нумератора, обязательный параметр
template — шаблон номера, обязательный параметр ||
|| SequentNumberGenerator | start — с какого числа начинать
step — шаг для увеличения номера
periodicBy — сбрасывать счетчик в start при наступлении нового периода
timezone — по какому часовому поясу определять наступление нового периода
isDirectNumeration — использовать сквозную нумерацию или иметь независимые счетчики ||
|| RandomNumberGenerator | length — длина номера ||
|| PrefixNumberGenerator | prefix — строка символов ||
|| DateNumberGenerator | Без параметров ||
|#
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() содержит идентификатор нового нумератора.
Как получить нумератор
Нумератор можно загрузить по идентификатору или по типу. После загрузки вызовите метод 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.
- Через метод
setDynamicConfig.
Как использовать хеш
Нумератор с {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.
- В
setHashчерез сеттер в виде объектаHashable.
- В методе
getNextв виде строки.