temporaryStorageFactory = $temporaryStorageFactory; $this->searchRequestName = $searchRequestName; } /** * MP LayerNavigation Clone collection * * @return \Mageplaza\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 \Mageplaza\LayeredNavigation\Model\ResourceModel\Fulltext\Collection $collectionClone */ $collectionClone = clone $this->collectionClone; $collectionClone->setSearchCriteriaBuilder($searchCriterialBuilder); return $collectionClone; } /** * MP LayerNavigation Add multi-filter categories * * @param $categories * @return $this */ public function addLayerCategoryFilter($categories) { if ($this->getSearchEngine() == 'elasticsearch') { $this->addFieldToFilter('category_ids', ['in' => $categories]); } else { $this->addFieldToFilter('category_ids', implode(',', $categories)); } return $this; } /** * MP LayerNavigation 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(); } /** * MP LayerNavigation 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); } /** * MP LayerNavigation Reset Total records * * @return $this */ public function resetTotalRecords() { $this->_totalRecords = null; return $this; } /** * @deprecated * @return \Magento\Search\Api\SearchInterface */ private function getSearch() { if ($this->search === null) { $this->search = ObjectManager::getInstance()->get('\Magento\Search\Api\SearchInterface'); } return $this->search; } /** * @deprecated * @param \Magento\Search\Api\SearchInterface $object * @return void */ public function setSearch(\Magento\Search\Api\SearchInterface $object) { $this->search = $object; } /** * @deprecated * @return \Mageplaza\LayeredNavigation\Model\Search\SearchCriteriaBuilder */ public function getSearchCriteriaBuilder() { if ($this->searchCriteriaBuilder === null) { $this->searchCriteriaBuilder = ObjectManager::getInstance() ->get('\Mageplaza\LayeredNavigation\Model\Search\SearchCriteriaBuilder'); } return $this->searchCriteriaBuilder; } /** * @param \Mageplaza\LayeredNavigation\Model\Search\SearchCriteriaBuilder $object */ public function setSearchCriteriaBuilder(\Mageplaza\LayeredNavigation\Model\Search\SearchCriteriaBuilder $object) { $this->searchCriteriaBuilder = $object; } /** * @deprecated * @return \Magento\Framework\Api\FilterBuilder */ private function getFilterBuilder() { if ($this->filterBuilder === null) { $this->filterBuilder = ObjectManager::getInstance()->get('\Magento\Framework\Api\FilterBuilder'); } return $this->filterBuilder; } /** * @deprecated * @param \Magento\Framework\Api\FilterBuilder $object * @return void */ 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 (isset($condition['in']) && $this->getSearchEngine() == 'elasticsearch') { $this->filterBuilder->setField($field); $this->filterBuilder->setValue($condition['in']); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } else { if (!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('auto'); $this->searchCriteriaBuilder->addFilter($this->filterBuilder->create()); } $searchCriteria = $this->searchCriteriaBuilder->create(); $searchCriteria->setRequestName($this->searchRequestName); try { $this->searchResult = $this->getSearch()->search($searchCriteria); } catch (\Exception $e) { throw new LocalizedException(__('Sorry, something went wrong. You can find out more in the error log.')); } $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']); } parent::_renderFiltersBefore(); } /** * @return $this */ protected function _renderFilters() { $this->_filters = []; return parent::_renderFilters(); } /** * sort product before load */ protected function _beforeLoad() { $this->setOrder('entity_id'); return parent::_beforeLoad(); } /** * 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(); // This behavior is for case with empty object when we got EmptyRequestDataException 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->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); } /** * Get Search Engine Config * * @return string */ public function getSearchEngine() { return $this->_scopeConfig->getValue( \Magento\Config\Model\Config\Backend\Admin\Custom::XML_PATH_CATALOG_SEARCH_ENGINE, \Magento\Store\Model\ScopeInterface::SCOPE_STORE ); } }