mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-29 10:12:41 +01:00
Remove the old, non-modular Excel export workflow from Maniphest
Summary: Depends on D18960. Ref T13049. Now that Maniphest fully supports "Export Data", remove the old hard-coded version. This is a backward compatibility break with the handful of installs that might have defined a custom export by subclassing `ManiphestExcelFormat`. I suspect this is almost zero installs, and that the additional data in the new format may serve most of the needs of this tiny number of installs. They can upgrade to `ExportEngineExtensions` fairly easily if this isn't true. Test Plan: - Viewed Maniphest, no longer saw the old export workflow. - Grepped for `export` and similar strings to try to hunt everything down. Reviewers: amckinley Reviewed By: amckinley Maniphest Tasks: T13049 Differential Revision: https://secure.phabricator.com/D18961
This commit is contained in:
parent
c00838878a
commit
ea58b6acea
8 changed files with 2 additions and 342 deletions
|
@ -1525,10 +1525,6 @@ phutil_register_library_map(array(
|
||||||
'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php',
|
'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php',
|
||||||
'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php',
|
'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php',
|
||||||
'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php',
|
'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php',
|
||||||
'ManiphestExcelDefaultFormat' => 'applications/maniphest/export/ManiphestExcelDefaultFormat.php',
|
|
||||||
'ManiphestExcelFormat' => 'applications/maniphest/export/ManiphestExcelFormat.php',
|
|
||||||
'ManiphestExcelFormatTestCase' => 'applications/maniphest/export/__tests__/ManiphestExcelFormatTestCase.php',
|
|
||||||
'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php',
|
|
||||||
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
|
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php',
|
||||||
'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php',
|
'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php',
|
||||||
'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
|
'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php',
|
||||||
|
@ -6780,10 +6776,6 @@ phutil_register_library_map(array(
|
||||||
'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability',
|
'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability',
|
||||||
'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability',
|
'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability',
|
||||||
'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand',
|
||||||
'ManiphestExcelDefaultFormat' => 'ManiphestExcelFormat',
|
|
||||||
'ManiphestExcelFormat' => 'Phobject',
|
|
||||||
'ManiphestExcelFormatTestCase' => 'PhabricatorTestCase',
|
|
||||||
'ManiphestExportController' => 'ManiphestController',
|
|
||||||
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||||
'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension',
|
||||||
'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
|
||||||
|
|
|
@ -57,7 +57,6 @@ final class PhabricatorManiphestApplication extends PhabricatorApplication {
|
||||||
$this->getEditRoutePattern('edit/')
|
$this->getEditRoutePattern('edit/')
|
||||||
=> 'ManiphestTaskEditController',
|
=> 'ManiphestTaskEditController',
|
||||||
),
|
),
|
||||||
'export/(?P<key>[^/]+)/' => 'ManiphestExportController',
|
|
||||||
'subpriority/' => 'ManiphestSubpriorityController',
|
'subpriority/' => 'ManiphestSubpriorityController',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ManiphestExportController extends ManiphestController {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 handleRequest(AphrontRequest $request) {
|
|
||||||
$viewer = $this->getViewer();
|
|
||||||
$key = $request->getURIData('key');
|
|
||||||
|
|
||||||
$ok = @include_once 'PHPExcel.php';
|
|
||||||
if (!$ok) {
|
|
||||||
$dialog = $this->newDialog();
|
|
||||||
|
|
||||||
$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 "%s" needs to be updated to include the '.
|
|
||||||
'PHPExcel Classes directory.',
|
|
||||||
'include_path');
|
|
||||||
|
|
||||||
$dialog->setTitle(pht('Excel Export Not Configured'));
|
|
||||||
$dialog->appendChild(hsprintf(
|
|
||||||
'<p>%s</p>'.
|
|
||||||
'<br />'.
|
|
||||||
'<p>'.
|
|
||||||
'<a href="https://github.com/PHPOffice/PHPExcel">'.
|
|
||||||
'https://github.com/PHPOffice/PHPExcel'.
|
|
||||||
'</a>'.
|
|
||||||
'</p>'.
|
|
||||||
'<br />'.
|
|
||||||
'<p>%s</p>',
|
|
||||||
$inst1,
|
|
||||||
$inst2));
|
|
||||||
|
|
||||||
$dialog->addCancelButton('/maniphest/');
|
|
||||||
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($viewer)
|
|
||||||
->withQueryKeys(array($key))
|
|
||||||
->executeOne();
|
|
||||||
if (!$saved) {
|
|
||||||
$engine = id(new ManiphestTaskSearchEngine())
|
|
||||||
->setViewer($viewer);
|
|
||||||
if ($engine->isBuiltinQuery($key)) {
|
|
||||||
$saved = $engine->buildSavedQueryFromBuiltin($key);
|
|
||||||
}
|
|
||||||
if (!$saved) {
|
|
||||||
return new Aphront404Response();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$formats = ManiphestExcelFormat::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($viewer);
|
|
||||||
|
|
||||||
$dialog->setTitle(pht('Export Tasks 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('/maniphest/');
|
|
||||||
$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(pht('Excel format object not found.'));
|
|
||||||
}
|
|
||||||
|
|
||||||
$saved->makeEphemeral();
|
|
||||||
$saved->setParameter('limit', PHP_INT_MAX);
|
|
||||||
|
|
||||||
$engine = id(new ManiphestTaskSearchEngine())
|
|
||||||
->setViewer($viewer);
|
|
||||||
|
|
||||||
$query = $engine->buildQueryFromSavedQuery($saved);
|
|
||||||
$query->setViewer($viewer);
|
|
||||||
$tasks = $query->execute();
|
|
||||||
|
|
||||||
$all_projects = array_mergev(mpull($tasks, 'getProjectPHIDs'));
|
|
||||||
$all_assigned = mpull($tasks, 'getOwnerPHID');
|
|
||||||
|
|
||||||
$handles = id(new PhabricatorHandleQuery())
|
|
||||||
->setViewer($viewer)
|
|
||||||
->withPHIDs(array_merge($all_projects, $all_assigned))
|
|
||||||
->execute();
|
|
||||||
|
|
||||||
$workbook = new PHPExcel();
|
|
||||||
$format->buildWorkbook($workbook, $tasks, $handles, $viewer);
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,140 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ManiphestExcelDefaultFormat extends ManiphestExcelFormat {
|
|
||||||
|
|
||||||
public function getName() {
|
|
||||||
return pht('Default');
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFileName() {
|
|
||||||
return 'maniphest_tasks_'.date('Ymd');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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 buildWorkbook(
|
|
||||||
PHPExcel $workbook,
|
|
||||||
array $tasks,
|
|
||||||
array $handles,
|
|
||||||
PhabricatorUser $user) {
|
|
||||||
|
|
||||||
$sheet = $workbook->setActiveSheetIndex(0);
|
|
||||||
$sheet->setTitle(pht('Tasks'));
|
|
||||||
|
|
||||||
$widths = array(
|
|
||||||
null,
|
|
||||||
15,
|
|
||||||
null,
|
|
||||||
10,
|
|
||||||
15,
|
|
||||||
15,
|
|
||||||
60,
|
|
||||||
30,
|
|
||||||
20,
|
|
||||||
100,
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($widths as $col => $width) {
|
|
||||||
if ($width !== null) {
|
|
||||||
$sheet->getColumnDimension($this->col($col))->setWidth($width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$status_map = ManiphestTaskStatus::getTaskStatusMap();
|
|
||||||
$pri_map = ManiphestTaskPriority::getTaskPriorityMap();
|
|
||||||
|
|
||||||
$date_format = null;
|
|
||||||
|
|
||||||
$rows = array();
|
|
||||||
$rows[] = array(
|
|
||||||
pht('ID'),
|
|
||||||
pht('Owner'),
|
|
||||||
pht('Status'),
|
|
||||||
pht('Priority'),
|
|
||||||
pht('Date Created'),
|
|
||||||
pht('Date Updated'),
|
|
||||||
pht('Title'),
|
|
||||||
pht('Tags'),
|
|
||||||
pht('URI'),
|
|
||||||
pht('Description'),
|
|
||||||
);
|
|
||||||
|
|
||||||
$is_date = array(
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
$header_format = array(
|
|
||||||
'font' => array(
|
|
||||||
'bold' => true,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
foreach ($tasks as $task) {
|
|
||||||
$task_owner = null;
|
|
||||||
if ($task->getOwnerPHID()) {
|
|
||||||
$task_owner = $handles[$task->getOwnerPHID()]->getName();
|
|
||||||
}
|
|
||||||
|
|
||||||
$projects = array();
|
|
||||||
foreach ($task->getProjectPHIDs() as $phid) {
|
|
||||||
$projects[] = $handles[$phid]->getName();
|
|
||||||
}
|
|
||||||
$projects = implode(', ', $projects);
|
|
||||||
|
|
||||||
$rows[] = array(
|
|
||||||
'T'.$task->getID(),
|
|
||||||
$task_owner,
|
|
||||||
idx($status_map, $task->getStatus(), '?'),
|
|
||||||
idx($pri_map, $task->getPriority(), '?'),
|
|
||||||
$this->computeExcelDate($task->getDateCreated()),
|
|
||||||
$this->computeExcelDate($task->getDateModified()),
|
|
||||||
$task->getTitle(),
|
|
||||||
$projects,
|
|
||||||
PhabricatorEnv::getProductionURI('/T'.$task->getID()),
|
|
||||||
id(new PhutilUTF8StringTruncator())
|
|
||||||
->setMaximumBytes(512)
|
|
||||||
->truncateString($task->getDescription()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($rows as $row => $cols) {
|
|
||||||
foreach ($cols as $col => $spec) {
|
|
||||||
$cell_name = $this->col($col).($row + 1);
|
|
||||||
$cell = $sheet
|
|
||||||
->setCellValue($cell_name, $spec, $return_cell = true);
|
|
||||||
|
|
||||||
if ($row == 0) {
|
|
||||||
$sheet->getStyle($cell_name)->applyFromArray($header_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($is_date[$col]) {
|
|
||||||
$code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2;
|
|
||||||
$sheet
|
|
||||||
->getStyle($cell_name)
|
|
||||||
->getNumberFormat()
|
|
||||||
->setFormatCode($code);
|
|
||||||
} else {
|
|
||||||
$cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private function col($n) {
|
|
||||||
return chr(ord('A') + $n);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
abstract class ManiphestExcelFormat extends Phobject {
|
|
||||||
|
|
||||||
final public static function loadAllFormats() {
|
|
||||||
return id(new PhutilClassMapQuery())
|
|
||||||
->setAncestorClass(__CLASS__)
|
|
||||||
->setSortMethod('getOrder')
|
|
||||||
->execute();
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract public function getName();
|
|
||||||
abstract public function getFileName();
|
|
||||||
|
|
||||||
public function getOrder() {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function computeExcelDate($epoch) {
|
|
||||||
$seconds_per_day = (60 * 60 * 24);
|
|
||||||
$offset = ($seconds_per_day * 25569);
|
|
||||||
|
|
||||||
return ($epoch + $offset) / $seconds_per_day;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @phutil-external-symbol class PHPExcel
|
|
||||||
*/
|
|
||||||
abstract public function buildWorkbook(
|
|
||||||
PHPExcel $workbook,
|
|
||||||
array $tasks,
|
|
||||||
array $handles,
|
|
||||||
PhabricatorUser $user);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,10 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
final class ManiphestExcelFormatTestCase extends PhabricatorTestCase {
|
|
||||||
|
|
||||||
public function testLoadAllFormats() {
|
|
||||||
ManiphestExcelFormat::loadAllFormats();
|
|
||||||
$this->assertTrue(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -175,8 +175,7 @@ final class ManiphestTaskResultListView extends ManiphestView {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$user->isLoggedIn()) {
|
if (!$user->isLoggedIn()) {
|
||||||
// Don't show the batch editor or excel export for logged-out users.
|
// Don't show the batch editor for logged-out users.
|
||||||
// Technically we //could// let them export, but ehh.
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,14 +219,6 @@ final class ManiphestTaskResultListView extends ManiphestView {
|
||||||
),
|
),
|
||||||
pht("Bulk Edit Selected \xC2\xBB"));
|
pht("Bulk Edit Selected \xC2\xBB"));
|
||||||
|
|
||||||
$export = javelin_tag(
|
|
||||||
'a',
|
|
||||||
array(
|
|
||||||
'href' => '/maniphest/export/'.$saved_query->getQueryKey().'/',
|
|
||||||
'class' => 'button button-grey',
|
|
||||||
),
|
|
||||||
pht('Export to Excel'));
|
|
||||||
|
|
||||||
$hidden = phutil_tag(
|
$hidden = phutil_tag(
|
||||||
'div',
|
'div',
|
||||||
array(
|
array(
|
||||||
|
@ -239,14 +230,12 @@ final class ManiphestTaskResultListView extends ManiphestView {
|
||||||
'<table class="maniphest-batch-editor-layout">'.
|
'<table class="maniphest-batch-editor-layout">'.
|
||||||
'<tr>'.
|
'<tr>'.
|
||||||
'<td>%s%s</td>'.
|
'<td>%s%s</td>'.
|
||||||
'<td>%s</td>'.
|
|
||||||
'<td id="batch-select-status-cell">%s</td>'.
|
'<td id="batch-select-status-cell">%s</td>'.
|
||||||
'<td class="batch-select-submit-cell">%s%s</td>'.
|
'<td class="batch-select-submit-cell">%s%s</td>'.
|
||||||
'</tr>'.
|
'</tr>'.
|
||||||
'</table>',
|
'</table>',
|
||||||
$select_all,
|
$select_all,
|
||||||
$select_none,
|
$select_none,
|
||||||
$export,
|
|
||||||
'',
|
'',
|
||||||
$submit,
|
$submit,
|
||||||
$hidden);
|
$hidden);
|
||||||
|
|
|
@ -154,7 +154,7 @@ final class PhabricatorApplicationSearchController
|
||||||
$saved_query = $engine->buildSavedQueryFromRequest($request);
|
$saved_query = $engine->buildSavedQueryFromRequest($request);
|
||||||
|
|
||||||
// Save the query to generate a query key, so "Save Custom Query..." and
|
// Save the query to generate a query key, so "Save Custom Query..." and
|
||||||
// other features like Maniphest's "Export..." work correctly.
|
// other features like "Bulk Edit" and "Export Data" work correctly.
|
||||||
$engine->saveQuery($saved_query);
|
$engine->saveQuery($saved_query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue