From bf84866292a9484c27a54f4af50c2bbc0d73b112 Mon Sep 17 00:00:00 2001
From: Peter Rotich <peter@enhancesoft.com>
Date: Mon, 15 Oct 2018 03:22:17 +0000
Subject: [PATCH] Advanced Search: Keyword search

* Require keyword search term to be 3 words or less
* Show keyword search option on Advanced Search dialog
---
 bootstrap.php            |  4 ++++
 include/class.queue.php  | 11 +++++++----
 include/class.search.php |  9 +++------
 scp/tickets.php          | 22 +++++++++++++---------
 4 files changed, 27 insertions(+), 19 deletions(-)

diff --git a/bootstrap.php b/bootstrap.php
index 4b64227a8..056c5f01d 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -293,6 +293,10 @@ class Bootstrap {
         }
         if (extension_loaded('iconv'))
             iconv_set_encoding('internal_encoding', 'UTF-8');
+
+        function mb_str_wc($str) {
+            return count(preg_split('~[^\p{L}\p{N}\'].+~u', trim($str)));
+        }
     }
 
     function croak($message) {
diff --git a/include/class.queue.php b/include/class.queue.php
index 5e9f3dcbf..812f9da30 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -174,10 +174,7 @@ class CustomQueue extends VerySimpleModel {
      */
     function getForm($source=null, $searchable=null) {
         $fields = array();
-        $validator = false;
         if (!isset($searchable)) {
-            $searchable = $this->getCurrentSearchFields($source);
-            $validator = true;
             $fields = array(
                 ':keywords' => new TextboxField(array(
                     'id' => 3001,
@@ -188,11 +185,17 @@ class CustomQueue extends VerySimpleModel {
                         'classes' => 'full-width headline',
                         'placeholder' => __('Keywords — Optional'),
                     ),
+                    'validators' => function($self, $v) {
+                        if (mb_str_wc($v) > 3)
+                            $self->addError(__('Search term cannot have more than 3 keywords'));
+                    },
                 )),
             );
+
+            $searchable = $this->getCurrentSearchFields($source);
         }
 
-        foreach ($searchable as $path=>$field)
+        foreach ($searchable ?: array() as $path => $field)
             $fields = array_merge($fields, static::getSearchField($field, $path));
 
         $form = new AdvancedSearchForm($fields, $source);
diff --git a/include/class.search.php b/include/class.search.php
index 469c3f5e0..f76aacf16 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -707,12 +707,9 @@ class SavedQueue extends CustomQueue {
      *
      */
     function getForm($source=null, $searchable=array()) {
-        global $thisstaff;
-
-        if (!$this->isAQueue())
-            $searchable =  $this->getCurrentSearchFields($source,
-                     parent::getCriteria());
-        else // Only allow supplemental matches.
+        $searchable = null;
+        if ($this->isAQueue())
+            // Only allow supplemental matches.
             $searchable = array_intersect_key($this->getCurrentSearchFields($source),
                     $this->getSupplementalMatches());
 
diff --git a/scp/tickets.php b/scp/tickets.php
index d100f38d7..41ba48538 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -79,16 +79,20 @@ if (!$ticket) {
     elseif (isset($_GET['a']) && $_GET['a'] === 'search'
         && ($_GET['query'])
     ) {
-        $key = substr(md5($_GET['query']), -10);
-        if ($_GET['search-type'] == 'typeahead') {
-            // Use a faster index
-            $criteria = ['user__emails__address', 'equal', $_GET['query']];
-        }
-        else {
-            $criteria = [':keywords', null, $_GET['query']];
+        $wc = mb_str_wc($_GET['query']);
+        if ($wc < 4) {
+            $key = substr(md5($_GET['query']), -10);
+            if ($_GET['search-type'] == 'typeahead') {
+                // Use a faster index
+                $criteria = ['user__emails__address', 'equal', $_GET['query']];
+            } else {
+                $criteria = [':keywords', null, $_GET['query']];
+            }
+            $_SESSION['advsearch'][$key] = [$criteria];
+            $queue_id = "adhoc,{$key}";
+        } else {
+            $errors['err'] = __('Search term cannot have more than 3 keywords');
         }
-        $_SESSION['advsearch'][$key] = [$criteria];
-        $queue_id = "adhoc,{$key}";
     }
 
     $queue_key = sprintf('::Q:%s', ObjectModel::OBJECT_TYPE_TICKET);
-- 
GitLab