diff --git a/app/code/Magento/CatalogImportExport/Model/Export/Product.php b/app/code/Magento/CatalogImportExport/Model/Export/Product.php index 2ae758cd4e44e..6ca73df206ae2 100644 --- a/app/code/Magento/CatalogImportExport/Model/Export/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Export/Product.php @@ -632,7 +632,7 @@ protected function updateDataWithCategoryColumns(&$dataRow, &$rowCategories, $pr } $categories[] = $categoryPath; } - $dataRow[self::COL_CATEGORY] = implode(ImportProduct::PSEUDO_MULTI_LINE_SEPARATOR, $categories); + $dataRow[self::COL_CATEGORY] = implode(ImportProduct::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $categories); unset($rowCategories[$productId]); return true; @@ -666,7 +666,7 @@ protected function setHeaderColumns($customOptionsData, $stockItemRows) self::COL_ATTR_SET, self::COL_TYPE, self::COL_CATEGORY, - '_product_websites', + self::COL_PRODUCT_WEBSITES, ], $this->_getExportMainAttrCodes(), [self::COL_ADDITIONAL_ATTRIBUTES], @@ -1032,7 +1032,7 @@ protected function addMultirowData($dataRow, $multiRawData) foreach ($multiRawData['rowWebsites'][$productId] as $productWebsite) { $websiteCodes[] = $this->_websiteIdToCode[$productWebsite]; } - $dataRow['_product_websites'] = + $dataRow[self::COL_PRODUCT_WEBSITES] = implode(ImportProduct::DEFAULT_GLOBAL_MULTI_VALUE_SEPARATOR, $websiteCodes); $multiRawData['rowWebsites'][$productId] = []; } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php index 7f9a5d05af67c..2001d54f76db7 100755 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php @@ -1372,7 +1372,9 @@ protected function _saveProducts() } } - $this->websitesCache[$rowSku] = []; + if (!array_key_exists($rowSku, $this->websitesCache)) { + $this->websitesCache[$rowSku] = []; + } // 2. Product-to-Website phase if (!empty($rowData[self::COL_PRODUCT_WEBSITES])) { $websiteCodes = explode($this->getMultipleValueSeparator(), $rowData[self::COL_PRODUCT_WEBSITES]); @@ -1383,12 +1385,12 @@ protected function _saveProducts() } // 3. Categories phase - $categoriesString = empty($rowData[self::COL_CATEGORY]) ? '' : $rowData[self::COL_CATEGORY]; - $this->categoriesCache[$rowSku] = []; - if (!empty($categoriesString)) { - foreach ($this->categoryProcessor->upsertCategories($categoriesString) as $categoryId) { - $this->categoriesCache[$rowSku][$categoryId] = true; - } + $categoryIds = $this->processRowCategories($rowData); + if (!array_key_exists($rowData[Product::COL_SKU], $this->categoriesCache)) { + $this->categoriesCache[$rowData[Product::COL_SKU]] = []; + } + foreach ($categoryIds as $id) { + $this->categoriesCache[$rowData[Product::COL_SKU]][$id] = true; } // 4.1. Tier prices phase @@ -1541,7 +1543,9 @@ protected function _saveProducts() } } foreach ($storeIds as $storeId) { - $attributes[$attrTable][$rowSku][$attrId][$storeId] = $attrValue; + if (!isset($attributes[$attrTable][$rowSku][$attrId][$storeId])) { + $attributes[$attrTable][$rowSku][$attrId][$storeId] = $attrValue; + } } // restore 'backend_model' to avoid 'default' setting $attribute->setBackendModel($backModel); @@ -1574,7 +1578,24 @@ protected function _saveProducts() } /** - * @param $productSku + * @param array $rowData + * @return array + */ + protected function processRowCategories($rowData) + { + $categoriesString = empty($rowData[self::COL_CATEGORY]) ? '' : $rowData[self::COL_CATEGORY]; + $categoryIds = []; + if (!empty($categoriesString)) { + $categoryIds = $this->categoryProcessor->upsertCategories( + $categoriesString, + $this->getMultipleValueSeparator() + ); + } + return $categoryIds; + } + + /** + * @param string $productSku * @return array */ public function getProductWebsites($productSku) @@ -1583,7 +1604,7 @@ public function getProductWebsites($productSku) } /** - * @param $productSku + * @param string $productSku * @return array */ public function getProductCategories($productSku) @@ -1592,7 +1613,7 @@ public function getProductCategories($productSku) } /** - * @param $storeCode + * @param string $storeCode * @return array|int|null|string */ public function getStoreIdByCode($storeCode) @@ -2213,7 +2234,7 @@ private function _setStockUseConfigFieldsValues($rowData) private function _customFieldsMapping($rowData) { foreach ($this->_fieldsMap as $systemFieldName => $fileFieldName) { - if (isset($rowData[$fileFieldName])) { + if (array_key_exists($fileFieldName, $rowData)) { $rowData[$systemFieldName] = $rowData[$fileFieldName]; } } @@ -2221,10 +2242,12 @@ private function _customFieldsMapping($rowData) $rowData = $this->_parseAdditionalAttributes($rowData); $rowData = $this->_setStockUseConfigFieldsValues($rowData); - if (isset($rowData['status'])) { - if (($rowData['status'] == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) || $rowData['status'] == 'yes') { + if (array_key_exists('status', $rowData) + && $rowData['status'] != \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED + ) { + if ($rowData['status'] == 'yes') { $rowData['status'] = \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED; - } else { + } elseif (!empty($rowData['status']) || $this->getRowScope($rowData) == self::SCOPE_DEFAULT) { $rowData['status'] = \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_DISABLED; } } diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php index 8fa6ecc7be945..e071467771a4c 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/CategoryProcessor.php @@ -7,11 +7,6 @@ class CategoryProcessor { - /** - * Delimiter in import file between categories. - */ - const DELIMITER_CATEGORIES = '|'; - /** * Delimiter in category path. */ @@ -144,13 +139,14 @@ protected function upsertCategory($categoryPath) * Returns IDs of categories by string path creating nonexistent ones. * * @param string $categoriesString + * @param string $categoriesSeparator * * @return array */ - public function upsertCategories($categoriesString) + public function upsertCategories($categoriesString, $categoriesSeparator) { $categoriesIds = []; - $categories = explode(self::DELIMITER_CATEGORIES, $categoriesString); + $categories = explode($categoriesSeparator, $categoriesString); foreach ($categories as $category) { $categoriesIds[] = $this->upsertCategory($category); diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php index 3301e3d9fa9c0..66e1efbc2d9a6 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Product/Validator.php @@ -142,7 +142,7 @@ public function isAttributeValid($attrCode, array $attrParams, array $rowData) $values = explode(Product::PSEUDO_MULTI_LINE_SEPARATOR, $rowData[$attrCode]); $valid = true; foreach ($values as $value) { - $valid = $valid || isset($attrParams['options'][strtolower($value)]); + $valid = $valid && isset($attrParams['options'][strtolower($value)]); } if (!$valid) { $this->_addMessages( diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php index a78e978d84c6f..f22d910ccd45e 100644 --- a/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php +++ b/app/code/Magento/CatalogImportExport/Model/Import/Uploader.php @@ -223,7 +223,7 @@ protected function _validateFile() && method_exists($params['object'], $params['method']) && is_callable([$params['object'], $params['method']]) ) { - $params['object']->{$params['method']}($filePath); + $params['object']->{$params['method']}($this->_directory->getAbsolutePath($filePath)); } } } @@ -314,4 +314,12 @@ protected function _moveFile($tmpPath, $destPath) return false; } } + + /** + * {@inheritdoc} + */ + protected function chmod($file) + { + return; + } } diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php index e4ebc3069ef24..7a8bfeef19839 100644 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/CategoryProcessorTest.php @@ -110,7 +110,7 @@ protected function setUp() public function testUpsertCategories() { - $categoryIds = $this->categoryProcessor->upsertCategories(self::CHILD_CATEGORY_NAME); + $categoryIds = $this->categoryProcessor->upsertCategories(self::CHILD_CATEGORY_NAME, ','); $this->assertArrayHasKey(self::CHILD_CATEGORY_ID, array_flip($categoryIds)); } diff --git a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/ValidatorTest.php b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/ValidatorTest.php index c358decc64084..fad86286b1511 100755 --- a/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/ValidatorTest.php +++ b/app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/Product/ValidatorTest.php @@ -83,7 +83,8 @@ public function testIsBooleanAttributeValid() [ 'type' => 'boolean', 'apply_to' => ['simple'], - 'is_required' => false + 'is_required' => false, + 'options' => ['yes' => 0, 'no' => 1] ], [ 'product_type' => 'simple',