@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+2 -342
-8
src/__phutil_library_map__.php
··· 1525 1525 'ManiphestEditProjectsCapability' => 'applications/maniphest/capability/ManiphestEditProjectsCapability.php', 1526 1526 'ManiphestEditStatusCapability' => 'applications/maniphest/capability/ManiphestEditStatusCapability.php', 1527 1527 'ManiphestEmailCommand' => 'applications/maniphest/command/ManiphestEmailCommand.php', 1528 - 'ManiphestExcelDefaultFormat' => 'applications/maniphest/export/ManiphestExcelDefaultFormat.php', 1529 - 'ManiphestExcelFormat' => 'applications/maniphest/export/ManiphestExcelFormat.php', 1530 - 'ManiphestExcelFormatTestCase' => 'applications/maniphest/export/__tests__/ManiphestExcelFormatTestCase.php', 1531 - 'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php', 1532 1528 'ManiphestGetTaskTransactionsConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestGetTaskTransactionsConduitAPIMethod.php', 1533 1529 'ManiphestHovercardEngineExtension' => 'applications/maniphest/engineextension/ManiphestHovercardEngineExtension.php', 1534 1530 'ManiphestInfoConduitAPIMethod' => 'applications/maniphest/conduit/ManiphestInfoConduitAPIMethod.php', ··· 6780 6776 'ManiphestEditProjectsCapability' => 'PhabricatorPolicyCapability', 6781 6777 'ManiphestEditStatusCapability' => 'PhabricatorPolicyCapability', 6782 6778 'ManiphestEmailCommand' => 'MetaMTAEmailTransactionCommand', 6783 - 'ManiphestExcelDefaultFormat' => 'ManiphestExcelFormat', 6784 - 'ManiphestExcelFormat' => 'Phobject', 6785 - 'ManiphestExcelFormatTestCase' => 'PhabricatorTestCase', 6786 - 'ManiphestExportController' => 'ManiphestController', 6787 6779 'ManiphestGetTaskTransactionsConduitAPIMethod' => 'ManiphestConduitAPIMethod', 6788 6780 'ManiphestHovercardEngineExtension' => 'PhabricatorHovercardEngineExtension', 6789 6781 'ManiphestInfoConduitAPIMethod' => 'ManiphestConduitAPIMethod',
-1
src/applications/maniphest/application/PhabricatorManiphestApplication.php
··· 57 57 $this->getEditRoutePattern('edit/') 58 58 => 'ManiphestTaskEditController', 59 59 ), 60 - 'export/(?P<key>[^/]+)/' => 'ManiphestExportController', 61 60 'subpriority/' => 'ManiphestSubpriorityController', 62 61 ), 63 62 );
-135
src/applications/maniphest/controller/ManiphestExportController.php
··· 1 - <?php 2 - 3 - final class ManiphestExportController extends ManiphestController { 4 - 5 - /** 6 - * @phutil-external-symbol class PHPExcel 7 - * @phutil-external-symbol class PHPExcel_IOFactory 8 - * @phutil-external-symbol class PHPExcel_Style_NumberFormat 9 - * @phutil-external-symbol class PHPExcel_Cell_DataType 10 - */ 11 - public function handleRequest(AphrontRequest $request) { 12 - $viewer = $this->getViewer(); 13 - $key = $request->getURIData('key'); 14 - 15 - $ok = @include_once 'PHPExcel.php'; 16 - if (!$ok) { 17 - $dialog = $this->newDialog(); 18 - 19 - $inst1 = pht( 20 - 'This system does not have PHPExcel installed. This software '. 21 - 'component is required to export tasks to Excel. Have your system '. 22 - 'administrator install it from:'); 23 - 24 - $inst2 = pht( 25 - 'Your PHP "%s" needs to be updated to include the '. 26 - 'PHPExcel Classes directory.', 27 - 'include_path'); 28 - 29 - $dialog->setTitle(pht('Excel Export Not Configured')); 30 - $dialog->appendChild(hsprintf( 31 - '<p>%s</p>'. 32 - '<br />'. 33 - '<p>'. 34 - '<a href="https://github.com/PHPOffice/PHPExcel">'. 35 - 'https://github.com/PHPOffice/PHPExcel'. 36 - '</a>'. 37 - '</p>'. 38 - '<br />'. 39 - '<p>%s</p>', 40 - $inst1, 41 - $inst2)); 42 - 43 - $dialog->addCancelButton('/maniphest/'); 44 - return id(new AphrontDialogResponse())->setDialog($dialog); 45 - } 46 - 47 - // TODO: PHPExcel has a dependency on the PHP zip extension. We should test 48 - // for that here, since it fatals if we don't have the ZipArchive class. 49 - 50 - $saved = id(new PhabricatorSavedQueryQuery()) 51 - ->setViewer($viewer) 52 - ->withQueryKeys(array($key)) 53 - ->executeOne(); 54 - if (!$saved) { 55 - $engine = id(new ManiphestTaskSearchEngine()) 56 - ->setViewer($viewer); 57 - if ($engine->isBuiltinQuery($key)) { 58 - $saved = $engine->buildSavedQueryFromBuiltin($key); 59 - } 60 - if (!$saved) { 61 - return new Aphront404Response(); 62 - } 63 - } 64 - 65 - $formats = ManiphestExcelFormat::loadAllFormats(); 66 - $export_formats = array(); 67 - foreach ($formats as $format_class => $format_object) { 68 - $export_formats[$format_class] = $format_object->getName(); 69 - } 70 - 71 - if (!$request->isDialogFormPost()) { 72 - $dialog = new AphrontDialogView(); 73 - $dialog->setUser($viewer); 74 - 75 - $dialog->setTitle(pht('Export Tasks to Excel')); 76 - $dialog->appendChild( 77 - phutil_tag( 78 - 'p', 79 - array(), 80 - pht('Do you want to export the query results to Excel?'))); 81 - 82 - $form = id(new PHUIFormLayoutView()) 83 - ->appendChild( 84 - id(new AphrontFormSelectControl()) 85 - ->setLabel(pht('Format:')) 86 - ->setName('excel-format') 87 - ->setOptions($export_formats)); 88 - 89 - $dialog->appendChild($form); 90 - 91 - $dialog->addCancelButton('/maniphest/'); 92 - $dialog->addSubmitButton(pht('Export to Excel')); 93 - return id(new AphrontDialogResponse())->setDialog($dialog); 94 - } 95 - 96 - $format = idx($formats, $request->getStr('excel-format')); 97 - if ($format === null) { 98 - throw new Exception(pht('Excel format object not found.')); 99 - } 100 - 101 - $saved->makeEphemeral(); 102 - $saved->setParameter('limit', PHP_INT_MAX); 103 - 104 - $engine = id(new ManiphestTaskSearchEngine()) 105 - ->setViewer($viewer); 106 - 107 - $query = $engine->buildQueryFromSavedQuery($saved); 108 - $query->setViewer($viewer); 109 - $tasks = $query->execute(); 110 - 111 - $all_projects = array_mergev(mpull($tasks, 'getProjectPHIDs')); 112 - $all_assigned = mpull($tasks, 'getOwnerPHID'); 113 - 114 - $handles = id(new PhabricatorHandleQuery()) 115 - ->setViewer($viewer) 116 - ->withPHIDs(array_merge($all_projects, $all_assigned)) 117 - ->execute(); 118 - 119 - $workbook = new PHPExcel(); 120 - $format->buildWorkbook($workbook, $tasks, $handles, $viewer); 121 - $writer = PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); 122 - 123 - ob_start(); 124 - $writer->save('php://output'); 125 - $data = ob_get_clean(); 126 - 127 - $mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'; 128 - 129 - return id(new AphrontFileResponse()) 130 - ->setMimeType($mime) 131 - ->setDownload($format->getFileName().'.xlsx') 132 - ->setContent($data); 133 - } 134 - 135 - }
-140
src/applications/maniphest/export/ManiphestExcelDefaultFormat.php
··· 1 - <?php 2 - 3 - final class ManiphestExcelDefaultFormat extends ManiphestExcelFormat { 4 - 5 - public function getName() { 6 - return pht('Default'); 7 - } 8 - 9 - public function getFileName() { 10 - return 'maniphest_tasks_'.date('Ymd'); 11 - } 12 - 13 - /** 14 - * @phutil-external-symbol class PHPExcel 15 - * @phutil-external-symbol class PHPExcel_IOFactory 16 - * @phutil-external-symbol class PHPExcel_Style_NumberFormat 17 - * @phutil-external-symbol class PHPExcel_Cell_DataType 18 - */ 19 - public function buildWorkbook( 20 - PHPExcel $workbook, 21 - array $tasks, 22 - array $handles, 23 - PhabricatorUser $user) { 24 - 25 - $sheet = $workbook->setActiveSheetIndex(0); 26 - $sheet->setTitle(pht('Tasks')); 27 - 28 - $widths = array( 29 - null, 30 - 15, 31 - null, 32 - 10, 33 - 15, 34 - 15, 35 - 60, 36 - 30, 37 - 20, 38 - 100, 39 - ); 40 - 41 - foreach ($widths as $col => $width) { 42 - if ($width !== null) { 43 - $sheet->getColumnDimension($this->col($col))->setWidth($width); 44 - } 45 - } 46 - 47 - $status_map = ManiphestTaskStatus::getTaskStatusMap(); 48 - $pri_map = ManiphestTaskPriority::getTaskPriorityMap(); 49 - 50 - $date_format = null; 51 - 52 - $rows = array(); 53 - $rows[] = array( 54 - pht('ID'), 55 - pht('Owner'), 56 - pht('Status'), 57 - pht('Priority'), 58 - pht('Date Created'), 59 - pht('Date Updated'), 60 - pht('Title'), 61 - pht('Tags'), 62 - pht('URI'), 63 - pht('Description'), 64 - ); 65 - 66 - $is_date = array( 67 - false, 68 - false, 69 - false, 70 - false, 71 - true, 72 - true, 73 - false, 74 - false, 75 - false, 76 - false, 77 - ); 78 - 79 - $header_format = array( 80 - 'font' => array( 81 - 'bold' => true, 82 - ), 83 - ); 84 - 85 - foreach ($tasks as $task) { 86 - $task_owner = null; 87 - if ($task->getOwnerPHID()) { 88 - $task_owner = $handles[$task->getOwnerPHID()]->getName(); 89 - } 90 - 91 - $projects = array(); 92 - foreach ($task->getProjectPHIDs() as $phid) { 93 - $projects[] = $handles[$phid]->getName(); 94 - } 95 - $projects = implode(', ', $projects); 96 - 97 - $rows[] = array( 98 - 'T'.$task->getID(), 99 - $task_owner, 100 - idx($status_map, $task->getStatus(), '?'), 101 - idx($pri_map, $task->getPriority(), '?'), 102 - $this->computeExcelDate($task->getDateCreated()), 103 - $this->computeExcelDate($task->getDateModified()), 104 - $task->getTitle(), 105 - $projects, 106 - PhabricatorEnv::getProductionURI('/T'.$task->getID()), 107 - id(new PhutilUTF8StringTruncator()) 108 - ->setMaximumBytes(512) 109 - ->truncateString($task->getDescription()), 110 - ); 111 - } 112 - 113 - foreach ($rows as $row => $cols) { 114 - foreach ($cols as $col => $spec) { 115 - $cell_name = $this->col($col).($row + 1); 116 - $cell = $sheet 117 - ->setCellValue($cell_name, $spec, $return_cell = true); 118 - 119 - if ($row == 0) { 120 - $sheet->getStyle($cell_name)->applyFromArray($header_format); 121 - } 122 - 123 - if ($is_date[$col]) { 124 - $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2; 125 - $sheet 126 - ->getStyle($cell_name) 127 - ->getNumberFormat() 128 - ->setFormatCode($code); 129 - } else { 130 - $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING); 131 - } 132 - } 133 - } 134 - } 135 - 136 - private function col($n) { 137 - return chr(ord('A') + $n); 138 - } 139 - 140 - }
-35
src/applications/maniphest/export/ManiphestExcelFormat.php
··· 1 - <?php 2 - 3 - abstract class ManiphestExcelFormat extends Phobject { 4 - 5 - final public static function loadAllFormats() { 6 - return id(new PhutilClassMapQuery()) 7 - ->setAncestorClass(__CLASS__) 8 - ->setSortMethod('getOrder') 9 - ->execute(); 10 - } 11 - 12 - abstract public function getName(); 13 - abstract public function getFileName(); 14 - 15 - public function getOrder() { 16 - return 0; 17 - } 18 - 19 - protected function computeExcelDate($epoch) { 20 - $seconds_per_day = (60 * 60 * 24); 21 - $offset = ($seconds_per_day * 25569); 22 - 23 - return ($epoch + $offset) / $seconds_per_day; 24 - } 25 - 26 - /** 27 - * @phutil-external-symbol class PHPExcel 28 - */ 29 - abstract public function buildWorkbook( 30 - PHPExcel $workbook, 31 - array $tasks, 32 - array $handles, 33 - PhabricatorUser $user); 34 - 35 - }
-10
src/applications/maniphest/export/__tests__/ManiphestExcelFormatTestCase.php
··· 1 - <?php 2 - 3 - final class ManiphestExcelFormatTestCase extends PhabricatorTestCase { 4 - 5 - public function testLoadAllFormats() { 6 - ManiphestExcelFormat::loadAllFormats(); 7 - $this->assertTrue(true); 8 - } 9 - 10 - }
+1 -12
src/applications/maniphest/view/ManiphestTaskResultListView.php
··· 175 175 } 176 176 177 177 if (!$user->isLoggedIn()) { 178 - // Don't show the batch editor or excel export for logged-out users. 179 - // Technically we //could// let them export, but ehh. 178 + // Don't show the batch editor for logged-out users. 180 179 return null; 181 180 } 182 181 ··· 220 219 ), 221 220 pht("Bulk Edit Selected \xC2\xBB")); 222 221 223 - $export = javelin_tag( 224 - 'a', 225 - array( 226 - 'href' => '/maniphest/export/'.$saved_query->getQueryKey().'/', 227 - 'class' => 'button button-grey', 228 - ), 229 - pht('Export to Excel')); 230 - 231 222 $hidden = phutil_tag( 232 223 'div', 233 224 array( ··· 239 230 '<table class="maniphest-batch-editor-layout">'. 240 231 '<tr>'. 241 232 '<td>%s%s</td>'. 242 - '<td>%s</td>'. 243 233 '<td id="batch-select-status-cell">%s</td>'. 244 234 '<td class="batch-select-submit-cell">%s%s</td>'. 245 235 '</tr>'. 246 236 '</table>', 247 237 $select_all, 248 238 $select_none, 249 - $export, 250 239 '', 251 240 $submit, 252 241 $hidden);
+1 -1
src/applications/search/controller/PhabricatorApplicationSearchController.php
··· 154 154 $saved_query = $engine->buildSavedQueryFromRequest($request); 155 155 156 156 // Save the query to generate a query key, so "Save Custom Query..." and 157 - // other features like Maniphest's "Export..." work correctly. 157 + // other features like "Bulk Edit" and "Export Data" work correctly. 158 158 $engine->saveQuery($saved_query); 159 159 } 160 160