[ Index ]

PHP Cross Reference of Phabricator

title

Body

[close]

/src/applications/dashboard/controller/ -> PhabricatorDashboardPanelEditController.php (source)

   1  <?php
   2  
   3  final class PhabricatorDashboardPanelEditController
   4    extends PhabricatorDashboardController {
   5  
   6    private $id;
   7  
   8    public function willProcessRequest(array $data) {
   9      $this->id = idx($data, 'id');
  10    }
  11  
  12    public function processRequest() {
  13      $request = $this->getRequest();
  14      $viewer = $request->getUser();
  15  
  16      // If the user is trying to create a panel directly on a dashboard, make
  17      // sure they have permission to see and edit the dashboard.
  18  
  19      $dashboard_id = $request->getInt('dashboardID');
  20      $dashboard = null;
  21      if ($dashboard_id) {
  22        $dashboard = id(new PhabricatorDashboardQuery())
  23          ->setViewer($viewer)
  24          ->withIDs(array($dashboard_id))
  25          ->requireCapabilities(
  26            array(
  27              PhabricatorPolicyCapability::CAN_VIEW,
  28              PhabricatorPolicyCapability::CAN_EDIT,
  29            ))
  30          ->executeOne();
  31        if (!$dashboard) {
  32          return new Aphront404Response();
  33        }
  34  
  35        $manage_uri = $this->getApplicationURI('manage/'.$dashboard_id.'/');
  36      }
  37  
  38      if ($this->id) {
  39        $is_create = false;
  40  
  41        if ($dashboard) {
  42          $capabilities = array(
  43            PhabricatorPolicyCapability::CAN_VIEW,
  44          );
  45        } else {
  46          $capabilities = array(
  47            PhabricatorPolicyCapability::CAN_VIEW,
  48            PhabricatorPolicyCapability::CAN_EDIT,
  49          );
  50        }
  51  
  52        $panel = id(new PhabricatorDashboardPanelQuery())
  53          ->setViewer($viewer)
  54          ->withIDs(array($this->id))
  55          ->requireCapabilities($capabilities)
  56          ->executeOne();
  57        if (!$panel) {
  58          return new Aphront404Response();
  59        }
  60  
  61        if ($dashboard) {
  62          $can_edit = PhabricatorPolicyFilter::hasCapability(
  63            $viewer,
  64            $panel,
  65            PhabricatorPolicyCapability::CAN_EDIT);
  66          if (!$can_edit) {
  67            if ($request->isFormPost() && $request->getBool('copy')) {
  68              $panel = $this->copyPanel(
  69                $request,
  70                $dashboard,
  71                $panel);
  72            } else {
  73              return $this->processPanelCloneRequest(
  74                $request,
  75                $dashboard,
  76                $panel);
  77            }
  78          }
  79        }
  80      } else {
  81        $is_create = true;
  82  
  83        $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
  84        $types = PhabricatorDashboardPanelType::getAllPanelTypes();
  85        $type = $request->getStr('type');
  86        if (empty($types[$type])) {
  87          return $this->processPanelTypeRequest($request);
  88        }
  89  
  90        $panel->setPanelType($type);
  91      }
  92  
  93      if ($is_create) {
  94        $title = pht('New Panel');
  95        $header = pht('Create New Panel');
  96        $button = pht('Create Panel');
  97        if ($dashboard) {
  98          $cancel_uri = $manage_uri;
  99        } else {
 100          $cancel_uri = $this->getApplicationURI('panel/');
 101        }
 102      } else {
 103        $title = pht('Edit %s', $panel->getMonogram());
 104        $header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
 105        $button = pht('Save Panel');
 106        if ($dashboard) {
 107          $cancel_uri = $manage_uri;
 108        } else {
 109          $cancel_uri = '/'.$panel->getMonogram();
 110        }
 111      }
 112  
 113      $v_name = $panel->getName();
 114      $e_name = true;
 115  
 116      $field_list = PhabricatorCustomField::getObjectFields(
 117        $panel,
 118        PhabricatorCustomField::ROLE_EDIT);
 119      $field_list
 120        ->setViewer($viewer)
 121        ->readFieldsFromStorage($panel);
 122  
 123      if ($is_create && !$request->isFormPost()) {
 124        $panel->requireImplementation()->initializeFieldsFromRequest(
 125          $panel,
 126          $field_list,
 127          $request);
 128      }
 129  
 130      $validation_exception = null;
 131  
 132      // NOTE: We require 'edit' to distinguish between the "Choose a Type"
 133      // and "Create a Panel" dialogs.
 134  
 135      if ($request->isFormPost() && $request->getBool('edit')) {
 136        $v_name = $request->getStr('name');
 137        $v_view_policy = $request->getStr('viewPolicy');
 138        $v_edit_policy = $request->getStr('editPolicy');
 139  
 140        $type_name = PhabricatorDashboardPanelTransaction::TYPE_NAME;
 141        $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
 142        $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
 143  
 144        $xactions = array();
 145  
 146        $xactions[] = id(new PhabricatorDashboardPanelTransaction())
 147          ->setTransactionType($type_name)
 148          ->setNewValue($v_name);
 149  
 150        $xactions[] = id(new PhabricatorDashboardPanelTransaction())
 151          ->setTransactionType($type_view_policy)
 152          ->setNewValue($v_view_policy);
 153  
 154        $xactions[] = id(new PhabricatorDashboardPanelTransaction())
 155          ->setTransactionType($type_edit_policy)
 156          ->setNewValue($v_edit_policy);
 157  
 158        $field_xactions = $field_list->buildFieldTransactionsFromRequest(
 159          new PhabricatorDashboardPanelTransaction(),
 160          $request);
 161        $xactions = array_merge($xactions, $field_xactions);
 162  
 163        try {
 164          $editor = id(new PhabricatorDashboardPanelTransactionEditor())
 165            ->setActor($viewer)
 166            ->setContinueOnNoEffect(true)
 167            ->setContentSourceFromRequest($request)
 168            ->applyTransactions($panel, $xactions);
 169  
 170          // If we're creating a panel directly on a dashboard, add it now.
 171          if ($dashboard) {
 172            PhabricatorDashboardTransactionEditor::addPanelToDashboard(
 173              $viewer,
 174              PhabricatorContentSource::newFromRequest($request),
 175              $panel,
 176              $dashboard,
 177              $request->getInt('column', 0));
 178          }
 179  
 180          if ($dashboard) {
 181            $done_uri = $manage_uri;
 182          } else {
 183            $done_uri = '/'.$panel->getMonogram();
 184          }
 185  
 186          return id(new AphrontRedirectResponse())->setURI($done_uri);
 187        } catch (PhabricatorApplicationTransactionValidationException $ex) {
 188          $validation_exception = $ex;
 189  
 190          $e_name = $validation_exception->getShortMessage($type_name);
 191  
 192          $panel->setViewPolicy($v_view_policy);
 193          $panel->setEditPolicy($v_edit_policy);
 194        }
 195      }
 196  
 197      // NOTE: We're setting the submit URI explicitly because we need to edit
 198      // a different panel if we just cloned the original panel.
 199      if ($is_create) {
 200        $submit_uri = $this->getApplicationURI('panel/edit/');
 201      } else {
 202        $submit_uri = $this->getApplicationURI('panel/edit/'.$panel->getID().'/');
 203      }
 204  
 205      $policies = id(new PhabricatorPolicyQuery())
 206        ->setViewer($viewer)
 207        ->setObject($panel)
 208        ->execute();
 209  
 210      $form = id(new AphrontFormView())
 211        ->setUser($viewer)
 212        ->setAction($submit_uri)
 213        ->addHiddenInput('edit', true)
 214        ->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
 215        ->addHiddenInput('column', $request->getInt('column'))
 216        ->appendChild(
 217          id(new AphrontFormTextControl())
 218            ->setLabel(pht('Name'))
 219            ->setName('name')
 220            ->setValue($v_name)
 221            ->setError($e_name))
 222        ->appendChild(
 223          id(new AphrontFormPolicyControl())
 224            ->setName('viewPolicy')
 225            ->setPolicyObject($panel)
 226            ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
 227            ->setPolicies($policies))
 228        ->appendChild(
 229          id(new AphrontFormPolicyControl())
 230            ->setName('editPolicy')
 231            ->setPolicyObject($panel)
 232            ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
 233            ->setPolicies($policies));
 234  
 235      $field_list->appendFieldsToForm($form);
 236  
 237      $crumbs = $this->buildApplicationCrumbs();
 238      $crumbs->addTextCrumb(
 239        pht('Panels'),
 240        $this->getApplicationURI('panel/'));
 241      if ($is_create) {
 242        $crumbs->addTextCrumb(pht('New Panel'));
 243        $form->addHiddenInput('type', $panel->getPanelType());
 244      } else {
 245        $crumbs->addTextCrumb(
 246          $panel->getMonogram(),
 247          '/'.$panel->getMonogram());
 248        $crumbs->addTextCrumb(pht('Edit'));
 249      }
 250  
 251      if ($request->isAjax()) {
 252        return $this->newDialog()
 253          ->setTitle($header)
 254          ->setSubmitURI($submit_uri)
 255          ->setWidth(AphrontDialogView::WIDTH_FORM)
 256          ->setValidationException($validation_exception)
 257          ->appendChild($form->buildLayoutView())
 258          ->addCancelButton($cancel_uri)
 259          ->addSubmitButton($button);
 260      } else {
 261        $form
 262          ->appendChild(
 263            id(new AphrontFormSubmitControl())
 264              ->setValue($button)
 265              ->addCancelButton($cancel_uri));
 266      }
 267  
 268      $box = id(new PHUIObjectBoxView())
 269        ->setHeaderText($header)
 270        ->setValidationException($validation_exception)
 271        ->setForm($form);
 272  
 273      return $this->buildApplicationPage(
 274        array(
 275          $crumbs,
 276          $box,
 277        ),
 278        array(
 279          'title' => $title,
 280        ));
 281    }
 282  
 283    private function processPanelTypeRequest(AphrontRequest $request) {
 284      $viewer = $request->getUser();
 285  
 286      $types = PhabricatorDashboardPanelType::getAllPanelTypes();
 287  
 288      $v_type = null;
 289      $errors = array();
 290      if ($request->isFormPost()) {
 291        $v_type = $request->getStr('type');
 292        if (!isset($types[$v_type])) {
 293          $errors[] = pht('You must select a type of panel to create.');
 294        }
 295      }
 296  
 297      $cancel_uri = $this->getApplicationURI('panel/');
 298  
 299      if (!$v_type) {
 300        $v_type = key($types);
 301      }
 302  
 303      $panel_types = id(new AphrontFormRadioButtonControl())
 304        ->setName('type')
 305        ->setValue($v_type);
 306  
 307      foreach ($types as $key => $type) {
 308        $panel_types->addButton(
 309          $key,
 310          $type->getPanelTypeName(),
 311          $type->getPanelTypeDescription());
 312      }
 313  
 314      $form = id(new AphrontFormView())
 315        ->setUser($viewer)
 316        ->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
 317        ->addHiddenInput('column', $request->getInt('column'))
 318        ->appendRemarkupInstructions(
 319          pht(
 320            'Choose the type of dashboard panel to create:'))
 321        ->appendChild($panel_types);
 322  
 323      if ($request->isAjax()) {
 324        return $this->newDialog()
 325          ->setTitle(pht('Add New Panel'))
 326          ->setWidth(AphrontDialogView::WIDTH_FORM)
 327          ->setErrors($errors)
 328          ->appendChild($form->buildLayoutView())
 329          ->addCancelbutton($cancel_uri)
 330          ->addSubmitButton(pht('Continue'));
 331      } else {
 332        $form->appendChild(
 333          id(new AphrontFormSubmitControl())
 334            ->setValue(pht('Continue'))
 335            ->addCancelButton($cancel_uri));
 336      }
 337  
 338      $title = pht('Create Dashboard Panel');
 339  
 340      $crumbs = $this->buildApplicationCrumbs();
 341      $crumbs->addTextCrumb(
 342        pht('Panels'),
 343        $this->getApplicationURI('panel/'));
 344      $crumbs->addTextCrumb(pht('New Panel'));
 345  
 346      $box = id(new PHUIObjectBoxView())
 347        ->setHeaderText($title)
 348        ->setFormErrors($errors)
 349        ->setForm($form);
 350  
 351      return $this->buildApplicationPage(
 352        array(
 353          $crumbs,
 354          $box,
 355        ),
 356        array(
 357          'title' => $title,
 358        ));
 359    }
 360  
 361    private function processPanelCloneRequest(
 362      AphrontRequest $request,
 363      PhabricatorDashboard $dashboard,
 364      PhabricatorDashboardPanel $panel) {
 365  
 366      $viewer = $request->getUser();
 367  
 368      $manage_uri = $this->getApplicationURI('manage/'.$dashboard->getID().'/');
 369  
 370      return $this->newDialog()
 371        ->setTitle(pht('Copy Panel?'))
 372        ->addHiddenInput('copy', true)
 373        ->addHiddenInput('dashboardID', $request->getInt('dashboardID'))
 374        ->addHiddenInput('column', $request->getInt('column'))
 375        ->appendParagraph(
 376          pht(
 377            'You do not have permission to edit this dashboard panel, but you '.
 378            'can make a copy and edit that instead. If you choose to copy the '.
 379            'panel, the original will be replaced with the new copy on this '.
 380            'dashboard.'))
 381        ->appendParagraph(
 382          pht(
 383            'Do you want to make a copy of this panel?'))
 384        ->addCancelButton($manage_uri)
 385        ->addSubmitButton(pht('Copy Panel'));
 386    }
 387  
 388    private function copyPanel(
 389      AphrontRequest $request,
 390      PhabricatorDashboard $dashboard,
 391      PhabricatorDashboardPanel $panel) {
 392  
 393      $viewer = $request->getUser();
 394  
 395      $copy = PhabricatorDashboardPanel::initializeNewPanel($viewer);
 396      $copy = PhabricatorDashboardPanel::copyPanel($copy, $panel);
 397  
 398      $copy->openTransaction();
 399        $copy->save();
 400  
 401        // TODO: This should record a transaction on the panel copy, too.
 402  
 403        $xactions = array();
 404        $xactions[] = id(new PhabricatorDashboardTransaction())
 405          ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
 406          ->setMetadataValue(
 407            'edge:type',
 408            PhabricatorEdgeConfig::TYPE_DASHBOARD_HAS_PANEL)
 409          ->setNewValue(
 410            array(
 411              '+' => array(
 412                $copy->getPHID() => $copy->getPHID(),
 413              ),
 414              '-' => array(
 415                $panel->getPHID() => $panel->getPHID(),
 416              ),
 417            ));
 418  
 419        $layout_config = $dashboard->getLayoutConfigObject();
 420        $layout_config->replacePanel($panel->getPHID(), $copy->getPHID());
 421        $dashboard->setLayoutConfigFromObject($layout_config);
 422        $dashboard->save();
 423  
 424        $editor = id(new PhabricatorDashboardTransactionEditor())
 425          ->setActor($viewer)
 426          ->setContentSourceFromRequest($request)
 427          ->setContinueOnMissingFields(true)
 428          ->setContinueOnNoEffect(true)
 429          ->applyTransactions($dashboard, $xactions);
 430      $copy->saveTransaction();
 431  
 432      return $copy;
 433    }
 434  
 435  
 436  }


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