1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-11-30 02:32:42 +01:00

Support "Set X to" as an action in Herald for tokenizer/datasource custom fields

Summary:
See PHI173. Adds custom field support for Herald actions, and implements actions for "Datasource/Tokenizer" fields.

The only action available for now is "set field to...". Other actions ("Add values", "Remove values") might make sense in the future for these fields, but there's currently no use case. For most other field types (text, select, checkbox, etc) only "Set to" makes sense.

Test Plan:
  - Added a "datasource" custom field to the custom field definition in Config.
  - Added a "if field is empty, set field to default value X" rule to Herald.
  - Created a task with a nonempty field: no Herald trigger.
  - Created a task with an empty field: Herald fired.
  - Reviewed rule and transcripts for text strings.

{F5297615}

{F5297616}

{F5297617}

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D18784
This commit is contained in:
epriestley 2017-11-27 15:11:06 -08:00
parent e919233b31
commit c7d6fd198c
5 changed files with 216 additions and 0 deletions

View file

@ -2535,6 +2535,8 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldEditField' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditField.php',
'PhabricatorCustomFieldEditType' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditType.php',
'PhabricatorCustomFieldFulltextEngineExtension' => 'infrastructure/customfield/engineextension/PhabricatorCustomFieldFulltextEngineExtension.php',
'PhabricatorCustomFieldHeraldAction' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldAction.php',
'PhabricatorCustomFieldHeraldActionGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldActionGroup.php',
'PhabricatorCustomFieldHeraldField' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php',
'PhabricatorCustomFieldHeraldFieldGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldFieldGroup.php',
'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php',
@ -7868,6 +7870,8 @@ phutil_register_library_map(array(
'PhabricatorCustomFieldEditField' => 'PhabricatorEditField',
'PhabricatorCustomFieldEditType' => 'PhabricatorEditType',
'PhabricatorCustomFieldFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension',
'PhabricatorCustomFieldHeraldAction' => 'HeraldAction',
'PhabricatorCustomFieldHeraldActionGroup' => 'HeraldActionGroup',
'PhabricatorCustomFieldHeraldField' => 'HeraldField',
'PhabricatorCustomFieldHeraldFieldGroup' => 'HeraldFieldGroup',
'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',

View file

@ -34,6 +34,7 @@ abstract class PhabricatorCustomField extends Phobject {
const ROLE_CONDUIT = 'conduit';
const ROLE_HERALD = 'herald';
const ROLE_EDITENGINE = 'EditEngine';
const ROLE_HERALDACTION = 'herald.action';
/* -( Building Applications with Custom Fields )--------------------------- */
@ -293,6 +294,8 @@ abstract class PhabricatorCustomField extends Phobject {
return $this->shouldAppearInTransactionMail();
case self::ROLE_HERALD:
return $this->shouldAppearInHerald();
case self::ROLE_HERALDACTION:
return $this->shouldAppearInHeraldActions();
case self::ROLE_EDITENGINE:
return $this->shouldAppearInEditView() ||
$this->shouldAppearInEditEngine();
@ -1476,4 +1479,56 @@ abstract class PhabricatorCustomField extends Phobject {
}
public function shouldAppearInHeraldActions() {
if ($this->proxy) {
return $this->proxy->shouldAppearInHeraldActions();
}
return false;
}
public function getHeraldActionName() {
if ($this->proxy) {
return $this->proxy->getHeraldActionName();
}
return null;
}
public function getHeraldActionStandardType() {
if ($this->proxy) {
return $this->proxy->getHeraldActionStandardType();
}
return null;
}
public function getHeraldActionDescription($value) {
if ($this->proxy) {
return $this->proxy->getHeraldActionDescription($value);
}
return null;
}
public function getHeraldActionEffectDescription($value) {
if ($this->proxy) {
return $this->proxy->getHeraldActionEffectDescription($value);
}
return null;
}
public function getHeraldActionDatasource() {
if ($this->proxy) {
return $this->proxy->getHeraldActionDatasource();
}
return null;
}
}

View file

@ -0,0 +1,105 @@
<?php
final class PhabricatorCustomFieldHeraldAction extends HeraldAction {
const ACTIONCONST = 'herald.action.custom';
const DO_SET_FIELD = 'do.set-custom-field';
private $customField;
public function setCustomField(PhabricatorCustomField $custom_field) {
$this->customField = $custom_field;
return $this;
}
public function getCustomField() {
return $this->customField;
}
public function getActionGroupKey() {
return PhabricatorCustomFieldHeraldActionGroup::ACTIONGROUPKEY;
}
public function supportsObject($object) {
return ($object instanceof PhabricatorCustomFieldInterface);
}
public function supportsRuleType($rule_type) {
return true;
}
public function getActionsForObject($object) {
$viewer = PhabricatorUser::getOmnipotentUser();
$role = PhabricatorCustomField::ROLE_HERALDACTION;
$field_list = PhabricatorCustomField::getObjectFields($object, $role)
->setViewer($viewer)
->readFieldsFromStorage($object);
$map = array();
foreach ($field_list->getFields() as $field) {
$key = $field->getFieldKey();
$map[$key] = id(new self())
->setCustomField($field);
}
return $map;
}
public function applyEffect($object, HeraldEffect $effect) {
$field = $this->getCustomField();
$value = $effect->getTarget();
$adapter = $this->getAdapter();
$old_value = $field->getOldValueForApplicationTransactions();
$new_value = id(clone $field)
->setValueFromApplicationTransactions($value)
->getValueForStorage();
$xaction = $adapter->newTransaction()
->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD)
->setMetadataValue('customfield:key', $field->getFieldKey())
->setOldValue($old_value)
->setNewValue($new_value);
$adapter->queueTransaction($xaction);
$this->logEffect(self::DO_SET_FIELD, $value);
}
public function getHeraldActionName() {
return $this->getCustomField()->getHeraldActionName();
}
public function getHeraldActionStandardType() {
return $this->getCustomField()->getHeraldActionStandardType();
}
protected function getDatasource() {
return $this->getCustomField()->getHeraldActionDatasource();
}
public function renderActionDescription($value) {
return $this->getCustomField()->getHeraldActionDescription($value);
}
protected function getActionEffectMap() {
return array(
self::DO_SET_FIELD => array(
'icon' => 'fa-pencil',
'color' => 'green',
'name' => pht('Set Field Value'),
),
);
}
protected function renderActionEffectDescription($type, $data) {
switch ($type) {
case self::DO_SET_FIELD:
return $this->getCustomField()->getHeraldActionEffectDescription($data);
}
}
}

View file

@ -0,0 +1,16 @@
<?php
final class PhabricatorCustomFieldHeraldActionGroup
extends HeraldActionGroup {
const ACTIONGROUPKEY = 'customfield';
public function getGroupLabel() {
return pht('Custom Fields');
}
protected function getGroupOrder() {
return 2000;
}
}

View file

@ -65,4 +65,40 @@ abstract class PhabricatorStandardCustomFieldTokenizer
return new ConduitPHIDListParameterType();
}
public function shouldAppearInHeraldActions() {
return true;
}
public function getHeraldActionName() {
return pht('Set "%s" to', $this->getFieldName());
}
public function getHeraldActionDescription($value) {
$list = $this->renderHeraldHandleList($value);
return pht('Set "%s" to: %s.', $this->getFieldName(), $list);
}
public function getHeraldActionEffectDescription($value) {
return $this->renderHeraldHandleList($value);
}
public function getHeraldActionStandardType() {
return HeraldAction::STANDARD_PHID_LIST;
}
public function getHeraldActionDatasource() {
return $this->getDatasource();
}
private function renderHeraldHandleList($value) {
if (!is_array($value)) {
return pht('(Invalid List)');
} else {
return $this->getViewer()
->renderHandleList($value)
->setAsInline(true)
->render();
}
}
}