Appearance
D7 в инфоблоках. Элементы.
Содержание
- Устаревший подход
- Получение элементов D7. Классический подход.
- D7 в инфоблоках. Подход realweb.api
Устаревший подход
\CIBlockElement::GetList
Много лет для получения элементов, разделов и т.п. Bitrix использовал классические методы `GetList` классов `CIBlockElement`, `CIBlockSection` и т.п.Постараемся решить задачу
Получить список активных элементов инфоблока. Для выборки потребуются поля
NAMECODEPREVIEW_PICTUREи путь до файла- Текстовое свойство
DESCRIPTION- Свойство типа список
TYPE_ID- Множественное свойство типа файл
GALLERYс путями до файлов- Название родительского раздела
- Количество активных элементов в родительском разделе
- Детальную ссылку элемента, состоящую из "пути" символьных кодов всех разделов + символьный код элемента
Стандартный запрос на получение элементов инфоблока с его свойствами.
php
$rsResult = \CIBlockElement::GetList(
array('SORT'=>"ASC"), //Сортировка
array("IBLOCK_ID"=>IBLOCK_CATALOG_CATALOG,'ACTIVE'=>'Y'),//Фильтр
false, //Группировка
false, //Навигация, не работает с множественными свойствами НЕ в Инфоблоках 2.0
array('ID','NAME','CODE','PREVIEW_PICTURE','DETAIL_PAGE_URL','PROPERTY_DESCRIPTION','PROPERTY_GALLERY')// Поля выбора
);Вызов данного метода сформирует следующий запрос:
mysql
SELECT BE.ID as ID,
BE.NAME as NAME,
BE.CODE as CODE,
BE.PREVIEW_PICTURE as PREVIEW_PICTURE,
FPS0.PROPERTY_119 as PROPERTY_DESCRIPTION_VALUE,
concat(BE.ID, ':', 119) as PROPERTY_DESCRIPTION_VALUE_ID,
FPS0.PROPERTY_127 as PROPERTY_GALLERY_VALUE,
FPS0.DESCRIPTION_127 as PROPERTY_GALLERY_DESCRIPTION,
BE.SORT as SORT
FROM b_iblock B //Таблица инфоблока лишняя
INNER JOIN b_lang L
ON B.LID=L.LID //Таблица языка лишняя
INNER JOIN b_iblock_element BE ON BE.IBLOCK_ID = B.ID
INNER JOIN b_iblock_element_prop_s6 FPS0 ON FPS0.IBLOCK_ELEMENT_ID = BE.ID
WHERE 1=1
AND (
((((BE.IBLOCK_ID = '6'))))
AND ((((BE.ACTIVE='Y'))))
)
AND (((BE.WF_STATUS_ID=1
AND BE.WF_PARENT_ELEMENT_ID IS NULL))) //Лишнее
ORDER BY BE.SORT ascКак видно из запроса, по умолчанию система формирует много лишних ненужных join и условий. (При добавлении пагинации и групировок запрос еще больше усложняется.)
В результате запроса получим массивы с искомыми полями. При этом для множественного свойства PROPERTY_GALLERY, поля PREVIEW_PICTURE все еще необходимо получить пути до файлов, а для поля DETAIL_PAGE_URL для каждого элемента будут производится отдельные запросы в цикле. Название родительского раздела и подсчет количества элементов в этом разделе также потребует вызова отдельных запросов.
Задача будет решаться в несколько этапов, любое изменение в ТЗ добавляет сложности и увеличивает количество запросов.
Альтернативой этому подходу является использование запросов D7 с Инфоблоками 2.0
Инфоблоки 2.0 - инфоблоки, у которых значения свойств элементов хранятся в отдельной таблице. Подробнее ->
Получение элементов D7. Классический подход.
Для выполнения такой же задачи обратимся к ORM классу таблицы элементов \Bitrix\Iblock\ElementTable. Данный класс расширяет класс \Bitrix\Main\ORM\Data\DataManager и имеет метод query, который возвращает экземпляр объекта Bitrix\Main\ORM\Query\Query
php
$obQuery = \Bitrix\Iblock\ElementTable::query();Данный объект запроса \Bitrix\Main\ORM\Query\Query имеет следующие наиболее используемые методы:
getQuery- возвращает итоговый запрос в виде строкиsetSelect- устанавливает поля для выборкиaddSelect- добавление поля в выборкуsetOrder- установка сортировкиaddOrder- добавление сортировкиsetGroup- установка группировкиaddGroup- добавление группировкиwhere- установка фильтраwhereIn- установка фильтраINwhereNotIn- установка фильтраNOT INwhereLike- установка фильтраLIKEwhereNull- установка фильтраWHERE NULLwhereNotNull- установка фильтраWHERE NOT NULLsetLimit- установка ограничения выборкиsetOffset- установки смещения ограничения выборкиexec- выполнение запросаregisterRuntimeField- добавление в запрос нового поля (Например, присоединение другой таблицы или вычисляемое поле MAX, COUNT и т.п.)
Основной запрос на получение элементов
Сформируем простой запрос на получение элементов
php
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID","=",IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true);Метод where может принимать разное количество и разные типы параметров
Три параметра
- Название поля
- Условие (=, >, < , >=, <=, !=)
- Значение
Два параметра
- Название поля булевого типа. В терминах битрикса значение такого поля хранится в БД в виде строки
Y/N - Значение - булево
true/false
Один параметр
- Вложенное условие
\Bitrix\Main\ORM\Query\Query::filter(). Подробнее
Все три вызова идентичны и приведут к одному результату:
php
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true);
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE","=","Y");
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where((
\Bitrix\Main\ORM\Query\Query::filter()
->logic(ConditionTree::LOGIC_AND)
->where('ACTIVE',true)
));mysql
SELECT
`iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`
FROM `b_iblock_element` `iblock_element`
WHERE `iblock_element`.`IBLOCK_ID` = 6 AND `iblock_element`.`ACTIVE` = 'Y'
php
$rsResult = $obQuery->exec();
while ($arRow = $rsResult->fetch()) {
//какие-то действия с массивом
}Результат выборки:
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
]registerRuntimeField
php
public function registerRuntimeField($name, $fieldInfo = null)$name- название поля (устаревшее)$fieldInfo- описание поля - экземпляр класса\Bitrix\Main\ORM\Fields\Field
В качестве первого аргумента можно сразу подать описание поля $fieldInfo
Зачастую, в качестве $fieldInfo подается экземпляр 1одно из следующих классов:
\Bitrix\Main\ORM\Fields\Relations\Reference- присоединение таблицы\Bitrix\Main\ORM\Fields\ExpressionField- вычисляемое поле (MAX, COUNT и т.п.)
Добавление полей в запрос
Название родительского раздела
Для получения названия родительского раздела присоединим таблицу с разделами, связанной с элементами по полю IBLOCK_SECTION_ID (выбирать само поле нам не потребуется).
Для этого воспользуемся классом \Bitrix\Main\ORM\Fields\Relations\Reference
Данный класс присоединяет к запросу любое поле из любой таблицы. В задаче такими полями могут быть: DESCRIPTION, путь до файла PREVIEW_PICTURE, название родительского раздела, Количество элементов в родительском разделе
php
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"SECTION", //Название присоединения
\Bitrix\Iblock\SectionTable::class, //Таблица разделов
\Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_SECTION_ID', 'ref.ID') //Условие присоединения
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT) //Тип присоединения
)
->addSelect("SECTION.NAME","SECTION_NAME") //Добавления названия раздела в выборку
;В условии присоединения используются алиасы
this- текущая таблица выборки, т.е.\Bitrix\Iblock\ElementTableref- таблица присоединения, т.е.\Bitrix\Iblock\SectionTableМетод
addSelectможет принимать один или 2 аргумента. Второй аргумент играет роль "алиаса" и в запросе подставляется вSELECT #FIELD_NAME# as #ALIAS#
mysql
SELECT
`iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
`iblock_element_section`.`NAME` AS `SECTION_NAME`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_section` `iblock_element_section` ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_section`.`ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6 AND `iblock_element`.`ACTIVE` = 'Y'
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"SECTION_NAME" => string(14) "Шампуни"
]Путь к файлу
Для "вычисления" пути до файла поля PREVIEW_PICTURE воспользуемся классом \Bitrix\Main\ORM\Fields\ExpressionField и MySql функцией CONCAT
php
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PREVIEW_PICTURE_FILE",
\Bitrix\Main\FileTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.PREVIEW_PICTURE', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new \Bitrix\Main\ORM\Fields\ExpressionField( //Сразу сформируем путь
"PREVIEW_PICTURE_FILE_SRC", //Название выражения
'CONCAT("/upload/",%s, "/" ,%s)', //Функция MySql
array('PREVIEW_PICTURE_FILE.SUBDIR', 'PREVIEW_PICTURE_FILE.FILE_NAME') //Значения шаблона подстановки
)
)
->addSelect("PREVIEW_PICTURE_FILE_SRC");В функции MySql допускается использование шаблонов подстановки %s, значения которых устанавливаются в массиве 3го аргумента по порядку использования.
mysql
SELECT
`iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
CONCAT("/upload/",`iblock_element_preview_picture_file`.`SUBDIR`, "/" ,`iblock_element_preview_picture_file`.`FILE_NAME`) AS `PREVIEW_PICTURE_FILE_SRC`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_file` `iblock_element_preview_picture_file` ON `iblock_element`.`PREVIEW_PICTURE` = `iblock_element_preview_picture_file`.`ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6 AND `iblock_element`.`ACTIVE` = 'Y'
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"PREVIEW_PICTURE_FILE_SRC" => string(55) "/upload/iblock/a41/ug1kpe849g5gh11uvy1gflmyossdvncr.png"
]Количество элементов
Для вычисления количества элементов также воспользуемся классом \Bitrix\Main\ORM\Fields\ExpressionField и функцией MySql COUNT Если мы добавим запрос на подсчет элементов в запрос напрямую, система добавит в запрос группировку по всем полям выборки. Для того чтобы этого избежать воспользуемся подзапросом
php
$obSubQuery = \Bitrix\Iblock\ElementTable::query()
->setSelect(array('COUNT_ELEMENTS'))
->where("IBLOCK_SECTION_ID", '=', new SqlExpression('%s'))
->where('ACTIVE', '=', 'Y')
->registerRuntimeField(
new ExpressionField('COUNT_ELEMENTS', 'COUNT(%s)', array('ID'))
)
->setTableAliasPostfix('_count');
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
new ExpressionField(
"SECTION_ELEMENTS_COUNT",
'(' . $obSubQuery->getQuery() . ')',
array('IBLOCK_SECTION_ID')
)
)
->addSelect("SECTION_ELEMENTS_COUNT");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
(SELECT COUNT(`iblock_element_count`.`ID`) AS `COUNT_ELEMENTS`
FROM `b_iblock_element` `iblock_element_count`
WHERE `iblock_element_count`.`IBLOCK_SECTION_ID` = `iblock_element`.`IBLOCK_SECTION_ID`
AND `iblock_element_count`.`ACTIVE` = 'Y') AS `SECTION_ELEMENTS_COUNT`
FROM `b_iblock_element` `iblock_element`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"SECTION_ELEMENTS_COUNT" => string(1) "2"
]Значения свойств
Так как использование технологии Инфоблоки 2.0 является стандратном необходимо узнать в каких таблицах хранятся значения свойств ИБ. Таких таблиц две - для множественных и немножественных свойств
- b_iblock_element_prop_s, где s означает single - одиночный
- b_iblock_element_prop_m, где m означает multiple - множественный
Создавать отдельный ORM класс для таких таблиц не надо (Как, например, для таблицы элементов или разделов). В Bitrix существует метод формирования ORM сущностей "на лету"
Получение значений одиночных свойств
Для получения нужных свойств скомпилируем объект инфоблока
Для присоединения свойств в настройках инфоблока необходимо указать Символьный код API, который передается в метод
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");После этого появляется возможность добавить нужные свойства
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY",
$obIblockEntity->getDataClass(), //Скомпилированная сущность
\Bitrix\Main\ORM\Query\Join::on('this.ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("PROPERTY.DESCRIPTION.VALUE","DESCRIPTION");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
`iblock_element_property_description`.`PROPERTY_119` AS `DESCRIPTION`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element` `iblock_element_property` ON `iblock_element`.`ID` = `iblock_element_property`.`ID`
INNER JOIN `b_iblock_element_prop_s6` `iblock_element_property_description`
ON `iblock_element_property`.`ID` = `iblock_element_property_description`.`IBLOCK_ELEMENT_ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"DESCRIPTION" => string(20) "от 40 до 90 см"
]Получение значений свойств типа список
Получение значений свойств типа список ничем не отличается от получения обычных свойств. Но необходимо помнить, что значением такого свойства является ID списка значений. Для получения значения присоединим таблицу со списком значений \Bitrix\Iblock\PropertyEnumerationTable
Также напомним, что ID в таблице значений списка автоинкрементный и не зависит от самого свойства, поэтому нужды присоединять таблицу со свойствами
\Bitrix\Iblock\PropertyTableнет необходимости
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY",
$obIblockEntity->getDataClass(), //Скомпилированная сущность
\Bitrix\Main\ORM\Query\Join::on('this.ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY_VALUE",
\Bitrix\Iblock\PropertyEnumerationTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.PROPERTY.TYPE_ID.VALUE', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("PROPERTY_VALUE.VALUE","TYPE_ID_VALUE");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
`iblock_element_property_value`.`VALUE` AS `TYPE_ID_VALUE`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element` `iblock_element_property` ON `iblock_element`.`ID` = `iblock_element_property`.`ID`
INNER JOIN `b_iblock_element_prop_s6` `iblock_element_property_type_id`
ON `iblock_element_property`.`ID` = `iblock_element_property_type_id`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_property_enum` `iblock_element_property_value`
ON `iblock_element_property_type_id`.`PROPERTY_169` = `iblock_element_property_value`.`ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(4)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"TYPE_ID_VALUE" => string(27) "Средства ухода"
]Получение значений множественных свойств
Для получения множественных свойств просто добавим их символьные коды в ранее подготовленный запрос. Т.к. GALLERY это файл, вместе с этим получим и пути до файлов
Необходимо помнить, что добавление множественных свойств в запрос увеличит количество выбираемых строк на количество значений множественного свойства.
Именно по этой причине не рекомендуется выбирать множественные свойства в основном запросе. (Не сработает пагинация) О способах выборки множественных свойств см. отдельно
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY",
$obIblockEntity->getDataClass(), //Скомпилированная сущнсость
\Bitrix\Main\ORM\Query\Join::on('this.ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("PROPERTY.GALLERY.ID","GALLERY_ID")
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"GALLERY_FILE",
\Bitrix\Main\FileTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.GALLERY_ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new \Bitrix\Main\ORM\Fields\ExpressionField( //Сразу сформируем путь
"GALLERY_FILE_SRC", //Название поля
'CONCAT("/upload/",%s, "/" ,%s)', //Функция MySql
array('GALLERY_FILE.SUBDIR', 'GALLERY_FILE.FILE_NAME') //Значения шаблона подстановки
)
)
->addSelect("GALLERY_FILE_SRC");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
`iblock_element_property_iblock_property127_src_element`.`ID` AS `GALLERY_ID`,
CONCAT("/upload/", `iblock_element_gallery_file`.`SUBDIR`, "/",
`iblock_element_gallery_file`.`FILE_NAME`) AS `GALLERY_FILE_SRC`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element` `iblock_element_property` ON `iblock_element`.`ID` = `iblock_element_property`.`ID`
LEFT JOIN `b_iblock_element_prop_m6` `iblock_element_property_iblock_property127_src_element`
ON `iblock_element_property_iblock_property127_src_element`.`IBLOCK_ELEMENT_ID` =
`iblock_element_property`.`ID` AND
`iblock_element_property_iblock_property127_src_element`.`IBLOCK_PROPERTY_ID` = 127
LEFT JOIN `b_file` `iblock_element_gallery_file`
ON `iblock_element_property_iblock_property127_src_element`.`ID` = `iblock_element_gallery_file`.`ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(5)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"GALLERY_ID" => string(3) "499"
"GALLERY_FILE_SRC" => string(55) "/upload/iblock/548/0chbm3f878bfrhbzrcrlze89059qk8lo.jpg"
]
array(5)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"GALLERY_ID" => string(3) "500"
"GALLERY_FILE_SRC" => string(55) "/upload/iblock/91e/38l006p52voljnr7uoe7rv6d39yhwbym.jpg"
]
array(5)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"GALLERY_ID" => string(3) "501"
"GALLERY_FILE_SRC" => string(55) "/upload/iblock/af0/36apvg5kemjhqhnrckplz7j0ezcpg23m.jpg"
]Получение детальной ссылки на товар
Детальная ссылка для товара состоит из "пути" из символьных кодов разделов + символьный код самого элемента.
Получим путь из символьных кодов разделов, используя подзапрос. Также не забудем и про шаблон детальной страницы, который хранится в свойствах инфоблока
php
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PARENT_SECTION",
\Bitrix\Iblock\SectionTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_SECTION_ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new ExpressionField(
'SECTION_CODE_PATH',
'(' . (
(\Bitrix\Iblock\SectionTable::query())
->setSelect(array('SECTION_CODE_PATH'))
->where('LEFT_MARGIN', '<=', new SqlExpression('%s'))
->where('RIGHT_MARGIN', '>=', new SqlExpression('%s'))
->where('IBLOCK_ID', '=', new SqlExpression('%s'))
->registerRuntimeField(
new ExpressionField(
'SECTION_CODE_PATH',
'GROUP_CONCAT(CODE ORDER BY LEFT_MARGIN ASC SEPARATOR \'/\')'
)
)
->setTableAliasPostfix('_groups')
)->getQuery() . ')',
array(
'PARENT_SECTION.LEFT_MARGIN',
'PARENT_SECTION.RIGHT_MARGIN',
'PARENT_SECTION.IBLOCK_ID',
)
)
)
->addSelect('SECTION_CODE_PATH')
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"IBLOCK",
\Bitrix\Iblock\IblockTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("IBLOCK.DETAIL_PAGE_URL", "DETAIL_PAGE_URL_TEMPLATE");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
(SELECT GROUP_CONCAT(CODE ORDER BY LEFT_MARGIN ASC SEPARATOR '/') AS `SECTION_CODE_PATH`
FROM `b_iblock_section` `iblock_section_groups`
WHERE `iblock_section_groups`.`LEFT_MARGIN` <= `iblock_element_parent_section`.`LEFT_MARGIN`
AND `iblock_section_groups`.`RIGHT_MARGIN` >= `iblock_element_parent_section`.`RIGHT_MARGIN`
AND `iblock_section_groups`.`IBLOCK_ID` = `iblock_element_parent_section`.`IBLOCK_ID`) AS `SECTION_CODE_PATH`,
`iblock_element_iblock`.`DETAIL_PAGE_URL` AS `DETAIL_PAGE_URL_TEMPLATE`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_section` `iblock_element_parent_section`
ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_parent_section`.`ID`
LEFT JOIN `b_iblock` `iblock_element_iblock` ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(5)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"SECTION_CODE_PATH" => string(29) "sredstva-dlya-ukhoda/shampuni"
"DETAIL_PAGE_URL_TEMPLATE" => string(39) "#SITE_DIR#/catalog/#SECTION_CODE_PATH#/"
]Вообще говоря, необходимости отдельно подключать таблицы
\Bitrix\Iblock\SectionTableи\Bitrix\Iblock\IblockTableнет необходимости, они подключаются автоматически, если использовать поляIBLOCK_SECTION.*иIBLOCK.*см. метод \Bitrix\Iblock\ElementTable::getMap()
Итоговый запрос
Соберем итоговый запрос вместе
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");
$obSubQuery = \Bitrix\Iblock\ElementTable::query()
->setSelect(array('COUNT_ELEMENTS'))
->where("IBLOCK_SECTION_ID", '=', new SqlExpression('%s'))
->where('ACTIVE', '=', 'Y')
->registerRuntimeField(
new ExpressionField('COUNT_ELEMENTS', 'COUNT(%s)', array('ID'))
)
->setTableAliasPostfix('_count');
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true)
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"SECTION", //Название присоединения
\Bitrix\Iblock\SectionTable::class, //Таблица разделов
\Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_SECTION_ID', 'ref.ID') //Условие присоединения
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT) //Тип присоединения
)
->addSelect("SECTION.NAME","SECTION_NAME") //Добавления названия раздела в выборку
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PREVIEW_PICTURE_FILE",
\Bitrix\Main\FileTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.PREVIEW_PICTURE', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new \Bitrix\Main\ORM\Fields\ExpressionField( //Сразу сформируем путь
"PREVIEW_PICTURE_FILE_SRC", //Название выражения
'CONCAT("/upload/",%s, "/" ,%s)', //Функция MySql
array('PREVIEW_PICTURE_FILE.SUBDIR', 'PREVIEW_PICTURE_FILE.FILE_NAME') //Значения шаблона подстановки
)
)
->addSelect("PREVIEW_PICTURE_FILE_SRC")
->registerRuntimeField(
new ExpressionField(
"SECTION_ELEMENTS_COUNT",
'(' . $obSubQuery->getQuery() . ')',
array('IBLOCK_SECTION_ID')
)
)
->addSelect("SECTION_ELEMENTS_COUNT")
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY",
$obIblockEntity->getDataClass(), //Скомпилированная сущность
\Bitrix\Main\ORM\Query\Join::on('this.ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("PROPERTY.DESCRIPTION.VALUE","DESCRIPTION")
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"PROPERTY_VALUE",
\Bitrix\Iblock\PropertyEnumerationTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.PROPERTY.TYPE_ID.VALUE', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("PROPERTY_VALUE.VALUE","TYPE_ID_VALUE")
->addSelect("PROPERTY.GALLERY.ID","GALLERY_ID")
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"GALLERY_FILE",
\Bitrix\Main\FileTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.GALLERY_ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new \Bitrix\Main\ORM\Fields\ExpressionField( //Сразу сформируем путь
"GALLERY_FILE_SRC", //Название поля
'CONCAT("/upload/",%s, "/" ,%s)', //Функция MySql
array('GALLERY_FILE.SUBDIR', 'GALLERY_FILE.FILE_NAME') //Значения шаблона подстановки
)
)
->addSelect("GALLERY_FILE_SRC")
//Второй раз можно не присоединять, уже присоединили выше SECTION
//->registerRuntimeField(
// (new \Bitrix\Main\ORM\Fields\Relations\Reference(
// "PARENT_SECTION",
// \Bitrix\Iblock\SectionTable::class,
// \Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_SECTION_ID', 'ref.ID')
// ))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
// )
->registerRuntimeField(
new ExpressionField(
'SECTION_CODE_PATH',
'(' . (
(\Bitrix\Iblock\SectionTable::query())
->setSelect(array('SECTION_CODE_PATH'))
->where('LEFT_MARGIN', '<=', new SqlExpression('%s'))
->where('RIGHT_MARGIN', '>=', new SqlExpression('%s'))
->where('IBLOCK_ID', '=', new SqlExpression('%s'))
->registerRuntimeField(
new ExpressionField(
'SECTION_CODE_PATH',
'GROUP_CONCAT(CODE ORDER BY LEFT_MARGIN ASC SEPARATOR \'/\')'
)
)
->setTableAliasPostfix('_groups')
)->getQuery() . ')',
array(
'SECTION.LEFT_MARGIN',
'SECTION.RIGHT_MARGIN',
'SECTION.IBLOCK_ID',
)
)
)
->addSelect('SECTION_CODE_PATH')
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"IBLOCK",
\Bitrix\Iblock\IblockTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.IBLOCK_ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->addSelect("IBLOCK.DETAIL_PAGE_URL", "DETAIL_PAGE_URL_TEMPLATE");mysql
SELECT `iblock_element`.`CODE` AS `CODE`,
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`PREVIEW_PICTURE` AS `PREVIEW_PICTURE`,
`iblock_element_section`.`NAME` AS `SECTION_NAME`,
CONCAT("/upload/", `iblock_element_preview_picture_file`.`SUBDIR`, "/",
`iblock_element_preview_picture_file`.`FILE_NAME`) AS `PREVIEW_PICTURE_FILE_SRC`,
(SELECT COUNT(`iblock_element_count`.`ID`) AS `COUNT_ELEMENTS`
FROM `b_iblock_element` `iblock_element_count`
WHERE `iblock_element_count`.`IBLOCK_SECTION_ID` = `iblock_element`.`IBLOCK_SECTION_ID`
AND `iblock_element_count`.`ACTIVE` = 'Y') AS `SECTION_ELEMENTS_COUNT`,
`iblock_element_property_description`.`PROPERTY_119` AS `DESCRIPTION`,
`iblock_element_property_value`.`VALUE` AS `TYPE_ID_VALUE`,
`iblock_element_property_iblock_property127_src_element`.`ID` AS `GALLERY_ID`,
CONCAT("/upload/", `iblock_element_gallery_file`.`SUBDIR`, "/",
`iblock_element_gallery_file`.`FILE_NAME`) AS `GALLERY_FILE_SRC`,
(SELECT GROUP_CONCAT(CODE ORDER BY LEFT_MARGIN ASC SEPARATOR '/') AS `SECTION_CODE_PATH`
FROM `b_iblock_section` `iblock_section_groups`
WHERE `iblock_section_groups`.`LEFT_MARGIN` <= `iblock_element_section`.`LEFT_MARGIN`
AND `iblock_section_groups`.`RIGHT_MARGIN` >= `iblock_element_section`.`RIGHT_MARGIN`
AND `iblock_section_groups`.`IBLOCK_ID` =
`iblock_element_section`.`IBLOCK_ID`) AS `SECTION_CODE_PATH`,
`iblock_element_iblock`.`DETAIL_PAGE_URL` AS `DETAIL_PAGE_URL_TEMPLATE`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_section` `iblock_element_section`
ON `iblock_element`.`IBLOCK_SECTION_ID` = `iblock_element_section`.`ID`
LEFT JOIN `b_file` `iblock_element_preview_picture_file`
ON `iblock_element`.`PREVIEW_PICTURE` = `iblock_element_preview_picture_file`.`ID`
LEFT JOIN `b_iblock_element` `iblock_element_property` ON `iblock_element`.`ID` = `iblock_element_property`.`ID`
INNER JOIN `b_iblock_element_prop_s6` `iblock_element_property_type_id`
ON `iblock_element_property`.`ID` = `iblock_element_property_type_id`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_property_enum` `iblock_element_property_value`
ON `iblock_element_property_type_id`.`PROPERTY_169` = `iblock_element_property_value`.`ID`
LEFT JOIN `b_iblock_element_prop_m6` `iblock_element_property_iblock_property127_src_element`
ON `iblock_element_property_iblock_property127_src_element`.`IBLOCK_ELEMENT_ID` =
`iblock_element_property`.`ID` AND
`iblock_element_property_iblock_property127_src_element`.`IBLOCK_PROPERTY_ID` = 127
LEFT JOIN `b_file` `iblock_element_gallery_file`
ON `iblock_element_property_iblock_property127_src_element`.`ID` = `iblock_element_gallery_file`.`ID`
LEFT JOIN `b_iblock` `iblock_element_iblock` ON `iblock_element`.`IBLOCK_ID` = `iblock_element_iblock`.`ID`
INNER JOIN `b_iblock_element_prop_s6` `iblock_element_property_description`
ON `iblock_element_property`.`ID` = `iblock_element_property_description`.`IBLOCK_ELEMENT_ID`
WHERE `iblock_element`.`IBLOCK_ID` = 6
AND `iblock_element`.`ACTIVE` = 'Y'
php
array(12)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"SECTION_NAME" => string(14) "Шампуни"
"PREVIEW_PICTURE_FILE_SRC" => string(55) "/upload/iblock/a41/ug1kpe849g5gh11uvy1gflmyossdvncr.png"
"SECTION_ELEMENTS_COUNT" => string(1) "2"
"DESCRIPTION" => string(20) "от 40 до 90 см"
"TYPE_ID_VALUE" => string(27) "Средства ухода"
"GALLERY_ID" => string(3) "500"
"GALLERY_FILE_SRC" => string(55) "/upload/iblock/91e/38l006p52voljnr7uoe7rv6d39yhwbym.jpg"
"SECTION_CODE_PATH" => string(29) "sredstva-dlya-ukhoda/shampuni"
"DETAIL_PAGE_URL_TEMPLATE" => string(39) "#SITE_DIR#/catalog/#SECTION_CODE_PATH#/"
]Осталось "собрать" все элементы в один массив
php
$arResult = array();
$rsResult = $obQuery->exec();
while ($arRow = $rsResult->fetch()) {
if (!array_key_exists($arRow['CODE'], $arResult)) {
$arResult[$arRow['CODE']] = array_merge($arRow, array("GALLERY" => array()));
unset($arResult[$arRow['CODE']]['GALLERY_ID'], $arResult[$arRow['CODE']]['GALLERY_FILE_SRC']);
}
if (strlen($arRow['GALLERY_FILE_SRC']) > 0) {
$arResult[$arRow['CODE']]["GALLERY"][] = array(
"ID" => $arRow['GALLERY_ID'],
"SRC" => $arRow['GALLERY_FILE_SRC'],
);
}
}php
array(11)
[
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"PREVIEW_PICTURE" => string(4) "2536"
"SECTION_NAME" => string(14) "Шампуни"
"PREVIEW_PICTURE_FILE_SRC" => string(55) "/upload/iblock/a41/ug1kpe849g5gh11uvy1gflmyossdvncr.png"
"SECTION_ELEMENTS_COUNT" => string(1) "2"
"DESCRIPTION" => string(20) "от 40 до 90 см"
"TYPE_ID_VALUE" => string(27) "Средства ухода"
"SECTION_CODE_PATH" => string(29) "sredstva-dlya-ukhoda/shampuni"
"DETAIL_PAGE_URL_TEMPLATE" => string(39) "#SITE_DIR#/catalog/#SECTION_CODE_PATH#/"
"GALLERY" => array(3)
[
0 => array(2)
[
"ID" => string(3) "499"
"SRC" => string(55) "/upload/iblock/548/0chbm3f878bfrhbzrcrlze89059qk8lo.jpg"
]
1 => array(2)
[
"ID" => string(3) "500"
"SRC" => string(55) "/upload/iblock/91e/38l006p52voljnr7uoe7rv6d39yhwbym.jpg"
]
2 => array(2)
[
"ID" => string(3) "501"
"SRC" => string(55) "/upload/iblock/af0/36apvg5kemjhqhnrckplz7j0ezcpg23m.jpg"
]
]
]Таким образом одним запросом с 10 подзапросам собрали всю интересующую нас информацию.
Альтернативный (рекомендуемый) способ получения значений множественных свойств
Для того чтобы не добавлять лишние строки в выборку и работала пагинация рекомендуется получать значения множественных свойств отдельно.
Для этого добавим в основную выборку ID элемента
php
$obIblockEntity = \Bitrix\Iblock\IblockTable::compileEntity("catalog");
$obQuery = \Bitrix\Iblock\ElementTable::query();
$obQuery
->setSelect(array("ID","CODE", "NAME", "PREVIEW_PICTURE"))
->where("IBLOCK_ID", "=", IBLOCK_CATALOG_CATALOG)
->where("ACTIVE",true);
$arResult = array();
$rsResult = $obQuery->exec();
while ($arRow = $rsResult->fetch()) {
$arRow['GALLERY'] = array();
$arResult[$arRow['ID']] = $arRow;
}Сформируем отдельный запрос на галерею только по тем элементам, которые у нас есть c помощью условия whereIn
php
$obQuery = $obIblockEntity->getDataClass()::query()
->setSelect(array("ID"))
->addSelect("GALLERY.ID", "GALLERY_ID")
->registerRuntimeField(
(new \Bitrix\Main\ORM\Fields\Relations\Reference(
"GALLERY_FILE",
\Bitrix\Main\FileTable::class,
\Bitrix\Main\ORM\Query\Join::on('this.GALLERY.ID', 'ref.ID')
))->configureJoinType(\Bitrix\Main\ORM\Query\Join::TYPE_LEFT)
)
->registerRuntimeField(
new \Bitrix\Main\ORM\Fields\ExpressionField( // Сразу сформируем путь
"GALLERY_FILE_SRC", // Название поля
'CONCAT("/upload/",%s, "/" ,%s)', // Функция MySql
array('GALLERY_FILE.SUBDIR', 'GALLERY_FILE.FILE_NAME') // Значения шаблона подстановки
)
)
->addSelect("GALLERY_FILE_SRC")
->whereIn("ID", array_keys($arResult));mysql
SELECT `iblock_elements_element_catalog`.`ID` AS `ID`,
`iblock_elements_element_catalog_iblock_property127_src_element`.`ID` AS `GALLERY_ID`,
CONCAT("/upload/", `iblock_elements_element_catalog_gallery_file`.`SUBDIR`, "/",
`iblock_elements_element_catalog_gallery_file`.`FILE_NAME`) AS `GALLERY_FILE_SRC`,
`iblock_elements_element_catalog_gallery_file`.`ID` AS `UALIAS_0`
FROM `b_iblock_element` `iblock_elements_element_catalog`
LEFT JOIN `b_iblock_element_prop_m6` `iblock_elements_element_catalog_iblock_property127_src_element`
ON `iblock_elements_element_catalog_iblock_property127_src_element`.`IBLOCK_ELEMENT_ID` =
`iblock_elements_element_catalog`.`ID` AND
`iblock_elements_element_catalog_iblock_property127_src_element`.`IBLOCK_PROPERTY_ID` = 127
LEFT JOIN `b_file` `iblock_elements_element_catalog_gallery_file`
ON `iblock_elements_element_catalog_iblock_property127_src_element`.`ID` =
`iblock_elements_element_catalog_gallery_file`.`ID`
WHERE `iblock_elements_element_catalog`.`ID` IN (6100, 6235, 6320, 6321)
AND `iblock_elements_element_catalog`.`IBLOCK_ID` = 6
php
array(3)
[
"ID" => string(4) "6100"
"GALLERY_ID" => string(3) "496"
"GALLERY_FILE_SRC" => string(55) "/upload/iblock/340/c3lk46y9ebcw2a2vkw2bc46k9a9c6rfd.jpg"
]Остается только добавить данные в нужные элементы
php
$rsResult = $obQuery->exec();
while ($arRow = $rsResult->fetch()) {
$iElementId = $arRow['ID'];
unset($arRow['ID']);
if (strlen($arRow['GALLERY_FILE_SRC']) > 0) {
$arResult[$iElementId][] = $arRow;
}
}\Bitrix\Main\ORM\Query\Query::filter()
Данный класс позволяет сформировать любой подзапрос в текущем запросе. Метод filter возвращает все тот же объект запроса \Bitrix\Main\ORM\Query\Query и с ним можно работать также, как и с основным запросом.
Пример работы с подзапросами показан выше при получении адреса детальной страницы.
D7 в инфоблоках. Подход realweb.api
Несмотря на достигнутый положительный результат, можно заметить, что сформированный запрос достаточно сложен для составления, восприятия и редактирования. В realweb.api реализованы все основные методы выборки, которые облегчают написание и чтение запроса. Перепишем этот запрос, используя ядро realweb.api. Подробнее про работу с элементами инфоблока в realweb.api
Длинна запроса изменяется с ~100 строк до 15
php
$obQuery = \Realweb\Api\Model\Iblock\Element\Table::query()
->setSelect(array(
"ID", "CODE", "NAME",
))
->addSelect("IBLOCK.DETAIL_PAGE_URL","DETAIL_PAGE_URL_TEMPLATE")//Подсоединять таблицу с ИБ не нужно, все произойдет автоматически
->where('IBLOCK_ID', '=', IBLOCK_CATALOG_CATALOG)
->where('ACTIVE',true)
->registerFields(array(
"DESCRIPTION",
), IBLOCK_CATALOG_CATALOG) //Данный метод регистрирует только одиночные свойства
->registerMultiFields(array("GALLERY"),IBLOCK_CATALOG_CATALOG) //Данный метод регистрирует множественные свойства
->registerParentSectionField(IBLOCK_CATALOG_CATALOG) //Добавление полей родительского раздела
->registerSectionCodePath() // Добавление пути символьных кодов раздела для детальной ссылки
->registerPreviewPicture()//Добавление пути к PREVIEW_PICTURE вынесено в отдельный метод
->registerFileField("GALLERY") //Добавление пути к файлу любого свойства или поля
->registerDropdownField("TYPE_ID",IBLOCK_CATALOG_CATALOG) //Добавление свойства типа список
;mysql
SELECT `realweb_api_model_iblock_element_`.`ID` AS `ID`,
`realweb_api_model_iblock_element_`.`CODE` AS `CODE`,
`realweb_api_model_iblock_element_`.`NAME` AS `NAME`,
`realweb_api_model_iblock_element__iblock`.`DETAIL_PAGE_URL` AS `DETAIL_PAGE_URL_TEMPLATE`,
`realweb_api_model_iblock_element__s_props`.`PROPERTY_119` AS `DESCRIPTION`,
`realweb_api_model_iblock_element__gallery_property`.`ID` AS `GALLERY_ID`,
`realweb_api_model_iblock_element__gallery_property`.`VALUE` AS `GALLERY`,
`realweb_api_model_iblock_element_`.`IBLOCK_SECTION_ID` AS `IBLOCK_SECTION_ID`,
`realweb_api_model_iblock_element__iblock_section`.`NAME` AS `IBLOCK_SECTION_NAME`,
`realweb_api_model_iblock_element__iblock_section`.`CODE` AS `IBLOCK_SECTION_CODE`,
`realweb_api_model_iblock_element__iblock_section`.`SORT` AS `IBLOCK_SECTION_SORT`,
(SELECT GROUP_CONCAT(CODE ORDER BY LEFT_MARGIN ASC SEPARATOR '/') AS `SECTION_CODE_PATH`
FROM `b_iblock_section` `realweb_api_model_iblock_section__groups`
WHERE `realweb_api_model_iblock_section__groups`.`LEFT_MARGIN` <=
`realweb_api_model_iblock_element__parent_section`.`LEFT_MARGIN`
AND `realweb_api_model_iblock_section__groups`.`RIGHT_MARGIN` >=
`realweb_api_model_iblock_element__parent_section`.`RIGHT_MARGIN`
AND `realweb_api_model_iblock_section__groups`.`IBLOCK_ID` =
`realweb_api_model_iblock_element__parent_section`.`IBLOCK_ID`) AS `SECTION_CODE_PATH`,
CONCAT("/", "upload", "/", `realweb_api_model_iblock_element__preview_picture_file`.`SUBDIR`, "/",
`realweb_api_model_iblock_element__preview_picture_file`.`FILE_NAME`) AS `PREVIEW_PICTURE_SRC`,
CONCAT("/", "upload", "/", `realweb_api_model_iblock_element__gallery_file`.`SUBDIR`, "/",
`realweb_api_model_iblock_element__gallery_file`.`FILE_NAME`) AS `GALLERY_SRC`,
`realweb_api_model_iblock_element__type_id_property`.`PROPERTY_169` AS `TYPE_ID`,
`realweb_api_model_iblock_element__type_id_enum`.`ID` AS `TYPE_ID_ID`,
`realweb_api_model_iblock_element__type_id_enum`.`PROPERTY_ID` AS `TYPE_ID_PROPERTY_ID`,
`realweb_api_model_iblock_element__type_id_enum`.`VALUE` AS `TYPE_ID_VALUE`,
`realweb_api_model_iblock_element__type_id_enum`.`DEF` AS `TYPE_ID_DEF`,
`realweb_api_model_iblock_element__type_id_enum`.`SORT` AS `TYPE_ID_SORT`,
`realweb_api_model_iblock_element__type_id_enum`.`XML_ID` AS `TYPE_ID_XML_ID`,
`realweb_api_model_iblock_element__type_id_enum`.`TMP_ID` AS `TYPE_ID_TMP_ID`
FROM `b_iblock_element` `realweb_api_model_iblock_element_`
LEFT JOIN `b_iblock_element_prop_s6` `realweb_api_model_iblock_element__s_props`
ON `realweb_api_model_iblock_element_`.`ID` =
`realweb_api_model_iblock_element__s_props`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_element_prop_m6` `realweb_api_model_iblock_element__gallery_property`
ON `realweb_api_model_iblock_element_`.`ID` =
`realweb_api_model_iblock_element__gallery_property`.`IBLOCK_ELEMENT_ID` AND
`realweb_api_model_iblock_element__gallery_property`.`IBLOCK_PROPERTY_ID` = 127
LEFT JOIN `b_iblock_section` `realweb_api_model_iblock_element__iblock_section`
ON `realweb_api_model_iblock_element_`.`IBLOCK_SECTION_ID` =
`realweb_api_model_iblock_element__iblock_section`.`ID`
LEFT JOIN `b_iblock_section` `realweb_api_model_iblock_element__parent_section`
ON `realweb_api_model_iblock_element_`.`IBLOCK_SECTION_ID` =
`realweb_api_model_iblock_element__parent_section`.`ID`
LEFT JOIN `b_file` `realweb_api_model_iblock_element__preview_picture_file`
ON `realweb_api_model_iblock_element_`.`PREVIEW_PICTURE` =
`realweb_api_model_iblock_element__preview_picture_file`.`ID`
LEFT JOIN `b_file` `realweb_api_model_iblock_element__gallery_file`
ON `realweb_api_model_iblock_element__gallery_property`.`VALUE` =
`realweb_api_model_iblock_element__gallery_file`.`ID`
LEFT JOIN `b_iblock_element_prop_s6` `realweb_api_model_iblock_element__type_id_property`
ON `realweb_api_model_iblock_element_`.`ID` =
`realweb_api_model_iblock_element__type_id_property`.`IBLOCK_ELEMENT_ID`
LEFT JOIN `b_iblock_property_enum` `realweb_api_model_iblock_element__type_id_enum`
ON `realweb_api_model_iblock_element__type_id_property`.`PROPERTY_169` =
`realweb_api_model_iblock_element__type_id_enum`.`ID`
LEFT JOIN `b_iblock` `realweb_api_model_iblock_element__iblock`
ON `realweb_api_model_iblock_element_`.`IBLOCK_ID` = `realweb_api_model_iblock_element__iblock`.`ID`
WHERE `realweb_api_model_iblock_element_`.`IBLOCK_ID` = 6
AND `realweb_api_model_iblock_element_`.`ACTIVE` = 'Y'
php
array(21)
[
"ID" => string(4) "6320"
"CODE" => string(38) "tigi-shampun-dlya-povrezhdennykh-volos"
"NAME" => string(62) "TIGI шампунь для поврежденных волос"
"DETAIL_PAGE_URL_TEMPLATE" => string(39) "#SITE_DIR#/catalog/#SECTION_CODE_PATH#/"
"DESCRIPTION" => string(20) "от 40 до 90 см"
"GALLERY" => array(0)
"IBLOCK_SECTION_ID" => string(3) "116"
"IBLOCK_SECTION_NAME" => string(14) "Шампуни"
"IBLOCK_SECTION_CODE" => string(8) "shampuni"
"IBLOCK_SECTION_SORT" => string(3) "500"
"SECTION_CODE_PATH" => string(29) "sredstva-dlya-ukhoda/shampuni"
"PREVIEW_PICTURE_SRC" => string(55) "/upload/iblock/a41/ug1kpe849g5gh11uvy1gflmyossdvncr.png"
"GALLERY_SRC" => string(55) "/upload/iblock/313/hw6puxktrq0tg7uu5gvvylc4iqnd501w.png"
"TYPE_ID" => string(3) "280"
"TYPE_ID_ID" => string(3) "280"
"TYPE_ID_PROPERTY_ID" => string(3) "169"
"TYPE_ID_VALUE" => string(27) "Средства ухода"
"TYPE_ID_DEF" => string(1) "N"
"TYPE_ID_SORT" => string(3) "500"
"TYPE_ID_XML_ID" => string(32) "cd6b5b5ce30bd60ef71c58a84fe50536"
"TYPE_ID_TMP_ID" => NULL
]В случае формирования запроса через realweb.api также не рекомендуется добавлять множественные свойства в выборку. Подробнее как получать значения множественных свойств