Skip to content

Commit

Permalink
Merge pull request #2792 from magento-engcom/2.3-develop-prs
Browse files Browse the repository at this point in the history
[EngCom] Public Pull Requests - 2.3-develop
  • Loading branch information
VladimirZaets authored Jul 3, 2018
2 parents d9fb867 + 16fc13b commit 2375461
Show file tree
Hide file tree
Showing 19 changed files with 209 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public function getItems($attributeCode);
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @throws \Magento\Framework\Exception\StateException
* @throws \Magento\Framework\Exception\InputException
* @return bool
* @return string
*/
public function add($attributeCode, $option);

Expand Down
13 changes: 13 additions & 0 deletions app/code/Magento/CatalogImportExport/Model/Import/Product.php
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,19 @@ public function getMultipleValueSeparator()
return Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR;
}

/**
* Return empty attribute value constant
*
* @return string
*/
public function getEmptyAttributeValueConstant()
{
if (!empty($this->_parameters[Import::FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT])) {
return $this->_parameters[Import::FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT];
}
return Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT;
}

/**
* Retrieve instance of product custom options import entity
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Magento\Catalog\Model\ResourceModel\Product\Option\Value\Collection as ProductOptionValueCollection;
use Magento\Catalog\Model\ResourceModel\Product\Option\Value\CollectionFactory as ProductOptionValueCollectionFactory;
use Magento\Store\Model\Store;
use Magento\ImportExport\Model\Import;

/**
* Entity class which provide possibility to import product custom options
Expand Down Expand Up @@ -1090,7 +1091,7 @@ protected function _getMultiRowFormat($rowData)
// Parse custom options.
$rowData = $this->_parseCustomOptions($rowData);
$multiRow = [];
if (empty($rowData['custom_options'])) {
if (empty($rowData['custom_options']) || !is_array($rowData['custom_options'])) {
return $multiRow;
}

Expand Down Expand Up @@ -1235,7 +1236,12 @@ protected function _importData()
$multiRowData = $this->_getMultiRowFormat($rowData);
if (!empty($rowData[self::COLUMN_SKU]) && isset($this->_productsSkuToId[$rowData[self::COLUMN_SKU]])) {
$this->_rowProductId = $this->_productsSkuToId[$rowData[self::COLUMN_SKU]];
if (array_key_exists('custom_options', $rowData) && trim($rowData['custom_options']) === '') {
if (array_key_exists('custom_options', $rowData)
&& (
trim($rowData['custom_options']) === '' ||
trim($rowData['custom_options']) === $this->_productEntity->getEmptyAttributeValueConstant()
)
) {
$optionsToRemove[] = $this->_rowProductId;
}
}
Expand Down Expand Up @@ -1923,7 +1929,8 @@ protected function _updateProducts(array $data)
protected function _parseCustomOptions($rowData)
{
$beforeOptionValueSkuDelimiter = ';';
if (empty($rowData['custom_options'])) {
if (empty($rowData['custom_options'])
|| $rowData['custom_options'] === Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT) {
return $rowData;
}
$rowData['custom_options'] = str_replace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ public function clearEmptyData(array $rowData)
if (!$attrParams['is_static'] && !isset($rowData[$attrCode])) {
unset($rowData[$attrCode]);
}

if (isset($rowData[$attrCode])
&& $rowData[$attrCode] === $this->_entityModel->getEmptyAttributeValueConstant()
) {
$rowData[$attrCode] = null;
}
}
return $rowData;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,12 @@ public function isRequiredAttributeValid($attrCode, array $attributeParams, arra
$doCheck = true;
}

return $doCheck ? isset($rowData[$attrCode]) && strlen(trim($rowData[$attrCode])) : true;
if ($doCheck === true) {
return isset($rowData[$attrCode])
&& strlen(trim($rowData[$attrCode]))
&& trim($rowData[$attrCode]) !== $this->context->getEmptyAttributeValueConstant();
}
return true;
}

/**
Expand Down Expand Up @@ -188,6 +193,11 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData)
if (!strlen(trim($rowData[$attrCode]))) {
return true;
}

if ($rowData[$attrCode] === $this->context->getEmptyAttributeValueConstant() && !$attrParams['is_required']) {
return true;
}

switch ($attrParams['type']) {
case 'varchar':
case 'text':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ class Quantity extends AbstractImportValidator implements RowValidatorInterface
public function isValid($value)
{
$this->_clearMessages();
if (!empty($value['qty']) && !is_numeric($value['qty'])) {
if (!empty($value['qty']) && (!is_numeric($value['qty'])
&& $value['qty'] !== $this->context->getEmptyAttributeValueConstant())
) {
$this->_addMessages(
[
sprintf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ class Weight extends AbstractImportValidator implements RowValidatorInterface
public function isValid($value)
{
$this->_clearMessages();
if (!empty($value['weight']) && (!is_numeric($value['weight']) || $value['weight'] < 0)) {
if (!empty($value['weight']) && (!is_numeric($value['weight']) || $value['weight'] < 0)
&& $value['weight'] !== $this->context->getEmptyAttributeValueConstant()
) {
$this->_addMessages(
[
sprintf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

use Magento\CatalogImportExport\Model\Import\Product;
use Magento\CatalogImportExport\Model\Import\Product\Validator\Quantity;
use Magento\ImportExport\Model\Import;

/**
* Class QuantityTest
Expand All @@ -25,6 +26,10 @@ protected function setUp()
$contextStub = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$contextStub->expects($this->any())
->method('getEmptyAttributeValueConstant')
->willReturn(Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT);

$contextStub->method('retrieveMessageTemplate')->willReturn(null);
$this->quantity->init($contextStub);
}
Expand Down Expand Up @@ -54,6 +59,9 @@ public function isValidDataProvider()
[true, ['qty' => '']],
[false, ['qty' => 'abc']],
[false, ['qty' => true]],
[false, ['qty' => true]],
[true, ['qty' => Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT]],
[false, ['qty' => '__EMPTY__VALUE__TEST__']],
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\CatalogImportExport\Test\Unit\Model\Import\Product\Validator;

use Magento\CatalogImportExport\Model\Import\Product;
use Magento\CatalogImportExport\Model\Import\Product\Validator\Weight;
use Magento\ImportExport\Model\Import;

/**
* Class WeightTest
*/
class WeightTest extends \PHPUnit\Framework\TestCase
{
/**
* @var Weight
*/
private $weight;

protected function setUp()
{
$this->weight = new Weight();

$contextStub = $this->getMockBuilder(Product::class)
->disableOriginalConstructor()
->getMock();
$contextStub->expects($this->any())
->method('getEmptyAttributeValueConstant')
->willReturn(Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT);

$contextStub->method('retrieveMessageTemplate')->willReturn(null);
$this->weight->init($contextStub);
}

/**
* @param bool $expectedResult
* @param array $value
* @dataProvider isValidDataProvider
*/
public function testIsValid($expectedResult, $value)
{
$result = $this->weight->isValid($value);
$this->assertEquals($expectedResult, $result);
}

/**
* @return array
*/
public function isValidDataProvider()
{
return [
[true, ['weight' => 0]],
[true, ['weight' => 1]],
[true, ['weight' => 5]],
[false, ['weight' => -1]],
[false, ['weight' => -10]],
[true, ['weight' => '']],
[false, ['weight' => 'abc']],
[false, ['weight' => true]],
[false, ['weight' => true]],
[true, ['weight' => Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT]],
[false, ['weight' => '__EMPTY__VALUE__TEST__']],
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -603,6 +603,28 @@ public function testGetMultipleValueSeparatorFromParameters()
);
}

public function testGetEmptyAttributeValueConstantDefault()
{
$this->setPropertyValue($this->importProduct, '_parameters', null);
$this->assertEquals(
Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT,
$this->importProduct->getEmptyAttributeValueConstant()
);
}

public function testGetEmptyAttributeValueConstantFromParameters()
{
$expectedSeparator = '__EMPTY__VALUE__TEST__';
$this->setPropertyValue($this->importProduct, '_parameters', [
\Magento\ImportExport\Model\Import::FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT => $expectedSeparator,
]);

$this->assertEquals(
$expectedSeparator,
$this->importProduct->getEmptyAttributeValueConstant()
);
}

public function testDeleteProductsForReplacement()
{
$importProduct = $this->getMockBuilder(\Magento\CatalogImportExport\Model\Import\Product::class)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public function aroundExecute(FlushFormKey $subject, callable $proceed, ...$args
$currentFormKey = $this->dataFormKey->getFormKey();
$proceed(...$args);
$beforeParams = $this->session->getBeforeRequestParams();
if ($beforeParams['form_key'] == $currentFormKey) {
if (isset($beforeParams['form_key']) && $beforeParams['form_key'] === $currentFormKey) {
$beforeParams['form_key'] = $this->dataFormKey->getFormKey();
$this->session->setBeforeRequestParams($beforeParams);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ interface AttributeOptionManagementInterface
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @throws \Magento\Framework\Exception\StateException
* @throws \Magento\Framework\Exception\InputException
* @return bool
* @return string
*/
public function add($entityType, $attributeCode, $option);

Expand Down
34 changes: 31 additions & 3 deletions app/code/Magento/Eav/Model/Entity/Attribute/OptionManagement.php
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,10 @@ public function add($entityType, $attributeCode, $option)
throw new StateException(__('The "%1" attribute doesn\'t work with options.', $attributeCode));
}

$optionLabel = $option->getLabel();
$optionId = $this->getOptionId($option);
$options = [];
$options['value'][$optionId][0] = $option->getLabel();
$options['value'][$optionId][0] = $optionLabel;
$options['order'][$optionId] = $option->getSortOrder();

if (is_array($option->getStoreLabels())) {
Expand All @@ -67,11 +68,14 @@ public function add($entityType, $attributeCode, $option)
$attribute->setOption($options);
try {
$this->resourceModel->save($attribute);
if ($optionLabel && $attribute->getAttributeCode()) {
$this->setOptionValue($option, $attribute, $optionLabel);
}
} catch (\Exception $e) {
throw new StateException(__('The "%1" attribute can\'t be saved.', $attributeCode));
}

return true;
return $this->getOptionId($option);
}

/**
Expand Down Expand Up @@ -147,8 +151,32 @@ protected function validateOption($attribute, $optionId)
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @return string
*/
private function getOptionId($option)
private function getOptionId(\Magento\Eav\Api\Data\AttributeOptionInterface $option) : string
{
return $option->getValue() ?: 'new_option';
}

/**
* @param \Magento\Eav\Api\Data\AttributeOptionInterface $option
* @param \Magento\Eav\Api\Data\AttributeInterface $attribute
* @param string $optionLabel
* @return void
*/
private function setOptionValue(
\Magento\Eav\Api\Data\AttributeOptionInterface $option,
\Magento\Eav\Api\Data\AttributeInterface $attribute,
string $optionLabel
) {
$optionId = $attribute->getSource()->getOptionId($optionLabel);
if ($optionId) {
$option->setValue($attribute->getSource()->getOptionId($optionId));
} elseif (is_array($option->getStoreLabels())) {
foreach ($option->getStoreLabels() as $label) {
if ($optionId = $attribute->getSource()->getOptionId($label->getLabel())) {
$option->setValue($attribute->getSource()->getOptionId($optionId));
break;
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public function testAdd()
$attributeMock->expects($this->once())->method('setDefault')->with(['new_option']);
$attributeMock->expects($this->once())->method('setOption')->with($option);
$this->resourceModelMock->expects($this->once())->method('save')->with($attributeMock);
$this->assertTrue($this->model->add($entityType, $attributeCode, $optionMock));
$this->assertEquals('new_option', $this->model->add($entityType, $attributeCode, $optionMock));
}

/**
Expand Down
13 changes: 13 additions & 0 deletions app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@ protected function _prepareForm()
'value' => Import::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR,
]
);
$fieldsets[$behaviorCode]->addField(
$behaviorCode . \Magento\ImportExport\Model\Import::FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT,
'text',
[
'name' => \Magento\ImportExport\Model\Import::FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT,
'label' => __('Empty attribute value constant'),
'title' => __('Empty attribute value constant'),
'required' => true,
'disabled' => true,
'class' => $behaviorCode,
'value' => Import::DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT,
]
);
$fieldsets[$behaviorCode]->addField(
$behaviorCode . \Magento\ImportExport\Model\Import::FIELDS_ENCLOSURE,
'checkbox',
Expand Down
10 changes: 10 additions & 0 deletions app/code/Magento/ImportExport/Model/Import.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
*/
const FIELD_FIELD_MULTIPLE_VALUE_SEPARATOR = '_import_multiple_value_separator';

/**
* Import empty attribute value constant.
*/
const FIELD_EMPTY_ATTRIBUTE_VALUE_CONSTANT = '_import_empty_attribute_value_constant';

/**
* Allow multiple values wrapping in double quotes for additional attributes.
*/
Expand All @@ -89,6 +94,11 @@ class Import extends \Magento\ImportExport\Model\AbstractModel
*/
const DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR = ',';

/**
* default empty attribute value constant
*/
const DEFAULT_EMPTY_ATTRIBUTE_VALUE_CONSTANT = '__EMPTY__VALUE__';

/**#@+
* Import constants
*/
Expand Down
Loading

0 comments on commit 2375461

Please sign in to comment.