Skip to content

Commit c3615e1

Browse files
Merge branch 'magento-commerce:2.4-develop' into L3-PR-2024-02-16
2 parents 5f735a2 + c971859 commit c3615e1

File tree

18 files changed

+703
-20
lines changed

18 files changed

+703
-20
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/************************************************************************
3+
*
4+
* Copyright 2024 Adobe
5+
* All Rights Reserved.
6+
*
7+
* NOTICE: All information contained herein is, and remains
8+
* the property of Adobe and its suppliers, if any. The intellectual
9+
* and technical concepts contained herein are proprietary to Adobe
10+
* and its suppliers and are protected by all applicable intellectual
11+
* property laws, including trade secret and copyright laws.
12+
* Dissemination of this information or reproduction of this material
13+
* is strictly forbidden unless prior written permission is obtained
14+
* from Adobe.
15+
* ************************************************************************
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\CatalogGraphQl\Plugin;
20+
21+
use GraphQL\Language\AST\Node;
22+
use GraphQL\Language\AST\NodeKind;
23+
use GraphQL\Language\Visitor;
24+
use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
25+
use Magento\GraphQl\Model\Query\ContextInterface;
26+
27+
class ProductAttributeSortInput
28+
{
29+
/**
30+
* Plugin to preserve the original order of sort fields
31+
*
32+
* @param \Magento\Framework\GraphQl\Query\ResolverInterface $subject
33+
* @param \Magento\Framework\GraphQl\Config\Element\Field $field
34+
* @param ContextInterface $context
35+
* @param ResolveInfo $info
36+
* @param array|null $value
37+
* @param array|null $args
38+
* @return array
39+
* @throws \Exception
40+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
41+
*/
42+
public function beforeResolve(
43+
\Magento\Framework\GraphQl\Query\ResolverInterface $subject,
44+
\Magento\Framework\GraphQl\Config\Element\Field $field,
45+
ContextInterface $context,
46+
ResolveInfo $info,
47+
array $value = null,
48+
array $args = null
49+
): array {
50+
if (isset($args['sort'])) {
51+
$args['sort'] = $this->getSortFieldsOrder($info, $args['sort']);
52+
}
53+
return [$field, $context, $info, $value, $args];
54+
}
55+
56+
/**
57+
* Get sort fields in the original order
58+
*
59+
* @param ResolveInfo $info
60+
* @param array $sortFields
61+
* @return array
62+
* @throws \Exception
63+
*/
64+
private function getSortFieldsOrder(ResolveInfo $info, array $sortFields)
65+
{
66+
$sortFieldsOriginal = [];
67+
Visitor::visit(
68+
$info->operation,
69+
[
70+
'enter' => [
71+
NodeKind::ARGUMENT => function (Node $node) use (&$sortFieldsOriginal, $sortFields) {
72+
if ($node->name->value === 'sort') {
73+
Visitor::visit(
74+
$node->value,
75+
[
76+
'enter' => [
77+
NodeKind::OBJECT_FIELD =>
78+
function (Node $node) use (&$sortFieldsOriginal, $sortFields) {
79+
if (isset($sortFields[$node->name->value])) {
80+
$sortFieldsOriginal[$node->name->value] =
81+
$sortFields[$node->name->value];
82+
}
83+
}
84+
]
85+
]
86+
);
87+
return Visitor::stop();
88+
}
89+
}
90+
]
91+
]
92+
);
93+
return $sortFieldsOriginal;
94+
}
95+
}

app/code/Magento/CatalogGraphQl/etc/graphql/di.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,12 @@
283283
</argument>
284284
</arguments>
285285
</type>
286+
287+
<type name="Magento\CatalogGraphQl\Model\Resolver\Products">
288+
<plugin name="originalProductSortOrder" type="Magento\CatalogGraphQl\Plugin\ProductAttributeSortInput" />
289+
</type>
290+
291+
<type name="Magento\CatalogGraphQl\Model\Resolver\Category\Products">
292+
<plugin name="originalCategoryProductSortOrder" type="Magento\CatalogGraphQl\Plugin\ProductAttributeSortInput" />
293+
</type>
286294
</config>

