Skip to content

Commit 0f92be1

Browse files
author
Graham Wharton
committed
Fixed URL Rewrite generation and removal on product/website change.
Moved scope of ProductToWebsiteChangeObserver to base instead of adminhtml as this functionality has been moved to a consumer. With the observer set to adminhtml, this observer was not being called properly on changing the websites for a particular product in the consumer. Corrected ProductProcessUrlRewriteSavingObserver to correctly add and remove rewrite URLs when products are added and removed from websites using the Product Edit Admin Page. Corrected ProductToWebsiteChangeObserver to correctly add and remove rewrite URLs when products are added and removed using the Products Grid Mass Action function. Extended unit tests to cover both Observers. Fixed MFTF test for Product URL Rewrite generation.
1 parent 48423d7 commit 0f92be1

File tree

8 files changed

+465
-65
lines changed

8 files changed

+465
-65
lines changed

app/code/Magento/Catalog/Model/Product/Action.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,14 @@ public function updateWebsites($productIds, $websiteIds, $type)
169169
$categoryIndexer->reindexList(array_unique($productIds));
170170
}
171171

172-
$this->_eventManager->dispatch('catalog_product_to_website_change', ['products' => $productIds]);
172+
//Dispatch event to update Rewrite URLs for new/removed websites
173+
$this->_eventManager->dispatch(
174+
'catalog_product_to_website_change',
175+
[
176+
'products' => $productIds,
177+
'website_ids' => $websiteIds,
178+
'action_type' => $type
179+
]
180+
);
173181
}
174182
}

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

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,17 @@
1111
use Magento\Framework\App\ObjectManager;
1212
use Magento\UrlRewrite\Model\UrlPersistInterface;
1313
use Magento\Framework\Event\ObserverInterface;
14+
use Magento\Catalog\Model\Product\Visibility;
15+
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
17+
use Magento\Store\Api\StoreWebsiteRelationInterface;
1418

