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')); | ||||
} | } | ||||
} | } |