1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +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:
epriestley 2013-09-16 16:03:24 -07:00
parent ed126cd47e
commit 2b538bfb25
4 changed files with 167 additions and 70 deletions

View file

@ -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',

View file

@ -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,19 +140,18 @@ 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(); return id(new AphrontFormTextControl())
switch ($type) { ->setName($this->getFieldKey())
case 'text': ->setValue($this->getFieldValue())
default: ->setLabel($this->getFieldName());
return id(new AphrontFormTextControl())
->setName($this->getFieldKey())
->setValue($this->getFieldValue())
->setLabel($this->getFieldName());
}
} }
public function newStorageObject() { public function 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;
}
} }
} }

View file

@ -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));
}
}

View file

@ -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));
}
}