Skip to content

Commit 36ad542

Browse files
author
olysenko
committed
Merge remote-tracking branch 'origin/MAGETWO-97345' into chaika_january
2 parents 8e2ca94 + 5c5cf87 commit 36ad542

File tree

3 files changed

+192
-148
lines changed

3 files changed

+192
-148
lines changed

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

Lines changed: 73 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\CatalogImportExport\Model\Import;
78

89
use Magento\Catalog\Api\ProductRepositoryInterface;
910
use Magento\Catalog\Model\Config as CatalogConfig;
1011
use Magento\Catalog\Model\Product\Visibility;
11-
use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor;
1212
use Magento\CatalogImportExport\Model\Import\Product\ImageTypeProcessor;
13+
use Magento\CatalogImportExport\Model\Import\Product\MediaGalleryProcessor;
1314
use Magento\CatalogImportExport\Model\Import\Product\RowValidatorInterface as ValidatorInterface;
14-
use Magento\CatalogInventory\Api\Data\StockItemInterface;
1515
use Magento\CatalogImportExport\Model\StockItemImporterInterface;
16+
use Magento\CatalogInventory\Api\Data\StockItemInterface;
1617
use Magento\Framework\App\Filesystem\DirectoryList;
1718
use Magento\Framework\App\ObjectManager;
1819
use Magento\Framework\Exception\LocalizedException;
@@ -307,7 +308,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
307308
ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE => 'Imported resource (image) could not be downloaded from external resource due to timeout or access permissions',
308309
ValidatorInterface::ERROR_INVALID_WEIGHT => 'Product weight is invalid',
309310
ValidatorInterface::ERROR_DUPLICATE_URL_KEY => 'Url key: \'%s\' was already generated for an item with the SKU: \'%s\'. You need to specify the unique URL key manually',
310-
ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => "Value for multiselect attribute %s contains duplicated values",
311+
ValidatorInterface::ERROR_DUPLICATE_MULTISELECT_VALUES => 'Value for multiselect attribute %s contains duplicated values',
311312
ValidatorInterface::ERROR_NEW_TO_DATE => 'Make sure new_to_date is later than or the same as new_from_date',
312313
];
313314
//@codingStandardsIgnoreEnd
@@ -795,6 +796,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
795796
* @param StockItemImporterInterface|null $stockItemImporter
796797
* @param DateTimeFactory $dateTimeFactory
797798
* @param ProductRepositoryInterface|null $productRepository
799+
* @throws LocalizedException
800+
* @throws \Magento\Framework\Exception\FileSystemException
798801
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
799802
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
800803
*/
@@ -913,7 +916,7 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData, $
913916
{
914917
if (!$this->validator->isAttributeValid($attrCode, $attrParams, $rowData)) {
915918
foreach ($this->validator->getMessages() as $message) {
916-
$this->addRowError($message, $rowNum, $attrCode);
919+
$this->skipRow($rowNum, $message, ProcessingError::ERROR_LEVEL_NOT_CRITICAL, $attrCode);
917920
}
918921
return false;
919922
}
@@ -1646,19 +1649,16 @@ protected function _saveProducts()
16461649
continue;
16471650
}
16481651
if ($this->getErrorAggregator()->hasToBeTerminated()) {
1649-
$validationStrategy = $this->_parameters[Import::FIELD_NAME_VALIDATION_STRATEGY];
1650-
if (ProcessingErrorAggregatorInterface::VALIDATION_STRATEGY_SKIP_ERRORS !== $validationStrategy) {
1651-
$this->getErrorAggregator()->addRowToSkip($rowNum);
1652-
continue;
1653-
}
1652+
$this->getErrorAggregator()->addRowToSkip($rowNum);
1653+
continue;
16541654
}
16551655
$rowScope = $this->getRowScope($rowData);
16561656

