Page MenuHomePhabricator

D15925.id38342.diff
No OneTemporary

D15925.id38342.diff

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
@@ -435,6 +435,7 @@
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'applications/differential/doorkeeper/DifferentialDoorkeeperRevisionFeedStoryPublisher.php',
'DifferentialDraft' => 'applications/differential/storage/DifferentialDraft.php',
'DifferentialEditPolicyField' => 'applications/differential/customfield/DifferentialEditPolicyField.php',
+ 'DifferentialExactUserFunctionDatasource' => 'applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php',
'DifferentialFieldParseException' => 'applications/differential/exception/DifferentialFieldParseException.php',
'DifferentialFieldValidationException' => 'applications/differential/exception/DifferentialFieldValidationException.php',
'DifferentialFindConduitAPIMethod' => 'applications/differential/conduit/DifferentialFindConduitAPIMethod.php',
@@ -491,6 +492,8 @@
'DifferentialRepositoryField' => 'applications/differential/customfield/DifferentialRepositoryField.php',
'DifferentialRepositoryLookup' => 'applications/differential/query/DifferentialRepositoryLookup.php',
'DifferentialRequiredSignaturesField' => 'applications/differential/customfield/DifferentialRequiredSignaturesField.php',
+ 'DifferentialResponsibleDatasource' => 'applications/differential/typeahead/DifferentialResponsibleDatasource.php',
+ 'DifferentialResponsibleUserDatasource' => 'applications/differential/typeahead/DifferentialResponsibleUserDatasource.php',
'DifferentialRevertPlanField' => 'applications/differential/customfield/DifferentialRevertPlanField.php',
'DifferentialReviewedByField' => 'applications/differential/customfield/DifferentialReviewedByField.php',
'DifferentialReviewer' => 'applications/differential/storage/DifferentialReviewer.php',
@@ -4643,6 +4646,7 @@
'DifferentialDoorkeeperRevisionFeedStoryPublisher' => 'DoorkeeperFeedStoryPublisher',
'DifferentialDraft' => 'DifferentialDAO',
'DifferentialEditPolicyField' => 'DifferentialCoreCustomField',
+ 'DifferentialExactUserFunctionDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialFieldParseException' => 'Exception',
'DifferentialFieldValidationException' => 'Exception',
'DifferentialFindConduitAPIMethod' => 'DifferentialConduitAPIMethod',
@@ -4705,6 +4709,8 @@
'DifferentialRepositoryField' => 'DifferentialCoreCustomField',
'DifferentialRepositoryLookup' => 'Phobject',
'DifferentialRequiredSignaturesField' => 'DifferentialCoreCustomField',
+ 'DifferentialResponsibleDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
+ 'DifferentialResponsibleUserDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'DifferentialRevertPlanField' => 'DifferentialStoredCustomField',
'DifferentialReviewedByField' => 'DifferentialCoreCustomField',
'DifferentialReviewer' => 'Phobject',
diff --git a/src/applications/differential/query/DifferentialRevisionQuery.php b/src/applications/differential/query/DifferentialRevisionQuery.php
--- a/src/applications/differential/query/DifferentialRevisionQuery.php
+++ b/src/applications/differential/query/DifferentialRevisionQuery.php
@@ -501,39 +501,17 @@
$basic_authors = $this->authors;
$basic_reviewers = $this->reviewers;
- $authority_phids = $this->responsibles;
-
- $authority_projects = id(new PhabricatorProjectQuery())
- ->setViewer($this->getViewer())
- ->withMemberPHIDs($this->responsibles)
- ->execute();
- foreach ($authority_projects as $project) {
- $authority_phids[] = $project->getPHID();
- }
-
- // NOTE: We're querying by explicit owners to make this a little faster,
- // since we've already expanded project membership so we don't need to
- // have the PackageQuery do it again.
- $authority_packages = id(new PhabricatorOwnersPackageQuery())
- ->setViewer($this->getViewer())
- ->withOwnerPHIDs($authority_phids)
- ->execute();
- foreach ($authority_packages as $package) {
- $authority_phids[] = $package->getPHID();
- }
-
try {
// Build the query where the responsible users are authors.
$this->authors = array_merge($basic_authors, $this->responsibles);
+
$this->reviewers = $basic_reviewers;
$selects[] = $this->buildSelectStatement($conn_r);
// Build the query where the responsible users are reviewers, or
// projects they are members of are reviewers.
$this->authors = $basic_authors;
- $this->reviewers = array_merge(
- $basic_reviewers,
- $authority_phids);
+ $this->reviewers = array_merge($basic_reviewers, $this->responsibles);
$selects[] = $this->buildSelectStatement($conn_r);
// Put everything back like it was.
diff --git a/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php b/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php
--- a/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php
+++ b/src/applications/differential/query/DifferentialRevisionRequiredActionResultBucket.php
@@ -17,7 +17,7 @@
$this->objects = $objects;
- $phids = $query->getParameter('responsiblePHIDs', array());
+ $phids = $query->getEvaluatedParameter('responsiblePHIDs', array());
if (!$phids) {
throw new Exception(
pht(
diff --git a/src/applications/differential/query/DifferentialRevisionSearchEngine.php b/src/applications/differential/query/DifferentialRevisionSearchEngine.php
--- a/src/applications/differential/query/DifferentialRevisionSearchEngine.php
+++ b/src/applications/differential/query/DifferentialRevisionSearchEngine.php
@@ -51,10 +51,11 @@
protected function buildCustomSearchFields() {
return array(
- id(new PhabricatorUsersSearchField())
+ id(new PhabricatorSearchDatasourceField())
->setLabel(pht('Responsible Users'))
->setKey('responsiblePHIDs')
->setAliases(array('responsiblePHID', 'responsibles', 'responsible'))
+ ->setDatasource(new DifferentialResponsibleDatasource())
->setDescription(
pht('Find revisions that a given user is responsible for.')),
id(new PhabricatorUsersSearchField())
@@ -67,7 +68,7 @@
->setLabel(pht('Reviewers'))
->setKey('reviewerPHIDs')
->setAliases(array('reviewer', 'reviewers', 'reviewerPHID'))
- ->setDatasource(new DiffusionAuditorDatasource())
+ ->setDatasource(new DiffusionAuditorFunctionDatasource())
->setDescription(
pht('Find revisions with specific reviewers.')),
id(new PhabricatorSearchDatasourceField())
diff --git a/src/applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php b/src/applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/typeahead/DifferentialExactUserFunctionDatasource.php
@@ -0,0 +1,115 @@
+<?php
+
+final class DifferentialExactUserFunctionDatasource
+ extends PhabricatorTypeaheadCompositeDatasource {
+
+ public function getBrowseTitle() {
+ return pht('Browse Users');
+ }
+
+ public function getPlaceholderText() {
+ return pht('Type exact(<user>)...');
+ }
+
+ public function getDatasourceApplicationClass() {
+ return 'PhabricatorDifferentialApplication';
+ }
+
+ public function getComponentDatasources() {
+ return array(
+ new PhabricatorPeopleDatasource(),
+ );
+ }
+
+ public function getDatasourceFunctions() {
+ return array(
+ 'exact' => array(
+ 'name' => pht('Exact: ...'),
+ 'arguments' => pht('username'),
+ 'summary' => pht('Find results matching users exactly.'),
+ 'description' => pht(
+ "This function allows you to find results associated only with ".
+ "a user, exactly, and not any of their projects or packages. For ".
+ "example, this will find results associated with only `%s`:".
+ "\n\n%s\n\n",
+ 'alincoln',
+ '> exact(alincoln)'),
+ ),
+ );
+ }
+
+ protected function didLoadResults(array $results) {
+ foreach ($results as $result) {
+ $result
+ ->setColor(null)
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setIcon('fa-asterisk')
+ ->setPHID('exact('.$result->getPHID().')')
+ ->setDisplayName(pht('Exact User: %s', $result->getDisplayName()))
+ ->setName($result->getName().' exact');
+ }
+
+ return $results;
+ }
+
+ protected function evaluateFunction($function, array $argv_list) {
+ $phids = array();
+ foreach ($argv_list as $argv) {
+ $phids[] = head($argv);
+ }
+
+ return $this->resolvePHIDs($phids);
+ }
+
+ public function renderFunctionTokens($function, array $argv_list) {
+ $phids = array();
+ foreach ($argv_list as $argv) {
+ $phids[] = head($argv);
+ }
+
+ $phids = $this->resolvePHIDs($phids);
+
+ $tokens = $this->renderTokens($phids);
+ foreach ($tokens as $token) {
+ $token->setColor(null);
+ if ($token->isInvalid()) {
+ $token
+ ->setValue(pht('Exact User: Invalid User'));
+ } else {
+ $token
+ ->setIcon('fa-asterisk')
+ ->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
+ ->setKey('exact('.$token->getKey().')')
+ ->setValue(pht('Exact User: %s', $token->getValue()));
+ }
+ }
+
+ return $tokens;
+ }
+
+ private function resolvePHIDs(array $phids) {
+ $usernames = array();
+ foreach ($phids as $key => $phid) {
+ if (phid_get_type($phid) != PhabricatorPeopleUserPHIDType::TYPECONST) {
+ $usernames[$key] = $phid;
+ }
+ }
+
+ if ($usernames) {
+ $users = id(new PhabricatorPeopleQuery())
+ ->setViewer($this->getViewer())
+ ->withUsernames($usernames)
+ ->execute();
+ $users = mpull($users, null, 'getUsername');
+ foreach ($usernames as $key => $username) {
+ $user = idx($users, $username);
+ if ($user) {
+ $phids[$key] = $user->getPHID();
+ }
+ }
+ }
+
+ return $phids;
+ }
+
+}
diff --git a/src/applications/differential/typeahead/DifferentialResponsibleDatasource.php b/src/applications/differential/typeahead/DifferentialResponsibleDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/typeahead/DifferentialResponsibleDatasource.php
@@ -0,0 +1,27 @@
+<?php
+
+final class DifferentialResponsibleDatasource
+ extends PhabricatorTypeaheadCompositeDatasource {
+
+ public function getBrowseTitle() {
+ return pht('Browse Responsible Users');
+ }
+
+ public function getPlaceholderText() {
+ return pht('Type a user, project, or package name, or function...');
+ }
+
+ public function getDatasourceApplicationClass() {
+ return 'PhabricatorDifferentialApplication';
+ }
+
+ public function getComponentDatasources() {
+ return array(
+ new DifferentialResponsibleUserDatasource(),
+ new DifferentialExactUserFunctionDatasource(),
+ new PhabricatorProjectDatasource(),
+ new PhabricatorOwnersPackageDatasource(),
+ );
+ }
+
+}
diff --git a/src/applications/differential/typeahead/DifferentialResponsibleUserDatasource.php b/src/applications/differential/typeahead/DifferentialResponsibleUserDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/differential/typeahead/DifferentialResponsibleUserDatasource.php
@@ -0,0 +1,58 @@
+<?php
+
+final class DifferentialResponsibleUserDatasource
+ extends PhabricatorTypeaheadCompositeDatasource {
+
+ public function getBrowseTitle() {
+ return pht('Browse Users');
+ }
+
+ public function getPlaceholderText() {
+ return pht('Type a user name...');
+ }
+
+ public function getDatasourceApplicationClass() {
+ return 'PhabricatorDifferentialApplication';
+ }
+
+ public function getComponentDatasources() {
+ return array(
+ new PhabricatorPeopleDatasource(),
+ );
+ }
+
+ protected function evaluateValues(array $values) {
+ $viewer = $this->getViewer();
+
+ $phids = array();
+ foreach ($values as $value) {
+ if (phid_get_type($value) == PhabricatorPeopleUserPHIDType::TYPECONST) {
+ $phids[] = $value;
+ }
+ }
+
+ if (!$phids) {
+ return $values;
+ }
+
+ $projects = id(new PhabricatorProjectQuery())
+ ->setViewer($viewer)
+ ->withMemberPHIDs($phids)
+ ->execute();
+ foreach ($projects as $project) {
+ $phids[] = $project->getPHID();
+ $values[] = $project->getPHID();
+ }
+
+ $packages = id(new PhabricatorOwnersPackageQuery())
+ ->setViewer($viewer)
+ ->withOwnerPHIDs($phids)
+ ->execute();
+ foreach ($packages as $package) {
+ $values[] = $package->getPHID();
+ }
+
+ return $values;
+ }
+
+}
diff --git a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
--- a/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
+++ b/src/applications/search/engine/PhabricatorApplicationSearchEngine.php
@@ -143,8 +143,8 @@
* @param PhabricatorSavedQuery The saved query to operate on.
* @return The result of the query.
*/
- public function buildQueryFromSavedQuery(PhabricatorSavedQuery $saved) {
- $saved = clone $saved;
+ public function buildQueryFromSavedQuery(PhabricatorSavedQuery $original) {
+ $saved = clone $original;
$this->willUseSavedQuery($saved);
$fields = $this->buildSearchFields();
@@ -158,6 +158,7 @@
$map[$field->getKey()] = $value;
}
+ $original->attachParameterMap($map);
$query = $this->buildQueryFromParameters($map);
$object = $this->newResultObject();
diff --git a/src/applications/search/storage/PhabricatorSavedQuery.php b/src/applications/search/storage/PhabricatorSavedQuery.php
--- a/src/applications/search/storage/PhabricatorSavedQuery.php
+++ b/src/applications/search/storage/PhabricatorSavedQuery.php
@@ -7,6 +7,8 @@
protected $queryKey;
protected $engineClassName;
+ private $parameterMap = self::ATTACHABLE;
+
protected function getConfiguration() {
return array(
self::CONFIG_SERIALIZATION => array(
@@ -52,6 +54,15 @@
return newv($this->getEngineClassName(), array());
}
+ public function attachParameterMap(array $map) {
+ $this->parameterMap = $map;
+ return $this;
+ }
+
+ public function getEvaluatedParameter($key, $default = null) {
+ return $this->assertAttachedKey($this->parameterMap, $key, $default);
+ }
+
/* -( PhabricatorPolicyInterface )----------------------------------------- */
diff --git a/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php b/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php
--- a/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php
+++ b/src/applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php
@@ -142,6 +142,14 @@
return parent::canEvaluateFunction($function);
}
+ protected function evaluateValues(array $values) {
+ foreach ($this->getUsableDatasources() as $source) {
+ $values = $source->evaluateValues($values);
+ }
+
+ return parent::evaluateValues($values);
+ }
+
protected function evaluateFunction($function, array $argv) {
foreach ($this->getUsableDatasources() as $source) {
if ($source->canEvaluateFunction($function)) {
diff --git a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
--- a/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
+++ b/src/applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php
@@ -334,6 +334,14 @@
/**
* @task functions
*/
+ protected function evaluateValues(array $values) {
+ return $values;
+ }
+
+
+ /**
+ * @task functions
+ */
public function evaluateTokens(array $tokens) {
$results = array();
$evaluate = array();
@@ -345,6 +353,8 @@
}
}
+ $results = $this->evaluateValues($results);
+
foreach ($evaluate as $function) {
$function = self::parseFunction($function);
if (!$function) {

File Metadata

Mime Type
text/plain
Expires
Mon, Dec 23, 1:25 AM (17 h, 52 m)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6918665
Default Alt Text
D15925.id38342.diff (16 KB)

Event Timeline