Skip to content

Commit 9eb580c

Browse files
authored
Merge branch '2.4-develop' into AC-14307
2 parents 1e53f17 + 5660c9c commit 9eb580c

File tree

13 files changed

+429
-43
lines changed

13 files changed

+429
-43
lines changed

.github/app-projects-boards-automation.config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ automations:
219219
- ['merged', 'eq', true]
220220
actions:
221221
- moveTo: [23, 'Recently Merged'] #['Pull Requests Dashboard', 'Recently Merged']
222+
- moveTo: [22, 'Recently Merged'] #['Community Dashboard', 'Recently Merged']
222223

223224
# 18. Whenever a pull request is closed:
224225
# a. it must be removed from the "Pull Requests Dashboard" project

app/code/Magento/Catalog/etc/db_schema.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@
135135
<index referenceId="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID" indexType="btree">
136136
<column name="attribute_id"/>
137137
</index>
138+
<index referenceId="CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID_ENTITY_ID" indexType="btree">
139+
<column name="attribute_id"/>
140+
<column name="entity_id"/>
141+
</index>
138142
<index referenceId="CATALOG_PRODUCT_ENTITY_INT_STORE_ID" indexType="btree">
139143
<column name="store_id"/>
140144
</index>

app/code/Magento/Catalog/etc/db_schema_whitelist.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
},
7070
"index": {
7171
"CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID": true,
72+
"CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID_ENTITY_ID": true,
7273
"CATALOG_PRODUCT_ENTITY_INT_STORE_ID": true,
7374
"CATALOG_PRODUCT_ENTITY_INT_ATTRIBUTE_ID_STORE_ID_VALUE": true
7475
},

app/code/Magento/Checkout/Model/Sidebar.php

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66
namespace Magento\Checkout\Model;
77

@@ -10,6 +10,7 @@
1010
use Magento\Framework\Exception\LocalizedException;
1111
use Magento\Framework\Filter\LocalizedToNormalized;
1212
use Magento\Framework\Locale\ResolverInterface;
13+
use Magento\Framework\NumberFormatter;
1314
use Magento\Quote\Api\Data\CartItemInterface;
1415
use Magento\Quote\Model\Quote\Address\Total;
1516

@@ -129,8 +130,12 @@ public function updateQuoteItem($itemId, $itemQty)
129130
protected function normalize($itemQty)
130131
{
131132
if ($itemQty) {
133+
if (is_string($itemQty) && str_contains($itemQty, ',')) {
134+
$itemQty = (double)str_replace(',', '.', $itemQty);
135+
}
136+
132137
$filter = new LocalizedToNormalized(
133-
['locale' => $this->resolver->getLocale()]
138+
['locale' => $this->resolver->getLocale(), 'decimal_style' => NumberFormatter::DECIMAL]
134139
);
135140
return $filter->filter((string)$itemQty);
136141
}

app/code/Magento/Checkout/Test/Unit/Model/SidebarTest.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2015 Adobe
4+
* All Rights Reserved.
55
*/
66
declare(strict_types=1);
77

@@ -140,19 +140,29 @@ public function testRemoveQuoteItem()
140140
$this->assertEquals($this->sidebar, $this->sidebar->removeQuoteItem($itemId));
141141
}
142142

143-
public function testUpdateQuoteItem()
144-
{
145-
$itemId = 1;
146-
$itemQty = 2;
147-
143+
/**
144+
* @param string $locale
145+
* @param int|string $itemId
146+
* @param int|string|float $expectedItemQty
147+
* @param int|string|float $itemQty
148+
*
149+
* @dataProvider dataProviderUpdateQuoteItem
150+
*/
151+
public function testUpdateQuoteItem(
152+
string $locale,
153+
int|string $itemId,
154+
int|string|float $expectedItemQty,
155+
int|string|float $itemQty
156+
) {
148157
$this->resolverMock->expects($this->once())
149158
->method('getLocale')
150-
->willReturn('en');
159+
->willReturn($locale);
151160

152161
$this->cartMock->expects($this->once())
153162
->method('updateItems')
154-
->with([$itemId => ['qty' => $itemQty]])
163+
->with([$itemId => ['qty' => $expectedItemQty]])
155164
->willReturnSelf();
165+
156166
$this->cartMock->expects($this->once())
157167
->method('save')
158168
->willReturnSelf();
@@ -178,4 +188,18 @@ public function testUpdateQuoteItemWithZeroQty()
178188

179189
$this->assertEquals($this->sidebar, $this->sidebar->updateQuoteItem($itemId, $itemQty));
180190
}
191+
192+
/**
193+
* @return array
194+
*/
195+
public static function dataProviderUpdateQuoteItem(): array
196+
{
197+
return [
198+
//locale, itemId, expectedItemQty, ItemQty
199+
[ 'en_US', 1, 2, 2],
200+
[ 'en_US', 1, 0.5, 0.5],
201+
[ 'en_US', 1,"0.5","0.5"],
202+
[ 'nl_NL', 1,"0.5","0,5"]
203+
];
204+
}
181205
}

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
)

