Differential D18919 Diff 45427 src/applications/search/controller/PhabricatorApplicationSearchController.php
Changeset View
Changeset View
Standalone View
Standalone View
src/applications/search/controller/PhabricatorApplicationSearchController.php
Show First 20 Lines • Show All 60 Lines • ▼ Show 20 Lines | protected function validateDelegatingController() { | ||||
$engine->setViewer($this->getRequest()->getUser()); | $engine->setViewer($this->getRequest()->getUser()); | ||||
$parent = $this->getDelegatingController(); | $parent = $this->getDelegatingController(); | ||||
} | } | ||||
public function processRequest() { | public function processRequest() { | ||||
$this->validateDelegatingController(); | $this->validateDelegatingController(); | ||||
$query_action = $this->getRequest()->getURIData('queryAction'); | |||||
if ($query_action == 'export') { | |||||
return $this->processExportRequest(); | |||||
} | |||||
$key = $this->getQueryKey(); | $key = $this->getQueryKey(); | ||||
if ($key == 'edit') { | if ($key == 'edit') { | ||||
return $this->processEditRequest(); | return $this->processEditRequest(); | ||||
} else { | } else { | ||||
return $this->processSearchRequest(); | return $this->processSearchRequest(); | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 292 Lines • ▼ Show 20 Lines | return $this->newPage() | ||||
->setApplicationMenu($this->buildApplicationMenu()) | ->setApplicationMenu($this->buildApplicationMenu()) | ||||
->setTitle(pht('Query: %s', $title)) | ->setTitle(pht('Query: %s', $title)) | ||||
->setCrumbs($crumbs) | ->setCrumbs($crumbs) | ||||
->setNavigation($nav) | ->setNavigation($nav) | ||||
->addClass('application-search-view') | ->addClass('application-search-view') | ||||
->appendChild($body); | ->appendChild($body); | ||||
} | } | ||||
private function processExportRequest() { | |||||
$viewer = $this->getViewer(); | |||||
$engine = $this->getSearchEngine(); | |||||
$request = $this->getRequest(); | |||||
if (!$this->canExport()) { | |||||
return new Aphront404Response(); | |||||
} | |||||
$query_key = $this->getQueryKey(); | |||||
if ($engine->isBuiltinQuery($query_key)) { | |||||
$saved_query = $engine->buildSavedQueryFromBuiltin($query_key); | |||||
} else if ($query_key) { | |||||
$saved_query = id(new PhabricatorSavedQueryQuery()) | |||||
->setViewer($viewer) | |||||
->withQueryKeys(array($query_key)) | |||||
->executeOne(); | |||||
if (!$saved_query) { | |||||
return new Aphront404Response(); | |||||
} | |||||
} | |||||
$cancel_uri = $engine->getQueryResultsPageURI($query_key); | |||||
$named_query = idx($engine->loadEnabledNamedQueries(), $query_key); | |||||
if ($named_query) { | |||||
$filename = $named_query->getQueryName(); | |||||
} else { | |||||
$filename = $engine->getResultTypeDescription(); | |||||
} | |||||
$filename = phutil_utf8_strtolower($filename); | |||||
$filename = PhabricatorFile::normalizeFileName($filename); | |||||
if ($request->isFormPost()) { | |||||
$query = $engine->buildQueryFromSavedQuery($saved_query); | |||||
// NOTE: We aren't reading the pager from the request. Exports always | |||||
// affect the entire result set. | |||||
$pager = $engine->newPagerForSavedQuery($saved_query); | |||||
$pager->setPageSize(0x7FFFFFFF); | |||||
$objects = $engine->executeQuery($query, $pager); | |||||
$extension = 'json'; | |||||
$mime_type = 'application/json'; | |||||
$filename = $filename.'.'.$extension; | |||||
$result = $engine->newExport($objects); | |||||
$result = id(new PhutilJSON()) | |||||
->encodeAsList($result); | |||||
$file = PhabricatorFile::newFromFileData( | |||||
$result, | |||||
array( | |||||
'name' => $filename, | |||||
'authorPHID' => $viewer->getPHID(), | |||||
'ttl.relative' => phutil_units('15 minutes in seconds'), | |||||
'viewPolicy' => PhabricatorPolicies::POLICY_NOONE, | |||||
'mime-type' => $mime_type, | |||||
)); | |||||
return $this->newDialog() | |||||
->setTitle(pht('Download Results')) | |||||
->appendParagraph( | |||||
pht('Click the download button to download the exported data.')) | |||||
->addCancelButton($cancel_uri, pht('Done')) | |||||
->setSubmitURI($file->getDownloadURI()) | |||||
->setDisableWorkflowOnSubmit(true) | |||||
->addSubmitButton(pht('Download Results')); | |||||
} | |||||
$export_form = id(new AphrontFormView()) | |||||
->setViewer($viewer) | |||||
->appendControl( | |||||
id(new AphrontFormSelectControl()) | |||||
->setName('format') | |||||
->setLabel(pht('Format')) | |||||
->setOptions( | |||||
array( | |||||
'json' => 'JSON', | |||||
))); | |||||
return $this->newDialog() | |||||
->setTitle(pht('Export Results')) | |||||
->appendForm($export_form) | |||||
->addCancelButton($cancel_uri) | |||||
->addSubmitButton(pht('Continue')); | |||||
} | |||||
private function processEditRequest() { | private function processEditRequest() { | ||||
$parent = $this->getDelegatingController(); | $parent = $this->getDelegatingController(); | ||||
$request = $this->getRequest(); | $request = $this->getRequest(); | ||||
$viewer = $request->getUser(); | $viewer = $request->getUser(); | ||||
$engine = $this->getSearchEngine(); | $engine = $this->getSearchEngine(); | ||||
$nav = $this->getNavigation(); | $nav = $this->getNavigation(); | ||||
if (!$nav) { | if (!$nav) { | ||||
▲ Show 20 Lines • Show All 330 Lines • ▼ Show 20 Lines | private function newBuiltinUseActions() { | ||||
} | } | ||||
$can_use = $engine->canUseInPanelContext(); | $can_use = $engine->canUseInPanelContext(); | ||||
$is_installed = PhabricatorApplication::isClassInstalledForViewer( | $is_installed = PhabricatorApplication::isClassInstalledForViewer( | ||||
'PhabricatorDashboardApplication', | 'PhabricatorDashboardApplication', | ||||
$viewer); | $viewer); | ||||
if ($can_use && $is_installed) { | if ($can_use && $is_installed) { | ||||
$dashboard_uri = '/dashboard/install/'; | |||||
$actions[] = id(new PhabricatorActionView()) | $actions[] = id(new PhabricatorActionView()) | ||||
->setIcon('fa-dashboard') | ->setIcon('fa-dashboard') | ||||
->setName(pht('Add to Dashboard')) | ->setName(pht('Add to Dashboard')) | ||||
->setWorkflow(true) | ->setWorkflow(true) | ||||
->setHref("/dashboard/panel/install/{$engine_class}/{$query_key}/"); | ->setHref("/dashboard/panel/install/{$engine_class}/{$query_key}/"); | ||||
} | } | ||||
if ($this->canExport()) { | |||||
$export_uri = $engine->getExportURI($query_key); | |||||
$actions[] = id(new PhabricatorActionView()) | |||||
->setIcon('fa-download') | |||||
->setName(pht('Export Results')) | |||||
->setWorkflow(true) | |||||
->setHref($export_uri); | |||||
} | |||||
if ($is_dev) { | if ($is_dev) { | ||||
$engine = $this->getSearchEngine(); | $engine = $this->getSearchEngine(); | ||||
$nux_uri = $engine->getQueryBaseURI(); | $nux_uri = $engine->getQueryBaseURI(); | ||||
$nux_uri = id(new PhutilURI($nux_uri)) | $nux_uri = id(new PhutilURI($nux_uri)) | ||||
->setQueryParam('nux', true); | ->setQueryParam('nux', true); | ||||
$actions[] = id(new PhabricatorActionView()) | $actions[] = id(new PhabricatorActionView()) | ||||
->setIcon('fa-user-plus') | ->setIcon('fa-user-plus') | ||||
Show All 9 Lines | if ($is_dev) { | ||||
->setIcon('fa-fire') | ->setIcon('fa-fire') | ||||
->setName(pht('DEV: Overheated State')) | ->setName(pht('DEV: Overheated State')) | ||||
->setHref($overheated_uri); | ->setHref($overheated_uri); | ||||
} | } | ||||
return $actions; | return $actions; | ||||
} | } | ||||
private function canExport() { | |||||
$engine = $this->getSearchEngine(); | |||||
if (!$engine->canExport()) { | |||||
return false; | |||||
} | |||||
// Don't allow logged-out users to perform exports. There's no technical | |||||
// or policy reason they can't, but we don't normally give them access | |||||
// to write files or jobs. For now, just err on the side of caution. | |||||
$viewer = $this->getViewer(); | |||||
if (!$viewer->getPHID()) { | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
} | } |