objStoreMgr = \Magento\Framework\App\ObjectManager::getInstance()->get('\Magento\Store\Model\StoreManagerInterface'); $this->entityType = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Eav\Model\Entity\Type')->loadByCode('catalog_product'); } public function processImport($arrData, $options = array()) { if (!count($arrData)) { return; } $objResponse = $this->objResponse; $intStartTime = $objResponse->microtimeFloat(); $this->updateAttributes($arrData); $objResponse->addLogEntry('Finish attributes import', 'global', 'attributes', $objResponse->getDuration($intStartTime)); } function updateAttributes($arrData) { if (isset($arrData['attributeset'])) { array_walk($arrData['attributeset'], array($this, 'createAttributeSet')); } if (isset($arrData['attributes'])) { array_walk($arrData['attributes'], array($this, 'createAttribute')); } if ($arrData['attributeset_attributes']) { array_walk($arrData['attributeset_attributes'], array($this, 'removeAttributesFromAttributeSet')); } } protected function getDefaultAttributsetId() { static $id = null; if ($id === null) { $id = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Catalog\Model\Product')->getDefaultAttributeSetid(); } return $id; } protected function createAttributeSet($arrAttibuteSet, $copyGroupsFromID = -1) { $setName = trim($arrAttibuteSet['attribute_set_name'] ?? ''); if ($setName === '') { $this->logError("Could not create attribute set with an empty name."); return false; } $objAttributeset = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute\Set'); $this->logInfo("create/update attribute-set with name [" . $setName . "] and entity-type [" . $this->entityType->getId() . "]", 'global', 'attributes', -1); $attribute_set_id = $this->getAttributesetByName($setName)->getId(); $arrData = [ 'attribute_set_id' => $attribute_set_id, 'attribute_set_name' => $setName, 'entity_type_id' => $this->entityType->getId(), //'sort_order' => 1, ]; $objAttributeset->setData($arrData); $objAttributeset->validate(); $objAttributeset->save(); $objAttributeset->initFromSkeleton($this->getDefaultAttributsetId()); $objAttributeset->save(); if (!$objAttributeset->getId()) { $this->logError("Could not save AttributeSet: " . $setName); return false; } return true; } protected function getAttributesetByName($strAttributesetName) { static $cache = array(); //$a = new \Magento\Eav\Model\Entity\Attribute\Set(); if (!isset($cache[$strAttributesetName])) { $objAttributeset = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute\Set'); $objAttributeset->load($strAttributesetName, 'attribute_set_name'); $cache[$strAttributesetName] = $objAttributeset; } return $cache[$strAttributesetName]; } function removeAttributesFromAttributeSet($arrAttributesSend = array(), $strSetName = '') { if (!$strSetName) { return false; } $arrCurrentSet = $this->getAttributesForAttributset($strSetName); $intCurrentSetId = key($arrCurrentSet); $arrCurrentSetAttributes = reset($arrCurrentSet); //$arrCheck = array_diff_key($arrCurrentSet, $arrDefaultSet); $arrDelete = array_diff_key($arrCurrentSetAttributes, array_flip($arrAttributesSend)); $attributeSet = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute\Set')->load($intCurrentSetId); /* All attributes which are not in Default or given attribute set will deleted */ if ($attributeSet->getId() && !empty($arrDelete)) { foreach ((array) $arrDelete as $strAttrCode => $attribute) { if (!$attribute->getId()) { continue; } $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet(); $attribute->deleteEntity(); $this->logInfo("Remove Attribute: " . $strAttrCode . " [" . $attribute->getID() . "] from set " . $strSetName); } } return true; } private function getAttributesForAttributset($strSetName = 'Default', $bOnlyUserDefined = true) { $arrAttributes = array(); $attributeSetId = $this->getAttributesetByName($strSetName)->getId(); $attributeManagementInterface = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Api\AttributeManagementInterface'); if ($attributeSetId == 1) { $attributeSetId = 4; } $arrTmp = $attributeManagementInterface->getAttributes(\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE, $attributeSetId); foreach ((array) $arrTmp as $arrAttribute) { if ($bOnlyUserDefined && !$arrAttribute->getData('is_user_defined')) { continue; } $arrAttributes[$arrAttribute->getData('attribute_code')] = $arrAttribute; } return array($attributeSetId => $arrAttributes); } public static function getExistingFile($destinationPath, $newFile) { $fileInfo = pathinfo($newFile); $intNewFileSize = filesize($newFile); $strNewHash = md5_file($newFile); $baseName = $fileInfo['filename'] . '.' . $fileInfo['extension']; $index = 1; while (file_exists($destinationPath . '/' . $baseName)) { if (filesize($destinationPath . '/' . $baseName) === $intNewFileSize && md5_file($destinationPath . '/' . $baseName) === $strNewHash) { return $baseName; } $baseName = $fileInfo['filename'] . '_' . $index . '.' . $fileInfo['extension']; $index++; } return false; } protected function prepareImagesForSwatchAttriute($strImportDir, $arrSwatchImages) { $filesystem = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Framework\Filesystem'); $mediaDirectory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem\DirectoryList::MEDIA); $productMediaConfig = \Magento\Framework\App\ObjectManager::getInstance()->get('Magento\Catalog\Model\Product\Media\Config'); $fullTmpMediaPath = $mediaDirectory->getAbsolutePath($productMediaConfig->getBaseTmpMediaPath()); $driverFile = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Framework\Filesystem\Driver\File'); $driverFile->createDirectory($fullTmpMediaPath); $swatchHelper = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Swatches\Helper\Media'); $arrReturn = []; foreach ($arrSwatchImages as $intSwatchOptionID => $mixImage) { $strImage = is_array($mixImage) ? reset($mixImage) : $mixImage; $strImportImage = $strImportDir . DIRECTORY_SEPARATOR . $strImage; if (is_file($strImportImage)) { $strExistingFile = self::getExistingFile($mediaDirectory->getAbsolutePath($swatchHelper->getSwatchMediaPath() . '/'), $strImportImage); if ($strExistingFile !== false) { $newFile = DIRECTORY_SEPARATOR . $strExistingFile; } else { $driverFile->copy($strImportImage, $fullTmpMediaPath . '/' . basename($strImage)); $newFile = ltrim($swatchHelper->moveImageFromTmp(basename($strImage)), '.'); } $swatchHelper->generateSwatchVariations($newFile); } else { $newFile = (substr($strImage, 0, 1) == '#' && strlen($strImage) == 7) ? $strImage : '#ffffff'; } $arrReturn[$intSwatchOptionID] = $newFile; } return $arrReturn; } protected function createAttribute($values = array(), $productTypes = array(), $setInfo = -1) { $arrStoreLabels = $values['frontend_label']; $values['frontend_label'] = trim(reset($values['frontend_label'])); if (isset($values['backend_model'])) $values['backend_model'] = $this->getBackendModel($values['backend_model']); if (isset($values['source_model'])) $values['source_model'] = $this->getSourceModel($values['source_model']); $labelText = $values['frontend_label']; $attributeCode = trim($values['attribute_code']); if ($labelText == '' || $attributeCode == '') { $this->logError("Can't import the attribute with an empty label or code. LABEL= [$labelText] CODE= [$attributeCode]"); return false; } $strAttrGroup = 'General'; if (isset($values['attribute_group_name'])) { $strAttrGroup = reset($values['attribute_group_name']); } $arrAttrSets = array(); if (isset($values['attribute_set'])) { $arrAttrSets = $values['attribute_set']; } unset($values['attribute_set']); if (isset($values['attribute_group_name'])) { $strAttrGroup = reset($values['attribute_group_name']); } unset($values['attribute_group_name']); $values['entity_type_id'] = $this->entityType->getId(); $values['is_user_defined'] = 1; if (isset($values['apply_to']) && $values['apply_to'] == -1) $values['apply_to'] = ''; //unset($values['source_model']); if ($setInfo !== -1 && (isset($setInfo['SetID']) == false || isset($setInfo['GroupID']) == false)) { $this->logError("Please provide both the set-ID and the group-ID of the attribute-set if you'd like to subscribe to one."); return false; } //$attribute = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute'); $attribute = \Magento\Framework\App\ObjectManager::getInstance()->create(AttributeFactory::class)->create(); $values['modulePrefix'] = 'Magento_Catalog'; // $attribute = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Catalog\Model\Entity\Attribute'); $attribute->loadByCode('catalog_product', $attributeCode); $values['attribute_id'] = $attribute->getId(); foreach ((array) $arrStoreLabels as $strStoreView => $arrStoreLabel) { $intStoreID = $strStoreView == 'default' ? 0 : $this->objStoreMgr->getStore($strStoreView)->getId(); $values['store_labels'][$intStoreID] = $arrStoreLabels[$strStoreView]; $values['frontend_labels'][$intStoreID] = $arrStoreLabels[$strStoreView]; } $arrOptions = $values['options'] ?? []; $arrSwatchOptions = $values['swatch'] ?? []; unset($values['options']); unset($values['swatch']); $attribute->setData($values); $attribute->save(); if ($attribute->getId() < 1) { $this->logError("Attribute [$labelText] could not be saved!"); return; } $values['option'] = $this->prepareAttributeOptions($attribute, $arrOptions); $values['attribute_id'] = $attribute->getId(); $attribute->setData($values); $attribute->save(); if (count($arrSwatchOptions)) { $attribute = \Magento\Framework\App\ObjectManager::getInstance()->create(AttributeFactory::class)->create(); $values['modulePrefix'] = 'Magento_Catalog'; $attribute->loadByCode('catalog_product', $attributeCode); if ($values['swatch_input_type'] === 'text') { $values['optiontext'] = $this->prepareAttributeOptions($attribute, $arrSwatchOptions['optiontext'] ?? []) ?? []; $values['swatchtext']['value'] = $this->prepareAttributeOptions($attribute, $arrSwatchOptions['swatchtext'] ?? [])['value'] ?? []; } else if ($values['swatch_input_type'] === 'visual') { $objImageImport = \Magento\Framework\App\ObjectManager::getInstance()->get('saws\sawsconnector\Model\Import\SawsConnector\Factory')->create('images'); if (isset($arrSwatchOptions['images'])) { $objImageImport->downloadImages($arrSwatchOptions['images']); } $arrSwatchImages = $this->prepareAttributeOptions($attribute, $arrSwatchOptions['swatchvisual'] ?? [])['value'] ?? []; $values['swatchvisual']['value'] = $this->prepareImagesForSwatchAttriute($objImageImport->getImageDir(), $arrSwatchImages); $values['optionvisual'] = $this->prepareAttributeOptions($attribute, $arrSwatchOptions['optionvisual'] ?? []) ?? []; } // $values['additional_data']['update_product_preview_image'] = $arrSwatchOptions['update_product_preview_image'] ?? '0'; // $values['additional_data']['use_product_image_for_swatch'] = $arrSwatchOptions['use_product_image_for_swatch'] ?? '0'; unset($values['option']); $attribute->setData($values); $attribute->save(); } foreach ((array) $arrAttrSets as $strAttrSet) { $objAttributeset = $this->getAttributesetByName($strAttrSet); $objMg = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute\Group'); $arrGroups = $objMg->getCollection(); $arrGroupsFiltered = $arrGroups->addFieldToFilter("attribute_set_id", $objAttributeset->getId())->getItems(); $intGroupId = 0; //$objAttributeset->getDefaultGroupId(); foreach ($arrGroupsFiltered as $attributeGroup) { if ($attributeGroup->getAttributeGroupName() === $strAttrGroup) { $intGroupId = $attributeGroup->getAttributeGroupId(); } } if (!$intGroupId) { //create a new group $objMg->setAttributeGroupName($strAttrGroup)->setAttributeSetId($objAttributeset->getId())->setSortOrder(100); $objMg->save(); $intGroupId = $objMg->getAttributeGroupId(); $this->logInfo("Create new group for $strAttrGroup with ID (" . $objMg->getAttributeGroupId() . ")"); } $intSort = isset($values['sort_order'][$strAttrSet]) ? $values['sort_order'][$strAttrSet] : 0; \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\AttributeManagement') ->assign('catalog_product', $objAttributeset->getId(), $intGroupId, $attributeCode, $intSort); } return true; } // protected function addAttributeToSets($strAttributeCode, $arrAttributeSets, $strAttributeGroupName, $intSortOrder = 0) { // // foreach ((array) $arrAttributeSets as $strAttrSet) { // $objAttributeset = $this->getAttributesetByName($strAttrSet); // // $objMg = \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\Entity\Attribute\Group'); // $arrGroups = $objMg->getCollection(); // $arrGroupsFiltered = $arrGroups->addFieldToFilter("attribute_set_id", $objAttributeset->getId())->getItems(); // // $intGroupId = 0; //$objAttributeset->getDefaultGroupId(); // foreach ($arrGroupsFiltered as $attributeGroup) { // if ($attributeGroup->getAttributeGroupName() === $strAttributeGroupName) { // $intGroupId = $attributeGroup->getAttributeGroupId(); // } // } // // if (!$intGroupId) { // //create a new group // $objMg->setAttributeGroupName($strAttributeGroupName)->setAttributeSetId($objAttributeset->getId())->setSortOrder(100); // $objMg->save(); // $intGroupId = $objMg->getAttributeGroupId(); // $this->logInfo("Create new group for $strAttributeGroupName with ID (" . $objMg->getAttributeGroupId() . ")"); // } // // \Magento\Framework\App\ObjectManager::getInstance()->create('Magento\Eav\Model\AttributeManagement') // ->assign('catalog_product', $objAttributeset->getId(), $intGroupId, $strAttributeCode, $intSortOrder); // } // } protected function prepareAttributeOptions($attribute, $options) { if (!is_array($options) || !count($options)) { return []; } $arrOptionMap = array(); $arrMagOptions = $attribute->getSource()->getAllOptions(false, true); foreach ((array) $arrMagOptions as $arrMagOpt) { if (!is_array($arrMagOpt)) { continue; } if ($arrMagOpt['label'] && !is_array($arrMagOpt['label']) && !is_object($arrMagOpt['label'])) { $arrOptionMap[$arrMagOpt['label']] = $arrMagOpt['value']; } } $arrMagOptions = array(); $intSortOrder = 0; foreach ((array) $options as $strAdminKey => $arrStoreValues) { if (array_key_exists($strAdminKey, $arrOptionMap)) { $strAdminKey1 = $arrOptionMap[$strAdminKey]; unset($arrOptionMap[$strAdminKey]); $strAdminKey = $strAdminKey1; } else { $strAdminKey = 'new_' . strval($strAdminKey); } $arrMagOptions['value'][$strAdminKey] = array(); foreach ((array) $arrStoreValues as $strStoreViewKey => $strOptionValue) { $intStoreID = ($strStoreViewKey === "default") ? 0 : $this->objStoreMgr->getStore($strStoreViewKey)->getId(); $arrMagOptions['value'][$strAdminKey][$intStoreID] = $strOptionValue; $arrMagOptions['order'][$strAdminKey] = $intSortOrder; } $intSortOrder++; } if (is_array($arrOptionMap) && (count($arrOptionMap) > 0)) { /* delete unused options */ foreach ((array) $arrOptionMap as $iOptID) { if ($iOptID > 0) { $arrMagOptions['value'][$iOptID] = true; $arrMagOptions['delete'][$iOptID] = true; } } } return $arrMagOptions; } function replaceStoreViewCodes($arrValues, $bolAddDefault = true) { $bolFoundDefault = false; $arrRetValue = array(); foreach ($arrValues as $strKey => $strVal) { $intStoreID = $this->objStoreMgr->getStore($strKey)->getId(); if (!$intStoreID && !$bolFoundDefault) { $intStoreID = 0; } $arrRetValue[$intStoreID] = $strVal; if ($intStoreID == 0) { $bolFoundDefault = true; } } if (!$bolFoundDefault && $bolAddDefault) { $arrRetValue[0] = reset($arrValues); } return $arrRetValue; } protected function getBackendModel($strModel = '') { if (!$strModel) { return ''; } return str_replace( array('eav/entity_attribute_backend_array'), array('Magento\Eav\Model\Entity\Attribute\Backend\ArrayBackend'), $strModel); } protected function getSourceModel($strModel = '') { if (!$strModel) { return ''; } return str_replace( array('eav/entity_attribute_source_boolean', 'eav/entity_attribute_source_table'), array('Magento\Catalog\Model\Product\Attribute\Source\Boolean', ''), $strModel); } }