Wiki Bitrix

Кастомный тип свойства инфоблока

Как быстро сделать кастомный тип свойства в Битриксе.

Заготовка

Необходимо в файле init.php создать класс и обработчик который будет его вызывать:

/bitrix/php_interface/init.php
AddEventHandler("iblock", "OnIBlockPropertyBuildList", array("CIBlockNewProperty", "GetUserTypeDescription"));
 
class CIBlockNewProperty
{
  public function GetUserTypeDescription()
  {
    return array(
      "PROPERTY_TYPE"        => "S", #-----один из стандартных типов
      "USER_TYPE"            => "MYIDCODE", #-----идентификатор типа свойства
      "DESCRIPTION"          => "Название свойства",
      "GetPropertyFieldHtml" => array("CIBlockNewProperty", "GetPropertyFieldHtml"),
    );
  }
 
  /*--------- вывод поля свойства на странице редактирования ---------*/
  public function GetPropertyFieldHtml($arProperty, $value, $strHTMLControlName)
  {
    return '<input type="text" name="'.$strHTMLControlName["VALUE"].'" value="'.$value['VALUE'].'"> <input type="text" name="'.$strHTMLControlName["DESCRIPTION"].'" value="'.$value['DESCRIPTION'].'">';
  }
}

После этого в вашем списке свойств появится новое:

Теперь можно эту заготовку доработать до нужного вида.

Базовые типы свойств

Все пользовательские свойства имеют в основе какой-то базовый тип и отличаются, как правило, формой работы в админской части. К примеру, свойства дата имеет базовый тип Число. Вот список этих основных типов:

  • Строка - S
  • Число - N
  • Список - L
  • Файл - F
  • Привязка к элементам - E
  • Привязка к разделам - G

Хранение данных в базе

Значение каждого свойства может иметь две составляющие - это VALUE и DESCRIPTION.

Функция вывода в форме редактирования элемента

В описанном примере это GetPropertyFieldHtml и у нее три аргумента:

  • $arProperty - массив данных по этому типу свойств
  • $value - значение хранимое в базе данных для конкретного элемента инфоблока
  • $strHTMLControlName - массив с контрольными данными для формы на странице редактирования элемента инфоблока

Кейс: свойство время

Тут два пути, зависит от деталей задачи.

1. Выводить свойство как строку с маской 00:00 (может с секундами 00:00:00)
2. Выводить поле с календарем, как при вводе даты

В обоих случаях перед сохранением и выводом добавляете свои обработчики. Пример функции выше с обработчиками будет такой:

public function GetUserTypeDescription()
{
  return array(
    "PROPERTY_TYPE"        => "S", #-----один из стандартных типов
    "USER_TYPE"            => "MYIDCODE", #-----идентификатор типа свойства
    "DESCRIPTION"          => "Название свойства",
    "GetPropertyFieldHtml" => array("CIBlockNewProperty", "GetPropertyFieldHtml"),
    "ConvertToDB" => array(__CLASS__, "ConvertToDB"), #-----функция конвертирования данных перед сохранением в базу данных
    "ConvertFromDB" => array(__CLASS__, "ConvertFromDB"), #-----функция конвертации после извлечения значения из базы данных и перед показом в форме редактирования элемента инфоблока
  );
}

Как логично вытекает эти функции надо добавить в наш класс. Если брать пример с календарем, то можно так:

public static function ConvertToDB($arProperty, $arValue)
{
  if (strlen($arValue['VALUE'])) {
    $time = new \Bitrix\Main\Type\DateTime($arValue['VALUE']);
    $arValue['VALUE'] = $time->getTimestamp();
  }
  return $arValue;
}
 
public static function ConvertFromDB($arProperty, $arValue)
{
  if ($arValue['VALUE'] && defined('ADMIN_SECTION') && ADMIN_SECTION===true) {//мы так же проверяем, чтобы форматировалось только в админке
    $time = Bitrix\Main\Type\DateTime::createFromTimestamp($arValue['VALUE']);
    $arValue['VALUE'] = $time;
  }
  return $arValue;
}

И последнее, это вывод поля с календарем на странице редактирования. Берем стандартный Битриксовский:

public function GetPropertyHtml($arProperty, $value, $strHTMLControlName)
  {
    $ret = '<div class="adm-input-wrap adm-input-wrap-calendar"><input class="adm-input adm-input-calendar" type="text" name="'.$strHTMLControlName["VALUE"].'" size="23" value="'.$value['VALUE'].'">';
    $ret .= '<span class="adm-calendar-icon" title="Нажмите для выбора даты" onclick="BX.calendar({node:this, field:\''.$strHTMLControlName["VALUE"].'\', form: \'\', bTime: true, bHideTime: false});"></span>';
    $ret .= '</div>';
    return $ret;
  }

Источник