Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F15411154
D19127.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
12 KB
Referenced Files
None
Subscribers
None
D19127.diff
View Options
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
@@ -2617,6 +2617,9 @@
'PhabricatorCountdownViewController' => 'applications/countdown/controller/PhabricatorCountdownViewController.php',
'PhabricatorCursorPagedPolicyAwareQuery' => 'infrastructure/query/policy/PhabricatorCursorPagedPolicyAwareQuery.php',
'PhabricatorCustomField' => 'infrastructure/customfield/field/PhabricatorCustomField.php',
+ 'PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource' => 'infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource.php',
+ 'PhabricatorCustomFieldApplicationSearchDatasource' => 'infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchDatasource.php',
+ 'PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource' => 'infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource.php',
'PhabricatorCustomFieldAttachment' => 'infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php',
'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php',
'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
@@ -4387,6 +4390,7 @@
'PhabricatorTypeaheadInvalidTokenException' => 'applications/typeahead/exception/PhabricatorTypeaheadInvalidTokenException.php',
'PhabricatorTypeaheadModularDatasourceController' => 'applications/typeahead/controller/PhabricatorTypeaheadModularDatasourceController.php',
'PhabricatorTypeaheadMonogramDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadMonogramDatasource.php',
+ 'PhabricatorTypeaheadProxyDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadProxyDatasource.php',
'PhabricatorTypeaheadResult' => 'applications/typeahead/storage/PhabricatorTypeaheadResult.php',
'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'applications/typeahead/datasource/PhabricatorTypeaheadRuntimeCompositeDatasource.php',
'PhabricatorTypeaheadTestNumbersDatasource' => 'applications/typeahead/datasource/__tests__/PhabricatorTypeaheadTestNumbersDatasource.php',
@@ -8122,6 +8126,9 @@
'PhabricatorCountdownViewController' => 'PhabricatorCountdownController',
'PhabricatorCursorPagedPolicyAwareQuery' => 'PhabricatorPolicyAwareQuery',
'PhabricatorCustomField' => 'Phobject',
+ 'PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource' => 'PhabricatorTypeaheadDatasource',
+ 'PhabricatorCustomFieldApplicationSearchDatasource' => 'PhabricatorTypeaheadProxyDatasource',
+ 'PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource' => 'PhabricatorTypeaheadDatasource',
'PhabricatorCustomFieldAttachment' => 'Phobject',
'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType',
'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
@@ -10182,6 +10189,7 @@
'PhabricatorTypeaheadInvalidTokenException' => 'Exception',
'PhabricatorTypeaheadModularDatasourceController' => 'PhabricatorTypeaheadDatasourceController',
'PhabricatorTypeaheadMonogramDatasource' => 'PhabricatorTypeaheadDatasource',
+ 'PhabricatorTypeaheadProxyDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorTypeaheadResult' => 'Phobject',
'PhabricatorTypeaheadRuntimeCompositeDatasource' => 'PhabricatorTypeaheadCompositeDatasource',
'PhabricatorTypeaheadTestNumbersDatasource' => 'PhabricatorTypeaheadDatasource',
diff --git a/src/applications/typeahead/datasource/PhabricatorTypeaheadProxyDatasource.php b/src/applications/typeahead/datasource/PhabricatorTypeaheadProxyDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/applications/typeahead/datasource/PhabricatorTypeaheadProxyDatasource.php
@@ -0,0 +1,58 @@
+<?php
+
+abstract class PhabricatorTypeaheadProxyDatasource
+ extends PhabricatorTypeaheadCompositeDatasource {
+
+ private $datasource;
+
+ public function setDatasource(PhabricatorTypeaheadDatasource $datasource) {
+ $this->datasource = $datasource;
+ $this->setParameters(
+ array(
+ 'class' => get_class($datasource),
+ 'parameters' => $datasource->getParameters(),
+ ));
+ return $this;
+ }
+
+ public function getDatasource() {
+ if (!$this->datasource) {
+ $class = $this->getParameter('class');
+
+ $parent = 'PhabricatorTypeaheadDatasource';
+ if (!is_subclass_of($class, $parent)) {
+ throw new Exception(
+ pht(
+ 'Configured datasource class "%s" must be a valid subclass of '.
+ '"%s".',
+ $class,
+ $parent));
+ }
+
+ $datasource = newv($class, array());
+ $datasource->setParameters($this->getParameter('parameters', array()));
+ $this->datasource = $datasource;
+ }
+
+ return $this->datasource;
+ }
+
+ public function getComponentDatasources() {
+ return array(
+ $this->getDatasource(),
+ );
+ }
+
+ public function getDatasourceApplicationClass() {
+ return $this->getDatasource()->getDatasourceApplicationClass();
+ }
+
+ public function getBrowseTitle() {
+ return $this->getDatasource()->getBrowseTitle();
+ }
+
+ public function getPlaceholderText() {
+ return $this->getDatasource()->getPlaceholderText();
+ }
+
+}
diff --git a/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource.php b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource.php
@@ -0,0 +1,70 @@
+<?php
+
+final class PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource
+ extends PhabricatorTypeaheadDatasource {
+
+ public function getBrowseTitle() {
+ return pht('Browse Any');
+ }
+
+ public function getPlaceholderText() {
+ return pht('Type "any()"...');
+ }
+
+ public function getDatasourceApplicationClass() {
+ return null;
+ }
+
+ public function getDatasourceFunctions() {
+ return array(
+ 'any' => array(
+ 'name' => pht('Any Value'),
+ 'summary' => pht('Find results with any value.'),
+ 'description' => pht(
+ "This function includes results which have any value. Use a query ".
+ "like this to find results with any value:\n\n%s".
+ '> any()'),
+ ),
+ );
+ }
+
+ public function loadResults() {
+ $results = array(
+ $this->newAnyFunction(),
+ );
+ return $this->filterResultsAgainstTokens($results);
+ }
+
+ protected function evaluateFunction($function, array $argv_list) {
+ $results = array();
+
+ foreach ($argv_list as $argv) {
+ $results[] = new PhabricatorQueryConstraint(
+ PhabricatorQueryConstraint::OPERATOR_ANY,
+ null);
+ }
+
+ return $results;
+ }
+
+ public function renderFunctionTokens($function, array $argv_list) {
+ $results = array();
+ foreach ($argv_list as $argv) {
+ $results[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
+ $this->newAnyFunction());
+ }
+ return $results;
+ }
+
+ private function newAnyFunction() {
+ $name = pht('Any Value');
+ return $this->newFunctionResult()
+ ->setName($name.' any')
+ ->setDisplayName($name)
+ ->setIcon('fa-circle-o')
+ ->setPHID('any()')
+ ->setUnique(true)
+ ->addAttribute(pht('Select results with any value.'));
+ }
+
+}
diff --git a/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchDatasource.php b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchDatasource.php
@@ -0,0 +1,17 @@
+<?php
+
+final class PhabricatorCustomFieldApplicationSearchDatasource
+ extends PhabricatorTypeaheadProxyDatasource {
+
+ public function getComponentDatasources() {
+ $datasources = parent::getComponentDatasources();
+
+ $datasources[] =
+ new PhabricatorCustomFieldApplicationSearchAnyFunctionDatasource();
+ $datasources[] =
+ new PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource();
+
+ return $datasources;
+ }
+
+}
diff --git a/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource.php b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource.php
new file mode 100644
--- /dev/null
+++ b/src/infrastructure/customfield/datasource/PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource.php
@@ -0,0 +1,72 @@
+<?php
+
+final class PhabricatorCustomFieldApplicationSearchNoneFunctionDatasource
+ extends PhabricatorTypeaheadDatasource {
+
+ public function getBrowseTitle() {
+ return pht('Browse No Value');
+ }
+
+ public function getPlaceholderText() {
+ return pht('Type "none()"...');
+ }
+
+ public function getDatasourceApplicationClass() {
+ return null;
+ }
+
+ public function getDatasourceFunctions() {
+ return array(
+ 'none' => array(
+ 'name' => pht('No Value'),
+ 'summary' => pht('Find results with no value.'),
+ 'description' => pht(
+ "This function includes results which have no value. Use a query ".
+ "like this to find results with no value:\n\n%s\n\n",
+ 'If you combine this function with other constraints, results '.
+ 'which have no value or the specified values will be returned.',
+ '> any()'),
+ ),
+ );
+ }
+
+ public function loadResults() {
+ $results = array(
+ $this->newNoneFunction(),
+ );
+ return $this->filterResultsAgainstTokens($results);
+ }
+
+ protected function evaluateFunction($function, array $argv_list) {
+ $results = array();
+
+ foreach ($argv_list as $argv) {
+ $results[] = new PhabricatorQueryConstraint(
+ PhabricatorQueryConstraint::OPERATOR_NULL,
+ null);
+ }
+
+ return $results;
+ }
+
+ public function renderFunctionTokens($function, array $argv_list) {
+ $results = array();
+ foreach ($argv_list as $argv) {
+ $results[] = PhabricatorTypeaheadTokenView::newFromTypeaheadResult(
+ $this->newNoneFunction());
+ }
+ return $results;
+ }
+
+ private function newNoneFunction() {
+ $name = pht('No Value');
+ return $this->newFunctionResult()
+ ->setName($name.' none')
+ ->setDisplayName($name)
+ ->setIcon('fa-ban')
+ ->setPHID('none()')
+ ->setUnique(true)
+ ->addAttribute(pht('Select results with no value.'));
+ }
+
+}
diff --git a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php
--- a/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php
+++ b/src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php
@@ -33,12 +33,28 @@
$control = id(new AphrontFormTokenizerControl())
->setLabel($this->getFieldName())
->setName($this->getFieldKey())
- ->setDatasource($this->getDatasource())
+ ->setDatasource($this->newApplicationSearchDatasource())
->setValue(nonempty($value, array()));
$form->appendControl($control);
}
+ public function applyApplicationSearchConstraintToQuery(
+ PhabricatorApplicationSearchEngine $engine,
+ PhabricatorCursorPagedPolicyAwareQuery $query,
+ $value) {
+ if ($value) {
+
+ $datasource = $this->newApplicationSearchDatasource()
+ ->setViewer($this->getViewer());
+ $value = $datasource->evaluateTokens($value);
+
+ $query->withApplicationSearchContainsConstraint(
+ $this->newStringIndex(null),
+ $value);
+ }
+ }
+
public function getHeraldFieldValueType($condition) {
return id(new HeraldTokenizerFieldValue())
->setKey('custom.'.$this->getFieldKey())
@@ -120,4 +136,11 @@
}
}
+ protected function newApplicationSearchDatasource() {
+ $datasource = $this->getDatasource();
+
+ return id(new PhabricatorCustomFieldApplicationSearchDatasource())
+ ->setDatasource($datasource);
+ }
+
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Mar 20, 8:52 AM (5 d, 10 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225004
Default Alt Text
D19127.diff (12 KB)
Attached To
Mode
D19127: Support "Any Value" and "No Value" search constraints for datasource Custom Fields
Attached
Detach File
Event Timeline
Log In to Comment