dataDifferenceCalculator = $dataDifferenceCalculator; $this->processFactory = $processFactory; $this->storeManager = $storeManager; $this->cacheManager = $cacheManager; $this->resource = $resource; } /** * Imports the store data into the application. * After the import it flushes the store caches. * * {@inheritdoc} */ public function import(array $data) { $actions = [ ProcessorFactory::TYPE_CREATE, ProcessorFactory::TYPE_DELETE, ProcessorFactory::TYPE_UPDATE ]; $messages = ['Stores were processed']; try { $newGroups = $this->getGroupsToCreate($data); if ($newGroups) { $messages[] = sprintf( $this->getStoreGroupAssignMessage(), implode(', ', array_column($newGroups, 'name')) ); } // during import websites/stores database already has new entities // but cache is outdated which can cause to error in some cases $this->reinitStores(); $this->resource->beginTransaction(); foreach ($actions as $action) { $this->processFactory->create($action)->run($data); } } catch (\Exception $exception) { $this->resource->rollBack(); $this->reinitStores(); throw new InvalidTransitionException(__('%1', $exception->getMessage()), $exception); } $this->resource->commit(); $this->reinitStores(); return $messages; } /** * Reinitialize store list. * * @return void */ private function reinitStores() { $this->storeManager->reinitStores(); $this->cacheManager->clean(); } /** * Retrieves message reminder about root category assigning. * * @return string */ private function getStoreGroupAssignMessage() { return 'The following new store groups must be associated with a root category: %s. ' . PHP_EOL . 'Associate a store group with a root category in the Admin Panel: Stores > Settings > All Stores.'; } /** * Checks which new store groups will be created. * * @param array $data The data set. * @return array */ private function getGroupsToCreate(array $data) { if (!isset($data[ScopeInterface::SCOPE_GROUPS])) { return []; } $groups = $this->dataDifferenceCalculator->getItemsToCreate( ScopeInterface::SCOPE_GROUPS, $data[ScopeInterface::SCOPE_GROUPS] ); return $groups; } /** * Retrieves all affected entities during the import procedure. * * {@inheritdoc} */ public function getWarningMessages(array $data) { $messages = []; foreach ($data as $scope => $scopeData) { $messageMap = [ 'These %s will be deleted: %s' => $this->dataDifferenceCalculator->getItemsToDelete($scope, $scopeData), 'These %s will be updated: %s' => $this->dataDifferenceCalculator->getItemsToUpdate($scope, $scopeData), 'These %s will be created: %s' => $this->dataDifferenceCalculator->getItemsToCreate($scope, $scopeData), ]; foreach ($messageMap as $message => $items) { if (!$items) { continue; } $messages[] = $this->formatMessage($message, $items, $scope); } } return $messages; } /** * Formats message to appropriate format. * * @param string $message The message to display * @param array $items The items to be used * @param string $scope The given scope * @return string */ private function formatMessage($message, array $items, $scope) { return sprintf( $message, ucfirst($scope), implode(', ', array_column($items, 'name')) ); } }