8
8
namespace Magento \UrlRewrite \Model ;
9
9
10
10
use Magento \Framework \App \ObjectManager ;
11
+ use Magento \Framework \Data \Collection \AbstractDb ;
12
+ use Magento \Framework \EntityManager \EventManager ;
13
+ use Magento \Framework \Indexer \CacheContext ;
14
+ use Magento \Framework \Model \AbstractModel ;
15
+ use Magento \Framework \Model \Context ;
16
+ use Magento \Framework \Model \ResourceModel \AbstractResource ;
17
+ use Magento \Framework \Registry ;
11
18
use Magento \Framework \Serialize \Serializer \Json ;
19
+ use Magento \UrlRewrite \Controller \Adminhtml \Url \Rewrite ;
20
+ use Magento \UrlRewrite \Model \ResourceModel \UrlRewriteCollection ;
21
+ use Magento \UrlRewrite \Service \V1 \Data \UrlRewrite as UrlRewriteService ;
12
22
13
23
/**
14
24
* UrlRewrite model class
27
37
* @method UrlRewrite setStoreId($value)
28
38
* @method UrlRewrite setDescription($value)
29
39
*/
30
- class UrlRewrite extends \ Magento \ Framework \ Model \ AbstractModel
40
+ class UrlRewrite extends AbstractModel
31
41
{
32
42
/**
33
43
* @var Json
34
44
*/
35
45
private $ serializer ;
36
46
47
+ /**
48
+ * @var CacheContext|mixed|null
49
+ */
50
+ private $ cacheContext ;
51
+
52
+ /**
53
+ * @var EventManager|mixed|null
54
+ */
55
+ private $ eventManager ;
56
+
57
+ /**
58
+ * @var array
59
+ */
60
+ private $ entityToCacheTagMap ;
61
+
62
+ /**
63
+ * @var UrlFinderInterface
64
+ */
65
+ private $ urlFinder ;
66
+
37
67
/**
38
68
* UrlRewrite constructor.
39
69
*
40
- * @param \Magento\Framework\Model\ Context $context
41
- * @param \Magento\Framework\ Registry $registry
42
- * @param \Magento\Framework\Model\ResourceModel\ AbstractResource|null $resource
43
- * @param \Magento\Framework\Data\Collection\ AbstractDb|null $resourceCollection
70
+ * @param Context $context
71
+ * @param Registry $registry
72
+ * @param AbstractResource|null $resource
73
+ * @param AbstractDb|null $resourceCollection
44
74
* @param array $data
45
- * @param Json $serializer
75
+ * @param Json|null $serializer
76
+ * @param CacheContext|null $cacheContext
77
+ * @param EventManager|null $eventManager
78
+ * @param UrlFinderInterface|null $urlFinder
79
+ * @param array $entityToCacheTagMap
46
80
*/
47
81
public function __construct (
48
- \ Magento \ Framework \ Model \ Context $ context ,
49
- \ Magento \ Framework \ Registry $ registry ,
50
- \ Magento \ Framework \ Model \ ResourceModel \ AbstractResource $ resource = null ,
51
- \ Magento \ Framework \ Data \ Collection \ AbstractDb $ resourceCollection = null ,
82
+ Context $ context ,
83
+ Registry $ registry ,
84
+ AbstractResource $ resource = null ,
85
+ AbstractDb $ resourceCollection = null ,
52
86
array $ data = [],
53
- Json $ serializer = null
54
- ) {
87
+ Json $ serializer = null ,
88
+ CacheContext $ cacheContext = null ,
89
+ EventManager $ eventManager = null ,
90
+ UrlFinderInterface $ urlFinder = null ,
91
+ array $ entityToCacheTagMap = []
92
+ )
93
+ {
55
94
$ this ->serializer = $ serializer ?: ObjectManager::getInstance ()->get (Json::class);
95
+ $ this ->cacheContext = $ cacheContext ?: ObjectManager::getInstance ()->get (CacheContext::class);
96
+ $ this ->eventManager = $ eventManager ?: ObjectManager::getInstance ()->get (EventManager::class);
97
+ $ this ->urlFinder = $ urlFinder ?: ObjectManager::getInstance ()->get (UrlFinderInterface::class);
98
+ $ this ->entityToCacheTagMap = $ entityToCacheTagMap ;
56
99
parent ::__construct ($ context , $ registry , $ resource , $ resourceCollection , $ data );
57
100
}
58
101
@@ -63,8 +106,8 @@ public function __construct(
63
106
*/
64
107
protected function _construct ()
65
108
{
66
- $ this ->_init (\ Magento \ UrlRewrite \ Model \ ResourceModel \UrlRewrite::class);
67
- $ this ->_collectionName = \ Magento \ UrlRewrite \ Model \ ResourceModel \ UrlRewriteCollection::class;
109
+ $ this ->_init (ResourceModel \UrlRewrite::class);
110
+ $ this ->_collectionName = UrlRewriteCollection::class;
68
111
}
69
112
70
113
/**
@@ -92,4 +135,101 @@ public function setMetadata($metadata)
92
135
}
93
136
return $ this ->setData (\Magento \UrlRewrite \Service \V1 \Data \UrlRewrite::METADATA , $ metadata );
94
137
}
138
+
139
+ /**
140
+ * Gets final target UrlRewrite for custom rewrite record
141
+ *
142
+ * @param string $path
143
+ * @param int $storeId
144
+ * @return UrlRewriteService|null
145
+ */
146
+ private function getFinalTargetUrlRewrite (string $ path , int $ storeId ): ?UrlRewriteService
147
+ {
148
+ $ urlRewriteTarget = $ this ->urlFinder ->findOneByData (
149
+ [
150
+ 'request_path ' => $ path ,
151
+ 'store_id ' => $ storeId
152
+ ]
153
+ );
154
+
155
+ while (
156
+ $ urlRewriteTarget &&
157
+ $ urlRewriteTarget ->getTargetPath () !== $ urlRewriteTarget ->getRequestPath () &&
158
+ $ urlRewriteTarget ->getRedirectType () > 0
159
+ ) {
160
+ $ urlRewriteTarget = $ this ->urlFinder ->findOneByData (
161
+ [
162
+ 'request_path ' => $ urlRewriteTarget ->getTargetPath (),
163
+ 'store_id ' => $ urlRewriteTarget ->getStoreId ()
164
+ ]
165
+ );
166
+ }
167
+
168
+ return $ urlRewriteTarget ;
169
+ }
170
+
171
+ /**
172
+ * Clean the cache for entities affected by current rewrite
173
+ */
174
+ public function cleanEntitiesCache ()
175
+ {
176
+ if (!$ this ->isEmpty ()) {
177
+ if ($ this ->getEntityType () === Rewrite::ENTITY_TYPE_CUSTOM ) {
178
+ $ urlRewrite = $ this ->getFinalTargetUrlRewrite (
179
+ $ this ->getTargetPath (),
180
+ (int )$ this ->getStoreId ()
181
+ );
182
+
183
+ if ($ urlRewrite ) {
184
+ $ this ->cleanCacheForEntity ($ urlRewrite ->getEntityType (), (int ) $ urlRewrite ->getEntityId ());
185
+ }
186
+
187
+ if ($ this ->getOrigData () && $ this ->getOrigData ('target_path ' ) !== $ this ->getTargetPath ()) {
188
+ $ origUrlRewrite = $ this ->getFinalTargetUrlRewrite (
189
+ $ this ->getOrigData ('target_path ' ),
190
+ (int )$ this ->getOrigData ('store_id ' )
191
+ );
192
+
193
+ if ($ origUrlRewrite ) {
194
+ $ this ->cleanCacheForEntity ($ origUrlRewrite ->getEntityType (), (int ) $ origUrlRewrite ->getEntityId ());
195
+ }
196
+ }
197
+ } else {
198
+ $ this ->cleanCacheForEntity ($ this ->getEntityType (), (int ) $ this ->getEntityId ());
199
+ }
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Clean cache for specified entity type by id
205
+ *
206
+ * @param string $entityType
207
+ * @param int $entityId
208
+ */
209
+ private function cleanCacheForEntity (string $ entityType , int $ entityId )
210
+ {
211
+ if (array_key_exists ($ entityType , $ this ->entityToCacheTagMap )) {
212
+ $ cacheKey = $ this ->entityToCacheTagMap [$ entityType ];
213
+ $ this ->cacheContext ->registerEntities ($ cacheKey , [$ entityId ]);
214
+ $ this ->eventManager ->dispatch ('clean_cache_by_tags ' , ['object ' => $ this ->cacheContext ]);
215
+ }
216
+ }
217
+
218
+ /**
219
+ * @inheritdoc
220
+ */
221
+ public function afterDelete ()
222
+ {
223
+ $ this ->_getResource ()->addCommitCallback ([$ this , 'cleanEntitiesCache ' ]);
224
+ return parent ::afterDelete ();
225
+ }
226
+
227
+ /**
228
+ * @inheritdoc
229
+ */
230
+ public function afterSave ()
231
+ {
232
+ $ this ->_getResource ()->addCommitCallback ([$ this , 'cleanEntitiesCache ' ]);
233
+ return parent ::afterSave ();
234
+ }
95
235
}
0 commit comments