Fix tool for generic to sql filters. Must not be saved into api files.
This commit is contained in:
parent
7fd601a29d
commit
b41fdb6ec9
@ -302,49 +302,13 @@ class DolibarrApi
|
||||
{
|
||||
// phpcs:enable
|
||||
|
||||
//$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
|
||||
//$tmp=preg_replace_all('/'.$regexstring.'/', '', $sqlfilters);
|
||||
$tmp = trim($sqlfilters);
|
||||
|
||||
$i = 0; $nb = strlen($tmp);
|
||||
|
||||
if ($nb > 0 && $tmp[0] != '(') {
|
||||
$error = "Bad sqlfilters (first and last characters must be open and closing parenthesis) = ".$sqlfilters;
|
||||
dol_syslog($error, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
$counter = 0;
|
||||
while ($i < $nb) {
|
||||
if ($tmp[$i] == '(') {
|
||||
$counter++;
|
||||
}
|
||||
if ($tmp[$i] == ')') {
|
||||
$counter--;
|
||||
|
||||
// TODO: After a closing ), only a " or " or " and " or end of string is allowed.
|
||||
}
|
||||
if ($counter < 0) {
|
||||
$error = "Bad sqlfilters (too many closing parenthesis) = ".$sqlfilters;
|
||||
dol_syslog($error, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
if ($counter > 0) {
|
||||
$error = "Bad sqlfilters (too many opening parenthesis) = ".$sqlfilters;
|
||||
dol_syslog($error, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return dolCheckFilters($sqlfilters, $error);
|
||||
}
|
||||
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
|
||||
// phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore
|
||||
/**
|
||||
* Function to forge a SQL criteria
|
||||
* Function to forge a SQL criteria from a Generic filter string
|
||||
*
|
||||
* @param array $matches Array of found string by regex search.
|
||||
* Each entry is 1 and only 1 criteria.
|
||||
@ -353,51 +317,6 @@ class DolibarrApi
|
||||
*/
|
||||
protected static function _forge_criteria_callback($matches)
|
||||
{
|
||||
// phpcs:enable
|
||||
global $db;
|
||||
|
||||
//dol_syslog("Convert matches ".$matches[1]);
|
||||
if (empty($matches[1])) {
|
||||
return '';
|
||||
}
|
||||
$tmp = explode(':', $matches[1], 3);
|
||||
|
||||
if (count($tmp) < 3) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Sanitize operand
|
||||
$operand = preg_replace('/[^a-z0-9\._]/i', '', trim($tmp[0]));
|
||||
|
||||
// Sanitize operator
|
||||
$operator = strtoupper(preg_replace('/[^a-z<>=]/i', '', trim($tmp[1])));
|
||||
// Only some operators are allowed.
|
||||
if (! in_array($operator, array('LIKE', 'ULIKE', '<', '>', '<=', '>=', '=', '<>', 'IS', 'ISNOT', 'IN'))) {
|
||||
return '';
|
||||
}
|
||||
if ($operator == 'ISNOT') {
|
||||
$operator = 'IS NOT';
|
||||
}
|
||||
|
||||
// Sanitize value
|
||||
$tmpescaped = trim($tmp[2]);
|
||||
$regbis = array();
|
||||
if ($operator == 'IN') {
|
||||
$tmpescaped = "(".$db->sanitize($tmpescaped, 1).")";
|
||||
} elseif (in_array($operator, array('<', '>', '<=', '>=', '=', '<>'))) {
|
||||
if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) { // If 'YYYY-MM-DD HH:MM:SS+X'
|
||||
$tmpescaped = "'".$db->escape($regbis[1])."'";
|
||||
} else {
|
||||
$tmpescaped = ((float) $tmpescaped);
|
||||
}
|
||||
} else {
|
||||
if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
|
||||
$tmpescaped = "'".$db->escape($regbis[1])."'";
|
||||
} else {
|
||||
$tmpescaped = "'".$db->escape($tmpescaped)."'";
|
||||
}
|
||||
}
|
||||
|
||||
return $db->escape($operand).' '.$db->escape($operator)." ".$tmpescaped;
|
||||
return dolForgeCriteriaCallback($matches);
|
||||
}
|
||||
}
|
||||
|
||||
@ -9666,7 +9666,12 @@ class Form
|
||||
|
||||
$ret .= '<div class="search_component inline-block valignmiddle">'.$texttoshow.'</div>';
|
||||
$ret .= '</div>';
|
||||
$ret .= '<input type="hidden" name="search_component_params_hidden" class="search_component_params_hidden" value="'.GETPOST("search_component_params_hidden").'">';
|
||||
$ret .= "<!-- Syntax of Generic filter string: t.ref:like:'SO-%', t.date_creation:<:'20160101', t.date_creation:<:'2016-01-01 12:30:00', t.nature:is:NULL, t.field2:isnot:NULL -->\n";
|
||||
if (GETPOST('show_search_component_params_hidden', 'int')) {
|
||||
$ret .= '<input type="hidden" name="show_search_component_params_hidden" value="1">';
|
||||
}
|
||||
$ret .= '<input type="'.(GETPOST('show_search_component_params_hidden', 'int') ? 'text' : 'hidden').'" name="search_component_params_hidden" class="search_component_params_hidden marginleftonly" value="'.GETPOST("search_component_params_hidden").'">';
|
||||
|
||||
// For compatibility with forms that show themself the search criteria in addition of this component, we output the fields
|
||||
foreach ($arrayofcriterias as $criterias) {
|
||||
foreach ($criterias as $criteriafamilykey => $criteriafamilyval) {
|
||||
|
||||
@ -349,7 +349,7 @@ foreach ($arrayoftype as $key => $val) {
|
||||
}
|
||||
print $form->selectarray('objecttype', $newarrayoftype, $objecttype, 0, 0, 0, '', 1, 0, 0, '', 'minwidth200', 1);
|
||||
if (empty($conf->use_javascript_ajax)) {
|
||||
print '<input type="submit" class="button buttongen button-save" name="changeobjecttype" value="'.$langs->trans("Refresh").'">';
|
||||
print '<input type="submit" class="button buttongen button-save nomargintop" name="changeobjecttype" value="'.$langs->trans("Refresh").'">';
|
||||
} else {
|
||||
print '<script type="text/javascript">
|
||||
jQuery(document).ready(function() {
|
||||
@ -456,7 +456,7 @@ if ($mode == 'graph') {
|
||||
print '</div>';
|
||||
}
|
||||
print '<div class="divadvancedsearchfield">';
|
||||
print '<input type="submit" class="button buttongen button-save" value="'.$langs->trans("Refresh").'">';
|
||||
print '<input type="submit" class="button buttongen button-save nomargintop" value="'.$langs->trans("Refresh").'">';
|
||||
print '</div>';
|
||||
print '</div>';
|
||||
print '</form>';
|
||||
|
||||
@ -10597,3 +10597,90 @@ function jsonOrUnserialize($stringtodecode)
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 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).")";
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @param string $sqlfilters sqlfilter string
|
||||
* @param string $error Error message
|
||||
* @return boolean True if valid, False if not valid ($error is filled with the reason in such a case)
|
||||
*/
|
||||
function dolCheckFilters($sqlfilters, &$error = '')
|
||||
{
|
||||
//$regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
|
||||
//$tmp=preg_replace_all('/'.$regexstring.'/', '', $sqlfilters);
|
||||
$tmp = $sqlfilters;
|
||||
$i = 0; $nb = strlen($tmp);
|
||||
$counter = 0;
|
||||
while ($i < $nb) {
|
||||
if ($tmp[$i] == '(') {
|
||||
$counter++;
|
||||
}
|
||||
if ($tmp[$i] == ')') {
|
||||
$counter--;
|
||||
}
|
||||
if ($counter < 0) {
|
||||
$error = "Bad sqlfilters=".$sqlfilters;
|
||||
dol_syslog($error, LOG_WARNING);
|
||||
return false;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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).")";
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @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]);
|
||||
if (empty($matches[1])) {
|
||||
return '';
|
||||
}
|
||||
$tmp = explode(':', $matches[1], 3);
|
||||
|
||||
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])));
|
||||
|
||||
$tmpescaped = trim($tmp[2]);
|
||||
$regbis = array();
|
||||
if ($operator == 'IN') {
|
||||
$tmpescaped = "(".$db->sanitize($tmpescaped, 1).")";
|
||||
} elseif (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) {
|
||||
$tmpescaped = "'".$db->escape($regbis[1])."'";
|
||||
} else {
|
||||
$tmpescaped = $db->sanitize($db->escape($tmpescaped));
|
||||
}
|
||||
|
||||
return $db->escape($operand).' '.$db->escape($operator)." ".$tmpescaped;
|
||||
}
|
||||
|
||||
@ -983,7 +983,7 @@ div.divsearchfield {
|
||||
padding-top: 2px;
|
||||
}
|
||||
.divadvancedsearchfield span.select2.select2-container.select2-container--default {
|
||||
padding-bottom: 4px;
|
||||
/* padding-bottom: 4px; */
|
||||
}
|
||||
.search_component_params {
|
||||
/*display: flex; */
|
||||
@ -5917,9 +5917,14 @@ input.select2-input {
|
||||
border-right: none;
|
||||
border-radius: 0 !important;
|
||||
background: var(--inputbackgroundcolor);
|
||||
line-height: normal;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice{
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__rendered {
|
||||
line-height: 1.4em;
|
||||
}
|
||||
.select2-container--default .select2-selection--multiple .select2-selection__choice {
|
||||
background-color: #ddd;
|
||||
margin-top: 4px !important;
|
||||
}
|
||||
|
||||
.select2-search__field
|
||||
|
||||
Loading…
Reference in New Issue
Block a user