Как использовать D7 для работы с местоположениями?

Предположим я хочу сопоставить некоторый дополнительный набор данных стандартным местоположениям 2.0
У меня есть 2 (ну в крайнем случае 2.5) идеи по этому поводу.
Первая создать хайлойдблок с допданными где в UF_LOCATION_ID хранить id место положения, а в остальных полях нужные мне данные. Пусть для простоты это будет пока только символьный код, и так как CODE у местоположений занят, я буду хранить его в XML_ID.
Тогда у меня есть решение в лоб:
метод возвращающий подлокации по id
/*
* Возвращает дочерние локации по id родителя
*/
public function getChildrensById ($id,$key='ID') {
   $res = \Bitrix\Sale\Location\LocationTable::getList(array(
           'filter' => array(
               '=ID' => intval($id),
               '=CHILDREN.NAME.LANGUAGE_ID' => 'ru',
               //'=CHILDREN.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID,
           ),
           'select' => array(
               '_ID' => 'CHILDREN.ID',
               'CODE' => 'CHILDREN.CODE',
               'DEPTH_LEVEL' => 'CHILDREN.DEPTH_LEVEL',
               'LATITUDE' => 'CHILDREN.LATITUDE',
               'LONGITUDE' => 'CHILDREN.LONGITUDE',
               'NAME_RU' => 'CHILDREN.NAME.NAME',
               'TYPE_CODE' => 'CHILDREN.TYPE.CODE',
               //'TYPE_NAME_RU' => 'CHILDREN.TYPE.NAME.NAME'
           ),
           'order' => array(
               'CHILDREN.NAME.NAME' => 'ASC'
           )
       ));
   $arLocations = [];
   while($item = $res->fetch()) {
       $item['ID'] = $item['_ID'];
       $arLocations[$item[$key]] = $item;
   }
   $this->addExtData($arLocations);
   return $arLocations;
}
#

метод добавляющий допданные из хайлоад блока
/*
* Добавляет допданные из таблицы locode
*/
public function addExtData (&$arLocations) {
   $IDs = array_column($arLocations,'ID');
   
   $rsData = $this->locodes_data_class::getList(array(
           'select' => ['UF_XML_ID','UF_LOCATION_ID'],
           'filter' => ['UF_LOCATION_ID'=>$IDs]
       ));
   $arRefExtData = [];
   while ($arRow = $rsData->Fetch()) {
       $arRefExtData[$arRow['UF_LOCATION_ID']] = [
               'XML_ID' => $arRow['UF_XML_ID']
           ];
   }
   
   $arLocations = array_map(function ($arLoc) use ($arRefExtData) {
       $arLoc = array_merge($arRefExtData[$arLoc['ID']],$arLoc);
       return $arLoc;
   },$arLocations);
}
#

Костыльность решение и его производительность оставляю желать лучшего. Как-то можно используя возможности D7 извлечь допданные сразу, в том же запросе, где извлекаются данные по локациям?

Второе решение - создать в таблице b_sale_loc_name коды для местоположений скажем для языка ru_trnlt, но я не могу понять как в моем getChildrensById извлечь NAME.NAME сразу для двух языков. Можно как-то сделать?

Возможно есть еще какие-то решения вопроса?
  • Вопрос задан
  • 44 просмотра
Решения вопроса 2
@Snatch87
Битриксоид по принуждению
Если я правильно Вас понял, то Вам нужно использовать runtime, вот небольшой пример, только с использованием query вместо getList, но смысл тот же
$query  = \Entities\Marketing\PostingTmpTable::query()
             ->registerRuntimeField('CONTACT', [
                 'data_type' => '\Bitrix\Sender\ContactTable',
                 'reference' => [
                     '=this.CONTACT_ID' => 'ref.ID',
                 ],
             ])
             ->registerRuntimeField('PROPERTY', [
                'data_type' => $hlBlockEntity,
                'reference' => [
                    '=this.CONTACT.CODE' => 'ref.UF_EMAIL'
                ],
            ])
        ;


Вы просто добавляете к запросу новое поле (или несколько полей), которое берется из другой таблицы
Ответ написан
gromdron
@gromdron
Bitrix developer
Как-то можно используя возможности D7 извлечь допданные сразу, в том же запросе, где извлекаются данные по локациям?


Используя runtime-секцию, ты можешь обьявить вычисляемое поле типа reference и вытаскивать данные, но неизвестно как себя поведет при этом запрос (могут появиться дубли).

Будет нечто выглядящее так:

$res = \Bitrix\Sale\Location\LocationTable::getList([
	'filter' => [
		'=ID' => intval($id),
		'=CHILDREN.NAME.LANGUAGE_ID' => 'ru',
	],
	'select' => [
		'_ID' => 'CHILDREN.ID',
		'CODE' => 'CHILDREN.CODE',
		'DEPTH_LEVEL' => 'CHILDREN.DEPTH_LEVEL',
		'LATITUDE' => 'CHILDREN.LATITUDE',
		'LONGITUDE' => 'CHILDREN.LONGITUDE',
		'NAME_RU' => 'CHILDREN.NAME.NAME',
		'TYPE_CODE' => 'CHILDREN.TYPE.CODE',

		'UF_XML_ID' => 'LOCODES.UF_XML_ID',
		'UF_LOCATION_ID' => 'LOCODES.UF_LOCATION_ID',
	],
	'runtime' => [
		new \Bitrix\Main\Entity\ReferenceField(
			'LOCODES',
			$this->locodes_data_class,
			['=this.ID' => 'ref.UF_LOCATION_ID'],
			['join_type' => 'LEFT']
		)
	],
	'order' => [
		'CHILDREN.NAME.NAME' => 'ASC'
	]
]);
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы