[ Index ] |
PHP Cross Reference of Phabricator |
[Summary view] [Print] [Text view]
1 <?php 2 3 final class HeraldNewController extends HeraldController { 4 5 public function processRequest() { 6 $request = $this->getRequest(); 7 $viewer = $request->getUser(); 8 9 $content_type_map = HeraldAdapter::getEnabledAdapterMap($viewer); 10 $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); 11 12 $errors = array(); 13 14 $e_type = null; 15 $e_rule = null; 16 $e_object = null; 17 18 $step = $request->getInt('step'); 19 if ($request->isFormPost()) { 20 $content_type = $request->getStr('content_type'); 21 if (empty($content_type_map[$content_type])) { 22 $errors[] = pht('You must choose a content type for this rule.'); 23 $e_type = pht('Required'); 24 $step = 0; 25 } 26 27 if (!$errors && $step > 1) { 28 $rule_type = $request->getStr('rule_type'); 29 if (empty($rule_type_map[$rule_type])) { 30 $errors[] = pht('You must choose a rule type for this rule.'); 31 $e_rule = pht('Required'); 32 $step = 1; 33 } 34 } 35 36 if (!$errors && $step >= 2) { 37 $target_phid = null; 38 $object_name = $request->getStr('objectName'); 39 $done = false; 40 if ($rule_type != HeraldRuleTypeConfig::RULE_TYPE_OBJECT) { 41 $done = true; 42 } else if (strlen($object_name)) { 43 $target_object = id(new PhabricatorObjectQuery()) 44 ->setViewer($viewer) 45 ->withNames(array($object_name)) 46 ->executeOne(); 47 if ($target_object) { 48 $can_edit = PhabricatorPolicyFilter::hasCapability( 49 $viewer, 50 $target_object, 51 PhabricatorPolicyCapability::CAN_EDIT); 52 if (!$can_edit) { 53 $errors[] = pht( 54 'You can not create a rule for that object, because you do '. 55 'not have permission to edit it. You can only create rules '. 56 'for objects you can edit.'); 57 $e_object = pht('Not Editable'); 58 $step = 2; 59 } else { 60 $adapter = HeraldAdapter::getAdapterForContentType($content_type); 61 if (!$adapter->canTriggerOnObject($target_object)) { 62 $errors[] = pht( 63 'This object is not of an allowed type for the rule. '. 64 'Rules can only trigger on certain objects.'); 65 $e_object = pht('Invalid'); 66 $step = 2; 67 } else { 68 $target_phid = $target_object->getPHID(); 69 $done = true; 70 } 71 } 72 } else { 73 $errors[] = pht('No object exists by that name.'); 74 $e_object = pht('Invalid'); 75 $step = 2; 76 } 77 } else if ($step > 2) { 78 $errors[] = pht( 79 'You must choose an object to associate this rule with.'); 80 $e_object = pht('Required'); 81 $step = 2; 82 } 83 84 if (!$errors && $done) { 85 $uri = id(new PhutilURI('edit/')) 86 ->setQueryParams( 87 array( 88 'content_type' => $content_type, 89 'rule_type' => $rule_type, 90 'targetPHID' => $target_phid, 91 )); 92 $uri = $this->getApplicationURI($uri); 93 return id(new AphrontRedirectResponse())->setURI($uri); 94 } 95 } 96 } 97 98 $content_type = $request->getStr('content_type'); 99 $rule_type = $request->getStr('rule_type'); 100 101 $form = id(new AphrontFormView()) 102 ->setUser($viewer) 103 ->setAction($this->getApplicationURI('new/')); 104 105 switch ($step) { 106 case 0: 107 default: 108 $content_types = $this->renderContentTypeControl( 109 $content_type_map, 110 $e_type); 111 112 $form 113 ->addHiddenInput('step', 1) 114 ->appendChild($content_types); 115 116 $cancel_text = null; 117 $cancel_uri = $this->getApplicationURI(); 118 break; 119 case 1: 120 $rule_types = $this->renderRuleTypeControl( 121 $rule_type_map, 122 $e_rule); 123 124 $form 125 ->addHiddenInput('content_type', $content_type) 126 ->addHiddenInput('step', 2) 127 ->appendChild( 128 id(new AphrontFormStaticControl()) 129 ->setLabel(pht('Rule for')) 130 ->setValue( 131 phutil_tag( 132 'strong', 133 array(), 134 idx($content_type_map, $content_type)))) 135 ->appendChild($rule_types); 136 137 $cancel_text = pht('Back'); 138 $cancel_uri = id(new PhutilURI('new/')) 139 ->setQueryParams( 140 array( 141 'content_type' => $content_type, 142 'step' => 0, 143 )); 144 $cancel_uri = $this->getApplicationURI($cancel_uri); 145 break; 146 case 2: 147 $adapter = HeraldAdapter::getAdapterForContentType($content_type); 148 $form 149 ->addHiddenInput('content_type', $content_type) 150 ->addHiddenInput('rule_type', $rule_type) 151 ->addHiddenInput('step', 3) 152 ->appendChild( 153 id(new AphrontFormStaticControl()) 154 ->setLabel(pht('Rule for')) 155 ->setValue( 156 phutil_tag( 157 'strong', 158 array(), 159 idx($content_type_map, $content_type)))) 160 ->appendChild( 161 id(new AphrontFormStaticControl()) 162 ->setLabel(pht('Rule Type')) 163 ->setValue( 164 phutil_tag( 165 'strong', 166 array(), 167 idx($rule_type_map, $rule_type)))) 168 ->appendRemarkupInstructions( 169 pht( 170 'Choose the object this rule will act on (for example, enter '. 171 '`rX` to act on the `rX` repository, or `#project` to act on '. 172 'a project).')) 173 ->appendRemarkupInstructions( 174 $adapter->explainValidTriggerObjects()) 175 ->appendChild( 176 id(new AphrontFormTextControl()) 177 ->setName('objectName') 178 ->setError($e_object) 179 ->setValue($request->getStr('objectName')) 180 ->setLabel(pht('Object'))); 181 182 $cancel_text = pht('Back'); 183 $cancel_uri = id(new PhutilURI('new/')) 184 ->setQueryParams( 185 array( 186 'content_type' => $content_type, 187 'rule_type' => $rule_type, 188 'step' => 1, 189 )); 190 $cancel_uri = $this->getApplicationURI($cancel_uri); 191 break; 192 } 193 194 195 $form 196 ->appendChild( 197 id(new AphrontFormSubmitControl()) 198 ->setValue(pht('Continue')) 199 ->addCancelButton($cancel_uri, $cancel_text)); 200 201 $form_box = id(new PHUIObjectBoxView()) 202 ->setFormErrors($errors) 203 ->setHeaderText(pht('Create Herald Rule')) 204 ->setForm($form); 205 206 $crumbs = $this 207 ->buildApplicationCrumbs() 208 ->addTextCrumb(pht('Create Rule')); 209 210 return $this->buildApplicationPage( 211 array( 212 $crumbs, 213 $form_box, 214 ), 215 array( 216 'title' => pht('Create Herald Rule'), 217 )); 218 } 219 220 private function renderContentTypeControl(array $content_type_map, $e_type) { 221 $request = $this->getRequest(); 222 223 $radio = id(new AphrontFormRadioButtonControl()) 224 ->setLabel(pht('New Rule for')) 225 ->setName('content_type') 226 ->setValue($request->getStr('content_type')) 227 ->setError($e_type); 228 229 foreach ($content_type_map as $value => $name) { 230 $adapter = HeraldAdapter::getAdapterForContentType($value); 231 $radio->addButton( 232 $value, 233 $name, 234 phutil_escape_html_newlines($adapter->getAdapterContentDescription())); 235 } 236 237 return $radio; 238 } 239 240 241 private function renderRuleTypeControl(array $rule_type_map, $e_rule) { 242 $request = $this->getRequest(); 243 244 // Reorder array to put less powerful rules first. 245 $rule_type_map = array_select_keys( 246 $rule_type_map, 247 array( 248 HeraldRuleTypeConfig::RULE_TYPE_PERSONAL, 249 HeraldRuleTypeConfig::RULE_TYPE_OBJECT, 250 HeraldRuleTypeConfig::RULE_TYPE_GLOBAL, 251 )) + $rule_type_map; 252 253 list($can_global, $global_link) = $this->explainApplicationCapability( 254 HeraldManageGlobalRulesCapability::CAPABILITY, 255 pht('You have permission to create and manage global rules.'), 256 pht('You do not have permission to create or manage global rules.')); 257 258 $captions = array( 259 HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => 260 pht( 261 'Personal rules notify you about events. You own them, but they can '. 262 'only affect you. Personal rules only trigger for objects you have '. 263 'permission to see.'), 264 HeraldRuleTypeConfig::RULE_TYPE_OBJECT => 265 pht( 266 'Object rules notify anyone about events. They are bound to an '. 267 'object (like a repository) and can only act on that object. You '. 268 'must be able to edit an object to create object rules for it. '. 269 'Other users who can edit the object can edit its rules.'), 270 HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => 271 array( 272 pht( 273 'Global rules notify anyone about events. Global rules can '. 274 'bypass access control policies and act on any object.'), 275 $global_link, 276 ), 277 ); 278 279 $radio = id(new AphrontFormRadioButtonControl()) 280 ->setLabel(pht('Rule Type')) 281 ->setName('rule_type') 282 ->setValue($request->getStr('rule_type')) 283 ->setError($e_rule); 284 285 $adapter = HeraldAdapter::getAdapterForContentType( 286 $request->getStr('content_type')); 287 288 foreach ($rule_type_map as $value => $name) { 289 $caption = idx($captions, $value); 290 $disabled = ($value == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) && 291 (!$can_global); 292 293 if (!$adapter->supportsRuleType($value)) { 294 $disabled = true; 295 $caption = array( 296 $caption, 297 "\n\n", 298 phutil_tag( 299 'em', 300 array(), 301 pht( 302 'This rule type is not supported by the selected content type.')), 303 ); 304 } 305 306 $radio->addButton( 307 $value, 308 $name, 309 phutil_escape_html_newlines($caption), 310 $disabled ? 'disabled' : null, 311 $disabled); 312 } 313 314 return $radio; 315 } 316 317 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Sun Nov 30 09:20:46 2014 | Cross-referenced by PHPXref 0.7.1 |