diff --git a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html index 9005e4816b43f..083c594996d59 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/billing-address/details.html @@ -1,7 +1,7 @@
@@ -12,7 +12,11 @@

- , + + + , + +


diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html index c5cc997d8cc85..f760fd0eb8e67 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-address/address-renderer/default.html @@ -1,7 +1,7 @@
@@ -11,7 +11,10 @@

- ,
+ + , + +


diff --git a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html index 292edbc13708c..c803d7950f5ee 100644 --- a/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html +++ b/app/code/Magento/Checkout/view/frontend/web/template/shipping-information/address-renderer/default.html @@ -1,7 +1,7 @@ @@ -11,7 +11,10 @@

- ,
+ + , + +


diff --git a/app/code/Magento/Customer/Block/Widget/City.php b/app/code/Magento/Customer/Block/Widget/City.php new file mode 100644 index 0000000000000..e64485cda5faf --- /dev/null +++ b/app/code/Magento/Customer/Block/Widget/City.php @@ -0,0 +1,182 @@ +options = $options; + parent::__construct($context, $addressHelper, $customerMetadata, $data); + $this->addressMetadata = $addressMetadata; + $this->_isScopePrivate = true; + } + + /** + * @inheritdoc + */ + public function _construct() + { + parent::_construct(); + + // default city location + $this->setTemplate('Magento_Customer::widget/city.phtml'); + } + + /** + * Can show prefix + * + * @return bool + */ + public function showCity() + { + return $this->isAttributeVisible(self::ATTRIBUTE_CODE); + } + + /** + * Retrieve customer attribute instance + * + * @param string $attributeCode + * + * @return AttributeMetadataInterface|null + * @throws LocalizedException + */ + //@codingStandardsIgnoreStart + protected function _getAttribute($attributeCode) + { + //@codingStandardsIgnoreEnd + if ($this->getForceUseCustomerAttributes() || $this->getObject() instanceof CustomerInterface) { + return parent::_getAttribute($attributeCode); + } + + try { + $attribute = $this->addressMetadata->getAttributeMetadata($attributeCode); + } catch (NoSuchEntityException $e) { + return null; + } + + if ($this->getForceUseCustomerRequiredAttributes() && $attribute && !$attribute->isRequired()) { + $customerAttribute = parent::_getAttribute($attributeCode); + if ($customerAttribute && $customerAttribute->isRequired()) { + $attribute = $customerAttribute; + } + } + + return $attribute; + } + + /** + * Retrieve store attribute label + * + * @param string $attributeCode + * + * @return string + */ + public function getStoreLabel(string $attributeCode) + { + $attribute = $this->_getAttribute($attributeCode); + return $attribute ? __($attribute->getStoreLabel()) : ''; + } + + /** + * Get string with frontend validation classes for attribute + * + * @param string $attributeCode + * + * @return string + * @throws LocalizedException + */ + public function getAttributeValidationClass(string $attributeCode) + { + return $this->_addressHelper->getAttributeValidationClass($attributeCode); + } + + /** + * Checks is attribute visible + * + * @param string $attributeCode + * + * @return bool + */ + private function isAttributeVisible(string $attributeCode) + { + $attributeMetadata = $this->_getAttribute($attributeCode); + return $attributeMetadata ? (bool)$attributeMetadata->isVisible() : false; + } + + /** + * Check if city attribute enabled in system + * + * @return bool + */ + public function isEnabled() + { + return $this->_getAttribute(self::ATTRIBUTE_CODE) + ? (bool)$this->_getAttribute(self::ATTRIBUTE_CODE)->isVisible() : false; + } + + /** + * Check if city attribute marked as required + * + * @return bool + */ + public function isRequired(): bool + { + return $this->_getAttribute(self::ATTRIBUTE_CODE) + ? (bool)$this->_getAttribute(self::ATTRIBUTE_CODE)->isRequired() : false; + } +} diff --git a/app/code/Magento/Customer/Model/Address/Validator/General.php b/app/code/Magento/Customer/Model/Address/Validator/General.php index 23c6d687328f3..3329fa490383d 100644 --- a/app/code/Magento/Customer/Model/Address/Validator/General.php +++ b/app/code/Magento/Customer/Model/Address/Validator/General.php @@ -1,7 +1,7 @@ 'street']); } - if (!ValidatorChain::is($address->getCity(), NotEmpty::class)) { - $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'city']); - } - return $errors; } @@ -88,6 +84,8 @@ private function checkRequiredFields(AbstractAddress $address) * @param AbstractAddress $address * @return array * @throws LocalizedException|ValidateException + * @SuppressWarnings(PHPMD.CyclomaticComplexity) + * @SuppressWarnings(PHPMD.NPathComplexity) */ private function checkOptionalFields(AbstractAddress $address) { @@ -111,6 +109,12 @@ private function checkOptionalFields(AbstractAddress $address) $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'company']); } + if ($this->isCityRequired() + && !ValidatorChain::is($address->getCity(), NotEmpty::class) + ) { + $errors[] = __('"%fieldName" is required. Enter and try again.', ['fieldName' => 'city']); + } + $havingOptionalZip = $this->directoryData->getCountriesWithOptionalZip(); if (!in_array($address->getCountryId(), $havingOptionalZip) && !ValidatorChain::is($address->getPostcode(), NotEmpty::class) @@ -154,6 +158,17 @@ private function isFaxRequired() return $this->eavConfig->getAttribute('customer_address', 'fax')->getIsRequired(); } + /** + * Check if city field required in configuration. + * + * @return bool + * @throws LocalizedException + */ + private function isCityRequired() + { + return $this->eavConfig->getAttribute('customer_address', 'city')->getIsRequired(); + } + /** * Reload address attributes for the certain store * diff --git a/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerShowCityActionGroup.xml b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerShowCityActionGroup.xml new file mode 100644 index 0000000000000..03d9c9cabcc3a --- /dev/null +++ b/app/code/Magento/Customer/Test/Mftf/ActionGroup/AdminCustomerShowCityActionGroup.xml @@ -0,0 +1,26 @@ + + + + + + + Goes to the customer configuration. Set "Show City" with provided value. + + + + + + + + + + + + + diff --git a/app/code/Magento/Customer/Test/Mftf/Data/AdminCustomerConfigData.xml b/app/code/Magento/Customer/Test/Mftf/Data/AdminCustomerConfigData.xml index 47b37a4a8e264..8a9690a88c86f 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/AdminCustomerConfigData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/AdminCustomerConfigData.xml @@ -18,6 +18,11 @@ Optional Required + + No + Optional + Required + No Optional diff --git a/app/code/Magento/Customer/Test/Mftf/Data/CustomerConfigData.xml b/app/code/Magento/Customer/Test/Mftf/Data/CustomerConfigData.xml index 3eb14604220e9..ba3c8ee0a9757 100644 --- a/app/code/Magento/Customer/Test/Mftf/Data/CustomerConfigData.xml +++ b/app/code/Magento/Customer/Test/Mftf/Data/CustomerConfigData.xml @@ -1,8 +1,8 @@ diff --git a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml index 671bdde86432f..92fe75714d49b 100644 --- a/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml +++ b/app/code/Magento/Customer/Test/Mftf/Section/AdminCustomerConfigSection.xml @@ -1,8 +1,8 @@ @@ -17,6 +17,7 @@ + diff --git a/app/code/Magento/Customer/etc/adminhtml/system.xml b/app/code/Magento/Customer/etc/adminhtml/system.xml index ec76e09fdf459..8ae8641d3d099 100644 --- a/app/code/Magento/Customer/etc/adminhtml/system.xml +++ b/app/code/Magento/Customer/etc/adminhtml/system.xml @@ -1,8 +1,8 @@ @@ -266,6 +266,11 @@ Magento\Config\Model\Config\Source\Nooptreq Magento\Customer\Model\Config\Backend\Show\AddressOnly + + + Magento\Config\Model\Config\Source\Nooptreq + Magento\Customer\Model\Config\Backend\Show\AddressOnly + diff --git a/app/code/Magento/Customer/etc/config.xml b/app/code/Magento/Customer/etc/config.xml index 23a7c9ebb4034..46ac5921e3d10 100644 --- a/app/code/Magento/Customer/etc/config.xml +++ b/app/code/Magento/Customer/etc/config.xml @@ -1,8 +1,8 @@ @@ -59,6 +59,7 @@ req opt + req 0 @@ -71,7 +72,7 @@ {{depend street2}}{{var street2}}{{/depend}} {{depend street3}}{{var street3}}{{/depend}} {{depend street4}}{{var street4}}{{/depend}} -{{if city}}{{var city}}, {{/if}}{{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}} +{{depend city}}{{var city}},{{/depend}} {{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}} {{var country}} {{depend telephone}}T: {{var telephone}}{{/depend}} {{depend fax}}F: {{var fax}}{{/depend}} @@ -83,7 +84,7 @@ {{depend street2}}{{var street2}}
{{/depend}} {{depend street3}}{{var street3}}
{{/depend}} {{depend street4}}{{var street4}}
{{/depend}} -{{if city}}{{var city}}, {{/if}}{{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}}
+{{depend city}}{{var city}},{{/depend}} {{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}}
{{var country}}
{{depend telephone}}T: {{var telephone}}{{/depend}} {{depend fax}}
F: {{var fax}}{{/depend}} @@ -94,7 +95,7 @@ {{depend street2}}{{var street2}}|{{/depend}} {{depend street3}}{{var street3}}|{{/depend}} {{depend street4}}{{var street4}}|{{/depend}} -{{if city}}{{var city}}, {{/if}}{{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}}| +{{depend city}}{{var city}},|{{/depend}} {{if region}}{{var region}}, {{/if}}{{if postcode}}{{var postcode}}{{/if}}| {{var country}}| {{depend telephone}}T: {{var telephone}}|{{/depend}} {{depend fax}}F: {{var fax}}|{{/depend}}| diff --git a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_address_form.xml b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_address_form.xml index 517d8151b5f10..a634425abdf32 100644 --- a/app/code/Magento/Customer/view/adminhtml/ui_component/customer_address_form.xml +++ b/app/code/Magento/Customer/view/adminhtml/ui_component/customer_address_form.xml @@ -1,8 +1,8 @@
@@ -207,9 +207,6 @@ text true - - true - diff --git a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml index a958f831e18a8..d272d14602ec6 100644 --- a/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml +++ b/app/code/Magento/Customer/view/frontend/templates/address/edit.phtml @@ -1,35 +1,45 @@ getViewModel(); $regionProvider = $block->getRegionProvider(); ?> -getLayout()->createBlock(\Magento\Customer\Block\Widget\Company::class) ?> -getLayout()->createBlock(\Magento\Customer\Block\Widget\Telephone::class) ?> -getLayout()->createBlock(\Magento\Customer\Block\Widget\Fax::class) ?> -getAttributeData()->getFrontendLabel('country_id'); ?> -getAttributeData()->getFrontendLabel('street'); ?> -getAttributeData()->getFrontendLabel('city'); ?> -getAttributeData()->getFrontendLabel('region'); ?> - -getConfig('general/region/display_all'); ?> +getLayout()->createBlock(Company::class) ?> +getLayout()->createBlock(Telephone::class) ?> +getLayout()->createBlock(Fax::class) ?> +getAttributeData()->getFrontendLabel('country_id'); ?> +getAttributeData()->getFrontendLabel('street'); ?> +getLayout()->createBlock(City::class); ?> +getAttributeData()->getFrontendLabel('region'); ?> + +getConfig('general/region/display_all'); ?> -addressGetAttributeValidationClass('vat_id'); ?> -addressGetAttributeValidationClass('city'); ?> -addressGetAttributeValidationClass('postcode'); ?> - -addressGetAttributeValidationClass('street'); ?> - -addressGetAttributeValidationClass('region'); ?> +addressGetAttributeValidationClass('vat_id'); ?> +addressGetAttributeValidationClass('city'); ?> +addressGetAttributeValidationClass('postcode'); ?> + +addressGetAttributeValidationClass('street'); ?> + +addressGetAttributeValidationClass('region'); ?> getRegionProvider(); getNameBlockHtml() ?> - isEnabled()): ?> - setCompany($block->getAddress()->getCompany())->toHtml() ?> + isEnabled()): ?> + setCompany($block->getAddress()->getCompany())->toHtml() ?> - isEnabled()): ?> - setTelephone($block->getAddress()->getTelephone())->toHtml() ?> + isEnabled()): ?> + setTelephone($block->getAddress()->getTelephone())->toHtml() ?> - isEnabled()): ?> - setFax($block->getAddress()->getFax())->toHtml() ?> + isEnabled()): ?> + setFax($block->getAddress()->getFax())->toHtml() ?>
escapeHtml(__('Address')) ?>
- +
@@ -119,38 +129,30 @@ $regionProvider = $block->getRegionProvider();
/> -
-
-
- -
- + escapeHtmlAttr($regionValidationClass) ?>" + />
+ + isEnabled()): ?> + setCity($block->getAddress()->getCity())->toHtml() ?> + +
-
- -
- -
-
+ getLayout()->createBlock(City::class) ?> + isEnabled()): ?> + setCity($formData->getCity())->toHtml() ?> +