58 $callback =
function (array $params) use ($product) {
59 yield from $this->getSkuIteratorForProduct($product, $params);
64 ->setIteratorCallback($callback)
78 return $this->getSkuIteratorForProduct($product, $params);
87 $callback =
function (array $params) use ($product) {
88 yield from $this->getSkuIteratorEagerLoading($product, $params);
93 ->setIteratorCallback($callback)
99 $sku = parent::getEntitiesBy($params);
103 $this->loadParentProducts(...$sku);
111 $filter = parent::getAdditionalFilter();
112 $filter[
'IBLOCK_ID'] = $this->iblockInfo->getSkuIblockId();
119 $filter = parent::getAdditionalProductFilter();
132 $type = (int)($fields[
'TYPE'] ?? 0);
136 $entityClass = $this->factory::SKU;
140 $entityClass = $this->factory::SIMPLE_SKU;
143 return $this->factory->createEntity($entityClass);
146 private function loadParentProducts(
BaseSku ...$skuItems): void
148 $skuByProductMap = $this->getSkuByProductMap($skuItems);
150 if (!empty($skuByProductMap))
152 $products = $this->productRepository->getEntitiesBy([
154 '=ID' => array_keys($skuByProductMap),
159 foreach ($products as $product)
161 $productSkuItems = $skuByProductMap[$product->getId()] ?? [];
163 ->setParent($product)
164 ->add(...$productSkuItems)
166 $product->setSkuCollection($skuCollection);
171 private function getSkuByProductMap(array $skuItems): array
173 $skuByProductMap = [];
177 foreach ($skuItems as $sku)
179 if ($sku->getParent() ===
null)
181 $skuMap[$sku->getId()] = $sku;
187 $skuPropertyId = $this->iblockInfo->getSkuPropertyId();
188 $propertyValuesIterator = \CIBlockElement::GetPropertyValues(
189 $this->iblockInfo->getSkuIblockId(),
190 [
'ID' => array_keys($skuMap)],
192 [
'ID' => $skuPropertyId]
195 while ($propertyValues = $propertyValuesIterator->fetch())
198 $sku = $skuMap[$propertyValues[
'IBLOCK_ELEMENT_ID']];
204 return $skuByProductMap;
207 private function getSkuIteratorForProduct(BaseProduct $product, array $params = []): \Generator
209 if ($product->isSimple())
211 if ($product->getSkuCollection()->isEmpty())
216 elseif (!$product->isNew())
218 $params[
'filter'][
'PROPERTY_' . $this->iblockInfo->getSkuPropertyId()] = $product->getId();
219 $params[
'order'][
'ID'] ??=
'DESC';
221 foreach ($this->
getList($params) as $item)
228 private function getSkuIteratorEagerLoading(BaseProduct $product, array $params = []): \Generator
230 if ($product->isSimple())
232 if ($product->getSkuCollection()->isEmpty())
237 elseif (!$product->isNew())
239 $params[
'filter'][
'PROPERTY_' . $this->iblockInfo->getSkuPropertyId()] = $product->getId();
240 $params[
'order'][
'ID'] =
'DESC';
243 foreach ($this->
getList($params) as $item)
245 $items[$item[
'ID']] = $item;
248 $skuIds = array_keys($items);
250 $propertySettings = $this->propertyRepository->getPropertiesSettingsByFilter([
251 '=IBLOCK_ID' => $this->iblockInfo->getSkuIblockId(),
254 $propertyElementMap = $this->getPropertyMapBySkuIds($skuIds, $propertySettings);
256 foreach ($items as $skuId => $item)
258 $propertyCollection = $this->propertyRepository->createCollection();
260 foreach ($propertySettings as $setting)
262 if (isset($propertyElementMap[$skuId][$setting[
'ID']]))
264 $propertyItem = $propertyElementMap[$skuId][$setting[
'ID']];
268 $propertyItem = $this->propertyRepository->createEntity([], $setting);
273 $propertyCollection->add($propertyItem);
287 private function getPropertyMapBySkuIds(array $skuIds, array $propertySettings): array
289 $skuPropertyFilter = [
291 'IBLOCK_ID' => $this->iblockInfo->getSkuIblockId(),
296 $properties = $this->propertyRepository->getEntitiesBy($skuPropertyFilter, $propertySettings);
297 $propertyElementMap = [];
300 foreach ($properties as $property)
302 $elementId = $property->getSetting(
'IBLOCK_ELEMENT_ID');
306 $propertyElementMap[$elementId] = $propertyElementMap[$elementId] ?? [];
307 $propertyElementMap[$elementId][$property->getSetting(
'ID')] = $property;
311 return $propertyElementMap;
316 $entity = parent::createEntity($fields);
318 if ($propertyCollection)
320 $entity->setPropertyCollection($propertyCollection);
328 if (isset($this->productRepository))
330 if ($this->productRepository->getDetailUrlTemplate() ===
null)
333 $this->productRepository->setAutoloadDetailUrl($template !==
null);
337 return parent::setDetailUrlTemplate($template);
342 if (isset($this->productRepository))
347 return parent::setAutoloadDetailUrl($state);
353 'PROPERTY_' . $this->iblockInfo->getSkuPropertyId() => $productId,
356 return \CIBlockElement::GetList(