Skip to content

Commit 7b3ae93

Browse files
authored
🔃 [Magento Community Engineering] Community Contributions - 2.4-develop daily delivery
Accepted Community Pull Requests: - #33844: Fix unable to remove parameter override for a webapi route (by @gowrizrh) - #33419: Fix regression - Add previous exception with more details (by @ihor-sviziev) - #31613: Generator matching optimization (by @kirmorozov) - #32720: Reinstate disposition header for email messages (by @fredden) - #33537: Add caching for product attributes used in sales rules (by @ihor-sviziev) - #34207: #34063 fixed issue with price block cache for different zones (by @vovsky) - #32637: magento2#32636: Improved JWK check in the JwsManager class to account… (by @bgorski) - #31878: Fixed Importing: non-default multiple value separator can't be used in custom multiple select attribute (by @engcom-Charlie) Fixed GitHub Issues: - #33843: Unable to remove parameter override for a webapi route (reported by @gowrizrh) has been fixed in #33844 by @gowrizrh in 2.4-develop branch Related commits: 1. 2e98f9d 2. 6a3bdcc 3. c6aaf4b 4. ae6a043 5. 372221b - #34166: [Issue] Fix regression - Add previous exception with more details (reported by @m2-assistant[bot]) has been fixed in #33419 by @ihor-sviziev in 2.4-develop branch Related commits: 1. 92f2c59 - #33809: [Issue] Generator matching optimization (reported by @m2-assistant[bot]) has been fixed in #31613 by @kirmorozov in 2.4-develop branch Related commits: 1. d32684d 2. aa240d4 3. d082e59 - #25076: Magento 2.3.3 notifications converted to attachments in MS Exchange - Disposition Header (reported by @jaminion) has been fixed in #32720 by @fredden in 2.4-develop branch Related commits: 1. 43fb1f1 2. 2cbb4e6 3. 3e89205 4. 4bf0192 5. ec29468 6. 4382def 7. e37a69e 8. d730aa3 9. dd8a13b 10. cc99355 11. 545f31a 12. 427e4b1 13. 06a8d2a - #29258: Magento does not send emails with Content-Disposition: inline headers anymore (reported by @gwharton) has been fixed in #32720 by @fredden in 2.4-develop branch Related commits: 1. 43fb1f1 2. 2cbb4e6 3. 3e89205 4. 4bf0192 5. ec29468 6. 4382def 7. e37a69e 8. d730aa3 9. dd8a13b 10. cc99355 11. 545f31a 12. 427e4b1 13. 06a8d2a - #34063: Related Products Block Breaks Rich Snippets Price on Product View (reported by @hewgim) has been fixed in #34207 by @vovsky in 2.4-develop branch Related commits: 1. 4cf352b - #32636: JWK check limits possible use cases for the JWT Framework Adapter (reported by @bgorski) has been fixed in #32637 by @bgorski in 2.4-develop branch Related commits: 1. ff9ec52 2. 25d12c5 - #23156: Importing: non-default multiple value separator can't be used in custom multiple select attribute (reported by @evs-xsarus) has been fixed in #31878 by @engcom-Charlie in 2.4-develop branch Related commits: 1. 15ccdfd 2. a749903 3. b07f7c0 4. 8d72601 5. 2664d7e 6. f2eec91 7. 7f00bbe
2 parents ac88ad9 + 0edbd28 commit 7b3ae93

File tree

16 files changed

+156
-40
lines changed

16 files changed

+156
-40
lines changed

app/code/Magento/Catalog/Pricing/Render/FinalPriceBox.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ public function getCacheKeyInfo()
196196
$cacheKeys['display_minimal_price'] = $this->getDisplayMinimalPrice();
197197
$cacheKeys['is_product_list'] = $this->isProductList();
198198
$cacheKeys['customer_group_id'] = $this->getSaleableItem()->getCustomerGroupId();
199+
$cacheKeys['zone'] = $this->getZone();
199200
return $cacheKeys;
200201
}
201202

