From e0cf29b1225a79793687b51b93e798cbb9502886 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Feb 2023 15:32:29 +0100 Subject: [PATCH 1/3] Fix #yogosha14973 --- htdocs/ecm/dir_add_card.php | 8 ++++++-- htdocs/ecm/index.php | 16 +++++++++++----- htdocs/ecm/index_auto.php | 12 ++++++------ htdocs/langs/en_US/ecm.lang | 2 +- 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/htdocs/ecm/dir_add_card.php b/htdocs/ecm/dir_add_card.php index acdc6c2990a..5de525e17ea 100644 --- a/htdocs/ecm/dir_add_card.php +++ b/htdocs/ecm/dir_add_card.php @@ -94,13 +94,16 @@ if (!empty($section)) { // Permissions $permissiontoadd = 0; +$permissiontodelete = 0; $permissiontoupload = 0; if ($module == 'ecm') { $permissiontoadd = $user->rights->ecm->setup; + $permissiontodelete = $user->rights->ecm->setup; $permissiontoupload = $user->rights->ecm->upload; } if ($module == 'medias') { $permissiontoadd = ($user->rights->mailing->creer || $user->rights->website->write); + $permissiontodelete = ($user->rights->mailing->creer || $user->rights->website->write); $permissiontoupload = ($user->rights->mailing->creer || $user->rights->website->write); } @@ -189,7 +192,7 @@ if ($action == 'add' && $permissiontoadd) { exit; } } -} elseif ($action == 'confirm_deletesection' && $confirm == 'yes' && $permissiontoadd) { +} elseif ($action == 'confirm_deletesection' && $confirm == 'yes' && $permissiontodelete) { // Deleting file $result = $ecmdir->delete($user); setEventMessages($langs->trans("ECMSectionWasRemoved", $ecmdir->label), null, 'mesgs'); @@ -231,7 +234,8 @@ if ($action == 'create') { print ''; // Label - print ''."\n"; + print ''."\n"; print '\n"; } } else { - print ''; + print ''; } print "
'.$langs->trans("Label").'label).'" autofocus>
'.$langs->trans("Label").''; + print '
'.$langs->trans("AddIn").''; print $formecm->selectAllSections((GETPOST("catParent", 'alpha') ? GETPOST("catParent", 'alpha') : $ecmdir->fk_parent), 'catParent', $module); diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 9eb512bc96d..d6cf8a0993f 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -83,6 +83,12 @@ if ($user->socid) { } $result = restrictedArea($user, 'ecm', 0); +$permissiontoread = $user->hasRight('ecm', 'read'); +$permissiontocreate = $user->hasRight('ecm', 'upload'); +$permissiontocreatedir = $user->hasRight('ecm', 'setup'); +$permissiontodelete = $user->hasRight('ecm', 'upload'); +$permissiontodeletedir = $user->hasRight('ecm', 'setup'); + /* * Actions @@ -93,7 +99,7 @@ $result = restrictedArea($user, 'ecm', 0); //include DOL_DOCUMENT_ROOT.'/core/actions_linkedfiles.inc.php'; // Upload file (code similar but different than actions_linkedfiles.inc.php) -if (GETPOST("sendit", 'alphanohtml') && !empty($conf->global->MAIN_UPLOAD_DOC)) { +if (GETPOST("sendit", 'alphanohtml') && !empty($conf->global->MAIN_UPLOAD_DOC) && $permissiontocreate) { // Define relativepath and upload_dir $relativepath = ''; if ($ecmdir->id) { @@ -130,7 +136,7 @@ if (GETPOST("sendit", 'alphanohtml') && !empty($conf->global->MAIN_UPLOAD_DOC)) } // Remove file (code similar but different than actions_linkedfiles.inc.php) -if ($action == 'confirm_deletefile') { +if ($action == 'confirm_deletefile' && $permissiontodelete) { if (GETPOST('confirm') == 'yes') { // GETPOST('urlfile','alpha') is full relative URL from ecm root dir. Contains path of all sections. @@ -152,7 +158,7 @@ if ($action == 'confirm_deletefile') { } // Add directory -if ($action == 'add' && $user->rights->ecm->setup) { +if ($action == 'add' && $permissiontocreatedir) { $ecmdir->ref = 'NOTUSEDYET'; $ecmdir->label = GETPOST("label"); $ecmdir->description = GETPOST("desc"); @@ -170,7 +176,7 @@ if ($action == 'add' && $user->rights->ecm->setup) { } // Remove directory -if ($action == 'confirm_deletesection' && GETPOST('confirm', 'alpha') == 'yes') { +if ($action == 'confirm_deletesection' && GETPOST('confirm', 'alpha') == 'yes' && $permissiontodeletedir) { $result = $ecmdir->delete($user); setEventMessages($langs->trans("ECMSectionWasRemoved", $ecmdir->label), null, 'mesgs'); @@ -180,7 +186,7 @@ if ($action == 'confirm_deletesection' && GETPOST('confirm', 'alpha') == 'yes') // Refresh directory view // This refresh list of dirs, not list of files (for preformance reason). List of files is refresh only if dir was not synchronized. // To refresh content of dir with cache, just open the dir in edit mode. -if ($action == 'refreshmanual') { +if ($action == 'refreshmanual' && $permissiontoread) { $ecmdirtmp = new EcmDirectory($db); // This part of code is same than into file ecm/ajax/ecmdatabase.php TODO Remove duplicate diff --git a/htdocs/ecm/index_auto.php b/htdocs/ecm/index_auto.php index 342d7d74129..628ef871ea5 100644 --- a/htdocs/ecm/index_auto.php +++ b/htdocs/ecm/index_auto.php @@ -34,12 +34,6 @@ require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; // Load translation files required by the page $langs->loadLangs(array("ecm", "companies", "other", "users", "orders", "propal", "bills", "contracts")); -// Security check -if ($user->socid) { - $socid = $user->socid; -} -$result = restrictedArea($user, 'ecm', 0); - // Get parameters $socid = GETPOST('socid', 'int'); $action = GETPOST('action', 'aZ09'); @@ -87,6 +81,12 @@ $userstatic = new User($db); $error = 0; +// Security check +if ($user->socid) { + $socid = $user->socid; +} +$result = restrictedArea($user, 'ecm', 0); + /* * Actions diff --git a/htdocs/langs/en_US/ecm.lang b/htdocs/langs/en_US/ecm.lang index 5ced4ec5617..724e5aa59d7 100644 --- a/htdocs/langs/en_US/ecm.lang +++ b/htdocs/langs/en_US/ecm.lang @@ -19,7 +19,7 @@ ECMArea=DMS/ECM area ECMAreaDesc=The DMS/ECM (Document Management System / Electronic Content Management) area allows you to save, share and search quickly all kind of documents in Dolibarr. ECMAreaDesc2a=* Manual directories can be used to save documents not linked to a particular element. ECMAreaDesc2b=* Automatic directories are filled automatically when adding documents from the page of an element. -ECMAreaDesc3=* Medias directories are files into the subdirectory /medias of documents directory, readable by everybody with no need to be logged and no need to have the file shared explicitely. It is used to store image files from emailing or website module. +ECMAreaDesc3=* Medias directories are files into the subdirectory /medias of documents directory, readable by everybody with no need to be logged and no need to have the file shared explicitely. It is used to store image files for the emailing or website module for example. ECMSectionWasRemoved=Directory %s has been deleted. ECMSectionWasCreated=Directory %s has been created. ECMSearchByKeywords=Search by keywords From ed9db6c9ddf50de9255078b44539a55d29e69530 Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Feb 2023 16:36:48 +0100 Subject: [PATCH 2/3] Fix #yogosha15050 --- htdocs/user/card.php | 101 +++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 47 deletions(-) diff --git a/htdocs/user/card.php b/htdocs/user/card.php index 688ac6c28ac..08c2defd546 100644 --- a/htdocs/user/card.php +++ b/htdocs/user/card.php @@ -63,6 +63,9 @@ if (isModEnabled('stock')) { require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; } +// Load translation files required by page +$langs->loadLangs(array('users', 'companies', 'ldap', 'admin', 'hrm', 'stocks', 'other')); + $id = GETPOST('id', 'int'); $action = GETPOST('action', 'aZ09'); $mode = GETPOST('mode', 'alpha'); @@ -77,42 +80,8 @@ $datestartvalidity = dol_mktime(0, 0, 0, GETPOST('datestartvaliditymonth', 'int' $dateendvalidity = dol_mktime(0, 0, 0, GETPOST('dateendvaliditymonth', 'int'), GETPOST('dateendvalidityday', 'int'), GETPOST('dateendvalidityyear', 'int')); $dateofbirth = dol_mktime(0, 0, 0, GETPOST('dateofbirthmonth', 'int'), GETPOST('dateofbirthday', 'int'), GETPOST('dateofbirthyear', 'int')); -// Define value to know what current user can do on users -$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); -$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); -$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); -$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); -$canreadgroup = $canreaduser; -$caneditgroup = $canedituser; -if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { - $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); - $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); -} - $childids = $user->getAllChildIds(1); // For later, test on salary visibility -// Define value to know what current user can do on properties of edited user -if ($id > 0) { - // $user is the current logged user, $id is the user we want to edit - $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) || (($user->id != $id) && $user->hasRight("user", "user", "write"))); - $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password"))); -} - -// Security check -$socid = 0; -if ($user->socid > 0) { - $socid = $user->socid; -} -$feature2 = 'user'; -$result = restrictedArea($user, 'user', $id, 'user', $feature2); - -if ($user->id != $id && !$canreaduser) { - accessforbidden(); -} - -// Load translation files required by page -$langs->loadLangs(array('users', 'companies', 'ldap', 'admin', 'hrm', 'stocks', 'other')); - $object = new User($db); $extrafields = new ExtraFields($db); @@ -129,6 +98,38 @@ $error = 0; $acceptlocallinktomedia = (acceptLocalLinktoMedia() > 0 ? 1 : 0); +// Security check +$socid = 0; +if ($user->socid > 0) { + $socid = $user->socid; +} +$feature2 = 'user'; +$result = restrictedArea($user, 'user', $id, 'user', $feature2); + +// Define value to know what current user can do on users +$canadduser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); +$canreaduser = (!empty($user->admin) || $user->hasRight("user", "user", "read")); +$canedituser = (!empty($user->admin) || $user->hasRight("user", "user", "write")); // edit other user +$candisableuser = (!empty($user->admin) || $user->hasRight("user", "user", "delete")); +$canreadgroup = $canreaduser; +$caneditgroup = $canedituser; +if (!empty($conf->global->MAIN_USE_ADVANCED_PERMS)) { + $canreadgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "read")); + $caneditgroup = (!empty($user->admin) || $user->hasRight("user", "group_advance", "write")); +} + +if ($user->id != $id && !$canreaduser) { + accessforbidden(); +} + +// Define value to know what current user can do on properties of edited user +if ($id > 0) { + // $user is the current logged user, $id is the user we want to edit + $canedituser = (($user->id == $id) && $user->hasRight("user", "self", "write")); // can edit myself + $caneditfield = ((($user->id == $id) && $user->hasRight("user", "self", "write")) || (($user->id != $id) && $user->hasRight("user", "user", "write"))); + $caneditpassword = ((($user->id == $id) && $user->hasRight("user", "self", "password")) || (($user->id != $id) && $user->hasRight("user", "user", "password"))); +} + /** * Actions @@ -390,7 +391,7 @@ if (empty($reshook)) { } } - if ($action == 'update' && !$cancel) { + if ($action == 'update' && $canedituser) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; if ($caneditfield) { // Case we can edit all field @@ -430,8 +431,12 @@ if (empty($reshook)) { $object->national_registration_number = GETPOST("national_registration_number", 'alphanohtml'); } $object->gender = GETPOST("gender", 'aZ09'); - $object->pass = GETPOST("password", 'none'); // We can keep 'none' for password fields - $object->api_key = (GETPOST("api_key", 'alphanohtml')) ? GETPOST("api_key", 'alphanohtml') : $object->api_key; + if ($caneditpassword) { + $object->pass = GETPOST("password", 'none'); // We can keep 'none' for password fields + } + if ($caneditpassword || $user->hasRight("api", "apikey", "generate")) { + $object->api_key = (GETPOST("api_key", 'alphanohtml')) ? GETPOST("api_key", 'alphanohtml') : $object->api_key; + } if (!empty($user->admin)) { // admin flag can only be set/unset by an admin user. A test is also done later when forging sql request $object->admin = GETPOST("admin", "int"); } @@ -2074,7 +2079,7 @@ if ($action == 'create' || $action == 'adduserldap') { print "
'.$langs->trans("None").'
'.$langs->trans("None").'
"; @@ -2091,7 +2096,7 @@ if ($action == 'create' || $action == 'adduserldap') { /* * Card in edit mode */ - if ($action == 'edit' && ($canedituser || $caneditfield || $caneditpassword || ($user->id == $object->id))) { + if ($action == 'edit' && ($canedituser || $caneditpassword)) { print '
'; print ''; print ''; @@ -2417,12 +2422,14 @@ if ($action == 'create' || $action == 'adduserldap') { print "\n"; // API key - if (!empty($conf->api->enabled) && ($user->id == $id || $user->admin || $user->hasRight("api", "apikey", "generate"))) { + if (isModEnabled('api')) { print ''.$langs->trans("ApiKey").''; print ''; - print ''; - if (!empty($conf->use_javascript_ajax)) { - print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); + if ($caneditpassword || $user->hasRight("api", "apikey", "generate")) { + print ''; + if (!empty($conf->use_javascript_ajax)) { + print ' '.img_picto($langs->trans('Generate'), 'refresh', 'id="generate_api_key" class="linkobject"'); + } } print ''; } @@ -2879,10 +2886,10 @@ if ($action == 'create' || $action == 'adduserldap') { } } -if (!empty($conf->api->enabled)) { - // Add button to autosuggest a key - include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - print dolJSToSetRandomPassword('password', 'generate_password', 0); +// Add button to autosuggest a key +include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; +print dolJSToSetRandomPassword('password', 'generate_password', 0); +if (isModEnabled('api')) { print dolJSToSetRandomPassword('api_key', 'generate_api_key', 1); } From cbb6ca071ab76e4e2d5f6c215ff02d7ebadb3d0d Mon Sep 17 00:00:00 2001 From: Laurent Destailleur Date: Sat, 25 Feb 2023 19:48:33 +0100 Subject: [PATCH 3/3] Fix #yogosha15157 --- htdocs/adherents/class/api_members.class.php | 7 +- .../class/api_memberstypes.class.php | 5 +- .../class/api_subscriptions.class.php | 5 +- htdocs/api/class/api.class.php | 4 +- htdocs/api/class/api_setup.class.php | 112 +++++++---------- htdocs/asset/class/asset.class.php | 2 +- htdocs/bom/class/api_boms.class.php | 7 +- htdocs/bookcal/class/booking.class.php | 2 +- .../categories/class/api_categories.class.php | 7 +- .../action/class/api_agendaevents.class.php | 7 +- .../comm/propal/class/api_proposals.class.php | 17 ++- htdocs/comm/propal/class/propal.class.php | 2 +- htdocs/commande/class/api_orders.class.php | 7 +- htdocs/commande/class/commande.class.php | 2 +- .../bank/class/api_bankaccounts.class.php | 14 +-- .../facture/class/api_invoices.class.php | 7 +- .../facture/class/facture-rec.class.php | 2 +- htdocs/compta/facture/class/facture.class.php | 2 +- htdocs/contrat/class/api_contracts.class.php | 7 +- htdocs/contrat/class/contrat.class.php | 2 +- htdocs/core/class/html.form.class.php | 57 ++------- htdocs/core/customreports.php | 15 +-- htdocs/core/lib/functions.lib.php | 118 +++++++++++++----- htdocs/don/class/api_donations.class.php | 7 +- .../class/conferenceorbooth.class.php | 4 +- .../class/conferenceorboothattendee.class.php | 2 +- .../expedition/class/api_shipments.class.php | 7 +- .../class/api_expensereports.class.php | 7 +- .../class/api_interventions.class.php | 7 +- htdocs/fichinter/class/fichinter.class.php | 2 +- .../class/api_supplier_invoices.class.php | 7 +- .../fourn/class/api_supplier_orders.class.php | 7 +- .../class/fournisseur.commande.class.php | 2 +- .../class/api_knowledgemanagement.class.php | 7 +- .../template/class/api_mymodule.class.php | 7 +- .../template/class/myobject.class.php | 2 +- htdocs/mrp/class/api_mos.class.php | 7 +- htdocs/mrp/class/mo.class.php | 4 +- .../class/api_partnership.class.php | 7 +- .../partnership/class/partnership.class.php | 6 +- htdocs/product/class/api_products.class.php | 22 ++-- .../stock/class/api_stockmovements.class.php | 7 +- .../stock/class/api_warehouses.class.php | 7 +- htdocs/product/stock/class/entrepot.class.php | 4 +- .../stock/class/mouvementstock.class.php | 4 +- .../class/stocktransfer.class.php | 2 +- htdocs/projet/class/api_projects.class.php | 7 +- htdocs/projet/class/api_tasks.class.php | 7 +- .../reception/class/api_receptions.class.php | 7 +- .../class/api_recruitment.class.php | 14 +-- .../class/recruitmentjobposition.class.php | 6 +- htdocs/societe/class/api_contacts.class.php | 7 +- .../societe/class/api_thirdparties.class.php | 7 +- .../class/api_supplier_proposals.class.php | 7 +- htdocs/ticket/class/api_tickets.class.php | 7 +- htdocs/user/class/api_users.class.php | 14 +-- htdocs/zapier/class/api_zapier.class.php | 7 +- test/phpunit/FunctionsLibTest.php | 28 +++++ 58 files changed, 321 insertions(+), 345 deletions(-) diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 51ef1153a57..4ecf79d9079 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -238,11 +238,10 @@ class Members extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index 95c514bfedf..8179612d769 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -103,11 +103,10 @@ class MembersTypes extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 67484a723fd..dfde21dc5a1 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -101,11 +101,10 @@ class Subscriptions extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index e0acc8faac8..3a1a176d818 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -302,6 +302,7 @@ class DolibarrApi // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** * Return if a $sqlfilters parameter is valid + * Function no more used. Kept for backward compatibility with old APIs of modules * * @param string $sqlfilters sqlfilter string * @param string $error Error message @@ -317,7 +318,8 @@ class DolibarrApi // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps // phpcs:disable PEAR.NamingConventions.ValidFunctionName.PublicUnderscore /** - * Function to forge a SQL criteria from a Generic filter string + * Function to forge a SQL criteria from a Generic filter string. + * Function no more used. Kept for backward compatibility with old APIs of modules * * @param array $matches Array of found string by regex search. * Each entry is 1 and only 1 criteria. diff --git a/htdocs/api/class/api_setup.class.php b/htdocs/api/class/api_setup.class.php index 9dcd168f344..95243f191ca 100644 --- a/htdocs/api/class/api_setup.class.php +++ b/htdocs/api/class/api_setup.class.php @@ -77,11 +77,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -141,11 +140,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -206,11 +204,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -277,11 +274,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -378,11 +374,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -554,11 +549,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -669,11 +663,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -733,11 +726,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -802,11 +794,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -868,11 +859,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -943,11 +933,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1014,11 +1003,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -1088,11 +1076,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1153,11 +1140,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1213,11 +1199,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1274,11 +1259,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1337,11 +1321,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1396,11 +1379,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1462,11 +1444,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1523,11 +1504,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1586,11 +1566,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } @@ -1650,11 +1629,10 @@ class Setup extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } diff --git a/htdocs/asset/class/asset.class.php b/htdocs/asset/class/asset.class.php index c01f4b967c4..00404d21d99 100644 --- a/htdocs/asset/class/asset.class.php +++ b/htdocs/asset/class/asset.class.php @@ -98,7 +98,7 @@ class Asset extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'noteditable'=>'0', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'validate'=>'1', 'comment'=>"Reference of object"), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'showoncombobox'=>'2', 'validate'=>'1',), - 'fk_asset_model' => array('type'=>'integer:AssetModel:asset/class/assetmodel.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'AssetModel', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'validate'=>'1',), + 'fk_asset_model' => array('type'=>'integer:AssetModel:asset/class/assetmodel.class.php:1:((status:=:1) and (entity:IN:__SHARED_ENTITIES__))', 'label'=>'AssetModel', 'enabled'=>'1', 'position'=>40, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'validate'=>'1',), 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>'1', 'position'=>50, 'notnull'=>1, 'visible'=>0, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp', 'validate'=>'1',), 'acquisition_type' => array('type'=>'smallint', 'label'=>'AssetAcquisitionType', 'enabled'=>'1', 'position'=>60, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetAcquisitionTypeNew', '1'=>'AssetAcquisitionTypeOccasion'), 'validate'=>'1',), 'asset_type' => array('type'=>'smallint', 'label'=>'AssetType', 'enabled'=>'1', 'position'=>70, 'notnull'=>1, 'visible'=>1, 'arrayofkeyval'=>array('0'=>'AssetTypeIntangible', '1'=>'AssetTypeTangible', '2'=>'AssetTypeInProgress', '3'=>'AssetTypeFinancial'), 'validate'=>'1',), diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php index fb7d175a229..57b0d26e80a 100644 --- a/htdocs/bom/class/api_boms.class.php +++ b/htdocs/bom/class/api_boms.class.php @@ -150,11 +150,10 @@ class Boms extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/bookcal/class/booking.class.php b/htdocs/bookcal/class/booking.class.php index a74cb87a43d..616fbbde03e 100644 --- a/htdocs/bookcal/class/booking.class.php +++ b/htdocs/bookcal/class/booking.class.php @@ -104,7 +104,7 @@ class Booking extends CommonObject public $fields=array( 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>1.2, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'searchall'=>1, 'validate'=>'1', 'comment'=>"Reference of object"), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'help'=>"LinkToThirparty", 'validate'=>'1',), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) and (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'help'=>"LinkToThirparty", 'validate'=>'1',), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'validate'=>'1',), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3, 'validate'=>'1',), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0, 'cssview'=>'wordbreak', 'validate'=>'1',), diff --git a/htdocs/categories/class/api_categories.class.php b/htdocs/categories/class/api_categories.class.php index e59ff070aec..e10371f87b6 100644 --- a/htdocs/categories/class/api_categories.class.php +++ b/htdocs/categories/class/api_categories.class.php @@ -149,11 +149,10 @@ class Categories extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/comm/action/class/api_agendaevents.class.php b/htdocs/comm/action/class/api_agendaevents.class.php index 8c13709b250..058de48542d 100644 --- a/htdocs/comm/action/class/api_agendaevents.class.php +++ b/htdocs/comm/action/class/api_agendaevents.class.php @@ -159,11 +159,10 @@ class AgendaEvents extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/comm/propal/class/api_proposals.class.php b/htdocs/comm/propal/class/api_proposals.class.php index cf675e01b62..cc6bfb2aa2f 100644 --- a/htdocs/comm/propal/class/api_proposals.class.php +++ b/htdocs/comm/propal/class/api_proposals.class.php @@ -204,11 +204,10 @@ class Proposals extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -309,14 +308,14 @@ class Proposals extends DolibarrApi } if (!empty($sqlfilters)) { - if (!DolibarrApi::_checkFilters($sqlfilters)) { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$sqlfilters); + $errormessage = ''; + $sql = forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)'; - $filters = " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } - $this->propal->getLinesArray($filters); + $this->propal->getLinesArray($sql); $result = array(); foreach ($this->propal->lines as $line) { array_push($result, $this->_cleanObjectDatas($line)); diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index 9dca1b1051d..8606b9df87d 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -302,7 +302,7 @@ class Propal extends CommonObject 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>22), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>40), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'position'=>23), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>24), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>24), 'tms' =>array('type'=>'timestamp', 'label'=>'DateModification', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>25), 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>55), 'datep' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>-1, 'position'=>60), diff --git a/htdocs/commande/class/api_orders.class.php b/htdocs/commande/class/api_orders.class.php index 2c916abda9a..af460b3b459 100644 --- a/htdocs/commande/class/api_orders.class.php +++ b/htdocs/commande/class/api_orders.class.php @@ -208,11 +208,10 @@ class Orders extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index a09fa8bdf5e..1b1b77343dd 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -307,7 +307,7 @@ class Commande extends CommonOrder 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'RefExt', 'enabled'=>1, 'visible'=>0, 'position'=>26), 'ref_client' =>array('type'=>'varchar(255)', 'label'=>'RefCustomer', 'enabled'=>1, 'visible'=>-1, 'position'=>28), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>20), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>25), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>25), 'date_commande' =>array('type'=>'date', 'label'=>'Date', 'enabled'=>1, 'visible'=>1, 'position'=>60), 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>62), 'date_cloture' =>array('type'=>'datetime', 'label'=>'DateClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>65), diff --git a/htdocs/compta/bank/class/api_bankaccounts.class.php b/htdocs/compta/bank/class/api_bankaccounts.class.php index c9886a176f0..052c45fbc56 100644 --- a/htdocs/compta/bank/class/api_bankaccounts.class.php +++ b/htdocs/compta/bank/class/api_bankaccounts.class.php @@ -82,11 +82,10 @@ class BankAccounts extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -440,11 +439,10 @@ class BankAccounts extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= " ORDER BY rowid"; diff --git a/htdocs/compta/facture/class/api_invoices.class.php b/htdocs/compta/facture/class/api_invoices.class.php index 4c1392e28eb..47fd0263d7e 100644 --- a/htdocs/compta/facture/class/api_invoices.class.php +++ b/htdocs/compta/facture/class/api_invoices.class.php @@ -237,11 +237,10 @@ class Invoices extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/compta/facture/class/facture-rec.class.php b/htdocs/compta/facture/class/facture-rec.class.php index f02850492b5..22ea97feb6d 100644 --- a/htdocs/compta/facture/class/facture-rec.class.php +++ b/htdocs/compta/facture/class/facture-rec.class.php @@ -181,7 +181,7 @@ class FactureRec extends CommonInvoice 'total_ht' =>array('type'=>'double(24,8)', 'label'=>'Total', 'enabled'=>1, 'visible'=>-1, 'position'=>70, 'isameasure'=>1), 'total_ttc' =>array('type'=>'double(24,8)', 'label'=>'Total ttc', 'enabled'=>1, 'visible'=>-1, 'position'=>75, 'isameasure'=>1), 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'Fk user author', 'enabled'=>1, 'visible'=>-1, 'position'=>80), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>85), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk projet', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>85), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'Fk cond reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>90), 'fk_mode_reglement' =>array('type'=>'integer', 'label'=>'Fk mode reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>95), 'date_lim_reglement' =>array('type'=>'date', 'label'=>'Date lim reglement', 'enabled'=>1, 'visible'=>-1, 'position'=>100), diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 161087a3bf9..2447db6af5d 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -336,7 +336,7 @@ class Facture extends CommonInvoice 'fk_user_valid' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>167), 'fk_user_closing' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserClosing', 'enabled'=>1, 'visible'=>-1, 'position'=>168), 'fk_facture_source' =>array('type'=>'integer', 'label'=>'SourceInvoice', 'enabled'=>1, 'visible'=>-1, 'position'=>170), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>1, 'visible'=>-1, 'position'=>175), 'fk_account' =>array('type'=>'integer', 'label'=>'Fk account', 'enabled'=>1, 'visible'=>-1, 'position'=>180), 'fk_currency' =>array('type'=>'varchar(3)', 'label'=>'CurrencyCode', 'enabled'=>1, 'visible'=>-1, 'position'=>185), 'fk_cond_reglement' =>array('type'=>'integer', 'label'=>'PaymentTerm', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>190), diff --git a/htdocs/contrat/class/api_contracts.class.php b/htdocs/contrat/class/api_contracts.class.php index f38fa4758d9..68ace23a26a 100644 --- a/htdocs/contrat/class/api_contracts.class.php +++ b/htdocs/contrat/class/api_contracts.class.php @@ -148,11 +148,10 @@ class Contracts extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php index 8f66cbdef2e..a29df83b834 100644 --- a/htdocs/contrat/class/contrat.class.php +++ b/htdocs/contrat/class/contrat.class.php @@ -233,7 +233,7 @@ class Contrat extends CommonObject 'datec' =>array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>1, 'visible'=>-1, 'position'=>40), 'date_contrat' =>array('type'=>'datetime', 'label'=>'Date contrat', 'enabled'=>1, 'visible'=>-1, 'position'=>45), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>70), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>75), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>75), 'fk_commercial_signature' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative Signature', 'enabled'=>1, 'visible'=>-1, 'position'=>80), 'fk_commercial_suivi' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'SaleRepresentative follower', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'fk_user_author' =>array('type'=>'integer:User:user/class/user.class.php', 'label'=>'UserAuthor', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>90), diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 921618f7edc..62fd1db45e6 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -7769,40 +7769,6 @@ class Form return $out; } - /** - * Function to forge a SQL criteria from a Dolibarr filter syntax string. - * - * @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%'" - */ - protected static function forgeCriteriaCallback($matches) - { - global $db; - - //dol_syslog("Convert matches ".$matches[1]); - if (empty($matches[1])) { - return ''; - } - $tmp = explode(':', $matches[1]); - if (count($tmp) < 3) { - return ''; - } - - $tmpescaped = $tmp[2]; - $regbis = array(); - - if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis)) { - $tmpescaped = "'".$db->escape($regbis[1])."'"; - } else { - $tmpescaped = $db->escape($tmpescaped); - } - - if ($tmp[1] == '!=') { - $tmp[1] = '<>'; - } - - return $db->escape($tmp[0]).' '.strtoupper($db->escape($tmp[1]))." ".$tmpescaped; - } /** * Output html form to select an object. @@ -7916,12 +7882,11 @@ class Form } if ($filter) { // Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')" - /*if (! DolibarrApi::_checkFilters($filter)) - { - throw new RestException(503, 'Error when validating parameter sqlfilters '.$filter); - }*/ - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'Form::forgeCriteriaCallback', $filter).")"; + $errormessage = ''; + $sql .= forgeSQLFromUniversalSearchCriteria($filter, $errormessage); + if ($errormessage) { + return 'Error forging a SQL request from an universal criteria: '.$errormessage; + } } } $sql .= $this->db->order($sortfield ? $sortfield : $fieldstoshow, "ASC"); @@ -10275,14 +10240,12 @@ class Form $search_component_params_hidden .= '('.$search_component_params_hidden.')'; } $errormessage = ''; - if (!dolCheckFilters($search_component_params_hidden, $errormessage)) { - print 'ERROR in parsing search string'; + $searchtags = forgeSQLFromUniversalSearchCriteria($search_component_params_hidden, $errormessage); + if ($errormessage) { + print 'ERROR in parsing search string: '.dol_escape_htmltag($errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - //var_dump($search_component_params_hidden); - $htmltags = preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $search_component_params_hidden); - //var_dump($htmltags); - $ret .= 'x '.$htmltags.''; + //var_dump($searchtags); + $ret .= 'x '.dol_escape_htmltag($searchtags).''; } //$ret .= ''; diff --git a/htdocs/core/customreports.php b/htdocs/core/customreports.php index fefdc5880c8..34561c91621 100644 --- a/htdocs/core/customreports.php +++ b/htdocs/core/customreports.php @@ -295,12 +295,7 @@ if (is_array($search_groupby) && count($search_groupby)) { $sqlfilters = GETPOST('search_component_params_hidden', 'alphanohtml'); if ($sqlfilters) { $errormessage = ''; - if (dolCheckFilters($sqlfilters, $errormessage)) { - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " WHERE (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")"; - } else { - print $errormessage; - } + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); }*/ $sql .= " LIMIT ".((int) ($MAXUNIQUEVALFORGROUP + 1)); @@ -681,11 +676,9 @@ if (!empty($search_measures) && !empty($search_xaxis)) { $sqlfilters = $search_component_params_hidden; if ($sqlfilters) { $errormessage = ''; - if (dolCheckFilters($sqlfilters, $errormessage)) { - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'dolForgeCriteriaCallback', $sqlfilters).")"; - } else { - print $errormessage; + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + print dol_escape_htmltag($errormessage); } } $sql .= " GROUP BY "; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 58a77279e6c..835c81c7131 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -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 diff --git a/htdocs/don/class/api_donations.class.php b/htdocs/don/class/api_donations.class.php index f9af0568bf0..fee513f2ed7 100644 --- a/htdocs/don/class/api_donations.class.php +++ b/htdocs/don/class/api_donations.class.php @@ -129,11 +129,10 @@ class Donations extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/eventorganization/class/conferenceorbooth.class.php b/htdocs/eventorganization/class/conferenceorbooth.class.php index b15dcf3e545..db6bbf7175e 100644 --- a/htdocs/eventorganization/class/conferenceorbooth.class.php +++ b/htdocs/eventorganization/class/conferenceorbooth.class.php @@ -106,8 +106,8 @@ class ConferenceOrBooth extends ActionComm 'id' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'integer', 'label'=>'Ref', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>2, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'csslist'=>'left', 'comment'=>"Id"), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth300', 'csslist'=>'tdoverflowmax125', 'help'=>"OrganizationEvenLabelName", 'showoncombobox'=>'1', 'autofocusoncreate'=>1), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:t.usage_organize_event=1', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'position'=>52, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'project', 'css'=>'tdoverflowmax150 maxwidth500', 'csslist'=>'width100'), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'picto'=>'company', 'csslist'=>'tdoverflowmax125', 'css'=>'maxwidth500'), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:(t.usage_organize_event:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'position'=>52, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'project', 'css'=>'tdoverflowmax150 maxwidth500', 'csslist'=>'width100'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'picto'=>'company', 'csslist'=>'tdoverflowmax125', 'css'=>'maxwidth500'), 'note' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>3), 'fk_action' => array('type'=>'sellist:c_actioncomm:libelle:id::module LIKE (\'%@eventorganization\')', 'label'=>'Format', 'enabled'=>'1', 'position'=>60, 'notnull'=>1, 'visible'=>1, 'css'=>'width100', 'csslist'=>'tdoverflowmax100'), 'datep' => array('type'=>'datetime', 'label'=>'DateStart', 'enabled'=>'1', 'position'=>70, 'notnull'=>0, 'visible'=>1, 'showoncombobox'=>'2',), diff --git a/htdocs/eventorganization/class/conferenceorboothattendee.class.php b/htdocs/eventorganization/class/conferenceorboothattendee.class.php index be06f70979e..062de3ef8d7 100644 --- a/htdocs/eventorganization/class/conferenceorboothattendee.class.php +++ b/htdocs/eventorganization/class/conferenceorboothattendee.class.php @@ -108,7 +108,7 @@ class ConferenceOrBoothAttendee extends CommonObject 'email' => array('type'=>'mail', 'label'=>'EmailAttendee', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'index'=>1, 'autofocusoncreate'=>1, 'searchall'=>1), 'firstname' => array('type'=>'varchar(100)', 'label'=>'Firstname', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'searchall'=>1), 'lastname' => array('type'=>'varchar(100)', 'label'=>'Lastname', 'enabled'=>'1', 'position'=>32, 'notnull'=>0, 'visible'=>1, 'index'=>1, 'searchall'=>1), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status = 1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'position'=>40, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'picto'=>'company', 'css'=>'tdoverflowmax150 maxwidth500'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'position'=>40, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'help'=>"OrganizationEventLinkToThirdParty", 'picto'=>'company', 'css'=>'tdoverflowmax150 maxwidth500'), 'email_company' => array('type'=>'mail', 'label'=>'EmailCompany', 'enabled'=>'1', 'position'=>41, 'notnull'=>0, 'visible'=>-2, 'searchall'=>1), 'date_subscription' => array('type'=>'datetime', 'label'=>'DateOfRegistration', 'enabled'=>'1', 'position'=>56, 'notnull'=>1, 'visible'=>1, 'showoncombobox'=>'1',), 'fk_invoice' => array('type'=>'integer:Facture:compta/facture/class/facture.class.php', 'label'=>'Invoice', 'enabled'=>'$conf->facture->enabled', 'position'=>57, 'notnull'=>0, 'visible'=>-1, 'index'=>0, 'picto'=>'bill', 'css'=>'tdoverflowmax150 maxwidth500'), diff --git a/htdocs/expedition/class/api_shipments.class.php b/htdocs/expedition/class/api_shipments.class.php index 357683ef35a..fea57fbea10 100644 --- a/htdocs/expedition/class/api_shipments.class.php +++ b/htdocs/expedition/class/api_shipments.class.php @@ -145,11 +145,10 @@ class Shipments extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index 876b08f18f0..c3bfeb2264d 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -118,11 +118,10 @@ class ExpenseReports extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/fichinter/class/api_interventions.class.php b/htdocs/fichinter/class/api_interventions.class.php index f96dc3d6aa7..4b97d6e21ad 100644 --- a/htdocs/fichinter/class/api_interventions.class.php +++ b/htdocs/fichinter/class/api_interventions.class.php @@ -152,11 +152,10 @@ class Interventions extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/fichinter/class/fichinter.class.php b/htdocs/fichinter/class/fichinter.class.php index 376e14c277f..cc6feb22f1c 100644 --- a/htdocs/fichinter/class/fichinter.class.php +++ b/htdocs/fichinter/class/fichinter.class.php @@ -39,7 +39,7 @@ class Fichinter extends CommonObject public $fields = array( 'rowid' =>array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'position'=>10), 'fk_soc' =>array('type'=>'integer:Societe:societe/class/societe.class.php', 'label'=>'ThirdParty', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>15), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk projet', 'enabled'=>'isModEnabled("project")', 'visible'=>-1, 'position'=>20), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk projet', 'enabled'=>'isModEnabled("project")', 'visible'=>-1, 'position'=>20), 'fk_contrat' =>array('type'=>'integer', 'label'=>'Fk contrat', 'enabled'=>'$conf->contrat->enabled', 'visible'=>-1, 'position'=>25), 'ref' =>array('type'=>'varchar(30)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>-1, 'notnull'=>1, 'showoncombobox'=>1, 'position'=>30), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), diff --git a/htdocs/fourn/class/api_supplier_invoices.class.php b/htdocs/fourn/class/api_supplier_invoices.class.php index 5cc3e5592a2..02bed2c5e0a 100644 --- a/htdocs/fourn/class/api_supplier_invoices.class.php +++ b/htdocs/fourn/class/api_supplier_invoices.class.php @@ -160,11 +160,10 @@ class SupplierInvoices extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/fourn/class/api_supplier_orders.class.php b/htdocs/fourn/class/api_supplier_orders.class.php index d55a398dbd6..4ad1f951883 100644 --- a/htdocs/fourn/class/api_supplier_orders.class.php +++ b/htdocs/fourn/class/api_supplier_orders.class.php @@ -176,11 +176,10 @@ class SupplierOrders extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index feb2466078d..2cf0401d6eb 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -219,7 +219,7 @@ class CommandeFournisseur extends CommonOrder 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>25, 'searchall'=>1), 'ref_ext' =>array('type'=>'varchar(255)', 'label'=>'Ref ext', 'enabled'=>1, 'visible'=>0, 'position'=>35), 'ref_supplier' =>array('type'=>'varchar(255)', 'label'=>'RefOrderSupplierShort', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'searchall'=>1), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>45), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>"isModEnabled('project')", 'visible'=>-1, 'position'=>45), 'date_valid' =>array('type'=>'datetime', 'label'=>'DateValidation', 'enabled'=>1, 'visible'=>-1, 'position'=>60), 'date_approve' =>array('type'=>'datetime', 'label'=>'DateApprove', 'enabled'=>1, 'visible'=>-1, 'position'=>62), 'date_approve2' =>array('type'=>'datetime', 'label'=>'DateApprove2', 'enabled'=>1, 'visible'=>3, 'position'=>64), diff --git a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php index 8232287b23b..6d5c15c0dc6 100644 --- a/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php +++ b/htdocs/knowledgemanagement/class/api_knowledgemanagement.class.php @@ -199,11 +199,10 @@ class KnowledgeManagement extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/modulebuilder/template/class/api_mymodule.class.php b/htdocs/modulebuilder/template/class/api_mymodule.class.php index ce92ef5ea8e..fdb56ff3c67 100644 --- a/htdocs/modulebuilder/template/class/api_mymodule.class.php +++ b/htdocs/modulebuilder/template/class/api_mymodule.class.php @@ -156,11 +156,10 @@ class MyModuleApi extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/modulebuilder/template/class/myobject.class.php b/htdocs/modulebuilder/template/class/myobject.class.php index 14b8fc6c09c..f309ef346c5 100644 --- a/htdocs/modulebuilder/template/class/myobject.class.php +++ b/htdocs/modulebuilder/template/class/myobject.class.php @@ -119,7 +119,7 @@ class MyObject extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'searchall'=>1, 'css'=>'minwidth300', 'cssview'=>'wordbreak', 'help'=>'Help text', 'showoncombobox'=>2, 'validate'=>1, 'alwayseditable'=>1), 'amount' => array('type'=>'price', 'label'=>'Amount', 'enabled'=>1, 'visible'=>1, 'default'=>'null', 'position'=>40, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for amount', 'validate'=>1), 'qty' => array('type'=>'real', 'label'=>'Qty', 'enabled'=>1, 'visible'=>1, 'default'=>'0', 'position'=>45, 'searchall'=>0, 'isameasure'=>1, 'help'=>'Help text for quantity', 'css'=>'maxwidth75imp', 'validate'=>1), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'picto'=>'company', 'label'=>'ThirdParty', 'visible'=> 1, 'enabled'=>'$conf->societe->enabled', 'position'=>50, 'notnull'=>-1, 'index'=>1, 'help'=>'OrganizationEventLinkToThirdParty', 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>52, 'notnull'=>-1, 'index'=>1, 'validate'=>1, 'css'=>'maxwidth500 widthcentpercentminusxx', 'csslist'=>'tdoverflowmax150'), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>3, 'position'=>60, 'validate'=>1), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'validate'=>1, 'cssview'=>'wordbreak'), diff --git a/htdocs/mrp/class/api_mos.class.php b/htdocs/mrp/class/api_mos.class.php index b747e5eafce..2312f4bd636 100644 --- a/htdocs/mrp/class/api_mos.class.php +++ b/htdocs/mrp/class/api_mos.class.php @@ -148,11 +148,10 @@ class Mos extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index 68523ace9da..9c27a21b1f5 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -101,13 +101,13 @@ class Mo extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>1, 'visible'=>-2, 'position'=>1, 'notnull'=>1, 'index'=>1, 'comment'=>"Id",), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>1, 'visible'=>0, 'position'=>5, 'notnull'=>1, 'default'=>'1', 'index'=>1), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of object", 'showoncombobox'=>'1', 'noteditable'=>1), - 'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:t.status=1', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>'$conf->bom->enabled', 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth300', 'csslist'=>'nowraponall', 'picto'=>'bom'), + 'fk_bom' => array('type'=>'integer:Bom:bom/class/bom.class.php:0:(t.status:=:1)', 'filter'=>'active=1', 'label'=>'BOM', 'enabled'=>'$conf->bom->enabled', 'visible'=>1, 'position'=>33, 'notnull'=>-1, 'index'=>1, 'comment'=>"Original BOM", 'css'=>'minwidth100 maxwidth300', 'csslist'=>'nowraponall', 'picto'=>'bom'), 'mrptype' => array('type'=>'integer', 'label'=>'Type', 'enabled'=>1, 'visible'=>1, 'position'=>34, 'notnull'=>1, 'default'=>'0', 'arrayofkeyval'=>array(0=>'Manufacturing', 1=>'Disassemble'), 'css'=>'minwidth150', 'csslist'=>'minwidth150 center'), 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:0', 'label'=>'Product', 'enabled'=>'$conf->product->enabled', 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'comment'=>"Product to produce", 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax100', 'picto'=>'product'), 'qty' => array('type'=>'real', 'label'=>'QtyToProduce', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'notnull'=>1, 'comment'=>"Qty to produce", 'css'=>'width75', 'default'=>1, 'isameasure'=>1), 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>42, 'notnull'=>-1, 'searchall'=>1, 'showoncombobox'=>'2', 'css'=>'maxwidth300', 'csslist'=>'tdoverflowmax200', 'alwayseditable'=>1), 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'$conf->societe->enabled', 'visible'=>-1, 'position'=>50, 'notnull'=>-1, 'index'=>1, 'css'=>'maxwidth400', 'csslist'=>'tdoverflowmax150'), - 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>51, 'notnull'=>-1, 'index'=>1, 'css'=>'minwidth200 maxwidth400', 'csslist'=>'tdoverflowmax100'), + 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'picto'=>'project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>51, 'notnull'=>-1, 'index'=>1, 'css'=>'minwidth200 maxwidth400', 'csslist'=>'tdoverflowmax100'), 'fk_warehouse' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:0', 'label'=>'WarehouseForProduction', 'picto'=>'stock', 'enabled'=>'$conf->stock->enabled', 'visible'=>1, 'position'=>52, 'css'=>'maxwidth400', 'csslist'=>'tdoverflowmax200'), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>1, 'visible'=>0, 'position'=>61, 'notnull'=>-1,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>1, 'visible'=>0, 'position'=>62, 'notnull'=>-1,), diff --git a/htdocs/partnership/class/api_partnership.class.php b/htdocs/partnership/class/api_partnership.class.php index 1e1c7ca80fe..13bc447c51d 100644 --- a/htdocs/partnership/class/api_partnership.class.php +++ b/htdocs/partnership/class/api_partnership.class.php @@ -156,11 +156,10 @@ class PartnershipApi extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/partnership/class/partnership.class.php b/htdocs/partnership/class/partnership.class.php index fab8b1ce32a..15d75f20cb3 100644 --- a/htdocs/partnership/class/partnership.class.php +++ b/htdocs/partnership/class/partnership.class.php @@ -104,8 +104,8 @@ class Partnership extends CommonObject 'rowid' => array('type'=>'integer', 'label'=>'TechnicalID', 'enabled'=>'1', 'position'=>1, 'notnull'=>1, 'visible'=>0, 'noteditable'=>'1', 'index'=>1, 'css'=>'left', 'comment'=>"Id"), 'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>'1', 'position'=>10, 'notnull'=>1, 'visible'=>4, 'noteditable'=>'1', 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'showoncombobox'=>'1', 'comment'=>"Reference of object"), 'entity' => array('type'=>'integer', 'label'=>'Entity', 'enabled'=>'1', 'position'=>15, 'notnull'=>1, 'visible'=>-2, 'default'=>'1', 'index'=>1,), - 'fk_type' => array('type'=>'integer:PartnershipType:partnership/class/partnership_type.class.php:0:active=1', 'label'=>'Type', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'csslist'=>'tdoverflowmax100'), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax125',), + 'fk_type' => array('type'=>'integer:PartnershipType:partnership/class/partnership_type.class.php:0:(active:=:1)', 'label'=>'Type', 'enabled'=>'1', 'position'=>20, 'notnull'=>1, 'visible'=>1, 'csslist'=>'tdoverflowmax100'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'picto'=>'company', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax125',), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), 'note_private' => array('type'=>'html', 'label'=>'NotePrivate', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>0,), 'date_creation' => array('type'=>'datetime', 'label'=>'DateCreation', 'enabled'=>'1', 'position'=>500, 'notnull'=>1, 'visible'=>-2,), @@ -197,7 +197,7 @@ class Partnership extends CommonObject if (getDolGlobalString('PARTNERSHIP_IS_MANAGED_FOR') == 'member') { $this->fields['fk_member'] = array('type'=>'integer:Adherent:adherents/class/adherent.class.php:1', 'label'=>'Member', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'member', 'csslist'=>'tdoverflowmax150'); } else { - $this->fields['fk_soc'] = array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'company', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150'); + $this->fields['fk_soc'] = array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1, 'picto'=>'company', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150'); } if (empty($conf->global->MAIN_SHOW_TECHNICAL_ID) && isset($this->fields['rowid']) && !empty($this->fields['ref'])) { diff --git a/htdocs/product/class/api_products.class.php b/htdocs/product/class/api_products.class.php index 7a10293d7e4..ac666824f0e 100644 --- a/htdocs/product/class/api_products.class.php +++ b/htdocs/product/class/api_products.class.php @@ -222,12 +222,10 @@ class Products extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - //var_dump($sqlfilters);exit; - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; // We must accept datc:<:2020-01-01 10:10:10 - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } //this query will return total products with the filters given @@ -905,11 +903,10 @@ class Products extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -1033,11 +1030,10 @@ class Products extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/product/stock/class/api_stockmovements.class.php b/htdocs/product/stock/class/api_stockmovements.class.php index 544485060af..942cf6fe101 100644 --- a/htdocs/product/stock/class/api_stockmovements.class.php +++ b/htdocs/product/stock/class/api_stockmovements.class.php @@ -110,11 +110,10 @@ class StockMovements extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/product/stock/class/api_warehouses.class.php b/htdocs/product/stock/class/api_warehouses.class.php index 0cf0e57fe3a..a0646598d96 100644 --- a/htdocs/product/stock/class/api_warehouses.class.php +++ b/htdocs/product/stock/class/api_warehouses.class.php @@ -117,11 +117,10 @@ class Warehouses extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/product/stock/class/entrepot.class.php b/htdocs/product/stock/class/entrepot.class.php index 8393b081a90..55e365f07da 100644 --- a/htdocs/product/stock/class/entrepot.class.php +++ b/htdocs/product/stock/class/entrepot.class.php @@ -127,8 +127,8 @@ class Entrepot extends CommonObject 'ref' =>array('type'=>'varchar(255)', 'label'=>'Ref', 'enabled'=>1, 'visible'=>1, 'showoncombobox'=>1, 'position'=>25, 'searchall'=>1), 'description' =>array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-2, 'position'=>35, 'searchall'=>1), 'lieu' =>array('type'=>'varchar(64)', 'label'=>'LocationSummary', 'enabled'=>1, 'visible'=>1, 'position'=>40, 'showoncombobox'=>2, 'searchall'=>1), - 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:statut=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), - 'fk_project' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>25), + 'fk_parent' =>array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ParentWarehouse', 'enabled'=>1, 'visible'=>-2, 'position'=>41), + 'fk_project' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'position'=>25), 'address' =>array('type'=>'varchar(255)', 'label'=>'Address', 'enabled'=>1, 'visible'=>-2, 'position'=>45, 'searchall'=>1), 'zip' =>array('type'=>'varchar(10)', 'label'=>'Zip', 'enabled'=>1, 'visible'=>-2, 'position'=>50, 'searchall'=>1), 'town' =>array('type'=>'varchar(50)', 'label'=>'Town', 'enabled'=>1, 'visible'=>-2, 'position'=>55, 'searchall'=>1), diff --git a/htdocs/product/stock/class/mouvementstock.class.php b/htdocs/product/stock/class/mouvementstock.class.php index ac5d612394b..55be0eaba3c 100644 --- a/htdocs/product/stock/class/mouvementstock.class.php +++ b/htdocs/product/stock/class/mouvementstock.class.php @@ -119,12 +119,12 @@ class MouvementStock extends CommonObject 'fk_origin' =>array('type'=>'integer', 'label'=>'Fk origin', 'enabled'=>1, 'visible'=>-1, 'position'=>60), 'origintype' =>array('type'=>'varchar(32)', 'label'=>'Origintype', 'enabled'=>1, 'visible'=>-1, 'position'=>65), 'model_pdf' =>array('type'=>'varchar(255)', 'label'=>'Model pdf', 'enabled'=>1, 'visible'=>0, 'position'=>70), - 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>75), + 'fk_projet' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'visible'=>-1, 'notnull'=>1, 'position'=>75), 'inventorycode' =>array('type'=>'varchar(128)', 'label'=>'InventoryCode', 'enabled'=>1, 'visible'=>-1, 'position'=>80), 'batch' =>array('type'=>'varchar(30)', 'label'=>'Batch', 'enabled'=>1, 'visible'=>-1, 'position'=>85), 'eatby' =>array('type'=>'date', 'label'=>'Eatby', 'enabled'=>1, 'visible'=>-1, 'position'=>90), 'sellby' =>array('type'=>'date', 'label'=>'Sellby', 'enabled'=>1, 'visible'=>-1, 'position'=>95), - 'fk_project' =>array('type'=>'integer:Project:projet/class/project.class.php:1:fk_statut=1', 'label'=>'Fk project', 'enabled'=>1, 'visible'=>-1, 'position'=>100), + 'fk_project' =>array('type'=>'integer:Project:projet/class/project.class.php:1:(fk_statut:=:1)', 'label'=>'Fk project', 'enabled'=>1, 'visible'=>-1, 'position'=>100), ); diff --git a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php index 0711815da15..441c420bf08 100644 --- a/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php +++ b/htdocs/product/stock/stocktransfer/class/stocktransfer.class.php @@ -123,7 +123,7 @@ class StockTransfer extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>'1', 'position'=>30, 'notnull'=>0, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth200'/*, 'help'=>"Help text"*/, 'showoncombobox'=>'1',), 'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>'1', 'position'=>31, 'notnull'=>0, 'visible'=>3,), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'position'=>32, 'notnull'=>-1, 'visible'=>-1, 'index'=>1,), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirdparty"*/,), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'ThirdParty', 'enabled'=>'1', 'position'=>50, 'notnull'=>-1, 'visible'=>1, 'index'=>1/*, 'help'=>"LinkToThirdparty"*/,), 'fk_warehouse_source' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt source', 'enabled'=>'1', 'position'=>50, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferSource',), 'fk_warehouse_destination' => array('type'=>'integer:Entrepot:product/stock/class/entrepot.class.php', 'label'=>'Entrepôt de destination', 'enabled'=>'1', 'position'=>51, 'notnull'=>0, 'visible'=>1, 'help'=>'HelpWarehouseStockTransferDestination'), 'note_public' => array('type'=>'html', 'label'=>'NotePublic', 'enabled'=>'1', 'position'=>61, 'notnull'=>0, 'visible'=>0,), diff --git a/htdocs/projet/class/api_projects.class.php b/htdocs/projet/class/api_projects.class.php index 9ed1bbf1441..f5c23f4b040 100644 --- a/htdocs/projet/class/api_projects.class.php +++ b/htdocs/projet/class/api_projects.class.php @@ -152,11 +152,10 @@ class Projects extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/projet/class/api_tasks.class.php b/htdocs/projet/class/api_tasks.class.php index cd232061bc4..64690f90950 100644 --- a/htdocs/projet/class/api_tasks.class.php +++ b/htdocs/projet/class/api_tasks.class.php @@ -150,11 +150,10 @@ class Tasks extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/reception/class/api_receptions.class.php b/htdocs/reception/class/api_receptions.class.php index 473650161e2..55e3fa59165 100644 --- a/htdocs/reception/class/api_receptions.class.php +++ b/htdocs/reception/class/api_receptions.class.php @@ -145,11 +145,10 @@ class Receptions extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/recruitment/class/api_recruitment.class.php b/htdocs/recruitment/class/api_recruitment.class.php index cf4fa7a143e..3ffa81626fe 100644 --- a/htdocs/recruitment/class/api_recruitment.class.php +++ b/htdocs/recruitment/class/api_recruitment.class.php @@ -194,11 +194,10 @@ class Recruitment extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -302,11 +301,10 @@ class Recruitment extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/recruitment/class/recruitmentjobposition.class.php b/htdocs/recruitment/class/recruitmentjobposition.class.php index 6b3fcf7eeb8..e4f6a9acb8a 100644 --- a/htdocs/recruitment/class/recruitmentjobposition.class.php +++ b/htdocs/recruitment/class/recruitmentjobposition.class.php @@ -120,11 +120,11 @@ class RecruitmentJobPosition extends CommonObject 'label' => array('type'=>'varchar(255)', 'label'=>'JobLabel', 'enabled'=>'1', 'position'=>30, 'notnull'=>1, 'visible'=>1, 'searchall'=>1, 'css'=>'minwidth500', 'csslist'=>'tdoverflowmax300', 'showoncombobox'=>'2', 'autofocusoncreate'=>1), 'qty' => array('type'=>'integer', 'label'=>'NbOfEmployeesExpected', 'enabled'=>'1', 'position'=>45, 'notnull'=>1, 'visible'=>1, 'default'=>'1', 'isameasure'=>'1', 'css'=>'maxwidth75imp'), 'fk_project' => array('type'=>'integer:Project:projet/class/project.class.php:1', 'label'=>'Project', 'enabled'=>'$conf->project->enabled', 'position'=>52, 'notnull'=>-1, 'visible'=>-1, 'index'=>1, 'css'=>'maxwidth500', 'picto'=>'project'), - 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php:status=1', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), + 'fk_user_recruiter' => array('type'=>'integer:User:user/class/user.class.php:1:(statut:=:1)', 'label'=>'ResponsibleOfRecruitement', 'enabled'=>'1', 'position'=>54, 'notnull'=>1, 'visible'=>1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), 'email_recruiter' => array('type'=>'varchar(255)', 'label'=>'EmailRecruiter', 'enabled'=>'1', 'position'=>54, 'notnull'=>0, 'visible'=>-1, 'help'=>'ToUseAGenericEmail', 'picto'=>'email'), - 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php:t.statut = 1', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), + 'fk_user_supervisor' => array('type'=>'integer:User:user/class/user.class.php:1:(statut:=:1)', 'label'=>'FutureManager', 'enabled'=>'1', 'position'=>55, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'user.rowid', 'css'=>'maxwidth500', 'csslist'=>'tdoverflowmax150', 'picto'=>'user'), 'fk_establishment' => array('type'=>'integer:Establishment:hrm/class/establishment.class.php', 'label'=>'Establishment', 'enabled'=>'$conf->hrm->enabled', 'position'=>56, 'notnull'=>0, 'visible'=>-1, 'foreignkey'=>'establishment.rowid',), - 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:status=1 AND entity IN (__SHARED_ENTITIES__)', 'label'=>'WorkPlace', 'enabled'=>'$conf->societe->enabled', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'css'=>'maxwidth500', 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner", 'picto'=>'company'), + 'fk_soc' => array('type'=>'integer:Societe:societe/class/societe.class.php:1:((status:=:1) AND (entity:IN:__SHARED_ENTITIES__))', 'label'=>'WorkPlace', 'enabled'=>'$conf->societe->enabled', 'position'=>57, 'notnull'=>-1, 'visible'=>-1, 'css'=>'maxwidth500', 'index'=>1, 'help'=>"IfJobIsLocatedAtAPartner", 'picto'=>'company'), 'date_planned' => array('type'=>'date', 'label'=>'DateExpected', 'enabled'=>'1', 'position'=>60, 'notnull'=>0, 'visible'=>1,), 'remuneration_suggested' => array('type'=>'varchar(255)', 'label'=>'Remuneration', 'enabled'=>'1', 'position'=>62, 'notnull'=>0, 'visible'=>1,), 'description' => array('type'=>'html', 'label'=>'Description', 'enabled'=>'1', 'position'=>65, 'notnull'=>0, 'visible'=>3,), diff --git a/htdocs/societe/class/api_contacts.class.php b/htdocs/societe/class/api_contacts.class.php index 68bba46a3cb..88e9398f5fa 100644 --- a/htdocs/societe/class/api_contacts.class.php +++ b/htdocs/societe/class/api_contacts.class.php @@ -225,11 +225,10 @@ class Contacts extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/societe/class/api_thirdparties.class.php b/htdocs/societe/class/api_thirdparties.class.php index db7eec3096e..ff958729d6a 100644 --- a/htdocs/societe/class/api_thirdparties.class.php +++ b/htdocs/societe/class/api_thirdparties.class.php @@ -203,11 +203,10 @@ class Thirdparties extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php index f2036edda88..3bf9cf3f982 100644 --- a/htdocs/supplier_proposal/class/api_supplier_proposals.class.php +++ b/htdocs/supplier_proposal/class/api_supplier_proposals.class.php @@ -140,11 +140,10 @@ class Supplierproposals extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/ticket/class/api_tickets.class.php b/htdocs/ticket/class/api_tickets.class.php index e7930569bdd..c27d9195683 100644 --- a/htdocs/ticket/class/api_tickets.class.php +++ b/htdocs/ticket/class/api_tickets.class.php @@ -251,11 +251,10 @@ class Tickets extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/user/class/api_users.class.php b/htdocs/user/class/api_users.class.php index 747d4ab3286..781de4d23cd 100644 --- a/htdocs/user/class/api_users.class.php +++ b/htdocs/user/class/api_users.class.php @@ -100,11 +100,10 @@ class Users extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); @@ -544,11 +543,10 @@ class Users extends DolibarrApi // Add sql filters if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/htdocs/zapier/class/api_zapier.class.php b/htdocs/zapier/class/api_zapier.class.php index 56ab923435d..3db40064473 100644 --- a/htdocs/zapier/class/api_zapier.class.php +++ b/htdocs/zapier/class/api_zapier.class.php @@ -198,11 +198,10 @@ class Zapier extends DolibarrApi } if ($sqlfilters) { $errormessage = ''; - if (!DolibarrApi::_checkFilters($sqlfilters, $errormessage)) { - throw new RestException(503, 'Error when validating parameter sqlfilters -> '.$errormessage); + $sql .= forgeSQLFromUniversalSearchCriteria($sqlfilters, $errormessage); + if ($errormessage) { + throw new RestException(400, 'Error when validating parameter sqlfilters -> '.$errormessage); } - $regexstring = '\(([^:\'\(\)]+:[^:\'\(\)]+:[^\(\)]+)\)'; - $sql .= " AND (".preg_replace_callback('/'.$regexstring.'/', 'DolibarrApi::_forge_criteria_callback', $sqlfilters).")"; } $sql .= $this->db->order($sortfield, $sortorder); diff --git a/test/phpunit/FunctionsLibTest.php b/test/phpunit/FunctionsLibTest.php index 12c8683bb8f..d910a9f9d57 100644 --- a/test/phpunit/FunctionsLibTest.php +++ b/test/phpunit/FunctionsLibTest.php @@ -167,6 +167,34 @@ class FunctionsLibTest extends PHPUnit\Framework\TestCase print __METHOD__."\n"; } + + /** + * testDolForgeCriteriaCallback + * + * @return boolean + */ + public function testDolForgeCriteriaCallback() + { + global $conf, $langs; + + // An attempt for SQL injection + $filter='if(now()=sysdate()%2Csleep(6)%2C0)'; + $sql = forgeSQLFromUniversalSearchCriteria($filter); + $this->assertEquals($sql, '1 = 3'); + + // A real search string + $filter='(((statut:=:1) or (entity:in:__AAA__)) and (abc:<:2.0) and (abc:!=:1.23))'; + $sql = forgeSQLFromUniversalSearchCriteria($filter); + $this->assertEquals($sql, ' AND (((statut = 1 or entity IN (__AAA__)) and abc < 2 and abc = 1.23))'); + + $filter="(t.ref:like:'SO-%') or (t.date_creation:<:'20160101') or (t.date_creation:<:'2016-01-01 12:30:00') or (t.nature:is:NULL)"; + $sql = forgeSQLFromUniversalSearchCriteria($filter); + $this->assertEquals($sql, " AND (t.ref LIKE 'SO-%' or t.date_creation < '20160101' or t.date_creation < 0 or t.nature IS NULL)"); + + return true; + } + + /** * testDolClone *