Нам при работе с построителем запросов Bitrix\Main\Entity\Query не хватает:
1/ Мануал по использованию метода registerRuntimeField(), в частности по настройке типов полей $fieldInfo 2/ Примеры решения типичных задач через построитель запросов 3/ можно ли получить сформированный SQL в построителе запросов без предварительного исполнения запроса?
Делюсь недавней находкой, как решить следующую задачу:
Необходимо выбрать из таблицы элементов инфоблока 1.0 элементы, отсортированные по значению свойства, заданного кодом.
Решение будет следующим, выбираем из таблицы b_iblock_element элементы инфоблока, а также к таблице джойним таблицу b_iblock_element_property со всеми свойствами, однако фильтруем именно нужное нам с кодом 30:
// дамп запроса на быструю руку
$showLastQuery = function ($queryBuilder) {
echo '<h4>' . wordwrap($queryBuilder->getLastQuery(), 150) . "</h4>\n\n";
};
// инфоблок 1.0. Выбираем элемент и одно свойство, по нему делаем сортировку.
// алиас поля делаем DOC_ID
use Bitrix\Iblock as ib;
use Bitrix\Main as bm;
$propertySelectAndSortId = 30;
$propertyFieldName = 'DOC_ID';
$queryBuilder = new bm\Entity\Query( ib\ElementTable::getEntity() );
$elC = $queryBuilder
->setSelect( array('NAME', 'ID', 'IBLOCK_ID', $propertyFieldName) )
->registerRuntimeField($propertyFieldName, array(
"data_type" => '\Bitrix\Iblock\ElementPropertyTable',
'reference' => array('=this.ID' => 'ref.IBLOCK_ELEMENT_ID'),
))
->setFilter(array(
'IBLOCK_ID' => 10,
'IBLOCK_ELEMENT_' . $propertyFieldName . '_IBLOCK_PROPERTY_ID'
=> $propertySelectAndSortId
))
->setOrder( array('IBLOCK_ELEMENT_' . $propertyFieldName . '_VALUE' => 'ASC') )
->exec()->fetchAll();
$showLastQuery( $queryBuilder );
echo count($elC);
xdebug_var_dump($elC);
Итого мы получаем следующую картинку:
дамп итогового запроса:
SEL ECT
`iblock_element`.`NAME` AS `NAME`,
`iblock_element`.`ID` AS `ID`,
`iblock_element`.`IBLOCK_ID` AS `IBLOCK_ID`,
`iblock_element_doc_id`.`ID` AS `IBLOCK_ELEMENT_DOC_ID_ID`,
`iblock_element_doc_id`.`IBLOCK_PROPERTY_ID` AS `IBLOCK_ELEMENT_DOC_ID_IBLOCK_PROPERTY_ID`,
`iblock_element_doc_id`.`IBLOCK_ELEMENT_ID` AS `IBLOCK_ELEMENT_DOC_ID_IBLOCK_ELEMENT_ID`,
`iblock_element_doc_id`.`VALUE` AS `IBLOCK_ELEMENT_DOC_ID_VALUE`,
`iblock_element_doc_id`.`VALUE_TYPE` AS `IBLOCK_ELEMENT_DOC_ID_VALUE_TYPE`,
`iblock_element_doc_id`.`VALUE_ENUM` AS `IBLOCK_ELEMENT_DOC_ID_VALUE_ENUM`,
`iblock_element_doc_id`.`VALUE_NUM` AS `IBLOCK_ELEMENT_DOC_ID_VALUE_NUM`,
`iblock_element_doc_id`.`DESCRIPTION` AS `IBLOCK_ELEMENT_DOC_ID_DESCRIPTION`
FR OM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element_property` `iblock_element_doc_id` ON `iblock_element`.`ID` = `iblock_element_doc_id`.`IBLOCK_ELEMENT_ID`
WHERE `iblock_element`.`IBLOCK_ID` = 10
AND `iblock_element_doc_id`.`IBLOCK_PROPERTY_ID` = 30
ORDER BY `iblock_element_doc_id`.`VALUE` ASC
дамп одного элемента итерации, как видите все поля таблицы свойств b_iblock_element_property заджойнились, но мы выбрали только нужное нам свойство и успешно по нему выполнили сортировку:
Также мы добавили следующее событие, чтобы не дописывать в урле orm=y для запуска генератора запросов:
/bitrix/php_interface/include/lib/handlers.php:
AddEventHandler('main', 'OnBeforeProlog', function () {
global $APPLICATION;
if ($APPLICATION->GetCurPage() == '/bitrix/admin/perfmon_tables.php' && $_GET['orm'] != 'y') {
LocalRedirect( $APPLICATION->GetCurPageParam("orm=y") );
}
});
Итог:
1/ Хотим документацию по построителю запросов, а еще больше по примерам решаемых задач. 2/ Очень хотим \Bitrix\Iblock\ElementPropertyTable и прочие сущности из коробки, которые часто используются в проектах 3/ Хотим диаграмму классов по D7!
Пробовал в общей таблице и в отдельные перемещал. Вообще хочется в отдельных. Наверное должно же быть какое то стандартное решение. Мне вообще надо просто получить записи из инфоблоков с свойствами, убил целый день на D7 для этой цели, плюнул и написал по старинке.
Pogudin Sergey, для использования d7 нужно создать класс для работы с таблицой со значениями свойств (используется для создания класса orm-генератор в модуле производительности).
Видимо в новых обновлениях удалили файл bitrix\modules\iblock\lib\elementproperty.php
Pogudin Sergey, переводите в отдельные таблицы. У вас появятся отдельные таблицы b_iblock_property_sN и b_iblock_property_mN, где N - ID инфоблока. Далее идете http://yoursite.domain/bitrix/admin/p...g=ru&orm=y параметр orm=y обязателен, щелкаете правой клавишей мышки и выбираете ORM. Битрикс выдаст вам уже готовый шаблон класса для выбранной таблицы
Чтобы избавиться от PROPERTY_N в запросах. Рекомендую сразу прописать алиасы полей, например:
'MY_PROPERTY_SYMBOL_CODE' => array(
'data_type' => 'float',
'column_name' => 'PROPERTY_203', // реальное имя поля в БД
'title' => Loc::getMessage('ELEMENT_PROP_S46_ENTITY_PROPERTY_203_FIELD'),
),
далее в селектах будете уже использовать MY_PROPERTY_SYMBOL_CODE, оно кстати может и не совпадать с заданным в свойствах инфоблока.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».