@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.

Allow Herald rules to add comments

Summary:
See PHI242. All use cases for this that I know of are pretty hacky, but they don't seem perilous, and it's easier than webhooks.

See P1895, T10183, and T9853 for me previously refusing to implement this since all those use cases were also pretty bad.

Test Plan:
- Wrote a rule to add comments, saw it add comments.
- Reviewed summary, re-edited rule, reviewed transcript to check that all the strings worked OK.
- Wrote a new rule for a non-commentable object (a blog) to make sure I wasn't offered the "Add a comment" action.

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D18823

+133 -13
+13 -13
resources/celerity/map.php
··· 80 80 'rsrc/css/application/flag/flag.css' => 'bba8f811', 81 81 'rsrc/css/application/harbormaster/harbormaster.css' => 'f491c9f4', 82 82 'rsrc/css/application/herald/herald-test.css' => 'a52e323e', 83 - 'rsrc/css/application/herald/herald.css' => 'dc31f6e9', 83 + 'rsrc/css/application/herald/herald.css' => 'cd8d0134', 84 84 'rsrc/css/application/maniphest/batch-editor.css' => 'b0f0b6d5', 85 85 'rsrc/css/application/maniphest/report.css' => '9b9580b7', 86 86 'rsrc/css/application/maniphest/task-edit.css' => 'fda62a9b', ··· 416 416 'rsrc/js/application/drydock/drydock-live-operation-status.js' => '901935ef', 417 417 'rsrc/js/application/files/behavior-icon-composer.js' => '8499b6ab', 418 418 'rsrc/js/application/files/behavior-launch-icon-composer.js' => '48086888', 419 - 'rsrc/js/application/herald/HeraldRuleEditor.js' => 'd6a7e717', 419 + 'rsrc/js/application/herald/HeraldRuleEditor.js' => '2dff5579', 420 420 'rsrc/js/application/herald/PathTypeahead.js' => 'f7fc67ec', 421 421 'rsrc/js/application/herald/herald-rule-editor.js' => '7ebaeed3', 422 422 'rsrc/js/application/maniphest/behavior-batch-editor.js' => '782ab6e7', ··· 578 578 'font-lato' => 'c7ccd872', 579 579 'global-drag-and-drop-css' => 'b556a948', 580 580 'harbormaster-css' => 'f491c9f4', 581 - 'herald-css' => 'dc31f6e9', 582 - 'herald-rule-editor' => 'd6a7e717', 581 + 'herald-css' => 'cd8d0134', 582 + 'herald-rule-editor' => '2dff5579', 583 583 'herald-test-css' => 'a52e323e', 584 584 'inline-comment-summary-css' => 'f23d4e8f', 585 585 'javelin-aphlict' => 'e1d4b11a', ··· 1106 1106 'javelin-install', 1107 1107 'javelin-event', 1108 1108 ), 1109 + '2dff5579' => array( 1110 + 'multirow-row-manager', 1111 + 'javelin-install', 1112 + 'javelin-util', 1113 + 'javelin-dom', 1114 + 'javelin-stratcom', 1115 + 'javelin-json', 1116 + 'phabricator-prefab', 1117 + ), 1109 1118 '2ee659ce' => array( 1110 1119 'javelin-install', 1111 1120 ), ··· 2000 2009 'javelin-behavior', 2001 2010 'javelin-dom', 2002 2011 'javelin-stratcom', 2003 - ), 2004 - 'd6a7e717' => array( 2005 - 'multirow-row-manager', 2006 - 'javelin-install', 2007 - 'javelin-util', 2008 - 'javelin-dom', 2009 - 'javelin-stratcom', 2010 - 'javelin-json', 2011 - 'phabricator-prefab', 2012 2012 ), 2013 2013 'd7a74243' => array( 2014 2014 'javelin-behavior',
+4
src/__phutil_library_map__.php
··· 1337 1337 'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php', 1338 1338 'HeraldBasicFieldGroup' => 'applications/herald/field/HeraldBasicFieldGroup.php', 1339 1339 'HeraldBuildableState' => 'applications/herald/state/HeraldBuildableState.php', 1340 + 'HeraldCommentAction' => 'applications/herald/action/HeraldCommentAction.php', 1340 1341 'HeraldCommitAdapter' => 'applications/diffusion/herald/HeraldCommitAdapter.php', 1341 1342 'HeraldCondition' => 'applications/herald/storage/HeraldCondition.php', 1342 1343 'HeraldConditionTranscript' => 'applications/herald/storage/transcript/HeraldConditionTranscript.php', ··· 1378 1379 'HeraldProjectsField' => 'applications/project/herald/HeraldProjectsField.php', 1379 1380 'HeraldRecursiveConditionsException' => 'applications/herald/engine/exception/HeraldRecursiveConditionsException.php', 1380 1381 'HeraldRelatedFieldGroup' => 'applications/herald/field/HeraldRelatedFieldGroup.php', 1382 + 'HeraldRemarkupFieldValue' => 'applications/herald/value/HeraldRemarkupFieldValue.php', 1381 1383 'HeraldRemarkupRule' => 'applications/herald/remarkup/HeraldRemarkupRule.php', 1382 1384 'HeraldRepetitionPolicyConfig' => 'applications/herald/config/HeraldRepetitionPolicyConfig.php', 1383 1385 'HeraldRule' => 'applications/herald/storage/HeraldRule.php', ··· 6488 6490 'HeraldApplyTranscript' => 'Phobject', 6489 6491 'HeraldBasicFieldGroup' => 'HeraldFieldGroup', 6490 6492 'HeraldBuildableState' => 'HeraldState', 6493 + 'HeraldCommentAction' => 'HeraldAction', 6491 6494 'HeraldCommitAdapter' => array( 6492 6495 'HeraldAdapter', 6493 6496 'HarbormasterBuildableAdapterInterface', ··· 6535 6538 'HeraldProjectsField' => 'HeraldField', 6536 6539 'HeraldRecursiveConditionsException' => 'Exception', 6537 6540 'HeraldRelatedFieldGroup' => 'HeraldFieldGroup', 6541 + 'HeraldRemarkupFieldValue' => 'HeraldFieldValue', 6538 6542 'HeraldRemarkupRule' => 'PhabricatorObjectRemarkupRule', 6539 6543 'HeraldRepetitionPolicyConfig' => 'Phobject', 6540 6544 'HeraldRule' => array(
+3
src/applications/herald/action/HeraldAction.php
··· 9 9 const STANDARD_NONE = 'standard.none'; 10 10 const STANDARD_PHID_LIST = 'standard.phid.list'; 11 11 const STANDARD_TEXT = 'standard.text'; 12 + const STANDARD_REMARKUP = 'standard.remarkup'; 12 13 13 14 const DO_STANDARD_EMPTY = 'do.standard.empty'; 14 15 const DO_STANDARD_NO_EFFECT = 'do.standard.no-effect'; ··· 60 61 return new HeraldEmptyFieldValue(); 61 62 case self::STANDARD_TEXT: 62 63 return new HeraldTextFieldValue(); 64 + case self::STANDARD_REMARKUP: 65 + return new HeraldRemarkupFieldValue(); 63 66 case self::STANDARD_PHID_LIST: 64 67 $tokenizer = id(new HeraldTokenizerFieldValue()) 65 68 ->setKey($this->getHeraldActionName())
+79
src/applications/herald/action/HeraldCommentAction.php
··· 1 + <?php 2 + 3 + final class HeraldCommentAction extends HeraldAction { 4 + 5 + const ACTIONCONST = 'comment'; 6 + const DO_COMMENT = 'do.comment'; 7 + 8 + public function getHeraldActionName() { 9 + return pht('Add comment'); 10 + } 11 + 12 + public function getActionGroupKey() { 13 + return HeraldUtilityActionGroup::ACTIONGROUPKEY; 14 + } 15 + 16 + public function supportsObject($object) { 17 + if (!($object instanceof PhabricatorApplicationTransactionInterface)) { 18 + return false; 19 + } 20 + 21 + $xaction = $object->getApplicationTransactionTemplate(); 22 + try { 23 + $comment = $xaction->getApplicationTransactionCommentObject(); 24 + if (!$comment) { 25 + return false; 26 + } 27 + } catch (PhutilMethodNotImplementedException $ex) { 28 + return false; 29 + } 30 + 31 + return true; 32 + } 33 + 34 + public function supportsRuleType($rule_type) { 35 + return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 36 + } 37 + 38 + public function applyEffect($object, HeraldEffect $effect) { 39 + $adapter = $this->getAdapter(); 40 + $comment_text = $effect->getTarget(); 41 + 42 + $xaction = $adapter->newTransaction() 43 + ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT); 44 + 45 + $comment = $xaction->getApplicationTransactionCommentObject() 46 + ->setContent($comment_text); 47 + 48 + $xaction->attachComment($comment); 49 + 50 + $adapter->queueTransaction($xaction); 51 + 52 + $this->logEffect(self::DO_COMMENT, $comment_text); 53 + } 54 + 55 + public function getHeraldActionStandardType() { 56 + return self::STANDARD_REMARKUP; 57 + } 58 + 59 + protected function getActionEffectMap() { 60 + return array( 61 + self::DO_COMMENT => array( 62 + 'icon' => 'fa-comment', 63 + 'color' => 'blue', 64 + 'name' => pht('Added Comment'), 65 + ), 66 + ); 67 + } 68 + 69 + public function renderActionDescription($value) { 70 + $summary = PhabricatorMarkupEngine::summarize($value); 71 + return pht('Add comment: %s', $summary); 72 + } 73 + 74 + protected function renderActionEffectDescription($type, $data) { 75 + $summary = PhabricatorMarkupEngine::summarize($data); 76 + return pht('Added a comment: %s', $summary); 77 + } 78 + 79 + }
+1
src/applications/herald/value/HeraldFieldValue.php
··· 8 8 const CONTROL_TEXT = 'herald.control.text'; 9 9 const CONTROL_SELECT = 'herald.control.select'; 10 10 const CONTROL_TOKENIZER = 'herald.control.tokenizer'; 11 + const CONTROL_REMARKUP = 'herald.control.remarkup'; 11 12 12 13 abstract public function getFieldValueKey(); 13 14 abstract public function getControlType();
+22
src/applications/herald/value/HeraldRemarkupFieldValue.php
··· 1 + <?php 2 + 3 + final class HeraldRemarkupFieldValue 4 + extends HeraldFieldValue { 5 + 6 + public function getFieldValueKey() { 7 + return 'remarkup'; 8 + } 9 + 10 + public function getControlType() { 11 + return self::CONTROL_REMARKUP; 12 + } 13 + 14 + public function renderFieldValue($value) { 15 + return $value; 16 + } 17 + 18 + public function renderEditorValue($value) { 19 + return $value; 20 + } 21 + 22 + }
+6
webroot/rsrc/css/application/herald/herald.css
··· 37 37 padding: 2px 4px; 38 38 } 39 39 40 + .herald-action-table td textarea { 41 + width: 95%; 42 + height: 8em; 43 + padding: 2px 4px; 44 + } 45 + 40 46 .herald-action-table td.target { 41 47 width: 100%; 42 48 }
+5
webroot/rsrc/js/application/herald/HeraldRuleEditor.js
··· 217 217 get_fn = function() { return input.value; }; 218 218 set_fn = function(v) { input.value = v; }; 219 219 break; 220 + case 'herald.control.remarkup': 221 + input = JX.$N('textarea'); 222 + get_fn = function() { return input.value; }; 223 + set_fn = function(v) { input.value = v; }; 224 + break; 220 225 case 'herald.control.select': 221 226 var options; 222 227