Page MenuHomePhabricator

D19127.id45831.diff
No OneTemporary

D19127.id45831.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
@@ -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

Mime Type
text/plain
Expires
Sun, Mar 23, 6:07 AM (2 d, 13 h ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7225004
Default Alt Text
D19127.id45831.diff (12 KB)

Event Timeline