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

Modularize Maniphest Herald "Assign Task" action

Summary: Ref T8726. No surprises here.

Test Plan:
- Created rules using this action.
- Applied migration.
- Verified rules still work.

{F659324}

Reviewers: btrahan

Reviewed By: btrahan

Subscribers: joshuaspence, epriestley

Maniphest Tasks: T8726

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

+218 -76
+13
resources/sql/autopatches/20150724.herald.4.sql
··· 1 + UPDATE {$NAMESPACE}_herald.herald_actionrecord a 2 + JOIN {$NAMESPACE}_herald.herald_rule r 3 + ON a.ruleID = r.id 4 + SET a.action = 'maniphest.assign.other' 5 + WHERE r.ruleType != 'personal' 6 + AND a.action = 'assigntask'; 7 + 8 + UPDATE {$NAMESPACE}_herald.herald_actionrecord a 9 + JOIN {$NAMESPACE}_herald.herald_rule r 10 + ON a.ruleID = r.id 11 + SET a.action = 'maniphest.assign.self' 12 + WHERE r.ruleType = 'personal' 13 + AND a.action = 'assigntask';
+8
src/__phutil_library_map__.php
··· 1013 1013 'HeraldAdapter' => 'applications/herald/adapter/HeraldAdapter.php', 1014 1014 'HeraldAlwaysField' => 'applications/herald/field/HeraldAlwaysField.php', 1015 1015 'HeraldAnotherRuleField' => 'applications/herald/field/HeraldAnotherRuleField.php', 1016 + 'HeraldApplicationActionGroup' => 'applications/herald/action/HeraldApplicationActionGroup.php', 1016 1017 'HeraldApplyTranscript' => 'applications/herald/storage/transcript/HeraldApplyTranscript.php', 1017 1018 'HeraldBasicFieldGroup' => 'applications/herald/field/HeraldBasicFieldGroup.php', 1018 1019 'HeraldCommitAdapter' => 'applications/diffusion/herald/HeraldCommitAdapter.php', ··· 1186 1187 'ManiphestStatusEmailCommand' => 'applications/maniphest/command/ManiphestStatusEmailCommand.php', 1187 1188 'ManiphestSubpriorityController' => 'applications/maniphest/controller/ManiphestSubpriorityController.php', 1188 1189 'ManiphestTask' => 'applications/maniphest/storage/ManiphestTask.php', 1190 + 'ManiphestTaskAssignHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignHeraldAction.php', 1191 + 'ManiphestTaskAssignOtherHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignOtherHeraldAction.php', 1192 + 'ManiphestTaskAssignSelfHeraldAction' => 'applications/maniphest/herald/ManiphestTaskAssignSelfHeraldAction.php', 1189 1193 'ManiphestTaskAssigneeHeraldField' => 'applications/maniphest/herald/ManiphestTaskAssigneeHeraldField.php', 1190 1194 'ManiphestTaskAuthorHeraldField' => 'applications/maniphest/herald/ManiphestTaskAuthorHeraldField.php', 1191 1195 'ManiphestTaskAuthorPolicyRule' => 'applications/maniphest/policyrule/ManiphestTaskAuthorPolicyRule.php', ··· 4710 4714 'HeraldAdapter' => 'Phobject', 4711 4715 'HeraldAlwaysField' => 'HeraldField', 4712 4716 'HeraldAnotherRuleField' => 'HeraldField', 4717 + 'HeraldApplicationActionGroup' => 'HeraldActionGroup', 4713 4718 'HeraldApplyTranscript' => 'Phobject', 4714 4719 'HeraldBasicFieldGroup' => 'HeraldFieldGroup', 4715 4720 'HeraldCommitAdapter' => 'HeraldAdapter', ··· 4922 4927 'PhabricatorProjectInterface', 4923 4928 'PhabricatorSpacesInterface', 4924 4929 ), 4930 + 'ManiphestTaskAssignHeraldAction' => 'HeraldAction', 4931 + 'ManiphestTaskAssignOtherHeraldAction' => 'ManiphestTaskAssignHeraldAction', 4932 + 'ManiphestTaskAssignSelfHeraldAction' => 'ManiphestTaskAssignHeraldAction', 4925 4933 'ManiphestTaskAssigneeHeraldField' => 'ManiphestTaskHeraldField', 4926 4934 'ManiphestTaskAuthorHeraldField' => 'ManiphestTaskHeraldField', 4927 4935 'ManiphestTaskAuthorPolicyRule' => 'PhabricatorPolicyRule',
+15
src/applications/herald/action/HeraldApplicationActionGroup.php
··· 1 + <?php 2 + 3 + final class HeraldApplicationActionGroup extends HeraldActionGroup { 4 + 5 + const ACTIONGROUPKEY = 'application'; 6 + 7 + public function getGroupLabel() { 8 + return pht('Application'); 9 + } 10 + 11 + protected function getGroupOrder() { 12 + return 1500; 13 + } 14 + 15 + }
-8
src/applications/herald/adapter/HeraldAdapter.php
··· 27 27 const CONDITION_IS_FALSE = 'false'; 28 28 29 29 const ACTION_AUDIT = 'audit'; 30 - const ACTION_ASSIGN_TASK = 'assigntask'; 31 30 const ACTION_ADD_REVIEWERS = 'addreviewers'; 32 31 const ACTION_ADD_BLOCKING_REVIEWERS = 'addblockingreviewers'; 33 32 const ACTION_APPLY_BUILD_PLANS = 'applybuildplans'; ··· 718 717 case HeraldRuleTypeConfig::RULE_TYPE_OBJECT: 719 718 $standard = array( 720 719 self::ACTION_AUDIT => pht('Trigger an Audit by'), 721 - self::ACTION_ASSIGN_TASK => pht('Assign task to'), 722 720 self::ACTION_ADD_REVIEWERS => pht('Add reviewers'), 723 721 self::ACTION_ADD_BLOCKING_REVIEWERS => pht('Add blocking reviewers'), 724 722 self::ACTION_APPLY_BUILD_PLANS => pht('Run build plans'), ··· 729 727 case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 730 728 $standard = array( 731 729 self::ACTION_AUDIT => pht('Trigger an Audit by me'), 732 - self::ACTION_ASSIGN_TASK => pht('Assign task to me'), 733 730 self::ACTION_ADD_REVIEWERS => pht('Add me as a reviewer'), 734 731 self::ACTION_ADD_BLOCKING_REVIEWERS => 735 732 pht('Add me as a blocking reviewer'), ··· 772 769 if ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL) { 773 770 switch ($action->getAction()) { 774 771 case self::ACTION_AUDIT: 775 - case self::ACTION_ASSIGN_TASK: 776 772 case self::ACTION_ADD_REVIEWERS: 777 773 case self::ACTION_ADD_BLOCKING_REVIEWERS: 778 774 // For personal rules, force these actions to target the rule owner. ··· 812 808 if ($is_personal) { 813 809 switch ($action) { 814 810 case self::ACTION_AUDIT: 815 - case self::ACTION_ASSIGN_TASK: 816 811 case self::ACTION_ADD_REVIEWERS: 817 812 case self::ACTION_ADD_BLOCKING_REVIEWERS: 818 813 return new HeraldEmptyFieldValue(); 819 814 } 820 815 } else { 821 816 switch ($action) { 822 - case self::ACTION_ASSIGN_TASK: 823 - return $this->buildTokenizerFieldValue( 824 - new PhabricatorPeopleDatasource()); 825 817 case self::ACTION_AUDIT: 826 818 case self::ACTION_ADD_REVIEWERS: 827 819 case self::ACTION_ADD_BLOCKING_REVIEWERS:
+3 -1
src/applications/herald/controller/HeraldTranscriptController.php
··· 233 233 $rule_list = id(new PHUIObjectItemListView()) 234 234 ->setNoDataString(pht('No Herald rules applied to this object.')); 235 235 236 - foreach ($xscript->getRuleTranscripts() as $rule_xscript) { 236 + $rule_xscripts = $xscript->getRuleTranscripts(); 237 + $rule_xscripts = msort($rule_xscripts, 'getRuleID'); 238 + foreach ($rule_xscripts as $rule_xscript) { 237 239 $rule_id = $rule_xscript->getRuleID(); 238 240 239 241 $rule_item = id(new PHUIObjectItemView())
-17
src/applications/maniphest/editor/ManiphestTransactionEditor.php
··· 506 506 ->setTask($object); 507 507 } 508 508 509 - protected function didApplyHeraldRules( 510 - PhabricatorLiskDAO $object, 511 - HeraldAdapter $adapter, 512 - HeraldTranscript $transcript) { 513 - 514 - $xactions = array(); 515 - 516 - $assign_phid = $adapter->getAssignPHID(); 517 - if ($assign_phid) { 518 - $xactions[] = id(new ManiphestTransaction()) 519 - ->setTransactionType(ManiphestTransaction::TYPE_OWNER) 520 - ->setNewValue($assign_phid); 521 - } 522 - 523 - return $xactions; 524 - } 525 - 526 509 protected function requireCapabilities( 527 510 PhabricatorLiskDAO $object, 528 511 PhabricatorApplicationTransaction $xaction) {
-50
src/applications/maniphest/herald/HeraldManiphestTaskAdapter.php
··· 3 3 final class HeraldManiphestTaskAdapter extends HeraldAdapter { 4 4 5 5 private $task; 6 - private $assignPHID; 7 6 8 7 protected function newObject() { 9 8 return new ManiphestTask(); ··· 55 54 return $this->task; 56 55 } 57 56 58 - public function setAssignPHID($assign_phid) { 59 - $this->assignPHID = $assign_phid; 60 - return $this; 61 - } 62 - public function getAssignPHID() { 63 - return $this->assignPHID; 64 - } 65 - 66 57 public function getAdapterContentName() { 67 58 return pht('Maniphest Tasks'); 68 59 } 69 60 70 - public function getActions($rule_type) { 71 - switch ($rule_type) { 72 - case HeraldRuleTypeConfig::RULE_TYPE_GLOBAL: 73 - return array_merge( 74 - array( 75 - self::ACTION_ASSIGN_TASK, 76 - ), 77 - parent::getActions($rule_type)); 78 - case HeraldRuleTypeConfig::RULE_TYPE_PERSONAL: 79 - return array_merge( 80 - array( 81 - self::ACTION_ASSIGN_TASK, 82 - ), 83 - parent::getActions($rule_type)); 84 - } 85 - } 86 - 87 61 public function getHeraldName() { 88 62 return 'T'.$this->getTask()->getID(); 89 - } 90 - 91 - public function applyHeraldEffects(array $effects) { 92 - assert_instances_of($effects, 'HeraldEffect'); 93 - 94 - $result = array(); 95 - foreach ($effects as $effect) { 96 - $action = $effect->getAction(); 97 - switch ($action) { 98 - case self::ACTION_ASSIGN_TASK: 99 - $target_array = $effect->getTarget(); 100 - $assign_phid = reset($target_array); 101 - $this->setAssignPHID($assign_phid); 102 - $result[] = new HeraldApplyTranscript( 103 - $effect, 104 - true, 105 - pht('Assigned task.')); 106 - break; 107 - default: 108 - $result[] = $this->applyStandardEffect($effect); 109 - break; 110 - } 111 - } 112 - return $result; 113 63 } 114 64 115 65 }
+116
src/applications/maniphest/herald/ManiphestTaskAssignHeraldAction.php
··· 1 + <?php 2 + 3 + abstract class ManiphestTaskAssignHeraldAction 4 + extends HeraldAction { 5 + 6 + const DO_EMPTY = 'do.send'; 7 + const DO_ALREADY = 'do.already'; 8 + const DO_INVALID = 'do.invalid'; 9 + const DO_PERMISSION = 'do.permission'; 10 + const DO_ASSIGN = 'do.assign'; 11 + 12 + public function supportsObject($object) { 13 + return ($object instanceof ManiphestTask); 14 + } 15 + 16 + public function getActionGroupKey() { 17 + return HeraldApplicationActionGroup::ACTIONGROUPKEY; 18 + } 19 + 20 + protected function applyAssign(array $phids) { 21 + $phid = head($phids); 22 + 23 + if (!$phid) { 24 + $this->logEffect(self::DO_EMPTY); 25 + return; 26 + } 27 + 28 + $adapter = $this->getAdapter(); 29 + $object = $adapter->getObject(); 30 + 31 + if ($object->getOwnerPHID() == $phid) { 32 + $this->logEffect(self::DO_ALREADY, array($phid)); 33 + return; 34 + } 35 + 36 + $user = id(new PhabricatorPeopleQuery()) 37 + ->setViewer(PhabricatorUser::getOmnipotentUser()) 38 + ->withPHIDs(array($phid)) 39 + ->executeOne(); 40 + if (!$user) { 41 + $this->logEffect(self::DO_INVALID, array($phid)); 42 + return; 43 + } 44 + 45 + $can_view = PhabricatorPolicyFilter::hasCapability( 46 + $user, 47 + $object, 48 + PhabricatorPolicyCapability::CAN_VIEW); 49 + if (!$can_view) { 50 + $this->logEffect(self::DO_PERMISSION, array($phid)); 51 + return; 52 + } 53 + 54 + $xaction = $adapter->newTransaction() 55 + ->setTransactionType(ManiphestTransaction::TYPE_OWNER) 56 + ->setNewValue($phid); 57 + 58 + $adapter->queueTransaction($xaction); 59 + 60 + $this->logEffect(self::DO_ASSIGN, array($phid)); 61 + } 62 + 63 + protected function getActionEffectMap() { 64 + return array( 65 + self::DO_EMPTY => array( 66 + 'icon' => 'fa-ban', 67 + 'color' => 'grey', 68 + 'name' => pht('Empty Action'), 69 + ), 70 + self::DO_ALREADY => array( 71 + 'icon' => 'fa-user', 72 + 'color' => 'grey', 73 + 'name' => pht('Already Assigned'), 74 + ), 75 + self::DO_INVALID => array( 76 + 'icon' => 'fa-ban', 77 + 'color' => 'red', 78 + 'name' => pht('Invalid Owner'), 79 + ), 80 + self::DO_PERMISSION => array( 81 + 'icon' => 'fa-ban', 82 + 'color' => 'red', 83 + 'name' => pht('No Permission'), 84 + ), 85 + self::DO_ASSIGN => array( 86 + 'icon' => 'fa-user', 87 + 'color' => 'green', 88 + 'name' => pht('Assigned Task'), 89 + ), 90 + ); 91 + } 92 + 93 + public function renderActionEffectDescription($type, $data) { 94 + switch ($type) { 95 + case self::DO_EMPTY: 96 + return pht('Action lists no user to assign.'); 97 + case self::DO_ALREADY: 98 + return pht( 99 + 'User is already task owner: %s.', 100 + $this->renderHandleList($data)); 101 + case self::DO_INVALID: 102 + return pht( 103 + 'User is invalid: %s.', 104 + $this->renderHandleList($data)); 105 + case self::DO_PERMISSION: 106 + return pht( 107 + 'User does not have permission to see task: %s.', 108 + $this->renderHandleList($data)); 109 + case self::DO_ASSIGN: 110 + return pht( 111 + 'Assigned task to: %s.', 112 + $this->renderHandleList($data)); 113 + } 114 + } 115 + 116 + }
+34
src/applications/maniphest/herald/ManiphestTaskAssignOtherHeraldAction.php
··· 1 + <?php 2 + 3 + final class ManiphestTaskAssignOtherHeraldAction 4 + extends ManiphestTaskAssignHeraldAction { 5 + 6 + const ACTIONCONST = 'maniphest.assign.other'; 7 + 8 + public function getHeraldActionName() { 9 + return pht('Assign task to'); 10 + } 11 + 12 + public function supportsRuleType($rule_type) { 13 + return ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 14 + } 15 + 16 + public function applyEffect($object, HeraldEffect $effect) { 17 + return $this->applyAssign($effect->getTarget()); 18 + } 19 + 20 + public function getHeraldActionStandardType() { 21 + return self::STANDARD_PHID_LIST; 22 + } 23 + 24 + protected function getDatasource() { 25 + // TODO: Eventually, it would be nice to get "limit = 1" exported from here 26 + // up to the UI. 27 + return new PhabricatorPeopleDatasource(); 28 + } 29 + 30 + public function renderActionDescription($value) { 31 + return pht('Assign task to: %s.', $this->renderHandleList($value)); 32 + } 33 + 34 + }
+29
src/applications/maniphest/herald/ManiphestTaskAssignSelfHeraldAction.php
··· 1 + <?php 2 + 3 + final class ManiphestTaskAssignSelfHeraldAction 4 + extends ManiphestTaskAssignHeraldAction { 5 + 6 + const ACTIONCONST = 'maniphest.assign.self'; 7 + 8 + public function getHeraldActionName() { 9 + return pht('Assign task to me'); 10 + } 11 + 12 + public function supportsRuleType($rule_type) { 13 + return ($rule_type == HeraldRuleTypeConfig::RULE_TYPE_PERSONAL); 14 + } 15 + 16 + public function applyEffect($object, HeraldEffect $effect) { 17 + $phid = $effect->getRule()->getAuthorPHID(); 18 + return $this->applyAssign(array($phid)); 19 + } 20 + 21 + public function getHeraldActionStandardType() { 22 + return self::STANDARD_NONE; 23 + } 24 + 25 + public function renderActionDescription($value) { 26 + return pht('Assign task to rule author.'); 27 + } 28 + 29 + }