[BUGFIX] Adapt ShowPic popup to use FAL 52/28252/6
authorSteffen Ritter <info@rs-websystems.de>
Tue, 11 Mar 2014 13:07:00 +0000 (14:07 +0100)
committerSteffen Ritter <info@rs-websystems.de>
Wed, 12 Mar 2014 10:38:16 +0000 (11:38 +0100)
If not using own Lightboxes TYPO3 ships a custom solution
of an image-enlarge popup. This combines an eID for rendering
the image as well as a short JavaScript snippet opening that
in a new window.

The php code for rendering that link as well as the popup code
itself are not fal aware and to image-processing on their own.
As a result this feature is only able to deal with files in local
file system.

This change refactors both imageLinkWrap as well as
ShowImageController to use and work on FAL objects.

Releases: 6.2
Resolves: #56723
Change-Id: Iebf1379b8f72cf57d69a06b0b7540cbd8ccb32c1
Reviewed-on: https://review.typo3.org/28252
Reviewed-by: Frans Saris
Tested-by: Frans Saris
Reviewed-by: Fabien Udriot
Tested-by: Fabien Udriot
Reviewed-by: Steffen Ritter
Tested-by: Steffen Ritter
typo3/sysext/cms/tslib/showpic.php
typo3/sysext/css_styled_content/Classes/Controller/CssStyledContentController.php
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Classes/Controller/ShowImageController.php

index f5294bd..35939e8 100644 (file)
  ***************************************************************/
 
 /**
- * Shows a picture from uploads/* in enlarged format in a separate window.
- * Picture file and settings is supplied by GET-parameters: file, width, height, sample, alternativeTempPath, effects, frame, bodyTag, title, wrap, md5
+ * eID-Script for tx_cms_showpic
  *
- * @author Kasper Skårhøj <kasperYYYY@typo3.com>
+ * Shows a picture from FAL in enlarged format in a separate window.
+ * Picture file and settings is supplied by GET-parameters:
+ *  - file = fileUid or Combined Identifier
+ *  - encoded in an parameter Array (with weird format - see ContentObjectRenderer about ll. 1500)
+ *     - width, height = usual width an height, m/c supported
+ *     - sample = 0/1
+ *     - effects
+ *     - frame
+ *     - bodyTag
+ *     - title
+ *     - wrap
+ *  - md5 = actually contains an hmac
  */
 
 if (!defined('PATH_typo3conf')) {
        die('The configuration path was not properly defined!');
 }
 
-require_once \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('core') . 'Classes/Imaging/GraphicalFunctions.php';
-
-/*
- * @deprecated since 6.0, the classname SC_tslib_showpic and this file is obsolete
- * and will be removed with 6.2. The class was renamed and is now located at:
- * typo3/sysext/frontend/Classes/Controller/ShowImageController.php
- */
-require_once \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::extPath('frontend') . 'Classes/Controller/ShowImageController.php';
-
 // Make instance:
 $SOBE = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Controller\\ShowImageController');
