@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+216
+4
src/__phutil_library_map__.php
··· 2535 2535 'PhabricatorCustomFieldEditField' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditField.php', 2536 2536 'PhabricatorCustomFieldEditType' => 'infrastructure/customfield/editor/PhabricatorCustomFieldEditType.php', 2537 2537 'PhabricatorCustomFieldFulltextEngineExtension' => 'infrastructure/customfield/engineextension/PhabricatorCustomFieldFulltextEngineExtension.php', 2538 + 'PhabricatorCustomFieldHeraldAction' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldAction.php', 2539 + 'PhabricatorCustomFieldHeraldActionGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldActionGroup.php', 2538 2540 'PhabricatorCustomFieldHeraldField' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldField.php', 2539 2541 'PhabricatorCustomFieldHeraldFieldGroup' => 'infrastructure/customfield/herald/PhabricatorCustomFieldHeraldFieldGroup.php', 2540 2542 'PhabricatorCustomFieldImplementationIncompleteException' => 'infrastructure/customfield/exception/PhabricatorCustomFieldImplementationIncompleteException.php', ··· 7868 7870 'PhabricatorCustomFieldEditField' => 'PhabricatorEditField', 7869 7871 'PhabricatorCustomFieldEditType' => 'PhabricatorEditType', 7870 7872 'PhabricatorCustomFieldFulltextEngineExtension' => 'PhabricatorFulltextEngineExtension', 7873 + 'PhabricatorCustomFieldHeraldAction' => 'HeraldAction', 7874 + 'PhabricatorCustomFieldHeraldActionGroup' => 'HeraldActionGroup', 7871 7875 'PhabricatorCustomFieldHeraldField' => 'HeraldField', 7872 7876 'PhabricatorCustomFieldHeraldFieldGroup' => 'HeraldFieldGroup', 7873 7877 'PhabricatorCustomFieldImplementationIncompleteException' => 'Exception',
+55
src/infrastructure/customfield/field/PhabricatorCustomField.php
··· 34 34 const ROLE_CONDUIT = 'conduit'; 35 35 const ROLE_HERALD = 'herald'; 36 36 const ROLE_EDITENGINE = 'EditEngine'; 37 + const ROLE_HERALDACTION = 'herald.action'; 37 38 38 39 39 40 /* -( Building Applications with Custom Fields )--------------------------- */ ··· 293 294 return $this->shouldAppearInTransactionMail(); 294 295 case self::ROLE_HERALD: 295 296 return $this->shouldAppearInHerald(); 297 + case self::ROLE_HERALDACTION: 298 + return $this->shouldAppearInHeraldActions(); 296 299 case self::ROLE_EDITENGINE: 297 300 return $this->shouldAppearInEditView() || 298 301 $this->shouldAppearInEditEngine(); ··· 1475 1478 return null; 1476 1479 } 1477 1480 1481 + 1482 + public function shouldAppearInHeraldActions() { 1483 + if ($this->proxy) { 1484 + return $this->proxy->shouldAppearInHeraldActions(); 1485 + } 1486 + return false; 1487 + } 1488 + 1489 + 1490 + public function getHeraldActionName() { 1491 + if ($this->proxy) { 1492 + return $this->proxy->getHeraldActionName(); 1493 + } 1494 + 1495 + return null; 1496 + } 1497 + 1498 + 1499 + public function getHeraldActionStandardType() { 1500 + if ($this->proxy) { 1501 + return $this->proxy->getHeraldActionStandardType(); 1502 + } 1503 + 1504 + return null; 1505 + } 1506 + 1507 + 1508 + public function getHeraldActionDescription($value) { 1509 + if ($this->proxy) { 1510 + return $this->proxy->getHeraldActionDescription($value); 1511 + } 1512 + 1513 + return null; 1514 + } 1515 + 1516 + 1517 + public function getHeraldActionEffectDescription($value) { 1518 + if ($this->proxy) { 1519 + return $this->proxy->getHeraldActionEffectDescription($value); 1520 + } 1521 + 1522 + return null; 1523 + } 1524 + 1525 + 1526 + public function getHeraldActionDatasource() { 1527 + if ($this->proxy) { 1528 + return $this->proxy->getHeraldActionDatasource(); 1529 + } 1530 + 1531 + return null; 1532 + } 1478 1533 1479 1534 }
+105
src/infrastructure/customfield/herald/PhabricatorCustomFieldHeraldAction.php
··· 1 + <?php 2 + 3 + final class PhabricatorCustomFieldHeraldAction extends HeraldAction { 4 + 5 + const ACTIONCONST = 'herald.action.custom'; 6 + 7 + const DO_SET_FIELD = 'do.set-custom-field'; 8 + 9 + private $customField; 10 + 11 + public function setCustomField(PhabricatorCustomField $custom_field) { 12 + $this->customField = $custom_field; 13 + return $this; 14 + } 15 + 16 + public function getCustomField() { 17 + return $this->customField; 18 + } 19 + 20 + public function getActionGroupKey() { 21 + return PhabricatorCustomFieldHeraldActionGroup::ACTIONGROUPKEY; 22 + } 23 + 24 + public function supportsObject($object) { 25 + return ($object instanceof PhabricatorCustomFieldInterface); 26 + } 27 + 28 + public function supportsRuleType($rule_type) { 29 + return true; 30 + } 31 + 32 + public function getActionsForObject($object) { 33 + $viewer = PhabricatorUser::getOmnipotentUser(); 34 + $role = PhabricatorCustomField::ROLE_HERALDACTION; 35 + 36 + $field_list = PhabricatorCustomField::getObjectFields($object, $role) 37 + ->setViewer($viewer) 38 + ->readFieldsFromStorage($object); 39 + 40 + $map = array(); 41 + foreach ($field_list->getFields() as $field) { 42 + $key = $field->getFieldKey(); 43 + $map[$key] = id(new self()) 44 + ->setCustomField($field); 45 + } 46 + 47 + return $map; 48 + } 49 + 50 + public function applyEffect($object, HeraldEffect $effect) { 51 + $field = $this->getCustomField(); 52 + $value = $effect->getTarget(); 53 + $adapter = $this->getAdapter(); 54 + 55 + $old_value = $field->getOldValueForApplicationTransactions(); 56 + $new_value = id(clone $field) 57 + ->setValueFromApplicationTransactions($value) 58 + ->getValueForStorage(); 59 + 60 + $xaction = $adapter->newTransaction() 61 + ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD) 62 + ->setMetadataValue('customfield:key', $field->getFieldKey()) 63 + ->setOldValue($old_value) 64 + ->setNewValue($new_value); 65 + 66 + $adapter->queueTransaction($xaction); 67 + 68 + $this->logEffect(self::DO_SET_FIELD, $value); 69 + } 70 + 71 + public function getHeraldActionName() { 72 + return $this->getCustomField()->getHeraldActionName(); 73 + } 74 + 75 + public function getHeraldActionStandardType() { 76 + return $this->getCustomField()->getHeraldActionStandardType(); 77 + } 78 + 79 + protected function getDatasource() { 80 + return $this->getCustomField()->getHeraldActionDatasource(); 81 + } 82 + 83 + public function renderActionDescription($value) { 84 + return $this->getCustomField()->getHeraldActionDescription($value); 85 + } 86 + 87 + protected function getActionEffectMap() { 88 + return array( 89 + self::DO_SET_FIELD => array( 90 + 'icon' => 'fa-pencil', 91 + 'color' => 'green', 92 + 'name' => pht('Set Field Value'), 93 + ), 94 + ); 95 + } 96 + 97 + protected function renderActionEffectDescription($type, $data) { 98 + switch ($type) { 99 + case self::DO_SET_FIELD: 100 + return $this->getCustomField()->getHeraldActionEffectDescription($data); 101 + } 102 + } 103 + 104 + 105 + }
+16
src/infrastructure/customfield/herald/PhabricatorCustomFieldHeraldActionGroup.php
··· 1 + <?php 2 + 3 + final class PhabricatorCustomFieldHeraldActionGroup 4 + extends HeraldActionGroup { 5 + 6 + const ACTIONGROUPKEY = 'customfield'; 7 + 8 + public function getGroupLabel() { 9 + return pht('Custom Fields'); 10 + } 11 + 12 + protected function getGroupOrder() { 13 + return 2000; 14 + } 15 + 16 + }
+36
src/infrastructure/customfield/standard/PhabricatorStandardCustomFieldTokenizer.php
··· 65 65 return new ConduitPHIDListParameterType(); 66 66 } 67 67 68 + public function shouldAppearInHeraldActions() { 69 + return true; 70 + } 71 + 72 + public function getHeraldActionName() { 73 + return pht('Set "%s" to', $this->getFieldName()); 74 + } 75 + 76 + public function getHeraldActionDescription($value) { 77 + $list = $this->renderHeraldHandleList($value); 78 + return pht('Set "%s" to: %s.', $this->getFieldName(), $list); 79 + } 80 + 81 + public function getHeraldActionEffectDescription($value) { 82 + return $this->renderHeraldHandleList($value); 83 + } 84 + 85 + public function getHeraldActionStandardType() { 86 + return HeraldAction::STANDARD_PHID_LIST; 87 + } 88 + 89 + public function getHeraldActionDatasource() { 90 + return $this->getDatasource(); 91 + } 92 + 93 + private function renderHeraldHandleList($value) { 94 + if (!is_array($value)) { 95 + return pht('(Invalid List)'); 96 + } else { 97 + return $this->getViewer() 98 + ->renderHandleList($value) 99 + ->setAsInline(true) 100 + ->render(); 101 + } 102 + } 103 + 68 104 }