diff --git a/src/applications/maniphest/ManiphestTaskQuery.php b/src/applications/maniphest/ManiphestTaskQuery.php index 27ee4d5d44..1ab0880d59 100644 --- a/src/applications/maniphest/ManiphestTaskQuery.php +++ b/src/applications/maniphest/ManiphestTaskQuery.php @@ -34,6 +34,8 @@ final class ManiphestTaskQuery { private $anyProject = false; private $includeNoProject = null; + private $fullTextSearch = ''; + private $status = 'status-any'; const STATUS_ANY = 'status-any'; const STATUS_OPEN = 'status-open'; @@ -117,6 +119,11 @@ final class ManiphestTaskQuery { return $this; } + public function withFullTextSearch($fulltext_search) { + $this->fullTextSearch = $fulltext_search; + return $this; + } + public function setGroupBy($group) { $this->groupBy = $group; return $this; @@ -176,6 +183,7 @@ final class ManiphestTaskQuery { $where[] = $this->buildSubscriberWhereClause($conn); $where[] = $this->buildProjectWhereClause($conn); $where[] = $this->buildXProjectWhereClause($conn); + $where[] = $this->buildFullTextWhereClause($conn); $where = array_filter($where); if ($where) { @@ -336,6 +344,30 @@ final class ManiphestTaskQuery { } } + private function buildFullTextWhereClause($conn) { + if (!$this->fullTextSearch) { + return null; + } + + // In doing a fulltext search, we first find all the PHIDs that match the + // fulltext search, and then use that to limit the rest of the search + $fulltext_query = new PhabricatorSearchQuery(); + $fulltext_query->setQuery($this->fullTextSearch); + $fulltext_query->setParameter('limit', PHP_INT_MAX); + + $engine = PhabricatorSearchEngineSelector::newSelector()->newEngine(); + $fulltext_results = $engine->executeSearch($fulltext_query); + + if (empty($fulltext_results)) { + $fulltext_results = array(null); + } + + return qsprintf( + $conn, + 'phid IN (%Ls)', + $fulltext_results); + } + private function buildSubscriberWhereClause($conn) { if (!$this->subscriberPHIDs) { return null; diff --git a/src/applications/maniphest/controller/ManiphestTaskListController.php b/src/applications/maniphest/controller/ManiphestTaskListController.php index af98fbbf90..3eda25d564 100644 --- a/src/applications/maniphest/controller/ManiphestTaskListController.php +++ b/src/applications/maniphest/controller/ManiphestTaskListController.php @@ -46,13 +46,17 @@ final class ManiphestTaskListController extends ManiphestController { $task_ids = $request->getStr('set_tasks'); $task_ids = nonempty($task_ids, null); + $search_text = $request->getStr('set_search'); + $search_text = nonempty($search_text, null); + $uri = $request->getRequestURI() ->alter('users', $this->getArrToStrList('set_users')) ->alter('projects', $this->getArrToStrList('set_projects')) ->alter('xprojects', $this->getArrToStrList('set_xprojects')) ->alter('owners', $this->getArrToStrList('set_owners')) ->alter('authors', $this->getArrToStrList('set_authors')) - ->alter('tasks', $task_ids); + ->alter('tasks', $task_ids) + ->alter('search', $search_text); return id(new AphrontRedirectResponse())->setURI($uri); } @@ -99,6 +103,8 @@ final class ManiphestTaskListController extends ManiphestController { // Extract information we need to render the filters from the query. + $search_text = $query->getParameter('fullTextSearch'); + $user_phids = $query->getParameter('userPHIDs', array()); $task_ids = $query->getParameter('taskIDs', array()); $owner_phids = $query->getParameter('ownerPHIDs', array()); @@ -143,6 +149,12 @@ final class ManiphestTaskListController extends ManiphestController { } if ($this->view == 'custom') { + $form->appendChild( + id(new AphrontFormTextControl()) + ->setName('set_search') + ->setLabel('Search') + ->setValue($search_text) + ); $form->appendChild( id(new AphrontFormTextControl()) ->setName('set_tasks') @@ -355,6 +367,7 @@ final class ManiphestTaskListController extends ManiphestController { public static function loadTasks(PhabricatorSearchQuery $search_query) { $any_project = false; + $search_text = $search_query->getParameter('fullTextSearch'); $user_phids = $search_query->getParameter('userPHIDs', array()); $project_phids = $search_query->getParameter('projectPHIDs', array()); $task_ids = $search_query->getParameter('taskIDs', array()); @@ -419,6 +432,8 @@ final class ManiphestTaskListController extends ManiphestController { $query->withAnyProject($any_project); + $query->withFullTextSearch($search_text); + $order_map = array( 'priority' => ManiphestTaskQuery::ORDER_PRIORITY, 'created' => ManiphestTaskQuery::ORDER_CREATED, @@ -649,6 +664,8 @@ final class ManiphestTaskListController extends ManiphestController { $owner_phids = $request->getStrList('owners'); $author_phids = $request->getStrList('authors'); + $search_string = $request->getStr('search'); + $page = $request->getInt('offset'); $page_size = self::DEFAULT_PAGE_SIZE; @@ -656,6 +673,7 @@ final class ManiphestTaskListController extends ManiphestController { $query->setQuery('<>'); $query->setParameters( array( + 'fullTextSearch' => $search_string, 'view' => $this->view, 'userPHIDs' => $user_phids, 'projectPHIDs' => $project_phids,