Debug v17

This commit is contained in:
Laurent Destailleur 2023-02-19 16:12:28 +01:00
parent 56add74e71
commit 93927cceff
2 changed files with 106 additions and 51 deletions

View File

@ -784,6 +784,12 @@ function GETPOST($paramname, $check = 'alphanohtml', $method = 0, $filter = null
}
}
} else {
// If field name is 'search_xxx' then we force the add of space after each < and > (when following char is numeric) because it means
// we use the < or > to make a search on a numeric value to do higher or lower so we can add a space to break html tags
if (strpos($paramname, 'search_') === 0) {
$out = preg_replace('/([<>])([-+]?\d)/', '\1 \2', $out);
}
$out = sanitizeVal($out, $check, $filter, $options);
}
@ -9751,7 +9757,7 @@ function dol_getmypid()
* If param $mode is 0, can contains several keywords separated with a space or |
* like "keyword1 keyword2" = We want record field like keyword1 AND field like keyword2
* or like "keyword1|keyword2" = We want record field like keyword1 OR field like keyword2
* If param $mode is 1, can contains an operator <, > or = like "<10" or ">=100.5 < 1000"
* If param $mode is 1, can contains an operator <, > or = like "<10" or ">=100.5 < -1000"
* If param $mode is 2, can contains a list of int id separated by comma like "1,3,4"
* If param $mode is 3, can contains a list of string separated by comma like "a,b,c"
* @param integer $mode 0=value is list of keyword strings, 1=value is a numeric test (Example ">5.5 <10"), 2=value is a list of ID separated with comma (Example '1,3,4')
@ -9789,23 +9795,35 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0)
$newres = '';
foreach ($fields as $field) {
if ($mode == 1) {
$operator = '=';
$newcrit = preg_replace('/([!<>=]+)/', '', $crit);
$reg = array();
preg_match('/([!<>=]+)/', $crit, $reg);
if (!empty($reg[1])) {
$operator = $reg[1];
}
if ($newcrit != '') {
$numnewcrit = price2num($newcrit);
if (is_numeric($numnewcrit)) {
$newres .= ($i2 > 0 ? ' OR ' : '').$field.' '.$operator.' '.((float) $numnewcrit); // should be a numeric
} else {
$newres .= ($i2 > 0 ? ' OR ' : '').'1 = 2'; // force false
$tmpcrits = explode('|', $crit);
$i3 = 0; // count the nb of valid criteria added for this field
foreach ($tmpcrits as $tmpcrit) {
if ($tmpcrit !== '0' && empty($tmpcrit)) {
continue;
}
$tmpcrit = trim($tmpcrit);
$newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : '');
$operator = '=';
$newcrit = preg_replace('/([!<>=]+)/', '', $tmpcrit);
$reg = array();
preg_match('/([!<>=]+)/', $tmpcrit, $reg);
if (!empty($reg[1])) {
$operator = $reg[1];
}
if ($newcrit != '') {
$numnewcrit = price2num($newcrit);
if (is_numeric($numnewcrit)) {
$newres .= $field.' '.$operator.' '.((float) $numnewcrit); // should be a numeric
} else {
$newres .= '1 = 2'; // force false, we received a corrupted data
}
$i3++; // a criteria was added to string
}
$i2++; // a criteria was added to string
}
$i2++;
} elseif ($mode == 2 || $mode == -2) {
$crit = preg_replace('/[^0-9,]/', '', $crit); // ID are always integer
$newres .= ($i2 > 0 ? ' OR ' : '').$field." ".($mode == -2 ? 'NOT ' : '');
@ -9847,28 +9865,36 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0)
}
}
}
} else // $mode=0
{
} else { // $mode=0
$tmpcrits = explode('|', $crit);
$i3 = 0;
$i3 = 0; // count the nb of valid criteria added for this field
foreach ($tmpcrits as $tmpcrit) {
if ($tmpcrit !== '0' && empty($tmpcrit)) {
continue;
}
$tmpcrit = trim($tmpcrit);
$newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : '');
if ($tmpcrit == '^$') { // If we search empty, we must combined different fields with AND
$newres .= (($i2 > 0 || $i3 > 0) ? ' AND ' : '');
} else {
$newres .= (($i2 > 0 || $i3 > 0) ? ' OR ' : '');
}
if (preg_match('/\.(id|rowid)$/', $field)) { // Special case for rowid that is sometimes a ref so used as a search field
$newres .= $field." = ".(is_numeric(trim($tmpcrit)) ? ((float) trim($tmpcrit)) : '0');
$newres .= $field." = ".(is_numeric($tmpcrit) ? ((float) $tmpcrit) : '0');
} else {
$tmpcrit = trim($tmpcrit);
$tmpcrit2 = $tmpcrit;
$tmpbefore = '%';
$tmpafter = '%';
$tmps = '';
if (preg_match('/^!/', $tmpcrit)) {
$newres .= $field." NOT LIKE '"; // ! as exclude character
$tmps .= $field." NOT LIKE "; // ! as exclude character
$tmpcrit2 = preg_replace('/^!/', '', $tmpcrit2);
} else $newres .= $field." LIKE '";
} else {
$tmps .= $field." LIKE ";
}
$tmps .= "'";
if (preg_match('/^[\^\$]/', $tmpcrit)) {
$tmpbefore = '';
@ -9878,12 +9904,17 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0)
$tmpafter = '';
$tmpcrit2 = preg_replace('/[\^\$]$/', '', $tmpcrit2);
}
if ($tmpcrit2 == '' || preg_match('/^!/', $tmpcrit)) {
$tmps = "(".$tmps;
}
$newres .= $tmps;
$newres .= $tmpbefore;
$newres .= $db->escape($tmpcrit2);
$newres .= $tmpafter;
$newres .= "'";
if ($tmpcrit2 == '') {
$newres .= " OR ".$field." IS NULL";
if ($tmpcrit2 == '' || preg_match('/^!/', $tmpcrit)) {
$newres .= " OR ".$field." IS NULL)";
}
}
@ -9893,13 +9924,14 @@ function natural_search($fields, $value, $mode = 0, $nofirstand = 0)
}
$i++;
}
if ($newres) {
$res = $res.($res ? ' AND ' : '').($i2 > 1 ? '(' : '').$newres.($i2 > 1 ? ')' : '');
}
$j++;
}
$res = ($nofirstand ? "" : " AND ")."(".$res.")";
//print 'xx'.$res.'yy';
return $res;
}

