Skip to content

Commit 918a86e

Browse files
committed
ACP2E-1754: Store level URL rewrites are removed after product import
1 parent 9164666 commit 918a86e

File tree

2 files changed

+92
-26
lines changed

2 files changed

+92
-26
lines changed

app/code/Magento/CatalogUrlRewrite/Observer/AfterImportDataObserver.php

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,8 @@
66

77
namespace Magento\CatalogUrlRewrite\Observer;
88

9-
use Magento\Catalog\Api\Data\ProductInterface;
109
use Magento\Catalog\Api\Data\ProductAttributeInterface;
11-
use Magento\Eav\Model\ResourceModel\AttributeValue;
12-
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Catalog\Api\Data\ProductInterface;
1311
use Magento\Catalog\Model\Category;
1412
use Magento\Catalog\Model\Product;
1513
use Magento\Catalog\Model\Product\Visibility;
@@ -23,6 +21,7 @@
2321
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
2422
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
2523
use Magento\CatalogUrlRewrite\Service\V1\StoreViewService;
24+
use Magento\Eav\Model\ResourceModel\AttributeValue;
2625
use Magento\Framework\App\Config\ScopeConfigInterface;
2726
use Magento\Framework\App\ObjectManager;
2827
use Magento\Framework\DataObject;
@@ -191,11 +190,6 @@ class AfterImportDataObserver implements ObserverInterface
191190
*/
192191
private $productCollectionFactory;
193192

