Skip to content

Commit 58f9f29

Browse files
committed
MC-39463: GraphQL caches urlResolver response and can return the old value after the url rewrite update
1 parent f48b70f commit 58f9f29

File tree

1 file changed

+77
-11
lines changed

1 file changed

+77
-11
lines changed

app/code/Magento/UrlRewrite/Model/UrlRewrite.php

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77

88
namespace Magento\UrlRewrite\Model;
99

10-
use Magento\Catalog\Model\Category;
11-
use Magento\Catalog\Model\Product;
12-
use Magento\Cms\Model\Page;
1310
use Magento\Framework\App\ObjectManager;
1411
use Magento\Framework\Data\Collection\AbstractDb;
1512
use Magento\Framework\EntityManager\EventManager;
@@ -61,6 +58,11 @@ class UrlRewrite extends AbstractModel
6158
*/
6259
private $entityToCacheTagMap;
6360

61+
/**
62+
* @var UrlFinderInterface
63+
*/
64+
private $urlFinder;
65+
6466
/**
6567
* UrlRewrite constructor.
6668
*
@@ -72,6 +74,7 @@ class UrlRewrite extends AbstractModel
7274
* @param Json|null $serializer
7375
* @param CacheContext|null $cacheContext
7476
* @param EventManager|null $eventManager
77+
* @param UrlFinderInterface|null $urlFinder
7578
* @param array $entityToCacheTagMap
7679
*/
7780
public function __construct(
@@ -83,12 +86,14 @@ public function __construct(
8386
Json $serializer = null,
8487
CacheContext $cacheContext = null,
8588
EventManager $eventManager = null,
89+
UrlFinderInterface $urlFinder = null,
8690
array $entityToCacheTagMap = []
8791
)
8892
{
8993
$this->serializer = $serializer ?: ObjectManager::getInstance()->get(Json::class);
9094
$this->cacheContext = $cacheContext ?: ObjectManager::getInstance()->get(CacheContext::class);
9195
$this->eventManager = $eventManager ?: ObjectManager::getInstance()->get(EventManager::class);
96+
$this->urlFinder = $urlFinder ?: ObjectManager::getInstance()->get(UrlFinderInterface::class);
9297
$this->entityToCacheTagMap = $entityToCacheTagMap;
9398
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
9499
}
@@ -131,30 +136,91 @@ public function setMetadata($metadata)
131136
}
132137

133138
/**
134-
* Clean cache for the entity which was affected by updating UrlRewrite
139+
* Gets final target UrlRewrite for custom rewrite record
135140
*
136-
* @param $entityType
137-
* @param $entityId
141+
* @param string $path
142+
* @param int $storeId
143+
* @return UrlRewrite|null
144+
*/
145+
private function getFinalTargetUrlRewrite(string $path, int $storeId) {
146+
$urlRewriteTarget = $this->urlFinder->findOneByData(
147+
[
148+
'request_path' => $path,
149+
'store_id' => $storeId
150+
]
151+
);
152+
153+
while ($urlRewriteTarget && $urlRewriteTarget->getRedirectType() > 0) {
154+
$urlRewriteTarget = $this->urlFinder->findOneByData(
155+
[
156+
'request_path' => $urlRewriteTarget->getTargetPath(),
157+
'store_id' => $urlRewriteTarget->getStoreId()
158+
]
159+
);
160+
}
161+
162+
return $urlRewriteTarget;
163+
}
164+
165+
/**
166+
* Clean the cache for entities affected by current rewrite
138167
*/
139-
private function cleanCacheForEntity($entityType, $entityId)
168+
private function cleanEntitiesCache() {
169+
if ($this->getEntityType() === Rewrite::ENTITY_TYPE_CUSTOM) {
170+
$urlRewrite = $this->getFinalTargetUrlRewrite(
171+
$this->getTargetPath(),
172+
(int)$this->getStoreId()
173+
);
174+
175+
if ($urlRewrite) {
176+
$this->cleanCacheForEntity($urlRewrite->getEntityType(), (int) $urlRewrite->getEntityId());
177+
}
178+
179+
if ($this->getOrigData() && $this->getOrigData('target_path') !== $this->getTargetPath()) {
180+
$origUrlRewrite = $this->getFinalTargetUrlRewrite(
181+
$this->getOrigData('target_path'),
182+
(int)$this->getOrigData('store_id')
183+
);
184+
185+
if ($origUrlRewrite) {
186+
$this->cleanCacheForEntity($origUrlRewrite->getEntityType(), (int) $origUrlRewrite->getEntityId());
187+
}
188+
}
189+
} else {
190+
$this->cleanCacheForEntity($this->getEntityType(), (int) $this->getEntityId());
191+
}
192+
}
193+
194+
/**
195+
* Clean cache for specified entity type by id
196+
*
197+
* @param string $entityType
198+
* @param int $entityId
199+
*/
200+
private function cleanCacheForEntity(string $entityType, int $entityId)
140201
{
141-
if ($entityType !== Rewrite::ENTITY_TYPE_CUSTOM && array_key_exists($entityType, $this->entityToCacheTagMap)) {
202+
if (array_key_exists($entityType, $this->entityToCacheTagMap)) {
142203
$cacheKey = $this->entityToCacheTagMap[$entityType];
143-
144204
$this->cacheContext->registerEntities($cacheKey, [$entityId]);
145205
$this->eventManager->dispatch('clean_cache_by_tags', ['object' => $this->cacheContext]);
146206
}
147207
}
148208

209+
/**
210+
* @inheritdoc
211+
*/
149212
public function afterDelete()
150213
{
151-
$this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId());
214+
$this->cleanEntitiesCache();
152215
return parent::afterDelete();
153216
}
154217

218+
/**
219+
* @inheritdoc
220+
*/
155221
public function afterSave()
156222
{
157-
$this->cleanCacheForEntity($this->getEntityType(), $this->getEntityId());
223+
$this->cleanEntitiesCache();
158224
return parent::afterSave();
159225
}
160226
}

0 commit comments

Comments
 (0)