Skip to content

Commit aaf99a9

Browse files
author
Alexander Akimov
authored
Merge pull request #2581 from magento-chaika/bugfixes
[Chaika] Bugfixes
2 parents 7509a5f + 86685fb commit aaf99a9

File tree

4 files changed

+118
-48
lines changed

4 files changed

+118
-48
lines changed

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper.php

Lines changed: 21 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,18 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Catalog\Controller\Adminhtml\Product\Initialization;
78

89
use Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory as CustomOptionFactory;
910
use Magento\Catalog\Api\Data\ProductLinkInterfaceFactory as ProductLinkFactory;
11+
use Magento\Catalog\Api\ProductRepositoryInterface;
1012
use Magento\Catalog\Api\ProductRepositoryInterface\Proxy as ProductRepository;
13+
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeDefaultValueFilter;
1114
use Magento\Catalog\Model\Product;
1215
use Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks;
1316
use Magento\Catalog\Model\Product\Link\Resolver as LinkResolver;
17+
use Magento\Catalog\Model\Product\LinkTypeProvider;
1418
use Magento\Framework\App\ObjectManager;
1519
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeFilter;
1620

@@ -81,7 +85,7 @@ class Helper
8185
private $dateTimeFilter;
8286

8387
/**
84-
* @var \Magento\Catalog\Model\Product\LinkTypeProvider
88+
* @var LinkTypeProvider
8589
*/
8690
private $linkTypeProvider;
8791

