Skip to content

Commit 9af321c

Browse files
authored
Merge pull request #1712 from algolia/fix/MAGE-1245-fix-category-fpc
MAGE-1245 Fix category FPC
2 parents c0ae4e0 + 48a3aca commit 9af321c

35 files changed

+643
-69
lines changed

Helper/ConfigHelper.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,7 @@ public function getExtraSettings($section, $storeId = null)
13771377
/**
13781378
* @param $storeId
13791379
* @return bool
1380+
* @deprecated This feature is deprecated and will be replaced in an upcoming version
13801381
*/
13811382
public function preventBackendRendering($storeId = null)
13821383
{

Plugin/RenderingCacheContextPlugin.php

Lines changed: 69 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
use Algolia\AlgoliaSearch\Helper\ConfigHelper;
66
use Magento\Framework\App\Http\Context as HttpContext;
77
use Magento\Framework\App\Request\Http;
8+
use Magento\Framework\Exception\NoSuchEntityException;
89
use Magento\Store\Model\StoreManagerInterface;
10+
use Magento\UrlRewrite\Model\UrlFinderInterface;
911

1012
/**
1113
* The purpose of this class is to render different cached versions of the pages according to the user agent.
@@ -15,39 +17,36 @@
1517
*/
1618
class RenderingCacheContextPlugin
1719
{
18-
public const RENDERING_CONTEXT = 'rendering_context';
20+
public const RENDERING_CONTEXT = 'algolia_rendering_context';
1921
public const RENDERING_WITH_BACKEND = 'with_backend';
2022
public const RENDERING_WITHOUT_BACKEND = 'without_backend';
2123

22-
private $configHelper;
23-
private $storeManager;
24-
private $request;
24+
public const CATEGORY_CONTROLLER = 'category';
25+
public const CATEGORY_ROUTE = 'catalog/category/view';
2526

2627
public function __construct(
27-
ConfigHelper $configHelper,
28-
StoreManagerInterface $storeManager,
29-
Http $request
30-
) {
31-
$this->configHelper = $configHelper;
32-
$this->storeManager = $storeManager;
33-
$this->request = $request;
34-
}
28+
protected ConfigHelper $configHelper,
29+
protected StoreManagerInterface $storeManager,
30+
protected Http $request,
31+
protected UrlFinderInterface $urlFinder
32+
) { }
3533

3634
/**
37-
* Add Rendering context for caching purposes
38-
* (If the prevent rendering configuration is enabled and the user agent has no white card to display it,
35+
* Add a rendering context to the vary string data to distinguish which versions of the category PLP should be cached
36+
* (If the "prevent backend rendering" configuration is enabled and the user agent is not whitelisted to display it,
3937
* we set a different page variation, and the FPC stores a different cached page)
4038
*
41-
* @param HttpContext $subject
42-
* @param string[] $data
39+
* IMPORTANT:
40+
* Magento\Framework\App\Http\Context::getData can be called multiple times over the course of the request lifecycle
41+
* it is important that this plugin return the data consistently - or the cache will be invalidated unexpectedly!
4342
*
44-
* @return array
43+
* @param HttpContext $subject
44+
* @param array $data
45+
* @return array original params
46+
* @throws NoSuchEntityException
4547
*/
46-
public function afterGetData(HttpContext $subject, $data)
47-
{
48-
$storeId = $this->storeManager->getStore()->getId();
49-
if (!($this->request->getControllerName() === 'category'
50-
&& $this->configHelper->replaceCategories($storeId) === true)) {
48+
public function afterGetData(HttpContext $subject, array $data): array {
49+
if (!$this->shouldApplyCacheContext()) {
5150
return $data;
5251
}
5352

@@ -59,4 +58,52 @@ public function afterGetData(HttpContext $subject, $data)
5958

6059
return $data;
6160
}
61+
62+
/**
63+
* @param int $storeId
64+
* @return string
65+
*/
66+
protected function getOriginalRoute(int $storeId): string
67+
{
68+
$requestUri = $this->request->getRequestUri();
69+
70+
$rewrite = $this->urlFinder->findOneByData([
71+
'request_path' => ltrim($requestUri, '/'),
72+
'store_id' => $storeId,
73+
]);
74+
75+
return $rewrite?->getTargetPath() ?? "";
76+
}
77+
78+
/**
79+
* @param string $path
80+
* @return bool
81+
*/
82+
protected function isCategoryRoute(string $path): bool {
83+
$path = ltrim($path, '/');
84+
return str_starts_with($path, self::CATEGORY_ROUTE);
85+
}
86+
87+
/**
88+
* This can be called in a variety of contexts - so this should always be called consistently
89+
*
90+
* @param int $storeId
91+
* @return bool
92+
*/
93+
protected function isCategoryPage(int $storeId): bool
94+
{
95+
return $this->request->getControllerName() === self::CATEGORY_CONTROLLER
96+
|| $this->isCategoryRoute($this->request->getRequestUri())
97+
|| $this->isCategoryRoute($this->getOriginalRoute($storeId));
98+
}
99+
100+
/**
101+
* @return bool
102+
* @throws NoSuchEntityException
103+
*/
104+
protected function shouldApplyCacheContext(): bool
105+
{
106+
$storeId = $this->storeManager->getStore()->getId();
107+
return $this->isCategoryPage($storeId) && $this->configHelper->replaceCategories($storeId);
108+
}
62109
}

0 commit comments

Comments
 (0)