![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-catalog-search/Model/Search/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace Magento\CatalogSearch\Model\Search; use Magento\Catalog\Api\Data\EavAttributeInterface; use Magento\Catalog\Model\Entity\Attribute; use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory; use Magento\CatalogSearch\Model\Search\RequestGenerator\GeneratorResolver; use Magento\Framework\App\ObjectManager; use Magento\Framework\Search\Request\FilterInterface; use Magento\Framework\Search\Request\QueryInterface; /** * Catalog search request generator. * * @api * @since 100.0.2 */ class RequestGenerator { /** Filter name suffix */ const FILTER_SUFFIX = '_filter'; /** Bucket name suffix */ const BUCKET_SUFFIX = '_bucket'; /** * @var CollectionFactory */ private $productAttributeCollectionFactory; /** * @var GeneratorResolver */ private $generatorResolver; /** * @param CollectionFactory $productAttributeCollectionFactory * @param GeneratorResolver $generatorResolver */ public function __construct( CollectionFactory $productAttributeCollectionFactory, GeneratorResolver $generatorResolver = null ) { $this->productAttributeCollectionFactory = $productAttributeCollectionFactory; $this->generatorResolver = $generatorResolver ?: ObjectManager::getInstance()->get(GeneratorResolver::class); } /** * Generate dynamic fields requests * * @return array */ public function generate() { $requests = []; $requests['catalog_view_container'] = $this->generateRequest(EavAttributeInterface::IS_FILTERABLE, 'catalog_view_container', false); $requests['quick_search_container'] = $this->generateRequest(EavAttributeInterface::IS_FILTERABLE_IN_SEARCH, 'quick_search_container', true); $requests['advanced_search_container'] = $this->generateAdvancedSearchRequest(); return $requests; } /** * Generate search request * * @param string $attributeType * @param string $container * @param bool $useFulltext * @return array */ private function generateRequest($attributeType, $container, $useFulltext) { $request = []; foreach ($this->getSearchableAttributes() as $attribute) { /** @var $attribute Attribute */ if ($attribute->getData($attributeType)) { if (!in_array($attribute->getAttributeCode(), ['price', 'category_ids'], true)) { $queryName = $attribute->getAttributeCode() . '_query'; $request['queries'][$container]['queryReference'][] = [ 'clause' => 'must', 'ref' => $queryName, ]; $filterName = $attribute->getAttributeCode() . self::FILTER_SUFFIX; $request['queries'][$queryName] = [ 'name' => $queryName, 'type' => QueryInterface::TYPE_FILTER, 'filterReference' => [ [ 'clause' => 'must', 'ref' => $filterName, ] ], ]; $bucketName = $attribute->getAttributeCode() . self::BUCKET_SUFFIX; $generator = $this->generatorResolver->getGeneratorForType($attribute->getBackendType()); $request['filters'][$filterName] = $generator->getFilterData($attribute, $filterName); $request['aggregations'][$bucketName] = $generator->getAggregationData($attribute, $bucketName); } } if (!$attribute->getIsSearchable() || in_array($attribute->getAttributeCode(), ['price'], true)) { // Some fields have their own specific handlers continue; } $request = $this->processPriceAttribute($useFulltext, $attribute, $request); } return $request; } /** * Retrieve searchable attributes * * @return \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection */ protected function getSearchableAttributes() { /** @var \Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection $productAttributes */ $productAttributes = $this->productAttributeCollectionFactory->create(); $productAttributes->addFieldToFilter( ['is_searchable', 'is_visible_in_advanced_search', 'is_filterable', 'is_filterable_in_search'], [1, 1, [1, 2], 1] ); return $productAttributes; } /** * Generate advanced search request * * @return array * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ private function generateAdvancedSearchRequest() { $request = []; foreach ($this->getSearchableAttributes() as $attribute) { /** @var $attribute Attribute */ if (!$attribute->getIsVisibleInAdvancedSearch()) { continue; } if (in_array($attribute->getAttributeCode(), ['price', 'sku'])) { //same fields have special semantics continue; } $queryName = $attribute->getAttributeCode() . '_query'; $request['queries']['advanced_search_container']['queryReference'][] = [ 'clause' => 'must', 'ref' => $queryName, ]; switch ($attribute->getBackendType()) { case 'static': break; case 'text': case 'varchar': if ($attribute->getFrontendInput() === 'multiselect') { $filterName = $attribute->getAttributeCode() . self::FILTER_SUFFIX; $request['queries'][$queryName] = [ 'name' => $queryName, 'type' => QueryInterface::TYPE_FILTER, 'filterReference' => [ [ 'ref' => $filterName, ], ], ]; $request['filters'][$filterName] = [ 'type' => FilterInterface::TYPE_TERM, 'name' => $filterName, 'field' => $attribute->getAttributeCode(), 'value' => '$' . $attribute->getAttributeCode() . '$', ]; } else { $request['queries'][$queryName] = [ 'name' => $queryName, 'type' => 'matchQuery', 'value' => '$' . $attribute->getAttributeCode() . '$', 'match' => [ [ 'field' => $attribute->getAttributeCode(), 'boost' => $attribute->getSearchWeight() ?: 1, 'matchCondition' => 'match_phrase_prefix', ], ], ]; } break; case 'decimal': case 'datetime': case 'date': $filterName = $attribute->getAttributeCode() . self::FILTER_SUFFIX; $request['queries'][$queryName] = [ 'name' => $queryName, 'type' => QueryInterface::TYPE_FILTER, 'filterReference' => [ [ 'ref' => $filterName, ], ], ]; $request['filters'][$filterName] = [ 'field' => $attribute->getAttributeCode(), 'name' => $filterName, 'type' => FilterInterface::TYPE_RANGE, 'from' => '$' . $attribute->getAttributeCode() . '.from$', 'to' => '$' . $attribute->getAttributeCode() . '.to$', ]; break; default: $filterName = $attribute->getAttributeCode() . self::FILTER_SUFFIX; $request['queries'][$queryName] = [ 'name' => $queryName, 'type' => QueryInterface::TYPE_FILTER, 'filterReference' => [ [ 'ref' => $filterName, ], ], ]; $request['filters'][$filterName] = [ 'type' => FilterInterface::TYPE_TERM, 'name' => $filterName, 'field' => $attribute->getAttributeCode(), 'value' => '$' . $attribute->getAttributeCode() . '$', ]; } } return $request; } /** * Modify request for price attribute. * * @param bool $useFulltext * @param Attribute $attribute * @param array $request * @return array */ private function processPriceAttribute($useFulltext, $attribute, $request) { // Match search by custom price attribute isn't supported if ($useFulltext && $attribute->getFrontendInput() !== 'price') { $request['queries']['search']['match'][] = [ 'field' => $attribute->getAttributeCode(), 'boost' => $attribute->getSearchWeight() ?: 1, ]; } return $request; } }