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 *