@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.

Implemented support for different export formats.

Summary:
This adds support for different export formats to Excel
via a drop-down on the Export page as per the discussion
in D5443.

Test Plan:
Export some things from Maniphest. Do a simple implementation
of ManiphestExcelFormat just for testing and make sure that
it appears in the list after you run `arc liberate`.

Reviewers: epriestley

Reviewed By: epriestley

CC: aran, Korvin

Maniphest Tasks: T2575

Differential Revision: https://secure.phabricator.com/D5642

Conflicts:

src/applications/maniphest/controller/ManiphestExportController.php

authored by

James Rhodes and committed by
epriestley
8ba593b3 bdef566f

+214 -120
+3
src/__phutil_library_map__.php
··· 621 621 'ManiphestDAO' => 'applications/maniphest/storage/ManiphestDAO.php', 622 622 'ManiphestDefaultTaskExtensions' => 'applications/maniphest/extensions/ManiphestDefaultTaskExtensions.php', 623 623 'ManiphestEdgeEventListener' => 'applications/maniphest/event/ManiphestEdgeEventListener.php', 624 + 'ManiphestExcelDefaultFormat' => 'applications/maniphest/export/ManiphestExcelDefaultFormat.php', 625 + 'ManiphestExcelFormat' => 'applications/maniphest/export/ManiphestExcelFormat.php', 624 626 'ManiphestExportController' => 'applications/maniphest/controller/ManiphestExportController.php', 625 627 'ManiphestHovercardEventListener' => 'applications/maniphest/event/ManiphestHovercardEventListener.php', 626 628 'ManiphestPeopleMenuEventListener' => 'applications/maniphest/event/ManiphestPeopleMenuEventListener.php', ··· 2302 2304 'ManiphestDAO' => 'PhabricatorLiskDAO', 2303 2305 'ManiphestDefaultTaskExtensions' => 'ManiphestTaskExtensions', 2304 2306 'ManiphestEdgeEventListener' => 'PhutilEventListener', 2307 + 'ManiphestExcelDefaultFormat' => 'ManiphestExcelFormat', 2305 2308 'ManiphestExportController' => 'ManiphestController', 2306 2309 'ManiphestHovercardEventListener' => 'PhutilEventListener', 2307 2310 'ManiphestPeopleMenuEventListener' => 'PhutilEventListener',
+22 -120
src/applications/maniphest/controller/ManiphestExportController.php
··· 62 62 return new Aphront404Response(); 63 63 } 64 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 + 65 71 if (!$request->isDialogFormPost()) { 66 72 $dialog = new AphrontDialogView(); 67 73 $dialog->setUser($user); ··· 70 76 $dialog->appendChild(phutil_tag('p', array(), pht( 71 77 'Do you want to export the query results to Excel?'))); 72 78 79 + $form = id(new AphrontFormLayoutView()) 80 + ->appendChild( 81 + id(new AphrontFormSelectControl()) 82 + ->setLabel(pht('Format:')) 83 + ->setName("excel-format") 84 + ->setOptions($export_formats)); 85 + 86 + $dialog->appendChild($form); 87 + 73 88 $dialog->addCancelButton('/maniphest/'); 74 89 $dialog->addSubmitButton(pht('Export to Excel')); 75 90 return id(new AphrontDialogResponse())->setDialog($dialog); 76 91 77 92 } 78 93 94 + $format = idx($formats, $request->getStr("excel-format")); 95 + if ($format === null) { 96 + throw new Exception('Excel format object not found.'); 97 + } 98 + 79 99 $query->setParameter('limit', null); 80 100 $query->setParameter('offset', null); 81 101 $query->setParameter('order', 'p'); ··· 92 112 $handles += $project_handles; 93 113 94 114 $workbook = new PHPExcel(); 95 - $sheet = $workbook->setActiveSheetIndex(0); 96 - $sheet->setTitle(pht('Tasks')); 97 - 98 - $widths = array( 99 - null, 100 - 15, 101 - null, 102 - 10, 103 - 15, 104 - 15, 105 - 60, 106 - 30, 107 - 20, 108 - 100, 109 - ); 110 - 111 - foreach ($widths as $col => $width) { 112 - if ($width !== null) { 113 - $sheet->getColumnDimension($this->col($col))->setWidth($width); 114 - } 115 - } 116 - 117 - $status_map = ManiphestTaskStatus::getTaskStatusMap(); 118 - $pri_map = ManiphestTaskPriority::getTaskPriorityMap(); 119 - 120 - $date_format = null; 121 - 122 - $rows = array(); 123 - $rows[] = array( 124 - pht('ID'), 125 - pht('Owner'), 126 - pht('Status'), 127 - pht('Priority'), 128 - pht('Date Created'), 129 - pht('Date Updated'), 130 - pht('Title'), 131 - pht('Projects'), 132 - pht('URI'), 133 - pht('Description'), 134 - ); 135 - 136 - $is_date = array( 137 - false, 138 - false, 139 - false, 140 - false, 141 - true, 142 - true, 143 - false, 144 - false, 145 - false, 146 - false, 147 - ); 148 - 149 - $header_format = array( 150 - 'font' => array( 151 - 'bold' => true, 152 - ), 153 - ); 154 - 155 - foreach ($tasks as $task) { 156 - $task_owner = null; 157 - if ($task->getOwnerPHID()) { 158 - $task_owner = $handles[$task->getOwnerPHID()]->getName(); 159 - } 160 - 161 - $projects = array(); 162 - foreach ($task->getProjectPHIDs() as $phid) { 163 - $projects[] = $handles[$phid]->getName(); 164 - } 165 - $projects = implode(', ', $projects); 166 - 167 - $rows[] = array( 168 - 'T'.$task->getID(), 169 - $task_owner, 170 - idx($status_map, $task->getStatus(), '?'), 171 - idx($pri_map, $task->getPriority(), '?'), 172 - $this->computeExcelDate($task->getDateCreated()), 173 - $this->computeExcelDate($task->getDateModified()), 174 - $task->getTitle(), 175 - $projects, 176 - PhabricatorEnv::getProductionURI('/T'.$task->getID()), 177 - phutil_utf8_shorten($task->getDescription(), 512), 178 - ); 179 - } 180 - 181 - foreach ($rows as $row => $cols) { 182 - foreach ($cols as $col => $spec) { 183 - $cell_name = $this->col($col).($row + 1); 184 - $cell = $sheet 185 - ->setCellValue($cell_name, $spec, $return_cell = true); 186 - 187 - if ($row == 0) { 188 - $sheet->getStyle($cell_name)->applyFromArray($header_format); 189 - } 190 - 191 - if ($is_date[$col]) { 192 - $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2; 193 - $sheet 194 - ->getStyle($cell_name) 195 - ->getNumberFormat() 196 - ->setFormatCode($code); 197 - } else { 198 - $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING); 199 - } 200 - } 201 - } 202 - 115 + $format->buildWorkbook($workbook, $tasks, $handles, $user); 203 116 $writer = PHPExcel_IOFactory::createWriter($workbook, 'Excel2007'); 204 117 205 118 ob_start(); ··· 210 123 211 124 return id(new AphrontFileResponse()) 212 125 ->setMimeType($mime) 213 - ->setDownload('maniphest_tasks_'.date('Ymd').'.xlsx') 126 + ->setDownload($format->getFileName().'.xlsx') 214 127 ->setContent($data); 215 - } 216 - 217 - private function computeExcelDate($epoch) { 218 - $seconds_per_day = (60 * 60 * 24); 219 - $offset = ($seconds_per_day * 25569); 220 - 221 - return ($epoch + $offset) / $seconds_per_day; 222 - } 223 - 224 - private function col($n) { 225 - return chr(ord('A') + $n); 226 128 } 227 129 228 130 }
+142
src/applications/maniphest/export/ManiphestExcelDefaultFormat.php
··· 1 + <?php 2 + 3 + /** 4 + * @group maniphest 5 + */ 6 + final class ManiphestExcelDefaultFormat extends ManiphestExcelFormat { 7 + 8 + public function getName() { 9 + return pht('Default'); 10 + } 11 + 12 + public function getFileName() { 13 + return 'maniphest_tasks_'.date('Ymd'); 14 + } 15 + 16 + /** 17 + * @phutil-external-symbol class PHPExcel 18 + * @phutil-external-symbol class PHPExcel_IOFactory 19 + * @phutil-external-symbol class PHPExcel_Style_NumberFormat 20 + * @phutil-external-symbol class PHPExcel_Cell_DataType 21 + */ 22 + public function buildWorkbook( 23 + PHPExcel $workbook, 24 + array $tasks, 25 + array $handles, 26 + PhabricatorUser $user) { 27 + 28 + $sheet = $workbook->setActiveSheetIndex(0); 29 + $sheet->setTitle(pht('Tasks')); 30 + 31 + $widths = array( 32 + null, 33 + 15, 34 + null, 35 + 10, 36 + 15, 37 + 15, 38 + 60, 39 + 30, 40 + 20, 41 + 100, 42 + ); 43 + 44 + foreach ($widths as $col => $width) { 45 + if ($width !== null) { 46 + $sheet->getColumnDimension($this->col($col))->setWidth($width); 47 + } 48 + } 49 + 50 + $status_map = ManiphestTaskStatus::getTaskStatusMap(); 51 + $pri_map = ManiphestTaskPriority::getTaskPriorityMap(); 52 + 53 + $date_format = null; 54 + 55 + $rows = array(); 56 + $rows[] = array( 57 + pht('ID'), 58 + pht('Owner'), 59 + pht('Status'), 60 + pht('Priority'), 61 + pht('Date Created'), 62 + pht('Date Updated'), 63 + pht('Title'), 64 + pht('Projects'), 65 + pht('URI'), 66 + pht('Description'), 67 + ); 68 + 69 + $is_date = array( 70 + false, 71 + false, 72 + false, 73 + false, 74 + true, 75 + true, 76 + false, 77 + false, 78 + false, 79 + false, 80 + ); 81 + 82 + $header_format = array( 83 + 'font' => array( 84 + 'bold' => true, 85 + ), 86 + ); 87 + 88 + foreach ($tasks as $task) { 89 + $task_owner = null; 90 + if ($task->getOwnerPHID()) { 91 + $task_owner = $handles[$task->getOwnerPHID()]->getName(); 92 + } 93 + 94 + $projects = array(); 95 + foreach ($task->getProjectPHIDs() as $phid) { 96 + $projects[] = $handles[$phid]->getName(); 97 + } 98 + $projects = implode(', ', $projects); 99 + 100 + $rows[] = array( 101 + 'T'.$task->getID(), 102 + $task_owner, 103 + idx($status_map, $task->getStatus(), '?'), 104 + idx($pri_map, $task->getPriority(), '?'), 105 + $this->computeExcelDate($task->getDateCreated()), 106 + $this->computeExcelDate($task->getDateModified()), 107 + $task->getTitle(), 108 + $projects, 109 + PhabricatorEnv::getProductionURI('/T'.$task->getID()), 110 + phutil_utf8_shorten($task->getDescription(), 512), 111 + ); 112 + } 113 + 114 + foreach ($rows as $row => $cols) { 115 + foreach ($cols as $col => $spec) { 116 + $cell_name = $this->col($col).($row + 1); 117 + $cell = $sheet 118 + ->setCellValue($cell_name, $spec, $return_cell = true); 119 + 120 + if ($row == 0) { 121 + $sheet->getStyle($cell_name)->applyFromArray($header_format); 122 + } 123 + 124 + if ($is_date[$col]) { 125 + $code = PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2; 126 + $sheet 127 + ->getStyle($cell_name) 128 + ->getNumberFormat() 129 + ->setFormatCode($code); 130 + } else { 131 + $cell->setDataType(PHPExcel_Cell_DataType::TYPE_STRING); 132 + } 133 + } 134 + } 135 + } 136 + 137 + 138 + private function col($n) { 139 + return chr(ord('A') + $n); 140 + } 141 + 142 + }
+47
src/applications/maniphest/export/ManiphestExcelFormat.php
··· 1 + <?php 2 + 3 + /** 4 + * @group maniphest 5 + */ 6 + abstract class ManiphestExcelFormat { 7 + 8 + final public static function loadAllFormats() { 9 + $classes = id(new PhutilSymbolLoader()) 10 + ->setAncestorClass(__CLASS__) 11 + ->setConcreteOnly(true) 12 + ->selectAndLoadSymbols(); 13 + 14 + $objects = array(); 15 + foreach ($classes as $class) { 16 + $objects[$class['name']] = newv($class['name'], array()); 17 + } 18 + 19 + $objects = msort($objects, 'getOrder'); 20 + 21 + return $objects; 22 + } 23 + 24 + public abstract function getName(); 25 + public abstract function getFileName(); 26 + 27 + public function getOrder() { 28 + return 0; 29 + } 30 + 31 + protected function computeExcelDate($epoch) { 32 + $seconds_per_day = (60 * 60 * 24); 33 + $offset = ($seconds_per_day * 25569); 34 + 35 + return ($epoch + $offset) / $seconds_per_day; 36 + } 37 + 38 + /** 39 + * @phutil-external-symbol class PHPExcel 40 + */ 41 + public abstract function buildWorkbook( 42 + PHPExcel $workbook, 43 + array $tasks, 44 + array $handles, 45 + PhabricatorUser $user); 46 + 47 + }