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

Add a normal "view" page for Herald rules

Summary:
Ref T2769. This will house the transaction list and replace the "edit log" stuff.

The UI is a little bit rough and can probably share more code with the transaction history, but seems mostly-reasonable.

Test Plan: {F53253}

Reviewers: btrahan

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T2769

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

+199 -11
+2
src/__phutil_library_map__.php
··· 628 628 'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php', 629 629 'HeraldRuleTranscript' => 'applications/herald/storage/transcript/HeraldRuleTranscript.php', 630 630 'HeraldRuleTypeConfig' => 'applications/herald/config/HeraldRuleTypeConfig.php', 631 + 'HeraldRuleViewController' => 'applications/herald/controller/HeraldRuleViewController.php', 631 632 'HeraldTestConsoleController' => 'applications/herald/controller/HeraldTestConsoleController.php', 632 633 'HeraldTranscript' => 'applications/herald/storage/transcript/HeraldTranscript.php', 633 634 'HeraldTranscriptController' => 'applications/herald/controller/HeraldTranscriptController.php', ··· 2640 2641 'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine', 2641 2642 'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction', 2642 2643 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment', 2644 + 'HeraldRuleViewController' => 'HeraldController', 2643 2645 'HeraldTestConsoleController' => 'HeraldController', 2644 2646 'HeraldTranscript' => 'HeraldDAO', 2645 2647 'HeraldTranscriptController' => 'HeraldController',
+70
src/applications/herald/adapter/HeraldAdapter.php
··· 663 663 } 664 664 665 665 666 + public function renderRuleAsText(HeraldRule $rule) { 667 + $out = array(); 668 + 669 + if ($rule->getMustMatchAll()) { 670 + $out[] = pht('When all of these conditions are met:'); 671 + } else { 672 + $out[] = pht('When any of these conditions are met:'); 673 + } 674 + 675 + $out[] = null; 676 + foreach ($rule->getConditions() as $condition) { 677 + $out[] = " ".$this->renderConditionAsText($condition); 678 + } 679 + $out[] = null; 680 + 681 + if ($rule->getRepetitionPolicy() == HeraldRepetitionPolicyConfig::EVERY) { 682 + $out[] = pht('Take these actions every time this rule matches:'); 683 + } else { 684 + $out[] = pht('Take these actions the first time this rule matches:'); 685 + } 686 + 687 + $out[] = null; 688 + foreach ($rule->getActions() as $action) { 689 + $out[] = " ".$this->renderActionAsText($action); 690 + } 691 + 692 + return implode("\n", $out); 693 + } 694 + 695 + private function renderConditionAsText(HeraldCondition $condition) { 696 + $field_type = $condition->getFieldName(); 697 + $field_name = idx($this->getFieldNameMap(), $field_type); 698 + 699 + $condition_type = $condition->getFieldCondition(); 700 + $condition_name = idx($this->getConditionNameMap(), $condition_type); 701 + 702 + $value = $this->renderConditionValueAsText($condition); 703 + 704 + return "{$field_name} {$condition_name} {$value}"; 705 + } 706 + 707 + private function renderActionAsText(HeraldAction $action) { 708 + $rule_global = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL; 709 + 710 + $action_type = $action->getAction(); 711 + $action_name = idx($this->getActionNameMap($rule_global), $action_type); 712 + 713 + $target = $this->renderActionTargetAsText($action); 714 + 715 + return "{$action_name} {$target}"; 716 + } 717 + 718 + private function renderConditionValueAsText(HeraldCondition $condition) { 719 + // TODO: This produces sketchy results for many conditions. 720 + $value = $condition->getValue(); 721 + if (is_array($value)) { 722 + $value = implode(', ', $value); 723 + } 724 + return $value; 725 + } 726 + 727 + private function renderActionTargetAsText(HeraldAction $action) { 728 + // TODO: This produces sketchy results for Flags and PHIDs. 729 + $target = $action->getTarget(); 730 + if (is_array($target)) { 731 + $target = implode(', ', $target); 732 + } 733 + 734 + return $target; 735 + } 666 736 667 737 } 668 738
+2 -1
src/applications/herald/application/PhabricatorApplicationHerald.php
··· 36 36 '(?:query/(?P<queryKey>[^/]+)/)?' => 'HeraldRuleListController', 37 37 'new/(?:(?P<type>[^/]+)/(?:(?P<rule_type>[^/]+)/)?)?' 38 38 => 'HeraldNewController', 39 - 'rule/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleController', 39 + 'rule/(?P<id>[1-9]\d*)/' => 'HeraldRuleViewController', 40 + 'edit/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleController', 40 41 'history/(?:(?P<id>[1-9]\d*)/)?' => 'HeraldRuleEditHistoryController', 41 42 'delete/(?P<id>[1-9]\d*)/' => 'HeraldDeleteController', 42 43 'test/' => 'HeraldTestConsoleController',
+3 -5
src/applications/herald/controller/HeraldNewController.php
··· 56 56 57 57 $form = id(new AphrontFormView()) 58 58 ->setUser($user) 59 - ->setAction('/herald/rule/') 59 + ->setAction('/herald/edit/') 60 60 ->setFlexible(true) 61 61 ->appendChild( 62 62 id(new AphrontFormSelectControl()) ··· 68 68 ->appendChild( 69 69 id(new AphrontFormSubmitControl()) 70 70 ->setValue(pht('Create Rule')) 71 - ->addCancelButton('/herald/view/'.$this->contentType.'/')); 71 + ->addCancelButton($this->getApplicationURI())); 72 72 73 73 $crumbs = $this 74 74 ->buildApplicationCrumbs() 75 75 ->addCrumb( 76 76 id(new PhabricatorCrumbView()) 77 - ->setName(pht('Create Herald Rule')) 78 - ->setHref($this->getApplicationURI( 79 - 'view/'.$this->contentType.'/'.$this->ruleType))); 77 + ->setName(pht('Create Rule'))); 80 78 81 79 return $this->buildApplicationPage( 82 80 array(
+8 -5
src/applications/herald/controller/HeraldRuleController.php
··· 18 18 $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); 19 19 20 20 if ($this->id) { 21 + $id = $this->id; 21 22 $rule = id(new HeraldRuleQuery()) 22 23 ->setViewer($user) 23 - ->withIDs(array($this->id)) 24 + ->withIDs(array($id)) 24 25 ->requireCapabilities( 25 26 array( 26 27 PhabricatorPolicyCapability::CAN_VIEW, ··· 30 31 if (!$rule) { 31 32 return new Aphront404Response(); 32 33 } 34 + $cancel_uri = $this->getApplicationURI("rule/{$id}/"); 33 35 } else { 34 36 $rule = new HeraldRule(); 35 37 $rule->setAuthorPHID($user->getPHID()); ··· 43 45 $rule_type = HeraldRuleTypeConfig::RULE_TYPE_GLOBAL; 44 46 } 45 47 $rule->setRuleType($rule_type); 48 + 49 + $cancel_uri = $this->getApplicationURI(); 46 50 } 47 51 48 52 $adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType()); ··· 70 74 if ($request->isFormPost() && $request->getStr('save')) { 71 75 list($e_name, $errors) = $this->saveRule($adapter, $rule, $request); 72 76 if (!$errors) { 73 - $uri = '/herald/view/'. 74 - $rule->getContentType().'/'. 75 - $rule->getRuleType().'/'; 77 + $id = $rule->getID(); 78 + $uri = $this->getApplicationURI("rule/{$id}/"); 76 79 return id(new AphrontRedirectResponse())->setURI($uri); 77 80 } 78 81 } ··· 171 174 ->appendChild( 172 175 id(new AphrontFormSubmitControl()) 173 176 ->setValue(pht('Save Rule')) 174 - ->addCancelButton('/herald/view/'.$rule->getContentType().'/')); 177 + ->addCancelButton($cancel_uri)); 175 178 176 179 $this->setupEditorBehavior($rule, $handles, $adapter); 177 180
+114
src/applications/herald/controller/HeraldRuleViewController.php
··· 1 + <?php 2 + 3 + final class HeraldRuleViewController extends HeraldController { 4 + 5 + private $id; 6 + 7 + public function willProcessRequest(array $data) { 8 + $this->id = $data['id']; 9 + } 10 + 11 + public function processRequest() { 12 + $request = $this->getRequest(); 13 + $viewer = $request->getUser(); 14 + 15 + $rule = id(new HeraldRuleQuery()) 16 + ->setViewer($viewer) 17 + ->withIDs(array($this->id)) 18 + ->needConditionsAndActions(true) 19 + ->executeOne(); 20 + if (!$rule) { 21 + return new Aphront404Response(); 22 + } 23 + 24 + $header = id(new PhabricatorHeaderView()) 25 + ->setHeader($rule->getName()); 26 + 27 + $actions = $this->buildActionView($rule); 28 + $properties = $this->buildPropertyView($rule); 29 + 30 + $crumbs = $this->buildApplicationCrumbs(); 31 + $crumbs->addCrumb( 32 + id(new PhabricatorCrumbView()) 33 + ->setName(pht('Rule %d', $rule->getID()))); 34 + 35 + return $this->buildApplicationPage( 36 + array( 37 + $crumbs, 38 + $header, 39 + $actions, 40 + $properties, 41 + ), 42 + array( 43 + 'title' => $rule->getName(), 44 + 'device' => true, 45 + 'dust' => true, 46 + )); 47 + } 48 + 49 + private function buildActionView(HeraldRule $rule) { 50 + $viewer = $this->getRequest()->getUser(); 51 + $id = $rule->getID(); 52 + 53 + $view = id(new PhabricatorActionListView()) 54 + ->setUser($viewer) 55 + ->setObject($rule) 56 + ->setObjectURI($this->getApplicationURI("rule/{$id}/")); 57 + 58 + $can_edit = PhabricatorPolicyFilter::hasCapability( 59 + $viewer, 60 + $rule, 61 + PhabricatorPolicyCapability::CAN_EDIT); 62 + 63 + $view->addAction( 64 + id(new PhabricatorActionView()) 65 + ->setName(pht('Edit Rule')) 66 + ->setHref($this->getApplicationURI("edit/{$id}/")) 67 + ->setIcon('edit') 68 + ->setDisabled(!$can_edit) 69 + ->setWorkflow(!$can_edit)); 70 + 71 + return $view; 72 + } 73 + 74 + private function buildPropertyView(HeraldRule $rule) { 75 + $viewer = $this->getRequest()->getUser(); 76 + 77 + $this->loadHandles(array($rule->getAuthorPHID())); 78 + 79 + $view = id(new PhabricatorPropertyListView()) 80 + ->setUser($viewer) 81 + ->setObject($rule); 82 + 83 + $view->addProperty( 84 + pht('Rule Type'), 85 + idx(HeraldRuleTypeConfig::getRuleTypeMap(), $rule->getRuleType())); 86 + 87 + if ($rule->isPersonalRule()) { 88 + $view->addProperty( 89 + pht('Author'), 90 + $this->getHandle($rule->getAuthorPHID())->renderLink()); 91 + } 92 + 93 + $adapter = HeraldAdapter::getAdapterForContentType($rule->getContentType()); 94 + if ($adapter) { 95 + $view->addProperty( 96 + pht('Applies To'), 97 + idx(HeraldAdapter::getEnabledAdapterMap(), $rule->getContentType())); 98 + 99 + $view->invokeWillRenderEvent(); 100 + 101 + $view->addSectionHeader(pht('Rule Description')); 102 + $view->addTextContent( 103 + phutil_tag( 104 + 'div', 105 + array( 106 + 'style' => 'white-space: pre-wrap;', 107 + ), 108 + $adapter->renderRuleAsText($rule))); 109 + } 110 + 111 + return $view; 112 + } 113 + 114 + }