diff --git a/core/config.class.inc.php b/core/config.class.inc.php index 0a8ec2740..dc0f3bab1 100644 --- a/core/config.class.inc.php +++ b/core/config.class.inc.php @@ -736,6 +736,14 @@ class Config 'source_of_value' => '', 'show_in_conf_sample' => false, ), + 'full_text_needle_min' => array( + 'type' => 'integer', + 'description' => 'Minimum size of the full text needle.', + 'default' => 3, + 'value' => 3, + 'source_of_value' => '', + 'show_in_conf_sample' => false, + ), 'tracking_level_linked_set_default' => array( 'type' => 'integer', 'description' => 'Default tracking level if not explicitely set at the attribute level, for AttributeLinkedSet (defaults to NONE in case of a fresh install, LIST otherwise - this to preserve backward compatibility while upgrading from a version older than 2.0.3 - see TRAC #936)', diff --git a/dictionaries/dictionary.itop.ui.php b/dictionaries/dictionary.itop.ui.php index 4a796d7a9..d5c255ee4 100644 --- a/dictionaries/dictionary.itop.ui.php +++ b/dictionaries/dictionary.itop.ui.php @@ -765,6 +765,7 @@ Dict::Add('EN US', 'English', 'English', array( 'UI:ObjectDoesNotExist' => 'Sorry, this object does not exist (or you are not allowed to view it).', 'UI:SearchResultsPageTitle' => 'iTop - Search Results', 'UI:Search:NoSearch' => 'Nothing to search for', + 'UI:Search:NeedleTooShort' => 'The search string "%1$s" is too short. Please type at least %2$d characters.', 'UI:Search:Ongoing' => 'Searching for "%1$s"', 'UI:Search:Enlarge' => 'Broaden the search', 'UI:FullTextSearchTitle_Text' => 'Results for "%1$s":', diff --git a/dictionaries/fr.dictionary.itop.ui.php b/dictionaries/fr.dictionary.itop.ui.php index 9aa82f0a2..e27a58789 100644 --- a/dictionaries/fr.dictionary.itop.ui.php +++ b/dictionaries/fr.dictionary.itop.ui.php @@ -635,6 +635,7 @@ Dict::Add('FR FR', 'French', 'Français', array( 'UI:ObjectDoesNotExist' => 'Désolé cet objet n\'existe pas (où vous n\'êtes pas autorisé à l\'afficher).', 'UI:SearchResultsPageTitle' => 'iTop - Résultats de la recherche', 'UI:Search:NoSearch' => 'Rien à rechercher', + 'UI:Search:NeedleTooShort' => 'La clé de recherche "%1$s" est trop courte. Veuillez saisir au moins %2$d caractères.', 'UI:Search:Ongoing' => 'Recherche de "%1$s"', 'UI:Search:Enlarge' => 'Elargir la recherche', 'UI:FullTextSearchTitle_Text' => 'Résultats pour "%1$s" :', diff --git a/pages/UI.php b/pages/UI.php index a1bce7648..630533ac7 100644 --- a/pages/UI.php +++ b/pages/UI.php @@ -535,8 +535,46 @@ try } else { - // Sanity check of the accelerators $iErrors = 0; + + // Check if a class name/label is supplied to limit the search + $sClassName = ''; + if (preg_match('/^([a-zA-Z]+):(.+)$/', $sFullText, $aMatches)) + { + $sClassName = $aMatches[1]; + if (MetaModel::IsValidClass($sClassName)) + { + $sFullText = trim($aMatches[2]); + } + elseif ($sClassName = MetaModel::GetClassFromLabel($sClassName, false /* => not case sensitive */)) + { + $sFullText = trim($aMatches[2]); + } + } + + if (preg_match('/^"(.*)"$/', $sFullText, $aMatches)) + { + // The text is surrounded by double-quotes, remove the quotes and treat it as one single expression + $aFullTextNeedles = array($aMatches[1]); + } + else + { + // Split the text on the blanks and treat this as a search for AND AND + $aFullTextNeedles = explode(' ', $sFullText); + } + + // Check the needle length + $iMinLenth = MetaModel::GetConfig()->Get('full_text_needle_min'); + foreach ($aFullTextNeedles as $sNeedle) + { + if (strlen($sNeedle) < $iMinLenth) + { + $oP->p(Dict::Format('UI:Search:NeedleTooShort', $sNeedle, $iMinLenth)); + $iErrors++; + } + } + + // Sanity check of the accelerators $aAccelerators = MetaModel::GetConfig()->Get('full_text_accelerators'); foreach ($aAccelerators as $sClass => $aAccelerator) { @@ -568,10 +606,11 @@ try $oP->add("

".Dict::Format('UI:FullTextSearchTitle_Text', htmlentities($sFullText, ENT_QUOTES, 'UTF-8'))."

"); $oP->add("\n"); $oP->add("\n"); - $sJSNeedle = addslashes($sFullText); + $sJSClass = addslashes($sClassName); + $sJSNeedles = json_encode($aFullTextNeedles); $oP->add_ready_script( << not case sensitive */)) - { - $sFullText = $aMatches[2]; - } - } - - if (preg_match('/^"(.*)"$/', $sFullText, $aMatches)) - { - // The text is surrounded by double-quotes, remove the quotes and treat it as one single expression - $aFullTextNeedles = array($aMatches[1]); - } - else - { - // Split the text on the blanks and treat this as a search for AND AND - $aFullTextNeedles = explode(' ', $sFullText); - } // Build the ordered list of classes to search into //