mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-21 21:10: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:
parent
2bbe3b0cbf
commit
c246aa2638
5 changed files with 121 additions and 3 deletions
|
@ -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',
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue