b374k
m1n1 1.01
Apache/2.4.41 (Ubuntu)
Linux vmi616275.contaboserver.net 5.4.0-84-generic #94-Ubuntu SMP Thu Aug 26 20:27:37 UTC 2021 x86_64
uid=33(www-data) gid=33(www-data) groups=33(www-data)
server ip : 62.171.164.128 | your ip : 127.0.0.1
safemode OFF
 >  / home / Mirasvit / SearchMysql / SearchAdapter /
Filename/home/Mirasvit/SearchMysql/SearchAdapter/Mapper.php
Size7.2 kb
Permissionrw-r--r--
Ownerroot : root
Create time01-Jul-2024 20:52
Last modified06-Apr-2021 18:06
Last accessed21-Aug-2025 20:34
Actionsedit | rename | delete | download (gzip)
Viewtext | code | image
<?php
/**
* Mirasvit
*
* This source file is subject to the Mirasvit Software License, which is available at https://mirasvit.com/license/.
* Do not edit or add to this file if you wish to upgrade the to newer versions in the future.
* If you wish to customize this module for your needs.
* Please refer to http://www.magentocommerce.com for more information.
*
* @category Mirasvit
* @package mirasvit/module-search-ultimate
* @version 2.0.25
* @copyright Copyright (C) 2021 Mirasvit (https://mirasvit.com/)
*/



namespace Mirasvit\SearchMysql\SearchAdapter;

use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Select;
use Magento\Framework\Search\Request\Query\BoolExpression as BoolQuery;
use Magento\Framework\Search\Request\Query\Filter as FilterQuery;
use Magento\Framework\Search\Request\Query\Match as MatchQuery;
use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
use Magento\Framework\Search\RequestInterface;

class Mapper
{
private $resource;

private $queryContainerFactory;

private $scoreBuilderFactory;

private $filterBuilder;

private $matchBuilder;

private $indexProviders = [];

public function __construct(
ResourceConnection $resource,
Query\QueryContainerFactory $queryContainerFactory,
ScoreBuilderFactory $scoreBuilderFactory,
Filter\Builder $filterBuilder,
Query\Builder\Match $matchBuilder,
array $indexProviders = []
) {
$this->resource = $resource;
$this->queryContainerFactory = $queryContainerFactory;
$this->scoreBuilderFactory = $scoreBuilderFactory;
$this->filterBuilder = $filterBuilder;
$this->matchBuilder = $matchBuilder;
$this->indexProviders = $indexProviders;
}

public function buildQuery(RequestInterface $request): Select
{
if (!isset($this->indexProviders[$request->getIndex()])) {
throw new \Exception('Index provider not configured for ' . $request->getIndex());
}

$indexBuilder = $this->indexProviders[$request->getIndex()];

$queryContainer = $this->queryContainerFactory->create([
'indexBuilder' => $indexBuilder,
'request' => $request,
]);

$select = $indexBuilder->build($request);

$scoreBuilder = $this->scoreBuilderFactory->create();

$select = $this->processQuery(
$scoreBuilder,
$request->getQuery(),
$select,
BoolQuery::QUERY_CONDITION_MUST,
$queryContainer
);

$select = $this->addDerivedQueries(
$request,
$queryContainer,
$scoreBuilder,
$select,
$indexBuilder
);

$select->order('score ' . Select::SQL_DESC)
->order('entity_id ' . Select::SQL_DESC);

return $select;
}

protected function processQuery(
ScoreBuilder $scoreBuilder,
RequestQueryInterface $query,
Select $select,
string $conditionType,
Query\QueryContainer $queryContainer
): Select {
switch ($query->getType()) {
case RequestQueryInterface::TYPE_MATCH:
/** @var MatchQuery $query */
$select = $queryContainer->addMatchQuery(
$select,
$query,
$conditionType
);
break;
case RequestQueryInterface::TYPE_BOOL:
/** @var BoolQuery $query */
$select = $this->processBoolQuery($scoreBuilder, $query, $select, $queryContainer);
break;
case RequestQueryInterface::TYPE_FILTER:
/** @var FilterQuery $query */
$select = $this->processFilterQuery($scoreBuilder, $query, $select, $conditionType, $queryContainer);
break;
default:
throw new \Exception(sprintf('Unknown query type \'%s\'', $query->getType()));
}

return $select;
}


private function processBoolQuery(
ScoreBuilder $scoreBuilder,
BoolQuery $query,
Select $select,
Query\QueryContainer $queryContainer
): Select {
$scoreBuilder->startQuery();

$select = $this->processBoolQueryCondition(
$scoreBuilder,
$query->getMust(),
$select,
BoolQuery::QUERY_CONDITION_MUST,
$queryContainer
);

$select = $this->processBoolQueryCondition(
$scoreBuilder,
$query->getShould(),
$select,
BoolQuery::QUERY_CONDITION_SHOULD,
$queryContainer
);

$select = $this->processBoolQueryCondition(
$scoreBuilder,
$query->getMustNot(),
$select,
BoolQuery::QUERY_CONDITION_NOT,
$queryContainer
);

$scoreBuilder->endQuery((int)$query->getBoost());

return $select;
}

private function processBoolQueryCondition(
ScoreBuilder $scoreBuilder,
array $subQueryList,
Select $select,
string $conditionType,
Query\QueryContainer $queryContainer
): Select {
foreach ($subQueryList as $subQuery) {
$select = $this->processQuery($scoreBuilder, $subQuery, $select, $conditionType, $queryContainer);
}

return $select;
}

private function processFilterQuery(
ScoreBuilder $scoreBuilder,
FilterQuery $query,
Select $select,
string $conditionType,
Query\QueryContainer $queryContainer
): Select {
$scoreBuilder->startQuery();
switch ($query->getReferenceType()) {
case FilterQuery::REFERENCE_QUERY:
$select = $this->processQuery(
$scoreBuilder,
$query->getReference(),
$select,
$conditionType,
$queryContainer
);
$scoreBuilder->endQuery((int)$query->getBoost());
break;

case FilterQuery::REFERENCE_FILTER:
$filterCondition = $this->filterBuilder->build($query->getReference(), $conditionType);

if ($filterCondition) {
$select->where($filterCondition);
}
break;
}
$scoreBuilder->endQuery((int)$query->getBoost());

return $select;
}

private function addDerivedQueries(
RequestInterface $request,
Query\QueryContainer $queryContainer,
ScoreBuilder $scoreBuilder,
Select $select,
Mapper\IndexBuilder $indexBuilder
): Select {
$matchQueries = $queryContainer->getMatchQueries();

if (!$matchQueries) {
$select->columns($scoreBuilder->build());
} else {
$matchContainer = array_shift($matchQueries);

$this->matchBuilder->build(
$scoreBuilder,
$select,
$matchContainer->getRequest(),
$matchContainer->getConditionType()
);

$select->columns($scoreBuilder->build());
}

return $select;
}
}