diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -2188,6 +2188,7 @@ '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 @@ '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 --- a/src/applications/maniphest/query/ManiphestTaskQuery.php +++ b/src/applications/maniphest/query/ManiphestTaskQuery.php @@ -10,7 +10,8 @@ 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 @@ 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 @@ } 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 --- /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 --- a/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php +++ b/src/applications/people/typeahead/PhabricatorPeopleOwnerDatasource.php @@ -15,6 +15,7 @@ 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 --- a/src/applications/search/engine/PhabricatorSearchEngineElastic.php +++ b/src/applications/search/engine/PhabricatorSearchEngineElastic.php @@ -125,8 +125,6 @@ $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 @@ $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 --- a/src/applications/search/engine/PhabricatorSearchEngineMySQL.php +++ b/src/applications/search/engine/PhabricatorSearchEngineMySQL.php @@ -231,7 +231,14 @@ 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 --- a/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php +++ b/src/applications/search/query/PhabricatorSearchApplicationSearchEngine.php @@ -58,6 +58,10 @@ $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);