Skip to content

Commit 2f5b3d5

Browse files
Merge remote-tracking branch '38270/fix-38269' into aprilcomprs
2 parents d927d0b + 1bfa69b commit 2f5b3d5

File tree

4 files changed

+264
-7
lines changed

4 files changed

+264
-7
lines changed

app/code/Magento/PageCache/Model/App/Request/Http/IdentifierForSave.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,14 +46,38 @@ public function getValue()
4646
{
4747
$pattern = $this->identifier->getMarketingParameterPatterns();
4848
$replace = array_fill(0, count($pattern), '');
49+
$url = preg_replace($pattern, $replace, (string)$this->request->getUriString());
50+
list($baseUrl, $query) = $this->reconstructUrl($url);
4951
$data = [
5052
$this->request->isSecure(),
51-
preg_replace($pattern, $replace, (string)$this->request->getUriString()),
53+
$baseUrl,
54+
$query,
5255
$this->context->getVaryString()
5356
];
5457

5558
$data = $this->identifierStoreReader->getPageTagsWithStoreCacheTags($data);
56-
5759
return sha1($this->serializer->serialize($data));
5860
}
61+
62+
/**
63+
* Reconstruct url and sort query
64+
*
65+
* @param string $url
66+
* @return array
67+
*/
68+
private function reconstructUrl(string $url): array
69+
{
70+
if (empty($url)) {
71+
return [$url, ''];
72+
}
73+
$baseUrl = strtok($url, '?');
74+
$query = $this->request->getUri()->getQueryAsArray();
75+
if (!empty($query)) {
76+
ksort($query);
77+
$query = http_build_query($query);
78+
} else {
79+
$query = '';
80+
}
81+
return [$baseUrl, $query];
82+
}
5983
}

app/code/Magento/PageCache/Test/Unit/Model/App/Request/Http/IdentifierForSaveTest.php

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
namespace Magento\PageCache\Test\Unit\Model\App\Request\Http;
99

10+
use Laminas\Stdlib\Parameters;
11+
use Laminas\Uri\Http as HttpUri;
1012
use Magento\Framework\App\Http\Context;
1113
use Magento\Framework\App\ObjectManager;
1214
use Magento\Framework\App\PageCache\Identifier;
@@ -49,6 +51,9 @@ class IdentifierForSaveTest extends TestCase
4951
*/
5052
private $identifierStoreReader;
5153

54+
/** @var Parameters|MockObject */
55+
private $fileParams;
56+
5257
/**
5358
* @var Identifier
5459
*/
@@ -76,6 +81,7 @@ function ($value) {
7681
return json_encode($value);
7782
}
7883
);
84+
$this->fileParams = $this->createMock(Parameters::class);
7985

8086
$this->identifierStoreReader = $this->getMockBuilder(IdentifierStoreReader::class)
8187
->onlyMethods(['getPageTagsWithStoreCacheTags'])
@@ -120,10 +126,24 @@ public function testGetValue(): void
120126
->method('getUriString')
121127
->willReturn('http://example.com/path1/');
122128

129+
$this->requestMock->expects($this->any())
130+
->method('getQuery')
131+
->willReturn($this->fileParams);
132+
133+
$this->fileParams->expects($this->any())
134+
->method('toArray')
135+
->willReturn([]);
136+
123137
$this->contextMock->expects($this->any())
124138
->method('getVaryString')
125139
->willReturn(self::VARY);
126140