app/code/Magento/CatalogImportExport/Model/Import/Product.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
*/
4848
class Product extends AbstractEntity
4949
{
50+
private const DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR = ',';
5051
public const CONFIG_KEY_PRODUCT_TYPES = 'global/importexport/import_product_types';
5152
private const HASH_ALGORITHM = 'sha256';
5253

@@ -707,8 +708,6 @@ class Product extends AbstractEntity
707708
private $filesystem;
708709

709710
/**
710-
* Catalog config.
711-
*
712711
* @var CatalogConfig
713712
*/
714713
private $catalogConfig;
@@ -2812,6 +2811,10 @@ private function parseAttributesWithWrappedValues($attributesData)
28122811
public function parseMultiselectValues($values, $delimiter = self::PSEUDO_MULTI_LINE_SEPARATOR)
28132812
{
28142813
if (empty($this->_parameters[Import::FIELDS_ENCLOSURE])) {
2814+
if ($this->getMultipleValueSeparator() !== self::DEFAULT_GLOBAL_MULTIPLE_VALUE_SEPARATOR) {
2815+
$delimiter = $this->getMultipleValueSeparator();
2816+
}
2817+
28152818
return explode($delimiter, $values);
28162819
}
28172820
if (preg_match_all('~"((?:[^"]|"")*)"~', $values, $matches)) {

app/code/Magento/Email/Model/Transport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ public function sendMessage()
111111
$this->laminasTransport->send($laminasMessage);
112112
} catch (\Exception $e) {
113113
$this->logger->error($e);
114-
throw new MailException(new Phrase('Unable to send mail. Please try again later.'));
114+
throw new MailException(new Phrase('Unable to send mail. Please try again later.'), $e);
115115
}
116116
}
117117

app/code/Magento/JwtFrameworkAdapter/Model/JwsManager.php

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626

2727
/**
2828
* Works with JWS.
29+
*
30+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2931
*/
3032
class JwsManager
3133
{
@@ -77,26 +79,13 @@ public function __construct(
7779
*/
7880
public function build(JwsInterface $jws, EncryptionSettingsInterface $encryptionSettings): string
7981
{
80-
if (!$encryptionSettings instanceof JwsSignatureJwks) {
81-
throw new JwtException('Can only work with JWK encryption settings for JWS tokens');
82-
}
83-
$signaturesCount = count($encryptionSettings->getJwkSet()->getKeys());
84-
if ($jws->getProtectedHeaders() && count($jws->getProtectedHeaders()) !== $signaturesCount) {
85-
throw new MalformedTokenException('Number of headers must equal to number of JWKs');
86-
}
87-
if ($jws->getUnprotectedHeaders()
88-
&& count($jws->getUnprotectedHeaders()) !== $signaturesCount
89-
) {
90-
throw new MalformedTokenException('There must be an equal number of protected and unprotected headers.');
91-
}
82+
$this->validate($jws, $encryptionSettings);
9283
$builder = $this->jwsBuilder->create();
9384
$builder = $builder->withPayload($jws->getPayload()->getContent());
85+
$signaturesCount = count($encryptionSettings->getJwkSet()->getKeys());
86+
9487
for ($i = 0; $i < $signaturesCount; $i++) {
9588
$jwk = $encryptionSettings->getJwkSet()->getKeys()[$i];
96-
$alg = $jwk->getAlgorithm();
97-
if (!$alg) {
98-
throw new EncryptionException('Algorithm is required for JWKs');
99-
}
10089
$protected = [];
10190
if ($jws->getPayload()->getContentType()) {
10291
$protected['cty'] = $jws->getPayload()->getContentType();
@@ -105,9 +94,13 @@ public function build(JwsInterface $jws, EncryptionSettingsInterface $encryption
10594
$protected['kid'] = $jwk->getKeyId();
10695
}
10796
if ($jws->getProtectedHeaders()) {
97+
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
10898
$protected = array_merge($protected, $this->extractHeaderData($jws->getProtectedHeaders()[$i]));
10999
}
110-
$protected['alg'] = $alg;
100+
$protected['alg'] = $protected['alg'] ?? $jwk->getAlgorithm();
101+
if (!$protected['alg']) {
102+
throw new EncryptionException('Algorithm is required for JWKs');
103+
}
111104
$unprotected = [];
112105
if ($jws->getUnprotectedHeaders()) {
113106
$unprotected = $this->extractHeaderData($jws->getUnprotectedHeaders()[$i]);
@@ -125,6 +118,28 @@ public function build(JwsInterface $jws, EncryptionSettingsInterface $encryption
125118
return $this->jwsSerializer->serialize('jws_compact', $jwsCreated);
126119
}
127120

121+
/**
122+
* Validate jws and encryption settings.
123+
*
124+
* @param JwsInterface $jws
125+
* @param EncryptionSettingsInterface $encryptionSettings
126+
*/
127+
private function validate(JwsInterface $jws, EncryptionSettingsInterface $encryptionSettings): void
128+
{
129+
if (!$encryptionSettings instanceof JwsSignatureJwks) {
130+
throw new JwtException('Can only work with JWK encryption settings for JWS tokens');
131+
}
132+
$signaturesCount = count($encryptionSettings->getJwkSet()->getKeys());
133+
if ($jws->getProtectedHeaders() && count($jws->getProtectedHeaders()) !== $signaturesCount) {
134+
throw new MalformedTokenException('Number of headers must equal to number of JWKs');
135+
}
136+
if ($jws->getUnprotectedHeaders()
137+
&& count($jws->getUnprotectedHeaders()) !== $signaturesCount
138+
) {
139+
throw new MalformedTokenException('There must be an equal number of protected and unprotected headers.');
140+
}
141+
}
142+
128143
/**
129144
* Read and verify JWS token.
130145
*

app/code/Magento/SalesRule/Model/Plugin/QuoteConfigProductAttributes.php

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,43 +3,47 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\SalesRule\Model\Plugin;
78

9+
use Magento\Quote\Model\Quote\Config;
810
use Magento\SalesRule\Model\ResourceModel\Rule as RuleResource;
911

10-
/**
11-
* Quote Config Product Attributes Class
12-
*/
1312
class QuoteConfigProductAttributes
1413
{
1514
/**
1615
* @var RuleResource
1716
*/
18-
protected $_ruleResource;
17+
private $ruleResource;
18+
19+
/**
20+
* @var array|null
21+
*/
22+
private $activeAttributeCodes;
1923

2024
/**
2125
* @param RuleResource $ruleResource
2226
*/
2327
public function __construct(RuleResource $ruleResource)
2428
{
25-
$this->_ruleResource = $ruleResource;
29+
$this->ruleResource = $ruleResource;
2630
}
2731

2832
/**
2933
* Append sales rule product attribute keys to select by quote item collection
3034
*
31-
* @param \Magento\Quote\Model\Quote\Config $subject
35+
* @param Config $subject
3236
* @param array $attributeKeys
3337
*
3438
* @return array
3539
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
3640
*/
37-
public function afterGetProductAttributes(\Magento\Quote\Model\Quote\Config $subject, array $attributeKeys)
41+
public function afterGetProductAttributes(Config $subject, array $attributeKeys): array
3842
{
39-
$attributes = $this->_ruleResource->getActiveAttributes();
40-
foreach ($attributes as $attribute) {
41-
$attributeKeys[] = $attribute['attribute_code'];
43+
if ($this->activeAttributeCodes === null) {
44+
$this->activeAttributeCodes = array_column($this->ruleResource->getActiveAttributes(), 'attribute_code');
4245
}
43-
return $attributeKeys;
46+
47+
return array_merge($attributeKeys, $this->activeAttributeCodes);
4448
}
4549
}

app/code/Magento/Webapi/Model/Config/Converter.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public function convert($source)
8383
} else {
8484
$serviceClassData[self::KEY_METHODS][$soapMethod][self::KEY_ACL_RESOURCES] =
8585
array_unique(
86+
// phpcs:ignore Magento2.Performance.ForeachArrayMerge
8687
array_merge(
8788
$serviceClassData[self::KEY_METHODS][$soapMethod][self::KEY_ACL_RESOURCES],
8889
$resourcePermissionSet
@@ -138,7 +139,7 @@ protected function convertMethodParameters($parameters)
138139
}
139140
$name = $parameter->attributes->getNamedItem('name')->nodeValue;
140141
$forceNode = $parameter->attributes->getNamedItem('force');
141-
$force = $forceNode ? (bool)$forceNode->nodeValue : false;
142+
$force = $forceNode ? filter_var($forceNode->nodeValue, FILTER_VALIDATE_BOOLEAN) : false;
142143
$value = $parameter->nodeValue;
143144
$data[$name] = [
144145
self::KEY_FORCE => $force,

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"laminas/laminas-feed": "^2.13.0",
4747
"laminas/laminas-http": "^2.6.0",
4848
"laminas/laminas-json": "^3.2.0",
49-
"laminas/laminas-mail": "^2.9.0",
49+
"laminas/laminas-mail": "^2.11.0",
5050
"laminas/laminas-mime": "^2.8.0",
5151
"laminas/laminas-modulemanager": "^2.7",
5252
"laminas/laminas-mvc": "^3.2.0",

composer.lock

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/ProductTest/ProductValidationTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,32 @@ public function testProductWithInvalidWeight()
373373
$errors->getErrorByRowNumber(1)[0]->getErrorMessage()
374374
);
375375
}
376+
377+
/**
378+
* Test validate multiselect values with custom separator
379+
*
380+
* @magentoDataFixture Magento/Catalog/_files/products_with_multiselect_attribute.php
381+
* @magentoAppIsolation enabled
382+
* @magentoDbIsolation enabled
383+
*
384+
* @return void
385+
*/
386+
public function testValidateMultiselectValuesWithCustomSeparator(): void
387+
{
388+
$pathToFile = __DIR__ . './../_files/products_with_custom_multiselect_values_separator.csv';
389+
$filesystem = $this->objectManager->create(Filesystem::class);
390+
$directory = $filesystem->getDirectoryWrite(DirectoryList::ROOT);
391+
$source = $this->objectManager->create(Csv::class, ['file' => $pathToFile, 'directory' => $directory]);
392+
$params = [
393+
'behavior' => Import::BEHAVIOR_ADD_UPDATE,
394+
'entity' => 'catalog_product',
395+
Import::FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR => '|||'
396+
];
397+
398+
$errors = $this->_model->setParameters($params)
399+
->setSource($source)
400+
->validateData();
401+
402+
$this->assertEmpty($errors->getAllErrors());
403+
}
376404
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
sku,store_view_code,product_type,name,price,additional_attributes
2+
simple_ms_2,,simple,"With Multiselect 2",10,"multiselect_attribute=Option 2|||Option 3"

0 commit comments

Comments
 (0)