Skip to content

Commit bd6ed7c

Browse files
Fix PageCache: async rendering of blocks can corrupt layout cache #8554 #9050 #9560
Create cache key object to be injected separately with its own interface
1 parent 0a69b5b commit bd6ed7c

File tree

6 files changed

+92
-36
lines changed

6 files changed

+92
-36
lines changed

app/code/Magento/PageCache/Controller/Block.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ abstract class Block extends \Magento\Framework\App\Action\Action
2727
*/
2828
private $base64jsonSerializer;
2929

30+
/**
31+
* Layout cache keys to be able to generate different cache id for same handles
32+
*
33+
* @var \Magento\Framework\View\Layout\CacheKeyInterface
34+
*/
35+
private $cacheKey;
36+
3037
/**
3138
* @var string
3239
*/
@@ -37,19 +44,22 @@ abstract class Block extends \Magento\Framework\App\Action\Action
3744
* @param \Magento\Framework\Translate\InlineInterface $translateInline
3845
* @param Json $jsonSerializer
3946
* @param Base64Json $base64jsonSerializer
47+
* @param \Magento\Framework\View\Layout\CacheKeyInterface $cacheKey
4048
*/
4149
public function __construct(
4250
\Magento\Framework\App\Action\Context $context,
4351
\Magento\Framework\Translate\InlineInterface $translateInline,
4452
Json $jsonSerializer = null,
45-
Base64Json $base64jsonSerializer = null
53+
Base64Json $base64jsonSerializer = null,
54+
\Magento\Framework\View\Layout\CacheKeyInterface $cacheKey
4655
) {
4756
parent::__construct($context);
4857
$this->translateInline = $translateInline;
4958
$this->jsonSerializer = $jsonSerializer
5059
?: \Magento\Framework\App\ObjectManager::getInstance()->get(Json::class);
5160
$this->base64jsonSerializer = $base64jsonSerializer
5261
?: \Magento\Framework\App\ObjectManager::getInstance()->get(Base64Json::class);
62+
$this->cacheKey = $cacheKey;
5363
}
5464

5565
/**
@@ -69,7 +79,7 @@ protected function _getBlocks()
6979
$handles = $this->base64jsonSerializer->unserialize($handles);
7080

7181
$layout = $this->_view->getLayout();
72-
$layout->getUpdate()->addCacheKey($this->layoutCacheKey);
82+
$this->cacheKey->addCacheKey($this->layoutCacheKey);
7383

7484
$this->_view->loadLayout($handles, true, true, false);
7585
$data = [];

app/etc/di.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@
6868
<preference for="Magento\Framework\Event\ManagerInterface" type="Magento\Framework\Event\Manager\Proxy" />
6969
<preference for="Magento\Framework\View\LayoutInterface" type="Magento\Framework\View\Layout" />
7070
<preference for="Magento\Framework\View\Layout\ProcessorInterface" type="Magento\Framework\View\Model\Layout\Merge" />
71+
<preference for="Magento\Framework\View\Layout\CacheKeyInterface" type="Magento\Framework\View\Model\Layout\CacheKey" />
7172
<preference for="Magento\Framework\View\Url\ConfigInterface" type="Magento\Framework\View\Url\Config" />
7273
<preference for="Magento\Framework\App\Route\ConfigInterface" type="Magento\Framework\App\Route\Config" />
7374
<preference for="Magento\Framework\App\ResourceConnection\ConfigInterface" type="Magento\Framework\App\ResourceConnection\Config\Proxy" />
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\View\Layout;
7+
8+
/**
9+
* Interface CacheKeyInterface
10+
*/
11+
interface CacheKeyInterface
12+
{
13+
/**
14+
* Add cache key for generating different cache id for same handles
15+
*
16+
* @param array|string $cacheKey
17+
*/
18+
public function addCacheKey($cacheKey);
19+
20+
/**
21+
* Return cache keys array stored
22+
*
23+
* @return array
24+
*/
25+
public function getCacheKeys();
26+
}

lib/internal/Magento/Framework/View/Layout/ProcessorInterface.php

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,6 @@ public function getFileLayoutUpdatesXml();
125125
*/
126126
public function getContainers();
127127

