Page MenuHomePhabricator

D12482.id29968.diff
No OneTemporary

D12482.id29968.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
@@ -2639,6 +2639,7 @@
'PhabricatorTypeaheadCompositeDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadCompositeDatasource.php',
'PhabricatorTypeaheadDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadDatasource.php',
'PhabricatorTypeaheadDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadDatasourceController.php',
+ 'PhabricatorTypeaheadFunctionHelpController' => 'applications/typeahead/controller/PhabricatorTypeaheadFunctionHelpController.php',
'PhabricatorTypeaheadInvalidTokenException' => 'applications/typeahead/exception/PhabricatorTypeaheadInvalidTokenException.php',
'PhabricatorTypeaheadModularDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php',
'PhabricatorTypeaheadMonogramDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadMonogramDatasource.php',
@@ -6054,6 +6055,7 @@
'PhabricatorTypeaheadCompositeDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorTypeaheadDatasource' => 'Phobject',
'PhabricatorTypeaheadDatasourceController' => 'PhabricatorController',
+ 'PhabricatorTypeaheadFunctionHelpController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadInvalidTokenException' => 'Exception',
'PhabricatorTypeaheadModularDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadMonogramDatasource' => 'PhabricatorTypeaheadDatasource',
diff --git a/src/applications/maniphest/typeahead/ManiphestNoOwnerDatasource.php b/src/applications/maniphest/typeahead/ManiphestNoOwnerDatasource.php
--- a/src/applications/maniphest/typeahead/ManiphestNoOwnerDatasource.php
+++ b/src/applications/maniphest/typeahead/ManiphestNoOwnerDatasource.php
@@ -20,7 +20,20 @@
public function getDatasourceFunctions() {
return array(
'none' => array(
- 'name' => pht('Find results which are not assigned.'),
+ 'name' => pht('No Owner'),
+ 'summary' => pht('Find results which are not assigned.'),
+ 'description' => pht(
+ 'This function includes results which have no owner. Use a query '.
+ 'like this to find unassigned results:'.
+ "\n\n".
+ '> none()'.
+ "\n\n".
+ 'If you combine this function with other functions, the query will '.
+ 'return results which match the other selectors //or// have no '.
+ 'owner. For example, this query will find results which are owned '.
+ 'by `alincoln`, and will also find results which have no owner:'.
+ "\n\n".
+ '> alincoln, none()'),
),
);
}
diff --git a/src/applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php b/src/applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectLogicalOrNotDatasource.php
@@ -24,10 +24,54 @@
public function getDatasourceFunctions() {
return array(
'any' => array(
- 'name' => pht('Find results in any of several projects.'),
+ 'name' => pht('In Any: ...'),
+ 'arguments' => pht('project'),
+ 'summary' => pht('Find results in any of several projects.'),
+ 'description' => pht(
+ 'This function allows you to find results in one of several '.
+ 'projects. Another way to think of this function is that it '.
+ 'allows you to perform an "or" query.'.
+ "\n\n".
+ 'By default, if you enter several projects, results are returned '.
+ 'only if they belong to all of the projects you enter. That is, '.
+ 'this query will only return results in //both// projects:'.
+ "\n\n".
+ '> ios, android'.
+ "\n\n".
+ 'If you want to find results in any of several projects, you can '.
+ 'use the `any()` function. For example, you can use this query to '.
+ 'find results which are in //either// project:'.
+ "\n\n".
+ '> any(ios), any(android)'.
+ "\n\n".
+ 'You can combine the `any()` function with normal project tokens '.
+ 'to refine results. For example, use this query to find bugs in '.
+ '//either// iOS or Android:'.
+ "\n\n".
+ '> bug, any(ios), any(android)'),
),
'not' => array(
- 'name' => pht('Find results not in specific projects.'),
+ 'name' => pht('Not In: ...'),
+ 'arguments' => pht('project'),
+ 'summary' => pht('Find results not in specific projects.'),
+ 'description' => pht(
+ 'This function allows you to find results which are not in '.
+ 'one or more projects. For example, use this query to find '.
+ 'results which are not associated with a specific project:'.
+ "\n\n".
+ '> not(vanilla)'.
+ "\n\n".
+ 'You can exclude multiple projects. This will cause the query '.
+ 'to return only results which are not in any of the excluded '.
+ 'projects:'.
+ "\n\n".
+ '> not(vanilla), not(chocolate)'.
+ "\n\n".
+ 'You can combine this function with other functions to refine '.
+ 'results. For example, use this query to find iOS results which '.
+ 'are not bugs:'.
+ "\n\n".
+ '> ios, not(bug)'),
),
);
}
diff --git a/src/applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php b/src/applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectLogicalUserDatasource.php
@@ -24,7 +24,17 @@
public function getDatasourceFunctions() {
return array(
'projects' => array(
- 'name' => pht("Find results in any of a user's projects."),
+ 'name' => pht('Projects: ...'),
+ 'arguments' => pht('username'),
+ 'summary' => pht("Find results in any of a user's projects."),
+ 'description' => pht(
+ 'This function allows you to find results associated with any '.
+ 'of the projects a specified user is a member of. For example, '.
+ 'this will find results associated with all of the projects '.
+ '`alincoln` is a member of:'.
+ "\n\n".
+ '> projects(alincoln)'.
+ "\n\n"),
),
);
}
diff --git a/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php b/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectLogicalViewerDatasource.php
@@ -18,7 +18,19 @@
public function getDatasourceFunctions() {
return array(
'viewerprojects' => array(
- 'name' => pht("Find results in any of the current viewer's projects."),
+ 'name' => pht("Current Viewer's Projects"),
+ 'summary' => pht(
+ "Find results in any of the current viewer's projects."),
+ 'description' => pht(
+ "This function matches results in any of the current viewing ".
+ "user's projects:".
+ "\n\n".
+ "> viewerprojects()".
+ "\n\n".
+ "This normally means //your// projects, but if you save a query ".
+ "using this function and send it to someone else, it will mean ".
+ "//their// projects when they run it (they become the currnet ".
+ "viewer). This can be useful for building dashboard panels."),
),
);
}
diff --git a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectMembersDatasource.php
@@ -24,7 +24,14 @@
public function getDatasourceFunctions() {
return array(
'members' => array(
- 'name' => pht('Find results for members of a project.'),
+ 'name' => pht('Members: ...'),
+ 'arguments' => pht('project'),
+ 'summary' => pht('Find results for members of a project.'),
+ 'description' => pht(
+ 'This function allows you to find results for any of the members '.
+ 'of a project:'.
+ "\n\n".
+ '> members(frontend)'),
),
);
}
diff --git a/src/applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php b/src/applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php
--- a/src/applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php
+++ b/src/applications/project/typeahead/PhabricatorProjectNoProjectsDatasource.php
@@ -18,7 +18,15 @@
public function getDatasourceFunctions() {
return array(
'null' => array(
- 'name' => pht('Find results which are not in any projects.'),
+ 'name' => pht('Not In Any Projects'),
+ 'summary' => pht('Find results which are not in any projects.'),
+ 'description' => pht(
+ 'This function matches results which are not associated with any '.
+ 'projects. It is usually most often used to find objects which '.
+ 'might have slipped through the cracks and not been organized '.
+ 'properly.'.
+ "\n\n".
+ "> null()"),
),
);
}
diff --git a/src/applications/typeahead/application/PhabricatorTypeaheadApplication.php b/src/applications/typeahead/application/PhabricatorTypeaheadApplication.php
--- a/src/applications/typeahead/application/PhabricatorTypeaheadApplication.php
+++ b/src/applications/typeahead/application/PhabricatorTypeaheadApplication.php
@@ -11,6 +11,8 @@
'/typeahead/' => array(
'(?P<action>browse|class)/(?:(?P<class>\w+)/)?'
=> 'PhabricatorTypeaheadModularDatasourceController',
+ 'help/(?P<class>\w+)/'
+ => 'PhabricatorTypeaheadFunctionHelpController',
),
);
}
diff --git a/src/applications/typeahead/controller/PhabricatorTypeaheadFunctionHelpController.php b/src/applications/typeahead/controller/PhabricatorTypeaheadFunctionHelpController.php
new file mode 100644
--- /dev/null
+++ b/src/applications/typeahead/controller/PhabricatorTypeaheadFunctionHelpController.php
@@ -0,0 +1,150 @@
+<?php
+
+final class PhabricatorTypeaheadFunctionHelpController
+ extends PhabricatorTypeaheadDatasourceController {
+
+ public function shouldAllowPublic() {
+ return true;
+ }
+
+ public function handleRequest(AphrontRequest $request) {
+ $viewer = $this->getViewer();
+ $class = $request->getURIData('class');
+
+ $sources = id(new PhutilSymbolLoader())
+ ->setAncestorClass('PhabricatorTypeaheadDatasource')
+ ->loadObjects();
+ if (!isset($sources[$class])) {
+ return new Aphront404Response();
+ }
+
+ $source = $sources[$class];
+
+ $application_class = $source->getDatasourceApplicationClass();
+ if ($application_class) {
+ $result = id(new PhabricatorApplicationQuery())
+ ->setViewer($this->getViewer())
+ ->withClasses(array($application_class))
+ ->execute();
+ if (!$result) {
+ return new Aphront404Response();
+ }
+ }
+
+ $source->setViewer($viewer);
+
+ $title = pht('Typeahead Function Help');
+
+ $functions = $source->getAllDatasourceFunctions();
+ ksort($functions);
+
+ $content = array();
+
+ $content[] = '= '.pht('Overview');
+ $content[] = pht(
+ 'Typeahead functions are an advanced feature which allow you to build '.
+ 'more powerful queries. This document explains functions available '.
+ 'for the selected control.'.
+ "\n\n".
+ 'Note that different controls support //different// functions '.
+ '(depending on what the control is doing), so these specific functions '.
+ 'may not work everywhere. You can always check the help for a control '.
+ 'to review which functions are available for that control.');
+
+ $table = array();
+
+ $table_header = array(
+ pht('Function'),
+ pht('Token Name'),
+ pht('Summary'),
+ );
+ $table[] = '| '.implode(' | ', $table_header).' |';
+ $table[] = '|---|---|---|';
+
+ foreach ($functions as $function => $spec) {
+ $spec = $spec + array(
+ 'summary' => null,
+ 'arguments' => null,
+ );
+
+ if (idx($spec, 'arguments')) {
+ $signature = '**'.$function.'(**//'.$spec['arguments'].'//**)**';
+ } else {
+ $signature = '**'.$function.'()**';
+ }
+
+ $name = idx($spec, 'name', '');
+ $summary = idx($spec, 'summary', '');
+
+ $table[] = '| '.$signature.' | '.$name.' | '.$summary.' |';
+ }
+
+ $table = implode("\n", $table);
+ $content[] = '= '.pht('Function Quick Reference');
+ $content[] = pht(
+ 'This table briefly describes available functions for this control. '.
+ 'For details on a particular function, see the corresponding section '.
+ 'below.');
+ $content[] = $table;
+
+ $content[] = '= '.pht('Using Typeahead Functions');
+ $content[] = pht(
+ 'In addition to typing user and project names to build queries, you can '.
+ 'also type the names of special functions which give you more options '.
+ 'and the ability to express more complex queries.'.
+ "\n\n".
+ 'Functions have an internal name (like `viewer()`) and a '.
+ 'human-readable name, like `Current Viewer`. In general, you can type '.
+ 'either one to select the function. You can also click the '.
+ '{nav icon=search} button on any typeahead control to browse available '.
+ 'functions and find this documentation.'.
+ "\n\n".
+ 'This documentation uses the internal names to make it clear where '.
+ 'tokens begin and end. Specifically, you will find queries written '.
+ 'out like this in the documentation: '.
+ "\n\n".
+ '> viewer(), alincoln'.
+ "\n\n".
+ 'When this query is actually shown in the control, it will look more '.
+ 'like this:'.
+ "\n\n".
+ '> {nav Current Viewer} {nav alincoln (Abraham Lincoln)}');
+
+
+ $middot = "\xC2\xB7";
+ foreach ($functions as $function => $spec) {
+ $arguments = idx($spec, 'arguments', '');
+ $name = idx($spec, 'name');
+ $content[] = '= '.$function.'('.$arguments.') '.$middot.' '.$name;
+ $content[] = $spec['description'];
+ }
+
+ $content = implode("\n\n", $content);
+
+ $content_box = PhabricatorMarkupEngine::renderOneObject(
+ id(new PhabricatorMarkupOneOff())->setContent($content),
+ 'default',
+ $viewer);
+
+ $header = id(new PHUIHeaderView())
+ ->setHeader($title);
+
+ $document = id(new PHUIDocumentView())
+ ->setHeader($header)
+ ->setFontKit(PHUIDocumentView::FONT_SOURCE_SANS)
+ ->appendChild($content_box);
+
+ $crumbs = $this->buildApplicationCrumbs();
+ $crumbs->addTextCrumb(pht('Function Help'));
+
+ return $this->buildApplicationPage(
+ array(
+ $crumbs,
+ $document,
+ ),
+ array(
+ 'title' => $title,
+ ));
+ }
+
+}
diff --git a/src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php b/src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php
--- a/src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php
+++ b/src/applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php
@@ -222,11 +222,32 @@
$frame,
);
+ $function_help = null;
+ if ($source->getAllDatasourceFunctions()) {
+ $reference_uri = '/typeahead/help/'.get_class($source).'/';
+
+ $reference_link = phutil_tag(
+ 'a',
+ array(
+ 'href' => $reference_uri,
+ 'target' => '_blank',
+ ),
+ pht('Reference: Advanced Functions'));
+
+ $function_help = array(
+ id(new PHUIIconView())
+ ->setIconFont('fa-book'),
+ ' ',
+ $reference_link,
+ );
+ }
+
return $this->newDialog()
->setWidth(AphrontDialogView::WIDTH_FORM)
->setRenderDialogAsDiv(true)
->setTitle($source->getBrowseTitle())
->appendChild($browser)
+ ->addFooter($function_help)
->addCancelButton('/', pht('Close'));
}
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
@@ -117,6 +117,14 @@
return $this->usable;
}
+ public function getAllDatasourceFunctions() {
+ $results = parent::getAllDatasourceFunctions();
+ foreach ($this->getUsableDatasources() as $source) {
+ $results += $source->getAllDatasourceFunctions();
+ }
+ return $results;
+ }
+
protected function didEvaluateTokens(array $results) {
foreach ($this->getUsableDatasources() as $source) {
$results = $source->didEvaluateTokens($results);
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
@@ -279,6 +279,14 @@
/**
* @task functions
*/
+ public function getAllDatasourceFunctions() {
+ return $this->getDatasourceFunctions();
+ }
+
+
+ /**
+ * @task functions
+ */
protected function canEvaluateFunction($function) {
return $this->shouldStripFunction($function);
}

File Metadata

Mime Type
text/plain
Expires
Mon, May 13, 3:49 AM (1 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6289583
Default Alt Text
D12482.id29968.diff (18 KB)

Event Timeline