1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-19 05:12:41 +01:00

Partially support CustomFields in EditEngine

Summary:
Ref T9132. This isn't perfect, but doesn't break any existing functionality. This stuff works:

  - Editing values.
  - Reordering fields.
  - All builtin field tyepes.

This stuff may not work yet:

  - Assigning custom field defaults.
  - Some conduit stuff.
  - Fully custom fields?
  - Locking/hiding fields? Didn't actually test this one.

I'll keep chipping away at that stuff. In some cases, it may be easier to convert all the CustomField apps first, although Differential might be a fair bit of work.

Test Plan:
Created a bunch of custom fields of every avialable type and edited them.

{F1008789}

Reviewers: chad

Reviewed By: chad

Maniphest Tasks: T9132

Differential Revision: https://secure.phabricator.com/D14617
This commit is contained in:
epriestley 2015-11-29 10:47:16 -08:00
parent a407b83dc2
commit 029b1b6733
7 changed files with 239 additions and 15 deletions

View file

@ -1979,6 +1979,9 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldAttachment' => 'infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php', 'PhabricatorCustomFieldAttachment' => 'infrastructure/customfield/field/PhabricatorCustomFieldAttachment.php',
'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php', 'PhabricatorCustomFieldConfigOptionType' => 'infrastructure/customfield/config/PhabricatorCustomFieldConfigOptionType.php',
'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php', 'PhabricatorCustomFieldDataNotAvailableException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldDataNotAvailableException.php',
'PhabricatorCustomFieldEditEngineExtension' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditEngineExtension.php',
'PhabricatorCustomFieldEditField' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditField.php',
'PhabricatorCustomFieldEditType' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditType.php',
'PhabricatorCustomFieldHeraldField' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php', 'PhabricatorCustomFieldHeraldField' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php',
'PhabricatorCustomFieldHeraldFieldGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldFieldGroup.php', 'PhabricatorCustomFieldHeraldFieldGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldFieldGroup.php',
'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php', 'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
@ -6065,6 +6068,9 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldAttachment' => 'Phobject', 'PhabricatorCustomFieldAttachment' => 'Phobject',
'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType', 'PhabricatorCustomFieldConfigOptionType' => 'PhabricatorConfigOptionType',
'PhabricatorCustomFieldDataNotAvailableException' => 'Exception', 'PhabricatorCustomFieldDataNotAvailableException' => 'Exception',
'PhabricatorCustomFieldEditEngineExtension' => 'PhabricatorEditEngineExtension',
'PhabricatorCustomFieldEditField' => 'PhabricatorEditField',
'PhabricatorCustomFieldEditType' => 'PhabricatorEditType',
'PhabricatorCustomFieldHeraldField' => 'HeraldField', 'PhabricatorCustomFieldHeraldField' => 'HeraldField',
'PhabricatorCustomFieldHeraldFieldGroup' => 'HeraldFieldGroup', 'PhabricatorCustomFieldHeraldFieldGroup' => 'HeraldFieldGroup',
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception', 'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',

View file

