Skip to content

Commit c865bdc

Browse files
author
Vitaliy Boyko
committed
ENGCOM-20434: refactoring, test coverage
1 parent 5687704 commit c865bdc

File tree

7 files changed

+478
-71
lines changed

7 files changed

+478
-71
lines changed
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\CatalogUrlRewrite\Model\Products;
9+
10+
use Magento\Catalog\Api\Data\ProductInterface;
11+
use Magento\Catalog\Model\Product;
12+
use Magento\Catalog\Model\Product\Visibility;
13+
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
14+
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
15+
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
16+
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
17+
use Magento\UrlRewrite\Model\UrlPersistInterface;
18+
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
19+
20+
/**
21+
* Save/Delete UrlRewrites by Product ID's and visibility
22+
*/
23+
class AdaptUrlRewritesToVisibilityAttribute
24+
{
25+
/**
26+
* @var CollectionFactory
27+
*/
28+
private $productCollectionFactory;
29+
30+
/**
31+
* @var ProductUrlRewriteGenerator
32+
*/
33+
private $urlRewriteGenerator;
34+
35+
/**
36+
* @var UrlPersistInterface
37+
*/
38+
private $urlPersist;
39+
40+
/**
41+
* @var ProductUrlPathGenerator
42+
*/
43+
private $urlPathGenerator;
44+
45+
/**
46+
* @param CollectionFactory $collectionFactory
47+
* @param ProductUrlRewriteGenerator $urlRewriteGenerator
48+
* @param UrlPersistInterface $urlPersist
49+
* @param ProductUrlPathGenerator|null $urlPathGenerator
50+
*/
51+
public function __construct(
52+
CollectionFactory $collectionFactory,
53+
ProductUrlRewriteGenerator $urlRewriteGenerator,
54+
UrlPersistInterface $urlPersist,
55+
ProductUrlPathGenerator $urlPathGenerator
56+
) {
57+
$this->productCollectionFactory = $collectionFactory;
58+
$this->urlRewriteGenerator = $urlRewriteGenerator;
59+
$this->urlPersist = $urlPersist;
60+
$this->urlPathGenerator = $urlPathGenerator;
61+
}
62+
63+
/**
64+
* @param array $productIds
65+
* @param int $visibility
66+
* @throws UrlAlreadyExistsException
67+
*/
68+
public function execute(array $productIds, int $visibility): void
69+
{
70+
$products = $this->getProductsByIds($productIds);
71+
72+
/** @var Product $product */
73+
foreach ($products as $product) {
74+
if ($visibility == Visibility::VISIBILITY_NOT_VISIBLE) {
75+
$this->urlPersist->deleteByData(
76+
[
77+
UrlRewrite::ENTITY_ID => $product->getId(),
78+
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
79+
]
80+
);
81+
} elseif ($visibility !== Visibility::VISIBILITY_NOT_VISIBLE) {
82+
$product->setVisibility($visibility);
83+
$productUrlPath = $this->urlPathGenerator->getUrlPath($product);
84+
$productUrlRewrite = $this->urlRewriteGenerator->generate($product);
85+
$product->unsUrlPath();
86+
$product->setUrlPath($productUrlPath);
87+
88+
try {
89+
$this->urlPersist->replace($productUrlRewrite);
90+
} catch (UrlAlreadyExistsException $e) {
91+
throw new UrlAlreadyExistsException(
92+
__(
93+
'Can not change the visibility of the product with SKU equals "%1". URL key "%2" for specified store already exists.',
94+
$product->getSku(),
95+
$product->getUrlKey()
96+
),
97+
$e,
98+
$e->getCode(),
99+
$e->getUrls()
100+
);
101+
}
102+
}
103+
}
104+
}
105+
106+
/**
107+
* @param array $productIds
108+
* @return array
109+
*/
110+
protected function getProductsByIds(array $productIds): array
111+
{
112+
$productCollection = $this->productCollectionFactory->create();
113+
$productCollection->addAttributeToSelect(ProductInterface::VISIBILITY);
114+
$productCollection->addAttributeToSelect('url_key');
115+
$productCollection->addFieldToFilter(
116+
'entity_id',
117+
['in' => array_unique($productIds)]
118+
);
119+
120+
return $productCollection->getItems();
121+
}
122+
}

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

Lines changed: 14 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -8,104 +8,47 @@
88
namespace Magento\CatalogUrlRewrite\Observer;
99

