diff --git a/src/applications/herald/application/PhabricatorApplicationHerald.php b/src/applications/herald/application/PhabricatorApplicationHerald.php index 4cc1ff8432..4dfec83b6c 100644 --- a/src/applications/herald/application/PhabricatorApplicationHerald.php +++ b/src/applications/herald/application/PhabricatorApplicationHerald.php @@ -1,68 +1,67 @@ array( '(?:query/(?P[^/]+)/)?' => 'HeraldRuleListController', - 'new/(?:(?P[^/]+)/(?:(?P[^/]+)/)?)?' - => 'HeraldNewController', + 'new/' => 'HeraldNewController', 'rule/(?P[1-9]\d*)/' => 'HeraldRuleViewController', 'edit/(?:(?P[1-9]\d*)/)?' => 'HeraldRuleController', 'disable/(?P[1-9]\d*)/(?P\w+)/' => 'HeraldDisableController', 'history/(?:(?P[1-9]\d*)/)?' => 'HeraldRuleEditHistoryController', 'test/' => 'HeraldTestConsoleController', 'transcript/' => 'HeraldTranscriptListController', 'transcript/(?P[1-9]\d*)/(?:(?P\w+)/)?' => 'HeraldTranscriptController', ), ); } protected function getCustomCapabilities() { return array( HeraldCapabilityManageGlobalRules::CAPABILITY => array( 'caption' => pht('Global rules can bypass access controls.'), 'default' => PhabricatorPolicies::POLICY_ADMIN, ), ); } } diff --git a/src/applications/herald/controller/HeraldNewController.php b/src/applications/herald/controller/HeraldNewController.php index 7fac8d08ad..48595f9247 100644 --- a/src/applications/herald/controller/HeraldNewController.php +++ b/src/applications/herald/controller/HeraldNewController.php @@ -1,105 +1,165 @@ contentType = idx($data, 'type'); - $this->ruleType = idx($data, 'rule_type'); - } - public function processRequest() { $request = $this->getRequest(); $user = $request->getUser(); $content_type_map = HeraldAdapter::getEnabledAdapterMap($user); - if (empty($content_type_map[$this->contentType])) { - $this->contentType = head_key($content_type_map); + $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); + + $errors = array(); + + $e_type = null; + $e_rule = null; + + $step = 0; + if ($request->isFormPost()) { + $step = $request->getInt('step'); + $content_type = $request->getStr('content_type'); + if (empty($content_type_map[$content_type])) { + $errors[] = pht('You must choose a content type for this rule.'); + $e_type = pht('Required'); + $step = 0; + } + + if (!$errors && $step > 1) { + $rule_type = $request->getStr('rule_type'); + if (empty($rule_type_map[$rule_type])) { + $errors[] = pht('You must choose a rule type for this rule.'); + $e_rule = pht('Required'); + $step = 1; + } + } + + if (!$errors && $step == 2) { + $uri = id(new PhutilURI('edit/')) + ->setQueryParams( + array( + 'content_type' => $content_type, + 'rule_type' => $rule_type, + )); + $uri = $this->getApplicationURI($uri); + return id(new AphrontRedirectResponse())->setURI($uri); + } } - $rule_type_map = HeraldRuleTypeConfig::getRuleTypeMap(); - if (empty($rule_type_map[$this->ruleType])) { - $this->ruleType = HeraldRuleTypeConfig::RULE_TYPE_PERSONAL; + if ($errors) { + $errors = id(new AphrontErrorView())->setErrors($errors); } + $form = id(new AphrontFormView()) + ->setUser($user) + ->setAction($this->getApplicationURI('new/')); + + $rule_types = $this->renderRuleTypeControl($rule_type_map, $e_rule); + + switch ($step) { + case 0: + default: + $form + ->addHiddenInput('step', 1) + ->appendChild( + id(new AphrontFormSelectControl()) + ->setLabel(pht('New Rule for')) + ->setName('content_type') + ->setValue($request->getStr('content_type')) + ->setOptions($content_type_map)); + $cancel_text = null; + $cancel_uri = $this->getApplicationURI(); + break; + case 1: + $form + ->addHiddenInput('content_type', $request->getStr('content_type')) + ->addHiddenInput('step', 2) + ->appendChild($rule_types); + $cancel_text = pht('Back'); + $cancel_uri = id(new PhutilURI('new/')) + ->setQueryParams( + array( + 'content_type' => $request->getStr('content_type'), + 'step' => 1, + )); + $cancel_uri = $this->getApplicationURI($cancel_uri); + break; + } + + + $form + ->appendChild( + id(new AphrontFormSubmitControl()) + ->setValue(pht('Continue')) + ->addCancelButton($cancel_uri, $cancel_text)); + + $form_box = id(new PHUIObjectBoxView()) + ->setFormError($errors) + ->setHeaderText(pht('Create Herald Rule')) + ->setForm($form); + + $crumbs = $this + ->buildApplicationCrumbs() + ->addTextCrumb(pht('Create Rule')); + + return $this->buildApplicationPage( + array( + $crumbs, + $form_box, + ), + array( + 'title' => pht('Create Herald Rule'), + 'device' => true, + )); + } + + private function renderRuleTypeControl(array $rule_type_map, $e_rule) { + $request = $this->getRequest(); + // Reorder array to put "personal" first. $rule_type_map = array_select_keys( $rule_type_map, array( HeraldRuleTypeConfig::RULE_TYPE_PERSONAL, )) + $rule_type_map; list($can_global, $global_link) = $this->explainApplicationCapability( HeraldCapabilityManageGlobalRules::CAPABILITY, pht('You have permission to create and manage global rules.'), pht('You do not have permission to create or manage global rules.')); $captions = array( HeraldRuleTypeConfig::RULE_TYPE_PERSONAL => pht( 'Personal rules notify you about events. You own them, but they can '. 'only affect you. Personal rules only trigger for objects you have '. 'permission to see.'), HeraldRuleTypeConfig::RULE_TYPE_GLOBAL => array( pht( 'Global rules notify anyone about events. Global rules can '. 'bypass access control policies and act on any object.'), $global_link, ), ); $radio = id(new AphrontFormRadioButtonControl()) ->setLabel(pht('Type')) ->setName('rule_type') - ->setValue($this->ruleType); + ->setValue($request->getStr('rule_type')) + ->setError($e_rule); foreach ($rule_type_map as $value => $name) { $disabled = ($value == HeraldRuleTypeConfig::RULE_TYPE_GLOBAL) && (!$can_global); $radio->addButton( $value, $name, idx($captions, $value), $disabled ? 'disabled' : null, $disabled); } - $form = id(new AphrontFormView()) - ->setUser($user) - ->setAction('/herald/edit/') - ->appendChild( - id(new AphrontFormSelectControl()) - ->setLabel(pht('New Rule for')) - ->setName('content_type') - ->setValue($this->contentType) - ->setOptions($content_type_map)) - ->appendChild($radio) - ->appendChild( - id(new AphrontFormSubmitControl()) - ->setValue(pht('Create Rule')) - ->addCancelButton($this->getApplicationURI())); - - $form_box = id(new PHUIObjectBoxView()) - ->setHeaderText(pht('Create Herald Rule')) - ->setForm($form); - - $crumbs = $this - ->buildApplicationCrumbs() - ->addTextCrumb(pht('Create Rule')); - - return $this->buildApplicationPage( - array( - $crumbs, - $form_box, - ), - array( - 'title' => pht('Create Herald Rule'), - 'device' => true, - )); + return $radio; } - }