From 6e7ca9d45dde79c9f223367108017282ab0136a7 Mon Sep 17 00:00:00 2001
From: Carsten  Rose <carsten.rose@math.uzh.ch>
Date: Sun, 11 Feb 2018 20:12:42 +0100
Subject: [PATCH] Feature 5333 / Thumbnail: fixed unit tests

---
 extension/qfq/qfq/Constants.php           |  3 +-
 extension/qfq/qfq/helper/Token.php        | 23 +++++++------
 extension/qfq/qfq/report/Link.php         |  1 +
 extension/qfq/qfq/report/Thumbnail.php    | 40 +++++++++++++++--------
 extension/qfq/tests/phpunit/TokenTest.php | 26 +++++++++++++++
 5 files changed, 68 insertions(+), 25 deletions(-)
 create mode 100644 extension/qfq/tests/phpunit/TokenTest.php

diff --git a/extension/qfq/qfq/Constants.php b/extension/qfq/qfq/Constants.php
index d35737983..4a0b27b68 100644
--- a/extension/qfq/qfq/Constants.php
+++ b/extension/qfq/qfq/Constants.php
@@ -1127,6 +1127,7 @@ const EXISTING_PATH_FILE_NAME = '_existingPathFileName';
 
 const THUMBNAIL_WIDTH_DEFAULT = '150x';
 const THUMBNAIL_UNKNOWN_TYPE = 'typo3/sysext/frontend/Resources/Public/Icons/FileIcons/';
+const THUMBNAIL_MAX_SECONDS = 60;
 
 //SENDMAIL
 const SENDMAIL_TOKEN_RECEIVER = 't';
@@ -1290,7 +1291,7 @@ const TOKEN_FILE_DEPRECATED = 'f';  // since 5.12.17
 const TOKEN_DOWNLOAD_MODE = 'M';
 
 const TOKEN_THUMBNAIL = 'T';
-const TOKEN_THUMBNAIL_WIDTH = 'W';
+const TOKEN_THUMBNAIL_DIMENSION = 'W';
 
 const TOKEN_ACTION_DELETE = 'x';
 const TOKEN_ACTION_DELETE_AJAX = 'a';
