Skip to content

Commit 8eb50bf

Browse files
🔃 [Magento Community Engineering] Community Contributions - 2.3-develop
Accepted Community Pull Requests: - magento#24519: Resolve API "V1/attributeMetadata/customerAddress/attribute/prefix" and "V1/attributeMetadata/customerAddress/attribute/suffix" can not get options (by @edenduong) - magento#24499: Resolve "Clear Shopping Cart" button not working in Internet Explorer issue24491 (by @edenduong) Fixed GitHub Issues: - magento#24518: API "V1/attributeMetadata/customerAddress/attribute/prefix" and "V1/attributeMetadata/customerAddress/attribute/suffix" can not get options (reported by @edenduong) has been fixed in magento#24519 by @edenduong in 2.3-develop branch Related commits: 1. 1da4f2a 2. e779423 - magento#21499: Cart is emptied when enter is pressed after changing product quantity (reported by @wojtekn) has been fixed in magento#24499 by @edenduong in 2.3-develop branch Related commits: 1. 7005d99 2. 5847d9f - magento#24491: "Clear Shopping Cart" button not working in Internet Explorer (reported by @andrew-ebsco) has been fixed in magento#24499 by @edenduong in 2.3-develop branch Related commits: 1. 7005d99 2. 5847d9f
2 parents d1fbf76 + 619d02a commit 8eb50bf

File tree

4 files changed

+208
-29
lines changed

4 files changed

+208
-29
lines changed

app/code/Magento/Checkout/view/frontend/templates/cart/form.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
<span><?= $block->escapeHtml(__('Continue Shopping')) ?></span>
5757
</a>
5858
<?php endif; ?>
59-
<button type="submit"
59+
<button type="button"
6060
name="update_cart_action"
6161
data-cart-empty=""
6262
value="empty_cart"

