Получить значение маркировки продукта. UF_PRODUCT_GROUP при запросе информации о продукте или продуктах.

RSS
Получить значение маркировки продукта. UF_PRODUCT_GROUP при запросе информации о продукте или продуктах., Как получить значение указанной маркировки продукта в каталоге битрикс на API
 
Здравствуйте, Михаил.
Повторю вопрос из комментария под Вашим стримом:
Каким образом через апи битрикс можно получить значение поля UF_PRODUCT_GROUP?
Что пробовал я:
1) CIBlockElement::GetList, в массив arSelect передавать 'UF_*' и 'UF_PRODUCT_GROUP'... Бесполезно. Поле игнорируется.
2) CCatalogProduct::GetList. Те же самые приписки в arSelect. Опять эффекта 0.

Как я решил. Ручками прописал запрос к базе, к таблице b_uts_product по VALUE_ID, являющимся айдишником продукта. Но может таки есть способ проще?
Изменено: Михаил Базаров - 21.09.2022 23:28:56
 
Дополню. Не помогает ни устаревший запрос через CCatalog*, ни через D7 \Bitrix\Catalog\ProductTable::getList(array('filter' => array('=ID' => $_REQUEST['PRODUCT_ID']),    'select' => array('*', 'UF_*')));

Как то странно... Битрикс обновлен до последней версии.
 
Немного раcковырял форму добавления элемента в инфоблок и форму добавления продукта.

Вот что получилось: возможно, можно улучшить, все сократить и сделать более компактным (если есть идеи напишите  :) )
Но, так или иначе, работает на API
- Получаем пользователькие поля для товара с Main\UserField\Internal\UserFieldHelper
- Внутри получаем всю информацию о связанной записи HL блока
- дальше, зная ID записи в HL блоке, получаем значение
Код
use Bitrix\Main\Loader; // если в компоненте каталога, не все эти use нужны - там уже есть.
use Bitrix\Main;
use Bitrix\Iblock;
use Bitrix\Catalog;
use Bitrix\Highloadblock as HL;
use Bitrix\Main\Entity;

Loader::includeModule("highloadblock");
Loader::includeModule('iblock');
Loader::includeModule('catalog');

$hlbl = 1; // ID блока с маркировками, всегда первый вроде.
$hlblock = HL\HighloadBlockTable::getById($hlbl)->fetch();
$entity = HL\HighloadBlockTable::compileEntity($hlblock);
$entity_data_class = $entity->getDataClass();

$userFieldManager = Main\UserField\Internal\UserFieldHelper::getInstance()->getManager();
$result = $userFieldManager->GetUserFields(
    Catalog\ProductTable::getUfId(),
    '13019', // Это ID товара (элемента ИБ)
);
foreach ($result as $value) {
    // Вся информация об этой записи
    echo '<pre>';
    print_r($value);
    echo '</pre>';
    // end Вся информация об этой записи

    // Только значение
    $rsData = $entity_data_class::getList(array(
        "select" => array(
            "UF_NAME"
        ),
        "filter" => array(
            'ID' => $value['VALUE']
        )
    ));
    while ($arData = $rsData->Fetch()) {
        echo $arData['UF_NAME']; // Собсно- все ради этого
    }
    // end Только значение
}

Тут улучшения, которые можно сделать вижу такие:
- Как то получить ID HL блока, не указывая его явно.
- Оптимизмровать вызовы, что бы код стал компактнее и очевиднее.
Изменено: Михаил Базаров - 23.09.2022 11:35:00
 
Спасибо огромное.
А вот что ответила техподдержка, куда обратился возмущенный я. Они предлагают написать кастомный класс, расширяющий DataManager.
Код
<?php
namespace Bitrix\Uts;

use Bitrix\Main\Localization\Loc,
   Bitrix\Main\ORM\Data\DataManager,
   Bitrix\Main\ORM\Fields\IntegerField;

Loc::loadMessages(__FILE__);

/**
 * Class ProductTable
 * 
 * Fields:
 * <ul>
 * <li> VALUE_ID int mandatory
 * <li> UF_PRODUCT_GROUP int optional
 * </ul>
 *
 * @package Bitrix\Uts
 **/

class ProductTable extends DataManager
{
   /**
    * Returns DB table name for entity.
    *
    * @return string
    */
   public static function getTableName()
   {
      return 'b_uts_product';
   }

   /**
    * Returns entity map definition.
    *
    * @return array
    */
   public static function getMap()
   {
      return [
         new IntegerField(
            'VALUE_ID',
            [
               'primary' => true,
               'title' => Loc::getMessage('PRODUCT_ENTITY_VALUE_ID_FIELD')
            ]
         ),
         new IntegerField(
            'UF_PRODUCT_GROUP',
            [
               'title' => Loc::getMessage('PRODUCT_ENTITY_UF_PRODUCT_GROUP_FIELD')
            ]
         ),
      ];
   }
}

А потом применять его так:
Код
include($_SERVER['DOCUMENT_ROOT'].'/bitrix/modules/uts/lib/producttable.php');
$productId = 328;
$group = \Bitrix\Uts\ProductTable::getList(["select"=>["UF_PRODUCT_GROUP"],"filter"=>["VALUE_ID"=>$productId]]);
echo "<pre>";
print_r($group->fetch());
echo "</pre>";
 
Подумал, может быть для не админов нет доступа к
Main\UserField\Internal\UserFieldHelper::getInstance()->getManager();
но нет, моим способом все выводится и для всех.

ТП шный вариант интересный, но какой-то избыточный.
 
На мой вкус он тоже достаточно избыточен. Плодить классы на каждую частную ситуацию - это, имхо, перебор.
Проверил Ваш вариант и вариант ТП - по производительности примерно одно и то же, только Ваш вариант больше подходит для решения моей задачи, т.к. запрос инфы требуется только в одной точке приложения и не планируется к расширению на остальной функционал.
Еще раз огромное Вам спасибо за помощь!
 
Приветствую.
Строго говоря вариант с классом - это решение в рамках ORM внедренного в D7. Этот метод позволяет не только запрос данных реализовать, но и изменение данных. В некоторых случаях это нужно.  
Форма ответов
 
Текст сообщения*
Перетащите файлы
Ничего не найдено
Файл
Загрузить картинки
 
Поблагодарить и поддержать:
Или подписаться на boosty канал: Видео на Ютубе