searchResultFactory = $searchResultFactory ?? ObjectManager::getInstance()->get(SearchResultFactory::class); parent::__construct( $entityFactory, $logger, $fetchStrategy, $eventManager, $eavConfig, $resource, $eavEntityFactory, $resourceHelper, $universalFactory, $storeManager, $moduleManager, $catalogProductFlatState, $scopeConfig, $productOptionFactory, $catalogUrl, $localeDate, $customerSession, $dateTime, $groupManagement, $connection ); $this->temporaryStorageFactory = $temporaryStorageFactory; $this->searchRequestName = $searchRequestName; $this->_scopeConfig = $scopeConfig; $this->_productMetadata = $productMetadata; $this->_isMTwoOneVersion(); } /** * WeltPixel LayeredNavigation Clone collection * * @return \WeltPixel\LayeredNavigation\Model\ResourceModel\Fulltext\Collection|null */ public function getCollectionClone() { if ($this->collectionClone === null) { $this->collectionClone = clone $this; $this->collectionClone->setSearchCriteriaBuilder($this->searchCriteriaBuilder->cloneObject()); } $searchCriterialBuilder = $this->collectionClone->getSearchCriteriaBuilder()->cloneObject(); /** @var \WeltPixel\LayeredNavigation\Model\ResourceModel\Fulltext\Collection $collectionClone */ $collectionClone = clone $this->collectionClone; $collectionClone->setSearchCriteriaBuilder($searchCriterialBuilder); return $collectionClone; } /** * WeltPixel LayeredNavigation Add multi-filter categories * * @param $categories * @return $this */ public function addLayerCategoryFilter($categories) { $this->addFieldToFilter('category_ids', implode(',', $categories)); return $this; } /** * WeltPixel LayeredNavigation remove filter to load option item data * * @param $attributeCode * @return $this */ public function removeAttributeSearch($attributeCode) { if (is_array($attributeCode)) { foreach ($attributeCode as $attCode) { $this->searchCriteriaBuilder->removeFilter($attCode); } } else { $this->searchCriteriaBuilder->removeFilter($attributeCode); } $this->_isFiltersRendered = false; return $this->loadWithFilter(); } /** * WeltPixel LayeredNavigation Get attribute condition sql * * @param $attribute * @param $condition * @param string $joinType * @return string */ public function getAttributeConditionSql($attribute, $condition, $joinType = 'inner') { return $this->_getAttributeConditionSql($attribute, $condition, $joinType); } /** * WeltPixel LayeredNavigation Reset Total records * * @return $this */ public function resetTotalRecords($collectionCount = null) { $this->_totalRecords = $collectionCount; return $this; } /** * @return int|void */ public function getSize() { return sizeof($this->getAllIds()); } /** * @return \Magento\Search\Api\SearchInterface|mixed */ private function getSearch() { if ($this->search === null) { $this->search = ObjectManager::getInstance()->get('\Magento\Search\Api\SearchInterface'); } return $this->search; } /** * @param \Magento\Search\Api\SearchInterface $object */ public function setSearch(\Magento\Search\Api\SearchInterface $object) { $this->search = $object; } /** * @return mixed|\WeltPixel\LayeredNavigation\Model\ResourceModel\Search\SearchCriteriaBuilder */ public function getSearchCriteriaBuilder() { if ($this->searchCriteriaBuilder === null) { $this->searchCriteriaBuilder = ObjectManager::getInstance() ->get('\WeltPixel\LayeredNavigation\Model\ResourceModel\Search\SearchCriteriaBuilder'); } return $this->searchCriteriaBuilder; } /** * @param \WeltPixel\LayeredNavigation\Model\ResourceModel\Search\SearchCriteriaBuilder $object */ public function setSearchCriteriaBuilder(\WeltPixel\LayeredNavigation\Model\ResourceModel\Search\SearchCriteriaBuilder $object) { $this->searchCriteriaBuilder = $object; } /** * @return \Magento\Framework\Api\FilterBuilder|mixed */ private function getFilterBuilder() { if ($this->filterBuilder === null) { $this->filterBuilder = ObjectManager::getInstance()->get('\Magento\Framework\Api\FilterBuilder'); } return $this->filterBuilder; } /** * @param \Magento\Framework\Api\FilterBuilder $object */ public function setFilterBuilder(\Magento\Framework\Api\FilterBuilder $object) { $this->filterBuilder = $object; } /** * Apply attribute filter to facet collection * * @param string $field * @param null $condition * @return $this */ public function addFieldToFilter($field, $condition = null) { if ($this->searchResult !== null) { throw new \RuntimeException('Illegal state'); } $this->getSearchCriteriaBuilder(); $this->getFilterBuilder(); if (is_array($condition) && $this->_isElasticOrOpenSearchEngine()) { $this->filterBuilder->setField($field); $this->filterBuilder->setValue($condition); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } elseif (!is_array($condition) || !in_array(key($condition), ['from', 'to'])) { $this->filterBuilder->setField($field); $this->filterBuilder->setValue($condition); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } else { if (!empty($condition['from'])) { $this->filterBuilder->setField("{$field}.from"); $this->filterBuilder->setValue($condition['from']); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } if (!empty($condition['to'])) { $this->filterBuilder->setField("{$field}.to"); $this->filterBuilder->setValue($condition['to']); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } } return $this; } /** * Add search query filter * * @param string $query * @return $this */ public function addSearchFilter($query) { $this->queryText = trim($this->queryText . ' ' . $query); return $this; } /** * @inheritdoc */ protected function _renderFiltersBefore() { $this->getCollectionClone(); $this->getSearchCriteriaBuilder(); $this->getFilterBuilder(); $this->getSearch(); if ($this->queryText) { $this->filterBuilder->setField('search_term'); $this->filterBuilder->setValue($this->queryText); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } $priceRangeCalculation = $this->_scopeConfig->getValue( \Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory::XML_PATH_RANGE_CALCULATION, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); if ($priceRangeCalculation) { $this->filterBuilder->setField('price_dynamic_algorithm'); $this->filterBuilder->setValue($priceRangeCalculation); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } if ($this->_isTwoOne) { $this->filterBuilder->setField('category_ids'); $this->filterBuilder->setValue($this->_categoryId); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } $searchCriteria = $this->searchCriteriaBuilder->create(); $searchCriteria->setRequestName($this->searchRequestName); if ($this->_isElasticOrOpenSearchEngine()) { if ($this->order && isset($this->order['field'])) { $fieldValue = explode("~", $this->order['field']); } else { $fieldValue = []; $fieldValue[0]=null; } if (!$fieldValue[0]) { $searchCriteria->setSortOrders([ 'entity_id' => 'DESC' ]); } else { $searchCriteria->setSortOrders([ $fieldValue[0] => $this->order['dir'] ]); } } try { $this->searchResult = $this->getSearch()->search($searchCriteria); } catch (EmptyRequestDataException $e) { /** @var \Magento\Framework\Api\Search\SearchResultInterface $searchResult */ $this->searchResult = $this->searchResultFactory->create()->setItems([]); } catch (\Exception $e) { throw new LocalizedException(__('Something went wrong, check and test your Search Engine configurations, reindex catalog and clear cache. Thrown error: %1', $e->getMessage())); } try { $temporaryStorage = $this->temporaryStorageFactory->create(); $table = $temporaryStorage->storeDocuments($this->searchResult->getItems()); $this->getSelect()->joinInner( [ 'search_result' => $table->getName(), ], 'e.entity_id = search_result.' . TemporaryStorage::FIELD_ENTITY_ID, [] ); if ($this->order && 'relevance' === $this->order['field']) { $this->getSelect()->order('search_result.' . TemporaryStorage::FIELD_SCORE . ' ' . $this->order['dir']); } } catch (\Exception $ex) { $this->_logger->error($ex->getMessage()); } parent::_renderFiltersBefore(); } /** * @return $this */ protected function _renderFilters() { $this->_filters = []; return parent::_renderFilters(); } /** * Set Order field * * @param string $attribute * @param string $dir * @return $this */ public function setOrder($attribute, $dir = Select::SQL_DESC) { $this->order = ['field' => $attribute, 'dir' => $dir]; if ($attribute != 'relevance') { parent::setOrder($attribute, $dir); } return $this; } /** * Stub method for compatibility with other search engines * * @return $this */ public function setGeneralDefaultQuery() { return $this; } /** * Return field faceted data from faceted search result * * @param string $field * @return array * @throws StateException */ public function getFacetedData($field) { $this->_renderFilters(); $result = []; $aggregations = $this->searchResult->getAggregations(); if (null !== $aggregations) { $bucket = $aggregations->getBucket($field . RequestGenerator::BUCKET_SUFFIX); if ($bucket) { foreach ($bucket->getValues() as $value) { $metrics = $value->getMetrics(); $result[$metrics['value']] = $metrics; } } else { throw new StateException(__('Bucket does not exist')); } } return $result; } /** * Specify category filter for product collection * * @param \Magento\Catalog\Model\Category $category * @return $this */ public function addCategoryFilter(\Magento\Catalog\Model\Category $category) { $this->_categoryId = $category->getId(); $this->addFieldToFilter('category_ids', $category->getId()); return parent::addCategoryFilter($category); } /** * Set product visibility filter for enabled products * * @param array $visibility * @return $this */ public function setVisibility($visibility) { $this->addFieldToFilter('visibility', $visibility); return parent::setVisibility($visibility); } /** * Check the engine provider is 'elasticsearch' * @deprecated * * @return bool */ protected function _isElasticSearchEngine() { $currentEngine = $this->_scopeConfig->getValue(EngineInterface::CONFIG_ENGINE_PATH, ScopeInterface::SCOPE_STORE); if ($currentEngine == 'elasticsearch' || $currentEngine == 'elasticsearch5' || $currentEngine == 'elasticsearch6' || $currentEngine == 'elasticsearch7' || $currentEngine == 'elasticsearch8') { return true; } return false; } /** * Check the engine provider is 'elasticsearch' or 'opensearch' * * @return bool */ protected function _isElasticOrOpenSearchEngine() { $currentEngine = $this->_scopeConfig->getValue(EngineInterface::CONFIG_ENGINE_PATH, ScopeInterface::SCOPE_STORE); if ($currentEngine == 'elasticsearch' || $currentEngine == 'elasticsearch5' || $currentEngine == 'elasticsearch6' || $currentEngine == 'elasticsearch7' || $currentEngine == 'opensearch') { return true; } return false; } /** * check magento version * @return bool */ protected function _isMTwoOneVersion() { $version = $this->_productMetadata->getVersion(); $pos = strpos($version, '2.1'); if ($pos === false) { $this->_isTwoOne = false; } else { $this->_isTwoOne = true; } return $this->_isTwoOne; } }