1010
use Magento\Catalog\Api\Data\ProductInterface;
11-
use Magento\Catalog\Model\Product\Visibility;
12-
use Magento\CatalogUrlRewrite\Model\ProductUrlPathGenerator;
13-
use Magento\CatalogUrlRewrite\Model\ProductUrlRewriteGenerator;
14-
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
15-
use Magento\UrlRewrite\Model\UrlPersistInterface;
16-
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
17-
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
11+
use Magento\CatalogUrlRewrite\Model\Products\AdaptUrlRewritesToVisibilityAttribute;
1812
use Magento\Framework\Event\Observer;
1913
use Magento\Framework\Event\ObserverInterface;
14+
use Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException;
2015

2116
/**
22-
* Class ProductProcessUrlRewriteSavingObserver
17+
* Consider URL rewrites on change product visibility via mass action
2318
*/
2419
class ProcessUrlRewriteOnChangeProductVisibilityObserver implements ObserverInterface
2520
{
2621
/**
27-
* @var CollectionFactory
28-
*/
29-
private $productCollectionFactory;
30-
31-
/**
32-
* @var ProductUrlRewriteGenerator
33-
*/
34-
private $urlRewriteGenerator;
35-
36-
/**
37-
* @var UrlPersistInterface
22+
* @var AdaptUrlRewritesToVisibilityAttribute
3823
*/
39-
private $urlPersist;
24+
private $adaptUrlRewritesToVisibility;
4025

4126
/**
42-
* @var ProductUrlPathGenerator
27+
* @param AdaptUrlRewritesToVisibilityAttribute $adaptUrlRewritesToVisibility
4328
*/
44-
private $urlPathGenerator;
45-
46-
/**
47-
* @param CollectionFactory $collectionFactory
48-
* @param ProductUrlRewriteGenerator $urlRewriteGenerator
49-
* @param UrlPersistInterface $urlPersist
50-
* @param ProductUrlPathGenerator|null $urlPathGenerator
51-
*/
52-
public function __construct(
53-
CollectionFactory $collectionFactory,
54-
ProductUrlRewriteGenerator $urlRewriteGenerator,
55-
UrlPersistInterface $urlPersist,
56-
ProductUrlPathGenerator $urlPathGenerator
57-
) {
58-
$this->productCollectionFactory = $collectionFactory;
59-
$this->urlRewriteGenerator = $urlRewriteGenerator;
60-
$this->urlPersist = $urlPersist;
61-
$this->urlPathGenerator = $urlPathGenerator;
29+
public function __construct(AdaptUrlRewritesToVisibilityAttribute $adaptUrlRewritesToVisibility)
30+
{
31+
$this->adaptUrlRewritesToVisibility = $adaptUrlRewritesToVisibility;
6232
}
6333

6434
/**
6535
* Generate urls for UrlRewrites and save it in storage
6636
*
6737
* @param Observer $observer
68-
* @return array
38+
* @return void
6939
* @throws UrlAlreadyExistsException
7040
*/
7141
public function execute(Observer $observer)
7242
{
7343
$event = $observer->getEvent();
7444
$attrData = $event->getAttributesData();
7545
$productIds = $event->getProductIds();
76-
$storeId = $event->getStoreId();
77-
$visibility = $attrData[ProductInterface::VISIBILITY] ?? null;
78-
79-
if (!$visibility) {
80-
return [$attrData, $productIds, $storeId];
81-
}
82-
83-
$productCollection = $this->productCollectionFactory->create();
84-
$productCollection->addAttributeToSelect(ProductInterface::VISIBILITY);
85-
$productCollection->addAttributeToSelect('url_key');
86-
$productCollection->addFieldToFilter(
87-
'entity_id',
88-
['in' => array_unique($productIds)]
89-
);
46+
$visibility = $attrData[ProductInterface::VISIBILITY] ?? 0;
9047

91-
foreach ($productCollection as $product) {
92-
if ($visibility == Visibility::VISIBILITY_NOT_VISIBLE) {
93-
$this->urlPersist->deleteByData(
94-
[
95-
UrlRewrite::ENTITY_ID => $product->getId(),
96-
UrlRewrite::ENTITY_TYPE => ProductUrlRewriteGenerator::ENTITY_TYPE,
97-
]
98-
);
99-
} elseif ($visibility !== Visibility::VISIBILITY_NOT_VISIBLE) {
100-
$product->setVisibility($visibility);
101-
$productUrlPath = $this->urlPathGenerator->getUrlPath($product);
102-
$productUrlRewrite = $this->urlRewriteGenerator->generate($product);
103-
$product->unsUrlPath();
104-
$product->setUrlPath($productUrlPath);
105-
$this->urlPersist->replace($productUrlRewrite);
106-
}
48+
if (!$visibility || !$productIds) {
49+
return;
10750
}
10851

109-
return [$attrData, $productIds, $storeId];
52+
$this->adaptUrlRewritesToVisibility->execute($productIds, $visibility);
11053
}
11154
}

0 commit comments

Comments
 (0)