Случилась необходимость написать свою функцию для шаблонизатора SEO-свойств инфоблока. И по задаче нужно было, чтобы функция могла работать не только с приходящими значениями свойств и полей, но и с другими данными элемента.
Нужно сделать нечто вроде этого:
Если в методе onPrepareParameters посмотреть значение переменной $entity, то можно увидеть нечто вроде такого:
Мягко говоря, информации немного, но нужная нам, ID элемента, присутствует, и по ней мы уже можем вытянуть все необходимое.
Пока я копался в ядре, я сделал для себя несколько выводов:
1. Функция вызывается для разных типов $entity, по классу объекта можно получить представление, с чем мы в текущий момент работаем - элемент, раздел, инфоблок.
2. Можно без проблем вытянуть ID объекта через $entity->getId(). В случае Entity\Element это ID элемента, для Entity\Section это ID раздела, ну а для Entity\Iblock, как вы уже догадались - это ID инфоблока.
3. Жаль, что приходится много копаться в ядре, чтобы потом еще столько же делать эксперименты, чтобы получить хоть какой-то результат. Катастрофически не хватает примеров.
Нужно сделать нечто вроде этого:
namespace Custom\Iproperty\Template; // Создает функцию-обработчик для SEO-шаблонов инфоблока // {=namedValue "PROPERTY_CODE"} - выведет название свойства с кодом PROPERTY_CODE, двоеточие и значение свойства. Например, Ширина: 120см class NamedValue extends \Bitrix\Iblock\Template\Functions\FunctionBase { // Метод добавляет нашу функцию в реестр доступных public static function eventHandler($event) { $parameters = $event->getParameters(); // Обратите внимание, что название функции приходит в нижнем регистре $functionName = $parameters[0]; if ($functionName === "namedvalue") { //обработчик должен вернуть SUCCESS и имя класса //который будет отвечать за вычисления return new \Bitrix\Main\EventResult( \Bitrix\Main\EventResult::SUCCESS, "Custom\IpropertyFunction\NamedValue" ); } } // Метод позволяет обработать параметры - а заодно перехватить данные Entity, в данном случае это может быть инфоблок, раздел или элемент public function onPrepareParameters(\Bitrix\Iblock\Template\Entity\Base $entity, array $parameters) { $arguments = array(); // Перехватываем id элемента, чтобы можно было обращаться к его свойствам $this->data['id'] = $entity->getId(); /** @var \Bitrix\Iblock\Template\NodeBase $parameter */ foreach ($parameters as $parameter) { $arguments[] = $parameter->process($entity); } return $arguments; } //собственно функция выполняющая "магию" public function calculate($parameters) { // Получаем все свойства инфоблока $el = \CIBlockElement::getByID($this->data['id']); $props = $el->getNextElement()->getProperties(); // Получаем параметры для нашей функции $result = $this->parametersToArray($parameters); $code = $result[0]; $property = $props[$code]; if( array_key_exists($code, $props) ) return "{$property['NAME']}: {$property['VALUE']}"; else return ''; } } |
Если в методе onPrepareParameters посмотреть значение переменной $entity, то можно увидеть нечто вроде такого:
object(Bitrix\Iblock\Template\Entity\Element)[327] protected 'property' => null protected 'iblock' => null protected 'parent' => null protected 'sections' => null protected 'catalog' => null protected 'id' => int 3 protected 'fields' => null protected 'fieldMap' => array (size=7) 'name' => string 'NAME' (length=4) 'previewtext' => string 'PREVIEW_TEXT' (length=12) 'detailtext' => string 'DETAIL_TEXT' (length=11) 'code' => string 'CODE' (length=4) 'ID' => string 'ID' (length=2) 'IBLOCK_ID' => string 'IBLOCK_ID' (length=9) 'IBLOCK_SECTION_ID' => string 'IBLOCK_SECTION_ID' (length=17) |
Пока я копался в ядре, я сделал для себя несколько выводов:
1. Функция вызывается для разных типов $entity, по классу объекта можно получить представление, с чем мы в текущий момент работаем - элемент, раздел, инфоблок.
2. Можно без проблем вытянуть ID объекта через $entity->getId(). В случае Entity\Element это ID элемента, для Entity\Section это ID раздела, ну а для Entity\Iblock, как вы уже догадались - это ID инфоблока.
3. Жаль, что приходится много копаться в ядре, чтобы потом еще столько же делать эксперименты, чтобы получить хоть какой-то результат. Катастрофически не хватает примеров.