@@ -99,10 +103,10 @@ class Helper
99103
* @param ProductLinks $productLinks
100104
* @param \Magento\Backend\Helper\Js $jsHelper
101105
* @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
102-
* @param \Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory|null $customOptionFactory
103-
* @param \Magento\Catalog\Api\Data\ProductLinkInterfaceFactory|null $productLinkFactory
104-
* @param \Magento\Catalog\Api\ProductRepositoryInterface|null $productRepository
105-
* @param \Magento\Catalog\Model\Product\LinkTypeProvider|null $linkTypeProvider
106+
* @param CustomOptionFactory|null $customOptionFactory
107+
* @param ProductLinkFactory |null $productLinkFactory
108+
* @param ProductRepositoryInterface|null $productRepository
109+
* @param LinkTypeProvider|null $linkTypeProvider
106110
* @param AttributeFilter|null $attributeFilter
107111
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
108112
*/
@@ -113,10 +117,10 @@ public function __construct(
113117
\Magento\Catalog\Model\Product\Initialization\Helper\ProductLinks $productLinks,
114118
\Magento\Backend\Helper\Js $jsHelper,
115119
\Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
116-
\Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory $customOptionFactory = null,
117-
\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory $productLinkFactory = null,
118-
\Magento\Catalog\Api\ProductRepositoryInterface $productRepository = null,
119-
\Magento\Catalog\Model\Product\LinkTypeProvider $linkTypeProvider = null,
120+
CustomOptionFactory $customOptionFactory = null,
121+
ProductLinkFactory $productLinkFactory = null,
122+
ProductRepositoryInterface $productRepository = null,
123+
LinkTypeProvider $linkTypeProvider = null,
120124
AttributeFilter $attributeFilter = null
121125
) {
122126
$this->request = $request;
@@ -125,16 +129,13 @@ public function __construct(
125129
$this->productLinks = $productLinks;
126130
$this->jsHelper = $jsHelper;
127131
$this->dateFilter = $dateFilter;
128-
$this->customOptionFactory = $customOptionFactory ?: \Magento\Framework\App\ObjectManager::getInstance()
129-
->get(\Magento\Catalog\Api\Data\ProductCustomOptionInterfaceFactory::class);
130-
$this->productLinkFactory = $productLinkFactory ?: \Magento\Framework\App\ObjectManager::getInstance()
131-
->get(\Magento\Catalog\Api\Data\ProductLinkInterfaceFactory::class);
132-
$this->productRepository = $productRepository ?: \Magento\Framework\App\ObjectManager::getInstance()
133-
->get(\Magento\Catalog\Api\ProductRepositoryInterface::class);
134-
$this->linkTypeProvider = $linkTypeProvider ?: \Magento\Framework\App\ObjectManager::getInstance()
135-
->get(\Magento\Catalog\Model\Product\LinkTypeProvider::class);
136-
$this->attributeFilter = $attributeFilter ?: \Magento\Framework\App\ObjectManager::getInstance()
137-
->get(AttributeFilter::class);
132+
133+
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
134+
$this->customOptionFactory = $customOptionFactory ?: $objectManager->get(CustomOptionFactory::class);
135+
$this->productLinkFactory = $productLinkFactory ?: $objectManager->get(ProductLinkFactory::class);
136+
$this->productRepository = $productRepository ?: $objectManager->get(ProductRepositoryInterface::class);
137+
$this->linkTypeProvider = $linkTypeProvider ?: $objectManager->get(LinkTypeProvider::class);
138+
$this->attributeFilter = $attributeFilter ?: $objectManager->get(AttributeFilter::class);
138139
}
139140

140141
/**
@@ -150,8 +151,7 @@ public function __construct(
150151
*/
151152
public function initializeFromData(\Magento\Catalog\Model\Product $product, array $productData)
152153
{
153-
unset($productData['custom_attributes']);
154-
unset($productData['extension_attributes']);
154+
unset($productData['custom_attributes'], $productData['extension_attributes']);
155155

156156
if ($productData) {
157157
$stockData = isset($productData['stock_data']) ? $productData['stock_data'] : [];
@@ -199,28 +199,13 @@ public function initializeFromData(\Magento\Catalog\Model\Product $product, arra
199199
$productData['tier_price'] = isset($productData['tier_price']) ? $productData['tier_price'] : [];
200200

201201
$useDefaults = (array)$this->request->getPost('use_default', []);
202-
203202
$productData = $this->attributeFilter->prepareProductAttributes($product, $productData, $useDefaults);
204-
205203
$product->addData($productData);
206204

207205
if ($wasLockedMedia) {
208206
$product->lockAttribute('media');
209207
}
210208

211-
/**
212-
* Check "Use Default Value" checkboxes values
213-
*/
214-
foreach ($useDefaults as $attributeCode => $useDefaultState) {
215-
if ($useDefaultState) {
216-
$product->setData($attributeCode, null);
217-
// UI component sends value even if field is disabled, so 'Use Config Settings' must be reset to false
218-
if ($product->hasData('use_config_' . $attributeCode)) {
219-
$product->setData('use_config_' . $attributeCode, false);
220-
}
221-
}
222-
}
223-
224209
$product = $this->setProductLinks($product);
225210
$product = $this->fillProductOptions($product, $productOptions);
226211

app/code/Magento/Catalog/Controller/Adminhtml/Product/Initialization/Helper/AttributeFilter.php

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,57 @@ class AttributeFilter
2525
* @param array $useDefaults
2626
* @return array
2727
*/
28-
public function prepareProductAttributes(Product $product, array $productData, array $useDefaults)
28+
public function prepareProductAttributes(Product $product, array $productData, array $useDefaults): array
2929
{
30-
foreach ($productData as $attribute => $value) {
31-
if ($this->isAttributeShouldNotBeUpdated($product, $useDefaults, $attribute, $value)) {
32-
unset($productData[$attribute]);
30+
$attributeList = $product->getAttributes();
31+
foreach ($productData as $attributeCode => $attributeValue) {
32+
if ($this->isAttributeShouldNotBeUpdated($product, $useDefaults, $attributeCode, $attributeValue)) {
33+
unset($productData[$attributeCode]);
34+
}
35+
36+
if (isset($useDefaults[$attributeCode]) && $useDefaults[$attributeCode] === '1') {
37+
$productData = $this->prepareDefaultData($attributeList, $attributeCode, $productData);
38+
$productData = $this->prepareConfigData($product, $attributeCode, $productData);
39+
}
40+
}
41+
42+
return $productData;
43+
}
44+
45+
/**
46+
* @param Product $product
47+
* @param string $attributeCode
48+
* @param array $productData
49+
* @return array
50+
*/
51+
private function prepareConfigData(Product $product, $attributeCode, array $productData): array
52+
{
53+
// UI component sends value even if field is disabled, so 'Use Config Settings' must be reset to false
54+
if ($product->hasData('use_config_' . $attributeCode)) {
55+
$productData['use_config_' . $attributeCode] = false;
56+
}
57+
58+
return $productData;
59+
}
60+
61+
/**
62+
* @param array $attributeList
63+
* @param string $attributeCode
64+
* @param array $productData
65+
* @return array
66+
*/
67+
private function prepareDefaultData(array $attributeList, $attributeCode, array $productData): array
68+
{
69+
if (isset($attributeList[$attributeCode])) {
70+
/** @var \Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute */
71+
$attribute = $attributeList[$attributeCode];
72+
$attributeType = $attribute->getBackendType();
73+
// For non-numberic types set the attributeValue to 'false' to trigger their removal from the db
74+
if ($attributeType === 'varchar' || $attributeType === 'text' || $attributeType === 'datetime') {
75+
$attribute->setIsRequired(false);
76+
$productData[$attributeCode] = false;
77+
} else {
78+
$productData[$attributeCode] = null;
3379
}
3480
}
3581

@@ -43,9 +89,9 @@ public function prepareProductAttributes(Product $product, array $productData, a
4389
* @param $value
4490
* @return bool
4591
*/
46-
private function isAttributeShouldNotBeUpdated(Product $product, $useDefaults, $attribute, $value)
92+
private function isAttributeShouldNotBeUpdated(Product $product, $useDefaults, $attribute, $value): bool
4793
{
48-
$considerUseDefaultsAttribute = !isset($useDefaults[$attribute]) || $useDefaults[$attribute] === "1";
94+
$considerUseDefaultsAttribute = !isset($useDefaults[$attribute]) || $useDefaults[$attribute] === '1';
4995

5096
return ($value === '' && $considerUseDefaultsAttribute && !$product->getData($attribute));
5197
}

app/code/Magento/Catalog/Test/Unit/Controller/Adminhtml/Product/Initialization/Helper/AttributeFilterTest.php

Lines changed: 44 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Catalog\Test\Unit\Controller\Adminhtml\Product\Initialization\Helper;
78

89
use Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper\AttributeFilter;
910
use Magento\Catalog\Model\Product;
11+
use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
12+
use PHPUnit_Framework_MockObject_MockObject;
1013

1114
class AttributeFilterTest extends \PHPUnit\Framework\TestCase
1215
{
@@ -16,12 +19,12 @@ class AttributeFilterTest extends \PHPUnit\Framework\TestCase
1619
protected $model;
1720

1821
/**
19-
* @var \PHPUnit_Framework_MockObject_MockObject
22+
* @var PHPUnit_Framework_MockObject_MockObject
2023
*/
2124
protected $objectManagerMock;
2225

2326
/**
24-
* @var Product|\PHPUnit_Framework_MockObject_MockObject
27+
* @var Product|PHPUnit_Framework_MockObject_MockObject
2528
*/
2629
protected $productMock;
2730

@@ -44,15 +47,25 @@ public function testPrepareProductAttributes(
4447
$expectedProductData,
4548
$initialProductData
4649
) {
50+
/** @var PHPUnit_Framework_MockObject_MockObject | Product $productMockMap */
4751
$productMockMap = $this->getMockBuilder(Product::class)
4852
->disableOriginalConstructor()
49-
->setMethods(['getData'])
53+
->setMethods(['getData', 'getAttributes'])
5054
->getMock();
5155

5256
if (!empty($initialProductData)) {
5357
$productMockMap->expects($this->any())->method('getData')->willReturnMap($initialProductData);
5458
}
5559

60+
if ($useDefaults) {
61+
$productMockMap
62+
->expects($this->once())
63+
->method('getAttributes')
64+
->willReturn(
65+
$this->getProductAttributesMock($useDefaults)
66+
);
67+
}
68+
5669
$actualProductData = $this->model->prepareProductAttributes($productMockMap, $requestProductData, $useDefaults);
5770
$this->assertEquals($expectedProductData, $actualProductData);
5871
}
@@ -169,7 +182,7 @@ public function setupInputDataProvider()
169182
'description' => 'descr modified'
170183
],
171184
'initialProductData' => [
172-
['name', null,'testName2'],
185+
['name', null, 'testName2'],
173186
['sku', null, 'testSku2'],
174187
['price', null, '101'],
175188
['description', null, 'descr text']
@@ -180,7 +193,8 @@ public function setupInputDataProvider()
180193
'name' => 'testName3',
181194
'sku' => 'testSku3',
182195
'price' => '103',
183-
'special_price' => '100'
196+
'special_price' => '100',
197+
'description' => 'descr modified',
184198
],
185199
'useDefaults' => [
186200
'description' => '1'
@@ -190,14 +204,38 @@ public function setupInputDataProvider()
190204
'sku' => 'testSku3',
191205
'price' => '103',
192206
'special_price' => '100',
207+
'description' => false
193208
],
194209
'initialProductData' => [
195-
['name', null,'testName2'],
210+
['name', null, 'testName2'],
196211
['sku', null, 'testSku2'],
197212
['price', null, '101'],
198213
['description', null, 'descr text']
199214
]
200215
],
201216
];
202217
}
218+
219+
/**
220+
* @param array $useDefaults
221+
* @return array
222+
*/
223+
private function getProductAttributesMock(array $useDefaults): array
224+
{
225+
$returnArray = [];
226+
foreach ($useDefaults as $attributecode => $isDefault) {
227+
if ($isDefault === '1') {
228+
/** @var Attribute | PHPUnit_Framework_MockObject_MockObject $attribute */
229+
$attribute = $this->getMockBuilder(Attribute::class)
230+
->disableOriginalConstructor()
231+
->getMock();
232+
$attribute->expects($this->any())
233+
->method('getBackendType')
234+
->willReturn('varchar');
235+
236+
$returnArray[$attributecode] = $attribute;
237+
}
238+
}
239+
return $returnArray;
240+
}
203241
}

app/code/Magento/Checkout/view/frontend/web/js/proceed-to-checkout.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ define([
2222

2323
return false;
2424
}
25+
$(element).attr('disabled', true);
2526
location.href = config.checkoutUrl;
2627
});
2728

0 commit comments

Comments
 (0)