194-
/**
195-
* @var ProductRepositoryInterface
196-
*/
197-
private $productRepository;
198-
199193
/**
200194
* @var AttributeValue
201195
*/
@@ -214,7 +208,6 @@ class AfterImportDataObserver implements ObserverInterface
214208
* @param CategoryCollectionFactory|null $categoryCollectionFactory
215209
* @param ScopeConfigInterface|null $scopeConfig
216210
* @param CollectionFactory|null $collectionFactory
217-
* @param ProductRepositoryInterface|null $productRepository
218211
* @param AttributeValue|null $attributeValue
219212
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
220213
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -232,7 +225,6 @@ public function __construct(
232225
CategoryCollectionFactory $categoryCollectionFactory = null,
233226
ScopeConfigInterface $scopeConfig = null,
234227
CollectionFactory $collectionFactory = null,
235-
ProductRepositoryInterface $productRepository = null,
236228
AttributeValue $attributeValue = null
237229
) {
238230
$this->urlPersist = $urlPersist;
@@ -252,10 +244,6 @@ public function __construct(
252244
ObjectManager::getInstance()->get(ScopeConfigInterface::class);
253245
$this->productCollectionFactory = $collectionFactory ?:
254246
ObjectManager::getInstance()->get(CollectionFactory::class);
255-
$this->productRepository = $productRepository ?:
256-
ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
257-
$this->productRepository = $productRepository ?:
258-
ObjectManager::getInstance()->get(ProductRepositoryInterface::class);
259247
$this->attributeValue = $attributeValue ?:
260248
ObjectManager::getInstance()->get(AttributeValue::class);
261249
}
@@ -467,25 +455,21 @@ private function isGlobalScope($storeId)
467455
private function canonicalUrlRewriteGenerate(array $products)
468456
{
469457
$urls = [];
458+
$cachedValues = null;
470459
foreach ($products as $productId => $productsByStores) {
471460
foreach ($productsByStores as $storeId => $product) {
472461
if ($this->productUrlPathGenerator->getUrlPath($product)) {
473462
$reqPath = $this->productUrlPathGenerator->getUrlPathWithSuffix($product, $storeId);
474463
if ((int) $storeId !== (int) $product->getStoreId()
475464
&& $this->isGlobalScope($product->getStoreId())) {
476-
$values = $this->attributeValue->getValues(
477-
ProductInterface::class,
478-
$product->getId(),
479-
[ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY],
480-
[$storeId]
481-
);
482-
if (!empty($values)) {
465+
if ($cachedValues === null) {
466+
$cachedValues = $this->getScopeBasedUrlKeyValues($products);
467+
}
468+
if (!empty($cachedValues) && isset($cachedValues[$productId][$storeId])) {
483469
$storeProduct = clone $product;
484470
$storeProduct->setStoreId($storeId);
485-
$storeProduct->setUrlKey($values[0]['value']);
471+
$storeProduct->setUrlKey($cachedValues[$productId][$storeId]);
486472
$reqPath = $this->productUrlPathGenerator->getUrlPathWithSuffix($storeProduct, $storeId);
487-
} else {
488-
$reqPath = $this->productUrlPathGenerator->getUrlPathWithSuffix($product, $storeId);
489473
}
490474
}
491475
$urls[] = $this->urlRewriteFactory->create()
@@ -500,6 +484,37 @@ private function canonicalUrlRewriteGenerate(array $products)
500484
return $urls;
501485
}
502486

487+
/**
488+
* Get url key attribute values for the specified scope
489+
*
490+
* @param array $products
491+
* @return array
492+
*/
493+
private function getScopeBasedUrlKeyValues(array $products) : array
494+
{
495+
$values = [];
496+
$productIds = [];
497+
$storeIds = [];
498+
foreach ($products as $productId => $productsByStores) {
499+
$productIds[] = (int) $productId;
500+
foreach ($productsByStores as $storeId => $product) {
501+
$storeIds[] = (int) $storeId;
502+
}
503+
}
504+
$productIds = array_unique($productIds);
505+
$storeIds = array_unique($storeIds);
506+
if (!empty($productIds) && !empty($storeIds)) {
507+
$values = $this->attributeValue->getValuesMultiple(
508+
ProductInterface::class,
509+
$productIds,
510+
[ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY],
511+
$storeIds
512+
);
513+
}
514+
515+
return $values;
516+
}
517+
503518
/**
504519
* Generate list based on categories.
505520
*

app/code/Magento/Eav/Model/ResourceModel/AttributeValue.php

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,29 @@ public function getValues(
6060
int $entityId,
6161
array $attributeCodes = [],
6262
array $storeIds = []
63+
): array {
64+
return $this->getValuesImplementation($entityType, $entityId, $attributeCodes, $storeIds);
65+
}
66+
67+
/**
68+
* Implementation for the getValues methods
69+
*
70+
* @param string $entityType
71+
* @param int $entityId
72+
* @param string[] $attributeCodes
73+
* @param int[] $storeIds
74+
* @param int[] $entityIds
75+
* @param bool $isMultiple
76+
* @return array
77+
* @throws \Exception
78+
*/
79+
private function getValuesImplementation(
80+
string $entityType,
81+
int $entityId = 0,
82+
array $attributeCodes = [],
83+
array $storeIds = [],
84+
array $entityIds = [],
85+
bool $isMultiple = false
6386
): array {
6487
$metadata = $this->metadataPool->getMetadata($entityType);
6588
$connection = $metadata->getEntityConnection();
@@ -89,8 +112,12 @@ public function getValues(
89112
['t' => $attributeTable],
90113
['*']
91114
)
92-
->where($metadata->getLinkField() . ' = ?', $entityId)
93115
->where('attribute_id IN (?)', $attributeIds);
116+
if (!$isMultiple) {
117+
$select->where($metadata->getLinkField() . ' = ?', $entityId);
118+
} else {
119+
$select->where($metadata->getLinkField() . ' IN(?)', $entityIds, \Zend_Db::INT_TYPE);
120+
}
94121
if (!empty($storeIds)) {
95122
$select->where(
96123
'store_id IN (?)',
@@ -107,12 +134,36 @@ public function getValues(
107134
$select = reset($selects);
108135
}
109136

110-
$result = $connection->fetchAll($select);
137+
if (!$isMultiple) {
138+
$result = $connection->fetchAll($select);
139+
} else {
140+
foreach ($connection->fetchAll($select) as $row) {
141+
$result[$row[$metadata->getLinkField()]][$row['store_id']] = $row['value'];
142+
}
143+
}
111144
}
112145

113146
return $result;
114147
}
115148

149+
/**
150+
* Bulk version of the getValues() for several entities
151+
*
152+
* @param string $entityType
153+
* @param int[] $entityIds
154+
* @param string[] $attributeCodes
155+
* @param int[] $storeIds
156+
* @return array
157+
*/
158+
public function getValuesMultiple(
159+
string $entityType,
160+
array $entityIds,
161+
array $attributeCodes = [],
162+
array $storeIds = []
163+
) : array {
164+
return $this->getValuesImplementation($entityType, 0, $attributeCodes, $storeIds, $entityIds, true);
165+
}
166+
116167
/**
117168
* Delete attribute values
118169
*

0 commit comments

Comments
 (0)