Skip to content

Commit

Permalink
Fix thumbnail generation for mis-detected file types
Browse files Browse the repository at this point in the history
* Generate thumbnail despite wrong detected filetype

When a file has the wrong extension, fall back to other types
available until one works.
For unsupported files, get the mime type to determine if we truly cannot
support thumbnail generation.
Cache the type detected for further requests with different sizes.

* Test whether server has Fileinfo extension active

Only check mime types with fileinfo extension if it is active.
If not, avoid brute forcing type detection by rolling over the various
thumbnail generation methods and simply return no thumbnail.

* Keep capture file in memory instead of writing to disk

Keep the capture data in the Image class if the capture data is valid,
otherwise destroy the Image object.
Image doesn't read files from disk directly anymore.
  • Loading branch information
glubsy committed Jan 24, 2021
1 parent 8ac7f6a commit 40ff56e
Show file tree
Hide file tree
Showing 6 changed files with 335 additions and 103 deletions.
15 changes: 11 additions & 4 deletions src/_h5ai/private/php/core/class-context.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,12 +250,19 @@ public function get_l10n($iso_codes) {

public function get_thumbs($requests) {
$hrefs = [];

$thumbs = [];
foreach ($requests as $req) {
$thumb = new Thumb($this);
$hrefs[] = $thumb->thumb($req['type'], $req['href']);
$href = $this->to_path($req['href']);
if (!array_key_exists($href, $thumbs)) {
$thumbs[$href] = new Thumb($this, $href, $req['type']);
}
else if ($thumbs[$href]->type === 'file') {
// File has already been mime tested and cannot have a thumbnail
$hrefs[] = null;
continue;
}
$hrefs[] = $thumbs[$href]->thumb($this->thumbnail_width, $this->thumbnail_height);
}

return $hrefs;
}

Expand Down
3 changes: 3 additions & 0 deletions src/_h5ai/private/php/core/class-setup.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ private function add_php_checks() {
$has_php_jpeg = array_key_exists('JPEG Support', $infos) && $infos['JPEG Support'];
}
$this->set('HAS_PHP_JPEG', $has_php_jpeg);

$this->set('HAS_PHP_FILEINFO', extension_loaded('fileinfo'));
}

private function add_app_metadata() {
Expand Down Expand Up @@ -159,6 +161,7 @@ public function to_jsono($as_admin = false) {
'PHP_ARCH',
'HAS_PHP_EXIF',
'HAS_PHP_JPEG',
'HAS_PHP_FILEINFO',

'SERVER_NAME',
'SERVER_VERSION',
Expand Down
66 changes: 65 additions & 1 deletion src/_h5ai/private/php/core/class-util.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ class Util {
const ERR_UNSUPPORTED = 'ERR_UNSUPPORTED';
const NO_DEFAULT = 'NO_*@+#?!_DEFAULT';
const RE_DELIMITER = '@';
// 'file' has to be the last item!
public const AVAILABLE_TYPES = ['img', 'mov', 'doc', 'swf', 'file'];

public static function normalize_path($path, $trailing_slash = false) {
$path = preg_replace('#[\\\\/]+#', '/', $path);
Expand Down Expand Up @@ -71,7 +73,7 @@ public static function exec_cmdv($cmdv, $capture = false, $redirect = false) {
$lines = [];
$rc = null;
exec($cmd, $lines, $rc);
return [implode("\n", $lines), $rc];
return [$lines, $rc];
}
return exec($cmd);
}
Expand All @@ -86,9 +88,71 @@ public static function exec_0($cmd) {
return false;
}

public static function proc_open_cmdv($cmdv, &$output, &$error) {
$cmd = implode(' ', array_map('escapeshellarg', $cmdv));

$descriptorspec = array(
0 => array("pipe", "r"), // stdin is a pipe that the child will read from
1 => array("pipe", "w"), // stdout is a pipe that the child will write to
2 => array("pipe", "w") // stderr is a pipe the child will write to
);
$process = proc_open($cmd, $descriptorspec, $pipes);

if (is_resource($process)) {
fclose($pipes[0]); // We usually don't need stdin

if (is_resource($output)) {
stream_copy_to_stream($pipes[1], $output);
} else {
$output = stream_get_contents($pipes[1]);
}
fclose($pipes[1]);

$error = stream_get_contents($pipes[2]);
fclose($pipes[2]);

$exit_code = proc_close($process);
return $exit_code;
}
return -1;
}

public static function filesize($context, $path) {
$withFoldersize = $context->query_option('foldersize.enabled', false);
$withDu = $context->get_setup()->get('HAS_CMD_DU') && $context->query_option('foldersize.type', null) === 'shell-du';
return Filesize::getCachedSize($path, $withFoldersize, $withDu);
}

public static function get_mimetype($source_path) {
//return mime_content_type($filename);
$finfo = new finfo(FILEINFO_MIME_TYPE);
return $finfo->file($source_path);
}

public static function mime_to_type($mime) {
if (strpos($mime, 'image') !== false) {
return 'img';
}
if (strpos($mime, 'video') !== false) {
return 'mov';
}
if (strpos($mime, 'pdf') !== false) {
return 'doc';
}
if (strpos($mime, 'flash') !== false) {
return 'swf';
}
return 'file';
}

public static function get_types_array($type) {
/* Returns an array of possible types, with $type as the first element*/
$types = Util::AVAILABLE_TYPES;
$key = array_search($type, $types);
if ($key !== false) {
unset($types[$key]);
array_unshift($types, $type);
}
return $types;
}
}

0 comments on commit 40ff56e

Please sign in to comment.