Skip to content

Commit

Permalink
ENGCOM-7162: Fixed URL Rewrite addition/removal on product website ad…
Browse files Browse the repository at this point in the history
…d/remove #26999
  • Loading branch information
slavvka authored Mar 28, 2020
2 parents 259e16d + 9e1298e commit d8a31d4
Show file tree
Hide file tree
Showing 48 changed files with 1,534 additions and 236 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@
*/
namespace Magento\CatalogUrlRewrite\Observer;

use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
use Magento\CatalogUrlRewrite\Model\ProductScopeRewriteGenerator;
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Event\Observer;
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
use Magento\UrlRewrite\Model\Storage\DeleteEntitiesFromStores;
use Magento\UrlRewrite\Model\UrlPersistInterface;
use Magento\Framework\Event\ObserverInterface;
use Magento\Store\Model\StoreManagerInterface;

/**
* Class ProductProcessUrlRewriteSavingObserver
*
* Observer to update the Rewrite URLs for a product.
* This observer is triggered on the save function when making changes
* to the products website on the Product Edit page.
*/
class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
{
Expand All @@ -32,30 +43,62 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
*/
private $productUrlPathGenerator;

/**
* @var StoreManagerInterface
*/
private $storeManager;

/**
* @var ProductScopeRewriteGenerator
*/
private $productScopeRewriteGenerator;

/**
* @var DeleteEntitiesFromStores
*/
private $deleteEntitiesFromStores;

/**
* @var CollectionFactory
*/
private $collectionFactory;

/**
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
* @param UrlPersistInterface $urlPersist
* @param ProductUrlPathGenerator|null $productUrlPathGenerator
* @param ProductUrlPathGenerator $productUrlPathGenerator
* @param StoreManagerInterface $storeManager
* @param ProductScopeRewriteGenerator $productScopeRewriteGenerator
* @param DeleteEntitiesFromStores $deleteEntitiesFromStores
* @param CollectionFactory $collectionFactory
*/
public function __construct(
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
UrlPersistInterface $urlPersist,
ProductUrlPathGenerator $productUrlPathGenerator = null
ProductUrlPathGenerator $productUrlPathGenerator,
StoreManagerInterface $storeManager,
ProductScopeRewriteGenerator $productScopeRewriteGenerator,
DeleteEntitiesFromStores $deleteEntitiesFromStores,
CollectionFactory $collectionFactory
) {
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
$this->urlPersist = $urlPersist;
$this->productUrlPathGenerator = $productUrlPathGenerator ?: ObjectManager::getInstance()
->get(ProductUrlPathGenerator::class);
$this->productUrlPathGenerator = $productUrlPathGenerator;
$this->storeManager = $storeManager;
$this->productScopeRewriteGenerator = $productScopeRewriteGenerator;
$this->deleteEntitiesFromStores = $deleteEntitiesFromStores;
$this->collectionFactory = $collectionFactory;
}

/**
* Generate urls for UrlRewrite and save it in storage
*
* @param \Magento\Framework\Event\Observer $observer
* @param Observer $observer
* @return void
* @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException
* @throws UrlAlreadyExistsException
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function execute(\Magento\Framework\Event\Observer $observer)
public function execute(Observer $observer)
{
/** @var Product $product */
$product = $observer->getEvent()->getProduct();
Expand All @@ -65,11 +108,49 @@ public function execute(\Magento\Framework\Event\Observer $observer)
|| $product->getIsChangedWebsites()
|| $product->dataHasChangedFor('visibility')
) {
if ($product->isVisibleInSiteVisibility()) {
$product->unsUrlPath();
$product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product));
//Refresh rewrite urls
$product->unsUrlPath();
$product->setUrlPath($this->productUrlPathGenerator->getUrlPath($product));
if (!empty($this->productUrlRewriteGenerator->generate($product))) {
$this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
}