app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Capture.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
<?php
22
/**
3-
*
4-
* Copyright © Magento, Inc. All rights reserved.
5-
* See COPYING.txt for license details.
3+
* Copyright 2014 Adobe
4+
* All Rights Reserved.
65
*/
76
namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
87

9-
use Magento\Framework\App\Action\HttpPostActionInterface;
8+
use Magento\Framework\App\Action\HttpGetActionInterface;
109
use Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View;
1110

12-
class Capture extends View implements HttpPostActionInterface
11+
class Capture extends View implements HttpGetActionInterface
1312
{
1413
/**
1514
* Authorization level of a basic admin session

app/code/Magento/Tax/view/frontend/templates/checkout/subtotal.phtml

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,28 @@
11
<?php
22
/**
3-
* Copyright © Magento, Inc. All rights reserved.
4-
* See COPYING.txt for license details.
3+
* Copyright 2011 Adobe
4+
* All Rights Reserved.
55
*/
66

77
/**
88
* @var $block \Magento\Tax\Block\Checkout\Subtotal
99
* @see \Magento\Tax\Block\Checkout\Subtotal
1010
* @var \Magento\Framework\View\Helper\SecureHtmlRenderer $secureRenderer
11+
* @var $escaper \Magento\Framework\Escaper
1112
*/
1213
?>
1314
<?php
14-
$style = $block->escapeHtmlAttr($block->getStyle());
15+
$style = $escaper->escapeHtmlAttr($block->getStyle());
1516
$colspan = (int) $block->getColspan();
1617
/** @var \Magento\Checkout\Helper\Data $checkoutHelper */
1718
$checkoutHelper = $block->getData('checkoutHelper');
1819
?>
1920
<?php if ($block->displayBoth()): ?>
2021
<tr class="totals sub excl">
2122
<th class="mark" colspan="<?= /* @noEscape */ $colspan ?>" scope="row">
22-
<?= $block->escapeHtml(__('Subtotal (Excl. Tax)')) ?>
23+
<?= $escaper->escapeHtml(__('Subtotal (Excl. Tax)')) ?>
2324
</th>
24-
<tdclass="amount" data-th="<?= $block->escapeHtmlAttr(__('Subtotal (Excl. Tax)')) ?>">
25+
<td class="amount" data-th="<?= $escaper->escapeHtmlAttr(__('Subtotal (Excl. Tax)')) ?>">
2526
<?= /* @noEscape */ $checkoutHelper->formatPrice($block->getTotal()->getValueExclTax()) ?>
2627
</td>
2728
</tr>
@@ -31,9 +32,9 @@ $checkoutHelper = $block->getData('checkoutHelper');
3132
<?php endif; ?>
3233
<tr class="totals sub incl">
3334
<th class="mark" colspan="<?= /* @noEscape */ $colspan ?>" scope="row">
34-
<?= $block->escapeHtml(__('Subtotal (Incl. Tax)')) ?>
35+
<?= $escaper->escapeHtml(__('Subtotal (Incl. Tax)')) ?>
3536
</th>
36-
<td class="amount" data-th="<?= $block->escapeHtmlAttr(__('Subtotal (Incl. Tax)')) ?>">
37+
<td class="amount" data-th="<?= $escaper->escapeHtmlAttr(__('Subtotal (Incl. Tax)')) ?>">
3738
<?= /* @noEscape */ $checkoutHelper->formatPrice($block->getTotal()->getValueInclTax()) ?>
3839
</td>
3940
</tr>
@@ -44,9 +45,9 @@ $checkoutHelper = $block->getData('checkoutHelper');
4445
<?php else: ?>
4546
<tr class="totals sub">
4647
<th class="mark" colspan="<?= /* @noEscape */ $colspan ?>" scope="row">
47-
<?= $block->escapeHtml($block->getTotal()->getTitle()) ?>
48+
<?= $escaper->escapeHtml($block->getTotal()->getTitle()) ?>
4849
</th>
49-
<td class="amount" data-th="<?= $block->escapeHtmlAttr($block->getTotal()->getTitle()) ?>">
50+
<td class="amount" data-th="<?= $escaper->escapeHtmlAttr($block->getTotal()->getTitle()) ?>">
5051
<?= /* @noEscape */ $checkoutHelper->formatPrice($block->getTotal()->getValue()) ?>
5152
</td>
5253
</tr>

0 commit comments

Comments
 (0)