16571657
$urlKey = $this->getUrlKey($rowData);
16581658
if (!empty($rowData[self::URL_KEY])) {
16591659
// If url_key column and its value were in the CSV file
16601660
$rowData[self::URL_KEY] = $urlKey;
1661-
} else if ($this->isNeedToChangeUrlKey($rowData)) {
1661+
} elseif ($this->isNeedToChangeUrlKey($rowData)) {
16621662
// If url_key column was empty or even not declared in the CSV file but by the rules it is need to
16631663
// be setteed. In case when url_key is generating from name column we have to ensure that the bunch
16641664
// of products will pass for the event with url_key column.
@@ -1670,7 +1670,9 @@ protected function _saveProducts()
16701670
if (null === $rowSku) {
16711671
$this->getErrorAggregator()->addRowToSkip($rowNum);
16721672
continue;
1673-
} elseif (self::SCOPE_STORE == $rowScope) {
1673+
}
1674+
1675+
if (self::SCOPE_STORE == $rowScope) {
16741676
// set necessary data from SCOPE_DEFAULT row
16751677
$rowData[self::COL_TYPE] = $this->skuProcessor->getNewSku($rowSku)['type_id'];
16761678
$rowData['attribute_set_id'] = $this->skuProcessor->getNewSku($rowSku)['attr_set_id'];
@@ -1806,13 +1808,7 @@ protected function _saveProducts()
18061808
$uploadedImages[$columnImage] = $uploadedFile;
18071809
} else {
18081810
unset($rowData[$column]);
1809-
$this->addRowError(
1810-
ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE,
1811-
$rowNum,
1812-
null,
1813-
null,
1814-
ProcessingError::ERROR_LEVEL_NOT_CRITICAL
1815-
);
1811+
$this->skipRow($rowNum, ValidatorInterface::ERROR_MEDIA_URL_NOT_ACCESSIBLE);
18161812
}
18171813
} else {
18181814
$uploadedFile = $uploadedImages[$columnImage];
@@ -2436,6 +2432,7 @@ public function getRowScope(array $rowData)
24362432
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
24372433
* @SuppressWarnings(PHPMD.NPathComplexity)
24382434
* @SuppressWarnings(PHPMD.ExcessiveMethodLength)
2435+
* @throws \Zend_Validate_Exception
24392436
*/
24402437
public function validateRow(array $rowData, $rowNum)
24412438
{
@@ -2451,32 +2448,35 @@ public function validateRow(array $rowData, $rowNum)
24512448
// BEHAVIOR_DELETE and BEHAVIOR_REPLACE use specific validation logic
24522449
if (Import::BEHAVIOR_REPLACE == $this->getBehavior()) {
24532450
if (self::SCOPE_DEFAULT == $rowScope && !$this->isSkuExist($sku)) {
2454-
$this->addRowError(ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE, $rowNum);
2451+
$this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE);
24552452
return false;
24562453
}
24572454
}
24582455
if (Import::BEHAVIOR_DELETE == $this->getBehavior()) {
24592456
if (self::SCOPE_DEFAULT == $rowScope && !$this->isSkuExist($sku)) {
2460-
$this->addRowError(ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE, $rowNum);
2457+
$this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_NOT_FOUND_FOR_DELETE);
24612458
return false;
24622459
}
24632460
return true;
24642461
}
24652462

2463+
// if product doesn't exist, need to throw critical error else all errors should be not critical.
2464+
$errorLevel = $this->getValidationErrorLevel($sku);
2465+
24662466
if (!$this->validator->isValid($rowData)) {
24672467
foreach ($this->validator->getMessages() as $message) {
2468-
$this->addRowError($message, $rowNum, $this->validator->getInvalidAttribute());
2468+
$this->skipRow($rowNum, $message, $errorLevel, $this->validator->getInvalidAttribute());
24692469
}
24702470
}
24712471

24722472
if (null === $sku) {
2473-
$this->addRowError(ValidatorInterface::ERROR_SKU_IS_EMPTY, $rowNum);
2473+
$this->skipRow($rowNum, ValidatorInterface::ERROR_SKU_IS_EMPTY, $errorLevel);
24742474
} elseif (false === $sku) {
2475-
$this->addRowError(ValidatorInterface::ERROR_ROW_IS_ORPHAN, $rowNum);
2475+
$this->skipRow($rowNum, ValidatorInterface::ERROR_ROW_IS_ORPHAN, $errorLevel);
24762476
} elseif (self::SCOPE_STORE == $rowScope
24772477
&& !$this->storeResolver->getStoreCodeToId($rowData[self::COL_STORE])
24782478
) {
2479-
$this->addRowError(ValidatorInterface::ERROR_INVALID_STORE, $rowNum);
2479+
$this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_STORE, $errorLevel);
24802480
}
24812481

