Skip to content

Commit aa272e6

Browse files
Merge pull request #6306 from magento-tsg-csl3/2.4-develop-pr44
[TSG-CSL3] For 2.4 (pr44)
2 parents f472536 + b086b7d commit aa272e6

File tree

36 files changed

+1386
-241
lines changed

36 files changed

+1386
-241
lines changed

app/code/Magento/Catalog/Model/Category/Product/PositionResolver.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,30 @@ public function getPositions(int $categoryId): array
4949

5050
return array_flip($connection->fetchCol($select));
5151
}
52+
53+
/**
54+
* Get category product minimum position
55+
*
56+
* @param int $categoryId
57+
* @return int
58+
*/
59+
public function getMinPosition(int $categoryId): int
60+
{
61+
$connection = $this->getConnection();
62+
63+
$select = $connection->select()->from(
64+
['cpe' => $this->getTable('catalog_product_entity')],
65+
['position' => new \Zend_Db_Expr('MIN(position)')]
66+
)->joinLeft(
67+
['ccp' => $this->getTable('catalog_category_product')],
68+
'ccp.product_id=cpe.entity_id'
69+
)->where(
70+
'ccp.category_id = ?',
71+
$categoryId
72+
)->order(
73+
'ccp.product_id ' . \Magento\Framework\DB\Select::SQL_DESC
74+
);
75+
76+
return (int)$connection->fetchOne($select);
77+
}
5278
}

app/code/Magento/Catalog/Model/Product/Option/Type/Date.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ public function validateUserValue($values)
7272
$dateValid = true;
7373
if ($this->_dateExists()) {
7474
if ($this->useCalendar()) {
75+
if (is_array($value) && $this->checkDateWithoutJSCalendar($value)) {
76+
$value['date'] = sprintf("%s/%s/%s", $value['day'], $value['month'], $value['year']);
77+
}
7578
/* Fixed validation if the date was not saved correctly after re-saved the order
7679
for example: "09\/24\/2020,2020-09-24 00:00:00" */
7780
if (is_string($value) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4},+(\w|\W)*$/', $value)) {
@@ -81,6 +84,9 @@ public function validateUserValue($values)
8184
}
8285
$dateValid = isset($value['date']) && preg_match('/^\d{1,4}.+\d{1,4}.+\d{1,4}$/', $value['date']);
8386
} else {
87+
if (is_array($value)) {
88+
$value = $this->prepareDateByDateInternal($value);
89+
}
8490
$dateValid = isset(
8591
$value['day']
8692
) && isset(
@@ -411,4 +417,38 @@ protected function _timeExists()
411417
]
412418
);
413419
}
420+
421+
/**
422+
* Check is date without JS Calendar
423+
*
424+
* @param array $value
425+
*
426+
* @return bool
427+
*/
428+
private function checkDateWithoutJSCalendar(array $value): bool
429+
{
430+
return empty($value['date'])
431+
&& !empty($value['day'])
432+
&& !empty($value['month'])
433+
&& !empty($value['year']);
434+
}
435+
436+
/**
437+
* Prepare date by date internal
438+
*
439+
* @param array $value
440+
* @return array
441+
*/
442+
private function prepareDateByDateInternal(array $value): array
443+
{
444+
if (!empty($value['date']) && !empty($value['date_internal'])) {
445+
$formatDate = explode(' ', $value['date_internal']);
446+
$date = explode('-', $formatDate[0]);
447+
$value['year'] = $date[0];
448+
$value['month'] = $date[1];
449+
$value['day'] = $date[2];
450+
}
451+
452+
return $value;
453+
}
414454
}

app/code/Magento/Catalog/Model/Product/Type/AbstractType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\Catalog\Model\Product\Type;
89

@@ -620,7 +621,7 @@ protected function _prepareOptions(\Magento\Framework\DataObject $buyRequest, $p
620621
}
621622
}
622623
if (count($results) > 0) {
623-
throw new LocalizedException(__(implode("\n", $results)));
624+
throw new LocalizedException(__(implode("\n", array_unique($results))));
624625
}
625626
}
626627

