123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515 |
- <?php
- /**
- * Mageplaza
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Mageplaza.com license that is
- * available through the world-wide-web at this URL:
- * https://www.mageplaza.com/LICENSE.txt
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade this extension to newer
- * version in the future.
- *
- * @category Mageplaza
- * @package Mageplaza_LayeredNavigation
- * @copyright Copyright (c) Mageplaza (https://www.mageplaza.com/)
- * @license https://www.mageplaza.com/LICENSE.txt
- */
- namespace Mageplaza\LayeredNavigation\Model\ResourceModel\Fulltext;
- use Magento\CatalogSearch\Model\Search\RequestGenerator;
- use Magento\Framework\App\ObjectManager;
- use Magento\Framework\DB\Select;
- use Magento\Framework\Exception\LocalizedException;
- use Magento\Framework\Exception\StateException;
- use Magento\Framework\Search\Adapter\Mysql\TemporaryStorage;
- /**
- * Class Collection
- * @package Mageplaza\LayeredNavigation\Model\ResourceModel\Fulltext
- */
- class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
- {
- /** @var \Mageplaza\LayeredNavigation\Model\ResourceModel\Fulltext\Collection|null Clone collection */
- public $collectionClone = null;
- /** @var string */
- private $queryText;
- /** @var string|null */
- private $order = null;
- /** @var string */
- private $searchRequestName;
- /** @var \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory */
- private $temporaryStorageFactory;
- /** @var \Magento\Search\Api\SearchInterface */
- private $search;
- /** @var \Mageplaza\LayeredNavigation\Model\Search\SearchCriteriaBuilder */
- private $searchCriteriaBuilder;
- /** @var \Magento\Framework\Api\Search\SearchResultInterface */
- private $searchResult;
- /** @var \Magento\Framework\Api\FilterBuilder */
- private $filterBuilder;
- /**
- * Collection constructor.
- * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
- * @param \Psr\Log\LoggerInterface $logger
- * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
- * @param \Magento\Framework\Event\ManagerInterface $eventManager
- * @param \Magento\Eav\Model\Config $eavConfig
- * @param \Magento\Framework\App\ResourceConnection $resource
- * @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
- * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
- * @param \Magento\Framework\Validator\UniversalFactory $universalFactory
- * @param \Magento\Store\Model\StoreManagerInterface $storeManager
- * @param \Magento\Framework\Module\Manager $moduleManager
- * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState
- * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
- * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
- * @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl
- * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
- * @param \Magento\Customer\Model\Session $customerSession
- * @param \Magento\Framework\Stdlib\DateTime $dateTime
- * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
- * @param \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory
- * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
- * @param string $searchRequestName
- */
- public function __construct(
- \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
- \Psr\Log\LoggerInterface $logger,
- \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
- \Magento\Framework\Event\ManagerInterface $eventManager,
- \Magento\Eav\Model\Config $eavConfig,
- \Magento\Framework\App\ResourceConnection $resource,
- \Magento\Eav\Model\EntityFactory $eavEntityFactory,
- \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
- \Magento\Framework\Validator\UniversalFactory $universalFactory,
- \Magento\Store\Model\StoreManagerInterface $storeManager,
- \Magento\Framework\Module\Manager $moduleManager,
- \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
- \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
- \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
- \Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
- \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
- \Magento\Customer\Model\Session $customerSession,
- \Magento\Framework\Stdlib\DateTime $dateTime,
- \Magento\Customer\Api\GroupManagementInterface $groupManagement,
- \Magento\Framework\Search\Adapter\Mysql\TemporaryStorageFactory $temporaryStorageFactory,
- \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
- $searchRequestName = 'catalog_view_container'
- )
- {
- 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;
- }
- /**
- * 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
- );
- }
- }
|