mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-25 00:02:41 +01:00
65b891b095
Summary: Ref T8441. Ref T7715. Let SearchFields do some value massaging before buiding queries so we don't have to work as hard in each SearchEngine. Particularly, they can handle evaluateTokens() from Tokenizers. Test Plan: Paste automatically gained access to `viewer()`, etc. Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7715, T8441 Differential Revision: https://secure.phabricator.com/D13170
264 lines
5.8 KiB
PHP
264 lines
5.8 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @task config Configuring Fields
|
|
* @task error Handling Errors
|
|
* @task io Reading and Writing Field Values
|
|
* @task util Utility Methods
|
|
*/
|
|
abstract class PhabricatorSearchField extends Phobject {
|
|
|
|
private $key;
|
|
private $viewer;
|
|
private $value;
|
|
private $label;
|
|
private $aliases = array();
|
|
private $errors = array();
|
|
|
|
|
|
/* -( Configuring Fields )------------------------------------------------- */
|
|
|
|
|
|
/**
|
|
* Set the primary key for the field, like `projectPHIDs`.
|
|
*
|
|
* You can set human-readable aliases with @{method:setAliases}.
|
|
*
|
|
* The key should be a short, unique (within a search engine) string which
|
|
* does not contain any special characters.
|
|
*
|
|
* @param string Unique key which identifies the field.
|
|
* @return this
|
|
* @task config
|
|
*/
|
|
public function setKey($key) {
|
|
$this->key = $key;
|
|
return $this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the field's key.
|
|
*
|
|
* @return string Unique key for this field.
|
|
* @task config
|
|
*/
|
|
public function getKey() {
|
|
return $this->key;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set a human-readable label for the field.
|
|
*
|
|
* This should be a short text string, like "Reviewers" or "Colors".
|
|
*
|
|
* @param string Short, human-readable field label.
|
|
* @return this
|
|
* task config
|
|
*/
|
|
public function setLabel($label) {
|
|
$this->label = $label;
|
|
return $this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the field's human-readable label.
|
|
*
|
|
* @return string Short, human-readable field label.
|
|
* @task config
|
|
*/
|
|
public function getLabel() {
|
|
return $this->label;
|
|
}
|
|
|
|
|
|
/**
|
|
* Set the acting viewer.
|
|
*
|
|
* Engines do not need to do this explicitly; it will be done on their
|
|
* behalf by the caller.
|
|
*
|
|
* @param PhabricatorUser Viewer.
|
|
* @return this
|
|
* @task config
|
|
*/
|
|
public function setViewer(PhabricatorUser $viewer) {
|
|
$this->viewer = $viewer;
|
|
return $this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the acting viewer.
|
|
*
|
|
* @return PhabricatorUser Viewer.
|
|
* @task config
|
|
*/
|
|
public function getViewer() {
|
|
return $this->viewer;
|
|
}
|
|
|
|
|
|
/**
|
|
* Provide alternate field aliases, usually more human-readable versions
|
|
* of the key.
|
|
*
|
|
* These aliases can be used when building GET requests, so you can provide
|
|
* an alias like `authors` to let users write `&authors=alincoln` instead of
|
|
* `&authorPHIDs=alincoln`. This is a little easier to use.
|
|
*
|
|
* @param list<string> List of aliases for this field.
|
|
* @return this
|
|
* @task config
|
|
*/
|
|
public function setAliases(array $aliases) {
|
|
$this->aliases = $aliases;
|
|
return $this;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get aliases for this field.
|
|
*
|
|
* @return list<string> List of aliases for this field.
|
|
* @task config
|
|
*/
|
|
public function getAliases() {
|
|
return $this->aliases;
|
|
}
|
|
|
|
|
|
/* -( Handling Errors )---------------------------------------------------- */
|
|
|
|
|
|
protected function addError($short, $long) {
|
|
$this->errors[] = array($short, $long);
|
|
return $this;
|
|
}
|
|
|
|
public function getErrors() {
|
|
return $this->errors;
|
|
}
|
|
|
|
protected function validateControlValue($value) {
|
|
return;
|
|
}
|
|
|
|
protected function getShortError() {
|
|
$error = head($this->getErrors());
|
|
if ($error) {
|
|
return head($error);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
|
|
/* -( Reading and Writing Field Values )----------------------------------- */
|
|
|
|
|
|
public function readValueFromRequest(AphrontRequest $request) {
|
|
$check = array_merge(array($this->getKey()), $this->getAliases());
|
|
foreach ($check as $key) {
|
|
if ($this->getValueExistsInRequest($request, $key)) {
|
|
return $this->getValueFromRequest($request, $key);
|
|
}
|
|
}
|
|
return $this->getDefaultValue();
|
|
}
|
|
|
|
protected function getValueExistsInRequest(AphrontRequest $request, $key) {
|
|
return $request->getExists($key);
|
|
}
|
|
|
|
abstract protected function getValueFromRequest(
|
|
AphrontRequest $request,
|
|
$key);
|
|
|
|
public function readValueFromSavedQuery(PhabricatorSavedQuery $saved) {
|
|
$value = $saved->getParameter(
|
|
$this->getKey(),
|
|
$this->getDefaultValue());
|
|
$this->value = $this->didReadValueFromSavedQuery($value);
|
|
$this->validateControlValue($value);
|
|
return $this;
|
|
}
|
|
|
|
protected function didReadValueFromSavedQuery($value) {
|
|
return $value;
|
|
}
|
|
|
|
public function getValue() {
|
|
return $this->value;
|
|
}
|
|
|
|
protected function getValueForControl() {
|
|
return $this->value;
|
|
}
|
|
|
|
protected function getDefaultValue() {
|
|
return null;
|
|
}
|
|
|
|
public function getValueForQuery($value) {
|
|
return $value;
|
|
}
|
|
|
|
|
|
/* -( Rendering Controls )------------------------------------------------- */
|
|
|
|
|
|
abstract protected function newControl();
|
|
|
|
|
|
protected function renderControl() {
|
|
// TODO: We should `setError($this->getShortError())` here, but it looks
|
|
// terrible in the form layout.
|
|
|
|
return $this->newControl()
|
|
->setValue($this->getValueForControl())
|
|
->setName($this->getKey())
|
|
->setLabel($this->getLabel());
|
|
}
|
|
|
|
public function appendToForm(AphrontFormView $form) {
|
|
$form->appendControl($this->renderControl());
|
|
return $this;
|
|
}
|
|
|
|
|
|
/* -( Utility Methods )----------------------------------------------------- */
|
|
|
|
|
|
/**
|
|
* Read a list of items from the request, in either array format or string
|
|
* format:
|
|
*
|
|
* list[]=item1&list[]=item2
|
|
* list=item1,item2
|
|
*
|
|
* This provides flexibility when constructing URIs, especially from external
|
|
* sources.
|
|
*
|
|
* @param AphrontRequest Request to read strings from.
|
|
* @param string Key to read in the request.
|
|
* @return list<string> List of values.
|
|
* @task utility
|
|
*/
|
|
protected function getListFromRequest(
|
|
AphrontRequest $request,
|
|
$key) {
|
|
|
|
$list = $request->getArr($key, null);
|
|
if ($list === null) {
|
|
$list = $request->getStrList($key);
|
|
}
|
|
|
|
if (!$list) {
|
|
return array();
|
|
}
|
|
|
|
return $list;
|
|
}
|
|
}
|