From bc26827c7eb29658d1d3804d81c257329d16345f Mon Sep 17 00:00:00 2001
From: Carsten  Rose <carsten.rose@math.uzh.ch>
Date: Sun, 11 Feb 2018 23:18:03 +0100
Subject: [PATCH] Feature 5333 / Thumbnail: implemented for links.

---
 extension/Documentation/Manual.rst     |  16 +--
 extension/qfq/qfq/report/Link.php      | 132 +++++++++++++------------
 extension/qfq/qfq/report/Thumbnail.php |   9 ++
 3 files changed, 86 insertions(+), 71 deletions(-)

diff --git a/extension/Documentation/Manual.rst b/extension/Documentation/Manual.rst
index 60946e33e..8a4fe12a2 100644
--- a/extension/Documentation/Manual.rst
+++ b/extension/Documentation/Manual.rst
@@ -4886,6 +4886,10 @@ Column: _link
 +---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
 |   |x  |Check         |C:[<color>]                        |C:green                    |Show checked with '<color>'. Colors: blue, gray, green, pink, red, yellow. Default Color: green.                                        |
 +---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
+|   |x  |Thumbnail     |T:<pathFilename>                   |T:fileadmin/file.pdf       |Creates a thumbnail on the fly. Size is specified via 'W'. See `column-thumbnail`_                                                      |
++---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
+|   |   |Dimension     |W:[width]x[height]                 |W:50x , W:x60 , W:50x60    |Defines the pixel size of thumbnail.  See `column-thumbnail`_                                                                           |
++---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
 |   |   |URL Params    |U:<key1>=<value1>[&<keyN>=<valueN>]|U:a=value1&b=value2&c=...  |Any number of additional Params. Links to forms: U:form=Person&r=1234. Used to create 'record delete'-links.                            |
 +---+---+--------------+-----------------------------------+---------------------------+----------------------------------------------------------------------------------------------------------------------------------------+
 |   |   |Tooltip       |o:<text>                           |o:More information here    |Tooltip text                                                                                                                            |
@@ -5854,14 +5858,14 @@ or if the thumbnail dimension changes.
 
 The thumbnail pathFilename is a MD5 hash of the pathFilename plus the dimension.
 
