Skip to content

Fix #20332 - address fields sort order fixes #24784

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 44 additions & 37 deletions app/code/Magento/Checkout/Block/Checkout/LayoutProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,30 @@
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Checkout\Block\Checkout;

use Magento\Checkout\Helper\Data;
use Magento\Framework\App\ObjectManager;
use Magento\Customer\Model\AttributeMetadataDataProvider;
use Magento\Customer\Model\Options;
use Magento\Eav\Api\Data\AttributeInterface;
use Magento\Shipping\Model\Config;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Ui\Component\Form\AttributeMapper;

/**
* Class LayoutProcessor
* Checkout Layout Processor
*/
class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcessorInterface
class LayoutProcessor implements LayoutProcessorInterface
{
/**
* @var \Magento\Customer\Model\AttributeMetadataDataProvider
* @var AttributeMetadataDataProvider
*/
private $attributeMetadataDataProvider;

/**
* @var \Magento\Ui\Component\Form\AttributeMapper
* @var AttributeMapper
*/
protected $attributeMapper;

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

/**
* @var \Magento\Customer\Model\Options
* @var Options
*/
private $options;

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

/**
* @var \Magento\Shipping\Model\Config
* @var Config
*/
private $shippingConfig;

/**
* @param \Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider
* @param \Magento\Ui\Component\Form\AttributeMapper $attributeMapper
* @param AttributeMetadataDataProvider $attributeMetadataDataProvider
* @param AttributeMapper $attributeMapper
* @param AttributeMerger $merger
* @param \Magento\Customer\Model\Options|null $options
* @param Data|null $checkoutDataHelper
* @param \Magento\Shipping\Model\Config|null $shippingConfig
* @param StoreManagerInterface|null $storeManager
* @param Options $options
* @param Data $checkoutDataHelper
* @param Config $shippingConfig
* @param StoreManagerInterface $storeManager
*/
public function __construct(
\Magento\Customer\Model\AttributeMetadataDataProvider $attributeMetadataDataProvider,
\Magento\Ui\Component\Form\AttributeMapper $attributeMapper,
AttributeMetadataDataProvider $attributeMetadataDataProvider,
AttributeMapper $attributeMapper,
AttributeMerger $merger,
\Magento\Customer\Model\Options $options = null,
Data $checkoutDataHelper = null,
\Magento\Shipping\Model\Config $shippingConfig = null,
StoreManagerInterface $storeManager = null
Options $options,
Data $checkoutDataHelper,
Config $shippingConfig,
StoreManagerInterface $storeManager
) {
$this->attributeMetadataDataProvider = $attributeMetadataDataProvider;
$this->attributeMapper = $attributeMapper;
$this->merger = $merger;
$this->options = $options ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Customer\Model\Options::class);
$this->checkoutDataHelper = $checkoutDataHelper ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(Data::class);
$this->shippingConfig = $shippingConfig ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(\Magento\Shipping\Model\Config::class);
$this->storeManager = $storeManager ?: \Magento\Framework\App\ObjectManager::getInstance()
->get(StoreManagerInterface::class);
$this->options = $options;
$this->checkoutDataHelper = $checkoutDataHelper;
$this->shippingConfig = $shippingConfig;
$this->storeManager = $storeManager;
}

/**
Expand All @@ -87,7 +89,7 @@ public function __construct(
*/
private function getAddressAttributes()
{
/** @var \Magento\Eav\Api\Data\AttributeInterface[] $attributes */
/** @var AttributeInterface[] $attributes */
$attributes = $this->attributeMetadataDataProvider->loadAttributesCollection(
'customer_address',
'customer_register_address'
Expand Down Expand Up @@ -157,17 +159,22 @@ public function process($jsLayout)
$elements = $this->getAddressAttributes();
$elements = $this->convertElementsToSelect($elements, $attributesToConvert);
// The following code is a workaround for custom address attributes
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children'])) {
if (isset(
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']['payment']
['children']
)) {
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children'] = $this->processPaymentChildrenComponents(
$jsLayout['components']['checkout']['children']['steps']['children']['billing-step']['children']
['payment']['children'],
$elements
);
}
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['step-config']['children']['shipping-rates-validation']['children'])) {

if (isset(
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['step-config']['children']['shipping-rates-validation']['children']
)) {
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['step-config']['children']['shipping-rates-validation']['children'] =
$this->processShippingChildrenComponents(
Expand All @@ -176,8 +183,10 @@ public function process($jsLayout)
);
}

if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['shipping-address-fieldset']['children'])) {
if (isset(
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children']['shipping-address-fieldset']['children']
)) {
$fields = $jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['shipping-address-fieldset']['children'];
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
Expand All @@ -188,6 +197,7 @@ public function process($jsLayout)
$fields
);
}

return $jsLayout;
}

