Skip to content

Commit

Permalink
Merge pull request #8399 from magento-l3/PR-L3-2023-07-14
Browse files Browse the repository at this point in the history
PR-L3-2023-07-14
  • Loading branch information
dhorytskyi authored Sep 6, 2023
2 parents ab0c0b5 + a748735 commit 16cdf25
Show file tree
Hide file tree
Showing 78 changed files with 4,336 additions and 518 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ protected function _isApplicableAttribute($object, $attribute)
{
$applyTo = $attribute->getApplyTo() ?: [];
return (count($applyTo) == 0 || in_array($object->getTypeId(), $applyTo))
&& $attribute->isInSet($object->getAttributeSetId());
&& $attribute->isInSet($object->getAttributeSetId() ?? $this->getEntityType()->getDefaultAttributeSetId());
}

/**
Expand Down
43 changes: 43 additions & 0 deletions app/code/Magento/Catalog/Test/Fixture/AttributeSet.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Test\Fixture;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Eav\Model\Config;
use Magento\Framework\DataObject;
use Magento\TestFramework\Fixture\Api\ServiceFactory;
use Magento\TestFramework\Fixture\Data\ProcessorInterface;

class AttributeSet extends \Magento\Eav\Test\Fixture\AttributeSet
{
private const ENTITY_TYPE = ProductAttributeInterface::ENTITY_TYPE_CODE;

public function __construct(
ServiceFactory $serviceFactory,
ProcessorInterface $dataProcessor,
private readonly Config $eavConfig
) {
parent::__construct($serviceFactory, $dataProcessor);
}

/**
* {@inheritdoc}
*/
public function apply(array $data = []): ?DataObject
{
return parent::apply(
array_merge(
[
'entity_type_code' => self::ENTITY_TYPE,
'skeleton_id' => $this->eavConfig->getEntityType(self::ENTITY_TYPE)->getDefaultAttributeSetId(),
],
$data
)
);
}
}
51 changes: 29 additions & 22 deletions app/code/Magento/CatalogImportExport/Model/Import/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor;
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface;
use Magento\CatalogImportExport\Model\Import\Product\Skip;
use Magento\CatalogImportExport\Model\Import\Product\SkuStorage;
use Magento\CatalogImportExport\Model\Import\Product\StatusProcessor;
use Magento\CatalogImportExport\Model\Import\Product\StockProcessor;
use Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType;
Expand Down Expand Up @@ -769,6 +770,11 @@ class Product extends AbstractEntity
*/
private $stockItemProcessor;

/**
* @var SkuStorage|null
*/
private ?SkuStorage $skuStorage;

