diff --git a/app/code/Magento/Customer/Helper/Address.php b/app/code/Magento/Customer/Helper/Address.php index c74c62dc6d98c..8dac704aaa085 100644 --- a/app/code/Magento/Customer/Helper/Address.php +++ b/app/code/Magento/Customer/Helper/Address.php @@ -8,7 +8,9 @@ use Magento\Customer\Api\AddressMetadataInterface; use Magento\Customer\Api\CustomerMetadataInterface; use Magento\Customer\Api\Data\AttributeMetadataInterface; +use Magento\Customer\Model\Metadata\AttributeResolver; use Magento\Directory\Model\Country\Format; +use Magento\Framework\App\ObjectManager; use Magento\Framework\Exception\NoSuchEntityException; /** @@ -93,6 +95,11 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper */ protected $_addressConfig; + /** + * @var AttributeResolver + */ + private $attributeResolver; + /** * @param \Magento\Framework\App\Helper\Context $context * @param \Magento\Framework\View\Element\BlockFactory $blockFactory @@ -100,6 +107,7 @@ class Address extends \Magento\Framework\App\Helper\AbstractHelper * @param CustomerMetadataInterface $customerMetadataService * @param AddressMetadataInterface $addressMetadataService * @param \Magento\Customer\Model\Address\Config $addressConfig + * @param AttributeResolver|null $attributeResolver */ public function __construct( \Magento\Framework\App\Helper\Context $context, @@ -107,13 +115,15 @@ public function __construct( \Magento\Store\Model\StoreManagerInterface $storeManager, CustomerMetadataInterface $customerMetadataService, AddressMetadataInterface $addressMetadataService, - \Magento\Customer\Model\Address\Config $addressConfig + \Magento\Customer\Model\Address\Config $addressConfig, + AttributeResolver $attributeResolver = null ) { $this->_blockFactory = $blockFactory; $this->_storeManager = $storeManager; $this->_customerMetadataService = $customerMetadataService; $this->_addressMetadataService = $addressMetadataService; $this->_addressConfig = $addressConfig; + $this->attributeResolver = $attributeResolver ?: ObjectManager::getInstance()->get(AttributeResolver::class); parent::__construct($context); } @@ -391,4 +401,31 @@ public function isAttributeVisible($code) } return false; } + + /** + * Checks whether it is allowed to show an attribute on the form + * + * This check relies on the attribute's property 'getUsedInForms' which contains a list of forms + * where allowed to render specified attribute. + * + * @param string $attributeCode + * @param string $formName + * @return bool + */ + public function isAttributeAllowedOnForm($attributeCode, $formName) + { + $isAllowed = false; + $attributeMetadata = $this->_addressMetadataService->getAttributeMetadata($attributeCode); + if ($attributeMetadata) { + /** @var \Magento\Customer\Model\Attribute $attribute */ + $attribute = $this->attributeResolver->getModelByAttribute( + \Magento\Customer\Api\AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, + $attributeMetadata + ); + $usedInForms = $attribute->getUsedInForms(); + $isAllowed = in_array($formName, $usedInForms, true); + } + + return $isAllowed; + } } diff --git a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php index e41831a1ced60..7b42e8b7774c8 100644 --- a/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php +++ b/app/code/Magento/Customer/Test/Unit/Helper/AddressTest.php @@ -7,6 +7,7 @@ namespace Magento\Customer\Test\Unit\Helper; use Magento\Customer\Api\AddressMetadataInterface; +use Magento\Customer\Api\AddressMetadataManagementInterface; use Magento\Customer\Api\CustomerMetadataInterface; /** @@ -35,6 +36,9 @@ class AddressTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Customer\Model\Address\Config|\PHPUnit_Framework_MockObject_MockObject */ protected $addressConfig; + /** @var \Magento\Customer\Model\Metadata\AttributeResolver|\PHPUnit_Framework_MockObject_MockObject */ + protected $attributeResolver; + /** @var \PHPUnit_Framework_MockObject_MockObject|AddressMetadataInterface */ private $addressMetadataService; @@ -51,6 +55,7 @@ protected function setUp() $this->customerMetadataService = $arguments['customerMetadataService']; $this->addressConfig = $arguments['addressConfig']; $this->addressMetadataService = $arguments['addressMetadataService']; + $this->attributeResolver = $arguments['attributeResolver']; $this->helper = $objectManagerHelper->getObject($className, $arguments); } @@ -322,9 +327,11 @@ public function testGetFormatTypeRenderer($code, $result) $this->addressConfig->expects($this->once()) ->method('getFormatByCode') ->with($code) - ->will($this->returnValue( - new \Magento\Framework\DataObject($result !== null ? ['renderer' => $result] : []) - )); + ->will( + $this->returnValue( + new \Magento\Framework\DataObject($result !== null ? ['renderer' => $result] : []) + ) + ); $this->assertEquals($result, $this->helper->getFormatTypeRenderer($code)); } @@ -334,7 +341,7 @@ public function getFormatTypeRendererDataProvider() ->disableOriginalConstructor()->getMock(); return [ ['valid_code', $renderer], - ['invalid_code', null] + ['invalid_code', null], ]; } @@ -355,9 +362,11 @@ public function testGetFormat($code, $result) $this->addressConfig->expects($this->once()) ->method('getFormatByCode') ->with($code) - ->will($this->returnValue( - new \Magento\Framework\DataObject(!empty($result) ? ['renderer' => $renderer] : []) - )); + ->will( + $this->returnValue( + new \Magento\Framework\DataObject(!empty($result) ? ['renderer' => $renderer] : []) + ) + ); $this->assertEquals($result, $this->helper->getFormat($code)); } @@ -366,7 +375,7 @@ public function getFormatDataProvider() { return [ ['valid_code', ['key' => 'value']], - ['invalid_code', ''] + ['invalid_code', ''], ]; } @@ -396,7 +405,71 @@ public function isAttributeVisibleDataProvider() { return [ ['fax', true], - ['invalid_code', false] + ['invalid_code', false], + ]; + } + + /** + * @dataProvider attributeOnFormDataProvider + * @param bool $isAllowed + * @param bool $isMetadataExists + * @param string $attributeCode + * @param string $formName + * @param array $attributeFormsList + */ + public function testIsAttributeAllowedOnForm( + $isAllowed, + $isMetadataExists, + $attributeCode, + $formName, + array $attributeFormsList + ) { + $attributeMetadata = null; + if ($isMetadataExists) { + $attributeMetadata = $this->getMockBuilder(\Magento\Customer\Api\Data\AttributeMetadataInterface::class) + ->getMockForAbstractClass(); + $attribute = $this->getMockBuilder(\Magento\Customer\Model\Attribute::class) + ->disableOriginalConstructor() + ->getMock(); + $this->attributeResolver->expects($this->once()) + ->method('getModelByAttribute') + ->with(AddressMetadataManagementInterface::ENTITY_TYPE_ADDRESS, $attributeMetadata) + ->willReturn($attribute); + $attribute->expects($this->once()) + ->method('getUsedInForms') + ->willReturn($attributeFormsList); + } + $this->addressMetadataService->expects($this->once()) + ->method('getAttributeMetadata') + ->with($attributeCode) + ->willReturn($attributeMetadata); + $this->assertEquals($isAllowed, $this->helper->isAttributeAllowedOnForm($attributeCode, $formName)); + } + + public function attributeOnFormDataProvider() + { + return [ + 'metadata not exists' => [ + 'isAllowed' => false, + 'isMetadataExists' => false, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => [], + ], + 'form not in the list' => [ + 'isAllowed' => false, + 'isMetadataExists' => true, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => ['form_1', 'form_2'], + ], + 'allowed' => [ + 'isAllowed' => true, + 'isMetadataExists' => true, + 'attributeCode' => 'attribute_code', + 'formName' => 'form_name', + 'attributeFormsList' => ['form_name', 'form_1', 'form_2'], + ], ]; } } diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php index 4f331baa20cd8..a9887b24bf3d8 100644 --- a/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php +++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Block/Address/Edit.php @@ -30,6 +30,13 @@ class Edit extends Form */ protected $vatFieldId = 'vat_id'; + /** + * Locator for address simple (input, textarea, not multiple fields) attribute + * + * @var string + */ + private $addressSimpleAttribute = "[name='%s']"; + /** * Edit customer address * @@ -77,4 +84,15 @@ protected function dataMapping(array $fields = null, $parent = null) } return parent::dataMapping($fields, $parent); } + + /** + * Check if Customer Address Simple(input, textarea, not multiple fields) Attribute visible + * + * @param string $attributeCode + * @return bool + */ + public function isAddressSimpleAttributeVisible($attributeCode) + { + return $this->_rootElement->find(sprintf($this->addressSimpleAttribute, $attributeCode))->isVisible(); + } } diff --git a/lib/internal/Magento/Framework/Data/Form/Element/Multiselect.php b/lib/internal/Magento/Framework/Data/Form/Element/Multiselect.php index be043bab8bbf9..6e9b598cc8f4d 100644 --- a/lib/internal/Magento/Framework/Data/Form/Element/Multiselect.php +++ b/lib/internal/Magento/Framework/Data/Form/Element/Multiselect.php @@ -59,6 +59,10 @@ public function getElementHtml() if ($this->getCanBeEmpty()) { $html .= ''; } + if (!empty($this->_data['disabled'])) { + $html .= ''; + } + $html .= '_model->setDisabled(true); + $this->_model->setName($fieldName); + $elementHtml = $this->_model->getElementHtml(); + $this->assertContains('_model->setDisabled(false); + $this->_model->setName($fieldName); $elementHtml = $this->_model->getElementHtml(); - $this->assertContains('assertNotContains('