24822482
// SKU is specified, row is SCOPE_DEFAULT, new product block begins
@@ -2491,16 +2491,15 @@ public function validateRow(array $rowData, $rowNum)
24912491
$this->prepareNewSkuData($sku)
24922492
);
24932493
} else {
2494-
$this->addRowError(ValidatorInterface::ERROR_TYPE_UNSUPPORTED, $rowNum);
2494+
$this->skipRow($rowNum, ValidatorInterface::ERROR_TYPE_UNSUPPORTED, $errorLevel);
24952495
}
24962496
} else {
24972497
// validate new product type and attribute set
2498-
if (!isset($rowData[self::COL_TYPE]) || !isset($this->_productTypeModels[$rowData[self::COL_TYPE]])) {
2499-
$this->addRowError(ValidatorInterface::ERROR_INVALID_TYPE, $rowNum);
2500-
} elseif (!isset($rowData[self::COL_ATTR_SET])
2501-
|| !isset($this->_attrSetNameToId[$rowData[self::COL_ATTR_SET]])
2498+
if (!isset($rowData[self::COL_TYPE], $this->_productTypeModels[$rowData[self::COL_TYPE]])) {
2499+
$this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_TYPE, $errorLevel);
2500+
} elseif (!isset($rowData[self::COL_ATTR_SET], $this->_attrSetNameToId[$rowData[self::COL_ATTR_SET]])
25022501
) {
2503-
$this->addRowError(ValidatorInterface::ERROR_INVALID_ATTR_SET, $rowNum);
2502+
$this->skipRow($rowNum, ValidatorInterface::ERROR_INVALID_ATTR_SET, $errorLevel);
25042503
} elseif ($this->skuProcessor->getNewSku($sku) === null) {
25052504
$this->skuProcessor->addNewSku(
25062505
$sku,
@@ -2556,8 +2555,11 @@ public function validateRow(array $rowData, $rowNum)
25562555
ValidatorInterface::ERROR_DUPLICATE_URL_KEY,
25572556
$rowNum,
25582557
$rowData[self::COL_NAME],
2559-
$message
2560-
);
2558+
$message,
2559+
ProcessingError::ERROR_LEVEL_NOT_CRITICAL
2560+
)
2561+
->getErrorAggregator()
2562+
->addRowToSkip($rowNum);
25612563
}
25622564
}
25632565
}
@@ -2567,9 +2569,10 @@ public function validateRow(array $rowData, $rowNum)
25672569
$newFromTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_FROM_DATE], false));
25682570
$newToTimestamp = strtotime($this->dateTime->formatDate($rowData[self::COL_NEW_TO_DATE], false));
25692571
if ($newFromTimestamp > $newToTimestamp) {
2570-
$this->addRowError(
2571-
ValidatorInterface::ERROR_NEW_TO_DATE,
2572+
$this->skipRow(
25722573
$rowNum,
2574+
ValidatorInterface::ERROR_NEW_TO_DATE,
2575+
$errorLevel,
25732576
$rowData[self::COL_NEW_TO_DATE]
25742577
);
25752578
}
@@ -2588,8 +2591,8 @@ private function isNeedToValidateUrlKey($rowData)
25882591
{
25892592
return (!empty($rowData[self::URL_KEY]) || !empty($rowData[self::COL_NAME]))
25902593
&& (empty($rowData[self::COL_VISIBILITY])
2591-
|| $rowData[self::COL_VISIBILITY]
2592-
!== (string)Visibility::getOptionArray()[Visibility::VISIBILITY_NOT_VISIBLE]);
2594+
|| $rowData[self::COL_VISIBILITY]
2595+
!== (string)Visibility::getOptionArray()[Visibility::VISIBILITY_NOT_VISIBLE]);
25932596
}
25942597

25952598
/**
@@ -3097,4 +3100,38 @@ private function retrieveProductBySku($sku)
30973100
}
30983101
return $product;
30993102
}
3103+
3104+
/**
3105+
* Add row as skipped
3106+
*
3107+
* @param int $rowNum
3108+
* @param string $errorCode Error code or simply column name
3109+
* @param string $errorLevel error level
3110+
* @param string|null $colName optional column name
3111+
* @return $this
3112+
*/
3113+
private function skipRow(
3114+
$rowNum,
3115+
string $errorCode,
3116+
string $errorLevel = ProcessingError::ERROR_LEVEL_NOT_CRITICAL,
3117+
$colName = null
3118+
): self {
3119+
$this->addRowError($errorCode, $rowNum, $colName, null, $errorLevel);
3120+
$this->getErrorAggregator()
3121+
->addRowToSkip($rowNum);
3122+
return $this;
3123+
}
3124+
3125+
/**
3126+
* Returns errorLevel for validation
3127+
*
3128+
* @param string $sku
3129+
* @return string
3130+
*/
3131+
private function getValidationErrorLevel($sku): string
3132+
{
3133+
return (!$this->isSkuExist($sku) && Import::BEHAVIOR_REPLACE !== $this->getBehavior())
3134+
? ProcessingError::ERROR_LEVEL_CRITICAL
3135+
: ProcessingError::ERROR_LEVEL_NOT_CRITICAL;
3136+
}
31003137
}

0 commit comments

Comments
 (0)