@ -145,10 +145,6 @@ abstract class PhabricatorEditField extends Phobject {
return $this->isHidden; return $this->isHidden;
} }
protected function newControl() {
throw new PhutilMethodNotImplementedException();
}
public function setIsSubmittedForm($is_submitted) { public function setIsSubmittedForm($is_submitted) {
$this->isSubmittedForm = $is_submitted; $this->isSubmittedForm = $is_submitted;
return $this; return $this;
@ -176,7 +172,11 @@ abstract class PhabricatorEditField extends Phobject {
return $this->controlError; return $this->controlError;
} }
protected function renderControl() { protected function newControl() {
throw new PhutilMethodNotImplementedException();
}
protected function buildControl() {
$control = $this->newControl(); $control = $this->newControl();
if ($control === null) { if ($control === null) {
return null; return null;
@ -190,6 +190,24 @@ abstract class PhabricatorEditField extends Phobject {
$control->setLabel($this->getLabel()); $control->setLabel($this->getLabel());
} }
if ($this->getIsSubmittedForm()) {
$error = $this->getControlError();
if ($error !== null) {
$control->setError($error);
}
} else if ($this->getIsRequired()) {
$control->setError(true);
}
return $control;
}
protected function renderControl() {
$control = $this->buildControl();
if ($control === null) {
return null;
}
if ($this->getIsPreview()) { if ($this->getIsPreview()) {
$disabled = true; $disabled = true;
$hidden = false; $hidden = false;
@ -207,16 +225,6 @@ abstract class PhabricatorEditField extends Phobject {
$control->setDisabled($disabled); $control->setDisabled($disabled);
if ($this->getIsSubmittedForm()) {
$error = $this->getControlError();
if ($error !== null) {
$control->setError($error);
}
} else if ($this->getIsRequired()) {
$control->setError(true);
}
return $control; return $control;
} }

View file

@ -0,0 +1,50 @@
<?php
final class PhabricatorCustomFieldEditEngineExtension
extends PhabricatorEditEngineExtension {
const EXTENSIONKEY = 'customfield.fields';
public function getExtensionPriority() {
return 5000;
}
public function isExtensionEnabled() {
return true;
}
public function getExtensionName() {
return pht('Custom Fields');
}
public function supportsObject(
PhabricatorEditEngine $engine,
PhabricatorApplicationTransactionInterface $object) {
return ($object instanceof PhabricatorCustomFieldInterface);
}
public function buildCustomEditFields(
PhabricatorEditEngine $engine,
PhabricatorApplicationTransactionInterface $object) {
$viewer = $this->getViewer();
$field_list = PhabricatorCustomField::getObjectFields(
$object,
PhabricatorCustomField::ROLE_EDIT);
$field_list->setViewer($viewer);
$field_list->readFieldsFromStorage($object);
$results = array();
foreach ($field_list->getFields() as $field) {
$edit_fields = $field->getEditEngineFields($engine);
foreach ($edit_fields as $edit_field) {
$results[] = $edit_field;
}
}
return $results;
}
}

View file

@ -0,0 +1,73 @@
<?php
final class PhabricatorCustomFieldEditField
extends PhabricatorEditField {
private $customField;
public function setCustomField(PhabricatorCustomField $custom_field) {
$this->customField = $custom_field;
return $this;
}
public function getCustomField() {
return $this->customField;
}
protected function buildControl() {
$field = $this->getCustomField();
$clone = clone $field;
if ($this->getIsSubmittedForm()) {
$value = $this->getValue();
$clone->setValueFromApplicationTransactions($value);
}
return $clone->renderEditControl(array());
}
protected function newEditType() {
return id(new PhabricatorCustomFieldEditType())
->setCustomField($this->getCustomField());
}
public function getValueForTransaction() {
$value = $this->getValue();
$field = $this->getCustomField();
// Avoid changing the value of the field itself, since later calls would
// incorrectly reflect the new value.
$clone = clone $field;
$clone->setValueFromApplicationTransactions($value);
return $clone->getNewValueForApplicationTransactions();
}
protected function getValueExistsInRequest(AphrontRequest $request, $key) {
// For now, never read these out of the request.
return false;
}
protected function getValueExistsInSubmit(AphrontRequest $request, $key) {
return true;
}
protected function getValueFromSubmit(AphrontRequest $request, $key) {
$field = $this->getCustomField();
$clone = clone $field;
$clone->readValueFromRequest($request);
return $clone->getNewValueForApplicationTransactions();
}
public function getConduitEditTypes() {
// TODO: For now, don't support custom fields over Conduit.
return array();
}
protected function newHTTPParameterType() {
// TODO: For now, don't support custom fields for HTTP prefill.
return null;
}
}

View file

@ -0,0 +1,53 @@
<?php
final class PhabricatorCustomFieldEditType
extends PhabricatorEditType {
private $customField;
public function setCustomField(PhabricatorCustomField $custom_field) {
$this->customField = $custom_field;
return $this;
}
public function getCustomField() {
return $this->customField;
}
public function getValueType() {
// TODO: Improve.
return 'custom';
}
public function getMetadata() {
$field = $this->getCustomField();
return parent::getMetadata() + $field->getApplicationTransactionMetadata();
}
public function getValueDescription() {
$field = $this->getCustomField();
return $field->getFieldDescription();
}
public function generateTransactions(
PhabricatorApplicationTransaction $template,
array $spec) {
$value = idx($spec, 'value');
$xaction = $this->newTransaction($template)
->setNewValue($value);
$custom_type = PhabricatorTransactions::TYPE_CUSTOMFIELD;
if ($xaction->getTransactionType() == $custom_type) {
$field = $this->getCustomField();
$xaction
->setOldValue($field->getOldValueForApplicationTransactions())
->setMetadataValue('customfield:key', $field->getFieldKey());
}
return array($xaction);
}
}

View file

@ -1082,6 +1082,33 @@ abstract class PhabricatorCustomField extends Phobject {
/* -( Edit View )---------------------------------------------------------- */ /* -( Edit View )---------------------------------------------------------- */
public function getEditEngineFields(PhabricatorEditEngine $engine) {
$field = $this->newStandardEditField($engine);
return array(
$field,
);
}
protected function newEditField() {
return id(new PhabricatorCustomFieldEditField())
->setCustomField($this);
}
protected function newStandardEditField() {
if ($this->proxy) {
return $this->proxy->newStandardEditField();
}
return $this->newEditField()
->setKey($this->getFieldKey())
->setEditTypeKey('custom.'.$this->getFieldKey())
->setLabel($this->getFieldName())
->setDescription($this->getFieldDescription())
->setTransactionType($this->getApplicationTransactionType())
->setValue($this->getNewValueForApplicationTransactions());
}
/** /**
* @task edit * @task edit
*/ */

View file

@ -426,4 +426,11 @@ abstract class PhabricatorStandardCustomField
} }
} }
protected function newStandardEditField() {
$short = 'custom.'.$this->getRawStandardFieldKey();
return parent::newStandardEditField()
->setEditTypeKey($short);
}
} }