Differential D20414 Diff 48757 src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/dashboard/controller/PhabricatorDashboardQueryPanelInstallController.php
| <?php | <?php | ||||
| final class PhabricatorDashboardQueryPanelInstallController | final class PhabricatorDashboardQueryPanelInstallController | ||||
| extends PhabricatorDashboardController { | extends PhabricatorDashboardController { | ||||
| public function handleRequest(AphrontRequest $request) { | public function handleRequest(AphrontRequest $request) { | ||||
| $viewer = $request->getViewer(); | $viewer = $request->getViewer(); | ||||
| $v_dashboard = null; | $v_dashboard = null; | ||||
| $v_name = null; | $e_dashboard = null; | ||||
| $v_column = 0; | |||||
| $v_engine = $request->getURIData('engineKey'); | |||||
| $v_query = $request->getURIData('queryKey'); | |||||
| $v_name = null; | |||||
| $e_name = true; | $e_name = true; | ||||
| // Validate Engines | $v_engine = $request->getStr('engine'); | ||||
| $engines = PhabricatorApplicationSearchEngine::getAllEngines(); | if (!strlen($v_engine)) { | ||||
| foreach ($engines as $name => $engine) { | $v_engine = $request->getURIData('engineKey'); | ||||
| if (!$engine->canUseInPanelContext()) { | |||||
| unset($engines[$name]); | |||||
| } | |||||
| } | |||||
| if (!in_array($v_engine, array_keys($engines))) { | |||||
| return new Aphront404Response(); | |||||
| } | } | ||||
| // Validate Queries | $v_query = $request->getStr('query'); | ||||
| $engine = $engines[$v_engine]; | if (!strlen($v_query)) { | ||||
| $engine->setViewer($viewer); | $v_query = $request->getURIData('queryKey'); | ||||
| $good_query = false; | |||||
| if ($engine->isBuiltinQuery($v_query)) { | |||||
| $good_query = true; | |||||
| } else { | |||||
| $saved_query = id(new PhabricatorSavedQueryQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withEngineClassNames(array($v_engine)) | |||||
| ->withQueryKeys(array($v_query)) | |||||
| ->executeOne(); | |||||
| if ($saved_query) { | |||||
| $good_query = true; | |||||
| } | |||||
| } | |||||
| if (!$good_query) { | |||||
| return new Aphront404Response(); | |||||
| } | } | ||||
| $engines = PhabricatorApplicationSearchEngine::getAllEngines(); | |||||
| $engine = idx($engines, $v_engine); | |||||
| if ($engine) { | |||||
| $engine = id(clone $engine) | |||||
| ->setViewer($viewer); | |||||
| $redirect_uri = $engine->getQueryResultsPageURI($v_query); | |||||
| $named_query = idx($engine->loadEnabledNamedQueries(), $v_query); | $named_query = idx($engine->loadEnabledNamedQueries(), $v_query); | ||||
| if ($named_query) { | if ($named_query) { | ||||
| $v_name = $named_query->getQueryName(); | $v_name = $named_query->getQueryName(); | ||||
| } | } | ||||
| } else { | |||||
| $redirect_uri = '/'; | |||||
| } | |||||
| $errors = array(); | $errors = array(); | ||||
| $xaction_name = PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE; | |||||
| $xaction_engine = | |||||
| PhabricatorDashboardQueryPanelApplicationTransaction::TRANSACTIONTYPE; | |||||
| $xaction_query = | |||||
| PhabricatorDashboardQueryPanelQueryTransaction::TRANSACTIONTYPE; | |||||
| if ($request->isFormPost()) { | if ($request->isFormPost()) { | ||||
| $v_dashboard = $request->getInt('dashboardID'); | |||||
| $v_name = $request->getStr('name'); | $v_name = $request->getStr('name'); | ||||
| if (!$v_name) { | if (!$v_name) { | ||||
| $errors[] = pht('You must provide a name for this panel.'); | $errors[] = pht('You must provide a name for this panel.'); | ||||
| $e_name = pht('Required'); | $e_name = pht('Required'); | ||||
| } | } | ||||
| $v_dashboard = head($request->getArr('dashboardPHIDs')); | |||||
| if (!$v_dashboard) { | |||||
| $errors[] = pht('You must select a dashboard.'); | |||||
| $e_dashboard = pht('Required'); | |||||
| } else { | |||||
| $dashboard = id(new PhabricatorDashboardQuery()) | $dashboard = id(new PhabricatorDashboardQuery()) | ||||
| ->setViewer($viewer) | ->setViewer($viewer) | ||||
| ->withIDs(array($v_dashboard)) | ->withPHIDs(array($v_dashboard)) | ||||
| ->requireCapabilities( | |||||
| array( | |||||
| PhabricatorPolicyCapability::CAN_VIEW, | |||||
| PhabricatorPolicyCapability::CAN_EDIT, | |||||
| )) | |||||
| ->executeOne(); | ->executeOne(); | ||||
| if (!$dashboard) { | if (!$dashboard) { | ||||
| $errors[] = pht('Please select a valid dashboard.'); | $errors[] = pht('You must select a valid dashboard.'); | ||||
| $e_dashboard = pht('Invalid'); | |||||
| } | |||||
| $can_edit = PhabricatorPolicyFilter::hasCapability( | |||||
| $viewer, | |||||
| $dashboard, | |||||
| PhabricatorPolicyCapability::CAN_EDIT); | |||||
| if (!$can_edit) { | |||||
| $errors[] = pht( | |||||
| 'You must select a dashboard you have permission to edit.'); | |||||
| } | |||||
| } | } | ||||
| if (!$errors) { | if (!$errors) { | ||||
| $redirect_uri = "/dashboard/view/{$v_dashboard}/"; | $done_uri = $dashboard->getURI(); | ||||
| // First, create a new panel. | |||||
| $panel_type = id(new PhabricatorDashboardQueryPanelType()) | $panel_type = id(new PhabricatorDashboardQueryPanelType()) | ||||
| ->getPanelTypeKey(); | ->getPanelTypeKey(); | ||||
| $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer); | |||||
| $panel->setPanelType($panel_type); | |||||
| $field_list = PhabricatorCustomField::getObjectFields( | |||||
| $panel, | |||||
| PhabricatorCustomField::ROLE_EDIT); | |||||
| $field_list | $panel = PhabricatorDashboardPanel::initializeNewPanel($viewer) | ||||
| ->setViewer($viewer) | ->setPanelType($panel_type); | ||||
| ->readFieldsFromStorage($panel); | |||||
| $panel->requireImplementation()->initializeFieldsFromRequest( | |||||
| $panel, | |||||
| $field_list, | |||||
| $request); | |||||
| $xactions = array(); | $xactions = array(); | ||||
| $xactions[] = id(new PhabricatorDashboardPanelTransaction()) | $xactions[] = $panel->getApplicationTransactionTemplate() | ||||
| ->setTransactionType( | ->setTransactionType($xaction_engine) | ||||
| PhabricatorDashboardPanelNameTransaction::TRANSACTIONTYPE) | |||||
| ->setNewValue($v_name); | |||||
| $xactions[] = id(new PhabricatorDashboardPanelTransaction()) | |||||
| ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD) | |||||
| ->setMetadataValue('customfield:key', 'std:dashboard:core:class') | |||||
| ->setOldValue(null) | |||||
| ->setNewValue($v_engine); | ->setNewValue($v_engine); | ||||
| $xactions[] = id(new PhabricatorDashboardPanelTransaction()) | $xactions[] = $panel->getApplicationTransactionTemplate() | ||||
| ->setTransactionType(PhabricatorTransactions::TYPE_CUSTOMFIELD) | ->setTransactionType($xaction_query) | ||||
| ->setMetadataValue('customfield:key', 'std:dashboard:core:key') | |||||
| ->setOldValue(null) | |||||
| ->setNewValue($v_query); | ->setNewValue($v_query); | ||||
| $editor = id(new PhabricatorDashboardPanelTransactionEditor()) | $xactions[] = $panel->getApplicationTransactionTemplate() | ||||
| ->setTransactionType($xaction_name) | |||||
| ->setNewValue($v_name); | |||||
| $editor = $panel->getApplicationTransactionEditor() | |||||
| ->setActor($viewer) | ->setActor($viewer) | ||||
| ->setContinueOnNoEffect(true) | |||||
| ->setContentSourceFromRequest($request) | ->setContentSourceFromRequest($request) | ||||
| ->applyTransactions($panel, $xactions); | ->applyTransactions($panel, $xactions); | ||||
| PhabricatorDashboardTransactionEditor::addPanelToDashboard( | // Now that we've created a panel, add it to the dashboard. | ||||
| $viewer, | |||||
| PhabricatorContentSource::newFromRequest($request), | |||||
| $panel, | |||||
| $dashboard, | |||||
| $request->getInt('column', 0)); | |||||
| return id(new AphrontRedirectResponse())->setURI($redirect_uri); | $xactions = array(); | ||||
| } | |||||
| } | |||||
| // Make this a select for now, as we don't expect someone to have | $ref_list = clone $dashboard->getPanelRefList(); | ||||
| // edit access to a vast number of dashboards. | $ref_list->newPanelRef($panel); | ||||
| // Can add optiongroup if needed down the road. | $new_panels = $ref_list->toDictionary(); | ||||
| $dashboards = id(new PhabricatorDashboardQuery()) | |||||
| ->setViewer($viewer) | |||||
| ->withStatuses(array( | |||||
| PhabricatorDashboard::STATUS_ACTIVE, | |||||
| )) | |||||
| ->requireCapabilities( | |||||
| array( | |||||
| PhabricatorPolicyCapability::CAN_VIEW, | |||||
| PhabricatorPolicyCapability::CAN_EDIT, | |||||
| )) | |||||
| ->execute(); | |||||
| $options = mpull($dashboards, 'getName', 'getID'); | |||||
| asort($options); | |||||
| $redirect_uri = $engine->getQueryResultsPageURI($v_query); | $xactions[] = $dashboard->getApplicationTransactionTemplate() | ||||
| ->setTransactionType( | |||||
| PhabricatorDashboardPanelsTransaction::TRANSACTIONTYPE) | |||||
| ->setNewValue($new_panels); | |||||
| if (!$options) { | $editor = $dashboard->getApplicationTransactionEditor() | ||||
| $notice = id(new PHUIInfoView()) | ->setActor($viewer) | ||||
| ->setSeverity(PHUIInfoView::SEVERITY_NOTICE) | ->setContentSourceFromRequest($request) | ||||
| ->appendChild(pht('You do not have access to any dashboards. To '. | ->setContinueOnNoEffect(true) | ||||
| 'continue, please create a dashboard first.')); | ->setContinueOnMissingFields(true) | ||||
| ->applyTransactions($dashboard, $xactions); | |||||
| return $this->newDialog() | return id(new AphrontRedirectResponse())->setURI($done_uri); | ||||
| ->setTitle(pht('No Dashboards')) | } | ||||
| ->setWidth(AphrontDialogView::WIDTH_FORM) | } | ||||
| ->appendChild($notice) | |||||
| ->addCancelButton($redirect_uri); | if ($v_dashboard) { | ||||
| $dashboard_phids = array($v_dashboard); | |||||
| } else { | |||||
| $dashboard_phids = array(); | |||||
| } | } | ||||
| $form = id(new AphrontFormView()) | $form = id(new AphrontFormView()) | ||||
| ->setUser($viewer) | ->setViewer($viewer) | ||||
| ->addHiddenInput('engine', $v_engine) | ->appendControl( | ||||
| ->addHiddenInput('query', $v_query) | |||||
| ->addHiddenInput('column', $v_column) | |||||
| ->appendChild( | |||||
| id(new AphrontFormTextControl()) | id(new AphrontFormTextControl()) | ||||
| ->setLabel(pht('Name')) | ->setLabel(pht('Name')) | ||||
| ->setName('name') | ->setName('name') | ||||
| ->setValue($v_name) | ->setValue($v_name) | ||||
| ->setError($e_name)) | ->setError($e_name)) | ||||
| ->appendChild( | ->appendControl( | ||||
| id(new AphrontFormSelectControl()) | id(new AphrontFormTokenizerControl()) | ||||
| ->setUser($this->getViewer()) | ->setValue($dashboard_phids) | ||||
| ->setValue($v_dashboard) | ->setError($e_dashboard) | ||||
| ->setName('dashboardID') | ->setName('dashboardPHIDs') | ||||
| ->setOptions($options) | ->setLimit(1) | ||||
| ->setDatasource(new PhabricatorDashboardDatasource()) | |||||
| ->setLabel(pht('Dashboard'))); | ->setLabel(pht('Dashboard'))); | ||||
| return $this->newDialog() | return $this->newDialog() | ||||
| ->setTitle(pht('Add Panel to Dashboard')) | ->setTitle(pht('Add Panel to Dashboard')) | ||||
| ->setErrors($errors) | ->setErrors($errors) | ||||
| ->setWidth(AphrontDialogView::WIDTH_FORM) | ->setWidth(AphrontDialogView::WIDTH_FORM) | ||||
| ->appendChild($form->buildLayoutView()) | ->addHiddenInput('engine', $v_engine) | ||||
| ->addHiddenInput('query', $v_query) | |||||
| ->appendForm($form) | |||||
| ->addCancelButton($redirect_uri) | ->addCancelButton($redirect_uri) | ||||
| ->addSubmitButton(pht('Add Panel')); | ->addSubmitButton(pht('Add Panel')); | ||||
| } | } | ||||
| } | } | ||||