6
6
namespace Magento \CatalogUrlRewrite \Observer ;
7
7
8
8
use Magento \Catalog \Model \Product ;
9
+ use Magento \Catalog \Model \ProductRepository ;
10
+ use Magento \CatalogUrlRewrite \Model \ProductScopeRewriteGenerator ;
9
11
use Magento \CatalogUrlRewrite \Model \ProductUrlPathGenerator ;
10
12
use Magento \CatalogUrlRewrite \Model \ProductUrlRewriteGenerator ;
11
- use Magento \Framework \App \ObjectManager ;
13
+ use Magento \Framework \Event \Observer ;
14
+ use Magento \Framework \Exception \NoSuchEntityException ;
15
+ use Magento \UrlRewrite \Model \Exception \UrlAlreadyExistsException ;
12
16
use Magento \UrlRewrite \Model \UrlPersistInterface ;
13
17
use Magento \Framework \Event \ObserverInterface ;
14
- use Magento \Catalog \Model \Product \Visibility ;
15
18
use Magento \Store \Model \StoreManagerInterface ;
16
- use Magento \UrlRewrite \Service \V1 \Data \UrlRewrite ;
17
19
use Magento \Store \Api \StoreWebsiteRelationInterface ;
20
+ use Magento \UrlRewrite \Model \Storage \DbStorage ;
21
+ use Magento \Store \Model \Store ;
18
22
19
23
/**
20
24
* Class ProductProcessUrlRewriteSavingObserver
@@ -50,38 +54,61 @@ class ProductProcessUrlRewriteSavingObserver implements ObserverInterface
50
54
*/
51
55
private $ storeWebsiteRelation ;
52
56
57
+ /**
58
+ * @var ProductRepository $productRepository
59
+ */
60
+ private $ productRepository ;
61
+
62
+ /**
63
+ * @var ProductScopeRewriteGenerator
64
+ */
65
+ private $ productScopeRewriteGenerator ;
66
+
67
+ /**
68
+ * @var DbStorage
69
+ */
70
+ private $ dbStorage ;
71
+
53
72
/**
54
73
* @param ProductUrlRewriteGenerator $productUrlRewriteGenerator
55
74
* @param UrlPersistInterface $urlPersist
56
- * @param ProductUrlPathGenerator|null $productUrlPathGenerator
57
- * @param StoreManagerInterface|null $storeManager
58
- * @param StoreWebsiteRelationInterface|null $storeWebsiteRelation
75
+ * @param ProductUrlPathGenerator $productUrlPathGenerator
76
+ * @param StoreManagerInterface $storeManager
77
+ * @param StoreWebsiteRelationInterface $storeWebsiteRelation
78
+ * @param ProductRepository $productRepository
79
+ * @param ProductScopeRewriteGenerator $productScopeRewriteGenerator
80
+ * @param DbStorage $dbStorage
59
81
*/
60
82
public function __construct (
61
83
ProductUrlRewriteGenerator $ productUrlRewriteGenerator ,
62
84
UrlPersistInterface $ urlPersist ,
63
- ProductUrlPathGenerator $ productUrlPathGenerator = null ,
64
- StoreManagerInterface $ storeManager = null ,
65
- StoreWebsiteRelationInterface $ storeWebsiteRelation = null
85
+ ProductUrlPathGenerator $ productUrlPathGenerator ,
86
+ StoreManagerInterface $ storeManager ,
87
+ StoreWebsiteRelationInterface $ storeWebsiteRelation ,
88
+ ProductRepository $ productRepository ,
89
+ ProductScopeRewriteGenerator $ productScopeRewriteGenerator ,
90
+ DbStorage $ dbStorage
66
91
) {
67
92
$ this ->productUrlRewriteGenerator = $ productUrlRewriteGenerator ;
68
93
$ this ->urlPersist = $ urlPersist ;
69
- $ this ->productUrlPathGenerator = $ productUrlPathGenerator ?: ObjectManager:: getInstance ()
70
- -> get (ProductUrlPathGenerator::class) ;
71
- $ this ->storeManager = $ storeManager ?: ObjectManager:: getInstance ()
72
- -> get (StoreManagerInterface::class) ;
73
- $ this ->storeWebsiteRelation = $ storeWebsiteRelation ?: ObjectManager:: getInstance ()
74
- -> get (StoreWebsiteRelationInterface::class) ;
94
+ $ this ->productUrlPathGenerator = $ productUrlPathGenerator;
95
+ $ this -> storeManager = $ storeManager ;
96
+ $ this ->storeWebsiteRelation = $ storeWebsiteRelation ;
97
+ $ this -> productRepository = $ productRepository ;
98
+ $ this ->productScopeRewriteGenerator = $ productScopeRewriteGenerator ;
99
+ $ this -> dbStorage = $ dbStorage ;
75
100
}
76
101
77
102
/**
78
103
* Generate urls for UrlRewrite and save it in storage
79
104
*
80
- * @param \Magento\Framework\Event\ Observer $observer
105
+ * @param Observer $observer
81
106
* @return void
82
- * @throws \Magento\UrlRewrite\Model\Exception\UrlAlreadyExistsException
107
+ * @throws UrlAlreadyExistsException
108
+ * @throws NoSuchEntityException
109
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
83
110
*/
84
- public function execute (\ Magento \ Framework \ Event \ Observer $ observer )
111
+ public function execute (Observer $ observer )
85
112
{
86
113
/** @var Product $product */
87
114
$ product = $ observer ->getEvent ()->getProduct ();
@@ -91,24 +118,45 @@ public function execute(\Magento\Framework\Event\Observer $observer)
91
118
|| $ product ->getIsChangedWebsites ()
92
119
|| $ product ->dataHasChangedFor ('visibility ' )
93
120
) {
94
- if ($ product ->getVisibility () != Visibility::VISIBILITY_NOT_VISIBLE ) {
95
- $ product ->unsUrlPath ();
96
- $ product ->setUrlPath ($ this ->productUrlPathGenerator ->getUrlPath ($ product ));
121
+ //Refresh rewrite urls
122
+ $ product ->unsUrlPath ();
123
+ $ product ->setUrlPath ($ this ->productUrlPathGenerator ->getUrlPath ($ product ));
124
+ if (!empty ($ this ->productUrlRewriteGenerator ->generate ($ product ))) {
97
125
$ this ->urlPersist ->replace ($ this ->productUrlRewriteGenerator ->generate ($ product ));
126
+ }
98
127
99
- //Remove any rewrite URLs for websites the product is not in
128
+ $ storeIdsToRemove = [];
129
+ if ($ this ->productScopeRewriteGenerator ->isGlobalScope ($ product ->getStoreId ())) {
130
+ //Remove any rewrite URLs for websites the product is not in, or is not visible in. Global Scope.
100
131
foreach ($ this ->storeManager ->getWebsites () as $ website ) {
101
132
$ 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
- }
133
+ foreach ($ this ->storeWebsiteRelation ->getStoreByWebsiteId ($ websiteId ) as $ storeid ) {
134
+ //Load the product for the store we are processing so we can see if it is visible
135
+ $ storeProduct = $ this ->productRepository ->getById (
136
+ $ product ->getId (),
137
+ false ,
138
+ $ storeid ,
139
+ true
140
+ );
141
+ if (!$ storeProduct ->isVisibleInSiteVisibility () ||
142
+ !in_array ($ websiteId , $ product ->getWebsiteIds ())) {
143
+ $ storeIdsToRemove [] = $ storeid ;
144
+ };
110
145
}
111
146
}
147
+ } else {
148
+ //Only remove rewrite for current scope
149
+ if (!$ product ->isVisibleInSiteVisibility () ||
150
+ !in_array ($ product ->getStoreId (), $ product ->getStoreIds ())) {
151
+ $ storeIdsToRemove [] = $ product ->getStoreId ();
152
+ }
153
+ }
154
+ if (count ($ storeIdsToRemove )) {
155
+ $ this ->dbStorage ->deleteEntitiesFromStores (
156
+ $ storeIdsToRemove ,
157
+ [$ product ->getId ()],
158
+ ProductUrlRewriteGenerator::ENTITY_TYPE
159
+ );
112
160
}
113
161
}
114
162
}
0 commit comments