Недокументированный битрикс. Свои вкладки с кастомным функционалом на странице элемента инфоблока, и не только

Уж не знаю почему, но многие администраторы сайтов хвалят битриксовую админку. Однако я не разделяю этого мнения, и считаю что структура админки построена нелогично, в ней очень много лишнего, а как разработчик могу сказать, что разрабатывать свой функционал для админки — то еще сомнительное удовольствие.

И тем не менее работать с ней нужно. Время от времени появляется необходимость добавить что-то свое. Очень много времени администраторы проводят в формах работы с инфоблоками, и эти формы иногда нужно дорабатывать. Стандартные документированные возможности по кастомизации формы редактирования элемента инфоблока ограничены следующими способами:

  • можно написать свой тип свойства, тем самым добавив новые визуальные и функциональные возможности для каких-то полей. Ограничений почти нет, все зависит от вашей фантазии и умений. Изменения будут применены к конкретному свойству
  • можно создать php-скрипт, который полностью заменит форму редактирования элемента инфоблока. Путь до такого скрипта задается в настройках инфоблока в опции «Файл с формой редактирования элемента». Чтобы создать этот скрипт, придется скопипастить очень много кода из ядра, и если вам нужно кастомизировать форму ради какой-то мелочи, это может быть неразумно
  • UPD. Спасибо комментарию от Алексея. В конце концов есть стандартный редактор форм админки, про который я совсем забыл. Этот редактор позволяет сгруппировать имеющиеся свойства и поля инфоблока (а также любой другой формы в админке, если она разработана по фен-шую) в разные вкладки, можно создавать новые, удалять существующие и т.д. Но это все же способ именно группировки, а не создания новых вкладок с новым функционалом

Но есть еще один способ.

Обратимся к событиям.

Довольно забавно, но эта возможность существует в битриксе начиная с версии 5.9.0 модуля инфоблоков 🙂 т.е. очень давно — вот пруф. Это событие OnAdminIBlockElementEdit. Событие относится к главному модулю и в документации его прямой страницы нет. Оно упоминается лишь вскользь в статье про метод \CAdminTabControl::AddTabs. Также это событие всплывало пару раз на форуме битрикса, но вообще в интернете мало инфы про него. Убежден, что с ним знакомы далеко не все, поэтому оно удостоилось отдельного упоминания в моем блоге.

С помощью этого события вы можете легко добавить к любому инфоблоку собственную вкладку и разместить там любое содержимое.

Как?

Для того, чтобы осуществить задуманное, нужно зарегистрировать обработчик события OnAdminIBlockElementEdit главного модуля. Это событие обрабатывается классом \CAdminTabEngine. Ожидается, что один обработчик призван добавить группу из нескольких табов для формы редактирования элемента.

Этот обработчик должен вернуть массив следующей структуры:

  • TABSET — это строковое некириллическое название группы табов. Используется битриксом для того, чтобы отличать друг от друга обработчики табов
  • Check — callable, который будет вызван перед показом таба. Он может обработать какую-то ситуацию, чтобы запретить показ таба. Туда будут переданы те аргументы, которые были использованы при создании экземпляра класса \CAdminTabEngine
  • Action — callable, который будет вызван при выполнении какого-то действия над формой, к которой прицеплена группа табов. Например — перед сохранением элемента инфоблока. Туда будут переданы те же аргументы, что и в Check
  • GetTabs — callable, который вернет массив с описанием всех табов, которые надо добавить с помощью этого набора табов. Должен содержать массив из элементов следующей структуры:
    • DIV — id для дива в верстке
    • SORT — порядковый номер таба
    • TAB — название таба
    • TITLE — заголовок таба (текст на нем)

    Сюда будет передан аргумент с данными о редактируемом элементе

  • ShowTab — callable, который должен сформировать html содержимое таба. Сюда битрикс передаст идентификатор таба, информацию о редактируемом элементе и данные формы редактирования.

Короче говоря — создаете класс, который описывает ваш набор табов. Добавляете ему методы, которые будут отвечать за выполнение каждой операции, реализуете эти методы, прицепляете класс на событие и вуаля — все работает.

Пример

Создадим класс с описанием табсета:

Мы у себя в компании накатали небольшой абстрактный класс и интерфейс, которые помогают реализовывать подобные табы, но это не обязательно, можно и без них обойтись.

Зарегистрируем методы этого класса в обработчике событий примерно таким способом:

И … все … 🙂 будет создана вкладка, а содержимое из метода showTabContent попадет во вкладку.

Еще больше табов

Это событие добавления таба к элементу — не единственное. Есть и другие — OnAdminIBlockSectionEdit (в раздел тоже можно добавить, ага), OnAdminSaleOrderView. Чтобы найти все, ищите конструктор \CAdminTabControl в ядре.

Кроме этого, на примерно таком же движке работают события кастомизации формы заказа в обновленном модуле магазина, что уже описано в курсе разработчика более подробно.

Кстати

Вы обратили внимание, что на скрине с кастомным табом отсутствует вкладка «Реклама»? Она добавляется тоже с помощью события OnAdminIBlockElementEdit, и нет никакого труда ее отрубить. Данная вкладка регистрируется модулем seo в инсталляторе и прописывает регистрацию события в БД. Можно удалить запись об этом событии из БД также, как это прописано в деинсталляторе модуля seo:

Либо с помощью эвент-менеджера найти это событие в списке всех событий данного типа и отрубить его с помощью метода \Bitrix\Main\EventManager::removeEventHandler.

Дерзайте! 😉