app/code/Magento/CustomerImportExport/Model/Import/AbstractCustomer.php

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
namespace Magento\CustomerImportExport\Model\Import;
88

9+
use Magento\Customer\Model\Config\Share;
10+
use Magento\Framework\App\ObjectManager;
911
use Magento\Framework\Validator\EmailAddress;
1012
use Magento\Framework\Validator\ValidateException;
1113
use Magento\Framework\Validator\ValidatorChain;
@@ -87,6 +89,11 @@ abstract class AbstractCustomer extends \Magento\ImportExport\Model\Import\Entit
8789
*/
8890
protected $masterAttributeCode = '_email';
8991

92+
/**
93+
* @var Share
94+
*/
95+
private $configShare;
96+
9097
/**
9198
* @param \Magento\Framework\Stdlib\StringUtils $string
9299
* @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
@@ -99,6 +106,7 @@ abstract class AbstractCustomer extends \Magento\ImportExport\Model\Import\Entit
99106
* @param \Magento\Eav\Model\Config $eavConfig
100107
* @param \Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\StorageFactory $storageFactory
101108
* @param array $data
109+
* @param Share|null $configShare
102110
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
103111
*/
104112
public function __construct(
@@ -112,7 +120,8 @@ public function __construct(
112120
\Magento\ImportExport\Model\Export\Factory $collectionFactory,
113121
\Magento\Eav\Model\Config $eavConfig,
114122
\Magento\CustomerImportExport\Model\ResourceModel\Import\Customer\StorageFactory $storageFactory,
115-
array $data = []
123+
array $data = [],
124+
?Share $configShare = null
116125
) {
117126
$this->_storageFactory = $storageFactory;
118127
parent::__construct(
@@ -127,7 +136,7 @@ public function __construct(
127136
$eavConfig,
128137
$data
129138
);
130-
139+
$this->configShare = $configShare ?? ObjectManager::getInstance()->get(Share::class);
131140
$this->addMessageTemplate(self::ERROR_WEBSITE_IS_EMPTY, __('Please specify a website.'));
132141
$this->addMessageTemplate(
133142
self::ERROR_EMAIL_IS_EMPTY,
@@ -174,6 +183,11 @@ protected function _initCustomers(array $data)
174183
protected function _getCustomerId($email, $websiteCode)
175184
{
176185
$email = strtolower(trim($email));
186+
187+
if ($this->configShare->isGlobalScope()) {
188+
return $this->_customerStorage->getCustomerIdByEmail($email);
189+
}
190+
177191
if (isset($this->_websiteCodeToId[$websiteCode])) {
178192
$websiteId = $this->_websiteCodeToId[$websiteCode];
179193
return $this->_customerStorage->getCustomerId($email, $websiteId);

app/code/Magento/CustomerImportExport/Model/Import/Address.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
namespace Magento\CustomerImportExport\Model\Import;
88

9+
use Magento\Customer\Model\Config\Share;
910
use Magento\Customer\Model\ResourceModel\Address\Attribute\Source\CountryWithWebsites as CountryWithWebsitesSource;
1011
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
1112
use Magento\Framework\App\ObjectManager;
@@ -272,7 +273,8 @@ class Address extends AbstractCustomer
272273
* @param array $data
273274
* @param CountryWithWebsitesSource|null $countryWithWebsites
274275
* @param AddressStorage|null $addressStorage
275-
* @param Processor $indexerProcessor
276+
* @param Processor|null $indexerProcessor
277+
* @param Share|null $configShare
276278
*
277279
* @SuppressWarnings(PHPMD.NPathComplexity)
278280
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -297,7 +299,8 @@ public function __construct(
297299
array $data = [],
298300
?CountryWithWebsitesSource $countryWithWebsites = null,
299301
?AddressStorage $addressStorage = null,
300-
?Processor $indexerProcessor = null
302+
?Processor $indexerProcessor = null,
303+
?Share $configShare = null
301304
) {
302305
$this->_customerFactory = $customerFactory;
303306
$this->_addressFactory = $addressFactory;
@@ -325,7 +328,8 @@ public function __construct(
325328
$collectionFactory,
326329
$eavConfig,
327330
$storageFactory,
328-
$data
331+
$data,
332+
$configShare
329333
);
330334

331335
$this->_entityTable = isset(

app/code/Magento/CustomerImportExport/Model/ResourceModel/Import/Customer/Storage.php

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
namespace Magento\CustomerImportExport\Model\ResourceModel\Import\Customer;
77

8+
use Magento\Customer\Api\CustomerRepositoryInterface;
89
use Magento\Customer\Model\ResourceModel\Customer\Collection as CustomerCollection;
910
use Magento\Customer\Model\ResourceModel\Customer\CollectionFactory as CustomerCollectionFactory;
1011
use Magento\Framework\DataObject;
@@ -29,6 +30,11 @@ class Storage
2930
*/
3031
protected $_customerIds = [];
3132

33+
/**
34+
* @var array
35+
*/
36+
private $customerIdsByEmail = [];
37+
3238
/**
3339
* Number of items to fetch from db in one query
3440
*
@@ -60,19 +66,27 @@ class Storage
6066
*/
6167
private $customerStoreIds = [];
6268

69+
/**
70+
* @var CustomerRepositoryInterface
71+
*/
72+
private $customerRepository;
73+
6374
/**
6475
* @param CustomerCollectionFactory $collectionFactory
76+
* @param CustomerRepositoryInterface $customerRepository
6577
* @param array $data
6678
*/
6779
public function __construct(
6880
CustomerCollectionFactory $collectionFactory,
81+
CustomerRepositoryInterface $customerRepository,
6982
array $data = []
7083
) {
7184
$this->_customerCollection = isset(
7285
$data['customer_collection']
7386
) ? $data['customer_collection'] : $collectionFactory->create();
7487
$this->_pageSize = isset($data['page_size']) ? (int) $data['page_size'] : 0;
7588
$this->customerCollectionFactory = $collectionFactory;
89+
$this->customerRepository = $customerRepository;
7690
}
7791

7892
/**
@@ -130,7 +144,8 @@ public function addCustomerByArray(array $customer): Storage
130144
/**
131145
* Add customer to array
132146
*
133-
* @deprecated 100.3.0 @see addCustomerByArray
147+
* @deprecated 100.3.0
148+
* @see addCustomerByArray
134149
* @param DataObject $customer
135150
* @return $this
136151
*/
@@ -164,6 +179,25 @@ public function getCustomerId(string $email, int $websiteId)
164179
return false;
165180
}
166181

182+
/**
183+
* Find customer ID by email.
184+
*
185+
* @param string $email
186+
* @return bool|int
187+
*/
188+
public function getCustomerIdByEmail(string $email)
189+
{
190+
if (!isset($this->customerIdsByEmail[$email])) {
191+
try {
192+
$this->customerIdsByEmail[$email] = $this->customerRepository->get($email)->getId();
193+
} catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
194+
$this->customerIdsByEmail[$email] = false;
195+
}
196+
}
197+
198+
return $this->customerIdsByEmail[$email];
199+
}
200+
167201
/**
168202
* Get previously loaded customer id.
169203
*

app/code/Magento/CustomerImportExport/Test/Unit/Model/Import/AddressTest.php

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
use Magento\Customer\Model\Address\Validator\Postcode;
1111
use Magento\Customer\Model\AddressFactory;
12+
use Magento\Customer\Model\Config\Share;
1213
use Magento\Customer\Model\CustomerFactory;
1314
use Magento\Customer\Model\Indexer\Processor;
1415
use Magento\Customer\Model\ResourceModel\Address\Attribute as AddressAttribute;
@@ -149,6 +150,16 @@ class AddressTest extends TestCase
149150
*/
150151
private $countryWithWebsites;
151152

153+
/**
154+
* @var Share|MockObject
155+
*/
156+
private $configShare;
157+
158+
/**
159+
* @var Storage
160+
*/
161+
private $customerStorage;
162+
152163
/**
153164
* Init entity adapter model
154165
*/
@@ -171,6 +182,7 @@ protected function setUp(): void
171182

172183
->method('getAllOptions')
173184
->willReturn([]);
185+
$this->configShare = $this->createMock(Share::class);
174186
$this->_model = $this->_getModelMock();
175187
$this->errorAggregator = $this->createPartialMock(
176188
ProcessingErrorAggregator::class,
@@ -198,7 +210,7 @@ protected function _getModelDependencies()
198210
->getMock();
199211
$connection = $this->createMock(\stdClass::class);
200212
$attributeCollection = $this->_createAttrCollectionMock();
201-
$customerStorage = $this->_createCustomerStorageMock();
213+
$this->customerStorage = $this->_createCustomerStorageMock();
202214
$customerEntity = $this->_createCustomerEntityMock();
203215
$addressCollection = new Collection(
204216
$this->createMock(EntityFactory::class)
@@ -222,7 +234,7 @@ protected function _getModelDependencies()
222234
'bunch_size' => 1,
223235
'attribute_collection' => $attributeCollection,
224236
'entity_type_id' => 1,
225-
'customer_storage' => $customerStorage,
237+
'customer_storage' => $this->customerStorage,
226238
'customer_entity' => $customerEntity,
227239
'address_collection' => $addressCollection,
228240
'entity_table' => 'not_used',
@@ -388,7 +400,8 @@ protected function _getModelMock()
388400
$this->_getModelDependencies(),
389401
$this->countryWithWebsites,
390402
$this->createMock(\Magento\CustomerImportExport\Model\ResourceModel\Import\Address\Storage::class),
391-
$this->createMock(Processor::class)
403+
$this->createMock(Processor::class),
404+
$this->configShare
392405
);
393406

394407
$property = new \ReflectionProperty($modelMock, '_availableBehaviors');
@@ -447,6 +460,37 @@ public function testValidateRowForUpdate(array $rowData, array $errors, $isValid
447460
{
448461
$this->_model->setParameters(['behavior' => Import::BEHAVIOR_ADD_UPDATE]);
449462

463+
$this->configShare->expects($this->once())
464+
->method('isGlobalScope')
465+
->willReturn(false);
466+
467+
if ($isValid) {
468+
$this->assertTrue($this->_model->validateRow($rowData, 0));
469+
} else {
470+
$this->assertFalse($this->_model->validateRow($rowData, 0));
471+
}
472+
}
473+
474+
/**
475+
* @dataProvider validateRowForUpdateDataProvider
476+
*
477+
* @param array $rowData
478+
* @param array $errors
479+
* @param boolean $isValid
480+
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
481+
*/
482+
public function testValidateRowForUpdateGlobalCustomer(array $rowData, array $errors, $isValid = false)
483+
{
484+
$this->_model->setParameters(['behavior' => Import::BEHAVIOR_ADD_UPDATE]);
485+
486+
$this->configShare->expects($this->once())
487+
->method('isGlobalScope')
488+
->willReturn(true);
489+
490+
$this->customerStorage->expects($this->once())
491+
->method('getCustomerIdByEmail')
492+
->willReturn(1);
493+
450494
if ($isValid) {
451495
$this->assertTrue($this->_model->validateRow($rowData, 0));
452496
} else {

0 commit comments

Comments
 (0)