Перейти к содержанию

Объекты Provider SDK

Справочник относится к модулю 0.133.0, редакция документации 1.2. Пример регистрации находится в руководстве по подключению источника.

Классы объектов данных объявлены как final, публичные свойства — как readonly. Значения scalar|null — это строки, числа, логические значения или null. В summary и displaySettings допустимы только такие значения, без вложенных массивов и объектов.

EntityProviderDefinition и реестр провайдеров

EntityProviderDefinition(provider, renderer, cache, permissions) объединяет реализации четырёх интерфейсов. Метод id(): string возвращает provider->descriptor()->providerId.

Метод EntityProviderRegistry Назначение
collect(): self Создаёт реестр и отправляет событие сбора провайдеров
register(EntityProviderDefinition): bool Регистрирует провайдер; возвращает false, если идентификатор занят
get(string): ?EntityProviderDefinition Возвращает провайдер по идентификатору или null
all(): array<string, EntityProviderDefinition> Возвращает зарегистрированные провайдеры
conflicts(): list<string> Возвращает идентификаторы с конфликтами регистрации

При повторной регистрации одного идентификатора сохраняется первая реализация.

EntityProviderDescriptor

Описывает источник: его название, версию схемы, настройки отображения и CSS.

Поле конструктора Тип и значение по умолчанию Ограничение
providerId string Формат ^[a-z][a-z0-9._-]{1,127}$
label string Непустое название источника
entityLabel string Непустое название одной записи
schemaVersion int = 1 Положительное число
settingsSchema list<array> = [] Не более 32 полей
stylesheets list<string> = [] Не более 16 локальных путей от /; повторы удаляются

В stylesheets укажите локальные пути от корня сайта, например /local/css/catalog-cards.css. В путях запрещены внешние URL, //, .., обратная косая черта, пробелы, управляющие символы и опасные разделители в процентной кодировке. Начинайте CSS-селекторы с класса своего блока и проверьте оформление в редакторе и на сайте.

Поля settingsSchema

settingsSchema описывает поля формы и проверку значений. Используйте формат Provider SDK из таблицы ниже; JSON Schema здесь не поддерживается.

Ключ Тип Назначение
key Обязательная строка Уникальное имя по шаблону ^[a-z][a-zA-Z0-9_]{0,63}$, без __
type number, string, boolean, enum Тип поля и способ проверки значения
label Непустая строка Подпись поля
description Необязательная строка Пояснение пользователю
default Необязательное scalar|null Значение по умолчанию, соответствующее типу и ограничениям
min, max Конечные числа Границы для number; min <= max
options list<{value: string, label: string}> Для enum: от 1 до 32 вариантов с непустыми строками и уникальными значениями
responsive Необязательное bool Разрешает отдельные значения для размеров экрана через ключи key__кодВарианта

Перед проверкой выбора и выводом ядро подставляет значения по умолчанию и применяет ограничения схемы. Дополнительные скалярные поля сохраняются — проверяйте их в своём коде.

PHP
[
    ['key' => 'columns', 'type' => 'number', 'label' => 'Колонки',
     'default' => 3, 'min' => 1, 'max' => 6, 'responsive' => true],
    ['key' => 'variant', 'type' => 'enum', 'label' => 'Вид',
     'default' => 'cards', 'options' => [
         ['value' => 'cards', 'label' => 'Карточки'],
         ['value' => 'list', 'label' => 'Список'],
     ]],
]

Пример сохранённых настроек: {"columns":3,"columns__mobile":1,"variant":"cards"}. Вместо mobile используйте фактический код режима экрана из конфигурации установленного редактора.

EntityContext

Поле Тип Назначение
siteId string Сайт документа; 1–32 символа [A-Za-z0-9_-]
languageId string Язык; 2–16 символов [A-Za-z_-]
userId ?int Положительный идентификатор пользователя или null
editor bool Вызов из редактора либо для публичного вывода
contentUid ?string = null Нормализованный идентификатор документа

Сервер создаёт контекст после проверки доступа. Для общего публичного HTML он задаёт editor=false и userId=null, чтобы не использовать права автора публикации при выводе для посетителей.

При прямом вызове EntityProviderService проверьте доступ к документу и сформируйте контекст на сервере. Не принимайте сайт и пользователя из браузера без проверки.

EntitySearchRequest

Поле Значение по умолчанию Ограничение
query: string '' Не более 300 символов
limit: int 20 От 1 до 100
offset: int 0 Неотрицательное число

Верните list<EntityRecord> с числом записей не больше limit. Проверьте права и примените пагинацию в провайдере. Ядро дополнительно уберёт из результатов неактивные записи.

EntityRecord

Конструктор принимает id: string, label: string, summary: array<string, scalar|null> = [], state: string = 'active'.

