Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/catalog/lib/v2/ |
Upload File : |
<?php namespace Bitrix\Catalog\v2; use Bitrix\Catalog\Model\Product; use Bitrix\Catalog\ProductTable; use Bitrix\Catalog\v2\Iblock\IblockInfo; use Bitrix\Catalog\v2\Internal\ProductInternalService; use Bitrix\Main\Error; use Bitrix\Main\Result; /** * Class BaseIblockElementRepository * * @package Bitrix\Catalog\v2 * * !!! This API is in alpha stage and is not stable. This is subject to change at any time without notice. * @internal */ abstract class BaseIblockElementRepository implements IblockElementRepositoryContract { /** @var \Bitrix\Catalog\v2\BaseIblockElementFactory */ protected $factory; /** @var \Bitrix\Catalog\v2\Iblock\IblockInfo */ protected $iblockInfo; private ?string $detailUrlTemplate = null; private bool $allowedDetailUrl; /** * BaseIblockElementRepository constructor. * * @param \Bitrix\Catalog\v2\BaseIblockElementFactory $factory * @param \Bitrix\Catalog\v2\Iblock\IblockInfo $iblockInfo */ public function __construct(BaseIblockElementFactory $factory, IblockInfo $iblockInfo) { $this->factory = $factory; $this->iblockInfo = $iblockInfo; $this->setAutoloadDetailUrl(false); } public function getEntityById(int $id): ?BaseIblockElementEntity { if ($id <= 0) { throw new \OutOfRangeException($id); } $entities = $this->getEntitiesBy([ 'filter' => [ '=ID' => $id, ], ]); return reset($entities) ?: null; } public function getEntitiesBy($params): array { $entities = []; foreach ($this->getList((array)$params) as $item) { $entities[] = $this->createEntity($item); } return $entities; } public function save(BaseEntity ...$entities): Result { $result = new Result(); $savedIds = []; foreach ($entities as $entity) { $entityId = $entity->getId(); if ($entityId !== null) { $res = $this->updateInternal($entityId, $entity->getChangedFields()); if ($res->isSuccess()) { $savedIds[] = $entityId; } else { $result->addErrors($res->getErrors()); } } else { $res = $this->addInternal($entity->getFields()); if ($res->isSuccess()) { $id = $res->getData()['ID']; $entity->setId($id); $savedIds[] = $id; } else { $result->addErrors($res->getErrors()); } } } // re-initialize original fields from database after save (DETAIL_PICTURE, etc) if (!empty($savedIds)) { $fields = $this->getList([ 'filter' => [ 'ID' => $savedIds, ], ]); foreach ($entities as $entity) { $entityFields = $fields[$entity->getId()] ?? null; if (!is_array($entityFields)) { continue; } $entityFields = array_diff_key($entityFields, ['TYPE' => true]); if ($entityFields) { $entity->initFields($entityFields); } } } return $result; } public function delete(BaseEntity ...$entities): Result { $result = new Result(); foreach ($entities as $entity) { if ($entityId = $entity->getId()) { $res = $this->deleteInternal($entityId); if (!$res->isSuccess()) { $result->addErrors($res->getErrors()); } } } return $result; } public function setAutoloadDetailUrl(bool $state): self { $this->allowedDetailUrl = $state; return $this; } public function checkAutoloadDetailUrl(): bool { return $this->allowedDetailUrl; } public function setDetailUrlTemplate(?string $template): self { $this->detailUrlTemplate = $template; $this->setAutoloadDetailUrl($template !== null); return $this; } public function getDetailUrlTemplate(): ?string { return $this->detailUrlTemplate; } protected function getDefaultElementSelect(): array { $result = [ 'ID', 'TIMESTAMP_X', 'MODIFIED_BY', 'DATE_CREATE', 'CREATED_BY', 'IBLOCK_ID', 'IBLOCK_SECTION_ID', 'ACTIVE', 'ACTIVE_FROM', 'ACTIVE_TO', 'SORT', 'NAME', 'PREVIEW_PICTURE', 'PREVIEW_TEXT', 'PREVIEW_TEXT_TYPE', 'DETAIL_PICTURE', 'DETAIL_TEXT', 'DETAIL_TEXT_TYPE', 'WF_STATUS_ID', 'WF_PARENT_ELEMENT_ID', 'WF_NEW', 'IN_SECTIONS', 'SHOW_COUNTER', 'SHOW_COUNTER_START', 'CODE', 'TAGS', 'XML_ID', 'TMP_ID', ]; if ($this->checkAutoloadDetailUrl()) { $result[] = 'DETAIL_PAGE_URL'; } return $result; } protected function getList(array $params): array { $filter = $params['filter'] ?? []; $order = $params['order'] ?? []; $nav = $params['nav'] ?? false; $iblockElements = []; $listIds = []; $iterator = \CIBlockElement::GetList( $order, array_merge( $filter, $this->getAdditionalFilter(), $this->getAdditionalProductFilter(), ), false, $nav, [ 'ID', 'IBLOCK_ID', ], ); while ($row = $iterator->fetch()) { $id = (int)$row['ID']; $iblockElements[$id] = $row; $listIds[] = $id; } unset($iterator); if (empty($iblockElements)) { return []; } $elementSelect = $this->getDefaultElementSelect(); $detailUrlTemplate = $this->checkAutoloadDetailUrl() ? $this->getDetailUrlTemplate() : null; $specificFields = [ 'QUANTITY_TRACE' => 'QUANTITY_TRACE_ORIG', 'CAN_BUY_ZERO' => 'CAN_BUY_ZERO_ORIG', 'SUBSCRIBE' => 'SUBSCRIBE_ORIG', ]; $productSelect = array_merge(['*', 'UF_*'], array_values($specificFields)); foreach (array_chunk($listIds, CATALOG_PAGE_SIZE) as $pageIds) { $elementsIterator = \CIBlockElement::GetList( [], [ 'ID' => $pageIds, 'CHECK_PERMISSIONS' => 'N', 'SHOW_NEW' => 'Y', ], false, false, $elementSelect, ); if ($detailUrlTemplate) { $elementsIterator->SetUrlTemplates($detailUrlTemplate); } while ($element = $elementsIterator->getNext()) { $id = (int)$element['ID']; $iblockElements[$id] += $this->replaceRawFromTilda($element); } unset($elementsIterator); $productIterator = ProductTable::getList([ 'select' => $productSelect, 'filter' => [ '@ID' => $pageIds, ], ]); while ($product = $productIterator->fetch()) { $id = (int)$product['ID']; unset($product['ID']); foreach ($specificFields as $field => $originalField) { $product[$field] = $product[$originalField]; unset($product[$originalField]); } $iblockElements[$id] += $product; } unset($productIterator); } return $iblockElements; } protected function getAdditionalFilter(): array { return [ 'CHECK_PERMISSIONS' => 'N', 'MIN_PERMISSION' => 'R', ]; } protected function getAdditionalProductFilter(): array { return []; } protected function createEntity(array $fields = []): BaseIblockElementEntity { $entity = $this->makeEntity($fields); $entity->initFields($fields); return $entity; } abstract protected function makeEntity(array $fields = []): BaseIblockElementEntity; protected function addInternal(array $fields): Result { $productService = new ProductInternalService(); return $productService->add($fields); } protected function updateInternal(int $id, array $fields): Result { $productService = new ProductInternalService(); return $productService->update($id, $fields); } protected function deleteInternal(int $id): Result { $result = new Result(); $res = \CIBlockElement::delete($id); if ($res) { $res = Product::delete($id); if (!$res->isSuccess()) { $result->addErrors($res->getErrors()); } } else { global $APPLICATION; $exception = $APPLICATION->GetException(); if ($exception && $exception->GetString()) { $errorMessage = $exception->GetString(); } else { $errorMessage = "Delete operation for entity with id {$id} failed."; } $result->addError(new Error($errorMessage)); } return $result; } private function replaceRawFromTilda(array $element): array { $newElement = []; foreach ($element as $key => $value) { $tildaKey = "~{$key}"; if (isset($element[$tildaKey])) { $newElement[$key] = $element[$tildaKey]; } } return $newElement; } }