[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/herald/controller/ -> HeraldNewController.php (source)

   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  }


Generated: Sun Nov 30 09:20:46 2014 Cross-referenced by PHPXref 0.7.1