Skip to content

Commit 4bccc29

Browse files
committed
ACP2E-2166: Magento is slow for customers with large address books
- using search address settings
1 parent 9cf2cf0 commit 4bccc29

File tree

8 files changed

+132
-35
lines changed

8 files changed

+132
-35
lines changed

app/code/Magento/Checkout/Block/Checkout/AttributeMerger.php

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Magento\Customer\Api\CustomerRepositoryInterface as CustomerRepository;
99
use Magento\Customer\Api\Data\CustomerInterface;
1010
use Magento\Customer\Helper\Address as AddressHelper;
11-
use Magento\Customer\Model\Customer;
1211
use Magento\Customer\Model\Session;
1312
use Magento\Directory\Helper\Data as DirectoryHelper;
1413
use Magento\Directory\Model\AllowedCountries;
@@ -79,7 +78,7 @@ class AttributeMerger
7978
private $customerRepository;
8079

8180
/**
82-
* @var Customer
81+
* @var CustomerInterface
8382
*/
8483
private $customer;
8584

@@ -381,13 +380,13 @@ protected function getDefaultValue($attributeCode): ?string
381380
*
382381
* @throws NoSuchEntityException
383382
* @throws LocalizedException
384-
* @return Customer|null
383+
* @return CustomerInterface|null
385384
*/
386-
protected function getCustomer(): ?Customer
385+
protected function getCustomer(): ?CustomerInterface
387386
{
388387
if (!$this->customer) {
389388
if ($this->customerSession->isLoggedIn()) {
390-
$this->customerSession->getCustomer();
389+
$this->customer = $this->customerRepository->getById($this->customerSession->getCustomerId());
391390
} else {
392391
return null;
393392
}

app/code/Magento/Checkout/Controller/Action.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public function __construct(
6060
protected function _preDispatchValidateCustomer($redirect = true, $addErrors = true)
6161
{
6262
try {
63-
$customer = $this->_customerSession->getCustomerData();
63+
$customer = $this->customerRepository->getById($this->_customerSession->getCustomerId());
6464
} catch (NoSuchEntityException $e) {
6565
return true;
6666
}

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,14 @@ private function getCustomerData(): array
397397
if ($this->isCustomerLoggedIn()) {
398398
$customer = $this->getCustomer();
399399
$customerData = $customer->__toArray();
400-
$customerData['addresses'] = $this->customerAddressData->getAddressDataByCustomer($customer);
400+
$addressLimit = null;
401+
if ($this->scopeConfig->getValue('checkout/options/enable_address_search', ScopeInterface::SCOPE_STORE)) {
402+
$addressLimit = (int)$this->scopeConfig->getValue(
403+
'checkout/options/customer_address_limit',
404+
ScopeInterface::SCOPE_STORE
405+
);
406+
}
407+
$customerData['addresses'] = $this->customerAddressData->getAddressDataByCustomer($customer, $addressLimit);
401408
}
402409
return $customerData;
403410
}
@@ -775,6 +782,6 @@ private function getQuoteAddressData(): array
775782
*/
776783
private function getCustomer(): CustomerInterface
777784
{
778-
return $this->customerSession->getCustomerData();
785+
return $this->customerRepository->getById($this->customerSession->getCustomerId());
779786
}
780787
}

app/code/Magento/Checkout/Model/Type/Onepage.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,7 +344,7 @@ public function initCheckout()
344344
* want to load the correct customer information by assigning to address
345345
* instead of just loading from sales/quote_address
346346
*/
347-
$customer = $customerSession->getCustomerData();
347+
$customer = $customerSession->getCustomerDataObject();
348348
if ($customer) {
349349
$quote->assignCustomer($customer);
350350
}

app/code/Magento/Customer/Model/Address/CustomerAddressDataProvider.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
namespace Magento\Customer\Model\Address;
99

10+
use Magento\Customer\Api\Data\CustomerInterface;
1011
use Magento\Customer\Model\Config\Share;
1112
use Magento\Directory\Model\AllowedCountries;
1213
use Magento\Framework\App\ObjectManager;
14+
use Magento\Framework\Exception\LocalizedException;
1315

1416
/**
1517
* Provides customer address data.
@@ -58,12 +60,14 @@ public function __construct(
5860
/**
5961
* Get addresses for customer.
6062
*
61-
* @param \Magento\Customer\Api\Data\CustomerInterface $customer
63+
* @param CustomerInterface $customer
64+
* @param int|null $addressLimit
6265
* @return array
63-
* @throws \Magento\Framework\Exception\LocalizedException
66+
* @throws LocalizedException
6467
*/
6568
public function getAddressDataByCustomer(
66-
\Magento\Customer\Api\Data\CustomerInterface $customer
69+
\Magento\Customer\Api\Data\CustomerInterface $customer,
70+
?int $addressLimit = null
6771
): array {
6872
if (!empty($this->customerAddresses)) {
6973
return $this->customerAddresses;
@@ -83,6 +87,9 @@ public function getAddressDataByCustomer(
8387
}
8488

8589
$customerAddresses[$address->getId()] = $this->customerAddressDataFormatter->prepareAddress($address);
90+
if ($addressLimit && count($customerAddresses) >= $addressLimit) {
91+
break;
92+
}
8693
}
8794

8895
$this->customerAddresses = $customerAddresses;

app/code/Magento/Customer/Model/Customer.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -342,21 +342,21 @@ public function _construct()
342342
public function getDataModel()
343343
{
344344
$customerData = $this->getData();
345-
if (!$this->storedAddress) {
346-
/** @var \Magento\Customer\Model\Address $address */
347-
foreach ($this->getAddresses() as $address) {
348-
if (!isset($this->storedAddress[$address->getId()])) {
349-
$this->storedAddress[$address->getId()] = $address->getDataModel();
350-
}
345+
$addressesData = [];
346+
/** @var \Magento\Customer\Model\Address $address */
347+
foreach ($this->getAddresses() as $address) {
348+
if (!isset($this->storedAddress[$address->getId()])) {
349+
$this->storedAddress[$address->getId()] = $address->getDataModel();
351350
}
351+
$addressesData[] = $this->storedAddress[$address->getId()];
352352
}
353353
$customerDataObject = $this->customerDataFactory->create();
354354
$this->dataObjectHelper->populateWithArray(
355355
$customerDataObject,
356356
$customerData,
357357
\Magento\Customer\Api\Data\CustomerInterface::class
358358
);
359-
$customerDataObject->setAddresses(array_values($this->storedAddress))
359+
$customerDataObject->setAddresses($addressesData)
360360
->setId($this->getId());
361361
return $customerDataObject;
362362
}

app/code/Magento/Customer/Model/Session.php

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313
use Magento\Customer\Model\Config\Share;
1414
use Magento\Customer\Model\ResourceModel\Customer as ResourceCustomer;
1515
use Magento\Framework\App\ObjectManager;
16-
use Magento\Framework\Exception\NoSuchEntityException;
1716
use Magento\Framework\Session\Generic;
1817

1918
/**
@@ -108,11 +107,6 @@ class Session extends \Magento\Framework\Session\SessionManager
108107
*/
109108
private $accountConfirmation;
110109

111-
/**
112-
* @var CustomerRegistry
113-
*/
114-
private $customerRegistry;
115-
116110
/**
117111
* Session constructor.
118112
*
@@ -138,7 +132,6 @@ class Session extends \Magento\Framework\Session\SessionManager
138132
* @param GroupManagementInterface $groupManagement
139133
* @param \Magento\Framework\App\Response\Http $response
140134
* @param AccountConfirmation $accountConfirmation
141-
* @param CustomerRegistry $customerRegistry
142135
* @throws \Magento\Framework\Exception\SessionException
143136
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
144137
*/
@@ -164,8 +157,7 @@ public function __construct(
164157
CustomerRepositoryInterface $customerRepository,
165158
GroupManagementInterface $groupManagement,
166159
\Magento\Framework\App\Response\Http $response,
167-
AccountConfirmation $accountConfirmation = null,
168-
CustomerRegistry $customerRegistry = null
160+
AccountConfirmation $accountConfirmation = null
169161
) {
170162
$this->_coreUrl = $coreUrl;
171163
$this->_customerUrl = $customerUrl;
@@ -181,8 +173,6 @@ public function __construct(
181173
$this->response = $response;
182174
$this->accountConfirmation = $accountConfirmation ?: ObjectManager::getInstance()
183175
->get(AccountConfirmation::class);
184-
$this->customerRegistry = $customerRegistry ?: ObjectManager::getInstance()
185-
->get(CustomerRegistry::class);
186176
parent::__construct(
187177
$request,
188178
$sidResolver,
@@ -309,15 +299,14 @@ public function setCustomer(Customer $customerModel)
309299
*
310300
* @return Customer
311301
* use getCustomerId() instead
312-
* @throws NoSuchEntityException
313302
*/
314303
public function getCustomer()
315304
{
316305
if ($this->_customerModel === null) {
317306
$this->_customerModel = $this->_customerFactory->create();
318307

319308
if ($this->getCustomerId()) {
320-
$this->_customerModel = $this->customerRegistry->retrieve($this->getCustomerId());
309+
$this->_customerResource->load($this->_customerModel, $this->getCustomerId());
321310
}
322311
}
323312

@@ -396,8 +385,8 @@ public function getCustomerGroupId()
396385
if ($this->storage->getData('customer_group_id')) {
397386
return $this->storage->getData('customer_group_id');
398387
}
399-
if ($this->getCustomer()) {
400-
$customerGroupId = $this->getCustomer()->getGroupId();
388+
if ($this->getCustomerData()) {
389+
$customerGroupId = $this->getCustomerData()->getGroupId();
401390
$this->setCustomerGroupId($customerGroupId);
402391
return $customerGroupId;
403392
}
@@ -442,7 +431,7 @@ public function checkCustomerId($customerId)
442431
}
443432

444433
try {
445-
$this->customerRegistry->retrieve($customerId);
434+
$this->customerRepository->getById($customerId);
446435
$this->_isCustomerIdChecked = $customerId;
447436
return true;
448437
} catch (\Exception $e) {
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/**
3+
* Copyright 2023 Adobe
4+
* All Rights Reserved.
5+
*
6+
* ADOBE CONFIDENTIAL
7+
*
8+
* NOTICE: All information contained herein is, and remains
9+
* the property of Adobe and its suppliers, if any. The intellectual
10+
* and technical concepts contained herein are proprietary to Adobe
11+
* and its suppliers and are protected by all applicable intellectual
12+
* property laws, including trade secret and copyright laws.
13+
* Dissemination of this information or reproduction of this material
14+
* is strictly forbidden unless prior written permission is obtained
15+
* from Adobe.
16+
*/
17+
declare(strict_types=1);
18+
19+
namespace Magento\Customer\Test\Unit\Model\Address;
20+
21+
use Magento\Customer\Api\Data\AddressInterface;
22+
use Magento\Customer\Api\Data\CustomerInterface;
23+
use Magento\Customer\Model\Address\CustomerAddressDataFormatter;
24+
use Magento\Customer\Model\Address\CustomerAddressDataProvider;
25+
use Magento\Customer\Model\Config\Share;
26+
use Magento\Directory\Model\AllowedCountries;
27+
use PHPUnit\Framework\MockObject\MockObject;
28+
use PHPUnit\Framework\TestCase;
29+
30+
class CustomerAddressDataProviderTest extends TestCase
31+
{
32+
/**
33+
* @var CustomerAddressDataFormatter|MockObject
34+
*/
35+
private CustomerAddressDataFormatter $customerAddressDataFormatter;
36+
37+
/**
38+
* @var Share|MockObject
39+
*/
40+
private Share $shareConfig;
41+
42+
/**
43+
* @var AllowedCountries|MockObject
44+
*/
45+
private AllowedCountries $allowedCountryReader;
46+
47+
/**
48+
* @var CustomerAddressDataProvider
49+
*/
50+
private CustomerAddressDataProvider $provider;
51+
52+
/**
53+
* @inheritdoc
54+
*/
55+
protected function setUp(): void
56+
{
57+
$this->customerAddressDataFormatter = $this->createMock(CustomerAddressDataFormatter::class);
58+
$this->shareConfig = $this->createMock(Share::class);
59+
$this->allowedCountryReader = $this->createMock(AllowedCountries::class);
60+
61+
$this->provider = new CustomerAddressDataProvider(
62+
$this->customerAddressDataFormatter,
63+
$this->shareConfig,
64+
$this->allowedCountryReader
65+
);
66+
}
67+
68+
/**
69+
* @return void
70+
* @throws \Magento\Framework\Exception\LocalizedException
71+
*/
72+
public function testGetAddressDataByCustomer(): void
73+
{
74+
$addressLimit = 1;
75+
$this->allowedCountryReader->expects($this->once())->method('getAllowedCountries')->willReturn(['1']);
76+
$this->customerAddressDataFormatter->expects($this->once())
77+
->method('prepareAddress')
78+
->willreturn([1]);
79+
$this->shareConfig->expects($this->any())->method('isGlobalScope')->willReturn(false);
80+
81+
$viableAddress = $this->getMockForAbstractClass(AddressInterface::class);
82+
$viableAddress->expects($this->once())->method('getId')->willReturn(1);
83+
$faultyAddress = $this->getMockForAbstractClass(AddressInterface::class);
84+
85+
$customer = $this->getMockForAbstractClass(CustomerInterface::class);
86+
$customer->expects($this->once())
87+
->method('getAddresses')
88+
->willReturn([$viableAddress, $faultyAddress]);
89+
90+
$expectedResult = [
91+
'1' => [1]
92+
];
93+
$this->assertSame($expectedResult, $this->provider->getAddressDataByCustomer($customer, $addressLimit));
94+
}
95+
}

0 commit comments

Comments
 (0)