128-
/**
129-
* Add cache key for generating different cache id for same handles
130-
*
131-
* @param array|string $cacheKey
132-
* @return ProcessorInterface
133-
*/
134-
public function addCacheKey($cacheKey);
135-
136128
/**
137129
* Return cache ID based current area/package/theme/store, handles and cache key(s)
138130
*
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
namespace Magento\Framework\View\Model\Layout;
7+
8+
/**
9+
* Layout cache key model
10+
*/
11+
class CacheKey implements \Magento\Framework\View\Layout\CacheKeyInterface
12+
{
13+
/**
14+
* Cache keys to be able to generate different cache id for same handles
15+
*
16+
* @var array
17+
*/
18+
private $cacheKeys = [];
19+
20+
/**
21+
* Add cache key(s) for generating different cache id for same handles
22+
*
23+
* @param array|string $cacheKeys
24+
*/
25+
public function addCacheKey($cacheKeys)
26+
{
27+
if (!is_array($cacheKeys)) {
28+
$cacheKeys = [$cacheKeys];
29+
}
30+
$this->cacheKeys = array_merge($this->cacheKeys, $cacheKeys);
31+
}
32+
33+
/**
34+
* Return cache keys array stored
35+
*
36+
* @return array
37+
*/
38+
public function getCacheKeys() {
39+
return $this->cacheKeys;
40+
}
41+
}

lib/internal/Magento/Framework/View/Model/Layout/Merge.php

Lines changed: 12 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
use Magento\Framework\Config\Dom\ValidationException;
1010
use Magento\Framework\Filesystem\DriverPool;
1111
use Magento\Framework\Filesystem\File\ReadFactory;
12-
use Magento\Framework\View\Layout\ProcessorInterface;
1312
use Magento\Framework\View\Model\Layout\Update\Validator;
1413

1514
/**
@@ -104,6 +103,13 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
104103
*/
105104
private $appState;
106105

106+
/**
107+
* Cache keys to be able to generate different cache id for same handles
108+
*
109+
* @var \Magento\Framework\View\Layout\CacheKeyInterface
110+
*/
111+
private $cacheKey;
112+
107113
/**
108114
* @var \Magento\Framework\Cache\FrontendInterface
109115
*/
@@ -129,13 +135,6 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
129135
*/
130136
protected $cacheSuffix;
131137

132-
/**
133-
* Cache keys to be able to generate different cache id for same handles
134-
*
135-
* @var array
136-
*/
137-
protected $cacheKeys = [];
138-
139138
/**
140139
* All processed handles used in this update
141140
*
@@ -173,8 +172,9 @@ class Merge implements \Magento\Framework\View\Layout\ProcessorInterface
173172
* @param \Magento\Framework\Cache\FrontendInterface $cache
174173
* @param \Magento\Framework\View\Model\Layout\Update\Validator $validator
175174
* @param \Psr\Log\LoggerInterface $logger
176-
* @param ReadFactory $readFactory,
175+
* @param ReadFactory $readFactory ,
177176
* @param \Magento\Framework\View\Design\ThemeInterface $theme Non-injectable theme instance
177+
* @param \Magento\Framework\View\Layout\CacheKeyInterface $cacheKey
178178
* @param string $cacheSuffix
179179
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
180180
*/
@@ -189,6 +189,7 @@ public function __construct(
189189
\Psr\Log\LoggerInterface $logger,
190190
ReadFactory $readFactory,
191191
\Magento\Framework\View\Design\ThemeInterface $theme = null,
192+
\Magento\Framework\View\Layout\CacheKeyInterface $cacheKey,
192193
$cacheSuffix = ''
193194
) {
194195
$this->theme = $theme ?: $design->getDesignTheme();
@@ -200,6 +201,7 @@ public function __construct(
200201
$this->layoutValidator = $validator;
201202
$this->logger = $logger;
202203
$this->readFactory = $readFactory;
204+
$this->cacheKey = $cacheKey;
203205
$this->cacheSuffix = $cacheSuffix;
204206
}
205207

@@ -915,29 +917,13 @@ public function getScope()
915917
return $this->scope;
916918
}
917919

918-
/**
919-
* Add cache key(s) for generating different cache id for same handles
920-
*
921-
* @param array|string $cacheKeys
922-
* @return $this
923-
*/
924-
public function addCacheKey($cacheKeys)
925-
{
926-
if (!is_array($cacheKeys)) {
927-
$cacheKeys = [$cacheKeys];
928-
}
929-
$this->cacheKeys = array_merge($this->cacheKeys, $cacheKeys);
930-
931-
return $this;
932-
}
933-
934920
/**
935921
* Return cache ID based current area/package/theme/store and handles
936922
*
937923
* @return string
938924
*/
939925
public function getCacheId()
940926
{
941-
return $this->generateCacheId(md5(implode('|', array_merge($this->getHandles(), $this->cacheKeys))));
927+
return $this->generateCacheId(md5(implode('|', array_merge($this->getHandles(), $this->cacheKey->getCacheKeys()))));
942928
}
943929
}

0 commit comments

Comments
 (0)