/**
* @param \Magento\Framework\Json\Helper\Data $jsonHelper
* @param \Magento\ImportExport\Helper\Data $importExportData
Expand Down Expand Up @@ -819,6 +825,7 @@ class Product extends AbstractEntity
* @param LinkProcessor|null $linkProcessor
* @param File|null $fileDriver
* @param StockItemProcessorInterface|null $stockItemProcessor
* @param SkuStorage|null $skuStorage
* @throws LocalizedException
* @throws \Magento\Framework\Exception\FileSystemException
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
Expand Down Expand Up @@ -874,7 +881,8 @@ public function __construct(
StockProcessor $stockProcessor = null,
LinkProcessor $linkProcessor = null,
?File $fileDriver = null,
?StockItemProcessorInterface $stockItemProcessor = null
?StockItemProcessorInterface $stockItemProcessor = null,
?SkuStorage $skuStorage = null
) {
$this->_eventManager = $eventManager;
$this->stockRegistry = $stockRegistry;
Expand Down Expand Up @@ -930,6 +938,8 @@ public function __construct(
);
$this->_optionEntity = $data['option_entity'] ??
$optionFactory->create(['data' => ['product_entity' => $this]]);
$this->skuStorage = $skuStorage ?? ObjectManager::getInstance()
->get(SkuStorage::class);
$this->_initAttributeSets()
->_initTypeModels()
->_initSkus()
Expand Down Expand Up @@ -1146,7 +1156,7 @@ protected function _importData()
protected function _replaceProducts()
{
$this->deleteProductsForReplacement();
$this->_oldSku = $this->skuProcessor->reloadOldSkus()->getOldSkus();
$this->skuStorage->reset();
$this->_validatedRows = null;
$this->setParameters(
array_merge(
Expand Down Expand Up @@ -1208,7 +1218,7 @@ protected function _initAttributeSets()
protected function _initSkus()
{
$this->skuProcessor->setTypeModels($this->_productTypeModels);
$this->_oldSku = $this->skuProcessor->reloadOldSkus()->getOldSkus();
$this->skuStorage->reset();
return $this;
}

Expand Down Expand Up @@ -1341,7 +1351,7 @@ protected function _saveProductAttributes(array $attributesData)
$linkIdBySkuForStatusChanged = [];
$tableData = [];
foreach ($skuData as $sku => $attributes) {
$linkId = $this->_oldSku[strtolower($sku)][$linkField];
$linkId = $this->skuStorage->get((string)$sku)[$linkField];
foreach ($attributes as $attributeId => $storeValues) {
foreach ($storeValues as $storeId => $storeValue) {
if ($attributeId === $statusAttributeId) {
Expand Down Expand Up @@ -1464,7 +1474,7 @@ public function saveProductEntity(array $entityRowsIn, array $entityRowsUp)
$this->skuProcessor->setNewSkuData($sku, $key, $value);
}
}
$this->updateOldSku($newProducts);
$this->updateSkuStorage($newProducts);
}
return $this;
}
Expand All @@ -1485,22 +1495,11 @@ private function getOldSkuFieldsForSelect()
* @param array $newProducts
* @return void
*/
private function updateOldSku(array $newProducts)
private function updateSkuStorage(array $newProducts): void
{
$oldSkus = [];
foreach ($newProducts as $info) {
$typeId = $info['type_id'];
$sku = strtolower($info['sku']);
$oldSkus[$sku] = [
'type_id' => $typeId,
'attr_set_id' => $info['attribute_set_id'],
$this->getProductIdentifierField() => $info[$this->getProductIdentifierField()],
'supported_type' => isset($this->_productTypeModels[$typeId]),
$this->getProductEntityLinkField() => $info[$this->getProductEntityLinkField()],
];
$this->skuStorage->set($info);
}

$this->_oldSku = array_replace($this->_oldSku, $oldSkus);
}

/**
Expand Down Expand Up @@ -2596,10 +2595,19 @@ public function getNextBunch()
* new products with the same SKU in different letter cases.
*
* @return array
* @deprecated This method is deprecated due to high memory consumption.
* @see SkuStorage
*/
public function getOldSku()
{
return $this->_oldSku;
// For backward compatibility get all data from storage
$oldSkus = [];
foreach ($this->skuStorage->iterate() as $sku => $value) {
$oldSkus[$sku] = $value;
$oldSkus[$sku]['supported_type'] = isset($this->_productTypeModels[$value['type_id']]);
}

return $oldSkus;
}

