Exemplo n.º 1
0
 /**
  * {@inheritdoc}
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  */
 public function isValid($value)
 {
     $this->_clearMessages();
     $emptyCategory = empty($value[Product::COL_CATEGORY]);
     $emptyRootCategory = empty($value[Product::COL_ROOT_CATEGORY]);
     $hasCategory = $emptyCategory ? false : $this->categoryProcessor->getCategory($value[Product::COL_CATEGORY]) !== null;
     $category = $emptyRootCategory ? null : $this->categoryProcessor->getCategoryWithRoot($value[Product::COL_ROOT_CATEGORY]);
     if (!$emptyCategory && !$hasCategory || !$emptyRootCategory && !isset($category) || !$emptyRootCategory && !$emptyCategory && !isset($category[$value[Product::COL_CATEGORY]])) {
         $this->_addMessages([self::ERROR_INVALID_CATEGORY]);
         return false;
     }
     return true;
 }
Exemplo n.º 2
0
 /**
  * Gather and save information about product entities.
  *
  * @return $this
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  * @SuppressWarnings(PHPMD.NPathComplexity)
  * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
  */
 protected function _saveProducts()
 {
     /** @var $resource \Magento\CatalogImportExport\Model\Import\Proxy\Product\Resource */
     $resource = $this->_resourceFactory->create();
     $priceIsGlobal = $this->_catalogData->isPriceGlobal();
     $productLimit = null;
     $productsQty = null;
     while ($bunch = $this->_dataSourceModel->getNextBunch()) {
         $entityRowsIn = [];
         $entityRowsUp = [];
         $attributes = [];
         $websites = [];
         $categories = [];
         $tierPrices = [];
         $groupPrices = [];
         $mediaGallery = [];
         $uploadedGalleryFiles = [];
         $previousType = null;
         $prevAttributeSet = null;
         foreach ($bunch as $rowNum => $rowData) {
             if (!$this->validateRow($rowData, $rowNum)) {
                 continue;
             }
             $rowScope = $this->getRowScope($rowData);
             if (self::SCOPE_DEFAULT == $rowScope) {
                 $rowSku = $rowData[self::COL_SKU];
                 // 1. Entity phase
                 if (isset($this->_oldSku[$rowSku])) {
                     // existing row
                     $entityRowsUp[] = ['updated_at' => (new \DateTime())->format(DateTime::DATETIME_PHP_FORMAT), 'entity_id' => $this->_oldSku[$rowSku]['entity_id']];
                 } else {
                     // new row
                     if (!$productLimit || $productsQty < $productLimit) {
                         $entityRowsIn[$rowSku] = ['attribute_set_id' => $this->skuProcessor->getNewSku($rowSku)['attr_set_id'], 'type_id' => $this->skuProcessor->getNewSku($rowSku)['type_id'], 'sku' => $rowSku, 'has_options' => isset($rowData['has_options']) ? $rowData['has_options'] : 0, 'created_at' => (new \DateTime())->format(DateTime::DATETIME_PHP_FORMAT), 'updated_at' => (new \DateTime())->format(DateTime::DATETIME_PHP_FORMAT)];
                         $productsQty++;
                     } else {
                         $rowSku = null;
                         // sign for child rows to be skipped
                         $this->_rowsToSkip[$rowNum] = true;
                         continue;
                     }
                 }
             } elseif (null === $rowSku) {
                 $this->_rowsToSkip[$rowNum] = true;
                 // skip rows when SKU is NULL
                 continue;
             } elseif (self::SCOPE_STORE == $rowScope) {
                 // set necessary data from SCOPE_DEFAULT row
                 $rowData[self::COL_TYPE] = $this->skuProcessor->getNewSku($rowSku)['type_id'];
                 $rowData['attribute_set_id'] = $this->skuProcessor->getNewSku($rowSku)['attr_set_id'];
                 $rowData[self::COL_ATTR_SET] = $this->skuProcessor->getNewSku($rowSku)['attr_set_code'];
             }
             // 2. Product-to-Website phase
             if (!empty($rowData['_product_websites'])) {
                 $websites[$rowSku][$this->storeResolver->getWebsiteCodeToId($rowData['_product_websites'])] = true;
             }
             // 3. Categories phase
             $categoryPath = empty($rowData[self::COL_CATEGORY]) ? '' : $rowData[self::COL_CATEGORY];
             if (!empty($rowData[self::COL_ROOT_CATEGORY])) {
                 $categoryId = $this->categoryProcessor->getCategoryWithRoot($rowData[self::COL_ROOT_CATEGORY], $categoryPath);
                 $categories[$rowSku][$categoryId] = true;
             } elseif (!empty($categoryPath)) {
                 $categories[$rowSku][$this->categoryProcessor->getCategory($categoryPath)] = true;
             }
             // 4.1. Tier prices phase
             if (!empty($rowData['_tier_price_website'])) {
                 $tierPrices[$rowSku][] = ['all_groups' => $rowData['_tier_price_customer_group'] == self::VALUE_ALL, 'customer_group_id' => $rowData['_tier_price_customer_group'] == self::VALUE_ALL ? 0 : $rowData['_tier_price_customer_group'], 'qty' => $rowData['_tier_price_qty'], 'value' => $rowData['_tier_price_price'], 'website_id' => self::VALUE_ALL == $rowData['_tier_price_website'] || $priceIsGlobal ? 0 : $this->storeResolver->getWebsiteCodeToId($rowData['_tier_price_website'])];
             }
             // 4.2. Group prices phase
             if (!empty($rowData['_group_price_website'])) {
                 $groupPrices[$rowSku][] = ['all_groups' => $rowData['_group_price_customer_group'] == self::VALUE_ALL, 'customer_group_id' => $rowData['_group_price_customer_group'] == self::VALUE_ALL ? 0 : $rowData['_group_price_customer_group'], 'value' => $rowData['_group_price_price'], 'website_id' => self::VALUE_ALL == $rowData['_group_price_website'] || $priceIsGlobal ? 0 : $this->storeResolver->getWebsiteCodeToId($rowData['_group_price_website'])];
             }
             // 5. Media gallery phase
             foreach ($this->_imagesArrayKeys as $imageCol) {
                 if (!empty($rowData[$imageCol])) {
                     if (!array_key_exists($rowData[$imageCol], $uploadedGalleryFiles)) {
                         $uploadedGalleryFiles[$rowData[$imageCol]] = $this->_uploadMediaFiles($rowData[$imageCol]);
                     }
                     $rowData[$imageCol] = $uploadedGalleryFiles[$rowData[$imageCol]];
                 }
             }
             if (!empty($rowData['_media_image'])) {
                 $mediaGallery[$rowSku][] = ['attribute_id' => $rowData['_media_attribute_id'], 'label' => $rowData['_media_label'], 'position' => $rowData['_media_position'], 'disabled' => $rowData['_media_is_disabled'], 'value' => $rowData['_media_image']];
             }
             // 6. Attributes phase
             $rowStore = self::SCOPE_STORE == $rowScope ? $this->storeResolver->getStoreCodeToId($rowData[self::COL_STORE]) : 0;
             $productType = isset($rowData[self::COL_TYPE]) ? $rowData[self::COL_TYPE] : null;
             if (!is_null($productType)) {
                 $previousType = $productType;
             }
             if (isset($rowData[self::COL_ATTR_SET])) {
                 $prevAttributeSet = $rowData[self::COL_ATTR_SET];
             }
             if (self::SCOPE_NULL == $rowScope) {
                 // for multiselect attributes only
                 if (!is_null($prevAttributeSet)) {
                     $rowData[self::COL_ATTR_SET] = $prevAttributeSet;
                 }
                 if (is_null($productType) && !is_null($previousType)) {
                     $productType = $previousType;
                 }
                 if (is_null($productType)) {
                     continue;
                 }
             }
             if ($this->getBehavior() == \Magento\ImportExport\Model\Import::BEHAVIOR_APPEND || empty($rowData[self::COL_SKU])) {
                 $rowData = $this->_productTypeModels[$productType]->clearEmptyData($rowData);
             }
             $rowData = $this->_productTypeModels[$productType]->prepareAttributesWithDefaultValueForSave($rowData, !isset($this->_oldSku[$rowSku]));
             $product = $this->_proxyProdFactory->create(['data' => $rowData]);
             foreach ($rowData as $attrCode => $attrValue) {
                 $attribute = $resource->getAttribute($attrCode);
                 if ('multiselect' != $attribute->getFrontendInput() && self::SCOPE_NULL == $rowScope) {
                     // skip attribute processing for SCOPE_NULL rows
                     continue;
                 }
                 $attrId = $attribute->getId();
                 $backModel = $attribute->getBackendModel();
                 $attrTable = $attribute->getBackend()->getTable();
                 $storeIds = [0];
                 if ('datetime' == $attribute->getBackendType() && strtotime($attrValue)) {
                     $attrValue = (new \DateTime())->setTimestamp(strtotime($attrValue));
                     $attrValue = $attrValue->format(DateTime::DATETIME_PHP_FORMAT);
                 } elseif ($backModel) {
                     $attribute->getBackend()->beforeSave($product);
                     $attrValue = $product->getData($attribute->getAttributeCode());
                 }
                 if (self::SCOPE_STORE == $rowScope) {
                     if (self::SCOPE_WEBSITE == $attribute->getIsGlobal()) {
                         // check website defaults already set
                         if (!isset($attributes[$attrTable][$rowSku][$attrId][$rowStore])) {
                             $storeIds = $this->storeResolver->getStoreIdToWebsiteStoreIds($rowStore);
                         }
                     } elseif (self::SCOPE_STORE == $attribute->getIsGlobal()) {
                         $storeIds = [$rowStore];
                     }
                 }
                 foreach ($storeIds as $storeId) {
                     if ('multiselect' == $attribute->getFrontendInput()) {
                         if (!isset($attributes[$attrTable][$rowSku][$attrId][$storeId])) {
                             $attributes[$attrTable][$rowSku][$attrId][$storeId] = '';
                         } else {
                             $attributes[$attrTable][$rowSku][$attrId][$storeId] .= ',';
                         }
                         $attributes[$attrTable][$rowSku][$attrId][$storeId] .= $attrValue;
                     } else {
                         $attributes[$attrTable][$rowSku][$attrId][$storeId] = $attrValue;
                     }
                 }
                 // restore 'backend_model' to avoid 'default' setting
                 $attribute->setBackendModel($backModel);
             }
         }
         $this->_saveProductEntity($entityRowsIn, $entityRowsUp)->_saveProductWebsites($websites)->_saveProductCategories($categories)->_saveProductTierPrices($tierPrices)->_saveProductGroupPrices($groupPrices)->_saveMediaGallery($mediaGallery)->_saveProductAttributes($attributes);
     }
     return $this;
 }