Skip to content

Commit 2d759c0

Browse files
committed
Fix #20332 - address fields sort order fixes
1 parent 2d46d98 commit 2d759c0

File tree

8 files changed

+399
-176
lines changed

8 files changed

+399
-176
lines changed

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

Lines changed: 44 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,30 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
7+
68
namespace Magento\Checkout\Block\Checkout;
79

810
use Magento\Checkout\Helper\Data;
9-
use Magento\Framework\App\ObjectManager;
11+
use Magento\Customer\Model\AttributeMetadataDataProvider;
12+
use Magento\Customer\Model\Options;
13+
use Magento\Eav\Api\Data\AttributeInterface;
14+
use Magento\Shipping\Model\Config;
1015
use Magento\Store\Model\StoreManagerInterface;
16+
use Magento\Ui\Component\Form\AttributeMapper;
1117

1218
/**
13-
* Class LayoutProcessor
19+
* Checkout Layout Processor
1420
*/
15-
class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
21+
class LayoutProcessor implements LayoutProcessorInterface
1622
{
1723
/**
18-
* @var \Magento\Customer\Model\AttributeMetadataDataProvider
24+
* @var AttributeMetadataDataProvider
1925
*/
2026
private $attributeMetadataDataProvider;
2127

2228
/**
23-
* @var \Magento\Ui\Component\Form\AttributeMapper
29+
* @var AttributeMapper
2430
*/
2531
protected $attributeMapper;
2632

@@ -30,7 +36,7 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
3036
protected $merger;
3137

3238
/**
33-
* @var \Magento\Customer\Model\Options
39+
* @var Options
3440
*/
3541
private $options;
3642

@@ -45,39 +51,35 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
4551
private $storeManager;
4652

4753
/**
48-
* @var \Magento\Shipping\Model\Config
54+
* @var Config
4955
*/
5056
private $shippingConfig;
5157

5258
/**
53-
* @param \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider
54-
* @param \Magento\Ui\Component\Form\AttributeMapper $attributeMapper
59+
* @param AttributeMetadataDataProvider $attributeMetadataDataProvider
60+
* @param AttributeMapper $attributeMapper
5561
* @param AttributeMerger $merger
56-
* @param \Magento\Customer\Model\Options|null $options
57-
* @param Data|null $checkoutDataHelper
58-
* @param \Magento\Shipping\Model\Config|null $shippingConfig
59-
* @param StoreManagerInterface|null $storeManager
62+
* @param Options $options
63+
* @param Data $checkoutDataHelper
64+
* @param Config $shippingConfig
65+
* @param StoreManagerInterface $storeManager
6066
*/
6167
public function __construct(
62-
\Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider,
63-
\Magento\Ui\Component\Form\AttributeMapper $attributeMapper,
68+
AttributeMetadataDataProvider $attributeMetadataDataProvider,
69+
AttributeMapper $attributeMapper,
6470
AttributeMerger $merger,
65-
\Magento\Customer\Model\Options $options = null,
66-
Data $checkoutDataHelper = null,
67-
\Magento\Shipping\Model\Config $shippingConfig = null,
68-
StoreManagerInterface $storeManager = null
71+
Options $options,
72+
Data $checkoutDataHelper,
73+
Config $shippingConfig,
74+
StoreManagerInterface $storeManager
6975
) {
7076
$this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
7177
$this->attributeMapper = $attributeMapper;
7278
$this->merger = $merger;
73-
$this->options = $options ?: \Magento\Framework\App\ObjectManager::getInstance()
74-
->get(\Magento\Customer\Model\Options::class);
75-
$this->checkoutDataHelper = $checkoutDataHelper ?: \Magento\Framework\App\ObjectManager::getInstance()
76-
->get(Data::class);
77-
$this->shippingConfig = $shippingConfig ?: \Magento\Framework\App\ObjectManager::getInstance()
78-
->get(\Magento\Shipping\Model\Config::class);
79-
$this->storeManager = $storeManager ?: \Magento\Framework\App\ObjectManager::getInstance()
80-
->get(StoreManagerInterface::class);
79+
$this->options = $options;
80+
$this->checkoutDataHelper = $checkoutDataHelper;
81+
$this->shippingConfig = $shippingConfig;
82+
$this->storeManager = $storeManager;
8183
}
8284

8385
/**
@@ -87,7 +89,7 @@ public function __construct(
8789
*/
8890
private function getAddressAttributes()
8991
{
90-
/** @var \Magento\Eav\Api\Data\AttributeInterface[] $attributes */
92+
/** @var AttributeInterface[] $attributes */
9193
$attributes = $this->attributeMetadataDataProvider->loadAttributesCollection(
9294
'customer_address',
9395
'customer_register_address'
@@ -157,17 +159,22 @@ public function process($jsLayout)
157159
$elements = $this->getAddressAttributes();
158160
$elements = $this->convertElementsToSelect($elements, $attributesToConvert);
159161
// The following code is a workaround for custom address attributes
160-
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
161-
['payment']['children'])) {
162+
if (isset(
163+
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']
164+
['children']
165+
)) {
162166
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
163167
['payment']['children'] = $this->processPaymentChildrenComponents(
164168
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
165169
['payment']['children'],
166170
$elements
167171
);
168172
}
169-
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
170-
['step-config']['children']['shipping-rates-validation']['children'])) {
173+
174+
if (isset(
175+
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
176+
['step-config']['children']['shipping-rates-validation']['children']
177+
)) {
171178
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
172179
['step-config']['children']['shipping-rates-validation']['children'] =
173180
$this->processShippingChildrenComponents(
@@ -176,8 +183,10 @@ public function process($jsLayout)
176183
);
177184
}
178185

179-
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
180-
['children']['shippingAddress']['children']['shipping-address-fieldset']['children'])) {
186+
if (isset(
187+
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
188+
['shippingAddress']['children']['shipping-address-fieldset']['children']
189+
)) {
181190
$fields = $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
182191
['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];
183192
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
@@ -188,6 +197,7 @@ public function process($jsLayout)
188197
$fields
189198
);
190199
}
200+
191201
return $jsLayout;
192202
}
193203