Expand Down Expand Up @@ -304,9 +314,6 @@ private function getBillingAddressComponent($paymentCode, $elements)
'checkoutProvider',
'billingAddress' . $paymentCode,
[
'country_id' => [
'sortOrder' => 115,
],
'region' => [
'visible' => false,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,16 @@
use Magento\Checkout\Helper\Data;
use Magento\Customer\Model\AttributeMetadataDataProvider;
use Magento\Customer\Model\Options;

use Magento\Shipping\Model\Config;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Ui\Component\Form\AttributeMapper;
use PHPUnit_Framework_MockObject_MockObject as MockObject;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

/**
* LayoutProcessorTest covers a list of variations for checkout layout processor
*/
class LayoutProcessorTest extends \PHPUnit\Framework\TestCase
class LayoutProcessorTest extends TestCase
{
/**
* @var AttributeMetadataDataProvider|MockObject
Expand Down Expand Up @@ -45,7 +47,7 @@ class LayoutProcessorTest extends \PHPUnit\Framework\TestCase
private $layoutProcessor;

/**
* @var MockObject
* @var StoreManagerInterface|MockObject
*/
private $storeManager;

Expand Down Expand Up @@ -75,11 +77,11 @@ protected function setUp()
->disableOriginalConstructor()
->getMock();

$shippingConfig = $this->getMockBuilder(\Magento\Shipping\Model\Config::class)
$shippingConfig = $this->getMockBuilder(Config::class)
->disableOriginalConstructor()
->getMock();

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

$this->layoutProcessor = new LayoutProcessor(
$this->attributeDataProvider,
Expand Down Expand Up @@ -109,10 +111,12 @@ public function testProcess()

$this->attributeMerger->expects(static::exactly(2))
->method('merge')
->willReturnMap([
['payment1_1' => $this->getBillingComponent('payment1_1')],
['payment2_1' => $this->getBillingComponent('payment2_1')],
]);
->willReturnMap(
[
['payment1_1' => $this->getBillingComponent('payment1_1')],
['payment2_1' => $this->getBillingComponent('payment2_1')],
]
);

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

Expand Down Expand Up @@ -236,9 +240,6 @@ private function getLayoutData()
private function getBillingComponent($paymentCode)
{
return [
'country_id' => [
'sortOrder' => 115,
],
'region' => [
'visible' => false,
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,6 @@
<item name="min_text_length" xsi:type="number">0</item>
</item>
</item>
<item name="country_id" xsi:type="array">
<item name="sortOrder" xsi:type="string">115</item>
</item>
<item name="telephone" xsi:type="array">
<item name="config" xsi:type="array">
<item name="tooltip" xsi:type="array">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Customer\Setup\Patch\Data;

use Magento\Customer\Setup\CustomerSetup;
use Magento\Customer\Setup\CustomerSetupFactory;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;

/**
* Update Customer Address Attributes to be displayed in following order: country, region, city, postcode
*/
class UpdateCustomerAddressAttributesSortOrder implements DataPatchInterface
{
/**
* @var ModuleDataSetupInterface
*/
private $moduleDataSetup;

/**
* @var CustomerSetupFactory
*/
private $customerSetupFactory;

/**
* UpdateCustomerAddressAttributesSortOrder constructor.
* @param ModuleDataSetupInterface $moduleDataSetup
* @param CustomerSetupFactory $customerSetupFactory
*/
public function __construct(
ModuleDataSetupInterface $moduleDataSetup,
CustomerSetupFactory $customerSetupFactory
) {
$this->moduleDataSetup = $moduleDataSetup;
$this->customerSetupFactory = $customerSetupFactory;
}

/**
* @inheritDoc
*/
public function apply()
{
/** @var CustomerSetup $customerSetup */
$customerSetup = $this->customerSetupFactory->create(['setup' => $this->moduleDataSetup]);
$this->updateCustomerAddressAttributesSortOrder($customerSetup);

return $this;
}

/**
* @inheritDoc
*/
public function getAliases()
{
return [];
}

/**
* @inheritDoc
*/
public static function getDependencies()
{
return [
DefaultCustomerGroupsAndAttributes::class,
];
}

/**
* Update customer address attributes sort order
*
* @param CustomerSetup $customerSetup
*
* @return void
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
*/
private function updateCustomerAddressAttributesSortOrder($customerSetup)
{
$entityAttributes = [
'customer_address' => [
'country_id' => [
'sort_order' => 80,
'position' => 80
],
'region' => [
'sort_order' => 90,
'position' => 90
],
'region_id' => [
'sort_order' => 90,
'position' => 90
],
'city' => [
'sort_order' => 100,
'position' => 100
],
],
];

$customerSetup->upgradeAttributes($entityAttributes);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,7 @@
<label translate="true">Company</label>
</settings>
</field>
<field name="city" sortOrder="80" formElement="input">
<settings>
<dataType>text</dataType>
<label translate="true">City</label>
<visible>true</visible>
<validation>
<rule name="required-entry" xsi:type="boolean">true</rule>
</validation>
</settings>
</field>
<field name="country_id" component="Magento_Customer/js/form/element/country" sortOrder="90" formElement="select">
<field name="country_id" component="Magento_Customer/js/form/element/country" sortOrder="80" formElement="select">
<settings>
<validation>
<rule name="required-entry" xsi:type="boolean">true</rule>
Expand Down Expand Up @@ -212,6 +202,16 @@
</select>
</formElements>
</field>
<field name="city" sortOrder="100" formElement="input">
<settings>
<dataType>text</dataType>
<label translate="true">City</label>
<visible>true</visible>
<validation>
<rule name="required-entry" xsi:type="boolean">true</rule>
</validation>
</settings>
</field>
<field name="postcode" component="Magento_Ui/js/form/element/post-code" sortOrder="120" formElement="input">
<settings>
<dataType>text</dataType>
Expand Down
Loading