A
A
Alexander2019-11-07 17:09:07
1C-Bitrix
Alexander, 2019-11-07 17:09:07

How to use D7 to work with locations?

Let's say I want to map some additional data set to standard 2.0 locations
. I have 2 (well, 2.5 at most) ideas about this.
The first is to create a hayloidblock with additional data where in UF_LOCATION_ID to store the location id, and in the remaining fields the data I need. For the sake of simplicity, this will only be a character code for now, and since CODE is taken from locations, I will store it in XML_ID.
Then I have a head-to-head solution:

method returning sublocations by 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;
}
#

method adding additional data from the highload block
/*
* Добавляет допданные из таблицы 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);
}
#

The crutchiness of the solution and its performance leave much to be desired. Is it somehow possible using the D7 capabilities to extract additional data immediately, in the same query where data is retrieved by location?
The second solution is to create in the table b_sale_loc_name codes for locations, say, for the language ru_trnlt, but I can't figure out how to extract NAME.NAME for two languages ​​at once in my getChildrensById. Can something be done?
Perhaps there are other solutions to the issue?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
G
Georgy Baruchyan, 2019-11-07
Madzhugin @Suntechnic

If I understood you correctly, then you need to use runtime, here is a small example, only using query instead of getList, but the meaning is the same

$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'
                ],
            ])
        ;

You simply add a new field (or several fields) to the query, which is taken from another table

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question