-$SOBE->init();
-$SOBE->main();
-$SOBE->printContent();
+$SOBE->execute();
index 0264db3..527c7d4 100644 (file)
@@ -732,7 +732,7 @@ class CssStyledContentController extends \TYPO3\CMS\Frontend\Plugin\AbstractPlug
                                }
                                if ($titleInLink && !$titleInLinkAndImg) {
                                        // Check if the image will be linked
-                                       $link = $this->cObj->imageLinkWrap('', $totalImagePath, $imgConf['imageLinkWrap.']);
+                                       $link = $this->cObj->imageLinkWrap('', $this->cObj->getCurrentFile() ?: $totalImagePath, $imgConf['imageLinkWrap.']);
                                        if ($link) {
                                                // Title in A-tag only (set above: ATagParams), not in IMG-tag
                                                unset($imgConf['titleText']);
index 750a194..c37c96a 100644 (file)
@@ -1327,7 +1327,7 @@ class ContentObjectRenderer {
                        if ($linkWrap) {
                                $theValue = $this->linkWrap($theValue, $linkWrap);
                        } elseif ($conf['imageLinkWrap']) {
-                               $theValue = $this->imageLinkWrap($theValue, $info['origFile'], $conf['imageLinkWrap.']);
+                               $theValue = $this->imageLinkWrap($theValue, $info['originalFile'], $conf['imageLinkWrap.']);
                        }
                        $wrap = isset($conf['wrap.']) ? $this->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap'];
                        if ($wrap) {
@@ -1464,7 +1464,7 @@ class ContentObjectRenderer {
         * Wraps the input string in link-tags that opens the image in a new window.
         *
         * @param string $string String to wrap, probably an <img> tag
-        * @param string $imageFile The original image file
+        * @param string|\TYPO3\CMS\Core\Resource\File|\TYPO3\CMS\Core\Resource\FileReference $imageFile The original image file
         * @param array $conf TypoScript properties for the "imageLinkWrap" function
         * @return string The input string, $string, wrapped as configured.
         * @see cImage()
@@ -1480,9 +1480,22 @@ class ContentObjectRenderer {
                        if (isset($conf['file.'])) {
                                $imageFile = $this->stdWrap($imageFile, $conf['file.']);
                        }
+
+                       if ($imageFile instanceof \TYPO3\CMS\Core\Resource\File) {
+                               $file = $imageFile;
+                       } elseif ($imageFile instanceof \TYPO3\CMS\Core\Resource\FileReference) {
+                               $file = $imageFile->getOriginalFile();
+                       } else {
+                               if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($imageFile)) {
+                                       $file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObject((int)$imageFile);
+                               } else {
+                                       $file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObjectFromCombinedIdentifier($imageFile);
+                               }
+                       }
+
                        // Create imageFileLink if not created with typolink
                        if ($content == $string) {
-                               $parameterNames = array('width', 'height', 'effects', 'alternativeTempPath', 'bodyTag', 'title', 'wrap');
+                               $parameterNames = array('width', 'height', 'effects', 'bodyTag', 'title', 'wrap');
                                $parameters = array();
                                $sample = isset($conf['sample.']) ? $this->stdWrap($conf['sample'], $conf['sample.']) : $conf['sample'];
                                if ($sample) {
@@ -1497,12 +1510,12 @@ class ContentObjectRenderer {
                                        }
                                }
                                $parametersEncoded = base64_encode(serialize($parameters));
-                               $md5_value = GeneralUtility::hmac(implode('|', array($imageFile, $parametersEncoded)));
-                               $params = '&md5=' . $md5_value;
+                               $hmac = GeneralUtility::hmac(implode('|', array($file->getUid(), $parametersEncoded)));
+                               $params = '&md5=' . $hmac;
                                foreach (str_split($parametersEncoded, 64) as $index => $chunk) {
                                        $params .= '&parameters' . rawurlencode('[') . $index . rawurlencode(']') . '=' . rawurlencode($chunk);
                                }
-                               $url = $GLOBALS['TSFE']->absRefPrefix . 'index.php?eID=tx_cms_showpic&file=' . rawurlencode($imageFile) . $params;
+                               $url = $GLOBALS['TSFE']->absRefPrefix . 'index.php?eID=tx_cms_showpic&file=' . $file->getUid() . $params;
                                $directImageLink = isset($conf['directImageLink.']) ? $this->stdWrap($conf['directImageLink'], $conf['directImageLink.']) : $conf['directImageLink'];
                                if ($directImageLink) {
                                        $imgResourceConf = array(
@@ -1534,14 +1547,12 @@ class ContentObjectRenderer {
                                                        $url = $altUrl . ($conf['JSwindow.']['altUrl_noDefaultParams'] ? '' : '?file=' . rawurlencode($imageFile) . $params);
                                                }
                                        }
-                                       $gifCreator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Imaging\\GifBuilder');
-                                       $gifCreator->init();
-                                       $gifCreator->mayScaleUp = 0;
-                                       $dims = $gifCreator->getImageScale($gifCreator->getImageDimensions($imageFile), $conf['width'], $conf['height'], array());
+
+                                       $processedFile = $file->process('Image.CropScaleMask', $conf);
                                        $JSwindowExpand = isset($conf['JSwindow.']['expand.']) ? $this->stdWrap($conf['JSwindow.']['expand'], $conf['JSwindow.']['expand.']) : $conf['JSwindow.']['expand'];
                                        $offset = GeneralUtility::intExplode(',', $JSwindowExpand . ',');
                                        $newWindow = isset($conf['JSwindow.']['newWindow.']) ? $this->stdWrap($conf['JSwindow.']['newWindow'], $conf['JSwindow.']['newWindow.']) : $conf['JSwindow.']['newWindow'];
-                                       $a1 = '<a href="' . htmlspecialchars($url) . '" onclick="' . htmlspecialchars(('openPic(\'' . $GLOBALS['TSFE']->baseUrlWrap($url) . '\',\'' . ($newWindow ? md5($url) : 'thePicture') . '\',\'width=' . ($dims[0] + $offset[0]) . ',height=' . ($dims[1] + $offset[1]) . ',status=0,menubar=0\'); return false;')) . '"' . $target . $GLOBALS['TSFE']->ATagParams . '>';
+                                       $a1 = '<a href="' . htmlspecialchars($url) . '" onclick="' . htmlspecialchars(('openPic(\'' . $GLOBALS['TSFE']->baseUrlWrap($url) . '\',\'' . ($newWindow ? md5($url) : 'thePicture') . '\',\'width=' . ($processedFile->getProperty('width') + $offset[0]) . ',height=' . ($processedFile->getProperty('height') + $offset[1]) . ',status=0,menubar=0\'); return false;')) . '"' . $target . $GLOBALS['TSFE']->ATagParams . '>';
                                        $a2 = '</a>';
                                        $GLOBALS['TSFE']->setJS('openPic');
                                } else {
index dce52a0..79ac594 100644 (file)
@@ -27,6 +27,10 @@ namespace TYPO3\CMS\Frontend\Controller;
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
 
+use \TYPO3\CMS\Core\Utility\HttpUtility;
+use \TYPO3\CMS\Core\Utility\GeneralUtility;
+use \TYPO3\CMS\Core\Utility\MathUtility;
+
 /**
  * Script Class, generating the page output.
  * Instantiated in the bottom of this script.
@@ -35,108 +39,116 @@ namespace TYPO3\CMS\Frontend\Controller;
  */
 class ShowImageController {
 
-       // Page content accumulated here.
-       /**
-        * @todo Define visibility
-        */
-       public $content;
-
        // Parameters loaded into these internal variables:
        /**
-        * @todo Define visibility
+        * @var \TYPO3\CMS\Core\Resource\File
         */
-       public $file;
+       protected $file;
 
        /**
-        * @todo Define visibility
+        * @var int
         */
-       public $width;
+       protected $width;
 
        /**
-        * @todo Define visibility
+        * @var int
         */
-       public $height;
+       protected $height;
 
        /**
-        * @todo Define visibility
-        */
-       public $sample;
-
-       /**
-        * @todo Define visibility
+        * @var string
         */
-       public $alternativeTempPath;
+       protected $sample;
 
        /**
-        * @todo Define visibility
+        * @var string
         */
-       public $effects;
+       protected $effects;
 
        /**
-        * @todo Define visibility
+        * @var int
         */
-       public $frame;
+       protected $frame;
 
        /**
-        * @todo Define visibility
+        * @var string
         */
-       public $bodyTag;
+       protected $hmac;
 
        /**
-        * @todo Define visibility
+        * @var string
         */
-       public $title;
+       protected $bodyTag = '<body>';
 
        /**
-        * @todo Define visibility
+        * @var string
         */
-       public $wrap;
+       protected $wrap = '|';
 
        /**
-        * @todo Define visibility
+        * @var string
         */
-       public $md5;
+       protected $title = 'Image';
 
        /**
         * @var string
         */
-       protected $parametersEncoded;
+       protected $content = <<<EOF
+<!DOCTYPE html>
+<html>
+<head>
+       <title>###TITLE###</title>
+       <meta name="robots" content="noindex,follow" />
+</head>
+###BODY###
+       ###IMAGE###
+</body>
+</html>
+EOF;
+
+       protected $imageTag = '<img src="###publicUrl###" alt="###alt###" title="###title###" />';
 
        /**
         * Init function, setting the input vars in the global space.
         *
         * @return void
-        * @todo Define visibility
         */
        public function init() {
                // Loading internal vars with the GET/POST parameters from outside:
-               $this->file = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('file');
-               $parametersArray = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('parameters');
-               $this->frame = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('frame');
-               $this->md5 = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('md5');
-               // Check parameters
+               $fileUid = GeneralUtility::_GP('file');
+               $this->frame = GeneralUtility::_GP('frame');
+               /* For backwards compatibility the HMAC is transported within the md5 param */
+               $this->hmac = GeneralUtility::_GP('md5');
+
+               $parametersArray = GeneralUtility::_GP('parameters');
+
                // If no file-param or parameters are given, we must exit
-               if (!$this->file || !isset($parametersArray) || !is_array($parametersArray)) {
-                       \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_410);
+               if (!$fileUid || !isset($parametersArray) || !is_array($parametersArray)) {
+                       HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_410);
                }
-               $this->parametersEncoded = implode('', $parametersArray);
-               // Chech md5-checksum: If this md5-value does not match the one submitted, then we fail... (this is a kind of security that somebody don't just hit the script with a lot of different parameters
-               $md5_value = \TYPO3\CMS\Core\Utility\GeneralUtility::hmac(implode('|', array($this->file, $this->parametersEncoded)));
-               if ($md5_value !== $this->md5) {
-                       \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_410);
+
+               // rebuild the parameter array and check if the HMAC is correct
+               $parametersEncoded = implode('', $parametersArray);
+               $hmac = GeneralUtility::hmac(implode('|', array($fileUid, $parametersEncoded)));
+               if ($hmac !== $this->hmac) {
+                       HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_410);
+
                }
-               $parameters = unserialize(base64_decode($this->parametersEncoded));
+
+               // decode the parameters Array
+               $parameters = unserialize(base64_decode($parametersEncoded));
                foreach ($parameters as $parameterName => $parameterValue) {
                        $this->{$parameterName} = $parameterValue;
                }
-               // Check the file. If must be in a directory beneath the dir of this script...
-               // $this->file remains unchanged, because of the code in stdgraphic, but we do check if the file exists within the current path
-               $test_file = PATH_site . $this->file;
-               if (!\TYPO3\CMS\Core\Utility\GeneralUtility::validPathStr($test_file)) {
-                       \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_410);
-               }
-               if (!@is_file($test_file)) {
-                       \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_404);
+
+               try {
+                       if (\TYPO3\CMS\Core\Utility\MathUtility::canBeInterpretedAsInteger($fileUid)) {
+                               $this->file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObject((int)$fileUid);
+                       } else {
+                               $this->file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->retrieveFileOrFolderObject($fileUid);
+                       }
+               } catch (\TYPO3\CMS\Core\Exception $e) {
+                       HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_404);
                }
        }
 
@@ -145,58 +157,67 @@ class ShowImageController {
         * Accumulates the content in $this->content
         *
         * @return void
-        * @todo Define visibility
         */
        public function main() {
-               // Creating stdGraphic object, initialize it and make image:
-               $img = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Imaging\\GraphicalFunctions');
-               $img->mayScaleUp = 0;
-               $img->init();
-               if ($this->sample) {
-                       $img->scalecmd = '-sample';
-               }
-               if ($this->alternativeTempPath && \TYPO3\CMS\Core\Utility\GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['FE']['allowedTempPaths'], $this->alternativeTempPath)) {
-                       $img->tempPath = $this->alternativeTempPath;
+               $processedImage = $this->processImage();
+               $imageTagMarkers = array(
+                       '###publicUrl###' => $processedImage->getPublicUrl(),
+                       '###alt###' => ($this->file->getProperty('alternative') ?: $this->title),
+                       '###title###' => ($this->file->getProperty('title') ?: $this->title)
+               );
+               $this->imageTag = str_replace(array_keys($imageTagMarkers), array_values($imageTagMarkers), $this->imageTag);
+               if ($this->wrap !== '|') {
+                       $wrapParts = explode('|', $this->wrap, 2);
+                       $this->imageTag = $wrapParts[0] . $this->imageTag . $wrapParts[1];
                }
+               $markerArray = array(
+                       '###TITLE###' => ($this->file->getProperty('title') ?: $this->title),
+                       '###IMAGE###' => $this->imageTag,
+                       '###BODY###' => $this->bodyTag
+               );
+
+               $this->content = str_replace(array_keys($markerArray), array_values($markerArray), $this->content);
+
+       }
+
+       /**
+        * Does the actual image processing
+        * @return \TYPO3\CMS\Core\Resource\ProcessedFile
+        */
+       protected function processImage() {
                if (strstr($this->width . $this->height, 'm')) {
                        $max = 'm';
                } else {
                        $max = '';
                }
-               $this->height = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->height, 0);
-               $this->width = \TYPO3\CMS\Core\Utility\MathUtility::forceIntegerInRange($this->width, 0);
-               if ($this->frame) {
-                       $this->frame = (int)$this->frame;
-               }
-               $imgInfo = $img->imageMagickConvert($this->file, 'web', $this->width . $max, $this->height, $img->IMparams($this->effects), $this->frame);
-               // Create HTML output:
-               $this->content = '';
-               $this->content .= '
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+               $this->height = MathUtility::forceIntegerInRange($this->height, 0);
+               $this->width = MathUtility::forceIntegerInRange($this->width, 0) . $max;
 
-<html>
-<head>
-       <title>' . htmlspecialchars(($this->title ?: 'Image')) . '</title>
-       ' . ($this->title ? '' : '<meta name="robots" content="noindex,follow" />') . '
-</head>
-               ' . ($this->bodyTag ?: '<body>');
-               if (is_array($imgInfo)) {
-                       $wrapParts = explode('|', $this->wrap);
-                       $this->content .= trim($wrapParts[0]) . $img->imgTag($imgInfo) . trim($wrapParts[1]);
-               }
-               $this->content .= '
-               </body>
-               </html>';
-       }
+               $processingConfiguration = array(
+                       'width' => $this->width,
+                       'height' => $this->height,
+                       'frame' => $this->frame,
 
+               );
+               return $this->file->process('Image.CropScaleMask', $processingConfiguration);
+       }
        /**
         * Outputs the content from $this->content
         *
         * @return void
-        * @todo Define visibility
         */
        public function printContent() {
                echo $this->content;
+               HttpUtility::setResponseCodeAndExit(HttpUtility::HTTP_STATUS_200);
        }
 
+       /**
+        *
+        * @return void
+        */
+       public function execute() {
+               $this->init();
+               $this->main();
+               $this->printContent();
+       }
 }