From 3ba56ceaf0f021fa9e8814aee424210ac96cb3b9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Thu, 23 Apr 2015 15:44:27 -0700 Subject: [PATCH] Add an anyone() typeahead function for matching any document owner Summary: Fixes T5733. Test Plan: Ran search and Maniphest queries. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T5733 Differential Revision: https://secure.phabricator.com/D12535 --- src/__phutil_library_map__.php | 2 + .../maniphest/query/ManiphestTaskQuery.php | 49 +++++++------ .../PhabricatorPeopleAnyOwnerDatasource.php | 68 +++++++++++++++++++ .../PhabricatorPeopleOwnerDatasource.php | 1 + .../engine/PhabricatorSearchEngineElastic.php | 10 ++- .../engine/PhabricatorSearchEngineMySQL.php | 9 ++- ...abricatorSearchApplicationSearchEngine.php | 4 ++ 7 files changed, 119 insertions(+), 24 deletions(-) create mode 100644 src/applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php index 1ba136f168..a994307b24 100644 --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2188,6 +2188,7 @@ phutil_register_library_map(array( 'PhabricatorPasteTransactionQuery' => 'applications/paste/query/PhabricatorPasteTransactionQuery.php', 'PhabricatorPasteViewController' => 'applications/paste/controller/PhabricatorPasteViewController.php', 'PhabricatorPathSetupCheck' => 'applications/config/check/PhabricatorPathSetupCheck.php', + 'PhabricatorPeopleAnyOwnerDatasource' => 'applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php', 'PhabricatorPeopleApplication' => 'applications/people/application/PhabricatorPeopleApplication.php', 'PhabricatorPeopleApproveController' => 'applications/people/controller/PhabricatorPeopleApproveController.php', 'PhabricatorPeopleCalendarController' => 'applications/people/controller/PhabricatorPeopleCalendarController.php', @@ -5560,6 +5561,7 @@ phutil_register_library_map(array( 'PhabricatorPasteTransactionQuery' => 'PhabricatorApplicationTransactionQuery', 'PhabricatorPasteViewController' => 'PhabricatorPasteController', 'PhabricatorPathSetupCheck' => 'PhabricatorSetupCheck', + 'PhabricatorPeopleAnyOwnerDatasource' => 'PhabricatorTypeaheadDatasource', 'PhabricatorPeopleApplication' => 'PhabricatorApplication', 'PhabricatorPeopleApproveController' => 'PhabricatorPeopleController', 'PhabricatorPeopleCalendarController' => 'PhabricatorPeopleController', diff --git a/src/applications/maniphest/query/ManiphestTaskQuery.php b/src/applications/maniphest/query/ManiphestTaskQuery.php index 974ac2ab44..1b988ab4c6 100644 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -10,7 +10,8 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { private $taskPHIDs = array(); private $authorPHIDs = array(); private $ownerPHIDs = array(); - private $includeUnowned = null; + private $noOwner; + private $anyOwner; private $subscriberPHIDs = array(); private $dateCreatedAfter; private $dateCreatedBefore; @@ -70,11 +71,16 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { public function withOwners(array $owners) { $no_owner = PhabricatorPeopleNoOwnerDatasource::FUNCTION_TOKEN; + $any_owner = PhabricatorPeopleAnyOwnerDatasource::FUNCTION_TOKEN; - $this->includeUnowned = false; foreach ($owners as $k => $phid) { if ($phid === $no_owner || $phid === null) { - $this->includeUnowned = true; + $this->noOwner = true; + unset($owners[$k]); + break; + } + if ($phid === $any_owner) { + $this->anyOwner = true; unset($owners[$k]); break; } @@ -512,31 +518,32 @@ final class ManiphestTaskQuery extends PhabricatorCursorPagedPolicyAwareQuery { } private function buildOwnerWhereClause(AphrontDatabaseConnection $conn) { - if (!$this->ownerPHIDs) { - if ($this->includeUnowned === null) { - return null; - } else if ($this->includeUnowned) { - return qsprintf( - $conn, - 'task.ownerPHID IS NULL'); - } else { - return qsprintf( - $conn, - 'task.ownerPHID IS NOT NULL'); - } + $subclause = array(); + + if ($this->noOwner) { + $subclause[] = qsprintf( + $conn, + 'task.ownerPHID IS NULL'); } - if ($this->includeUnowned) { - return qsprintf( + if ($this->anyOwner) { + $subclause[] = qsprintf( $conn, - 'task.ownerPHID IN (%Ls) OR task.ownerPHID IS NULL', - $this->ownerPHIDs); - } else { - return qsprintf( + 'task.ownerPHID IS NOT NULL'); + } + + if ($this->ownerPHIDs) { + $subclause[] = qsprintf( $conn, 'task.ownerPHID IN (%Ls)', $this->ownerPHIDs); } + + if (!$subclause) { + return ''; + } + + return '('.implode(') OR (', $subclause).')'; } private function buildFullTextWhereClause(AphrontDatabaseConnection $conn) { diff --git a/src/applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php b/src/applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php new file mode 100644 index 0000000000..803ecc59d2 --- /dev/null +++ b/src/applications/people/typeahead/PhabricatorPeopleAnyOwnerDatasource.php @@ -0,0 +1,68 @@ + array( + 'name' => pht('Anyone'), + 'summary' => pht('Find results which are assigned to anyone.'), + 'description' => pht( + 'This function includes results which have any owner. It excludes '. + 'unassigned or unowned results.'), + ), + ); + } + + public function loadResults() { + $results = array( + $this->buildAnyoneResult(), + ); + return $this->filterResultsAgainstTokens($results); + } + + protected function evaluateFunction($function, array $argv_list) { + $results = array(); + + foreach ($argv_list as $argv) { + $results[] = self::FUNCTION_TOKEN; + } + + return $results; + } + + public function renderFunctionTokens($function, array $argv_list) { + $results = array(); + foreach ($argv_list as $argv) { + $results[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult( + $this->buildAnyoneResult()); + } + return $results; + } + + private function buildAnyoneResult() { + $name = pht('Any Owner'); + return $this->newFunctionResult() + ->setName($name.' anyone') + ->setDisplayName($name) + ->setIcon('fa-certificate') + ->setPHID(self::FUNCTION_TOKEN) + ->setUnique(true); + } + +} diff --git a/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php b/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php index 0a38a0affb..63f96b22f3 100644 --- a/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php +++ b/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php @@ -15,6 +15,7 @@ final class PhabricatorPeopleOwnerDatasource return array( new PhabricatorViewerDatasource(), new PhabricatorPeopleNoOwnerDatasource(), + new PhabricatorPeopleAnyOwnerDatasource(), new PhabricatorPeopleDatasource(), new PhabricatorProjectMembersDatasource(), ); diff --git a/src/applications/search/engine/PhabricatorSearchEngineElastic.php b/src/applications/search/engine/PhabricatorSearchEngineElastic.php index 1cc83b11f9..b97d690752 100644 --- a/src/applications/search/engine/PhabricatorSearchEngineElastic.php +++ b/src/applications/search/engine/PhabricatorSearchEngineElastic.php @@ -125,8 +125,6 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine { $relationship_map = array( PhabricatorSearchRelationship::RELATIONSHIP_AUTHOR => $query->getParameter('authorPHIDs', array()), - PhabricatorSearchRelationship::RELATIONSHIP_OWNER => - $query->getParameter('ownerPHIDs', array()), PhabricatorSearchRelationship::RELATIONSHIP_SUBSCRIBER => $query->getParameter('subscriberPHIDs', array()), PhabricatorSearchRelationship::RELATIONSHIP_PROJECT => @@ -155,6 +153,14 @@ final class PhabricatorSearchEngineElastic extends PhabricatorSearchEngine { $relationship_map[$rel_unowned] = true; } + $rel_owner = PhabricatorSearchRelationship::RELATIONSHIP_OWNER; + if ($query->getParameter('withAnyOwner')) { + $relationship_map[$rel_owner] = true; + } else { + $owner_phids = $query->getParameter('ownerPHIDs', array()); + $relationship_map[$rel_owner] = $owner_phids; + } + foreach ($relationship_map as $field => $param) { if (is_array($param) && $param) { $should = array(); diff --git a/src/applications/search/engine/PhabricatorSearchEngineMySQL.php b/src/applications/search/engine/PhabricatorSearchEngineMySQL.php index b14b6bac0d..5366d3fd02 100644 --- a/src/applications/search/engine/PhabricatorSearchEngineMySQL.php +++ b/src/applications/search/engine/PhabricatorSearchEngineMySQL.php @@ -231,7 +231,14 @@ final class PhabricatorSearchEngineMySQL extends PhabricatorSearchEngine { true); } - if ($query->getParameter('withUnowned')) { + if ($query->getParameter('withAnyOwner')) { + $join[] = $this->joinRelationship( + $conn_r, + $query, + 'withAnyOwner', + PhabricatorSearchRelationship::RELATIONSHIP_OWNER, + true); + } else if ($query->getParameter('withUnowned')) { $join[] = $this->joinRelationship( $conn_r, $query, diff --git a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php index 15ffc82205..1ca6b109d3 100644 --- a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php +++ b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php @@ -58,6 +58,10 @@ final class PhabricatorSearchApplicationSearchEngine $config->setParameter('withUnowned', true); unset($owner_phids[$key]); } + if ($phid == PhabricatorPeopleAnyOwnerDatasource::FUNCTION_TOKEN) { + $config->setParameter('withAnyOwner', true); + unset($owner_phids[$key]); + } } $config->setParameter('ownerPHIDs', $owner_phids);