Files
citrus-cms/app/DevExtreme/FilterHelper.php
T
2026-04-28 21:14:25 +03:00

243 lines
9.8 KiB
PHP

<?php
namespace App\DevExtreme;
class FilterHelper {
private static $AND_OP = "AND";
private static $OR_OP = "OR";
private static $LIKE_OP = "LIKE";
private static $NOT_OP = "NOT";
private static $IS_OP = "IS";
private static function _GetSqlFieldName($field) {
$fieldParts = explode(".", $field);
$result = "";
$fieldName = Utils::QuoteStringValue(trim($fieldParts[0]));
if (count($fieldParts) == 2) {
$dateProperty = trim($fieldParts[1]);
$sqlDateFunction = "";
$fieldPattern = "";
switch ($dateProperty) {
case "year":
case "month":
case "day": {
$sqlDateFunction = strtoupper($dateProperty);
$fieldPattern = "%s(%s)";
break;
}
case "dayOfWeek": {
$sqlDateFunction = strtoupper($dateProperty);
$fieldPattern = "%s(%s) - 1";
break;
}
default: {
throw new \Exception("The \"".$dateProperty."\" command is not supported");
}
}
$result = sprintf($fieldPattern, $sqlDateFunction, $fieldName);
}
else {
$result = $fieldName;
}
return $result;
}
private static function _GetSimpleSqlExpr($expression) {
$result = "";
$itemsCount = count($expression);
$fieldName = self::_GetSqlFieldName(trim($expression[0]));
// Known operators list
$knownOperators = ['=', '<>', '>', '>=', '<', '<=', 'startswith', 'endswith', 'contains', 'notcontains', 'in', '==='];
if ($itemsCount == 2) {
$val = $expression[1];
$valLower = is_string($val) ? strtolower(trim($val)) : '';
// Check if second element is an operator (means searching for empty values)
if (in_array($valLower, $knownOperators)) {
// This is an operator without value - treat as empty value search
switch ($valLower) {
case 'contains':
case 'startswith':
case 'endswith':
case '=':
// Search for NULL or empty string
$result = sprintf("(%s IS NULL OR %s = '')", $fieldName, $fieldName);
break;
case '<>':
case 'notcontains':
// Search for NOT NULL and NOT empty
$result = sprintf("(%s IS NOT NULL AND %s != '')", $fieldName, $fieldName);
break;
default:
// For other operators, just check IS NULL
$result = sprintf("%s IS NULL", $fieldName);
break;
}
} elseif ($val === "(Empty)" || $val === "(Boş)" || $val === "") {
$result = sprintf("%s IS NULL", $fieldName);
} else {
$result = sprintf("%s = %s", $fieldName, Utils::QuoteStringValue($val, false));
}
}
else if ($itemsCount == 3) {
$clause = strtolower(trim($expression[1]));
$val = $expression[2];
if ($val === "(Empty)" || $val === "(Boş)" || $val === "" || is_null($val)) {
switch ($clause) {
case "=":
case "contains":
case "startswith":
case "endswith": {
// Hem NULL hem empty string için kontrol
if(strpos($fieldName, 'date') !== false) {
$result = sprintf("(%s IS NULL)", $fieldName);
} else {
$result = sprintf("(%s IS NULL OR %s = '')", $fieldName, $fieldName);
}
return $result;
}
case "<>":
case "notcontains": {
// Ne NULL ne de empty string
$result = sprintf("(%s IS NOT NULL AND %s != '')", $fieldName, $fieldName);
return $result;
}
}
}
else {
switch ($clause) {
case "===": {
// Exact match - DO NOT split comma-separated values
$result = sprintf("%s = %s", $fieldName, Utils::QuoteStringValue($val, false));
return $result;
}
case "=": {
// Exact match - treat comma-separated values as single entity
$pattern = "%s %s %s";
$val = Utils::QuoteStringValue($val, false);
break;
}
case "<>": {
$pattern = "%s %s %s";
$val = Utils::QuoteStringValue($val, false);
break;
}
case ">":
case ">=":
case "<":
case "<=": {
$pattern = "%s %s %s";
$val = Utils::QuoteStringValue($val, false);
break;
}
case "startswith": {
$pattern = "%s %s '%s%%'";
$clause = self::$LIKE_OP;
$val = addcslashes($val, "%_");
break;
}
case "endswith": {
$pattern = "%s %s '%%%s'";
$val = addcslashes($val, "%_");
$clause = self::$LIKE_OP;
break;
}
case "contains": {
$pattern = "%s %s '%%%s%%'";
$val = addcslashes($val, "%_");
$clause = self::$LIKE_OP;
break;
}
case "notcontains": {
$pattern = "%s %s '%%%s%%'";
$val = addcslashes($val, "%_");
$clause = sprintf("%s %s", self::$NOT_OP, self::$LIKE_OP);
break;
}
case "noneof": {
if (is_array($val) && count($val) > 0) {
$quotedValues = array_map(function($v) {
return Utils::QuoteStringValue($v, false);
}, $val);
$result = sprintf("%s NOT IN (%s)", $fieldName, implode(", ", $quotedValues));
return $result;
}
$pattern = "%s <> %s";
$val = Utils::QuoteStringValue($val, false);
break;
}
case "anyof":
case "in": {
if (is_array($val) && count($val) > 0) {
$quotedValues = array_map(function($v) {
return Utils::QuoteStringValue($v, false);
}, $val);
$result = sprintf("%s IN (%s)", $fieldName, implode(", ", $quotedValues));
return $result;
}
// Fall through to default if not array
}
default: {
$clause = $clause ?: "=";
$pattern = "%s %s %s";
if(!is_array($val)) {
$val = Utils::QuoteStringValue($val, false);
}
}
}
}
if(isset($pattern)) {
$result = sprintf($pattern, $fieldName, $clause, $val);
$result = str_replace(" = ''", " is null", $result);
} else {
$result = ""; // Should not happen with new default logic but safe fallback
}
}
return $result;
}
public static function GetSqlExprByArray($expression) {
$result = "(";
$prevItemWasArray = false;
foreach ($expression as $index => $item) {
if (is_string($item)) {
$prevItemWasArray = false;
if ($index == 0) {
if ($item == "!") {
$result .= sprintf("%s ", self::$NOT_OP);
continue;
}
$result .= (isset($expression) && is_array($expression)) ? self::_GetSimpleSqlExpr($expression) : "";
break;
}
$strItem = strtoupper(trim($item));
if ($strItem == self::$AND_OP || $strItem == self::$OR_OP) {
$result .= sprintf(" %s ", $strItem);
}
continue;
}
if (is_array($item)) {
if ($prevItemWasArray) {
$result .= sprintf(" %s ", self::$AND_OP);
}
$result .= self::GetSqlExprByArray($item);
$prevItemWasArray = true;
}
}
$result .= ")";
return $result;
}
public static function GetSqlExprByKey($key) {
$result = "";
foreach ($key as $prop => $value) {
$templ = strlen($result) == 0 ?
"%s = %s" :
" ".self::$AND_OP." %s = %s";
$result .= sprintf($templ,
Utils::QuoteStringValue($prop),
Utils::QuoteStringValue($value, false));
}
return $result;
}
}