/** * @param int $id * @return \Shopware\Models\Shop\Shop $shop * @throws AdapterException * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\TransactionRequiredException */ public function getShop($id) { $shop = $this->modelManager->find('Shopware\\Models\\Shop\\Shop', $id); if (!$shop) { $message = $this->snippetHelper->getNamespace()->get('adapters/articles/no_shop_id', 'Shop by id %s not found'); throw new AdapterException(sprintf($message, $id)); } return $shop; }
/** * Checks whether required fields are filled-in * * @param array $record * @throws AdapterException */ public function checkRequiredFields($record) { foreach ($this->requiredFields as $requiredField => $snippetName) { if (isset($record[$requiredField])) { continue; } $message = SnippetsHelper::getNamespace()->get($snippetName); throw new AdapterException($message); } }
/** * Checks whether required fields are filled-in * * @param array $record * @throws AdapterException */ public function checkRequiredFields($record) { foreach ($this->requiredFields as $key) { if (isset($record[$key])) { continue; } list($snippetName, $snippetMessage) = $this->snippetData[$key]; $message = SnippetsHelper::getNamespace()->get($snippetName, $snippetMessage); throw new AdapterException($message); } }
/** * Helper function, which is used to validate current field's value. * * @param string $type * @param $value * @param string $fieldName * @throws AdapterException * @throws \Exception */ private function validateType($type, $value, $fieldName) { $action = 'validate' . ucfirst($type); if (!is_callable(array($this, $action))) { throw new \Exception('Method with name `' . $action . '` does not exist!'); } $isCorrect = $this->{$action}($value); if (!$isCorrect) { $message = SnippetsHelper::getNamespace()->get('validators/wrong_type', '%s field has to be %s!'); throw new AdapterException(sprintf($message, $fieldName, $type)); } }
/** * Checks whether required fields are filled-in * * @param array $record * @param string $orderNumber * @throws AdapterException */ public function checkRequiredFields($record, $orderNumber) { foreach ($this->requiredFields as $key) { list($price, $priceGroup) = $key; if (!empty($record[$price]) || $record[$priceGroup] !== 'EK') { continue; } $key = $price; list($snippetName, $snippetMessage) = $this->snippetData[$key]; $message = SnippetsHelper::getNamespace()->get($snippetName, $snippetMessage); throw new AdapterException(sprintf($message, $orderNumber)); } }
/** * Checks whether required fields are filled-in * * @param array $record * @throws AdapterException */ public function checkRequiredFields($record) { foreach ($this->requiredFields as $key) { if (is_array($key)) { list($orderId, $number, $orderDetailId) = $key; if (isset($record[$orderId]) || isset($record[$number]) || isset($record[$orderDetailId])) { continue; } $key = $orderId; } elseif (isset($record[$key])) { continue; } list($snippetName, $snippetMessage) = $this->snippetData[$key]; $message = SnippetsHelper::getNamespace()->get($snippetName, $snippetMessage); throw new AdapterException($message); } }
/** * @param array $requestData * @param array $unprocessedFiles * @param string $inputFile * @return array * @throws \Exception */ public function import(array $requestData, array $unprocessedFiles, $inputFile) { $serviceHelpers = $this->buildServiceHelpers($requestData); // set default batchsize for adapter $requestData['batchSize'] = $serviceHelpers->getProfile()->getType() === 'articlesImages' ? 1 : 50; $this->initializeDataIO($serviceHelpers->getDataIO(), $requestData); $dataTransformerChain = $this->createDataTransformerChain($serviceHelpers->getProfile(), $serviceHelpers->getFileReader()->hasTreeStructure()); $sessionState = $serviceHelpers->getSession()->getState(); $dataWorkflow = new DataWorkflow($serviceHelpers->getDataIO(), $serviceHelpers->getProfile(), $dataTransformerChain, $serviceHelpers->getFileReader()); try { $resultData = $dataWorkflow->import($requestData, $inputFile); if (!empty($resultData['unprocessedData'])) { $unprocessedData = ['data' => $resultData['unprocessedData'], 'session' => ['prevState' => $sessionState, 'currentState' => $serviceHelpers->getDataIO()->getSessionState()]]; foreach ($unprocessedData['data'] as $profileName => $value) { $outputFile = $this->uploadPathProvider->getRealPath($this->uploadPathProvider->getFileNameFromPath($inputFile) . '-' . $profileName . '-tmp.csv'); $this->afterImport($unprocessedData, $profileName, $outputFile); $unprocessedFiles[$profileName] = $outputFile; } } if ($serviceHelpers->getSession()->getTotalCount() > 0 && $serviceHelpers->getSession()->getTotalCount() == $resultData['position']) { // unprocessed files $postProcessedData = null; if ($unprocessedFiles) { $postProcessedData = $this->processData($unprocessedFiles); } if ($postProcessedData) { unset($resultData['sessionId']); unset($resultData['adapter']); $resultData = array_merge($resultData, $postProcessedData); } if ($this->logger->getMessage() === null) { $message = sprintf('%s %s %s', $resultData['position'], SnippetsHelper::getNamespace('backend/swag_import_export/default_profiles')->get($resultData['adapter']), SnippetsHelper::getNamespace('backend/swag_import_export/log')->get('import/success')); $session = $serviceHelpers->getSession()->getEntity(); $this->logProcessing('false', $inputFile, $serviceHelpers->getProfile()->getName(), $message, 'true', $session); } } unset($resultData['unprocessedData']); $resultData['unprocessedFiles'] = json_encode($unprocessedFiles); $resultData['importFile'] = $this->uploadPathProvider->getFileNameFromPath($resultData['importFile']); return $resultData; } catch (\Exception $e) { $session = $serviceHelpers->getSession()->getEntity(); $this->logProcessing('true', $inputFile, $serviceHelpers->getProfile()->getName(), $e->getMessage(), 'false', $session); throw $e; } }
/** * Checks whether required fields for create are filled-in * * @param array $record * @throws AdapterException */ public function checkRequiredFieldsForCreate($record) { foreach ($this->requiredFieldsForCreate as $key) { if (is_array($key)) { list($supplierName, $supplierId) = $key; if (isset($record[$supplierName]) || isset($record[$supplierId])) { continue; } $key = $supplierName; } elseif (isset($record[$key]) && !empty($record[$key])) { continue; } list($snippetName, $snippetMessage) = $this->snippetData[$key]; $message = SnippetsHelper::getNamespace()->get($snippetName, $snippetMessage); throw new AdapterException(sprintf($message, $record['mainNumber'])); } }
/** * Checks whether required fields for create are filled-in * * @param array $record * @throws AdapterException */ public function checkRequiredFieldsForCreate($record) { foreach ($this->requiredFieldsForCreate as $columnName) { if (isset($record[$columnName])) { continue; } switch ($columnName) { case 'unhashedPassword': if (isset($record['password']) && isset($record['encoder'])) { continue 2; } break; } list($snippetName, $snippetMessage) = $this->snippetData[$columnName]; $message = SnippetsHelper::getNamespace()->get($snippetName, $snippetMessage); throw new AdapterException(sprintf($message, $record['email'])); } }
/** * @param array $requestData * @param array $filterParams * @return array * @throws \Exception */ public function export(array $requestData, array $filterParams) { $serviceHelpers = $this->buildServiceHelpers($requestData); $requestData['filter'] = $this->prepareFilter($serviceHelpers->getProfile()->getType(), $filterParams); $this->initializeDataIO($serviceHelpers->getDataIO(), $requestData); $dataTransformerChain = $this->createDataTransformerChain($serviceHelpers->getProfile(), $serviceHelpers->getFileWriter()->hasTreeStructure()); $dataWorkflow = new DataWorkflow($serviceHelpers->getDataIO(), $serviceHelpers->getProfile(), $dataTransformerChain, $serviceHelpers->getFileWriter()); $session = $serviceHelpers->getSession()->getEntity(); try { $resultData = $dataWorkflow->export($requestData); $message = sprintf('%s %s %s', $resultData['position'], SnippetsHelper::getNamespace('backend/swag_import_export/default_profiles')->get('type/' . $serviceHelpers->getProfile()->getType()), SnippetsHelper::getNamespace('backend/swag_import_export/log')->get('export/success')); $this->logProcessing('false', $resultData['fileName'], $serviceHelpers->getProfile()->getName(), $message, 'true', $session); unset($resultData['filter']); return $resultData; } catch (\Exception $e) { $this->logProcessing('true', $requestData['fileName'], $serviceHelpers->getProfile()->getName(), $e->getMessage(), 'false', $session); throw $e; } }
/** * @param string $orderNumber * @param string $propertyData * @return array * @throws AdapterException */ private function updateOrCreateOptionAndValuesByValueName($orderNumber, $propertyData) { if (isset($propertyData['propertyOptionId']) && !empty($propertyData['propertyOptionId'])) { //todo: check propertyOptionId existence $optionId = $propertyData['propertyOptionId']; } elseif (isset($propertyData['propertyOptionName']) && !empty($propertyData['propertyOptionName'])) { $optionName = $propertyData['propertyOptionName']; $optionId = $this->getOptionByName($optionName); if (!$optionId) { $optionId = $this->createOption($optionName, $propertyData); } } else { $message = $this->snippetsHelper->getNamespace()->get('adapters/articles/property_option_required', ''); throw new AdapterException(sprintf($message, $orderNumber)); } $valueName = $propertyData['propertyValueName']; $valueId = $this->getValue($valueName, $optionId); if (!$valueId) { $valueId = $this->createValue($propertyData, $valueName, $optionId); } return [$optionId, $valueId]; }
/** * @param array $data * @return mixed|string * @throws AdapterException */ private function getConfiguratorGroup($data) { if (isset($data['configGroupId'])) { if ($this->checkExistence('s_article_configurator_groups', $data['configGroupId'])) { $groupId = $data['configGroupId']; } } if (isset($data['configGroupName']) && !$groupId) { $groupId = $this->getGroupIdByGroupName($data['configGroupName']); if (!$groupId) { $groupPosition = $this->getNextGroupPosition(); $groupData = array('name' => $data['configGroupName'], 'position' => $groupPosition); $groupId = $this->createGroup($groupData); $this->groups[$groupData['name']] = $groupId; } } if (!$groupId) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/provide_groupname_groupid', 'Please provide groupname or groupId'); throw new AdapterException($message); } return $groupId; }
/** * @param string $url URL of the resource that should be loaded (ftp, http, file) * @param string $baseFilename Optional: Instead of creating a hash, create a filename based on the given one * @return bool|string returns the absolute path of the downloaded file * @throws \Exception */ protected function load($url, $baseFilename = null) { if (!is_dir($this->docPath)) { mkdir($this->docPath, 0777, true); } $destPath = realpath($this->docPath); if (!file_exists($destPath)) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesImages/directory_not_found', 'Destination directory %s does not exist.'); throw new \Exception(sprintf($message, $destPath)); } elseif (!is_writable($destPath)) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesImages/directory_permissions', 'Destination directory %s does not have write permissions.'); throw new \Exception(sprintf($message, $destPath)); } $urlArray = parse_url($url); $urlArray['path'] = explode("/", $urlArray['path']); switch ($urlArray['scheme']) { case "ftp": case "http": case "https": case "file": if ($baseFilename === null) { $filename = md5(uniqid(rand(), true)); } else { $filename = $baseFilename; } if (!($put_handle = fopen("{$destPath}/{$filename}", "w+"))) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesImages/could_open_dir_file', 'Could not open %s/%s for writing'); throw new AdapterException(sprintf($message), $destPath, $filename); } //replace empty spaces $url = str_replace(' ', '%20', $url); if (!($get_handle = fopen($url, "r"))) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesImages/could_not_open_url', 'Could not open %s for reading'); throw new AdapterException(sprintf($message, $url)); } while (!feof($get_handle)) { fwrite($put_handle, fgets($get_handle, 4096)); } fclose($get_handle); fclose($put_handle); return "{$destPath}/{$filename}"; } $message = SnippetsHelper::getNamespace()->get('adapters/articlesImages/unsupported_schema', 'Unsupported schema %s.'); throw new AdapterException(sprintf($message, $urlArray['scheme'])); }
/** * Returns number of ids * * @param int $start * @param int $numberOfRecords * @return array * @throws \Exception */ private function loadIds($start, $numberOfRecords) { $storedIds = $this->getRecordIds(); if ($storedIds === null || empty($storedIds)) { $message = SnippetsHelper::getNamespace()->get('dataio/no_loaded_records', 'No loaded record ids'); throw new \Exception($message); } $end = $start + $numberOfRecords; $filterIds = array(); for ($index = $start; $index < $end; $index++) { if (isset($storedIds[$index])) { $filterIds[] = $storedIds[$index]; } } return $filterIds; }
/** * @param array $article * @param array $defaultValues * @return ArticleWriterResult * @throws AdapterException */ protected function insertOrUpdateArticle($article, $defaultValues) { $shouldCreateMainArticle = false; list($mainDetailId, $articleId, $detailId) = $this->findExistingEntries($article); if ($article['processed']) { if (!$mainDetailId) { $mainDetailId = $detailId; } return new ArticleWriterResult($articleId, $detailId, $mainDetailId); } $createDetail = $detailId == 0; // if detail needs to be created and the (different) mainDetail does not exist: error if ($createDetail && !$mainDetailId && !$this->isMainDetail($article)) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/variant_existence', 'Variant with number %s does not exists.'); throw new AdapterException(sprintf($message, $article['mainNumber'])); } // Set create flag if ($createDetail && $this->isMainDetail($article)) { $shouldCreateMainArticle = true; $article = $this->dataManager->setDefaultFieldsForCreate($article, $defaultValues); $this->validator->checkRequiredFieldsForCreate($article); } $article = $this->dataManager->setDefaultFields($article); $this->validator->validate($article, ArticleDataType::$mapper); $article = $this->dataManager->setArticleData($article, ArticleDataType::$articleFieldsMapping); // insert/update main detail article if ($this->isMainDetail($article)) { $articleId = $this->createOrUpdateMainDetail($article, $shouldCreateMainArticle, $articleId); } $article['articleId'] = $articleId; $article['kind'] = $mainDetailId == $detailId ? 1 : 2; list($article, $detailId) = $this->createOrUpdateArticleDetail($article, $defaultValues, $detailId, $createDetail); // set reference if ($shouldCreateMainArticle) { $this->db->query('UPDATE s_articles SET main_detail_id = ? WHERE id = ?', array($detailId, $articleId)); } // insert attributes $this->createArticleAttributes($article, $articleId, $detailId, $shouldCreateMainArticle); if (!$mainDetailId) { $mainDetailId = $detailId; } return new ArticleWriterResult($articleId, $mainDetailId, $detailId); }
/** * @param array $record * @return array * @throws AdapterException * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\TransactionRequiredException * @throws \Exception */ protected function prepareCustomer(array &$record) { if ($this->customerMap === null) { $columns = $this->getCustomerColumns(); $columns = array_merge($columns, ['customer.subshopID as subshopID', 'customer.languageID as languageId']); foreach ($columns as $column) { $map = DataHelper::generateMappingFromColumns($column); if (empty($map)) { continue; } $this->customerMap[$map[0]] = $map[1]; } } $customerData = []; foreach ($record as $key => $value) { if (preg_match('/^attrCustomer/', $key)) { $newKey = lcfirst(preg_replace('/^attrCustomer/', '', $key)); $customerData['attribute'][$newKey] = $value; unset($record[$key]); } elseif (isset($this->customerMap[$key])) { $customerData[$this->customerMap[$key]] = $value; unset($record[$key]); } } if (isset($customerData['groupKey'])) { $customerData['group'] = $this->manager->getRepository(Group::class)->findOneBy(['key' => $customerData['groupKey']]); if (!$customerData['group']) { $message = SnippetsHelper::getNamespace()->get('adapters/customerGroup_not_found', 'Customer Group by key %s not found'); throw new \Exception(sprintf($message, $customerData['groupKey'])); } } if (isset($customerData['hashPassword']) && !empty($customerData['hashPassword'])) { $customerData['rawPassword'] = $customerData['hashPassword']; } unset($record['hashPassword']); return $customerData; }
protected function checkRequirements($price, $orderNumber) { if (!array_key_exists($price['priceGroup'], $this->customerGroups)) { $message = SnippetsHelper::getNamespace()->get('adapters/article_customerGroup_not_found', 'Customer Group by key %s not found for article %s'); throw new AdapterException(sprintf($message, $price['priceGroup'], $orderNumber)); } if ($price['from'] <= 0) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/invalid_price', 'Invalid Price "from" value for article %s'); throw new AdapterException(sprintf($message, $orderNumber)); } }
/** * Executes import action * * @return array */ public function importAction() { /** @var UploadPathProvider $uploadPathProvider */ $uploadPathProvider = Shopware()->Container()->get('swag_import_export.upload_path_provider'); $postData = array('type' => 'import', 'profileId' => (int) $this->profileEntity->getId(), 'importFile' => $this->filePath, 'sessionId' => $this->sessionId, 'format' => $this->format, 'columnOptions' => null, 'limit' => array(), 'filter' => null, 'max_record_count' => null); $inputFile = $postData['importFile']; $logger = $this->getLogger(); // we create the file reader that will read the result file /** @var FileIOFactory $fileFactory */ $fileFactory = $this->Plugin()->getFileIOFactory(); $fileReader = $fileFactory->createFileReader($postData['format']); //load profile /** @var Profile $profile */ $profile = $this->Plugin()->getProfileFactory()->loadProfile($postData); //get profile type $postData['adapter'] = $profile->getType(); //setting up the batch size $postData['batchSize'] = $profile->getType() === 'articlesImages' ? 1 : 50; /** @var DataFactory $dataFactory */ $dataFactory = $this->Plugin()->getDataFactory(); $dbAdapter = $dataFactory->createDbAdapter($profile->getType()); $dataSession = $dataFactory->loadSession($postData); //create dataIO $dataIO = $dataFactory->createDataIO($dbAdapter, $dataSession, $logger); $colOpts = $dataFactory->createColOpts($postData['columnOptions']); $limit = $dataFactory->createLimit($postData['limit']); $filter = $dataFactory->createFilter($postData['filter']); $maxRecordCount = $postData['max_record_count']; $type = $postData['type']; $format = $postData['format']; $dataIO->initialize($colOpts, $limit, $filter, $type, $format, $maxRecordCount); $dataIO->setUsername($this->username); /** @var DataTransformerChain $dataTransformerChain */ $dataTransformerChain = $this->Plugin()->getDataTransformerFactory()->createDataTransformerChain($profile, array('isTree' => $fileReader->hasTreeStructure())); $sessionState = $dataIO->getSessionState(); $dataWorkflow = new DataWorkflow($dataIO, $profile, $dataTransformerChain, $fileReader); try { $post = $dataWorkflow->import($postData, $inputFile); if (isset($post['unprocessedData']) && $post['unprocessedData']) { $data = array('data' => $post['unprocessedData'], 'session' => array('prevState' => $sessionState, 'currentState' => $dataIO->getSessionState())); $pathInfo = pathinfo($inputFile); foreach ($data['data'] as $key => $value) { $outputFile = $uploadPathProvider->getRealPath($pathInfo['filename'] . '-' . $key . '-tmp.csv'); $post['unprocessed'][] = array('profileName' => $key, 'fileName' => $outputFile); $this->afterImport($data, $key, $outputFile); } } $this->sessionId = $post['sessionId']; if ($dataSession->getTotalCount() > 0 && $dataSession->getTotalCount() == $post['position'] && $logger->getMessage() === null) { $message = sprintf('%s %s %s', $post['position'], SnippetsHelper::getNamespace('backend/swag_import_export/default_profiles')->get($post['adapter']), SnippetsHelper::getNamespace('backend/swag_import_export/log')->get('import/success')); $logger->write($message, 'false', $dataSession->getEntity()); $logDataStruct = new LogDataStruct(date("Y-m-d H:i:s"), $inputFile, $profile->getName(), $message, 'false'); $logger->writeToFile($logDataStruct); } return array('success' => true, 'data' => $post); } catch (\Exception $e) { $logger->write($e->getMessage(), 'true', $dataSession->getEntity()); $logDataStruct = new LogDataStruct(date("Y-m-d H:i:s"), $inputFile, $profile->getName(), $e->getMessage(), 'false'); $logger->writeToFile($logDataStruct); throw $e; } }
/** * Transform flat data into tree array * * @param mixed $node * @param array $data * @param null $nodePath * @param int $iteration * @return array * @throws \Exception */ public function transformToTree($node, $data, $nodePath = null, $iteration = 0) { $currentPath = null; if (isset($this->iterationParts[$nodePath])) { // iteration $iteration++; if ($node['adapter'] == 'price') { //find name of column with *price* values $priceColumnName = $this->findNodeByShopwareField($node, 'price'); if ($priceColumnName === false) { throw new \Exception("Price column not found"); } $dataColumns = array_keys($data); $isEkGroupMissing = false; $prices = []; $matches = []; $groups = []; // find groups $priceColumns = preg_grep("/^" . $priceColumnName . "_+(.*)/i", $dataColumns); foreach ($priceColumns as &$columns) { preg_match("/" . $priceColumnName . "_+(?P<group>.*)\$/i", $columns, $matches); $groups[] = $matches['group']; } // special case for EK group ('_EK' may be missing) if (!in_array('EK', $groups)) { array_unshift($groups, 'EK'); $isEkGroupMissing = true; } // TODO: add filters here // extract values foreach ($groups as $group) { // special case for EK group ('_EK' may be missing) if ($group == 'EK' && $isEkGroupMissing) { $group = ''; } $prices[] = $this->transformPricesToTree($node, $data, $group); } return $prices; } elseif ($node['adapter'] == 'configurator') { // find fields $columnMapper = ['configOptionName' => $this->findNodeByShopwareField($node, 'configOptionName'), 'configOptionPosition' => $this->findNodeByShopwareField($node, 'configOptionPosition'), 'configOptionId' => $this->findNodeByShopwareField($node, 'configOptionId'), 'configGroupName' => $this->findNodeByShopwareField($node, 'configGroupName'), 'configSetName' => $this->findNodeByShopwareField($node, 'configSetName'), 'configSetId' => $this->findNodeByShopwareField($node, 'configSetId'), 'configSetType' => $this->findNodeByShopwareField($node, 'configSetType')]; if ($columnMapper['configOptionId'] === false) { if ($columnMapper['configOptionName'] === false) { throw new \Exception("configOptionName column not found"); } if ($columnMapper['configGroupName'] === false) { throw new \Exception("configGroupName column not found"); } } $separator = '|'; if ($columnMapper['configSetId'] !== false) { $configSetId = explode($separator, $this->getDataValue($data, $columnMapper['configSetId'])); $configSetId = $this->getFirstElement($configSetId); } if ($columnMapper['configSetType'] !== false) { $configSetType = explode($separator, $this->getDataValue($data, $columnMapper['configSetType'])); $configSetType = $this->getFirstElement($configSetType); } if ($columnMapper['configSetName'] !== false) { $setNames = explode($separator, $this->getDataValue($data, $columnMapper['configSetName'])); $setNames = $this->getFirstElement($setNames); } if ($columnMapper['configOptionPosition'] !== false) { $positions = explode($separator, $this->getDataValue($data, $columnMapper['configOptionPosition'])); } $configs = []; $values = explode($separator, $this->getDataValue($data, $columnMapper['configOptionName'])); $optionIds = explode($separator, $this->getDataValue($data, $columnMapper['configOptionId'])); //creates configOptionId to have more priority than configOptionName $counter = $columnMapper['configOptionId'] !== false ? count($optionIds) : count($values); for ($i = 0; $i < $counter; $i++) { if (strstr($values[$i], '::')) { $message = SnippetsHelper::getNamespace()->get('transformers/used_colon', "In the group name, is used a colon ':'. Please delete it and try again."); throw new \Exception($message); } $value = explode(':', $values[$i]); $configs[] = $this->transformConfiguratorToTree($node, [$columnMapper['configGroupName'] => $value[0], $columnMapper['configOptionName'] => $value[1], $columnMapper['configOptionPosition'] => $positions[$i], $columnMapper['configOptionId'] => $optionIds[$i], $columnMapper['configSetId'] => $configSetId, $columnMapper['configSetType'] => $configSetType, $columnMapper['configSetName'] => $setNames]); } return $configs; } elseif ($node['adapter'] == 'propertyValue') { $mapper = $this->createMapperFromProfile($node); $columnMapper = ['propertyValueId' => $this->findNodeByShopwareField($node, 'propertyValueId'), 'propertyValueName' => $this->findNodeByShopwareField($node, 'propertyValueName'), 'propertyOptionName' => $this->findNodeByShopwareField($node, 'propertyOptionName'), 'propertyGroupName' => $this->findNodeByShopwareField($node, 'propertyGroupName')]; if ($columnMapper['propertyValueId'] === false) { if ($columnMapper['propertyValueName'] === false) { throw new \Exception("propertyValueName column not found"); } if ($columnMapper['propertyOptionName'] === false) { throw new \Exception("propertyOptionName column not found"); } } foreach ($mapper as $key => $value) { if ($mapper[$key] == 'propertyGroupName') { $propertyGroupName = $this->getDataValue($data, $key); } elseif ($mapper[$key] == 'propertyGroupId') { $propertyGroupId = $this->getDataValue($data, $key); } else { $collectedData[$key] = explode('|', $this->getDataValue($data, $key)); } } unset($collectedData[$columnMapper['propertyOptionName']]); $newData = []; if ($columnMapper['propertyValueId'] !== false) { $counter = count($collectedData[$columnMapper['propertyValueId']]); } else { $counter = count($collectedData[$columnMapper['propertyValueName']]); } foreach ($collectedData as $key => $values) { for ($i = 0; $i < $counter; $i++) { if ($mapper[$key] == 'propertyValueName') { $value = explode(':', $values[$i]); $newData[$i][$columnMapper['propertyOptionName']] = $value[0]; $newData[$i][$key] = $value[1]; } else { $newData[$i][$key] = $values[$i]; } $newData[$i][$columnMapper['propertyGroupName']] = $propertyGroupName; } } return $newData; } elseif ($node['adapter'] === 'translation') { $tempData = []; $translationColumns = []; $dataColumns = array_keys($data); $columns = $this->getAllTranslationColumns(); foreach ($columns as $column) { $tempData[$column] = $this->findNodeByShopwareField($node, $column); if ($tempData[$column]) { $greps = preg_grep('/^' . $tempData[$column] . '_\\d+$/i', $dataColumns); $translationColumns = array_merge($translationColumns, $greps); } } unset($tempData); $translationLang = $this->findNodeByShopwareField($node, 'languageId'); foreach ($translationColumns as $column) { preg_match("/(?P<column>.*)_+(?P<langId>.*)\$/i", $column, $matches); $columnName = $matches['column']; $translations[$matches['langId']][$columnName] = $data[$column]; if ($translationLang) { $translations[$matches['langId']][$translationLang] = $matches['langId']; } } return $translations; } elseif ($node['adapter'] != $this->getMainAdapter()) { $mapper = $this->createMapperFromProfile($node); foreach ($mapper as $key => $value) { $collectedData[$key] = $this->getDataValue($data, $key); } $newData = []; foreach ($collectedData as $key => $groupValue) { $values = explode('|', $groupValue); foreach ($values as $index => $value) { $newData[$index][$key] = $value; } } return $newData; } } if (isset($node['children'])) { if (isset($node['attributes'])) { foreach ($node['attributes'] as $attribute) { $currentNode['_attributes'][$attribute['name']] = $this->getDataValue($data, $attribute['name'], $iteration); } } foreach ($node['children'] as $child) { $currentPath = $nodePath . '/' . $child['name']; $dataValue = $this->transformToTree($child, $data, $currentPath); if ($dataValue !== null) { $currentNode[$child['name']] = $dataValue; } } } else { if (isset($node['attributes'])) { foreach ($node['attributes'] as $attribute) { $currentNode['_attributes'][$attribute['name']] = $this->getDataValue($data, $attribute['name'], $iteration); } $currentNode['_value'] = $this->getDataValue($data, $node['name'], $iteration); } else { $currentNode = $this->getDataValue($data, $node['name'], $iteration); } } return $currentNode; }
/** * Custom cronjob for import */ public function cronAction() { /** @var UploadPathProvider $uploadPathProvider */ $uploadPathProvider = $this->get('swag_import_export.upload_path_provider'); $directory = $uploadPathProvider->getPath(UploadPathProvider::CRON_DIR); $allFiles = scandir($directory); $files = array_diff($allFiles, ['.', '..']); $lockerFilename = '__running'; $lockerFileLocation = $directory . $lockerFilename; if (in_array($lockerFilename, $files)) { $file = fopen($lockerFileLocation, "r"); $fileContent = (int) fread($file, filesize($lockerFileLocation)); fclose($file); if ($fileContent > time()) { echo "There is already an import in progress.\n"; return; } else { unlink($lockerFileLocation); } } if ($files === false || count($files) == 0) { echo "No import files are found\n"; return; } //Create empty file to flag cron as running $timeout = time() + 1800; $file = fopen($lockerFileLocation, "w"); fwrite($file, $timeout); fclose($file); $manager = $this->getModelManager(); $profileRepository = $manager->getRepository(Profile::class); foreach ($files as $file) { $fileExtension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); $fileName = strtolower(pathinfo($file, PATHINFO_FILENAME)); if ($fileExtension == 'xml' || $fileExtension == 'csv') { try { $profile = CommandHelper::findProfileByName($file, $profileRepository); if ($profile === false) { $message = SnippetsHelper::getNamespace()->get('cronjob/no_profile', 'No profile found %s'); throw new \Exception(sprintf($message, $fileName)); } $mediaPath = $uploadPathProvider->getRealPath($file, UploadPathProvider::CRON_DIR); } catch (\Exception $e) { echo $e->getMessage() . "\n"; unlink($lockerFileLocation); return; } try { $return = $this->start($profile, $mediaPath, $fileExtension); $profilesMapper = ['articles', 'articlesImages']; //loops the unprocessed data $pathInfo = pathinfo($mediaPath); foreach ($profilesMapper as $profileName) { $tmpFile = $uploadPathProvider->getRealPath($pathInfo['filename'] . '-' . $profileName . '-tmp.csv', UploadPathProvider::CRON_DIR); if (file_exists($tmpFile)) { $outputFile = str_replace('-tmp', '-swag', $tmpFile); rename($tmpFile, $outputFile); $profile = $this->profileFactory->loadHiddenProfile($profileName); $profileEntity = $profile->getEntity(); $this->start($profileEntity, $outputFile, 'csv'); } } $message = $return['data']['position'] . ' ' . $return['data']['adapter'] . " imported successfully \n"; echo $message; unlink($mediaPath); } catch (\Exception $e) { // copy file as broken $brokenFilePath = $uploadPathProvider->getRealPath('broken-' . $file, UploadPathProvider::DIR); copy($mediaPath, $brokenFilePath); echo $e->getMessage() . "\n"; unlink($lockerFileLocation); return; } } } unlink($lockerFileLocation); }
/** * @throws \Exception */ protected function isRootExists() { $sql = "SELECT id FROM s_categories WHERE id = 1"; $rootId = $this->db->fetchOne($sql); if (false === $rootId) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/root_category_does_not_exist', 'Root category does not exist'); throw new \Exception($message); } }
/** * @param integer $articleId * @param string $mainOrderNumber * @param array $relations * @param string $relationType * @param integer $processedFlag * @throws AdapterException */ public function write($articleId, $mainOrderNumber, $relations, $relationType, $processedFlag) { if (!is_numeric($articleId)) { return; } $this->initializeRelationData($relationType); $newRelations = []; $allRelations = []; foreach ($relations as $relation) { //if relation data has only 'parentIndexElement' element if (count($relation) < 2) { break; } if ((!isset($relation[$this->idKey]) || !$relation[$this->idKey]) && (!isset($relation['ordernumber']) || !$relation['ordernumber'])) { $this->deleteAllRelations($articleId); continue; } if (isset($relation['ordernumber']) && $relation['ordernumber']) { $relationId = $this->getRelationIdByOrderNumber($relation['ordernumber']); if (!$relationId && $processedFlag === true) { $message = SnippetsHelper::getNamespace()->get($this->snippetName, $this->defaultSnippetMessage); throw new AdapterException(sprintf($message, $relation['ordernumber'])); } if (!$relationId) { $data = ['articleId' => $mainOrderNumber, 'ordernumber' => $relation['ordernumber']]; $this->getArticlesDbAdapter()->saveUnprocessedData('articles', strtolower($relationType), $mainOrderNumber, $data); continue; } $relation[$this->idKey] = $relationId; } if (!$this->isRelationIdExists($relation[$this->idKey])) { continue; } if (!$this->isRelationExists($relation[$this->idKey], $articleId)) { $newRelations[] = $relation; } $allRelations[] = $relation; } if ($allRelations && !$processedFlag) { //delete the relations that don't exist in the csv file, but exist in the db" $this->deleteRelations($allRelations, $articleId); } if ($newRelations) { $this->insertRelations($newRelations, $articleId); //insert only new relations } }
/** * @param array $records * @throws \Exception */ private function validateRecordsShouldNotBeEmpty($records) { if (empty($records)) { $message = SnippetsHelper::getNamespace()->get('adapters/categories/no_records', 'No category records were found.'); throw new \Exception($message); } }
/** * @param $records * @throws \Exception */ public function write($records) { $message = SnippetsHelper::getNamespace()->get('adapters/mainOrders/use_order_profile_for_import', 'This is only an export profile. Please use `Orders` profile for imports!'); throw new \Exception($message); }
/** * @param float $taxRate * @param string $orderNumber * @return mixed * @throws AdapterException */ private function getTaxByTaxRate($taxRate, $orderNumber) { $taxRate = number_format($taxRate, 2); $taxId = array_search($taxRate, $this->getTaxRates()); if (!$taxId) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/no_tax_found', "Tax by tax rate %s not found for article %s."); throw new AdapterException(sprintf($message, $taxRate, $orderNumber)); } return $taxId; }
/** * @param $records * @throws AdapterException * @throws \Doctrine\ORM\ORMException * @throws \Doctrine\ORM\OptimisticLockException * @throws \Doctrine\ORM\TransactionRequiredException * @throws \Enlight_Event_Exception * @throws \Exception */ public function write($records) { if (empty($records['default'])) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesTranslations/no_records', 'No article translation records were found.'); throw new \Exception($message); } $records = $this->eventManager->filter('Shopware_Components_SwagImportExport_DbAdapters_ArticlesTranslationsDbAdapter_Write', $records, ['subject' => $this]); $whiteList = ['name', 'description', 'descriptionLong', 'metaTitle', 'keywords']; $variantWhiteList = ['additionalText', 'packUnit']; $whiteList = array_merge($whiteList, $variantWhiteList); if (!SwagVersionHelper::isDeprecated('5.3.0')) { $elementBuilder = $this->getElementBuilder(); $legacyAttributes = $elementBuilder->getQuery()->getArrayResult(); if ($legacyAttributes) { foreach ($legacyAttributes as $attr) { $whiteList[] = $attr['name']; $variantWhiteList[] = $attr['name']; } } } $attributes = $this->getAttributes(); if ($attributes) { foreach ($attributes as $attribute) { $whiteList[] = $attribute['columnName']; $variantWhiteList[] = $attribute['columnName']; } } $articleDetailRepository = $this->manager->getRepository(Detail::class); $shopRepository = $this->manager->getRepository(Shop::class); foreach ($records['default'] as $index => $record) { try { $record = $this->validator->filterEmptyString($record); $this->validator->checkRequiredFields($record); $this->validator->validate($record, ArticleTranslationValidator::$mapper); $shop = false; if (isset($record['languageId'])) { $shop = $shopRepository->find($record['languageId']); } if (!$shop) { $message = SnippetsHelper::getNamespace()->get('adapters/articlesTranslations/lang_id_not_found', 'Language with id %s does not exists for article %s'); throw new AdapterException(sprintf($message, $record['languageId'], $record['articleNumber'])); } $articleDetail = $articleDetailRepository->findOneBy(['number' => $record['articleNumber']]); if (!$articleDetail) { $message = SnippetsHelper::getNamespace()->get('adapters/article_number_not_found', 'Article with order number %s doen not exists'); throw new AdapterException(sprintf($message, $record['articleNumber'])); } $articleId = $articleDetail->getArticle()->getId(); if ($articleDetail->getKind() === 1) { $data = array_intersect_key($record, array_flip($whiteList)); $type = 'article'; $objectKey = $articleId; } else { $data = array_intersect_key($record, array_flip($variantWhiteList)); $type = 'variant'; $objectKey = $articleDetail->getId(); } if (!empty($data)) { $data = $this->prepareAttributePrefix($data, $attributes); $this->translationComponent->write($shop->getId(), $type, $objectKey, $data); } } catch (AdapterException $e) { $message = $e->getMessage(); $this->saveMessage($message); } } }
/** * @param array $records * @throws \Enlight_Event_Exception * @throws \Exception */ public function write($records) { if (empty($records['default'])) { $message = SnippetsHelper::getNamespace()->get('adapters/newsletter/no_records', 'No newsletter records were found.'); throw new \Exception($message); } $records = Shopware()->Events()->filter('Shopware_Components_SwagImportExport_DbAdapters_CategoriesDbAdapter_Write', $records, ['subject' => $this]); $defaultValues = $this->getDefaultValues(); /** @var EntityRepository $addressRepository */ $addressRepository = $this->manager->getRepository(Address::class); /** @var EntityRepository $groupRepository */ $groupRepository = $this->manager->getRepository(Group::class); /** @var EntityRepository $contactDataRepository */ $contactDataRepository = $this->manager->getRepository(ContactData::class); $count = 0; foreach ($records['default'] as $newsletterData) { try { $count++; $newsletterData = $this->validator->filterEmptyString($newsletterData); $this->validator->checkRequiredFields($newsletterData); $recipient = $addressRepository->findOneBy(['email' => $newsletterData['email']]); if ($recipient instanceof Address && empty($newsletterData['groupName'])) { continue; } if (!$recipient instanceof Address) { $newsletterData = $this->dataManager->setDefaultFieldsForCreate($newsletterData, $defaultValues); $recipient = new Address(); } $this->validator->validate($newsletterData, NewsletterDataType::$mapper); if ($newsletterData['groupName']) { /** @var Group $group */ $group = $groupRepository->findOneBy(['name' => $newsletterData['groupName']]); if (!$group instanceof Group) { $group = new Group(); $group->setName($newsletterData['groupName']); $this->manager->persist($group); $this->manager->flush($group); } $newsletterData['groupId'] = $group->getId(); } // save newsletter address $newsletterAddress = $this->prepareNewsletterAddress($newsletterData); $recipient->fromArray($newsletterAddress); $this->manager->persist($recipient); if ($recipient->getGroupId() !== 0) { // save mail data $contactData = $contactDataRepository->findOneBy(['email' => $newsletterData['email']]); if (!$contactData instanceof ContactData) { $contactData = new ContactData(); $contactData->setAdded(new \DateTime()); $this->manager->persist($contactData); } $contactData->fromArray($newsletterData); } if ($count % 20 === 0) { $this->manager->flush(); } } catch (AdapterException $e) { $message = $e->getMessage(); $this->saveMessage($message); } } $this->manager->flush(); }
/** * Update order * * @param array $records * @throws \Exception */ public function write($records) { $records = Shopware()->Events()->filter('Shopware_Components_SwagImportExport_DbAdapters_OrdersDbAdapter_Write', $records, ['subject' => $this]); if (empty($records['default'])) { $message = SnippetsHelper::getNamespace()->get('adapters/orders/no_records', 'No order records were found.'); throw new \Exception($message); } $orderRepository = $this->modelManager->getRepository(Detail::class); $orderStatusRepository = $this->modelManager->getRepository(Status::class); $orderDetailStatusRepository = $this->modelManager->getRepository(DetailStatus::class); foreach ($records['default'] as $index => $record) { try { $record = $this->validator->filterEmptyString($record); $this->validator->checkRequiredFields($record); $this->validator->validate($record, OrderValidator::$mapper); if (isset($record['orderDetailId']) && $record['orderDetailId']) { /** @var \Shopware\Models\Order\Detail $orderDetailModel */ $orderDetailModel = $orderRepository->find($record['orderDetailId']); } else { $orderDetailModel = $orderRepository->findOneBy(['number' => $record['number']]); } if (!$orderDetailModel) { $message = SnippetsHelper::getNamespace()->get('adapters/orders/order_detail_id_not_found', 'Order detail id %s was not found'); throw new AdapterException(sprintf($message, $record['orderDetailId'])); } $orderModel = $orderDetailModel->getOrder(); if (isset($record['paymentId']) && is_numeric($record['paymentId'])) { $paymentStatusModel = $orderStatusRepository->find($record['cleared']); if (!$paymentStatusModel) { $message = SnippetsHelper::getNamespace()->get('adapters/orders/payment_status_id_not_found', 'Payment status id %s was not found for order %s'); throw new AdapterException(sprintf($message, $record['cleared'], $orderModel->getNumber())); } $orderModel->setPaymentStatus($paymentStatusModel); } if (isset($record['status']) && is_numeric($record['status'])) { $orderStatusModel = $orderStatusRepository->find($record['status']); if (!$orderStatusModel) { $message = SnippetsHelper::getNamespace()->get('adapters/orders/status_not_found', 'Status %s was not found for order %s'); throw new AdapterException(sprintf($message, $record['status'], $orderModel->getNumber())); } $orderModel->setOrderStatus($orderStatusModel); } if (isset($record['trackingCode'])) { $orderModel->setTrackingCode($record['trackingCode']); } if (isset($record['comment'])) { $orderModel->setComment($record['comment']); } if (isset($record['customerComment'])) { $orderModel->setCustomerComment($record['customerComment']); } if (isset($record['internalComment'])) { $orderModel->setInternalComment($record['internalComment']); } if (isset($record['transactionId'])) { $orderModel->setTransactionId($record['transactionId']); } if (isset($record['clearedDate'])) { $orderModel->setClearedDate($record['clearedDate']); } if (isset($record['shipped'])) { $orderDetailModel->setShipped($record['shipped']); } if (isset($record['statusId']) && is_numeric($record['statusId'])) { $detailStatusModel = $orderDetailStatusRepository->find($record['statusId']); if (!$detailStatusModel) { $message = SnippetsHelper::getNamespace()->get('adapters/orders/detail_status_not_found', 'Detail status with id %s was not found'); throw new AdapterException(sprintf($message, $record['statusId'])); } $orderDetailModel->setStatus($detailStatusModel); } //prepares the attributes foreach ($record as $key => $value) { if (preg_match('/^attribute/', $key)) { $newKey = lcfirst(preg_replace('/^attribute/', '', $key)); $orderData['attribute'][$newKey] = $value; unset($record[$key]); } } if ($orderData) { $orderModel->fromArray($orderData); } $this->modelManager->persist($orderModel); unset($orderDetailModel); unset($orderModel); unset($orderData); } catch (AdapterException $e) { $message = $e->getMessage(); $this->saveMessage($message); } } $this->modelManager->flush(); }
/** * Returns newsletter default group name. * * @param string $email * @param string $groupName * @return string * @throws AdapterException */ private function getGroupName($email, $groupName) { $group = $this->groupRepository->findOneBy(['name' => $groupName]); if ($group) { return $group->getName(); } $groupId = $this->config->get("sNEWSLETTERDEFAULTGROUP"); $group = $this->groupRepository->find($groupId); if (!$group instanceof Group) { $message = SnippetsHelper::getNamespace()->get('adapters/newsletter/group_required', 'Group is required for email %s'); throw new AdapterException(sprintf($message, $email)); } return $group->getName(); }
/** * @param $articleId * @param $mainDetailOrderNumber * @param $images * @throws AdapterException */ public function write($articleId, $mainDetailOrderNumber, $images) { $newImages = array(); foreach ($images as $image) { //if image data has only 'parentIndexElement' element if (count($image) < 2) { break; } if (empty($image['mediaId']) && empty($image['path']) && empty($image['imageUrl'])) { continue; } if (isset($image['mediaId']) && !empty($image['mediaId'])) { $media = $this->getMediaById($image['mediaId']); $image['path'] = $media['name']; } elseif (isset($image['path']) && !empty($image['path'])) { $media = $this->getMediaByName($image['path']); } elseif (isset($image['imageUrl']) && !empty($image['imageUrl'])) { $name = pathinfo($image['imageUrl'], PATHINFO_FILENAME); $media = $this->getMediaByName($name); $image['path'] = $name; // if data comes from article adapter prepare data for hidden profile if (!$media) { $thumbnail = isset($image['thumbnail']) && $image['thumbnail'] == 0 ? 0 : 1; $data = array('ordernumber' => $mainDetailOrderNumber, 'image' => $image['imageUrl'], 'thumbnail' => $thumbnail); // set unprocessed data to use hidden profile for articleImages $this->getArticlesDbAdapter()->setUnprocessedData('articlesImages', 'default', $data); } } if (!$media) { continue; } $image['mediaId'] = $media['id']; if (!$this->isImageExists($articleId, $image['mediaId'])) { $newImages['medias'][] = $media; $newImages['images'][] = $image; $isImageNameCorrect = $this->isImageNameCorrect($image['mediaId'], $image['path']); if (!$isImageNameCorrect) { $message = SnippetsHelper::getNamespace()->get('adapters/articles/image_not_found', 'Image with name %s could not be found'); throw new AdapterException(sprintf($message, $image['path'])); } } } if ($newImages) { $this->insertImages($newImages, $articleId); //insert only new images } }