diff --git a/extension/qfq/qfq/helper/Token.php b/extension/qfq/qfq/helper/Token.php
index 556bc5a43..c11d1f3b8 100644
--- a/extension/qfq/qfq/helper/Token.php
+++ b/extension/qfq/qfq/helper/Token.php
@@ -106,17 +106,20 @@ class Token {
     public static function explodeDimension($dimension) {
         $width = '';
         $height = '';
+        $sep = '';
 
-        if ($dimension[0] == 'x') {
-            $height = '-h ' . substr($dimension, 1);
-        } else {
-            $arr = explode('x', $dimension, 2);
-            if (count($arr) > 1) {
-                $width = '-w ' . $arr[0];
-                $height = ' -h ' . $arr[1];
-            } else {
-                $width = '-w ' . $dimension;
-            }
+        if (empty($dimension)) {
+            return '';
+        }
+
+        $arr = explode('x', $dimension, 2);
+        if (!empty($arr[0])) {
+            $width = '-w ' . $arr[0];
+            $sep = ' ';
+        }
+
+        if (!empty($arr[1])) {
+            $height = $sep . '-h ' . $arr[1];
         }
 
         return $width . $height;
diff --git a/extension/qfq/qfq/report/Link.php b/extension/qfq/qfq/report/Link.php
index 26a1cf846..5dbc7e1cc 100644
--- a/extension/qfq/qfq/report/Link.php
+++ b/extension/qfq/qfq/report/Link.php
@@ -32,6 +32,7 @@ require_once(__DIR__ . '/../store/Sip.php');
 require_once(__DIR__ . '/../exceptions/UserReportException.php');
 require_once(__DIR__ . '/../helper/KeyValueStringParser.php');
 require_once(__DIR__ . '/../helper/Token.php');
+require_once(__DIR__ . '/Thumbnail.php');
 
 /*
  * u:url
diff --git a/extension/qfq/qfq/report/Thumbnail.php b/extension/qfq/qfq/report/Thumbnail.php
index 401a2c6f4..9026127b7 100644
--- a/extension/qfq/qfq/report/Thumbnail.php
+++ b/extension/qfq/qfq/report/Thumbnail.php
@@ -55,16 +55,16 @@ class Thumbnail {
             throw new UserReportException("Thumbnail: source file not specified", ERROR_MISSING_REQUIRED_PARAMETER);
         }
 
-        if (empty($control[TOKEN_THUMBNAIL_WIDTH])) {
-            $control[TOKEN_THUMBNAIL_WIDTH] = THUMBNAIL_WIDTH_DEFAULT;
+        if (empty($control[TOKEN_THUMBNAIL_DIMENSION])) {
+            $control[TOKEN_THUMBNAIL_DIMENSION] = THUMBNAIL_WIDTH_DEFAULT;
         }
 
         $pathFilenameSource = $control[TOKEN_THUMBNAIL];
 
-        $dir = ($this->store->getVar($control[TOKEN_SIP]) == "1") ? $this->thumbnailDirSecure : $this->thumbnailDirPublic;
-        $pathFilenameThumbnail = Support::joinPath($dir, md5($pathFilenameSource . $control[TOKEN_THUMBNAIL_WIDTH]) . '.png');
+        $dir = ($control[TOKEN_SIP] == "1") ? $this->thumbnailDirSecure : $this->thumbnailDirPublic;
+        $pathFilenameThumbnail = Support::joinPath($dir, md5($pathFilenameSource . $control[TOKEN_THUMBNAIL_DIMENSION]) . '.png');
 
-        $pathFilenameThumbnail = $this->doThumbnail($pathFilenameSource, $pathFilenameThumbnail, $control[TOKEN_THUMBNAIL_WIDTH]);
+        $pathFilenameThumbnail = $this->doThumbnail($pathFilenameSource, $pathFilenameThumbnail, $control[TOKEN_THUMBNAIL_DIMENSION]);
 
         return $this->buildImageTag($pathFilenameThumbnail, $control[TOKEN_SIP] == "1");
     }
@@ -72,25 +72,35 @@ class Thumbnail {
     /**
      * @param string $pathFilenameSource
      * @param string $pathFilenameThumbnail
-     * @param string $width
+     * @param string $dimension
      * @return string
      * @throws UserFormException
      * @throws UserReportException
      */
-    private function doThumbnail($pathFilenameSource, $pathFilenameThumbnail, $width) {
+    private function doThumbnail($pathFilenameSource, $pathFilenameThumbnail, $dimension) {
+        $debugMode = false;
+
         $statSource = stat($pathFilenameSource);
         $statThumbnail = stat($pathFilenameThumbnail);
 
         if ($statSource === false) {
-            throw new UserFormException('File not found: "' . $pathFilenameSource . '"', ERROR_IO_FILE_NOT_FOUND);
+            throw new UserFormException('File not found: "' . OnString::strrstr($pathFilenameSource, '/') . '"', ERROR_IO_FILE_NOT_FOUND);
         }
 
         if (isset($statThumbnail['size']) && $statThumbnail['size'] == 0) {
-            return $pathFilenameThumbnail; // There seems to be a thumbnail rendering already running. User needs to refresh page.
+
+            // If the thumbnail has not been rendered during the last 60 secondes, something is wrong.
+            if (time() - $statThumbnail['mtime'] > THUMBNAIL_MAX_SECONDS) {
+                $debugMode = true;
+//                throw new UserFormException('Thumbnail rendering takes longer than ' . THUMBNAIL_MAX_SECONDS . 's for file: ' .
+//                    OnString::strrstr($pathFilenameSource,'/'), ERROR_THUMBNAIL_RENDER);
+            } else {
+                return $pathFilenameThumbnail; // There seems to be a thumbnail rendering already running. User needs to refresh page.
+            }
         }
 
         if ($statThumbnail === false || $statThumbnail['mtime'] < $statSource['mtime']) {
-            $pathFilenameThumbnail = $this->createThumbnail($pathFilenameSource, $pathFilenameThumbnail, $width);
+            $pathFilenameThumbnail = $this->createThumbnail($pathFilenameSource, $pathFilenameThumbnail, $dimension, $debugMode);
         }
 
         return $pathFilenameThumbnail;
@@ -104,21 +114,23 @@ class Thumbnail {
      * @param string $pathFilenameSource
      * @param string $pathFilenameThumbnail
      * @param string $dimension
+     * @param $debugMode
      * @return string
      * @throws CodeException
      * @throws UserFormException
      * @throws UserReportException
      */
-    private function createThumbnail($pathFilenameSource, $pathFilenameThumbnail, $dimension) {
+    private function createThumbnail($pathFilenameSource, $pathFilenameThumbnail, $dimension, $debugMode) {
         $outputInkscape = '';
         $cmdInkscape = '';
+        $background = $debugMode ? '&' : '';
 
         // Indicates a running thumbnail rendering process.
         if (false === touch($pathFilenameThumbnail)) {
             // Be sure that the target directory exist
             Support::mkDirParent($pathFilenameThumbnail);
             if (false === touch($pathFilenameThumbnail)) {
-                throw new UserReportException('Could not create file: ' . $pathFilenameThumbnail, ERROR_IO_CREATE_FILE);
+                throw new UserReportException('Could not create file: ' . OnString::strrstr($pathFilenameSource, '/'), ERROR_IO_CREATE_FILE);
             }
         }
 
@@ -128,7 +140,7 @@ class Thumbnail {
         // SVG files are best to thumbnail via 'inkscape'
         if ($ext == 'svg' && $this->inkscape != '') {
             $inkscapeDimension = Token::explodeDimension($dimension);
-            $cmdInkscape = $this->inkscape . " --without-gui $inkscapeDimension --export-png $pathFilenameThumbnail $pathFilenameSource &";
+            $cmdInkscape = $this->inkscape . " --export-area-drawing --without-gui $inkscapeDimension --export-png $pathFilenameThumbnail $pathFilenameSource $background";
             $outputInkscape = Token::qfqExec($cmdInkscape, $rc);
             if ($rc == 0) {
                 return $pathFilenameThumbnail;
@@ -141,7 +153,7 @@ class Thumbnail {
             $pathFilenameSource .= '[0]';
         }
 
-        $cmd = $this->convert . " -scale $dimension $pathFilenameSource $pathFilenameThumbnail &";
+        $cmd = $this->convert . " -scale $dimension $pathFilenameSource $pathFilenameThumbnail $background";
         $output = Token::qfqExec($cmd, $rc);
 
         if ($rc != 0) {
diff --git a/extension/qfq/tests/phpunit/TokenTest.php b/extension/qfq/tests/phpunit/TokenTest.php
new file mode 100644
index 000000000..f0974086f
--- /dev/null
+++ b/extension/qfq/tests/phpunit/TokenTest.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: crose
+ * Date: 11/02/18
+ * Time: 9:16 PM
+ */
+
+namespace qfq;
+
+require_once(__DIR__ . '/../../qfq/helper/Token.php');
+
+use qfq;
+
+class TokenTest extends \PHPUnit_Framework_TestCase {
+
+    public function testExplodeDimension() {
+
+        $this->assertEquals('', Token::explodeDimension(''));
+        $this->assertEquals('-w 150', Token::explodeDimension('150'));
+        $this->assertEquals('-w 150', Token::explodeDimension('150x'));
+        $this->assertEquals('-w 150 -h 200', Token::explodeDimension('150x200'));
+        $this->assertEquals('-h 200', Token::explodeDimension('x200'));
+    }
+}
+
-- 
GitLab