public function processRequest()
 {
     $request = $this->getRequest();
     $viewer = $request->getUser();
     $dashboard = id(new PhabricatorDashboardQuery())->setViewer($viewer)->withIDs(array($this->id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
     if (!$dashboard) {
         return new Aphront404Response();
     }
     $redirect_uri = $this->getApplicationURI('manage/' . $dashboard->getID() . '/');
     $v_panel = $request->getStr('panel');
     $e_panel = true;
     $errors = array();
     if ($request->isFormPost()) {
         if (strlen($v_panel)) {
             $panel = id(new PhabricatorDashboardPanelQuery())->setViewer($viewer)->withIDs(array($v_panel))->executeOne();
             if (!$panel) {
                 $errors[] = pht('No such panel!');
                 $e_panel = pht('Invalid');
             }
         } else {
             $errors[] = pht('Select a panel to add.');
             $e_panel = pht('Required');
         }
         if (!$errors) {
             PhabricatorDashboardTransactionEditor::addPanelToDashboard($viewer, PhabricatorContentSource::newFromRequest($request), $panel, $dashboard, $request->getInt('column', 0));
             return id(new AphrontRedirectResponse())->setURI($redirect_uri);
         }
     }
     $panels = id(new PhabricatorDashboardPanelQuery())->setViewer($viewer)->withArchived(false)->execute();
     if (!$panels) {
         return $this->newDialog()->setTitle(pht('No Panels Exist Yet'))->appendParagraph(pht('You have not created any dashboard panels yet, so you can not ' . 'add an existing panel.'))->appendParagraph(pht('Instead, add a new panel.'))->addCancelButton($redirect_uri);
     }
     $panel_options = array();
     foreach ($panels as $panel) {
         $panel_options[$panel->getID()] = pht('%s %s', $panel->getMonogram(), $panel->getName());
     }
     $form = id(new AphrontFormView())->setUser($viewer)->addHiddenInput('column', $request->getInt('column'))->appendRemarkupInstructions(pht('Choose a panel to add to this dashboard:'))->appendChild(id(new AphrontFormSelectControl())->setName('panel')->setLabel(pht('Panel'))->setValue($v_panel)->setError($e_panel)->setOptions($panel_options));
     return $this->newDialog()->setTitle(pht('Add Panel'))->setErrors($errors)->appendChild($form->buildLayoutView())->addCancelButton($redirect_uri)->addSubmitButton(pht('Add Panel'));
 }
 public function handleRequest(AphrontRequest $request)
 {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     // If the user is trying to create a panel directly on a dashboard, make
     // sure they have permission to see and edit the dashboard.
     $dashboard_id = $request->getInt('dashboardID');
     $dashboard = null;
     if ($dashboard_id) {
         $dashboard = id(new PhabricatorDashboardQuery())->setViewer($viewer)->withIDs(array($dashboard_id))->requireCapabilities(array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT))->executeOne();
         if (!$dashboard) {
             return new Aphront404Response();
         }
         $manage_uri = $this->getApplicationURI('manage/' . $dashboard_id . '/');
     }
     if ($id) {
         $is_create = false;
         if ($dashboard) {
             $capabilities = array(PhabricatorPolicyCapability::CAN_VIEW);
         } else {
             $capabilities = array(PhabricatorPolicyCapability::CAN_VIEW, PhabricatorPolicyCapability::CAN_EDIT);
         }
         $panel = id(new PhabricatorDashboardPanelQuery())->setViewer($viewer)->withIDs(array($id))->requireCapabilities($capabilities)->executeOne();
         if (!$panel) {
             return new Aphront404Response();
         }
         $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs($panel->getPHID(), PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
         $v_projects = array_reverse($v_projects);
         if ($dashboard) {
             $can_edit = PhabricatorPolicyFilter::hasCapability($viewer, $panel, PhabricatorPolicyCapability::CAN_EDIT);
             if (!$can_edit) {
                 if ($request->isFormPost() && $request->getBool('copy')) {
                     $panel = $this->copyPanel($request, $dashboard, $panel);
                 } else {
                     return $this->processPanelCloneRequest($request, $dashboard, $panel);
                 }
             }
         }
     } else {
         $is_create = true;
         $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer);
         $types = PhabricatorDashboardPanelType::getAllPanelTypes();
         $type = $request->getStr('type');
         if (empty($types[$type])) {
             return $this->processPanelTypeRequest($request);
         }
         $v_projects = array();
         $panel->setPanelType($type);
     }
     if ($is_create) {
         $title = pht('New Panel');
         $header = pht('Create New Panel');
         $button = pht('Create Panel');
         if ($dashboard) {
             $cancel_uri = $manage_uri;
         } else {
             $cancel_uri = $this->getApplicationURI('panel/');
         }
     } else {
         $title = pht('Edit %s', $panel->getMonogram());
         $header = pht('Edit %s %s', $panel->getMonogram(), $panel->getName());
         $button = pht('Save Panel');
         if ($dashboard) {
             $cancel_uri = $manage_uri;
         } else {
             $cancel_uri = '/' . $panel->getMonogram();
         }
     }
     $v_name = $panel->getName();
     $e_name = true;
     $field_list = PhabricatorCustomField::getObjectFields($panel, PhabricatorCustomField::ROLE_EDIT);
     $field_list->setViewer($viewer)->readFieldsFromStorage($panel);
     if ($is_create && !$request->isFormPost()) {
         $panel->requireImplementation()->initializeFieldsFromRequest($panel, $field_list, $request);
     }
     $validation_exception = null;
     // NOTE: We require 'edit' to distinguish between the "Choose a Type"
     // and "Create a Panel" dialogs.
     if ($request->isFormPost() && $request->getBool('edit')) {
         $v_name = $request->getStr('name');
         $v_view_policy = $request->getStr('viewPolicy');
         $v_edit_policy = $request->getStr('editPolicy');
         $v_projects = $request->getArr('projects');
         $type_name = PhabricatorDashboardPanelTransaction::TYPE_NAME;
         $type_view_policy = PhabricatorTransactions::TYPE_VIEW_POLICY;
         $type_edit_policy = PhabricatorTransactions::TYPE_EDIT_POLICY;
         $xactions = array();
         $xactions[] = id(new PhabricatorDashboardPanelTransaction())->setTransactionType($type_name)->setNewValue($v_name);
         $xactions[] = id(new PhabricatorDashboardPanelTransaction())->setTransactionType($type_view_policy)->setNewValue($v_view_policy);
         $xactions[] = id(new PhabricatorDashboardPanelTransaction())->setTransactionType($type_edit_policy)->setNewValue($v_edit_policy);
         $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
         $xactions[] = id(new PhabricatorDashboardPanelTransaction())->setTransactionType(PhabricatorTransactions::TYPE_EDGE)->setMetadataValue('edge:type', $proj_edge_type)->setNewValue(array('=' => array_fuse($v_projects)));
         $field_xactions = $field_list->buildFieldTransactionsFromRequest(new PhabricatorDashboardPanelTransaction(), $request);
         $xactions = array_merge($xactions, $field_xactions);
         try {
             $editor = id(new PhabricatorDashboardPanelTransactionEditor())->setActor($viewer)->setContinueOnNoEffect(true)->setContentSourceFromRequest($request)->applyTransactions($panel, $xactions);
             // If we're creating a panel directly on a dashboard, add it now.
             if ($dashboard) {
                 PhabricatorDashboardTransactionEditor::addPanelToDashboard($viewer, PhabricatorContentSource::newFromRequest($request), $panel, $dashboard, $request->getInt('column', 0));
             }
             if ($dashboard) {
                 $done_uri = $manage_uri;
             } else {
                 $done_uri = '/' . $panel->getMonogram();
             }
             return id(new AphrontRedirectResponse())->setURI($done_uri);
         } catch (PhabricatorApplicationTransactionValidationException $ex) {
             $validation_exception = $ex;
             $e_name = $validation_exception->getShortMessage($type_name);
             $panel->setViewPolicy($v_view_policy);
             $panel->setEditPolicy($v_edit_policy);
         }
     }
     // NOTE: We're setting the submit URI explicitly because we need to edit
     // a different panel if we just cloned the original panel.
     if ($is_create) {
         $submit_uri = $this->getApplicationURI('panel/edit/');
     } else {
         $submit_uri = $this->getApplicationURI('panel/edit/' . $panel->getID() . '/');
     }
     $policies = id(new PhabricatorPolicyQuery())->setViewer($viewer)->setObject($panel)->execute();
     $form = id(new AphrontFormView())->setUser($viewer)->setAction($submit_uri)->addHiddenInput('edit', true)->addHiddenInput('dashboardID', $request->getInt('dashboardID'))->addHiddenInput('column', $request->getInt('column'))->appendChild(id(new AphrontFormTextControl())->setLabel(pht('Name'))->setName('name')->setValue($v_name)->setError($e_name))->appendChild(id(new AphrontFormPolicyControl())->setName('viewPolicy')->setPolicyObject($panel)->setCapability(PhabricatorPolicyCapability::CAN_VIEW)->setPolicies($policies))->appendChild(id(new AphrontFormPolicyControl())->setName('editPolicy')->setPolicyObject($panel)->setCapability(PhabricatorPolicyCapability::CAN_EDIT)->setPolicies($policies));
     $form->appendControl(id(new AphrontFormTokenizerControl())->setLabel(pht('Projects'))->setName('projects')->setValue($v_projects)->setDatasource(new PhabricatorProjectDatasource()));
     $field_list->appendFieldsToForm($form);
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb(pht('Panels'), $this->getApplicationURI('panel/'));
     if ($is_create) {
         $crumbs->addTextCrumb(pht('New Panel'));
         $form->addHiddenInput('type', $panel->getPanelType());
     } else {
         $crumbs->addTextCrumb($panel->getMonogram(), '/' . $panel->getMonogram());
         $crumbs->addTextCrumb(pht('Edit'));
     }
     if ($request->isAjax()) {
         return $this->newDialog()->setTitle($header)->setSubmitURI($submit_uri)->setWidth(AphrontDialogView::WIDTH_FORM)->setValidationException($validation_exception)->appendChild($form->buildLayoutView())->addCancelButton($cancel_uri)->addSubmitButton($button);
     } else {
         $form->appendChild(id(new AphrontFormSubmitControl())->setValue($button)->addCancelButton($cancel_uri));
     }
     $box = id(new PHUIObjectBoxView())->setHeaderText($header)->setValidationException($validation_exception)->setForm($form);
     return $this->buildApplicationPage(array($crumbs, $box), array('title' => $title));
 }