Skip to content

Commit 4869c54

Browse files
committed
MAGETWO-67087: Saving category deletes url-rewrites for products in anchor categories
1 parent bab4284 commit 4869c54

File tree

6 files changed

+75
-11
lines changed

6 files changed

+75
-11
lines changed

app/code/Magento/CatalogUrlRewrite/Model/Product/AnchorUrlRewriteGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function __construct(
4141
}
4242

4343
/**
44-
* Generate list based on categories
44+
* Generate product rewrites for anchor categories
4545
*
4646
* @param int $storeId
4747
* @param Product $product

app/code/Magento/CatalogUrlRewrite/Model/Product/CanonicalUrlRewriteGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function __construct(ProductUrlPathGenerator $productUrlPathGenerator, Ur
3030
}
3131

3232
/**
33-
* Generate list based on store view
33+
* Generate product rewrites without categories
3434
*
3535
* @param int $storeId
3636
* @param Product $product

app/code/Magento/CatalogUrlRewrite/Model/Product/CategoriesUrlRewriteGenerator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function __construct(ProductUrlPathGenerator $productUrlPathGenerator, Ur
3131
}
3232

3333
/**
34-
* Generate list based on categories
34+
* Generate product rewrites with categories
3535
*
3636
* @param int $storeId
3737
* @param Product $product

app/code/Magento/CatalogUrlRewrite/Model/Product/CurrentUrlRewritesRegenerator.php

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace Magento\CatalogUrlRewrite\Model\Product;
77

88
use Magento\Catalog\Model\Category;
9+
use Magento\Catalog\Model\CategoryRepository;
910
use Magento\Catalog\Model\Product;
1011
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
1112
use Magento\UrlRewrite\Model\OptionProvider;
@@ -56,19 +57,24 @@ class CurrentUrlRewritesRegenerator
5657
/** @var \Magento\UrlRewrite\Model\MergeDataProvider */
5758
private $mergeDataProviderPrototype;
5859

