- Модуль: sale
- Путь к файлу: ~/bitrix/modules/sale/lib/location/search/finder.php
- Класс: BitrixSaleLocationSearchFinder
- Вызов: Finder::findUsingIndex
static function findUsingIndex($parameters)
{
$query = array();
$dbConnection = MainHttpApplication::getConnection();
$dbHelper = MainHttpApplication::getConnection()->getSqlHelper();
$filter = static::parseFilter($parameters['filter']);
$filterByPhrase = isset($filter['PHRASE']) && mb_strlen($filter['PHRASE']['VALUE']);
if($filterByPhrase) // filter by phrase
{
$bounds = WordTable::getBoundsForPhrase($filter['PHRASE']['VALUE']);
if (!empty($bounds))
{
$firstBound = array_shift($bounds);
$k = 0;
foreach($bounds as $bound)
{
$query['JOIN'][] = " inner join ".ChainTable::getTableName()." A".$k." on A.LOCATION_ID = A".$k.".LOCATION_ID and (
".($bound['INF'] == $bound['SUP']
? " A".$k.".POSITION = '".$bound['INF']."'"
: " A".$k.".POSITION >= '".$bound['INF']."' and A".$k.".POSITION <= '".$bound['SUP']."'"
)."
)";
$k++;
}
$query['WHERE'][] = (
$firstBound['INF'] == $firstBound['SUP']
? " A.POSITION = '".$firstBound['INF']."'"
: " A.POSITION >= '".$firstBound['INF']."' and A.POSITION <= '".$firstBound['SUP']."'"
);
}
$mainTableJoinCondition = 'A.LOCATION_ID';
}
else
{
$mainTableJoinCondition = 'L.ID';
}
// site link search
if (
isset($filter['SITE_ID']['VALUE'])
&& is_string($filter['SITE_ID']['VALUE'])
&& $filter['SITE_ID']['VALUE'] !== ''
&& SiteLinkTable::checkTableExists()
)
{
$query['JOIN'][] = "inner join ".SiteLinkTable::getTableName()." SL on SL.LOCATION_ID = ".$mainTableJoinCondition." and SL.SITE_ID = '".$dbHelper->forSql($filter['SITE_ID']['VALUE'])."'";
}
// process filter and select statements
// at least, we support here basic field selection and filtration + NAME.NAME and NAME.LANGUAGE_ID
$map = LocationLocationTable::getMap();
$nameRequired = false;
$locationRequired = false;
if(is_array($parameters['select']))
{
foreach($parameters['select'] as $alias => $field)
{
if($field == 'NAME.NAME' || $field == 'NAME.LANGUAGE_ID')
{
$nameRequired = true;
continue;
}
if(
!isset($map[$field]) ||
!in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean')) ||
isset($map[$field]['expression'])
)
{
unset($parameters['select'][$alias]);
}
$locationRequired = true;
}
}
foreach($filter as $field => $params)
{
if($field == 'NAME.NAME' || $field == 'NAME.LANGUAGE_ID')
{
$nameRequired = true;
continue;
}
if(
!isset($map[$field]) ||
!in_array($map[$field]['data_type'], array('integer', 'string', 'float', 'boolean')) ||
isset($map[$field]['expression'])
)
{
unset($filter[$field]);
}
$locationRequired = true;
}
// data join, only if extended select specified
if($locationRequired && $filterByPhrase)
$query['JOIN'][] = "inner join ".LocationLocationTable::getTableName()." L on A.LOCATION_ID = L.ID";
if($nameRequired)
$query['JOIN'][] = "inner join ".LocationNameLocationTable::getTableName()." NAME on NAME.LOCATION_ID = ".$mainTableJoinCondition; // and N.LANGUAGE_ID = 'ru'
// making select
if(is_array($parameters['select']))
{
$select = array();
foreach($parameters['select'] as $alias => $field)
{
if($field != 'NAME.NAME' && $field != 'NAME.LANGUAGE_ID')
$field = 'L.'.$dbHelper->forSql($field);
if((string) $alias === (string) intval($alias))
$select[] = $field;
else
$select[] = $field.' as '.$dbHelper->forSql($alias);
}
$sqlSelect = implode(', ', $select);
}
else
$sqlSelect = $mainTableJoinCondition.' as ID';
// making filter
foreach($filter as $field => $params)
{
if($field != 'NAME.NAME' && $field != 'NAME.LANGUAGE_ID')
$field = 'L.'.$dbHelper->forSql($field);
$values = $params['VALUE'];
if(!is_array($values))
$values = array($values);
foreach($values as $value)
$query['WHERE'][] = $field.' '.$params['OP']." '".$dbHelper->forSql($value)."'";
}
if($filterByPhrase)
{
$sql = "
select ".($dbConnection->getType() != 'mysql' ? '' : 'distinct')/*fix this in more clever way later*/."
".$sqlSelect.(BitrixSaleLocationDBHelper::needSelectFieldsInOrderByWhenDistinct() ? ', A.RELEVANCY' : '')."
from ".ChainTable::getTableName()." A
".implode(' ', $query['JOIN'])."
".(!empty($query['WHERE']) ? 'where ' : '').implode(' and ', $query['WHERE'])."
order by A.RELEVANCY asc
";
}
else
{
$sql = "
select
".$sqlSelect."
from ".LocationLocationTable::getTableName()." L
".implode(' ', $query['JOIN'])."
".(!empty($query['WHERE']) ? 'where ' : '').implode(' and ', $query['WHERE'])."
";
}
$offset = (int)($parameters['offset'] ?? 0);
$limit = (int)($parameters['limit'] ?? 0);
if ($limit)
{
$sql = $dbHelper->getTopSql($sql, $limit, $offset);
}
return $dbConnection->query($sql);
}