-From multi page files like PDFs, the first page is used
-as source. All file formats, which GraphicsMagick 'convert' (http://www.graphicsmagick.org/formats.html) supports, can be
+From multi page files like PDFs, the first page is used.
+All file formats, which GraphicsMagick 'convert' (http://www.graphicsmagick.org/formats.html) supports, can be
 used. Office file formats are not supported. Due to speed and quality reasons, SVG files will be converted by inkscape.
 If a file format is not known, QFQ tries to show a corresponding file type image provided by Typo3 - such an image ist not
 scaled.
 
 In `config.qfq.ini`_ the exact location of `convert` and `inkscape` can be configured (optional) as well as the directory
-names for the thumbnails.
+names for the cached thumbnails.
 
 Dimension
 '''''''''
@@ -5871,8 +5875,8 @@ GraphicsMagick support various settings to force the thumbnail size. See http://
 Cleaning
 ''''''''
 
-By default, the thumbnail directories are never cleaned. It's a good idea to install a cronjob which purges all files older than 1
- year: ::
+By default, the thumbnail directories are never cleaned. It's a good idea to install a cronjob which purges all files
+older than 1 year: ::
 
 	find /path/to/files -type f -mtime +365 -delete
 
@@ -5888,7 +5892,7 @@ Thumbnail: secure
 Mode 'secure' is activated via enabling SIP (`s:1`, default). The thumbnail is saved under the path `thumbnailDirSecure`
 as configured in `config.qfq.ini`_.
 
-The secure path needs to be protected against direct file access by the webmaster / webserver configuration.
+The secure path needs to be protected against direct file access by the webmaster / webserver configuration too.
 
 QFQ returns a HTML 'img'-tag: ::
 
diff --git a/extension/qfq/qfq/report/Link.php b/extension/qfq/qfq/report/Link.php
index 5dbc7e1cc..d7df298d1 100644
--- a/extension/qfq/qfq/report/Link.php
+++ b/extension/qfq/qfq/report/Link.php
@@ -95,6 +95,8 @@ const NAME_RIGHT = 'picturePositionRight';
 const NAME_ACTION_DELETE = 'actionDelete';
 const NAME_EXTRA_CONTENT_WRAP = 'extraContentWrap';
 const NAME_FILE = 'file';
+const NAME_THUMBNAIL = 'thumbnail';
+const NAME_THUMBNAIL_DIMENSION = 'thumbnailDimension';
 
 const FINAL_HREF = 'finalHref';
 const FINAL_ANCHOR = 'finalAnchor';
@@ -103,6 +105,7 @@ const FINAL_SYMBOL = 'finalSymbol';
 const FINAL_TOOL_TIP = 'finalToolTip';
 const FINAL_CLASS = 'finalClass';
 const FINAL_QUESTION = 'finalQuestion';
+const FINAL_THUMBNAIL = 'finalThumbnail';
 
 const LINK_ANCHOR = 'linkAnchor';
 const LINK_PICTURE = 'linkPicture';
@@ -139,6 +142,11 @@ class Link {
      */
     private $store = null;
 
+    /**
+     * @var Thumbnail
+     */
+    private $thumbnail = null;
+
     private $phpUnit;
     private $renderControl = array();
 //    private $linkClassSelector = array(TOKEN_CLASS_INTERNAL => "internal ", TOKEN_CLASS_EXTERNAL => "external ");
@@ -199,6 +207,8 @@ class Link {
         TOKEN_ACTION_DELETE => NAME_ACTION_DELETE,
         TOKEN_FILE => NAME_FILE,
         TOKEN_FILE_DEPRECATED => NAME_FILE,
+        TOKEN_THUMBNAIL => NAME_THUMBNAIL,
+        TOKEN_THUMBNAIL_DIMENSION => NAME_THUMBNAIL_DIMENSION,
     ];
 
     // Used to find double definitions.
@@ -552,57 +562,6 @@ class Link {
         return $vars;
     }
 
-    /**
-     * Verify Empty values. If appropriate, set defaults, if not throw an exception.
-     *
-     * @param string $key
-     * @param string $value
-     *
-     * @return string
-     * @throws UserReportException
-     */
-    private function checkForEmptyValue($key, $value) {
-
-        if ($value !== '') {
-            return $value;
-        }
-        $value = '';
-
-        switch ($key) {
-            case TOKEN_URL:
-            case TOKEN_MAIL:
-            case TOKEN_GLYPH:
-                throw new UserReportException ("Missing value for token '$key'", ERROR_MISSING_VALUE);
-                break;
-            case TOKEN_PAGE:
-                $value = $this->store->getVar(TYPO3_PAGE_ID, STORE_TYPO3); // If no pageid|pagealias is defined, take current page
-                break;
-            case TOKEN_RIGHT:
-                $value = 'r';
-                break;
-            case TOKEN_ENCRYPTION:
-                $value = '1';
-                break;
-            case TOKEN_SIP:
-                $value = '1';
-                break;
-            case TOKEN_BOOTSTRAP_BUTTON:
-                $value = '1';
-                break;
-            case TOKEN_QUESTION:
-                $value = DEFAULT_QUESTION_TEXT;
-                break;
-            case TOKEN_RENDER:
-                $value = DEFAULT_RENDER_MODE;
-                break;
-            case TOKEN_ACTION_DELETE:
-                $value = DEFAULT_ACTION_DELETE;
-                break;
-            default:
-        }
-
-        return $value;
-    }
     /**
      * Cleans and make existing the standard vars used every time to render a link.
      *
@@ -648,6 +607,7 @@ class Link {
             FINAL_TOOL_TIP => '',
             FINAL_CLASS => '',
             FINAL_QUESTION => '',
+            FINAL_THUMBNAIL => '',
         ];
 
     }
@@ -748,6 +708,7 @@ class Link {
         $vars[FINAL_TOOL_TIP] = $this->doToolTip($vars);
         $vars[FINAL_CLASS] = $this->doCssClass($vars);
         $vars[FINAL_SYMBOL] = $this->doSymbol($vars);
+        $vars[FINAL_THUMBNAIL] = $this->doThumbnail($vars);
         $vars[FINAL_CONTENT] = $this->doContent($vars); // must be called after doSymbol()
         $vars[FINAL_QUESTION] = $this->doQuestion($vars);
         $vars[FINAL_ANCHOR] = $this->doAnchor($vars);
@@ -974,29 +935,42 @@ class Link {
     }
 
     /**
-     * Concat Text and/or Image and or Glyph. $vars[NAME_RIGHT_PICTURE_POSITION]
-     * Concat Text and/or Image and or Glyph. Depending of $vars[NAME_RIGHT_PICTURE_POSITION], swapp the position,
+     * Concat Text, Image, Glyph and/or Thumbnail.
+     * Depending of $vars[NAME_RIGHT_PICTURE_POSITION], swap the position,
      *
      * @param array $vars
      *
      * @return string
      */
     private function doContent(array $vars) {
+        $arr = array();
 
-        $htmlImage = $vars[FINAL_SYMBOL];
-
-        // Compose Image & Text
-        if ($htmlImage === '') {
-            $content = $vars[NAME_TEXT];
-        } elseif ($vars[NAME_TEXT] === '') {
-            $content = $htmlImage;
-        } else {
-            if ($vars[NAME_RIGHT] === "l") {
-                $content = implode(' ', [$htmlImage, $vars[NAME_TEXT]]);
-            } else {
-                $content = implode(' ', [$vars[NAME_TEXT], $htmlImage]);
+        $order = ($vars[NAME_RIGHT] === "l") ? [FINAL_SYMBOL, FINAL_THUMBNAIL, NAME_TEXT] : [NAME_TEXT, FINAL_THUMBNAIL, FINAL_SYMBOL];
+        foreach ($order as $key) {
+            if (!empty($vars[$key])) {
+                $arr[] = $vars[$key];
             }
         }
+        $content = implode(' ', $arr);
+
+        // Compose Image & Text
+//        if ($htmlImage === '') {
+//            $content = $vars[NAME_TEXT];
+//        } elseif ($vars[NAME_TEXT] === '') {
+//            $content = $htmlImage;
+//        } else {
+//            if ($vars[NAME_RIGHT] === "l") {
+//                $content = implode(' ', [$htmlImage, $vars[NAME_TEXT]]);
+//            } else {
+//                $content = implode(' ', [$vars[NAME_TEXT], $htmlImage]);
+//            }
+//        }
+
+//        if ($vars[NAME_RIGHT] === "l") {
+//            $content = implode(' ', [$htmlImage, $vars[NAME_TEXT]]);
+//        } else {
+//            $content = implode(' ', [$vars[NAME_TEXT], $htmlImage]);
+//        }
 
         if ($vars[NAME_EXTRA_CONTENT_WRAP] != '') {
             $content = Support::wrapTag($vars[NAME_EXTRA_CONTENT_WRAP], $content);
@@ -1078,6 +1052,34 @@ EOF;
         return $anchor;
     }
 
+    /**
+     *
+     *
+     * @param array $vars
+     *
+     * @return string
+     * @throws UserReportException
+     */
+    private function doThumbnail(array $vars) {
+
+        if (empty($vars[NAME_THUMBNAIL])) {
+            return '';
+        }
+
+        $arr = array();
+        $arr[] = TOKEN_THUMBNAIL . ':' . $vars[NAME_THUMBNAIL];
+        $arr[] = TOKEN_THUMBNAIL_DIMENSION . ':' . $vars[NAME_THUMBNAIL_DIMENSION];
+        $arr[] = TOKEN_SIP . ':' . $vars[NAME_SIP];
+
+        $str = implode('|', $arr);
+
+        if ($this->thumbnail === null) {
+            $this->thumbnail = new Thumbnail();
+        }
+
+        return $this->thumbnail->getImageTag($str);
+    }
+
     /**
      * Get mode from table $this->renderControl, depending on $modeRender, $modeUrl, $modeText
      *
diff --git a/extension/qfq/qfq/report/Thumbnail.php b/extension/qfq/qfq/report/Thumbnail.php
index 9026127b7..1a7e1ea5a 100644
--- a/extension/qfq/qfq/report/Thumbnail.php
+++ b/extension/qfq/qfq/report/Thumbnail.php
@@ -4,6 +4,8 @@
  * User: crose
  * Date: 2/10/18
  * Time: 3:14 PM
+ *
+ * See: doc/THUMBNAIL.md
  */
 
 namespace qfq;
@@ -39,6 +41,13 @@ class Thumbnail {
     }
 
     /**
+     * Renders a thumbnail based on $str.
+     * $str: "T:<pathfilename source>|W:<dimension>|s:<0|1>"
+     *
+     * Argument 'T' is mandatory.
+     * Argument 'W' is optional. Defaults to 'W:150x'.
+     * Argument 's' is optional. Defaults to 's:1'
+     *
      * @param string $str
      * @return string
      *
-- 
GitLab