1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-21 13:00:56 +01:00

Implement a projects() datasource function

Summary:
Ref T4100. This is like members(), but is implemented on top of the raw datasource. This is a lot simpler and involves way less code duplication.

I'll go back and implement members() like this, too.

Nothing actually uses this yet.

Test Plan:
  - Used browse view to browse datasource.

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: epriestley

Maniphest Tasks: T4100

Differential Revision: https://secure.phabricator.com/D12458
This commit is contained in:
epriestley 2015-04-18 09:15:09 -07:00
parent 2bbe3b0cbf
commit c246aa2638
5 changed files with 121 additions and 3 deletions

View file

@ -2664,6 +2664,7 @@ phutil_register_library_map(array(
'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php', 'PhabricatorUserPreferences' => 'applications/settings/storage/PhabricatorUserPreferences.php',
'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php', 'PhabricatorUserProfile' => 'applications/people/storage/PhabricatorUserProfile.php',
'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php', 'PhabricatorUserProfileEditor' => 'applications/people/editor/PhabricatorUserProfileEditor.php',
'PhabricatorUserProjectsDatasource' => 'applications/people/typeahead/PhabricatorUserProjectsDatasource.php',
'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php', 'PhabricatorUserRealNameField' => 'applications/people/customfield/PhabricatorUserRealNameField.php',
'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php', 'PhabricatorUserRolesField' => 'applications/people/customfield/PhabricatorUserRolesField.php',
'PhabricatorUserSchemaSpec' => 'applications/people/storage/PhabricatorUserSchemaSpec.php', 'PhabricatorUserSchemaSpec' => 'applications/people/storage/PhabricatorUserSchemaSpec.php',
@ -6083,6 +6084,7 @@ phutil_register_library_map(array(
'PhabricatorUserPreferences' => 'PhabricatorUserDAO', 'PhabricatorUserPreferences' => 'PhabricatorUserDAO',
'PhabricatorUserProfile' => 'PhabricatorUserDAO', 'PhabricatorUserProfile' => 'PhabricatorUserDAO',
'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor', 'PhabricatorUserProfileEditor' => 'PhabricatorApplicationTransactionEditor',
'PhabricatorUserProjectsDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField', 'PhabricatorUserRealNameField' => 'PhabricatorUserCustomField',
'PhabricatorUserRolesField' => 'PhabricatorUserCustomField', 'PhabricatorUserRolesField' => 'PhabricatorUserCustomField',
'PhabricatorUserSchemaSpec' => 'PhabricatorConfigSchemaSpec', 'PhabricatorUserSchemaSpec' => 'PhabricatorConfigSchemaSpec',

View file

@ -0,0 +1,85 @@
<?php
final class PhabricatorUserProjectsDatasource
extends PhabricatorTypeaheadCompositeDatasource {
public function getPlaceholderText() {
return pht('Type projects(<user>)...');
}
public function getDatasourceApplicationClass() {
return 'PhabricatorProjectApplication';
}
public function getComponentDatasources() {
return array(
new PhabricatorPeopleDatasource(),
);
}
public function getDatasourceFunctions() {
return array(
'projects' => array(
'name' => pht("Find results in any of a user's projects."),
),
);
}
protected function didLoadResults(array $results) {
foreach ($results as $result) {
$result
->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
->setIcon('fa-briefcase')
->setPHID('projects('.$result->getPHID().')')
->setDisplayName(pht('Projects: %s', $result->getDisplayName()))
->setName($result->getName().' projects');
}
return $results;
}
protected function evaluateFunction($function, array $argv_list) {
$phids = array();
foreach ($argv_list as $argv) {
$phids[] = head($argv);
}
$projects = id(new PhabricatorPeopleQuery())
->setViewer($this->getViewer())
->needMembers(true)
->withPHIDs($phids)
->execute();
$results = array();
foreach ($projects as $project) {
foreach ($project->getMemberPHIDs() as $phid) {
$results[$phid] = $phid;
}
}
return array_values($results);
}
public function renderFunctionTokens($function, array $argv_list) {
$phids = array();
foreach ($argv_list as $argv) {
$phids[] = head($argv);
}
$tokens = $this->renderTokens($phids);
foreach ($tokens as $token) {
if ($token->isInvalid()) {
$token
->setValue(pht('Projects: Invalid User'));
} else {
$token
->setTokenType(PhabricatorTypeaheadTokenView::TYPE_FUNCTION)
->setKey('projects('.$token->getKey().')')
->setValue(pht('Projects: %s', $token->getValue()));
}
}
return $tokens;
}
}

View file

@ -25,10 +25,22 @@ abstract class PhabricatorTypeaheadCompositeDatasource
$offset = $this->getOffset(); $offset = $this->getOffset();
$limit = $this->getLimit(); $limit = $this->getLimit();
// If the input query is a function like `members(platy`, and we can
// parse the function, we strip the function off and hand the stripped
// query to child sources. This makes it easier to implement function
// sources in terms of real object sources.
$raw_query = $this->getRawQuery();
if (self::isFunctionToken($raw_query)) {
$function = $this->parseFunction($raw_query, $allow_partial = true);
if ($function) {
$raw_query = head($function['argv']);
}
}
$results = array(); $results = array();
foreach ($this->getUsableDatasources() as $source) { foreach ($this->getUsableDatasources() as $source) {
$source $source
->setRawQuery($this->getRawQuery()) ->setRawQuery($raw_query)
->setQuery($this->getQuery()) ->setQuery($this->getQuery())
->setViewer($this->getViewer()); ->setViewer($this->getViewer());
@ -36,7 +48,9 @@ abstract class PhabricatorTypeaheadCompositeDatasource
$source->setLimit($offset + $limit); $source->setLimit($offset + $limit);
} }
$results[] = $source->loadResults(); $source_results = $source->loadResults();
$source_results = $source->didLoadResults($source_results);
$results[] = $source_results;
} }
$results = array_mergev($results); $results = array_mergev($results);

View file

@ -90,6 +90,10 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
abstract public function getDatasourceApplicationClass(); abstract public function getDatasourceApplicationClass();
abstract public function loadResults(); abstract public function loadResults();
protected function didLoadResults(array $results) {
return $results;
}
public static function tokenizeString($string) { public static function tokenizeString($string) {
$string = phutil_utf8_strtolower($string); $string = phutil_utf8_strtolower($string);
$string = trim($string); $string = trim($string);
@ -258,11 +262,20 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
/* -( Token Functions )---------------------------------------------------- */ /* -( Token Functions )---------------------------------------------------- */
/**
* @task functions
*/
public function getDatasourceFunctions() {
return array();
}
/** /**
* @task functions * @task functions
*/ */
protected function canEvaluateFunction($function) { protected function canEvaluateFunction($function) {
return false; $functions = $this->getDatasourceFunctions();
return isset($functions[$function]);
} }

View file

@ -44,6 +44,10 @@ final class PhabricatorTypeaheadTokenView
return $token; return $token;
} }
public function isInvalid() {
return ($this->getTokenType() == self::TYPE_INVALID);
}
public function setKey($key) { public function setKey($key) {
$this->key = $key; $this->key = $key;
return $this; return $this;