/**
Expand Down Expand Up @@ -3253,8 +3261,7 @@ private function parseMultipleValues($labelRow)
private function isSkuExist($sku)
{
if ($sku !== null) {
$sku = strtolower($sku);
return isset($this->_oldSku[$sku]);
return $this->skuStorage->has($sku);
}
return false;
}
Expand All @@ -3267,7 +3274,7 @@ private function isSkuExist($sku)
*/
private function getExistingSku($sku)
{
return $this->_oldSku[strtolower($sku)];
return $this->skuStorage->get((string)$sku);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ class LinkProcessor
*/
private $logger;

/**
* @var SkuStorage
*/
private SkuStorage $skuStorage;

/**
* LinkProcessor constructor.
*
Expand All @@ -54,20 +59,23 @@ class LinkProcessor
* @param SkuProcessor $skuProcessor
* @param LoggerInterface $logger
* @param array $linkNameToId
* @param SkuStorage $skuStorage
*/
public function __construct(
LinkFactory $linkFactory,
Helper $resourceHelper,
SkuProcessor $skuProcessor,
LoggerInterface $logger,
array $linkNameToId
array $linkNameToId,
SkuStorage $skuStorage
) {
$this->linkFactory = $linkFactory;
$this->resourceHelper = $resourceHelper;
$this->skuProcessor = $skuProcessor;
$this->logger = $logger;

$this->linkNameToId = $linkNameToId;
$this->skuStorage = $skuStorage;
}

/**
Expand Down Expand Up @@ -171,10 +179,10 @@ private function processLinkBunches(
? explode($importEntity->getMultipleValueSeparator(), $rowData[$linkName . 'position'])
: [];

$linkSkus = $this->filterValidLinks($importEntity, $sku, $linkSkus);
$linkSkus = $this->filterValidLinks($sku, $linkSkus);

foreach ($linkSkus as $linkedKey => $linkedSku) {
$linkedId = $this->getProductLinkedId($importEntity, $linkedSku);
$linkedId = $this->getProductLinkedId($linkedSku);
if ($linkedId == null) {
// Import file links to a SKU which is skipped for some reason, which leads to a "NULL"
// link causing fatal errors.
Expand Down Expand Up @@ -222,7 +230,7 @@ private function deleteProductsLinks(
Product $importEntity,
Link $resource,
array $linksToDelete
) {
): void {
if (!empty($linksToDelete) && Import::BEHAVIOR_APPEND === $importEntity->getBehavior()) {
foreach ($linksToDelete as $linkTypeId => $productIds) {
if (!empty($productIds)) {
Expand All @@ -243,27 +251,23 @@ private function deleteProductsLinks(
/**
* Check if product exists for specified SKU
*
* @param Product $importEntity
* @param string $sku
* @return bool
*/
private function isSkuExist(Product $importEntity, string $sku): bool
private function isSkuExist(string $sku): bool
{
$sku = strtolower($sku);
return isset($importEntity->getOldSku()[$sku]);
return $this->skuStorage->has($sku);
}

/**
* Get existing SKU record
*
* @param Product $importEntity
* @param string $sku
* @return mixed
* @return array|null
*/
private function getExistingSku(Product $importEntity, string $sku)
private function getExistingSku(string $sku): ?array
{
$sku = strtolower($sku);
return $importEntity->getOldSku()[$sku];
return $this->skuStorage->get($sku);
}

/**
Expand Down Expand Up @@ -296,20 +300,17 @@ private function fetchProductLinks(Product $importEntity, Link $resource, int $p
/**
* Gets the Id of the Sku
*
* @param Product $importEntity
* @param string $linkedSku
* @return int|null
*/
private function getProductLinkedId(Product $importEntity, string $linkedSku): ?int
private function getProductLinkedId(string $linkedSku): ?int
{
$linkedSku = trim($linkedSku);
$newSku = $this->skuProcessor->getNewSku($linkedSku);

$linkedId = ! empty($newSku) ?
return !empty($newSku) ?
$newSku['entity_id'] :
$this->getExistingSku($importEntity, $linkedSku)['entity_id'];

return $linkedId;
$this->getExistingSku($linkedSku)['entity_id'];
}

/**
Expand All @@ -329,7 +330,7 @@ private function saveLinksData(
array $productIds,
array $linkRows,
array $positionRows
) {
): void {
$mainTable = $resource->getMainTable();
if (Import::BEHAVIOR_APPEND != $importEntity->getBehavior() && $productIds) {
$importEntity->getConnection()->delete(
Expand Down Expand Up @@ -370,7 +371,7 @@ private function composeLinkKey(int $productId, int $linkedId, int $linkTypeId):
* @param array $rowData
* @return array
*/
private function filterProvidedLinkTypes(array $rowData)
private function filterProvidedLinkTypes(array $rowData): array
{
return array_filter(
$this->linkNameToId,
Expand All @@ -384,21 +385,20 @@ function ($linkName) use ($rowData) {
/**
* Filter out invalid links
*
* @param Product $importEntity
* @param string $sku
* @param array $linkSkus
* @return array
*/
private function filterValidLinks(Product $importEntity, string $sku, array $linkSkus)
private function filterValidLinks(string $sku, array $linkSkus): array
{
return array_filter(
$linkSkus,
function ($linkedSku) use ($sku, $importEntity) {
function ($linkedSku) use ($sku) {
$linkedSku = $linkedSku !== null ? trim($linkedSku) : '';

return (
$this->skuProcessor->getNewSku($linkedSku) !== null
|| $this->isSkuExist($importEntity, $linkedSku)
|| $this->isSkuExist($linkedSku)
)
&& strcasecmp($linkedSku, $sku) !== 0;
}
Expand Down
Loading

0 comments on commit 16cdf25

Please sign in to comment.