app/code/Magento/Checkout/view/frontend/web/js/shopping-cart.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ define([
1414
_create: function () {
1515
var items, i, reload;
1616

17-
$(this.options.emptyCartButton).on('click', $.proxy(function (event) {
18-
if (event.detail === 0) {
19-
return;
20-
}
21-
17+
$(this.options.emptyCartButton).on('click', $.proxy(function () {
2218
$(this.options.emptyCartButton).attr('name', 'update_cart_action_temp');
2319
$(this.options.updateCartActionContainer)
2420
.attr('name', 'update_cart_action').attr('value', 'empty_cart');
21+
22+
if ($(this.options.emptyCartButton).parents('form').length > 0) {
23+
$(this.options.emptyCartButton).parents('form').submit();
24+
}
2525
}, this));
2626
items = $.find('[data-role="cart-item-qty"]');
2727

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

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

810
use Magento\Customer\Api\Data\OptionInterfaceFactory;
911
use Magento\Customer\Api\Data\ValidationRuleInterfaceFactory;
1012
use Magento\Customer\Api\Data\AttributeMetadataInterfaceFactory;
1113
use Magento\Eav\Api\Data\AttributeDefaultValueInterface;
14+
use Magento\Framework\App\Config\ScopeConfigInterface;
15+
use Magento\Framework\App\ObjectManager;
1216

1317
/**
1418
* Converter for AttributeMetadata
1519
*/
1620
class AttributeMetadataConverter
1721
{
22+
/**
23+
* Attribute Code get options from system config
24+
*
25+
* @var array
26+
*/
27+
private const ATTRIBUTE_CODE_LIST_FROM_SYSTEM_CONFIG = ['prefix', 'suffix'];
28+
29+
/**
30+
* XML Path to get address config
31+
*
32+
* @var string
33+
*/
34+
private const XML_CUSTOMER_ADDRESS = 'customer/address/';
35+
1836
/**
1937
* @var OptionInterfaceFactory
2038
*/
@@ -35,24 +53,32 @@ class AttributeMetadataConverter
3553
*/
3654
protected $dataObjectHelper;
3755

56+
/**
57+
* @var ScopeConfigInterface
58+
*/
59+
private $scopeConfig;
60+
3861
/**
3962
* Initialize the Converter
4063
*
4164
* @param OptionInterfaceFactory $optionFactory
4265
* @param ValidationRuleInterfaceFactory $validationRuleFactory
4366
* @param AttributeMetadataInterfaceFactory $attributeMetadataFactory
4467
* @param \Magento\Framework\Api\DataObjectHelper $dataObjectHelper
68+
* @param ScopeConfigInterface $scopeConfig
4569
*/
4670
public function __construct(
4771
OptionInterfaceFactory $optionFactory,
4872
ValidationRuleInterfaceFactory $validationRuleFactory,
4973
AttributeMetadataInterfaceFactory $attributeMetadataFactory,
50-
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper
74+
\Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
75+
ScopeConfigInterface $scopeConfig = null
5176
) {
5277
$this->optionFactory = $optionFactory;
5378
$this->validationRuleFactory = $validationRuleFactory;
5479
$this->attributeMetadataFactory = $attributeMetadataFactory;
5580
$this->dataObjectHelper = $dataObjectHelper;
81+
$this->scopeConfig = $scopeConfig ?? ObjectManager::getInstance()->get(ScopeConfigInterface::class);
5682
}
5783

5884
/**
@@ -64,28 +90,34 @@ public function __construct(
6490
public function createMetadataAttribute($attribute)
6591
{
6692
$options = [];
67-
if ($attribute->usesSource()) {
68-
foreach ($attribute->getSource()->getAllOptions() as $option) {
69-
$optionDataObject = $this->optionFactory->create();
70-
if (!is_array($option['value'])) {
71-
$optionDataObject->setValue($option['value']);
72-
} else {
73-
$optionArray = [];
74-
foreach ($option['value'] as $optionArrayValues) {
75-
$optionObject = $this->optionFactory->create();
76-
$this->dataObjectHelper->populateWithArray(
77-
$optionObject,
78-
$optionArrayValues,
79-
\Magento\Customer\Api\Data\OptionInterface::class
80-
);
81-
$optionArray[] = $optionObject;
93+
94+
if (in_array($attribute->getAttributeCode(), self::ATTRIBUTE_CODE_LIST_FROM_SYSTEM_CONFIG)) {
95+
$options = $this->getOptionFromConfig($attribute->getAttributeCode());
96+
} else {
97+
if ($attribute->usesSource()) {
98+
foreach ($attribute->getSource()->getAllOptions() as $option) {
99+
$optionDataObject = $this->optionFactory->create();
100+
if (!is_array($option['value'])) {
101+
$optionDataObject->setValue($option['value']);
102+
} else {
103+
$optionArray = [];
104+
foreach ($option['value'] as $optionArrayValues) {
105+
$optionObject = $this->optionFactory->create();
106+
$this->dataObjectHelper->populateWithArray(
107+
$optionObject,
108+
$optionArrayValues,
109+
\Magento\Customer\Api\Data\OptionInterface::class
110+
);
111+
$optionArray[] = $optionObject;
112+
}
113+
$optionDataObject->setOptions($optionArray);
82114
}
83-
$optionDataObject->setOptions($optionArray);
115+
$optionDataObject->setLabel($option['label']);
116+
$options[] = $optionDataObject;
84117
}
85-
$optionDataObject->setLabel($option['label']);
86-
$options[] = $optionDataObject;
87118
}
88119
}
120+
89121
$validationRules = [];
90122
foreach ((array)$attribute->getValidateRules() as $name => $value) {
91123
$validationRule = $this->validationRuleFactory->create()
@@ -122,4 +154,26 @@ public function createMetadataAttribute($attribute)
122154
->setIsFilterableInGrid($attribute->getIsFilterableInGrid())
123155
->setIsSearchableInGrid($attribute->getIsSearchableInGrid());
124156
}
157+
158+
/**
159+
* Get option from System Config instead of Use Source (Prefix, Suffix)
160+
*
161+
* @param string $attributeCode
162+
* @return \Magento\Customer\Api\Data\OptionInterface[]
163+
*/
164+
private function getOptionFromConfig($attributeCode)
165+
{
166+
$result = [];
167+
$value = $this->scopeConfig->getValue(self::XML_CUSTOMER_ADDRESS . $attributeCode . '_options');
168+
if ($value) {
169+
$optionArray = explode(';', $value);
170+
foreach ($optionArray as $value) {
171+
$optionObject = $this->optionFactory->create();
172+
$optionObject->setLabel($value);
173+
$optionObject->setValue($value);
174+
$result[] = $optionObject;
175+
}
176+
}
177+
return $result;
178+
}
125179
}

dev/tests/api-functional/testsuite/Magento/Customer/Api/AddressMetadataTest.php

Lines changed: 129 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@
66

77
namespace Magento\Customer\Api;
88

9+
use Magento\Config\Model\ResourceModel\Config;
910
use Magento\Customer\Api\Data\AddressInterface as Address;
1011
use Magento\Customer\Model\Data\AttributeMetadata;
12+
use Magento\Framework\App\Config\ReinitableConfigInterface;
13+
use Magento\TestFramework\ObjectManager;
1114
use Magento\TestFramework\TestCase\WebapiAbstract;
1215

1316
/**
@@ -19,15 +22,40 @@ class AddressMetadataTest extends WebapiAbstract
1922
const SERVICE_VERSION = "V1";
2023
const RESOURCE_PATH = "/V1/attributeMetadata/customerAddress";
2124

25+
/**
26+
* @var Config $config
27+
*/
28+
private $resourceConfig;
29+
30+
/**
31+
* @var ReinitableConfigInterface
32+
*/
33+
private $reinitConfig;
34+
35+
/**
36+
* @inheritdoc
37+
*/
38+
protected function setUp()
39+
{
40+
parent::setUp();
41+
42+
$objectManager = ObjectManager::getInstance();
43+
$this->resourceConfig = $objectManager->get(Config::class);
44+
$this->reinitConfig = $objectManager->get(ReinitableConfigInterface::class);
45+
}
46+
2247
/**
2348
* Test retrieval of attribute metadata for the address entity type.
2449
*
2550
* @param string $attributeCode The attribute code of the requested metadata.
2651
* @param array $expectedMetadata Expected entity metadata for the attribute code.
2752
* @dataProvider getAttributeMetadataDataProvider
53+
* @magentoDbIsolation disabled
2854
*/
29-
public function testGetAttributeMetadata($attributeCode, $expectedMetadata)
55+
public function testGetAttributeMetadata($attributeCode, $configOptions, $expectedMetadata)
3056
{
57+
$this->initConfig($configOptions);
58+
3159
$serviceInfo = [
3260
'rest' => [
3361
'resourcePath' => self::RESOURCE_PATH . "/attribute/$attributeCode",
@@ -54,12 +82,14 @@ public function testGetAttributeMetadata($attributeCode, $expectedMetadata)
5482
* Data provider for testGetAttributeMetadata.
5583
*
5684
* @return array
85+
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
5786
*/
5887
public function getAttributeMetadataDataProvider()
5988
{
6089
return [
6190
Address::POSTCODE => [
6291
Address::POSTCODE,
92+
[],
6393
[
6494
AttributeMetadata::FRONTEND_INPUT => 'text',
6595
AttributeMetadata::INPUT_FILTER => '',
@@ -83,7 +113,85 @@ public function getAttributeMetadataDataProvider()
83113
AttributeMetadata::IS_SEARCHABLE_IN_GRID => true,
84114
AttributeMetadata::ATTRIBUTE_CODE => 'postcode',
85115
],
86-
]
116+
],
117+
'prefix' => [
118+
'prefix',
119+
[
120+
['path' => 'customer/address/prefix_show', 'value' => 'opt'],
121+
['path' => 'customer/address/prefix_options', 'value' => 'prefA;prefB']
122+
],
123+
[
124+
AttributeMetadata::FRONTEND_INPUT => 'text',
125+
AttributeMetadata::INPUT_FILTER => '',
126+
AttributeMetadata::STORE_LABEL => 'Name Prefix',
127+
AttributeMetadata::MULTILINE_COUNT => 0,
128+
AttributeMetadata::VALIDATION_RULES => [],
129+
AttributeMetadata::VISIBLE => false,
130+
AttributeMetadata::REQUIRED => false,
131+
AttributeMetadata::DATA_MODEL => '',
132+
AttributeMetadata::OPTIONS => [
133+
[
134+
'label' => 'prefA',
135+
'value' => 'prefA',
136+
],
137+
[
138+
'label' => 'prefB',
139+
'value' => 'prefB',
140+
],
141+
],
142+
AttributeMetadata::FRONTEND_CLASS => '',
143+
AttributeMetadata::USER_DEFINED => false,
144+
AttributeMetadata::SORT_ORDER => 10,
145+
AttributeMetadata::FRONTEND_LABEL => 'Name Prefix',
146+
AttributeMetadata::NOTE => '',
147+
AttributeMetadata::SYSTEM => false,
148+
AttributeMetadata::BACKEND_TYPE => 'static',
149+
AttributeMetadata::IS_USED_IN_GRID => false,
150+
AttributeMetadata::IS_VISIBLE_IN_GRID => false,
151+
AttributeMetadata::IS_FILTERABLE_IN_GRID => false,
152+
AttributeMetadata::IS_SEARCHABLE_IN_GRID => false,
153+
AttributeMetadata::ATTRIBUTE_CODE => 'prefix',
154+
],
155+
],
156+
'suffix' => [
157+
'suffix',
158+
[
159+
['path' => 'customer/address/suffix_show', 'value' => 'opt'],
160+
['path' => 'customer/address/suffix_options', 'value' => 'suffA;suffB']
161+
],
162+
[
163+
AttributeMetadata::FRONTEND_INPUT => 'text',
164+
AttributeMetadata::INPUT_FILTER => '',
165+
AttributeMetadata::STORE_LABEL => 'Name Suffix',
166+
AttributeMetadata::MULTILINE_COUNT => 0,
167+
AttributeMetadata::VALIDATION_RULES => [],
168+
AttributeMetadata::VISIBLE => false,
169+
AttributeMetadata::REQUIRED => false,
170+
AttributeMetadata::DATA_MODEL => '',
171+
AttributeMetadata::OPTIONS => [
172+
[
173+
'label' => 'suffA',
174+
'value' => 'suffA',
175+
],
176+
[
177+
'label' => 'suffB',
178+
'value' => 'suffB',
179+
],
180+
],
181+
AttributeMetadata::FRONTEND_CLASS => '',
182+
AttributeMetadata::USER_DEFINED => false,
183+
AttributeMetadata::SORT_ORDER => 50,
184+
AttributeMetadata::FRONTEND_LABEL => 'Name Suffix',
185+
AttributeMetadata::NOTE => '',
186+
AttributeMetadata::SYSTEM => false,
187+
AttributeMetadata::BACKEND_TYPE => 'static',
188+
AttributeMetadata::IS_USED_IN_GRID => false,
189+
AttributeMetadata::IS_VISIBLE_IN_GRID => false,
190+
AttributeMetadata::IS_FILTERABLE_IN_GRID => false,
191+
AttributeMetadata::IS_SEARCHABLE_IN_GRID => false,
192+
AttributeMetadata::ATTRIBUTE_CODE => 'suffix',
193+
],
194+
],
87195
];
88196
}
89197

@@ -106,7 +214,7 @@ public function testGetAllAttributesMetadata()
106214

107215
$attributeMetadata = $this->_webApiCall($serviceInfo);
108216
$this->assertCount(19, $attributeMetadata);
109-
$postcode = $this->getAttributeMetadataDataProvider()[Address::POSTCODE][1];
217+
$postcode = $this->getAttributeMetadataDataProvider()[Address::POSTCODE][2];
110218
$validationResult = $this->checkMultipleAttributesValidationRules($postcode, $attributeMetadata);
111219
list($postcode, $attributeMetadata) = $validationResult;
112220
$this->assertContains($postcode, $attributeMetadata);
@@ -187,7 +295,7 @@ public function getAttributesDataProvider()
187295
return [
188296
[
189297
'customer_address_edit',
190-
$attributeMetadata[Address::POSTCODE][1],
298+
$attributeMetadata[Address::POSTCODE][2],
191299
]
192300
];
193301
}
@@ -200,6 +308,7 @@ public function getAttributesDataProvider()
200308
* @param array $actualResult
201309
* @return array
202310
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
311+
* phpcs:disable Generic.Metrics.NestingLevel
203312
*/
204313
public function checkValidationRules($expectedResult, $actualResult)
205314
{
@@ -235,6 +344,7 @@ public function checkValidationRules($expectedResult, $actualResult)
235344
}
236345
return [$expectedResult, $actualResult];
237346
}
347+
//phpcs:enable
238348

239349
/**
240350
* Check specific attribute validation rules in set of multiple attributes
@@ -277,4 +387,19 @@ public static function tearDownAfterClass()
277387
$attribute->delete();
278388
}
279389
}
390+
391+
/**
392+
* Set core config data.
393+
*
394+
* @param $configOptions
395+
*/
396+
private function initConfig(array $configOptions): void
397+
{
398+
if ($configOptions) {
399+
foreach ($configOptions as $option) {
400+
$this->resourceConfig->saveConfig($option['path'], $option['value']);
401+
}
402+
}
403+
$this->reinitConfig->reinit();
404+
}
280405
}

0 commit comments

Comments
 (0)