Changeset View
Changeset View
Standalone View
Standalone View
src/applications/phrequent/controller/PhrequentExportController.php
- This file was added.
<?php | |||||
final class PhrequentExportController extends PhrequentController { | |||||
private $key; | |||||
public function willProcessRequest(array $data) { | |||||
$this->key = $data['key']; | |||||
return $this; | |||||
} | |||||
/** | |||||
* @phutil-external-symbol class PHPExcel | |||||
* @phutil-external-symbol class PHPExcel_IOFactory | |||||
* @phutil-external-symbol class PHPExcel_Style_NumberFormat | |||||
* @phutil-external-symbol class PHPExcel_Cell_DataType | |||||
*/ | |||||
public function processRequest() { | |||||
$request = $this->getRequest(); | |||||
$user = $request->getUser(); | |||||
$ok = @include_once 'PHPExcel.php'; | |||||
if (!$ok) { | |||||
$dialog = new AphrontDialogView(); | |||||
$dialog->setUser($user); | |||||
$inst1 = pht( | |||||
'This system does not have PHPExcel installed. This software '. | |||||
'component is required to export tasks to Excel. Have your system '. | |||||
'administrator install it from:'); | |||||
$inst2 = pht( | |||||
'Your PHP "include_path" needs to be updated to include the '. | |||||
'PHPExcel Classes directory.'); | |||||
$dialog->setTitle(pht('Excel Export Not Configured')); | |||||
$dialog->appendChild(hsprintf( | |||||
'<p>%s</p>'. | |||||
'<br />'. | |||||
'<p>'. | |||||
'<a href="http://www.phpexcel.net/">http://www.phpexcel.net/</a>'. | |||||
'</p>'. | |||||
'<br />'. | |||||
'<p>%s</p>', | |||||
$inst1, | |||||
$inst2)); | |||||
$dialog->addCancelButton('/phrequent/'); | |||||
return id(new AphrontDialogResponse())->setDialog($dialog); | |||||
} | |||||
// TODO: PHPExcel has a dependency on the PHP zip extension. We should test | |||||
// for that here, since it fatals if we don't have the ZipArchive class. | |||||
$saved = id(new PhabricatorSavedQueryQuery()) | |||||
->setViewer($user) | |||||
->withQueryKeys(array($this->key)) | |||||
->executeOne(); | |||||
if (!$saved) { | |||||
$engine = id(new PhrequentSearchEngine()) | |||||
->setViewer($user); | |||||
if ($engine->isBuiltinQuery($this->key)) { | |||||
$saved = $engine->buildSavedQueryFromBuiltin($this->key); | |||||
} | |||||
if (!$saved) { | |||||
return new Aphront404Response(); | |||||
} | |||||
} | |||||
$formats = PhrequentExcelFormat::loadAllFormats(); | |||||
$export_formats = array(); | |||||
foreach ($formats as $format_class => $format_object) { | |||||
$export_formats[$format_class] = $format_object->getName(); | |||||
} | |||||
if (!$request->isDialogFormPost()) { | |||||
$dialog = new AphrontDialogView(); | |||||
$dialog->setUser($user); | |||||
$dialog->setTitle(pht('Export User Time to Excel')); | |||||
$dialog->appendChild(phutil_tag('p', array(), pht( | |||||
'Do you want to export the query results to Excel?'))); | |||||
$form = id(new PHUIFormLayoutView()) | |||||
->appendChild( | |||||
id(new AphrontFormSelectControl()) | |||||
->setLabel(pht('Format:')) | |||||
->setName('excel-format') | |||||
->setOptions($export_formats)); | |||||
$dialog->appendChild($form); | |||||
$dialog->addCancelButton('/phrequent/'); | |||||
$dialog->addSubmitButton(pht('Export to Excel')); | |||||
return id(new AphrontDialogResponse())->setDialog($dialog); | |||||
} | |||||
$format = idx($formats, $request->getStr('excel-format')); | |||||
if ($format === null) { | |||||
throw new Exception('Excel format object not found.'); | |||||
} | |||||
$saved->makeEphemeral(); | |||||
$saved->setParameter('limit', PHP_INT_MAX); | |||||
$engine = id(new PhrequentSearchEngine()) | |||||
->setViewer($user); | |||||
$query = $engine->buildQueryFromSavedQuery($saved); | |||||
$query->setViewer($user); | |||||
$events = $query->execute(); | |||||
$before_date = $saved->getParameter('before'); | |||||
$after_date = $saved->getParameter('after'); | |||||
if ($before_date || $after_date) { | |||||
foreach ($events as $event) { | |||||
if ($before_date && $event->getDateEnded() > $before_date) { | |||||
$event->setDateEnded($before_date); | |||||
} | |||||
if ($after_date && $event->getDateStarted() < $after_date) { | |||||
$event->setDateStarted($after_date); | |||||
} | |||||
} | |||||
} | |||||
/* | |||||
* array_merge( | |||||
array_mergev(mpull($all_tasks, 'getProjectPHIDs')), | |||||
mpull($all_revisions, 'getArcanistProjectPHID'));*/ | |||||
$all_users = mpull($events, 'getUserPHID'); | |||||
$all_objects = phid_group_by_type(mpull($events, 'getObjectPHID')); | |||||
$all_tasks = id(new ManiphestTaskQuery()) | |||||
->setViewer($user) | |||||
->withPHIDS((array)array_unique($all_objects['TASK'])) | |||||
->execute(); | |||||
$all_revisions = id(new DifferentialRevisionQuery()) | |||||
->setViewer($user) | |||||
->withPHIDS((array)array_unique($all_objects['DREV'])) | |||||
->execute(); | |||||
$all_repositories = id(new PhabricatorRepositoryQuery()) | |||||
->setViewer($user) | |||||
->withPHIDs(array_unique(mpull($all_revisions, 'getRepositoryPHID'))) | |||||
->needProjectPHIDs(true) | |||||
->execute(); | |||||
$all_projects = array_merge( | |||||
array_mergev(mpull($all_tasks, 'getProjectPHIDs')), | |||||
array_mergev(mpull($all_repositories, 'getProjectPHIDs'))); | |||||
$all_users = id(new PhabricatorPeopleQuery()) | |||||
->setViewer($user) | |||||
->withPHIDS(array_unique($all_users)) | |||||
->execute(); | |||||
$all_projects = id(new PhabricatorHandleQuery()) | |||||
->setViewer($user) | |||||
->withPHIDs(array_unique($all_projects)) | |||||
->execute(); | |||||
$handles = array_merge( | |||||
mpull($all_tasks, null, 'getPHID'), | |||||
mpull($all_revisions, null, 'getPHID'), | |||||
mpull($all_users, null, 'getPHID'), | |||||
mpull($all_projects, null, 'getPHID'), | |||||
mpull($all_repositories, null, 'getPHID')); | |||||
$workbook = new PHPExcel(); | |||||
$format->buildWorkbook($workbook, $events, $handles, $user); | |||||
$writer = PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); | |||||
ob_start(); | |||||
$writer->save('php://output'); | |||||
$data = ob_get_clean(); | |||||
$mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; | |||||
return id(new AphrontFileResponse()) | |||||
->setMimeType($mime) | |||||
->setDownload($format->getFileName().'.xlsx') | |||||
->setContent($data); | |||||
} | |||||
} |