$storeIdsToRemove = [];
$productWebsiteMap = array_flip($product->getWebsiteIds());
$storeVisibilities = $this->collectionFactory->create()
->getAllAttributeValues(ProductInterface::VISIBILITY);
if ($this->productScopeRewriteGenerator->isGlobalScope($product->getStoreId())) {
//Remove any rewrite URLs for websites the product is not in, or is not visible in. Global Scope.
foreach ($this->storeManager->getStores() as $store) {
$websiteId = $store->getWebsiteId();
$storeId = $store->getStoreId();
if (!isset($productWebsiteMap[$websiteId])) {
$storeIdsToRemove[] = $storeId;
continue;
}
//Check the visibility of the product in each store.
if (isset($storeVisibilities[$product->getId()][$storeId])
&& ($storeVisibilities[$product->getId()][$storeId] === Visibility::VISIBILITY_NOT_VISIBLE)) {
$storeIdsToRemove[] = $storeId;
}
}
} else {
//Only remove rewrite for current scope
$websiteId = $product->getStore()->getWebsiteId();
$storeId = $product->getStoreId();
if (!isset($productWebsiteMap[$websiteId]) ||
(isset($storeVisibilities[$product->getId()][$storeId])
&& ($storeVisibilities[$product->getId()][$storeId] === Visibility::VISIBILITY_NOT_VISIBLE))) {
$storeIdsToRemove[] = $storeId;
}
}
if (count($storeIdsToRemove)) {
$this->deleteEntitiesFromStores->execute(
$storeIdsToRemove,
[$product->getId()],
ProductUrlRewriteGenerator::ENTITY_TYPE
);
}
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogUrlRewrite\Plugin;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Product\Action;
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
use Magento\Store\Api\StoreWebsiteRelationInterface;
use Magento\Store\Model\Store;
use Magento\UrlRewrite\Model\Storage\DeleteEntitiesFromStores;
use Magento\UrlRewrite\Model\UrlPersistInterface;

/**
* Class ProductProcessUrlRewriteRemovingPlugin
*
* Plugin to update the Rewrite URLs for a product.
* This plugin is triggered by the product_action_attribute.website.update
* consumer in response to Mass Action changes in the Admin Product Grid.
*/
class ProductProcessUrlRewriteRemovingPlugin
{
/**
* @var ProductRepositoryInterface
*/
private $productRepository;

/**
* @var StoreWebsiteRelationInterface
*/
private $storeWebsiteRelation;

/**
* @var UrlPersistInterface
*/
private $urlPersist;

/**
* @var ProductUrlRewriteGenerator
*/
private $productUrlRewriteGenerator;

/**
* @var DeleteEntitiesFromStores
*/
private $deleteEntitiesFromStores;

/**
* @param ProductRepositoryInterface $productRepository
* @param StoreWebsiteRelationInterface $storeWebsiteRelation
* @param UrlPersistInterface $urlPersist
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
* @param DeleteEntitiesFromStores $deleteEntitiesFromStores
*/
public function __construct(
ProductRepositoryInterface $productRepository,
StoreWebsiteRelationInterface $storeWebsiteRelation,
UrlPersistInterface $urlPersist,
ProductUrlRewriteGenerator $productUrlRewriteGenerator,
DeleteEntitiesFromStores $deleteEntitiesFromStores
) {
$this->productRepository = $productRepository;
$this->storeWebsiteRelation = $storeWebsiteRelation;
$this->urlPersist = $urlPersist;
$this->productUrlRewriteGenerator = $productUrlRewriteGenerator;
$this->deleteEntitiesFromStores = $deleteEntitiesFromStores;
}

/**
* Function afterUpdateWebsites
*
* @param Action $subject
* @param void $result
* @param array $productIds
* @param array $websiteIds
* @param string $type
* @return void
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
*/
public function afterUpdateWebsites(
Action $subject,
$result,
$productIds,
$websiteIds,
$type
) {
foreach ($productIds as $productId) {
/* @var Product $product */
$product = $this->productRepository->getById(
$productId,
false,
Store::DEFAULT_STORE_ID,
true
);

// Refresh all existing URLs for the product
if (!empty($this->productUrlRewriteGenerator->generate($product))) {
if ($product->isVisibleInSiteVisibility()) {
$this->urlPersist->replace($this->productUrlRewriteGenerator->generate($product));
}
}
}

$storeIdsToRemove = [];
// Remove the URLs for products in $productIds array
// from all stores that belong to websites in $websiteIds array
if ($type === "remove" && $websiteIds && $productIds) {
foreach ($websiteIds as $webId) {
foreach ($this->storeWebsiteRelation->getStoreByWebsiteId($webId) as $storeid) {
$storeIdsToRemove[] = $storeid;
}
}
if (count($storeIdsToRemove)) {
$this->deleteEntitiesFromStores->execute(
$storeIdsToRemove,
$productIds,
ProductUrlRewriteGenerator::ENTITY_TYPE
);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<testCaseId value="MC-17515"/>
<useCaseId value="MAGETWO-69825"/>
<group value="CatalogUrlRewrite"/>
<group value="urlRewrite"/>
</annotations>
<before>
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
Expand Down
Loading

0 comments on commit d8a31d4

Please sign in to comment.