app/code/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractType.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ public function prepareAttributesWithDefaultValueForSave(array $rowData, $withDe
533533
if ($attrParams['is_static']) {
534534
continue;
535535
}
536+
$attrCode = mb_strtolower($attrCode);
536537
if (isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode]))) {
537538
if (in_array($attrParams['type'], ['select', 'boolean'])) {
538539
$resultAttrs[$attrCode] = $attrParams['options'][strtolower($rowData[$attrCode])];

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/Type/AbstractTypeTest.php

Lines changed: 97 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
*/
77
namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Type;
88

9+
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
910
use Magento\CatalogImportExport\Model\Import\Product;
1011
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface;
1112
use Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType as AbstractType;
1213
use Magento\CatalogImportExport\Model\Import\Product\Type\Simple;
1314
use Magento\Eav\Model\Entity\Attribute;
1415
use Magento\Eav\Model\Entity\Attribute\Set;
1516
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\Collection;
17+
use Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory as AttributeSetCollectionFactory;
1618
use Magento\Framework\App\ResourceConnection;
1719
use Magento\Framework\DB\Adapter\AdapterInterface;
1820
use Magento\Framework\DB\Adapter\Pdo\Mysql;
@@ -68,12 +70,12 @@ protected function setUp(): void
6870
{
6971
$this->entityModel = $this->createMock(Product::class);
7072
$attrSetColFactory = $this->createPartialMock(
71-
\Magento\Eav\Model\ResourceModel\Entity\Attribute\Set\CollectionFactory::class,
73+
AttributeSetCollectionFactory::class,
7274
['create']
7375
);
7476
$attrSetCollection = $this->createMock(Collection::class);
7577
$attrColFactory = $this->createPartialMock(
76-
\Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory::class,
78+
AttributeCollectionFactory::class,
7779
['create']
7880
);
7981
$attributeSet = $this->createMock(Set::class);
@@ -100,14 +102,22 @@ protected function setUp(): void
100102
)
101103
->disableOriginalConstructor()
102104
->getMock();
103-
$attribute->expects($this->any())->method('getIsVisible')->willReturn(true);
104-
$attribute->expects($this->any())->method('getIsGlobal')->willReturn(true);
105-
$attribute->expects($this->any())->method('getIsRequired')->willReturn(true);
106-
$attribute->expects($this->any())->method('getIsUnique')->willReturn(true);
107-
$attribute->expects($this->any())->method('getFrontendLabel')->willReturn('frontend_label');
108-
$attribute->expects($this->any())->method('getApplyTo')->willReturn(['simple']);
109-
$attribute->expects($this->any())->method('getDefaultValue')->willReturn('default_value');
110-
$attribute->expects($this->any())->method('usesSource')->willReturn(true);
105+
$attribute->method('getIsVisible')
106+
->willReturn(true);
107+
$attribute->method('getIsGlobal')
108+
->willReturn(true);
109+
$attribute->method('getIsRequired')
110+
->willReturn(true);
111+
$attribute->method('getIsUnique')
112+
->willReturn(true);
113+
$attribute->method('getFrontendLabel')
114+
->willReturn('frontend_label');
115+
$attribute->method('getApplyTo')
116+
->willReturn(['simple']);
117+
$attribute->method('getDefaultValue')
118+
->willReturn('default_value');
119+
$attribute->method('usesSource')
120+
->willReturn(true);
111121

112122
$entityAttributes = [
113123
[
@@ -123,38 +133,54 @@ protected function setUp(): void
123133
$attribute2 = clone $attribute;
124134
$attribute3 = clone $attribute;
125135

126-
$attribute1->expects($this->any())->method('getId')->willReturn('1');
127-
$attribute1->expects($this->any())->method('getAttributeCode')->willReturn('attr_code');
128-
$attribute1->expects($this->any())->method('getFrontendInput')->willReturn('multiselect');
129-
$attribute1->expects($this->any())->method('isStatic')->willReturn(true);
130-
131-
$attribute2->expects($this->any())->method('getId')->willReturn('2');
132-
$attribute2->expects($this->any())->method('getAttributeCode')->willReturn('boolean_attribute');
133-
$attribute2->expects($this->any())->method('getFrontendInput')->willReturn('boolean');
134-
$attribute2->expects($this->any())->method('isStatic')->willReturn(false);
135-
136-
$attribute3->expects($this->any())->method('getId')->willReturn('3');
137-
$attribute3->expects($this->any())->method('getAttributeCode')->willReturn('text_attribute');
138-
$attribute3->expects($this->any())->method('getFrontendInput')->willReturn('text');
139-
$attribute3->expects($this->any())->method('isStatic')->willReturn(false);
140-
141-
$this->entityModel->expects($this->any())->method('getEntityTypeId')->willReturn(3);
142-
$this->entityModel->expects($this->any())->method('getAttributeOptions')->willReturnOnConsecutiveCalls(
143-
['option1', 'option2'],
144-
['yes' => 1, 'no' => 0]
145-
);
146-
$attrSetColFactory->expects($this->any())->method('create')->willReturn($attrSetCollection);
147-
$attrSetCollection->expects($this->any())->method('setEntityTypeFilter')->willReturn([$attributeSet]);
148-
$attrColFactory->expects($this->any())->method('create')->willReturn($attrCollection);
149-
$attrCollection->expects($this->any())
150-
->method('setAttributeSetFilter')
136+
$attribute1->method('getId')
137+
->willReturn('1');
138+
$attribute1->method('getAttributeCode')
139+
->willReturn('attr_code');
140+
$attribute1->method('getFrontendInput')
141+
->willReturn('multiselect');
142+
$attribute1->method('isStatic')
143+
->willReturn(true);
144+
145+
$attribute2->method('getId')
146+
->willReturn('2');
147+
$attribute2->method('getAttributeCode')
148+
->willReturn('boolean_attribute');
149+
$attribute2->method('getFrontendInput')
150+
->willReturn('boolean');
151+
$attribute2->method('isStatic')
152+
->willReturn(false);
153+
154+
$attribute3->method('getId')
155+
->willReturn('3');
156+
$attribute3->method('getAttributeCode')
157+
->willReturn('Text_attribute');
158+
$attribute3->method('getFrontendInput')
159+
->willReturn('text');
160+
$attribute3->method('isStatic')
161+
->willReturn(false);
162+
163+
$this->entityModel->method('getEntityTypeId')
164+
->willReturn(3);
165+
$this->entityModel->method('getAttributeOptions')
166+
->willReturnOnConsecutiveCalls(
167+
['option1', 'option2'],
168+
['yes' => 1, 'no' => 0]
169+
);
170+
$attrSetColFactory->method('create')
171+
->willReturn($attrSetCollection);
172+
$attrSetCollection->method('setEntityTypeFilter')
173+
->willReturn([$attributeSet]);
174+
$attrColFactory->method('create')
175+
->willReturn($attrCollection);
176+
$attrCollection->method('setAttributeSetFilter')
151177
->willReturn([$attribute1, $attribute2, $attribute3]);
152-
$attributeSet->expects($this->any())->method('getId')->willReturn(1);
153-
$attributeSet->expects($this->any())->method('getAttributeSetName')->willReturn('attribute_set_name');
178+
$attributeSet->method('getId')
179+
->willReturn(1);
180+
$attributeSet->method('getAttributeSetName')
181+
->willReturn('attribute_set_name');
154182

155-
$attrCollection
156-
->expects($this->any())
157-
->method('addFieldToFilter')
183+
$attrCollection->method('addFieldToFilter')
158184
->with(
159185
['main_table.attribute_id', 'main_table.attribute_code'],
160186
[
@@ -193,19 +219,26 @@ protected function setUp(): void
193219
'getConnection',
194220
]
195221
);
196-
$this->select->expects($this->any())->method('from')->willReturnSelf();
197-
$this->select->expects($this->any())->method('where')->willReturnSelf();
198-
$this->select->expects($this->any())->method('joinLeft')->willReturnSelf();
199-
$this->connection->expects($this->any())->method('select')->willReturn($this->select);
222+
$this->select->method('from')
223+
->willReturnSelf();
224+
$this->select->method('where')
225+
->willReturnSelf();
226+
$this->select->method('joinLeft')
227+
->willReturnSelf();
228+
$this->connection->method('select')
229+
->willReturn($this->select);
200230
$connection = $this->createMock(Mysql::class);
201-
$connection->expects($this->any())->method('quoteInto')->willReturn('query');
202-
$this->select->expects($this->any())->method('getConnection')->willReturn($connection);
203-
$this->connection->expects($this->any())->method('insertOnDuplicate')->willReturnSelf();
204-
$this->connection->expects($this->any())->method('delete')->willReturnSelf();
205-
$this->connection->expects($this->any())->method('quoteInto')->willReturn('');
206-
$this->connection
207-
->expects($this->any())
208-
->method('fetchAll')
231+
$connection->method('quoteInto')
232+
->willReturn('query');
233+
$this->select->method('getConnection')
234+
->willReturn($connection);
235+
$this->connection->method('insertOnDuplicate')
236+
->willReturnSelf();
237+
$this->connection->method('delete')
238+
->willReturnSelf();
239+
$this->connection->method('quoteInto')
240+
->willReturn('');
241+
$this->connection->method('fetchAll')
209242
->willReturn($entityAttributes);
210243

211244
$this->resource = $this->createPartialMock(
@@ -215,12 +248,10 @@ protected function setUp(): void
215248
'getTableName',
216249
]
217250
);
218-
$this->resource->expects($this->any())->method('getConnection')->willReturn(
219-
$this->connection
220-
);
221-
$this->resource->expects($this->any())->method('getTableName')->willReturn(
222-
'tableName'
223-
);
251+
$this->resource->method('getConnection')
252+
->willReturn($this->connection);
253+
$this->resource->method('getTableName')
254+
->willReturn('tableName');
224255

225256
$this->objectManagerHelper = new ObjectManagerHelper($this);
226257
$this->simpleType = $this->objectManagerHelper->getObject(
@@ -233,9 +264,7 @@ protected function setUp(): void
233264
]
234265
);
235266

236-
$this->abstractType = $this->getMockBuilder(
237-
\Magento\CatalogImportExport\Model\Import\Product\Type\AbstractType::class
238-
)
267+
$this->abstractType = $this->getMockBuilder(AbstractType::class)
239268
->disableOriginalConstructor()
240269
->getMockForAbstractClass();
241270
}
@@ -277,8 +306,10 @@ public function testIsRowValidSuccess()
277306
{
278307
$rowData = ['_attribute_set' => 'attribute_set_name'];
279308
$rowNum = 1;
280-
$this->entityModel->expects($this->any())->method('getRowScope')->willReturn(null);
281-
$this->entityModel->expects($this->never())->method('addRowError');
309+
$this->entityModel->method('getRowScope')
310+
->willReturn(null);
311+
$this->entityModel->expects($this->never())
312+
->method('addRowError');
282313
$this->setPropertyValue(
283314
$this->simpleType,
284315
'_attributes',
@@ -296,8 +327,9 @@ public function testIsRowValidError()
296327
'sku' => 'sku'
297328
];
298329
$rowNum = 1;
299-
$this->entityModel->expects($this->any())->method('getRowScope')->willReturn(1);
300-
$this->entityModel->expects($this->once())->method('addRowError')
330+
$this->entityModel->method('getRowScope')
331+
->willReturn(1);
332+
$this->entityModel->method('addRowError')
301333
->with(
302334
RowValidatorInterface::ERROR_VALUE_IS_REQUIRED,
303335
1,

0 commit comments

Comments
 (0)