searchResultsFactory = $searchResultsFactory; $this->synonymFactory = $synonymFactory; $this->synonymResource = $synonymResource; $this->synonymCollectionFactory = $synonymCollectionFactory; } /** * @inheritdoc */ public function save(SynonymInterface $synonym) { try { if ($synonym->getSynonymId()) { $synonym = $this->getById($synonym->getSynonymId())->addData($synonym->getData()); } $this->synonymResource->save($synonym); unset($this->synonyms[$synonym->getSynonymId()]); } catch (AlreadyExistsException $e) { throw new AlreadyExistsException(__($e->getMessage())); } catch (\Exception $e) { if ($synonym->getSynonymId()) { throw new CouldNotSaveException( __( 'Unable to save synonym with ID %1. Error: %2', [$synonym->getSynonymId(), $e->getMessage()] ) ); } throw new CouldNotSaveException(__('Unable to save new synonym. Error: %1', $e->getMessage())); } return $synonym; } /** * @inheritdoc */ public function getById($synonymId) { if (!isset($this->synonyms[$synonymId])) { /** @var \Amasty\ElasticSearch\Model\Synonym $synonym */ $synonym = $this->synonymFactory->create(); $this->synonymResource->load($synonym, $synonymId); if (!$synonym->getSynonymId()) { throw new NoSuchEntityException(__('Synonym with specified ID "%1" not found.', $synonymId)); } $this->synonyms[$synonymId] = $synonym; } return $this->synonyms[$synonymId]; } /** * @inheritdoc */ public function delete(SynonymInterface $synonym) { try { $this->synonymResource->delete($synonym); unset($this->synonyms[$synonym->getSynonymId()]); } catch (\Exception $e) { if ($synonym->getSynonymId()) { throw new CouldNotDeleteException( __( 'Unable to remove synonym with ID %1. Error: %2', [$synonym->getSynonymId(), $e->getMessage()] ) ); } throw new CouldNotDeleteException(__('Unable to remove synonym. Error: %1', $e->getMessage())); } return true; } /** * @inheritdoc */ public function deleteById($synonymId) { $synonymModel = $this->getById($synonymId); $this->delete($synonymModel); return true; } /** * @inheritdoc */ public function getList(SearchCriteriaInterface $searchCriteria) { $searchResults = $this->searchResultsFactory->create(); $searchResults->setSearchCriteria($searchCriteria); /** @var \Amasty\ElasticSearch\Model\ResourceModel\Synonym\Collection $synonymCollection */ $synonymCollection = $this->synonymCollectionFactory->create(); // Add filters from root filter group to the collection foreach ($searchCriteria->getFilterGroups() as $group) { $this->addFilterGroupToCollection($group, $synonymCollection); } $searchResults->setTotalCount($synonymCollection->getSize()); $sortOrders = $searchCriteria->getSortOrders(); if ($sortOrders) { $this->addOrderToCollection($sortOrders, $synonymCollection); } $synonymCollection->setCurPage($searchCriteria->getCurrentPage()); $synonymCollection->setPageSize($searchCriteria->getPageSize()); $synonyms = []; /** @var SynonymInterface $synonym */ foreach ($synonymCollection->getItems() as $synonym) { $synonyms[] = $this->getById($synonym->getId()); } $searchResults->setItems($synonyms); return $searchResults; } /** * Helper function that adds a FilterGroup to the collection. * * @param FilterGroup $filterGroup * @param Collection $synonymCollection * * @return void */ private function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $synonymCollection) { foreach ($filterGroup->getFilters() as $filter) { $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq'; $synonymCollection->addFieldToFilter($filter->getField(), [$condition => $filter->getValue()]); } } /** * Helper function that adds a SortOrder to the collection. * * @param SortOrder[] $sortOrders * @param Collection $synonymCollection * * @return void */ private function addOrderToCollection($sortOrders, Collection $synonymCollection) { /** @var SortOrder $sortOrder */ foreach ($sortOrders as $sortOrder) { $field = $sortOrder->getField(); $synonymCollection->addOrder( $field, ($sortOrder->getDirection() == SortOrder::SORT_DESC) ? 'DESC' : 'ASC' ); } } /** * @param string $query * @param int $storeId * @return array */ public function getSynonymsByQuery($query, $storeId) { $result = []; if (!$query) { return $result; } $queryArray = explode(' ', $query); $queryArray = array_map('trim', $queryArray); foreach ($queryArray as &$item) { $item = str_replace(',', '', $item); } $queryArray = array_filter($queryArray); if (!$queryArray) { return $result; } $searchString = $this->generateSearchPattern($queryArray); $terms = $this->getArrayTermsByConditions($searchString, $storeId); if (!$terms) { return $result; } foreach ($queryArray as $word) { $search = $this->generateSearchPattern([$word]); $search = '/' . $search . '/i'; $resultWord = [$word]; foreach ($terms as $term) { if (preg_match($search, $term)) { $term = explode(',', $term); $term = array_map('trim', $term); $term = array_filter($term); // phpcs:ignore Magento2.Performance.ForeachArrayMerge.ForeachArrayMerge $resultWord = array_merge($resultWord, $term); } } $result[] = array_unique($resultWord); } return $result; } /** * @param array $queryArray * @return string */ private function generateSearchPattern(array $queryArray) { $patterns = []; foreach ($queryArray as $word) { $patterns[] = '^' . $word . ','; $patterns[] = ',' . $word . ','; $patterns[] = ',' . $word . '$'; } $pattern = implode('|', $patterns); return $pattern; } /** * @param $searchString * @param $storeId * @return array */ private function getArrayTermsByConditions($searchString, $storeId) { $terms = []; $collection = $this->synonymCollectionFactory->create() ->addFieldToFilter(SynonymInterface::STORE_ID, $storeId) ->addSearchStringFilter($searchString); foreach ($collection as $term) { $terms[] = $term->getTerm(); } return $terms; } }