@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

When PHPExcel is not installed, detect it and provide install instructions

Summary:
Depends on D18957. Ref T13049. To do Excel exports, PHPExcel needs to be installed on the system somewhere.

This library is enormous (1K files, ~100K SLOC), which is why we don't just include it in `externals/`. This install process is a little weird and we could improve it, but users don't seem to have too much difficulty with it. This shouldn't be worse than the existing workflow in Maniphest, and I tried to make it at least slightly more clear.

Test Plan: Uninstalled PHPExcel, got it marked "Unavailable" and got reasonably-helpful-ish guidance on how to get it to work. Reinstalled, exported, got a sheet.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T13049

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

+58 -15
+34 -2
src/applications/search/controller/PhabricatorApplicationSearchController.php
··· 418 418 $filename = phutil_utf8_strtolower($filename); 419 419 $filename = PhabricatorFile::normalizeFileName($filename); 420 420 421 - $formats = PhabricatorExportFormat::getAllEnabledExportFormats(); 422 - $format_options = mpull($formats, 'getExportFormatName'); 421 + $all_formats = PhabricatorExportFormat::getAllExportFormats(); 422 + 423 + $available_options = array(); 424 + $unavailable_options = array(); 425 + $formats = array(); 426 + $unavailable_formats = array(); 427 + foreach ($all_formats as $key => $format) { 428 + if ($format->isExportFormatEnabled()) { 429 + $available_options[$key] = $format->getExportFormatName(); 430 + $formats[$key] = $format; 431 + } else { 432 + $unavailable_options[$key] = pht( 433 + '%s (Not Available)', 434 + $format->getExportFormatName()); 435 + $unavailable_formats[$key] = $format; 436 + } 437 + } 438 + $format_options = $available_options + $unavailable_options; 423 439 424 440 // Try to default to the format the user used last time. If you just 425 441 // exported to Excel, you probably want to export to Excel again. ··· 433 449 $e_format = null; 434 450 if ($request->isFormPost()) { 435 451 $format_key = $request->getStr('format'); 452 + 453 + if (isset($unavailable_formats[$format_key])) { 454 + $unavailable = $unavailable_formats[$format_key]; 455 + $instructions = $unavailable->getInstallInstructions(); 456 + 457 + $markup = id(new PHUIRemarkupView($viewer, $instructions)) 458 + ->setRemarkupOption( 459 + PHUIRemarkupView::OPTION_PRESERVE_LINEBREAKS, 460 + false); 461 + 462 + return $this->newDialog() 463 + ->setTitle(pht('Export Format Not Available')) 464 + ->appendChild($markup) 465 + ->addCancelButton($cancel_uri, pht('Done')); 466 + } 467 + 436 468 $format = idx($formats, $format_key); 437 469 438 470 if (!$format) {
+24 -1
src/infrastructure/export/format/PhabricatorExcelExportFormat.php
··· 14 14 } 15 15 16 16 public function isExportFormatEnabled() { 17 - return true; 17 + // TODO: PHPExcel has a dependency on the PHP zip extension. We should test 18 + // for that here, since it fatals if we don't have the ZipArchive class. 19 + return @include_once 'PHPExcel.php'; 20 + } 21 + 22 + public function getInstallInstructions() { 23 + return pht(<<<EOHELP 24 + Data can not be exported to Excel because the PHPExcel library is not 25 + installed. This software component is required for Phabricator to create 26 + Excel files. 27 + 28 + You can install PHPExcel from GitHub: 29 + 30 + > https://github.com/PHPOffice/PHPExcel 31 + 32 + Briefly: 33 + 34 + - Clone that repository somewhere on the sever 35 + (like `/path/to/example/PHPExcel`). 36 + - Update your PHP `%s` setting (in `php.ini`) to include the PHPExcel 37 + `Classes` directory (like `/path/to/example/PHPExcel/Classes`). 38 + EOHELP 39 + , 40 + 'include_path'); 18 41 } 19 42 20 43 public function getFileExtension() {
-12
src/infrastructure/export/format/PhabricatorExportFormat.php
··· 50 50 ->execute(); 51 51 } 52 52 53 - final public static function getAllEnabledExportFormats() { 54 - $formats = self::getAllExportFormats(); 55 - 56 - foreach ($formats as $key => $format) { 57 - if (!$format->isExportFormatEnabled()) { 58 - unset($formats[$key]); 59 - } 60 - } 61 - 62 - return $formats; 63 - } 64 - 65 53 }