60+
/** @var CategoryRepository */
61+
private $categoryRepository;
62+
5963
/**
6064
* @param UrlFinderInterface $urlFinder
6165
* @param ProductUrlPathGenerator $productUrlPathGenerator
6266
* @param UrlRewriteFactory $urlRewriteFactory
6367
* @param UrlRewriteFinder|null $urlRewriteFinder
6468
* @param \Magento\UrlRewrite\Model\MergeDataProviderFactory|null $mergeDataProviderFactory
69+
* @param CategoryRepository|null $categoryRepository
6570
*/
6671
public function __construct(
6772
UrlFinderInterface $urlFinder,
6873
ProductUrlPathGenerator $productUrlPathGenerator,
6974
UrlRewriteFactory $urlRewriteFactory,
7075
UrlRewriteFinder $urlRewriteFinder = null,
71-
MergeDataProviderFactory $mergeDataProviderFactory = null
76+
MergeDataProviderFactory $mergeDataProviderFactory = null,
77+
CategoryRepository $categoryRepository = null
7278
) {
7379
$this->urlFinder = $urlFinder;
7480
$this->productUrlPathGenerator = $productUrlPathGenerator;
@@ -78,11 +84,12 @@ public function __construct(
7884
if (!isset($mergeDataProviderFactory)) {
7985
$mergeDataProviderFactory = ObjectManager::getInstance()->get(MergeDataProviderFactory::class);
8086
}
87+
$this->categoryRepository = $categoryRepository ?: ObjectManager::getInstance()->get(CategoryRepository::class);
8188
$this->mergeDataProviderPrototype = $mergeDataProviderFactory->create();
8289
}
8390

8491
/**
85-
* Generate list based on current rewrites
92+
* Generate product rewrites based on current rewrites without anchor categories
8693
*
8794
* @param int $storeId
8895
* @param Product $product
@@ -115,6 +122,48 @@ public function generate($storeId, Product $product, ObjectRegistry $productCate
115122
return $mergeDataProvider->getData();
116123
}
117124

125+
/**
126+
* Generate product rewrites for anchor categories based on current rewrites
127+
*
128+
* @param int $storeId
129+
* @param Product $product
130+
* @param ObjectRegistry $productCategories
131+
* @param int|null $rootCategoryId
132+
* @return UrlRewrite[]
133+
*/
134+
public function generateAnchor($storeId, Product $product, ObjectRegistry $productCategories, $rootCategoryId = null)
135+
{
136+
$anchorCategoryIds = [];
137+
$mergeDataProvider = clone $this->mergeDataProviderPrototype;
138+
139+
$currentUrlRewrites = $this->urlRewriteFinder->findAllByData(
140+
$product->getEntityId(),
141+
$storeId,
142+
ProductUrlRewriteGenerator::ENTITY_TYPE,
143+
$rootCategoryId
144+
);
145+
146+
foreach ($productCategories->getList() as $productCategory) {
147+
$anchorCategoryIds = array_merge($productCategory->getAnchorsAbove(), $anchorCategoryIds);
148+
}
149+
150+
foreach ($currentUrlRewrites as $currentUrlRewrite) {
151+
$metadata = $currentUrlRewrite->getMetadata();
152+
if (isset($metadata['category_id']) && $metadata['category_id'] > 0) {
153+
$category = $this->categoryRepository->get($metadata['category_id'], $storeId);
154+
if (in_array($category->getId(), $anchorCategoryIds)) {
155+
$mergeDataProvider->merge(
156+
$currentUrlRewrite->getIsAutogenerated()
157+
? $this->generateForAutogenerated($currentUrlRewrite, $storeId, $category, $product)
158+
: $this->generateForCustom($currentUrlRewrite, $storeId, $category, $product)
159+
);
160+
}
161+
}
162+
}
163+
164+
return $mergeDataProvider->getData();
165+
}
166+
118167
/**
119168
* @param UrlRewrite $url
120169
* @param int $storeId

app/code/Magento/CatalogUrlRewrite/Model/ProductScopeRewriteGenerator.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,14 @@ public function generateForSpecificStoreView($storeId, $productCategories, Produ
171171
$mergeDataProvider->merge(
172172
$this->anchorUrlRewriteGenerator->generate($storeId, $product, $productCategories)
173173
);
174-
174+
$mergeDataProvider->merge(
175+
$this->currentUrlRewritesRegenerator->generateAnchor(
176+
$storeId,
177+
$product,
178+
$productCategories,
179+
$rootCategoryId
180+
)
181+
);
175182
return $mergeDataProvider->getData();
176183
}
177184

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ public function __construct(
8080
public function generateProductUrlRewrites(\Magento\Catalog\Model\Category $category)
8181
{
8282
$mergeDataProvider = clone $this->mergeDataProviderPrototype;
83-
$this->isSkippedProduct = [];
83+
$this->isSkippedProduct[$category->getEntityId()] = [];
8484
$saveRewriteHistory = $category->getData('save_rewrites_history');
8585
$storeId = $category->getStoreId();
8686
if ($category->getAffectedProductIds()) {
87-
$this->isSkippedProduct = $category->getAffectedProductIds();
87+
$this->isSkippedProduct[$category->getEntityId()] = $category->getAffectedProductIds();
8888
$collection = $this->productCollectionFactory->create()
8989
->setStoreId($storeId)
9090
->addIdFilter($category->getAffectedProductIds())
@@ -137,17 +137,25 @@ public function getCategoryProductsUrlRewrites(
137137
$rootCategoryId = null
138138
) {
139139
$mergeDataProvider = clone $this->mergeDataProviderPrototype;
140+
140141
/** @var \Magento\Catalog\Model\ResourceModel\Product\Collection $productCollection */
141-
$productCollection = $category->getProductCollection()
142+
$productCollection = $this->productCollectionFactory->create();//$category->getProductCollection()
143+
144+
$productCollection->addCategoriesFilter(['eq' => [$category->getEntityId()]])
145+
->setStoreId($storeId)
142146
->addAttributeToSelect('name')
143147
->addAttributeToSelect('visibility')
144148
->addAttributeToSelect('url_key')
145149
->addAttributeToSelect('url_path');
150+
146151
foreach ($productCollection as $product) {
147-
if (in_array($product->getId(), $this->isSkippedProduct)) {
152+
if (
153+
isset($this->isSkippedProduct[$category->getEntityId()]) &&
154+
in_array($product->getId(), $this->isSkippedProduct[$category->getEntityId()])
155+
) {
148156
continue;
149157
}
150-
$this->isSkippedProduct[] = $product->getId();
158+
$this->isSkippedProduct[$category->getEntityId()][] = $product->getId();
151159
$product->setStoreId($storeId);
152160
$product->setData('save_rewrites_history', $saveRewriteHistory);
153161
$mergeDataProvider->merge(

0 commit comments

Comments
 (0)