1519
/**
1620
* Class ProductProcessUrlRewriteSavingObserver
21+
*
22+
* Observer to update the Rewrite URLs for a product.
23+
* This observer is triggered on the save function when making changes
24+
* to the products website on the Product Edit page.
1725
*/
1826
class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
1927
{
@@ -32,20 +40,38 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
3240
*/
3341
private $productUrlPathGenerator;
3442

43+
/**
44+
* @var StoreManagerInterface $storeManager
45+
*/
46+
private $storeManager;
47+
48+
/**
49+
* @var StoreWebsiteRelationInterface
50+
*/
51+
private $storeWebsiteRelation;
52+
3553
/**
3654
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
3755
* @param UrlPersistInterface $urlPersist
3856
* @param ProductUrlPathGenerator|null $productUrlPathGenerator
57+
* @param StoreManagerInterface|null $storeManager
58+
* @param StoreWebsiteRelationInterface|null $storeWebsiteRelation
3959
*/
4060
public function __construct(
4161
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
4262
UrlPersistInterface $urlPersist,
43-
ProductUrlPathGenerator $productUrlPathGenerator = null
63+
ProductUrlPathGenerator $productUrlPathGenerator = null,
64+
StoreManagerInterface $storeManager = null,
65+
StoreWebsiteRelationInterface $storeWebsiteRelation = null
4466
) {
4567
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
4668
$this->urlPersist = $urlPersist;
4769
$this->productUrlPathGenerator = $productUrlPathGenerator ?: ObjectManager::getInstance()
4870
->get(ProductUrlPathGenerator::class);
71+
$this->storeManager = $storeManager ?: ObjectManager::getInstance()
72+
->get(StoreManagerInterface::class);
73+
$this->storeWebsiteRelation = $storeWebsiteRelation ?: ObjectManager::getInstance()
74+
->get(StoreWebsiteRelationInterface::class);
4975
}
5076

5177
/**
@@ -65,10 +91,24 @@ public function execute(\Magento\Framework\Event\Observer $observer)
6591
|| $product->getIsChangedWebsites()
6692
|| $product->dataHasChangedFor('visibility')
6793
) {
68-
if ($product->isVisibleInSiteVisibility()) {
94+
if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) {
6995
$product->unsUrlPath();
7096
$product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product));
7197
$this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
98+
99+
//Remove any rewrite URLs for websites the product is not in
100+
foreach ($this->storeManager->getWebsites() as $website) {
101+
$websiteId = $website->getWebsiteId();
102+
if (!in_array($websiteId, $product->getWebsiteIds())) {
103+
foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($websiteId) as $storeId) {
104+
$this->urlPersist->deleteByData([
105+
UrlRewrite::ENTITY_ID => $product->getId(),
106+
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
107+
UrlRewrite::STORE_ID => $storeId
108+
]);
109+
}
110+
}
111+
}
72112
}
73113
}
74114
}

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

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@
1717
use Magento\Framework\App\ObjectManager;
1818

1919
/**
20-
* Observer to assign the products to website
20+
* Class ProductToWebsiteChangeObserver
21+
*
22+
* Observer to update the Rewrite URLs for a product.
23+
* This observer is triggered by the product_action_attribute.website.update
24+
* consumer in response to Mass Action changes in the Admin Product Grid.
2125
*/
2226
class ProductToWebsiteChangeObserver implements ObserverInterface
2327
{
@@ -36,11 +40,6 @@ class ProductToWebsiteChangeObserver implements ObserverInterface
3640
*/
3741
protected $productRepository;
3842

39-
/**
40-
* @var RequestInterface
41-
*/
42-
protected $request;
43-
4443
/**
4544
* @var StoreWebsiteRelationInterface
4645
*/
@@ -52,6 +51,8 @@ class ProductToWebsiteChangeObserver implements ObserverInterface
5251
* @param ProductRepositoryInterface $productRepository
5352
* @param RequestInterface $request
5453
* @param StoreWebsiteRelationInterface $storeWebsiteRelation
54+
*
55+
* * @SuppressWarnings(PHPMD.UnusedFormalParameter)
5556
*/
5657
public function __construct(
5758
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
@@ -63,7 +64,6 @@ public function __construct(
6364
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
6465
$this->urlPersist = $urlPersist;
6566
$this->productRepository = $productRepository;
66-
$this->request = $request;
6767
$this->storeWebsiteRelation = $storeWebsiteRelation ?:
6868
ObjectManager::getInstance()->get(StoreWebsiteRelationInterface::class);
6969
}
@@ -77,24 +77,29 @@ public function __construct(
7777
public function execute(\Magento\Framework\Event\Observer $observer)
7878
{
7979
foreach ($observer->getEvent()->getProducts() as $productId) {
80+
/* @var \Magento\Catalog\Model\Product $product */
8081
$product = $this->productRepository->getById(
8182
$productId,
8283
false,
83-
$this->request->getParam('store_id', Store::DEFAULT_STORE_ID)
84+
Store::DEFAULT_STORE_ID,
85+
true
8486
);
8587

86-
if (!empty($this->productUrlRewriteGenerator->generate($product))) {
87-
if ($this->request->getParam('remove_website_ids')) {
88-
foreach ($this->request->getParam('remove_website_ids') as $webId) {
89-
foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeId) {
90-
$this->urlPersist->deleteByData([
91-
UrlRewrite::ENTITY_ID => $product->getId(),
92-
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
93-
UrlRewrite::STORE_ID => $storeId
94-
]);
95-
}
88+
// Remove the URLs from websites this product no longer belongs to
89+
if ($observer->getEvent()->getActionType() == "remove" && $observer->getEvent()->getWebsiteIds()) {
90+
foreach ($observer->getEvent()->getWebsiteIds() as $webId) {
91+
foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeId) {
92+
$this->urlPersist->deleteByData([
93+
UrlRewrite::ENTITY_ID => $product->getId(),
94+
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
95+
UrlRewrite::STORE_ID => $storeId
96+
]);
9697
}
9798
}
99+
}
100+
101+
// Refresh all existing URLs for the product
102+
if (!empty($this->productUrlRewriteGenerator->generate($product))) {
98103
if ($product->getVisibility() != Visibility::VISIBILITY_NOT_VISIBLE) {
99104
$this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
100105
}

0 commit comments

Comments
 (0)