@@ -304,9 +314,6 @@ private function getBillingAddressComponent($paymentCode, $elements)
304314
'checkoutProvider',
305315
'billingAddress' . $paymentCode,
306316
[
307-
'country_id' => [
308-
'sortOrder' => 115,
309-
],
310317
'region' => [
311318
'visible' => false,
312319
],

app/code/Magento/Checkout/Test/Unit/Block/Checkout/LayoutProcessorTest.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,16 @@
1010
use Magento\Checkout\Helper\Data;
1111
use Magento\Customer\Model\AttributeMetadataDataProvider;
1212
use Magento\Customer\Model\Options;
13-
13+
use Magento\Shipping\Model\Config;
14+
use Magento\Store\Model\StoreManagerInterface;
1415
use Magento\Ui\Component\Form\AttributeMapper;
15-
use PHPUnit_Framework_MockObject_MockObject as MockObject;
16+
use PHPUnit\Framework\MockObject\MockObject;
17+
use PHPUnit\Framework\TestCase;
1618

1719
/**
1820
* LayoutProcessorTest covers a list of variations for checkout layout processor
1921
*/
20-
class LayoutProcessorTest extends \PHPUnit\Framework\TestCase
22+
class LayoutProcessorTest extends TestCase
2123
{
2224
/**
2325
* @var AttributeMetadataDataProvider|MockObject
@@ -45,7 +47,7 @@ class LayoutProcessorTest extends \PHPUnit\Framework\TestCase
4547
private $layoutProcessor;
4648

4749
/**
48-
* @var MockObject
50+
* @var StoreManagerInterface|MockObject
4951
*/
5052
private $storeManager;
5153

@@ -75,11 +77,11 @@ protected function setUp()
7577
->disableOriginalConstructor()
7678
->getMock();
7779

78-
$shippingConfig = $this->getMockBuilder(\Magento\Shipping\Model\Config::class)
80+
$shippingConfig = $this->getMockBuilder(Config::class)
7981
->disableOriginalConstructor()
8082
->getMock();
8183

82-
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
84+
$this->storeManager = $this->createMock(StoreManagerInterface::class);
8385

8486
$this->layoutProcessor = new LayoutProcessor(
8587
$this->attributeDataProvider,
@@ -109,10 +111,12 @@ public function testProcess()
109111

110112
$this->attributeMerger->expects(static::exactly(2))
111113
->method('merge')
112-
->willReturnMap([
113-
['payment1_1' => $this->getBillingComponent('payment1_1')],
114-
['payment2_1' => $this->getBillingComponent('payment2_1')],
115-
]);
114+
->willReturnMap(
115+
[
116+
['payment1_1' => $this->getBillingComponent('payment1_1')],
117+
['payment2_1' => $this->getBillingComponent('payment2_1')],
118+
]
119+
);
116120

117121
$actual = $this->layoutProcessor->process($jsLayout);
118122

@@ -236,9 +240,6 @@ private function getLayoutData()
236240
private function getBillingComponent($paymentCode)
237241
{
238242
return [
239-
'country_id' => [
240-
'sortOrder' => 115,
241-
],
242243
'region' => [
243244
'visible' => false,
244245
],

app/code/Magento/Checkout/view/frontend/layout/checkout_index_index.xml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,6 @@
222222
<item name="min_text_length" xsi:type="number">0</item>
223223
</item>
224224
</item>
225-
<item name="country_id" xsi:type="array">
226-
<item name="sortOrder" xsi:type="string">115</item>
227-
</item>
228225
<item name="telephone" xsi:type="array">
229226
<item name="config" xsi:type="array">
230227
<item name="tooltip" xsi:type="array">
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
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\Customer\Setup\Patch\Data;
9+
10+
use Magento\Customer\Setup\CustomerSetup;
11+
use Magento\Customer\Setup\CustomerSetupFactory;
12+
use Magento\Framework\Setup\ModuleDataSetupInterface;
13+
use Magento\Framework\Setup\Patch\DataPatchInterface;
14+
15+
/**
16+
* Update Customer Address Attributes to be displayed in following order: country, region, city, postcode
17+
*/
18+
class UpdateCustomerAddressAttributesSortOrder implements DataPatchInterface
19+
{
20+
/**
21+
* @var ModuleDataSetupInterface
22+
*/
23+
private $moduleDataSetup;
24+
25+
/**
26+
* @var CustomerSetupFactory
27+
*/
28+
private $customerSetupFactory;
29+
30+
/**
31+
* UpdateCustomerAddressAttributesSortOrder constructor.
32+
* @param ModuleDataSetupInterface $moduleDataSetup
33+
* @param CustomerSetupFactory $customerSetupFactory
34+
*/
35+
public function __construct(
36+
ModuleDataSetupInterface $moduleDataSetup,
37+
CustomerSetupFactory $customerSetupFactory
38+
) {
39+
$this->moduleDataSetup = $moduleDataSetup;
40+
$this->customerSetupFactory = $customerSetupFactory;
41+
}
42+
43+
/**
44+
* @inheritDoc
45+
*/
46+
public function apply()
47+
{
48+
/** @var CustomerSetup $customerSetup */
49+
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
50+
$this->updateCustomerAddressAttributesSortOrder($customerSetup);
51+
52+
return $this;
53+
}
54+
55+
/**
56+
* @inheritDoc
57+
*/
58+
public function getAliases()
59+
{
60+
return [];
61+
}
62+
63+
/**
64+
* @inheritDoc
65+
*/
66+
public static function getDependencies()
67+
{
68+
return [
69+
DefaultCustomerGroupsAndAttributes::class,
70+
];
71+
}
72+
73+
/**
74+
* Update customer address attributes sort order
75+
*
76+
* @param CustomerSetup $customerSetup
77+
*
78+
* @return void
79+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
80+
*/
81+
private function updateCustomerAddressAttributesSortOrder($customerSetup)
82+
{
83+
$entityAttributes = [
84+
'customer_address' => [
85+
'country_id' => [
86+
'sort_order' => 80,
87+
'position' => 80
88+
],
89+
'region' => [
90+
'sort_order' => 90,
91+
'position' => 90
92+
],
93+
'region_id' => [
94+
'sort_order' => 90,
95+
'position' => 90
96+
],
97+
'city' => [
98+
'sort_order' => 100,
99+
'position' => 100
100+
],
101+
],
102+
];
103+
104+
$customerSetup->upgradeAttributes($entityAttributes);
105+
}
106+
}

app/code/Magento/Customer/view/adminhtml/ui_component/customer_address_form.xml

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -174,17 +174,7 @@
174174
<label translate="true">Company</label>
175175
</settings>
176176
</field>
177-
<field name="city" sortOrder="80" formElement="input">
178-
<settings>
179-
<dataType>text</dataType>
180-
<label translate="true">City</label>
181-
<visible>true</visible>
182-
<validation>
183-
<rule name="required-entry" xsi:type="boolean">true</rule>
184-
</validation>
185-
</settings>
186-
</field>
187-
<field name="country_id" component="Magento_Customer/js/form/element/country" sortOrder="90" formElement="select">
177+
<field name="country_id" component="Magento_Customer/js/form/element/country" sortOrder="80" formElement="select">
188178
<settings>
189179
<validation>
190180
<rule name="required-entry" xsi:type="boolean">true</rule>
@@ -212,6 +202,16 @@
212202
</select>
213203
</formElements>
214204
</field>
205+
<field name="city" sortOrder="100" formElement="input">
206+
<settings>
207+
<dataType>text</dataType>
208+
<label translate="true">City</label>
209+
<visible>true</visible>
210+
<validation>
211+
<rule name="required-entry" xsi:type="boolean">true</rule>
212+
</validation>
213+
</settings>
214+
</field>
215215
<field name="postcode" component="Magento_Ui/js/form/element/post-code" sortOrder="120" formElement="input">
216216
<settings>
217217
<dataType>text</dataType>

0 commit comments

Comments
 (0)