@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
at upstream/main 299 lines 8.6 kB view raw
1<?php 2 3final class PhabricatorProjectTriggerEditController 4 extends PhabricatorProjectTriggerController { 5 6 public function handleRequest(AphrontRequest $request) { 7 $request = $this->getRequest(); 8 $viewer = $request->getViewer(); 9 10 $id = $request->getURIData('id'); 11 if ($id) { 12 $trigger = id(new PhabricatorProjectTriggerQuery()) 13 ->setViewer($viewer) 14 ->withIDs(array($id)) 15 ->requireCapabilities( 16 array( 17 PhabricatorPolicyCapability::CAN_VIEW, 18 PhabricatorPolicyCapability::CAN_EDIT, 19 )) 20 ->executeOne(); 21 if (!$trigger) { 22 return new Aphront404Response(); 23 } 24 } else { 25 $trigger = PhabricatorProjectTrigger::initializeNewTrigger(); 26 } 27 28 $trigger->setViewer($viewer); 29 30 $column_phid = $request->getStr('columnPHID'); 31 if ($column_phid) { 32 $column = id(new PhabricatorProjectColumnQuery()) 33 ->setViewer($viewer) 34 ->withPHIDs(array($column_phid)) 35 ->requireCapabilities( 36 array( 37 PhabricatorPolicyCapability::CAN_VIEW, 38 PhabricatorPolicyCapability::CAN_EDIT, 39 )) 40 ->executeOne(); 41 if (!$column) { 42 return new Aphront404Response(); 43 } 44 $board_uri = $column->getWorkboardURI(); 45 } else { 46 $column = null; 47 $board_uri = null; 48 } 49 50 if ($board_uri) { 51 $cancel_uri = $board_uri; 52 } else if ($trigger->getID()) { 53 $cancel_uri = $trigger->getURI(); 54 } else { 55 $cancel_uri = $this->getApplicationURI('trigger/'); 56 } 57 58 $v_name = $trigger->getName(); 59 $v_edit = $trigger->getEditPolicy(); 60 $v_rules = $trigger->getTriggerRules(); 61 62 $e_name = null; 63 $e_edit = null; 64 65 $validation_exception = null; 66 if ($request->isFormPost()) { 67 try { 68 $v_name = $request->getStr('name'); 69 $v_edit = $request->getStr('editPolicy'); 70 71 // Read the JSON rules from the request and convert them back into 72 // "TriggerRule" objects so we can render the correct form state 73 // if the user is modifying the rules 74 $raw_rules = $request->getStr('rules'); 75 $raw_rules = phutil_json_decode($raw_rules); 76 77 $copy = clone $trigger; 78 $copy->setRuleset($raw_rules); 79 $v_rules = $copy->getTriggerRules(); 80 81 $xactions = array(); 82 if (!$trigger->getID()) { 83 $xactions[] = $trigger->getApplicationTransactionTemplate() 84 ->setTransactionType(PhabricatorTransactions::TYPE_CREATE) 85 ->setNewValue(true); 86 } 87 88 $xactions[] = $trigger->getApplicationTransactionTemplate() 89 ->setTransactionType( 90 PhabricatorProjectTriggerNameTransaction::TRANSACTIONTYPE) 91 ->setNewValue($v_name); 92 93 $xactions[] = $trigger->getApplicationTransactionTemplate() 94 ->setTransactionType(PhabricatorTransactions::TYPE_EDIT_POLICY) 95 ->setNewValue($v_edit); 96 97 $xactions[] = $trigger->getApplicationTransactionTemplate() 98 ->setTransactionType( 99 PhabricatorProjectTriggerRulesetTransaction::TRANSACTIONTYPE) 100 ->setNewValue($raw_rules); 101 102 $editor = $trigger->getApplicationTransactionEditor() 103 ->setActor($viewer) 104 ->setContentSourceFromRequest($request) 105 ->setContinueOnNoEffect(true); 106 107 $editor->applyTransactions($trigger, $xactions); 108 109 $next_uri = $trigger->getURI(); 110 111 if ($column) { 112 $column_xactions = array(); 113 114 $column_xactions[] = $column->getApplicationTransactionTemplate() 115 ->setTransactionType( 116 PhabricatorProjectColumnTriggerTransaction::TRANSACTIONTYPE) 117 ->setNewValue($trigger->getPHID()); 118 119 $column_editor = $column->getApplicationTransactionEditor() 120 ->setActor($viewer) 121 ->setContentSourceFromRequest($request) 122 ->setContinueOnNoEffect(true) 123 ->setContinueOnMissingFields(true); 124 125 $column_editor->applyTransactions($column, $column_xactions); 126 127 $next_uri = $column->getWorkboardURI(); 128 } 129 130 return id(new AphrontRedirectResponse())->setURI($next_uri); 131 } catch (PhabricatorApplicationTransactionValidationException $ex) { 132 $validation_exception = $ex; 133 134 $e_name = $ex->getShortMessage( 135 PhabricatorProjectTriggerNameTransaction::TRANSACTIONTYPE); 136 137 $e_edit = $ex->getShortMessage( 138 PhabricatorTransactions::TYPE_EDIT_POLICY); 139 140 $trigger->setEditPolicy($v_edit); 141 } 142 } 143 144 if ($trigger->getID()) { 145 $title = $trigger->getObjectName(); 146 $submit = pht('Save Trigger'); 147 $header = pht('Edit Trigger: %s', $trigger->getObjectName()); 148 } else { 149 $title = pht('New Trigger'); 150 $submit = pht('Create Trigger'); 151 $header = pht('New Trigger'); 152 } 153 154 $form_id = celerity_generate_unique_node_id(); 155 $table_id = celerity_generate_unique_node_id(); 156 $create_id = celerity_generate_unique_node_id(); 157 $input_id = celerity_generate_unique_node_id(); 158 159 $form = id(new AphrontFormView()) 160 ->setViewer($viewer) 161 ->setID($form_id); 162 163 if ($column) { 164 $form->addHiddenInput('columnPHID', $column->getPHID()); 165 } 166 167 $form->appendControl( 168 id(new AphrontFormTextControl()) 169 ->setLabel(pht('Name')) 170 ->setName('name') 171 ->setValue($v_name) 172 ->setError($e_name) 173 ->setPlaceholder($trigger->getDefaultName())); 174 175 $policies = id(new PhabricatorPolicyQuery()) 176 ->setViewer($viewer) 177 ->setObject($trigger) 178 ->execute(); 179 180 $form->appendControl( 181 id(new AphrontFormPolicyControl()) 182 ->setName('editPolicy') 183 ->setPolicyObject($trigger) 184 ->setCapability(PhabricatorPolicyCapability::CAN_EDIT) 185 ->setPolicies($policies) 186 ->setError($e_edit)); 187 188 $form->appendChild( 189 phutil_tag( 190 'input', 191 array( 192 'type' => 'hidden', 193 'name' => 'rules', 194 'id' => $input_id, 195 ))); 196 197 $form->appendChild( 198 id(new PHUIFormInsetView()) 199 ->setTitle(pht('Rules')) 200 ->setDescription( 201 pht( 202 'When a card is dropped into a column which uses this trigger:')) 203 ->setRightButton( 204 javelin_tag( 205 'a', 206 array( 207 'href' => '#', 208 'class' => 'button button-green', 209 'id' => $create_id, 210 'mustcapture' => true, 211 ), 212 pht('New Rule'))) 213 ->setContent( 214 javelin_tag( 215 'table', 216 array( 217 'id' => $table_id, 218 'class' => 'trigger-rules-table', 219 )))); 220 221 $this->setupEditorBehavior( 222 $trigger, 223 $v_rules, 224 $form_id, 225 $table_id, 226 $create_id, 227 $input_id); 228 229 $form->appendControl( 230 id(new AphrontFormSubmitControl()) 231 ->setValue($submit) 232 ->addCancelButton($cancel_uri)); 233 234 $header = id(new PHUIHeaderView()) 235 ->setHeader($header); 236 237 $box_view = id(new PHUIObjectBoxView()) 238 ->setHeader($header) 239 ->setValidationException($validation_exception) 240 ->appendChild($form); 241 242 $column_view = id(new PHUITwoColumnView()) 243 ->setFooter($box_view); 244 245 $crumbs = $this->buildApplicationCrumbs() 246 ->setBorder(true); 247 248 if ($column) { 249 $crumbs->addTextCrumb( 250 pht( 251 '%s: %s', 252 $column->getProject()->getDisplayName(), 253 $column->getName()), 254 $board_uri); 255 } 256 257 $crumbs->addTextCrumb($title); 258 259 return $this->newPage() 260 ->setTitle($title) 261 ->setCrumbs($crumbs) 262 ->appendChild($column_view); 263 } 264 265 private function setupEditorBehavior( 266 PhabricatorProjectTrigger $trigger, 267 array $rule_list, 268 $form_id, 269 $table_id, 270 $create_id, 271 $input_id) { 272 273 $rule_list = mpull($rule_list, 'toDictionary'); 274 $rule_list = array_values($rule_list); 275 276 $type_list = PhabricatorProjectTriggerRule::getAllTriggerRules(); 277 278 foreach ($type_list as $rule) { 279 $rule->setViewer($this->getViewer()); 280 } 281 $type_list = mpull($type_list, 'newTemplate'); 282 $type_list = array_values($type_list); 283 284 require_celerity_resource('project-triggers-css'); 285 286 Javelin::initBehavior( 287 'trigger-rule-editor', 288 array( 289 'formNodeID' => $form_id, 290 'tableNodeID' => $table_id, 291 'createNodeID' => $create_id, 292 'inputNodeID' => $input_id, 293 294 'rules' => $rule_list, 295 'types' => $type_list, 296 )); 297 } 298 299}