141+
$uri = $this->createMock(HttpUri::class);
142+
$uri->expects($this->any())->method('getQueryAsArray')->willReturn('');
143+
$this->requestMock->expects($this->any())
144+
->method('getUri')
145+
->willReturn($uri);
146+
127147
$this->identifierStoreReader->method('getPageTagsWithStoreCacheTags')->willReturnCallback(
128148
function ($value) {
129149
return $value;
@@ -136,6 +156,67 @@ function ($value) {
136156
[
137157
true,
138158
'http://example.com/path1/',
159+
'',
160+
self::VARY
161+
]
162+
)
163+
),
164+
$this->model->getValue()
165+
);
166+
}
167+
168+
/**
169+
* Test get identifier for save value with query parameters.
170+
*
171+
* @return void
172+
*/
173+
public function testGetValueWithQuery(): void
174+
{
175+
$this->requestMock->expects($this->any())
176+
->method('isSecure')
177+
->willReturn(true);
178+
179+
$this->requestMock->expects($this->any())
180+
->method('getUriString')
181+
->willReturn('http://example.com/path1/?b=2&a=1');
182+
183+
$this->requestMock->expects($this->any())
184+
->method('getQuery')
185+
->willReturn($this->fileParams);
186+
187+
$this->fileParams->expects($this->any())
188+
->method('toArray')
189+
->willReturn([
190+
'b' => 2,
191+
'a' => 1,
192+
]);
193+
194+
$this->contextMock->expects($this->any())
195+
->method('getVaryString')
196+
->willReturn(self::VARY);
197+
198+
$uri = $this->createMock(HttpUri::class);
199+
$uri->expects($this->any())->method('getQueryAsArray')->willReturn([
200+
'b' => 2,
201+
'a' => 1,
202+
]);
203+
$this->requestMock->expects($this->any())
204+
->method('getUri')
205+
->willReturn($uri);
206+
207+
$this->identifierStoreReader->method('getPageTagsWithStoreCacheTags')->willReturnCallback(
208+
function ($value) {
209+
return $value;
210+
}
211+
);
212+
213+
$this->assertEquals(
214+
sha1(
215+
json_encode(
216+
[
217+
true,
218+
'http://example.com/path1/',
219+
'a=1&b=2',
139220
self::VARY
140221
]
141222
)
@@ -167,18 +248,24 @@ public function testGetValueWithMarketingParameters(): void
167248
->method('getVaryString')
168249
->willReturn(self::VARY);
169250

251+
$uri = $this->createMock(HttpUri::class);
252+
$uri->expects($this->any())->method('getQueryAsArray')->willReturn(['abc' => '123']);
253+
$this->requestMock->expects($this->any())
254+
->method('getUri')
255+
->willReturn($uri);
256+
170257
$this->identifierStoreReader->method('getPageTagsWithStoreCacheTags')->willReturnCallback(
171258
function ($value) {
172259
return $value;
173260
}
174261
);
175-
176262
$this->assertEquals(
177263
sha1(
178264
json_encode(
179265
[
180266
true,
181-
'http://example.com/path1/?abc=123',
267+
'http://example.com/path1/',
268+
'abc=123',
182269
self::VARY
183270
]
184271
)

lib/internal/Magento/Framework/App/PageCache/Identifier.php

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,15 @@ public function getValue()
5252
{
5353
$pattern = $this->getMarketingParameterPatterns();
5454
$replace = array_fill(0, count($pattern), '');
55+
$url = preg_replace($pattern, $replace, (string)$this->request->getUriString());
56+
list($baseUrl, $query) = $this->reconstructUrl($url);
5557
$data = [
5658
$this->request->isSecure(),
57-
preg_replace($pattern, $replace, (string)$this->request->getUriString()),
59+
$baseUrl,
60+
$query,
5861
$this->request->get(\Magento\Framework\App\Response\Http::COOKIE_VARY_STRING)
5962
?: $this->context->getVaryString()
6063
];
61-
6264
return sha1($this->serializer->serialize($data));
6365
}
6466

@@ -92,4 +94,26 @@ public function getMarketingParameterPatterns(): array
9294
'/&?_bta_(.*?)\=[^&]+/',
9395
];
9496
}
97+
98+
/**
99+
* Reconstruct url and sort query
100+
*
101+
* @param string $url
102+
* @return array
103+
*/
104+
private function reconstructUrl(string $url): array
105+
{
106+
if (empty($url)) {
107+
return [$url, ''];
108+
}
109+
$baseUrl = strtok($url, '?');
110+
$query = $this->request->getUri()->getQueryAsArray();
111+
if (!empty($query)) {
112+
ksort($query);
113+
$query = http_build_query($query);
114+
} else {
115+
$query = '';
116+
}
117+
return [$baseUrl, $query];
118+
}
95119
}

0 commit comments

Comments
 (0)