Skip to content

Commit 3f697e0

Browse files
authored
Merge pull request #6798 from magento-tsg/2.4-develop-pr143
[Arrows] Fixes for 2.4 (pr143) (2.4-develop)
2 parents 9d1fe17 + 5d74a3a commit 3f697e0

File tree

12 files changed

+284
-69
lines changed

12 files changed

+284
-69
lines changed

Diff for: app/code/Magento/ConfigurableProduct/Plugin/Model/Attribute/Backend/AttributeValidation.php

+32-13
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,15 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\ConfigurableProduct\Plugin\Model\Attribute\Backend;
79

810
use Magento\Catalog\Api\Data\ProductInterface;
911
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
12+
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
13+
use Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend;
14+
use Magento\Framework\DataObject;
1015

1116
/**
1217
* Skip validate attributes used for create configurable product
@@ -19,7 +24,6 @@ class AttributeValidation
1924
private $configurableProductType;
2025

2126
/**
22-
* AttributeValidation constructor.
2327
* @param Configurable $configurableProductType
2428
*/
2529
public function __construct(
@@ -29,27 +33,42 @@ public function __construct(
2933
}
3034

3135
/**
32-
* @param \Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend $subject
36+
* Verify is attribute used for configurable product creation and should not be validated.
37+
*
38+
* @param AbstractBackend $subject
3339
* @param \Closure $proceed
34-
* @param \Magento\Framework\DataObject $entity
40+
* @param DataObject $entity
3541
* @return bool
3642
*/
3743
public function aroundValidate(
38-
\Magento\Eav\Model\Entity\Attribute\Backend\AbstractBackend $subject,
44+
AbstractBackend $subject,
3945
\Closure $proceed,
40-
\Magento\Framework\DataObject $entity
46+
DataObject $entity
4147
) {
4248
$attribute = $subject->getAttribute();
43-
if ($entity instanceof ProductInterface
44-
&& $entity->getTypeId() == Configurable::TYPE_CODE
45-
&& in_array(
46-
$attribute->getAttributeId(),
47-
$this->configurableProductType->getUsedProductAttributeIds($entity),
48-
true
49-
)
50-
) {
49+
if ($this->isAttributeShouldNotBeValidated($entity, $attribute)) {
5150
return true;
5251
}
5352
return $proceed($entity);
5453
}
54+
55+
/**
56+
* Verify if attribute is a part of configurable product and should not be validated.
57+
*
58+
* @param DataObject $entity
59+
* @param AbstractAttribute $attribute
60+
* @return bool
61+
*/
62+
private function isAttributeShouldNotBeValidated(DataObject $entity, AbstractAttribute $attribute): bool
63+
{
64+
if (!($entity instanceof ProductInterface && $entity->getTypeId() === Configurable::TYPE_CODE)) {
65+
return false;
66+
}
67+
$attributeId = $attribute->getAttributeId();
68+
$options = $entity->getConfigurableProductOptions() ?: [];
69+
$configurableAttributeIds = array_column($options, 'attribute_id');
70+
71+
return in_array($attributeId, $configurableAttributeIds)
72+
|| in_array($attributeId, $this->configurableProductType->getUsedProductAttributeIds($entity), true);
73+
}
5574
}

Diff for: app/code/Magento/Elasticsearch/etc/di.xml

+15-15
Original file line numberDiff line numberDiff line change
@@ -383,12 +383,12 @@
383383
<virtualType name="elasticsearch5FieldNameResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver">
384384
<arguments>
385385
<argument name="items" xsi:type="array">
386-
<item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
387-
<item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
388-
<item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
389-
<item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
390-
<item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
391-
<item name="default" xsi:type="object">elasticsearch5FieldNameDefaultResolver</item>
386+
<item name="notEav" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
387+
<item name="special" xsi:type="object" sortOrder="20">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
388+
<item name="price" xsi:type="object" sortOrder="30">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
389+
<item name="categoryName" xsi:type="object" sortOrder="40">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
390+
<item name="position" xsi:type="object" sortOrder="50">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
391+
<item name="default" xsi:type="object" sortOrder="100">elasticsearch5FieldNameDefaultResolver</item>
392392
</argument>
393393
</arguments>
394394
</virtualType>
@@ -401,21 +401,21 @@
401401
<type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver">
402402
<arguments>
403403
<argument name="items" xsi:type="array">
404-
<item name="integer" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item>
405-
<item name="datetime" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType</item>
406-
<item name="float" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType</item>
407-
<item name="default" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver</item>
404+
<item name="integer" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item>
405+
<item name="datetime" xsi:type="object" sortOrder="20">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DateTimeType</item>
406+
<item name="float" xsi:type="object" sortOrder="30">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\FloatType</item>
407+
<item name="default" xsi:type="object" sortOrder="100">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\DefaultResolver</item>
408408
</argument>
409409
</arguments>
410410
</type>
411411
<type name="Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\CompositeResolver">
412412
<arguments>
413413
<argument name="items" xsi:type="array">
414-
<item name="keyword" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType</item>
415-
<item name="integer" xsi:type="object">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item>
416-
<item name="datetime" xsi:type="object">elasticsearch5FieldTypeDateTimeResolver</item>
417-
<item name="float" xsi:type="object">elasticsearch5FieldTypeFloatResolver</item>
418-
<item name="default" xsi:type="object">elasticsearch5FieldTypeDefaultResolver</item>
414+
<item name="keyword" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\KeywordType</item>
415+
<item name="integer" xsi:type="object" sortOrder="20">\Magento\Elasticsearch\Elasticsearch5\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\Resolver\IntegerType</item>
416+
<item name="datetime" xsi:type="object" sortOrder="30">elasticsearch5FieldTypeDateTimeResolver</item>
417+
<item name="float" xsi:type="object" sortOrder="40">elasticsearch5FieldTypeFloatResolver</item>
418+
<item name="default" xsi:type="object" sortOrder="100">elasticsearch5FieldTypeDefaultResolver</item>
419419
</argument>
420420
</arguments>
421421
</type>

Diff for: app/code/Magento/Elasticsearch6/etc/di.xml

+6-6
Original file line numberDiff line numberDiff line change
@@ -144,12 +144,12 @@
144144
<virtualType name="elasticsearch6FieldNameResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver">
145145
<arguments>
146146
<argument name="items" xsi:type="array">
147-
<item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
148-
<item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
149-
<item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
150-
<item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
151-
<item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
152-
<item name="default" xsi:type="object">\Magento\Elasticsearch6\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item>
147+
<item name="notEav" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
148+
<item name="special" xsi:type="object" sortOrder="20">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
149+
<item name="price" xsi:type="object" sortOrder="30">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
150+
<item name="categoryName" xsi:type="object" sortOrder="40">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
151+
<item name="position" xsi:type="object" sortOrder="50">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
152+
<item name="default" xsi:type="object" sortOrder="100">\Magento\Elasticsearch6\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item>
153153
</argument>
154154
</arguments>
155155
</virtualType>

Diff for: app/code/Magento/Elasticsearch7/etc/di.xml

+6-6
Original file line numberDiff line numberDiff line change
@@ -134,12 +134,12 @@
134134
<virtualType name="\Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver" type="\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CompositeResolver">
135135
<arguments>
136136
<argument name="items" xsi:type="array">
137-
<item name="notEav" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
138-
<item name="special" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
139-
<item name="price" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
140-
<item name="categoryName" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
141-
<item name="position" xsi:type="object">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
142-
<item name="default" xsi:type="object">Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item>
137+
<item name="notEav" xsi:type="object" sortOrder="10">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\NotEavAttribute</item>
138+
<item name="special" xsi:type="object" sortOrder="20">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\SpecialAttribute</item>
139+
<item name="price" xsi:type="object" sortOrder="30">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Price</item>
140+
<item name="categoryName" xsi:type="object" sortOrder="40">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\CategoryName</item>
141+
<item name="position" xsi:type="object" sortOrder="50">\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\Position</item>
142+
<item name="default" xsi:type="object" sortOrder="100">Magento\Elasticsearch7\Model\Adapter\FieldMapper\Product\FieldProvider\FieldName\Resolver\DefaultResolver</item>
143143
</argument>
144144
</arguments>
145145
</virtualType>

Diff for: app/code/Magento/Email/Model/Transport.php

+13-2
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@
88
namespace Magento\Email\Model;
99

1010
use Magento\Framework\App\Config\ScopeConfigInterface;
11+
use Magento\Framework\App\ObjectManager;
1112
use Magento\Framework\Exception\MailException;
1213
use Magento\Framework\Mail\MessageInterface;
1314
use Magento\Framework\Mail\TransportInterface;
1415
use Magento\Framework\Phrase;
1516
use Magento\Store\Model\ScopeInterface;
1617
use Laminas\Mail\Message;
1718
use Laminas\Mail\Transport\Sendmail;
19+
use Psr\Log\LoggerInterface;
1820

1921
/**
2022
* Class that responsible for filling some message data before transporting it.
@@ -60,15 +62,22 @@ class Transport implements TransportInterface
6062
*/
6163
private $message;
6264

65+
/**
66+
* @var LoggerInterface|null
67+
*/
68+
private $logger;
69+
6370
/**
6471
* @param MessageInterface $message Email message object
6572
* @param ScopeConfigInterface $scopeConfig Core store config
6673
* @param null|string|array|\Traversable $parameters Config options for sendmail parameters
74+
* @param LoggerInterface|null $logger
6775
*/
6876
public function __construct(
6977
MessageInterface $message,
7078
ScopeConfigInterface $scopeConfig,
71-
$parameters = null
79+
$parameters = null,
80+
LoggerInterface $logger = null
7281
) {
7382
$this->isSetReturnPath = (int) $scopeConfig->getValue(
7483
self::XML_PATH_SENDING_SET_RETURN_PATH,
@@ -81,6 +90,7 @@ public function __construct(
8190

8291
$this->laminasTransport = new Sendmail($parameters);
8392
$this->message = $message;
93+
$this->logger = $logger ?: ObjectManager::getInstance()->get(LoggerInterface::class);
8494
}
8595

8696
/**
@@ -100,7 +110,8 @@ public function sendMessage()
100110

101111
$this->laminasTransport->send($laminasMessage);
102112
} catch (\Exception $e) {
103-
throw new MailException(new Phrase($e->getMessage()), $e);
113+
$this->logger->error($e);
114+
throw new MailException(new Phrase('Unable to send mail. Please try again later.'));
104115
}
105116
}
106117

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Email\Test\Unit\Model;
9+
10+
use Laminas\Mail\Transport\Exception\RuntimeException;
11+
use Magento\Email\Model\Transport;
12+
use Magento\Framework\App\Config\ScopeConfigInterface;
13+
use Magento\Framework\Mail\Message;
14+
use PHPUnit\Framework\MockObject\MockObject;
15+
use PHPUnit\Framework\TestCase;
16+
use Psr\Log\LoggerInterface;
17+
18+
/**
19+
* Tests for email transport functionality.
20+
*/
21+
class TransportTest extends TestCase
22+
{
23+
/**
24+
* @var MockObject|LoggerInterface
25+
*/
26+
private $loggerMock;
27+
28+
/**
29+
* @var Transport
30+
*/
31+
private $transport;
32+
33+
/**
34+
* @var ScopeConfigInterface|MockObject
35+
*/
36+
private $scopeConfigMock;
37+
38+
/**
39+
* @inheridoc
40+
*/
41+
protected function setUp(): void
42+
{
43+
$this->loggerMock = $this->getMockBuilder(LoggerInterface::class)
44+
->disableOriginalConstructor()
45+
->onlyMethods(['error'])
46+
->getMockForAbstractClass();
47+
$this->scopeConfigMock = $this->getMockBuilder(ScopeConfigInterface::class)
48+
->disableOriginalConstructor()
49+
->getMockForAbstractClass();
50+
$this->transport = new Transport(
51+
new Message(),
52+
$this->scopeConfigMock,
53+
null,
54+
$this->loggerMock
55+
);
56+
}
57+
58+
/**
59+
* Verify exception is properly handled in case one occurred when message sent.
60+
*
61+
* @return void
62+
*/
63+
public function testSendMessageBrokenMessage(): void
64+
{
65+
$exception = new RuntimeException('Invalid email; contains no at least one of "To", "Cc", and "Bcc" header');
66+
$this->loggerMock->expects(self::once())->method('error')->with($exception);
67+
$this->expectException('Magento\Framework\Exception\MailException');
68+
$this->expectExceptionMessage('Unable to send mail. Please try again later.');
69+
70+
$this->transport->sendMessage();
71+
}
72+
}

Diff for: app/code/Magento/Email/i18n/en_US.csv

+1
Original file line numberDiff line numberDiff line change
@@ -98,3 +98,4 @@ Action,Action
9898
"Email template chosen based on theme fallback, when the ""Default"" option is selected.","Email template chosen based on theme fallback, when the ""Default"" option is selected."
9999
"Header Template","Header Template"
100100
"Footer Template","Footer Template"
101+
"Unable to send mail. Please try again later.","Unable to send mail. Please try again later."

Diff for: app/design/frontend/Magento/blank/web/css/source/_actions-toolbar.less

+6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@
2727
margin-bottom: 0;
2828
}
2929
}
30+
31+
> .secondary {
32+
.action.back {
33+
display: none;
34+
}
35+
}
3036
}
3137
}
3238

Diff for: app/design/frontend/Magento/blank/web/css/source/_theme.less

+3
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,6 @@
1010
// Theme file should contain declarations (overrides) ONLY OF EXISTING variables
1111
// Otherwise this theme won't be available for parent nesting
1212
// All new variables should be placed in local theme lib or local theme files
13+
14+
// Form field note icon
15+
@form-field-note-icon-font__content: false;

0 commit comments

Comments
 (0)