mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Use classes to define standard field types and implement an "int" type
Summary: Currently, `ManiphestAuxiliaryFieldDefaultSpecification` uses about a dozen giant `switch` statements to implement stadard field types (int, string, date, bool, select, user, remarkup, etc). This is: - pretty gross; - not extensible; and - doesn't really let us share that much code. I got about halfway through porting a similar implementation into StandardField but I wasn't thrilled with it. Subclass StandardField instead to implement custom field types. Test Plan: Added an "int" custom field, verified it had integer semantics and indexed into the integer index. Reviewers: btrahan Reviewed By: btrahan CC: aran Differential Revision: https://secure.phabricator.com/D7005
This commit is contained in:
parent
ed126cd47e
commit
2b538bfb25
4 changed files with 167 additions and 70 deletions
|
@ -1635,8 +1635,10 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
|
'PhabricatorSlugTestCase' => 'infrastructure/util/__tests__/PhabricatorSlugTestCase.php',
|
||||||
'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php',
|
'PhabricatorSortTableExample' => 'applications/uiexample/examples/PhabricatorSortTableExample.php',
|
||||||
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
|
'PhabricatorSourceCodeView' => 'view/layout/PhabricatorSourceCodeView.php',
|
||||||
'PhabricatorStandardCustomField' => 'infrastructure/customfield/field/PhabricatorStandardCustomField.php',
|
'PhabricatorStandardCustomField' => 'infrastructure/customfield/standard/PhabricatorStandardCustomField.php',
|
||||||
|
'PhabricatorStandardCustomFieldInt' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldInt.php',
|
||||||
'PhabricatorStandardCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorStandardCustomFieldInterface.php',
|
'PhabricatorStandardCustomFieldInterface' => 'infrastructure/customfield/interface/PhabricatorStandardCustomFieldInterface.php',
|
||||||
|
'PhabricatorStandardCustomFieldText' => 'infrastructure/customfield/standard/PhabricatorStandardCustomFieldText.php',
|
||||||
'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
|
'PhabricatorStandardPageView' => 'view/page/PhabricatorStandardPageView.php',
|
||||||
'PhabricatorStatusController' => 'applications/system/PhabricatorStatusController.php',
|
'PhabricatorStatusController' => 'applications/system/PhabricatorStatusController.php',
|
||||||
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
|
'PhabricatorStorageFixtureScopeGuard' => 'infrastructure/testing/fixture/PhabricatorStorageFixtureScopeGuard.php',
|
||||||
|
@ -3783,6 +3785,8 @@ phutil_register_library_map(array(
|
||||||
'PhabricatorSortTableExample' => 'PhabricatorUIExample',
|
'PhabricatorSortTableExample' => 'PhabricatorUIExample',
|
||||||
'PhabricatorSourceCodeView' => 'AphrontView',
|
'PhabricatorSourceCodeView' => 'AphrontView',
|
||||||
'PhabricatorStandardCustomField' => 'PhabricatorCustomField',
|
'PhabricatorStandardCustomField' => 'PhabricatorCustomField',
|
||||||
|
'PhabricatorStandardCustomFieldInt' => 'PhabricatorStandardCustomField',
|
||||||
|
'PhabricatorStandardCustomFieldText' => 'PhabricatorStandardCustomField',
|
||||||
'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
|
'PhabricatorStandardPageView' => 'PhabricatorBarePageView',
|
||||||
'PhabricatorStatusController' => 'PhabricatorController',
|
'PhabricatorStatusController' => 'PhabricatorController',
|
||||||
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
'PhabricatorStorageManagementDatabasesWorkflow' => 'PhabricatorStorageManagementWorkflow',
|
||||||
|
|
|
@ -1,27 +1,41 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
final class PhabricatorStandardCustomField
|
abstract class PhabricatorStandardCustomField
|
||||||
extends PhabricatorCustomField {
|
extends PhabricatorCustomField {
|
||||||
|
|
||||||
private $fieldKey;
|
private $fieldKey;
|
||||||
private $fieldName;
|
private $fieldName;
|
||||||
private $fieldType;
|
|
||||||
private $fieldValue;
|
private $fieldValue;
|
||||||
private $fieldDescription;
|
private $fieldDescription;
|
||||||
private $fieldConfig;
|
private $fieldConfig;
|
||||||
private $applicationField;
|
private $applicationField;
|
||||||
|
|
||||||
|
abstract public function getFieldType();
|
||||||
|
|
||||||
public static function buildStandardFields(
|
public static function buildStandardFields(
|
||||||
PhabricatorCustomField $template,
|
PhabricatorCustomField $template,
|
||||||
array $config) {
|
array $config) {
|
||||||
|
|
||||||
|
$types = id(new PhutilSymbolLoader())
|
||||||
|
->setAncestorClass(__CLASS__)
|
||||||
|
->loadObjects();
|
||||||
|
$types = mpull($types, null, 'getFieldType');
|
||||||
|
|
||||||
$fields = array();
|
$fields = array();
|
||||||
foreach ($config as $key => $value) {
|
foreach ($config as $key => $value) {
|
||||||
|
$type = idx($value, 'type', 'text');
|
||||||
|
if (empty($types[$type])) {
|
||||||
|
// TODO: We should have better typechecking somewhere, and then make
|
||||||
|
// this more serious.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$namespace = $template->getStandardCustomFieldNamespace();
|
$namespace = $template->getStandardCustomFieldNamespace();
|
||||||
$full_key = "std:{$namespace}:{$key}";
|
$full_key = "std:{$namespace}:{$key}";
|
||||||
|
|
||||||
$template = clone $template;
|
$template = clone $template;
|
||||||
$standard = id(new PhabricatorStandardCustomField($full_key))
|
$standard = id(clone $types[$type])
|
||||||
|
->setFieldKey($full_key)
|
||||||
->setFieldConfig($value)
|
->setFieldConfig($value)
|
||||||
->setApplicationField($template);
|
->setApplicationField($template);
|
||||||
|
|
||||||
|
@ -32,10 +46,6 @@ final class PhabricatorStandardCustomField
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __construct($key) {
|
|
||||||
$this->fieldKey = $key;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function setApplicationField(
|
public function setApplicationField(
|
||||||
PhabricatorStandardCustomFieldInterface $application_field) {
|
PhabricatorStandardCustomFieldInterface $application_field) {
|
||||||
$this->applicationField = $application_field;
|
$this->applicationField = $application_field;
|
||||||
|
@ -51,15 +61,6 @@ final class PhabricatorStandardCustomField
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFieldType($type) {
|
|
||||||
$this->fieldType = $type;
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFieldType() {
|
|
||||||
return $this->fieldType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFieldValue() {
|
public function getFieldValue() {
|
||||||
return $this->fieldValue;
|
return $this->fieldValue;
|
||||||
}
|
}
|
||||||
|
@ -75,19 +76,17 @@ final class PhabricatorStandardCustomField
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setFieldConfig(array $config) {
|
public function setFieldConfig(array $config) {
|
||||||
$this->setFieldType('text');
|
|
||||||
|
|
||||||
foreach ($config as $key => $value) {
|
foreach ($config as $key => $value) {
|
||||||
switch ($key) {
|
switch ($key) {
|
||||||
case 'name':
|
case 'name':
|
||||||
$this->setFieldName($value);
|
$this->setFieldName($value);
|
||||||
break;
|
break;
|
||||||
case 'type':
|
|
||||||
$this->setFieldType($value);
|
|
||||||
break;
|
|
||||||
case 'description':
|
case 'description':
|
||||||
$this->setFieldDescription($value);
|
$this->setFieldDescription($value);
|
||||||
break;
|
break;
|
||||||
|
case 'type':
|
||||||
|
// We set this earlier on.
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->fieldConfig = $config;
|
$this->fieldConfig = $config;
|
||||||
|
@ -103,6 +102,11 @@ final class PhabricatorStandardCustomField
|
||||||
/* -( PhabricatorCustomField )--------------------------------------------- */
|
/* -( PhabricatorCustomField )--------------------------------------------- */
|
||||||
|
|
||||||
|
|
||||||
|
public function setFieldKey($field_key) {
|
||||||
|
$this->fieldKey = $field_key;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getFieldKey() {
|
public function getFieldKey() {
|
||||||
return $this->fieldKey;
|
return $this->fieldKey;
|
||||||
}
|
}
|
||||||
|
@ -136,20 +140,19 @@ final class PhabricatorStandardCustomField
|
||||||
}
|
}
|
||||||
|
|
||||||
public function readValueFromRequest(AphrontRequest $request) {
|
public function readValueFromRequest(AphrontRequest $request) {
|
||||||
$this->setFieldValue($request->getStr($this->getFieldKey()));
|
$value = $request->getStr($this->getFieldKey());
|
||||||
|
if (!strlen($value)) {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
$this->setFieldValue($value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function renderEditControl() {
|
public function renderEditControl() {
|
||||||
$type = $this->getFieldType();
|
|
||||||
switch ($type) {
|
|
||||||
case 'text':
|
|
||||||
default:
|
|
||||||
return id(new AphrontFormTextControl())
|
return id(new AphrontFormTextControl())
|
||||||
->setName($this->getFieldKey())
|
->setName($this->getFieldKey())
|
||||||
->setValue($this->getFieldValue())
|
->setValue($this->getFieldValue())
|
||||||
->setLabel($this->getFieldName());
|
->setLabel($this->getFieldName());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public function newStorageObject() {
|
public function newStorageObject() {
|
||||||
return $this->getApplicationField()->newStorageObject();
|
return $this->getApplicationField()->newStorageObject();
|
||||||
|
@ -176,42 +179,20 @@ final class PhabricatorStandardCustomField
|
||||||
}
|
}
|
||||||
|
|
||||||
public function buildFieldIndexes() {
|
public function buildFieldIndexes() {
|
||||||
$type = $this->getFieldType();
|
return array();
|
||||||
switch ($type) {
|
|
||||||
case 'text':
|
|
||||||
default:
|
|
||||||
return array(
|
|
||||||
$this->newStringIndex($this->getFieldValue()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function readApplicationSearchValueFromRequest(
|
public function readApplicationSearchValueFromRequest(
|
||||||
PhabricatorApplicationSearchEngine $engine,
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
AphrontRequest $request) {
|
AphrontRequest $request) {
|
||||||
$type = $this->getFieldType();
|
return;
|
||||||
switch ($type) {
|
|
||||||
case 'text':
|
|
||||||
default:
|
|
||||||
return $request->getStr('std:'.$this->getFieldIndex());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function applyApplicationSearchConstraintToQuery(
|
public function applyApplicationSearchConstraintToQuery(
|
||||||
PhabricatorApplicationSearchEngine $engine,
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
PhabricatorCursorPagedPolicyAwareQuery $query,
|
PhabricatorCursorPagedPolicyAwareQuery $query,
|
||||||
$value) {
|
$value) {
|
||||||
$type = $this->getFieldType();
|
return;
|
||||||
switch ($type) {
|
|
||||||
case 'text':
|
|
||||||
default:
|
|
||||||
if (strlen($value)) {
|
|
||||||
$query->withApplicationSearchContainsConstraint(
|
|
||||||
$this->newStringIndex(null),
|
|
||||||
$value);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appendToApplicationSearchForm(
|
public function appendToApplicationSearchForm(
|
||||||
|
@ -219,19 +200,7 @@ final class PhabricatorStandardCustomField
|
||||||
AphrontFormView $form,
|
AphrontFormView $form,
|
||||||
$value,
|
$value,
|
||||||
array $handles) {
|
array $handles) {
|
||||||
|
return;
|
||||||
$type = $this->getFieldType();
|
|
||||||
switch ($type) {
|
|
||||||
case 'text':
|
|
||||||
default:
|
|
||||||
$form->appendChild(
|
|
||||||
id(new AphrontFormTextControl())
|
|
||||||
->setLabel($this->getFieldName())
|
|
||||||
->setName('std:'.$this->getFieldIndex())
|
|
||||||
->setValue($value));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -0,0 +1,71 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorStandardCustomFieldInt
|
||||||
|
extends PhabricatorStandardCustomField {
|
||||||
|
|
||||||
|
public function getFieldType() {
|
||||||
|
return 'int';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildFieldIndexes() {
|
||||||
|
$indexes = array();
|
||||||
|
|
||||||
|
$value = $this->getFieldValue();
|
||||||
|
if (strlen($value)) {
|
||||||
|
$indexes[] = $this->newNumericIndex((int)$value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValueForStorage() {
|
||||||
|
$value = $this->getFieldValue();
|
||||||
|
if (strlen($value)) {
|
||||||
|
return (int)$value;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValueFromStorage($value) {
|
||||||
|
if (strlen($value)) {
|
||||||
|
$value = (int)$value;
|
||||||
|
} else {
|
||||||
|
$value = null;
|
||||||
|
}
|
||||||
|
return $this->setFieldValue($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readApplicationSearchValueFromRequest(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
AphrontRequest $request) {
|
||||||
|
|
||||||
|
return $request->getStr($this->getFieldKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyApplicationSearchConstraintToQuery(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
PhabricatorCursorPagedPolicyAwareQuery $query,
|
||||||
|
$value) {
|
||||||
|
|
||||||
|
if (strlen($value)) {
|
||||||
|
$query->withApplicationSearchContainsConstraint(
|
||||||
|
$this->newNumericIndex(null),
|
||||||
|
$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function appendToApplicationSearchForm(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
AphrontFormView $form,
|
||||||
|
$value,
|
||||||
|
array $handles) {
|
||||||
|
|
||||||
|
$form->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel($this->getFieldName())
|
||||||
|
->setName($this->getFieldKey())
|
||||||
|
->setValue($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
final class PhabricatorStandardCustomFieldText
|
||||||
|
extends PhabricatorStandardCustomField {
|
||||||
|
|
||||||
|
public function getFieldType() {
|
||||||
|
return 'text';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function buildFieldIndexes() {
|
||||||
|
$indexes = array();
|
||||||
|
|
||||||
|
$value = $this->getFieldValue();
|
||||||
|
if (strlen($value)) {
|
||||||
|
$indexes[] = $this->newStringIndex($value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $indexes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function readApplicationSearchValueFromRequest(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
AphrontRequest $request) {
|
||||||
|
|
||||||
|
return $request->getStr($this->getFieldKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function applyApplicationSearchConstraintToQuery(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
PhabricatorCursorPagedPolicyAwareQuery $query,
|
||||||
|
$value) {
|
||||||
|
|
||||||
|
if (strlen($value)) {
|
||||||
|
$query->withApplicationSearchContainsConstraint(
|
||||||
|
$this->newStringIndex(null),
|
||||||
|
$value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function appendToApplicationSearchForm(
|
||||||
|
PhabricatorApplicationSearchEngine $engine,
|
||||||
|
AphrontFormView $form,
|
||||||
|
$value,
|
||||||
|
array $handles) {
|
||||||
|
|
||||||
|
$form->appendChild(
|
||||||
|
id(new AphrontFormTextControl())
|
||||||
|
->setLabel($this->getFieldName())
|
||||||
|
->setName($this->getFieldKey())
|
||||||
|
->setValue($value));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in a new issue