Идентификатор соответствует ^[A-Za-z0-9._:-]{1,128}$, подпись должна быть непустой. Состояние принимает значение active, inactive или deleted.

Идентификаторы сравниваются как строки: "001" и "1" — разные записи. В summary передавайте краткие сведения, разрешённые для показа пользователю редактора.

EntitySelection

Поле Тип и значение по умолчанию Ограничение
providerId string Идентификатор из описания провайдера
entityIds list<string> От 1 до 100 уникальных идентификаторов формата EntityRecord; порядок значим
displaySettings array<string, scalar|null> = [] Настройки отображения
schemaVersion int = 1 Совпадает с версией схемы провайдера

Объект сохраняется в selection узла provider. В нём хранятся идентификаторы записей и настройки их отображения. Ответ API, HTML и параметры подключения остаются вне документа.

Сервис выводит записи в порядке entityIds. Если одна из них отсутствует, удалена или неактивна, он вернёт ошибку, а при выводе — пустой HTML. Остальные записи при этом тоже не показываются.

EntityRenderResult

Конструктор: EntityRenderResult(html: string, diagnostics: list<string> = []).

В diagnostics передаются непустые диагностические сообщения. Они не включаются в ответ с HTML. Максимальный размер HTML — 2 МиБ. Экранируйте текст и атрибуты в провайдере; модуль дополнительно очистит результат на сервере.

Методы и ответы сервиса

Метод Результат
discover(EntityContext) list<EntityProviderDescriptor>; HTTP-обработчик возвращает {status:'ok', providers}
search(string, EntitySearchRequest, EntityContext) {status, records: EntityRecord[]}
select(EntitySelection, EntityContext) {status, records: EntityRecord[]}
render(EntitySelection, EntityContext) {status, html}; при успехе также возможен stylesheets: string[]
invalidate(string, array = []) {status}; вызывается доверенным серверным кодом
status Что означает и что проверить
ok Операция завершена, результат можно использовать
invalid_request Неверный состав или типы данных запроса
context_unavailable Не удалось определить контекст; проверьте привязку документа к сайту
missing_provider Провайдер не зарегистрирован
forbidden Недостаточно прав для операции
incompatible_schema Нужна совместимая реализация или преобразование сохранённого выбора
missing_entity, deleted_entity, inactive_entity Одна из записей недоступна; предложите автору изменить выбор
invalid_provider_response Проверьте типы ответа, повторяющиеся или посторонние идентификаторы, лимиты и формирование HTML
unavailable Проверьте доступность источника и серверную диагностику

Ошибка аутентификации, CSRF или доступа может прийти как ошибка Битрикс AJAX или отклонённый Promise. Обработайте оба случая: ошибку самого запроса и поле status в полученном ответе.

Кеширование

ttl(EntitySelection): int задаёт срок хранения результата в секундах: 0 отключает кеш, максимум — 3600. Предпросмотр и вызовы с пользовательским контекстом не кешируются этим сервисом.

tags(EntitySelection): list<string> возвращает до 64 непустых тегов, каждый длиной до 256 байт. Перед выдачей кешированного результата сервис снова проверяет права и состояние записей. Кеш опубликованных страниц и CDN очищайте отдельно.

Очередь исходящих уведомлений

Очередь outbox хранит уведомления об изменении источника до подтверждения доставки. Записывайте событие в одной транзакции с изменением данных. Тогда после успешной записи данных уведомление останется в очереди, даже если отправить его сразу не удалось.

ProviderOutboxMessage(eventUid, providerId, entityIds, leaseToken, requestedBy = null) содержит:

  • eventUid — UUID версии 4 в нижнем регистре;
  • providerId — идентификатор провайдера;
  • entityIds — изменившиеся записи; пустой список означает все записи провайдера;
  • leaseToken — токен временного захвата события обработчиком, до 256 байт без пробелов и управляющих символов;
  • requestedBy — положительный идентификатор автора либо null.

Интерфейс ProviderOutboxInterface:

PHP
public function claim(int $limit): array; // list<ProviderOutboxMessage>
public function acknowledge(ProviderOutboxMessage $message): bool;
public function release(ProviderOutboxMessage $message, string $reason): bool;

claim() резервирует для обработчика не более limit событий из завершённых транзакций. Резервирование должно быть атомарным; перед возвратом результата блокировки БД снимаются. Если срок обработки истёк, событие можно передать другому обработчику с новым токеном. В acknowledge() и release() сверяйте UUID и токен, чтобы запоздавший ответ прежнего обработчика не изменил состояние события.

В приложении настройте повторную доставку и то, что делать с событиями, которые каждый раз завершаются ошибкой.

Готовый пример project.catalog показывает JSON-источник, проверку прав и варианты вывода списком и карточками. Настройте его пути и разрешения под свой проект; закрытый файл данных храните вне корня сайта.