View File

@ -54,6 +54,7 @@ $massaction = GETPOST('massaction', 'alpha');
$show_files = GETPOST('show_files', 'int');
$confirm = GETPOST('confirm', 'alpha');
$toselect = GETPOST('toselect', 'array');
$optioncss = GETPOST('optioncss', 'alpha');
$contextpage = GETPOST('contextpage', 'aZ') ?GETPOST('contextpage', 'aZ') : 'projectlist';
$title = $langs->trans("Projects");
@ -113,6 +114,7 @@ $search_accept_booth_suggestions = GETPOST('search_accept_booth_suggestions', 'i
$search_price_registration = GETPOST("search_price_registration", 'alpha');
$search_price_booth = GETPOST("search_price_booth", 'alpha');
$search_login = GETPOST('search_login', 'alpha');
$search_import_key = GETPOST('search_import_key', 'alpha');
$searchCategoryCustomerOperator = 0;
if (GETPOSTISSET('formfilteraction')) {
$searchCategoryCustomerOperator = GETPOST('search_category_customer_operator', 'int');
@ -120,7 +122,7 @@ if (GETPOSTISSET('formfilteraction')) {
$searchCategoryCustomerOperator = $conf->global->MAIN_SEARCH_CAT_OR_BY_DEFAULT;
}
$searchCategoryCustomerList = GETPOST('search_category_customer_list', 'array');
$optioncss = GETPOST('optioncss', 'alpha');
$mine = ((GETPOST('mode') == 'mine') ? 1 : 0);
if ($mine) {
@ -134,7 +136,6 @@ $search_eday = GETPOST('search_eday', 'int');
$search_emonth = GETPOST('search_emonth', 'int');
$search_eyear = GETPOST('search_eyear', 'int');
$search_date_start_startmonth = GETPOST('search_date_start_startmonth', 'int');
$search_date_start_startyear = GETPOST('search_date_start_startyear', 'int');
$search_date_start_startday = GETPOST('search_date_start_startday', 'int');
@ -152,6 +153,7 @@ $search_date_end_endmonth = GETPOST('search_date_end_endmonth', 'int');
$search_date_end_endyear = GETPOST('search_date_end_endyear', 'int');
$search_date_end_endday = GETPOST('search_date_end_endday', 'int');
$search_date_end_end = dol_mktime(23, 59, 59, $search_date_end_endmonth, $search_date_end_endday, $search_date_end_endyear); // Use tzserver
if (isModEnabled('categorie')) {
$search_category_array = GETPOST("search_category_".Categorie::TYPE_PROJECT."_list", "array");
}
@ -301,6 +303,7 @@ if (empty($reshook)) {
$search_price_registration = '';
$search_price_booth = '';
$search_login = '';
$search_import_key = '';
$toselect = array();
$search_array_options = array();
$search_category_array = array();
@ -368,6 +371,8 @@ if (empty($reshook)) {
$form = new Form($db);
$formcompany = new FormCompany($db);
$now = dol_now();
$companystatic = new Societe($db);
$taskstatic = new Task($db);
$formother = new FormOther($db);
@ -415,7 +420,7 @@ if (count($listofprojectcontacttypeexternal) == 0) {
$varpage = empty($contextpage) ? $_SERVER["PHP_SELF"] : $contextpage;
$selectedfields = $form->multiSelectArrayWithCheckbox('selectedfields', $arrayfields, $varpage); // This also change content of $arrayfields
$distinct = 'DISTINCT'; // We add distinct until we are added a protection to be sure a contact of a project and task is only once.
$distinct = 'DISTINCT'; // We add distinct until we have added a protection to be sure a contact of a project and task is only once.
$sql = "SELECT ".$distinct." p.rowid as id, p.ref, p.title, p.fk_statut as status, p.fk_opp_status, p.public, p.fk_user_creat,";
$sql .= " p.datec as date_creation, p.dateo as date_start, p.datee as date_end, p.opp_amount, p.opp_percent, (p.opp_amount*p.opp_percent/100) as opp_weighted_amount, p.tms as date_update, p.budget_amount,";
$sql .= " p.usage_opportunity, p.usage_task, p.usage_bill_time, p.usage_organize_event,";
@ -436,6 +441,9 @@ $parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= preg_replace('/^,/', '', $hookmanager->resPrint);
$sql = preg_replace('/,\s*$/', '', $sql);
$sqlfields = $sql; // $sql fields to remove for count total
$sql .= " FROM ".MAIN_DB_PREFIX.$object->table_element." as p";
if (!empty($extrafields->attributes[$object->table_element]['label']) &&is_array($extrafields->attributes[$object->table_element]['label']) && count($extrafields->attributes[$object->table_element]['label'])) {
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$object->table_element."_extrafields as ef on (p.rowid = ef.fk_object)";
@ -546,9 +554,11 @@ if ($search_sale > 0) {
// No check is done on company permission because readability is managed by public status of project and assignement.
//if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND ((s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id).") OR (s.rowid IS NULL))";
if ($search_project_user > 0) {
// TODO Replace this with a EXISTS and remove the link to table + DISTINCT
$sql .= " AND ecp.fk_c_type_contact IN (".$db->sanitize(join(',', array_keys($listofprojectcontacttype))).") AND ecp.element_id = p.rowid AND ecp.fk_socpeople = ".((int) $search_project_user);
}
if ($search_project_contact > 0) {
// TODO Replace this with a EXISTS and remove the link to table + DISTINCT
$sql .= " AND ecp_contact.fk_c_type_contact IN (".$db->sanitize(join(',', array_keys($listofprojectcontacttypeexternal))).") AND ecp_contact.element_id = p.rowid AND ecp_contact.fk_socpeople = ".((int) $search_project_contact);
}
if ($search_opp_amount != '') {
@ -584,6 +594,9 @@ if ($search_price_booth != '') {
if ($search_login) {
$sql .= natural_search(array('u.login', 'u.firstname', 'u.lastname'), $search_login);
}
if ($search_import_key) {
$sql .= natural_search(array('p.import_key'), $search_import_key);
}
// Search for tag/category ($searchCategoryProjectList is an array of ID)
$searchCategoryProjectList = $search_category_array;
$searchCategoryProjectOperator = 0;
@ -664,37 +677,45 @@ include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php';
$parameters = array();
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook
$sql .= $hookmanager->resPrint;
$sql .= $db->order($sortfield, $sortorder);
//print $sql;
// Count total nb of records
$nbtotalofrecords = '';
if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) {
$resql = $db->query($sql);
$nbtotalofrecords = $db->num_rows($resql);
if (($page * $limit) > $nbtotalofrecords) { // if total of record found is smaller than page * limit, goto and load page 0
/* The fast and low memory method to get and count full list converts the sql into a sql count */
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
$resql = $db->query($sqlforcount);
if ($resql) {
$objforcount = $db->fetch_object($resql);
$nbtotalofrecords = $objforcount->nbtotalofrecords;
} else {
dol_print_error($db);
}
if (($page * $limit) > $nbtotalofrecords) { // if total resultset is smaller then paging size (filtering), goto and load page 0
$page = 0;
$offset = 0;
}
$db->free($resql);
}
// if total of record found is smaller than limit, no need to do paging and to restart another select with limits set.
if (is_numeric($nbtotalofrecords) && ($limit > $nbtotalofrecords || empty($limit))) {
$num = $nbtotalofrecords;
} else {
if (!empty($limit)) {
$sql .= $db->plimit($limit + 1, $offset);
}
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
// Complete request and execute it with limit
$sql .= $db->order($sortfield, $sortorder);
if ($limit) {
$sql .= $db->plimit($limit + 1, $offset);
}
$resql = $db->query($sql);
if (!$resql) {
dol_print_error($db);
exit;
}
$num = $db->num_rows($resql);
// Direct jump if only one record found
if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all) {
if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $search_all && !$page) {
$obj = $db->fetch_object($resql);
header("Location: ".DOL_URL_ROOT.'/projet/card.php?id='.$obj->id);
exit;
@ -704,8 +725,6 @@ if ($num == 1 && !empty($conf->global->MAIN_SEARCH_DIRECT_OPEN_IF_ONLY_ONE) && $
// Output page
// --------------------------------------------------------------------
dol_syslog("list allowed project", LOG_DEBUG);
llxHeader('', $title, $help_url);
$arrayofselected = is_array($toselect) ? $toselect : array();
@ -855,6 +874,9 @@ if ($search_price_booth != '') {
if ($search_login) {
$param .= '&search_login='.urlencode($search_login);
}
if ($search_import_key) {
$param .= '&search_import_key='.urlencode($search_import_key);
}
if ($optioncss != '') {
$param .= '&optioncss='.urlencode($optioncss);
}
@ -1186,6 +1208,7 @@ if (!empty($arrayfields['p.email_msgid']['checked'])) {
if (!empty($arrayfields['p.import_key']['checked'])) {
// Import key
print '<td class="liste_titre">';
print '<input class="flat width75" type="text" name="search_import_key" value="'.dol_escape_htmltag($search_import_key).'">';
print '</td>';
}
if (!empty($arrayfields['p.fk_statut']['checked'])) {