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

Drive Herald edits via transactions

Summary: This is kinda bad in terms of UI (It just makes a json of the thing and diffs that), but it's a start.

Test Plan: edit rule, create rule, add/remove/edit conditions, actions

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin

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

authored by

Aviv Eyal and committed by
avivey
6dc30ecc 7b0b820b

+178 -15
+2
src/__phutil_library_map__.php
··· 1230 1230 'HeraldRulePHIDType' => 'applications/herald/phid/HeraldRulePHIDType.php', 1231 1231 'HeraldRuleQuery' => 'applications/herald/query/HeraldRuleQuery.php', 1232 1232 'HeraldRuleSearchEngine' => 'applications/herald/query/HeraldRuleSearchEngine.php', 1233 + 'HeraldRuleSerializer' => 'applications/herald/editor/HeraldRuleSerializer.php', 1233 1234 'HeraldRuleTestCase' => 'applications/herald/storage/__tests__/HeraldRuleTestCase.php', 1234 1235 'HeraldRuleTransaction' => 'applications/herald/storage/HeraldRuleTransaction.php', 1235 1236 'HeraldRuleTransactionComment' => 'applications/herald/storage/HeraldRuleTransactionComment.php', ··· 5497 5498 'HeraldRulePHIDType' => 'PhabricatorPHIDType', 5498 5499 'HeraldRuleQuery' => 'PhabricatorCursorPagedPolicyAwareQuery', 5499 5500 'HeraldRuleSearchEngine' => 'PhabricatorApplicationSearchEngine', 5501 + 'HeraldRuleSerializer' => 'Phobject', 5500 5502 'HeraldRuleTestCase' => 'PhabricatorTestCase', 5501 5503 'HeraldRuleTransaction' => 'PhabricatorApplicationTransaction', 5502 5504 'HeraldRuleTransactionComment' => 'PhabricatorApplicationTransactionComment',
+33 -14
src/applications/herald/controller/HeraldRuleController.php
··· 259 259 } 260 260 261 261 private function saveRule(HeraldAdapter $adapter, $rule, $request) { 262 - $rule->setName($request->getStr('name')); 262 + $new_name = $request->getStr('name'); 263 263 $match_all = ($request->getStr('must_match') == 'all'); 264 - $rule->setMustMatchAll((int)$match_all); 265 264 266 265 $repetition_policy_param = $request->getStr('repetition_policy'); 267 - $rule->setRepetitionPolicy( 268 - HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); 269 266 270 267 $e_name = true; 271 268 $errors = array(); 272 269 273 - if (!strlen($rule->getName())) { 270 + if (!strlen($new_name)) { 274 271 $e_name = pht('Required'); 275 272 $errors[] = pht('Rule must have a name.'); 276 273 } ··· 343 340 $actions[] = $obj; 344 341 } 345 342 346 - $rule->attachConditions($conditions); 347 - $rule->attachActions($actions); 348 - 349 343 if (!$errors) { 350 - $edit_action = $rule->getID() ? 'edit' : 'create'; 344 + $new_state = id(new HeraldRuleSerializer())->serializeRuleComponents( 345 + $match_all, 346 + $conditions, 347 + $actions, 348 + $repetition_policy_param); 351 349 352 - $rule->openTransaction(); 353 - $rule->save(); 354 - $rule->saveConditions($conditions); 355 - $rule->saveActions($actions); 356 - $rule->saveTransaction(); 350 + $xactions = array(); 351 + $xactions[] = id(new HeraldRuleTransaction()) 352 + ->setTransactionType(HeraldRuleTransaction::TYPE_EDIT) 353 + ->setNewValue($new_state); 354 + $xactions[] = id(new HeraldRuleTransaction()) 355 + ->setTransactionType(HeraldRuleTransaction::TYPE_NAME) 356 + ->setNewValue($new_name); 357 + 358 + try { 359 + id(new HeraldRuleEditor()) 360 + ->setActor($this->getViewer()) 361 + ->setContinueOnNoEffect(true) 362 + ->setContentSourceFromRequest($request) 363 + ->applyTransactions($rule, $xactions); 364 + return array(null, null); 365 + } catch (Exception $ex) { 366 + $errors[] = $ex->getMessage(); 367 + } 357 368 } 369 + 370 + // mutate current rule, so it would be sent to the client in the right state 371 + $rule->setMustMatchAll((int)$match_all); 372 + $rule->setName($new_name); 373 + $rule->setRepetitionPolicy( 374 + HeraldRepetitionPolicyConfig::toInt($repetition_policy_param)); 375 + $rule->attachConditions($conditions); 376 + $rule->attachActions($actions); 358 377 359 378 return array($e_name, $errors); 360 379 }
+27 -1
src/applications/herald/editor/HeraldRuleEditor.php
··· 15 15 $types = parent::getTransactionTypes(); 16 16 17 17 $types[] = PhabricatorTransactions::TYPE_COMMENT; 18 + $types[] = HeraldRuleTransaction::TYPE_EDIT; 19 + $types[] = HeraldRuleTransaction::TYPE_NAME; 18 20 $types[] = HeraldRuleTransaction::TYPE_DISABLE; 19 21 20 22 return $types; ··· 27 29 switch ($xaction->getTransactionType()) { 28 30 case HeraldRuleTransaction::TYPE_DISABLE: 29 31 return (int)$object->getIsDisabled(); 32 + case HeraldRuleTransaction::TYPE_EDIT: 33 + return id(new HeraldRuleSerializer()) 34 + ->serializeRule($object); 35 + case HeraldRuleTransaction::TYPE_NAME: 36 + return $object->getName(); 30 37 } 31 38 32 39 } ··· 38 45 switch ($xaction->getTransactionType()) { 39 46 case HeraldRuleTransaction::TYPE_DISABLE: 40 47 return (int)$xaction->getNewValue(); 48 + case HeraldRuleTransaction::TYPE_EDIT: 49 + case HeraldRuleTransaction::TYPE_NAME: 50 + return $xaction->getNewValue(); 41 51 } 42 - 43 52 } 44 53 45 54 protected function applyCustomInternalTransaction( ··· 49 58 switch ($xaction->getTransactionType()) { 50 59 case HeraldRuleTransaction::TYPE_DISABLE: 51 60 return $object->setIsDisabled($xaction->getNewValue()); 61 + case HeraldRuleTransaction::TYPE_NAME: 62 + return $object->setName($xaction->getNewValue()); 63 + case HeraldRuleTransaction::TYPE_EDIT: 64 + $new_state = id(new HeraldRuleSerializer()) 65 + ->deserializeRuleComponents($xaction->getNewValue()); 66 + $object->setMustMatchAll((int)$new_state['match_all']); 67 + $object->attachConditions($new_state['conditions']); 68 + $object->attachActions($new_state['actions']); 69 + $object->setRepetitionPolicy( 70 + HeraldRepetitionPolicyConfig::toInt($new_state['repetition_policy'])); 71 + return $object; 52 72 } 53 73 54 74 } ··· 56 76 protected function applyCustomExternalTransaction( 57 77 PhabricatorLiskDAO $object, 58 78 PhabricatorApplicationTransaction $xaction) { 79 + switch ($xaction->getTransactionType()) { 80 + case HeraldRuleTransaction::TYPE_EDIT: 81 + $object->saveConditions($object->getConditions()); 82 + $object->saveActions($object->getActions()); 83 + break; 84 + } 59 85 return; 60 86 } 61 87
+73
src/applications/herald/editor/HeraldRuleSerializer.php
··· 1 + <?php 2 + 3 + /** 4 + * Serialize for RuleTransactions / Editor. 5 + */ 6 + final class HeraldRuleSerializer extends Phobject { 7 + public function serializeRule(HeraldRule $rule) { 8 + return $this->serializeRuleComponents( 9 + (bool)$rule->getMustMatchAll(), 10 + $rule->getConditions(), 11 + $rule->getActions(), 12 + HeraldRepetitionPolicyConfig::toString($rule->getRepetitionPolicy())); 13 + } 14 + 15 + public function serializeRuleComponents( 16 + $match_all, 17 + array $conditions, 18 + array $actions, 19 + $repetition_policy) { 20 + 21 + assert_instances_of($conditions, 'HeraldCondition'); 22 + assert_instances_of($actions, 'HeraldActionRecord'); 23 + 24 + $conditions_array = array(); 25 + foreach ($conditions as $condition) { 26 + $conditions_array[] = array( 27 + 'field' => $condition->getFieldName(), 28 + 'condition' => $condition->getFieldCondition(), 29 + 'value' => $condition->getValue(), 30 + ); 31 + } 32 + 33 + $actions_array = array(); 34 + foreach ($actions as $action) { 35 + $actions_array[] = array( 36 + 'action' => $action->getAction(), 37 + 'target' => $action->getTarget(), 38 + ); 39 + } 40 + 41 + return array( 42 + 'match_all' => $match_all, 43 + 'conditions' => $conditions_array, 44 + 'actions' => $actions_array, 45 + 'repetition_policy' => $repetition_policy, 46 + ); 47 + } 48 + 49 + public function deserializeRuleComponents(array $serialized) { 50 + $deser_conditions = array(); 51 + foreach ($serialized['conditions'] as $condition) { 52 + $deser_conditions[] = id(new HeraldCondition()) 53 + ->setFieldName($condition['field']) 54 + ->setFieldCondition($condition['condition']) 55 + ->setValue($condition['value']); 56 + } 57 + 58 + $deser_actions = array(); 59 + foreach ($serialized['actions'] as $action) { 60 + $deser_actions[] = id(new HeraldActionRecord()) 61 + ->setAction($action['action']) 62 + ->setTarget($action['target']); 63 + } 64 + 65 + return array( 66 + 'match_all' => $serialized['match_all'], 67 + 'conditions' => $deser_conditions, 68 + 'actions' => $deser_actions, 69 + 'repetition_policy' => $serialized['repetition_policy'], 70 + ); 71 + } 72 + 73 + }
+43
src/applications/herald/storage/HeraldRuleTransaction.php
··· 4 4 extends PhabricatorApplicationTransaction { 5 5 6 6 const TYPE_EDIT = 'herald:edit'; 7 + const TYPE_NAME = 'herald:name'; 7 8 const TYPE_DISABLE = 'herald:disable'; 8 9 9 10 public function getApplicationName() { ··· 45 46 } else { 46 47 return pht('Enabled'); 47 48 } 49 + case self::TYPE_NAME: 50 + return pht('Renamed'); 48 51 } 49 52 50 53 return parent::getActionName(); ··· 84 87 '%s enabled this rule.', 85 88 $this->renderHandleLink($author_phid)); 86 89 } 90 + case self::TYPE_NAME: 91 + if ($old == null) { 92 + return pht( 93 + '%s created this rule.', 94 + $this->renderHandleLink($author_phid)); 95 + } else { 96 + return pht( 97 + '%s renamed this rule from "%s" to "%s".', 98 + $this->renderHandleLink($author_phid), 99 + $old, 100 + $new); 101 + } 102 + case self::TYPE_EDIT: 103 + return pht( 104 + '%s edited this rule.', 105 + $this->renderHandleLink($author_phid)); 87 106 } 88 107 89 108 return parent::getTitle(); 109 + } 110 + 111 + public function hasChangeDetails() { 112 + switch ($this->getTransactionType()) { 113 + case self::TYPE_EDIT: 114 + return true; 115 + } 116 + return parent::hasChangeDetails(); 117 + } 118 + 119 + public function renderChangeDetails(PhabricatorUser $viewer) { 120 + $json = new PhutilJSON(); 121 + switch ($this->getTransactionType()) { 122 + case self::TYPE_EDIT: 123 + return $this->renderTextCorpusChangeDetails( 124 + $viewer, 125 + $json->encodeFormatted($this->getOldValue()), 126 + $json->encodeFormatted($this->getNewValue())); 127 + } 128 + 129 + return $this->renderTextCorpusChangeDetails( 130 + $viewer, 131 + $this->getOldValue(), 132 + $this->getNewValue()); 90 133 } 91 134 92 135 }