1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2024-12-23 14:00:56 +01:00

Support thumbnailing non-image files and straighten out setup for 'gd'

Summary:
Make 'gd' an explicit optional dependency, test for it in setup, and make the
software behave correctly if it is not available.

When generating file thumnails, provide reasonable defaults and behavior for
non-image files.

Test Plan:
Uploaded text files, pdf files, etc., and got real thumbnails instead of a
broken image.

Simulated setup and gd failures and walked through setup process and image
fallback for thumbnails.

Reviewed By: aran
Reviewers: toulouse, jungejason, tuomaspelkonen, aran
CC: aran, epriestley
Differential Revision: 446
This commit is contained in:
epriestley 2011-06-13 08:43:42 -07:00
parent cb0cbc50ad
commit f706093933
11 changed files with 117 additions and 9 deletions

View file

@ -43,12 +43,10 @@ class PhabricatorFileTransformController extends PhabricatorFileController {
return new Aphront404Response(); return new Aphront404Response();
} }
if (!$file->isViewableInBrowser()) { $type = $file->getMimeType();
return new Aphront400Response();
}
if (!$file->isTransformableImage()) { if (!$file->isViewableInBrowser() || !$file->isTransformableImage()) {
return new Aphront400Response(); return $this->buildDefaultTransformation($file);
} }
switch ($this->transform) { switch ($this->transform) {
@ -78,6 +76,39 @@ class PhabricatorFileTransformController extends PhabricatorFileController {
return $this->buildTransformedFileResponse($xform); return $this->buildTransformedFileResponse($xform);
} }
private function buildDefaultTransformation(PhabricatorFile $file) {
static $regexps = array(
'@application/zip@' => 'zip',
'@image/@' => 'image',
'@application/pdf@' => 'pdf',
'@.*@' => 'default',
);
$type = $file->getMimeType();
$prefix = 'default';
foreach ($regexps as $regexp => $implied_prefix) {
if (preg_match($regexp, $type)) {
$prefix = $implied_prefix;
break;
}
}
switch ($this->transform) {
case 'thumb-160x120':
$suffix = '160x120';
break;
case 'thumb-60x45':
$suffix = '60x45';
break;
default:
throw new Exception("Unsupported transformation type!");
}
$path = "/rsrc/image/icon/fatcow/thumbnails/{$prefix}{$suffix}.png";
return id(new AphrontRedirectResponse())
->setURI($path);
}
private function buildTransformedFileResponse( private function buildTransformedFileResponse(
PhabricatorTransformedFile $xform) { PhabricatorTransformedFile $xform) {
@ -123,9 +154,25 @@ class PhabricatorFileTransformController extends PhabricatorFileController {
$dx, $dy, $dx, $dy,
$scale * $dx, $scale * $dy); $scale * $dx, $scale * $dy);
ob_start(); $img = null;
imagejpeg($dst);
return ob_get_clean(); if (function_exists('imagejpeg')) {
ob_start();
imagejpeg($dst);
$img = ob_get_clean();
} else if (function_exists('imagepng')) {
ob_start();
imagepng($dst);
$img = ob_get_clean();
} else if (function_exists('imagegif')) {
ob_start();
imagegif($dst);
$img = ob_get_clean();
} else {
throw new Exception("No image generation functions exist!");
}
return $img;
} }
} }

View file

@ -216,7 +216,35 @@ class PhabricatorFile extends PhabricatorFileDAO {
} }
public function isTransformableImage() { public function isTransformableImage() {
return preg_match('@^image/(gif|png|jpe?g)@', $this->getViewableMimeType());
// NOTE: The way the 'gd' extension works in PHP is that you can install it
// with support for only some file types, so it might be able to handle
// PNG but not JPEG. Try to generate thumbnails for whatever we can. Setup
// warns you if you don't have complete support.
$matches = null;
$ok = preg_match(
'@^image/(gif|png|jpe?g)@',
$this->getViewableMimeType(),
$matches);
if (!$ok) {
return false;
}
switch ($matches[1]) {
case 'jpg';
case 'jpeg':
return function_exists('imagejpeg');
break;
case 'png':
return function_exists('imagepng');
break;
case 'gif':
return function_exists('imagegif');
break;
default:
throw new Exception('Unknown type matched as image MIME type.');
}
} }
public function getViewableMimeType() { public function getViewableMimeType() {

View file

@ -165,6 +165,39 @@ class PhabricatorSetup {
self::write("[OKAY] Basic configuration OKAY\n"); self::write("[OKAY] Basic configuration OKAY\n");
$issue_gd_warning = false;
self::writeHeader('GD LIBRARY');
if (extension_loaded('gd')) {
self::write(" okay Extension 'gd' is loaded.\n");
$image_type_map = array(
'imagepng' => 'PNG',
'imagegif' => 'GIF',
'imagejpeg' => 'JPEG',
);
foreach ($image_type_map as $function => $image_type) {
if (function_exists($function)) {
self::write(" okay Support for '{$image_type}' is available.\n");
} else {
self::write(" warn Support for '{$image_type}' is not available!\n");
$issue_gd_warning = true;
}
}
} else {
self::write(" warn Extension 'gd' is not loaded.\n");
$issue_gd_warning = true;
}
if ($issue_gd_warning) {
self::write(
"[WARN] The 'gd' library is missing or lacks full support. ".
"Phabricator will not be able to generate image thumbnails without ".
"gd.\n");
} else {
self::write("[OKAY] 'gd' loaded and has full image type support.\n");
}
self::writeHeader('FACEBOOK INTEGRATION'); self::writeHeader('FACEBOOK INTEGRATION');
$fb_auth = PhabricatorEnv::getEnvConfig('facebook.auth-enabled'); $fb_auth = PhabricatorEnv::getEnvConfig('facebook.auth-enabled');
if (!$fb_auth) { if (!$fb_auth) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB