Задать вопрос
  • Как объединить результаты getList, в котором объединяются две таблицы?

    @Cyber-Pavel
    Проблема, с которой вы столкнулись, не в том, что ваш getList работает неправильно. Дело в том, как ORM Bitrix формирует SQL JOIN: при соединении одной таблицы с другой через ReferenceField каждая связанная запись из второй таблицы создаёт отдельную строку. Поэтому вы видите повторение основного профиля для каждой записи из UserPropsValueTable.

    К сожалению, чистого способа в getList получить массив, где вложенные данные объединены в один подмассив без циклов на PHP, нет. Bitrix ORM не умеет делать «группировку по родительской записи» на уровне fetch.

    То, что вы хотите — это фактически структура JSON с вложенным массивом, и её формирование всегда происходит на стороне PHP после выборки.

    Вот как можно сделать максимально компактно, без длинных циклов, используя array_reduce или foreach в одну строку:

    $rows = \Bitrix\Sale\Internals\UserPropsTable::getList([
        "select" => ["*", "PROFILE_" => "PROFILE.*"],
        "filter" => ["PERSON_TYPE_ID" => 49163, "ID" => 12],
        "runtime" => [
            new \Bitrix\Main\Entity\ReferenceField(
                'PROFILE',
                \Bitrix\Sale\Internals\UserPropsValueTable::class,
                ['=this.ID' => 'ref.USER_PROPS_ID']
            ),
        ]
    ])->fetchAll();
    
    $result = [];
    foreach ($rows as $row) {
        $id = $row['ID'];
        if (!isset($result[$id])) {
            $result[$id] = $row;
            $result[$id]['PROFILE_DATA'] = [];
            // удаляем вложенные поля, которые пойдут в PROFILE_DATA
            unset(
                $result[$id]['PROFILE_ID'],
                $result[$id]['PROFILE_USER_PROPS_ID'],
                $result[$id]['PROFILE_ORDER_PROPS_ID'],
                $result[$id]['PROFILE_NAME'],
                $result[$id]['PROFILE_VALUE']
            );
        }
        $result[$id]['PROFILE_DATA'][] = [
            'PROFILE_ID' => $row['PROFILE_ID'],
            'PROFILE_USER_PROPS_ID' => $row['PROFILE_USER_PROPS_ID'],
            'PROFILE_ORDER_PROPS_ID' => $row['PROFILE_ORDER_PROPS_ID'],
            'PROFILE_NAME' => $row['PROFILE_NAME'],
            'PROFILE_VALUE' => $row['PROFILE_VALUE'],
        ];
    }


    // Превращаем в обычный массив без ключей ID
    $result = array_values($result);
    Ответ написан
    Комментировать
  • Появляется сразу три яндекс.карты через API. Как исправить?

    @Cyber-Pavel Автор вопроса
    Немного подправил код и заработало)

    const acc=[];
    async function getTest(geocode,product) {

    const response = await fetch("https://geocode-maps.yandex.ru/1.x/?format=json&ap...'"', {
    method: "GET",
    headers: { "Accept": "application/json" }
    });

    const points = await response.json();
    array=points.response.GeoObjectCollection.featureMember;

    array.forEach(item =>{
    const pos=item.GeoObject.Point.pos;

    const posString = pos;
    const splitsPosition = posString.split(' ', 3);
    function swap(arr, a, b) {
    arr[a] = arr.splice(b, 1, arr[a])[0];
    }
    console.log(swap(splitsPosition,0,1));

    acc.unshift({
    ['address']:splitsPosition,
    ['product']:product
    });

    });

    return acc;
    }

    const formElement = document.getElementById('form');
    const buttonElement=document.getElementById('button');
    buttonElement.addEventListener('click', (e) => {
    e.preventDefault();
    console.log(document.getElementById('textarea').value);
    const arStr=[];
    arStr.push(document.getElementById('textarea').value);
    const result = document.getElementById('textarea').value.split('\n');
    const products = ["эспоо","симпл","вааса"];

    var resultText = result.map(str => str.split(",").reduce(
    (acc, item) => {
    if (products.filter(product=> item.toLowerCase().includes(product)).length > 0 || acc.product != "") {
    acc.product +=( acc.product!=""?",":"") + item;
    } else {
    acc.address +=( acc.address!=""?",":"") + item;
    }
    return acc;
    }

    , { address: "", product:""})
    );

    var accPromise=[];
    resultText.forEach((item)=>{
    const geocode='Россия, Москва,'+item.address+"'";
    const product=item.product;
    console.log(getTest(geocode,product));
    accPromise=getTest(geocode,product);

    });

    function init(){

    var myMap = new ymaps.Map("map", {
    center: [55.852713,37.682727],
    zoom: 16
    }, {
    searchControlProvider: 'yandex#search'
    });

    var myCollection = new ymaps.GeoObjectCollection();
    //здесь перебираю координаты

    accPromise.then((value) => {
    value.forEach((element)=>{

    var myPlacemark = new ymaps.Placemark(
    element.address
    ,

    {
    balloonContentHeader: 'Товар:',
    balloonContent: element.product
    }, {
    preset: 'islands#icon',
    iconColor: '#0000ff'
    });
    myCollection.add(myPlacemark);


    });
    });

    myMap.geoObjects.add(myCollection);
    myMap.setBounds(myCollection.getBounds(), {
    checkZoomRange: true,
    zoomMargin: 9
    });}

    ymaps.ready(init);

    });
    Ответ написан
    Комментировать