mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-15 22:11:36 +01:00
Fix #yogosha15157
This commit is contained in:
@@ -11522,17 +11522,35 @@ function jsonOrUnserialize($stringtodecode)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* forgeSQLFromUniversalSearchCriteria
|
||||
*
|
||||
* @param string $filter String with universal search string
|
||||
* @param string $error Error message
|
||||
* @return string Return forged SQL string
|
||||
*/
|
||||
function forgeSQLFromUniversalSearchCriteria($filter, &$error = '')
|
||||
{
|
||||
$regexstring = '\(([a-zA-Z0-9_\.]+:[<>!=insotlke]+:[^\(\)]+)\)'; // Must be (aaa:bbb:...) with aaa is a field name (with alias or not) and bbb is one of this operator '=', '<', '>', '<=', '>=', '!=', 'in', 'notin', 'like', 'notlike', 'is', 'isnot'
|
||||
|
||||
if (!dolCheckFilters($filter, $error)) {
|
||||
return '1 = 2'; // Bad balance of parenthesis, we force a SQL not found
|
||||
}
|
||||
|
||||
// Test the filter syntax
|
||||
$t = preg_replace_callback('/'.$regexstring.'/i', 'dolForgeDummyCriteriaCallback', $filter);
|
||||
$t = str_replace(array('and','or','AND','OR',' '), '', $t); // Remove the only strings allowed between each () criteria
|
||||
// If the string result contains something else than '()', the syntax was wrong
|
||||
if (preg_match('/[^\(\)]/', $t)) {
|
||||
$error = 'Bad syntax of the search string, filter criteria is inhalited';
|
||||
return '1 = 3'; // Bad syntax of the search string, we force a SQL not found
|
||||
}
|
||||
|
||||
return " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $filter).")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if a $sqlfilters parameter is valid and will pass the preg_replace_callback() to replace Generic filter string with SQL filter string
|
||||
* Example of usage:
|
||||
* if ($sqlfilters) {
|
||||
* $errormessage = '';
|
||||
* if (dolCheckFilters($sqlfilters, $errormessage)) {
|
||||
* $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
|
||||
* $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
|
||||
* }
|
||||
* }
|
||||
* Return if a $sqlfilters parameter has a valid balance of parenthesis
|
||||
*
|
||||
* @param string $sqlfilters sqlfilter string
|
||||
* @param string $error Error message
|
||||
@@ -11553,7 +11571,7 @@ function dolCheckFilters($sqlfilters, &$error = '')
|
||||
$counter--;
|
||||
}
|
||||
if ($counter < 0) {
|
||||
$error = "Bad sqlfilters=".$sqlfilters;
|
||||
$error = "Wrond balance of parenthesis in sqlfilters=".$sqlfilters;
|
||||
dol_syslog($error, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
@@ -11563,58 +11581,92 @@ function dolCheckFilters($sqlfilters, &$error = '')
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to forge a SQL criteria from a Generic filter string.
|
||||
* Example of usage:
|
||||
* if ($sqlfilters) {
|
||||
* $errormessage = '';
|
||||
* if (dolCheckFilters($sqlfilters, $errormessage)) {
|
||||
* $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)';
|
||||
* $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")";
|
||||
* }
|
||||
* }
|
||||
* Function to forge a SQL criteria from a Dolibarr filter syntax string.
|
||||
* This method is called by forgeSQLFromUniversalSearchCriteria()
|
||||
*
|
||||
* @param array $matches Array of found string by regex search.
|
||||
* Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.date_creation:<:'2016-01-01 12:30:00'" or "t.nature:is:NULL"
|
||||
* @return string Forged criteria. Example: "t.field like 'abc%'"
|
||||
* @param array $matches Array of found string by regex search. Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.nature:is:NULL"
|
||||
* @return string Forged criteria. Example: "t.field like 'abc%'"
|
||||
*/
|
||||
function dolForgeDummyCriteriaCallback($matches)
|
||||
{
|
||||
//dol_syslog("Convert matches ".$matches[1]);
|
||||
if (empty($matches[1])) {
|
||||
return '';
|
||||
}
|
||||
$tmp = explode(':', $matches[1]);
|
||||
if (count($tmp) < 3) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return '()'; // An empty criteria
|
||||
}
|
||||
|
||||
/**
|
||||
* Function to forge a SQL criteria from a Dolibarr filter syntax string.
|
||||
* This method is called by forgeSQLFromUniversalSearchCriteria()
|
||||
*
|
||||
* @param array $matches Array of found string by regex search.
|
||||
* Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.date_creation:<:'2016-01-01 12:30:00'" or "t.nature:is:NULL"
|
||||
* @return string Forged criteria. Example: "t.field like 'abc%'"
|
||||
*/
|
||||
function dolForgeCriteriaCallback($matches)
|
||||
{
|
||||
global $db;
|
||||
|
||||
dol_syslog("Convert matches ".$matches[1]);
|
||||
//dol_syslog("Convert matches ".$matches[1]);
|
||||
if (empty($matches[1])) {
|
||||
return '';
|
||||
}
|
||||
$tmp = explode(':', $matches[1], 3);
|
||||
|
||||
$tmp = explode(':', $matches[1]);
|
||||
if (count($tmp) < 3) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$operand = preg_replace('/[^a-z0-9\._]/i', '', trim($tmp[0]));
|
||||
|
||||
$operator = strtoupper(preg_replace('/[^a-z<>=]/i', '', trim($tmp[1])));
|
||||
if ($operator == 'NOTLIKE') {
|
||||
$operator = 'NOT LIKE';
|
||||
}
|
||||
if ($operator == 'ISNOT') {
|
||||
$operator = 'IS NOT';
|
||||
}
|
||||
if ($operator == '!=') {
|
||||
$operator = '<>';
|
||||
}
|
||||
|
||||
$tmpescaped = trim($tmp[2]);
|
||||
$tmpescaped = $tmp[2];
|
||||
$regbis = array();
|
||||
if ($operator == 'IN') {
|
||||
$tmpescaped = "(".$db->sanitize($tmpescaped, 1).")";
|
||||
|
||||
if ($operator == 'IN') { // IN is allowed for list of ID or code only
|
||||
//if (!preg_match('/^\(.*\)$/', $tmpescaped)) {
|
||||
$tmpescaped = '('.$db->escape($db->sanitize($tmpescaped, 1, 0)).')';
|
||||
//} else {
|
||||
// $tmpescaped = $db->escape($db->sanitize($tmpescaped, 1));
|
||||
//}
|
||||
} elseif ($operator == 'LIKE' || $operator == 'NOT LIKE') {
|
||||
if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
|
||||
$tmpescaped = $regbis[1];
|
||||
}
|
||||
//$tmpescaped = "'".$db->escapeforlike($db->escape($regbis[1]))."'";
|
||||
$tmpescaped = "'".$db->escape($tmpescaped)."'"; // We do not escape the _ and % so the like will works
|
||||
} elseif (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
|
||||
$tmpescaped = "'".$db->escape($regbis[1])."'";
|
||||
} else {
|
||||
$tmpescaped = $db->sanitize($db->escape($tmpescaped));
|
||||
if (strtoupper($tmpescaped) == 'NULL') {
|
||||
$tmpescaped = 'NULL';
|
||||
} elseif (is_int($tmpescaped)) {
|
||||
$tmpescaped = (int) $tmpescaped;
|
||||
} else {
|
||||
$tmpescaped = (float) $tmpescaped;
|
||||
}
|
||||
}
|
||||
|
||||
return $db->escape($operand).' '.$db->escape($operator)." ".$tmpescaped;
|
||||
return $db->escape($tmp[0]).' '.strtoupper($operator).' '.$tmpescaped;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get timeline icon
|
||||
*
|
||||
* @param ActionComm $actionstatic actioncomm
|
||||
* @param array $histo histo
|
||||
* @param int $key key
|
||||
|
||||
Reference in New Issue
Block a user