- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/sql_util.php
- Класс: CSqlUtil
- Вызов: CSqlUtil::PrepareSql
static function PrepareSql(&$arFields, $arOrder, $arFilter, $arGroupBy, $arSelectFields, $arOptions = array())
{
global $DB;
if(!is_array($arOptions))
{
$arOptions = array();
}
$strSqlSelect = '';
$strSqlFrom = '';
$strSqlFromWhere = '';
$strSqlGroupBy = '';
$arGroupByFunct = array("COUNT", "AVG", "MIN", "MAX", "SUM");
$arAlreadyJoined = array();
// GROUP BY -->
if (is_array($arGroupBy) && !empty($arGroupBy))
{
$arSelectFields = $arGroupBy;
foreach ($arGroupBy as $key => $val)
{
$val = mb_strtoupper($val);
$key = mb_strtoupper($key);
if (array_key_exists($val, $arFields) && !in_array($key, $arGroupByFunct))
{
if ($strSqlGroupBy <> '')
$strSqlGroupBy .= ", ";
$strSqlGroupBy .= $arFields[$val]["FIELD"];
if (isset($arFields[$val]["FROM"])
&& $arFields[$val]["FROM"] <> ''
&& !in_array($arFields[$val]["FROM"], $arAlreadyJoined))
{
if ($strSqlFrom <> '')
$strSqlFrom .= " ";
$strSqlFrom .= $arFields[$val]["FROM"];
$arAlreadyJoined[] = $arFields[$val]["FROM"];
}
}
}
}
// <-- GROUP BY
// SELECT -->
$arFieldsKeys = array_keys($arFields);
if (is_array($arGroupBy) && empty($arGroupBy))
{
$strSqlSelect = "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT ";
}
else
{
if (isset($arSelectFields) && !is_array($arSelectFields) && is_string($arSelectFields) && $arSelectFields <> '' && array_key_exists($arSelectFields, $arFields))
$arSelectFields = array($arSelectFields);
if (!isset($arSelectFields)
|| !is_array($arSelectFields)
|| empty($arSelectFields))
{
self::PrepareDefaultFields($arFields, $arOrder, $arAlreadyJoined, $strSqlSelect, $strSqlFrom);
}
else
{
foreach ($arSelectFields as $key => $val)
{
if($val === '*')
{
self::PrepareDefaultFields($arFields, $arOrder, $arAlreadyJoined, $strSqlSelect, $strSqlFrom);
}
$val = mb_strtoupper($val);
$key = mb_strtoupper($key);
if (!array_key_exists($val, $arFields))
{
continue;
}
if (in_array($key, $arGroupByFunct))
{
if ($strSqlSelect <> '')
$strSqlSelect .= ", ";
$strSqlSelect .= $key."(".$arFields[$val]["FIELD"].") as ".$val;
}
else
{
self::AddToSelect($val, $arFields[$val], $arOrder, $strSqlSelect);
}
self::AddToFrom($arFields[$val], $arAlreadyJoined, $strSqlFrom);
}
}
if($strSqlGroupBy === '')
{
$strSqlSelect = "%%_DISTINCT_%% ".$strSqlSelect;
}
elseif(!isset($arOptions['ENABLE_GROUPING_COUNT']) || $arOptions['ENABLE_GROUPING_COUNT'] === true)
{
if ($strSqlSelect <> '')
$strSqlSelect .= ", ";
$strSqlSelect .= "COUNT(%%_DISTINCT_%% ".$arFields[$arFieldsKeys[0]]["FIELD"].") as CNT";
}
}
// <-- SELECT
// WHERE -->
$arJoins = array();
$strSqlWhere = self::PrepareWhere($arFields, $arFilter, $arJoins);
foreach($arJoins as $join)
{
if($join === '')
{
continue;
}
if ($strSqlFromWhere !== '')
{
$strSqlFromWhere .= ' ';
}
$strSqlFromWhere .= $join;
if(!in_array($join, $arAlreadyJoined))
{
if ($strSqlFrom !== '')
{
$strSqlFrom .= ' ';
}
$strSqlFrom .= $join;
$arAlreadyJoined[] = $join;
}
}
// <-- WHERE
// ORDER BY -->
$arSqlOrder = array();
$dbType = $DB->type;
$nullsLast = isset($arOptions['NULLS_LAST']) ? (bool)$arOptions['NULLS_LAST'] : false;
foreach ($arOrder as $by => $order)
{
$by = mb_strtoupper($by);
$order = mb_strtoupper($order);
if ($order != "ASC")
$order = "DESC";
if (array_key_exists($by, $arFields))
{
if(!$nullsLast)
{
if($dbType !== "ORACLE")
{
$arSqlOrder[] = $arFields[$by]["FIELD"]." ".$order;
}
else
{
if($order === 'ASC')
$arSqlOrder[] = $arFields[$by]["FIELD"]." ".$order." NULLS FIRST";
else
$arSqlOrder[] = $arFields[$by]["FIELD"]." ".$order." NULLS LAST";
}
}
else
{
if($dbType === "MYSQL")
{
//Use MySql feature for sort in 'NULLS_LAST' mode
if($order === 'ASC')
$arSqlOrder[] = "-".$arFields[$by]["FIELD"]." DESC";
else
$arSqlOrder[] = $arFields[$by]["FIELD"]." ".$order;
}
}
if (isset($arFields[$by]["FROM"])
&& $arFields[$by]["FROM"] <> ''
&& !in_array($arFields[$by]["FROM"], $arAlreadyJoined))
{
if ($strSqlFrom <> '')
$strSqlFrom .= " ";
$strSqlFrom .= $arFields[$by]["FROM"];
$arAlreadyJoined[] = $arFields[$by]["FROM"];
}
}
}
$strSqlOrderBy = '';
DelDuplicateSort($arSqlOrder);
$sqlOrderQty = count($arSqlOrder);
for ($i = 0; $i < $sqlOrderQty; $i++)
{
if ($strSqlOrderBy <> '')
$strSqlOrderBy .= ", ";
$strSqlOrderBy .= $arSqlOrder[$i];
}
// <-- ORDER BY
return array(
"SELECT" => $strSqlSelect,
"FROM" => $strSqlFrom,
"WHERE" => $strSqlWhere,
"FROM_WHERE" => $strSqlFromWhere,
"GROUPBY" => $strSqlGroupBy,
"ORDERBY" => $strSqlOrderBy
);
}