Closed ProklUng closed 6 years ago
Скорее всего у тебя в настройках инфоблока указана первая версия (общая таблица). Крайне рекомендуется использовать вторую версию (даже сам Битрикс в доке пишет об этом).
"Во второй версии инфоблоков при выборке элементов можно сразу получать значения свойств, т.к. количество присоединяемых таблиц в запросе не увеличивается с каждым свойством, а всегда равно единице"
Добавил в документацию ремарку насчёт этого. Скорее всего это no-fix
Насчёт цен - можешь добавить уже непосредственно в свою модель. Если получится что-то стоящее и универсальное - присылай PR.
В интернтет-магазинах в инфоблоке может быть под сотню свойств (иногда больше, особенно если есть интеграция с 1С).
Поэтому там невозможно использование второй версии.
Есть идеи - как быть в таком случае?
1) мириться с ограничениями вроде невозможности использовать PROPS когда много свойств и использовать апи битрикса напрямую там где модель не работает 2) не использовать модель вообще для этого инфоблока
Все это не очень здорово конечно. Оставлю открытым всё-таки
http://bxapi.ru/src/?module_id=iblock&name=CIBlockElement::GetPropertyValuesArray
Как вариант можно для ИБ первой версии либо начиная с определенного количества свойств получать значения для каждого элемента отдельно.
Это несколько медленней, зато сработает.
Либо как в news.list
:
$rsElement = CIBlockElement::GetList($arSort, array_merge($arFilter, $arrFilter), false, $arNavParams, $arSelect);
$rsElement->SetUrlTemplates($arParams["DETAIL_URL"], "", $arParams["IBLOCK_URL"]);
while($obElement = $rsElement->GetNextElement())
{
$arItem = $obElement->GetFields();
$arItem = $obElement->GetProperties();
}
Либо как в catalog.section
:
if (!empty($arResult["ELEMENTS"]) && ($bGetProperties || ($bCatalog && $boolNeedCatalogCache)))
{
$arPropFilter = array(
'ID' => $arResult["ELEMENTS"],
'IBLOCK_ID' => $arParams['IBLOCK_ID']
);
CIBlockElement::GetPropertyValuesArray($arElementLink, $arParams["IBLOCK_ID"], $arPropFilter);
foreach ($arResult["ITEMS"] as &$arItem)
{
if ($bCatalog && $boolNeedCatalogCache)
CCatalogDiscount::SetProductPropertiesCache($arItem['ID'], $arItem["PROPERTIES"]);
if (!empty($bGetProperties))
{
if (!empty($propertyList))
{
foreach ($propertyList as &$pid)
{
if (!isset($arItem["PROPERTIES"][$pid]))
continue;
$prop = &$arItem["PROPERTIES"][$pid];
$boolArr = is_array($prop["VALUE"]);
if (
($boolArr && !empty($prop["VALUE"]))
|| (!$boolArr && strlen($prop["VALUE"]) > 0)
)
{
$arItem["DISPLAY_PROPERTIES"][$pid] = CIBlockFormatProperties::GetDisplayValue($arItem, $prop, "catalog_out");
}
unset($prop);
}
unset($pid);
}
if ($bGetProductProperties)
{
$arItem["PRODUCT_PROPERTIES"] = CIBlockPriceTools::GetProductProperties(
$arParams["IBLOCK_ID"],
$arItem["ID"],
$arParams["PRODUCT_PROPERTIES"],
$arItem["PROPERTIES"]
);
if (!empty($arItem["PRODUCT_PROPERTIES"]))
$arItem['PRODUCT_PROPERTIES_FILL'] = CIBlockPriceTools::getFillProductProperties($arItem['PRODUCT_PROPERTIES']);
}
}
}
unset($arItem);
}
О ценах. Подскажите, пожалуйста, как сделать так (унаследовать чего и как), чтобы можно было бы выполнять операцию таким образом:
$products = oboi::query()->select('ID')->setBasePrice (27.5, 'EUR');
И во всей выборке устанавливается базовая цена 27.5.
Или хотя бы в варианте для одной позиции.
$products = new oboi (27768); $products->price (27.5);
Еще момент. При выборке свойств не выдает XML_ID для свойства типа список.
$products = paints::ExcludeColorotecs()->select('ID')
->sort(['SORT' =>'DESC'])
->select ('NAME', 'FIELDS',
'PROPERTY_COLLECTIONV2', 'PROPERTY_COLLECTION',
'PROPERTY_ARTICUL', 'PROPERTY_GRADIENT',
'PROPERTY_COLLECTIONV2'
)
->getList()
->toArray()
;
printr ($products);
[50494] => Array ( [ID] => 50494 [TIMESTAMP_X] => 21.07.2017 10:50:55
[...]
[PROPERTY_GRADIENT_VALUE] => 0%
[PROPERTY_GRADIENT_ENUM_ID] => 24545
[PROPERTY_GRADIENT_VALUE_ID] => 50494:335
)
Он их не выдает потому что их не возвращает Битрикс из CiblockElement::GetList() + Fetch()/GetNext()
Битрикс возвращает только следующие поля для свойства типа список
"PROPERTY_COUNTRY_VALUE" => "Россия" "PROPERTY_COUNTRY_ENUM_ID" => "1" "PROPERTY_COUNTRY_VALUE_ID" => "28:17"
Проблема из темы issue решена в v0.6
Отличная штука, спасибо. Пара моментов:
Когда много полей в базе свойств элемента инфоблока и ставишь опцию PROPS ожидаемо вываливается с ошибкой Too many tables; MySQL can only use 61 tables in a join. Причем, количество property не впечатляющее - штук 20 или 30 на элемент.
Хорошо бы сделать по аналогии с activate/deactivate функцию установки цен.