From 521b3464ce1819de9728fd3434e62d36750b3a4d Mon Sep 17 00:00:00 2001 From: Stefan Neufeind Date: Fri, 6 Jun 2014 16:10:26 +0200 Subject: [PATCH] [BUGFIX] Gifbuilder: Fix image-mask-functionality Mask-functionality is broken since the introduction of FAL. Change-Id: Iff28d9561e10f7581041bcc35bd56dfc972954b3 Resolves: #59392 Releases: 6.3, 6.2, 6.1 Reviewed-on: https://review.typo3.org/31201 Reviewed-by: Markus Klein Tested-by: Markus Klein --- .../Classes/Imaging/GraphicalFunctions.php | 4 +- .../Processing/LocalCropScaleMaskHelper.php | 12 +- .../Processing/LocalImageProcessor.php | 4 +- .../ContentObject/ContentObjectRenderer.php | 158 ++++++++++-------- .../ImageResourceContentObject.php | 9 +- .../frontend/Classes/Imaging/GifBuilder.php | 2 +- 6 files changed, 109 insertions(+), 80 deletions(-) diff --git a/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php b/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php index 1d815a67810..f642f2fb124 100644 --- a/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php +++ b/typo3/sysext/core/Classes/Imaging/GraphicalFunctions.php @@ -2282,7 +2282,7 @@ class GraphicalFunctions { * Gets the input image dimensions. * * @param string $imageFile The image filepath - * @return array Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename. + * @return array|NULL Returns an array where [0]/[1] is w/h, [2] is extension and [3] is the filename. * @see imageMagickConvert(), \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getImgResource() * @todo Define visibility */ @@ -2303,7 +2303,7 @@ class GraphicalFunctions { } } } - return FALSE; + return NULL; } /** diff --git a/typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php b/typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php index 8a059466c39..72e5d586612 100644 --- a/typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php +++ b/typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php @@ -20,12 +20,12 @@ use \TYPO3\CMS\Core\Resource, \TYPO3\CMS\Core\Utility; * Helper class to locally perform a crop/scale/mask task with the TYPO3 image processing classes. */ class LocalCropScaleMaskHelper { + /** * @var LocalImageProcessor */ protected $processor; - /** * @param LocalImageProcessor $processor */ @@ -41,8 +41,13 @@ class LocalCropScaleMaskHelper { * copies the typo3temp/ file to the processing folder of the target storage and * removes the typo3temp/ file. * + * The returned array has the following structure: + * width => 100 + * height => 200 + * filePath => /some/path + * * @param TaskInterface $task - * @return array + * @return array|NULL */ public function process(TaskInterface $task) { $result = NULL; @@ -98,7 +103,7 @@ class LocalCropScaleMaskHelper { ); if (is_array($tempFileInfo)) { $maskBottomImage = $configuration['maskImages']['maskBottomImage']; - if ($maskBottomImage instanceof $maskBottomImage) { + if ($maskBottomImage instanceof Resource\FileInterface) { $maskBottomImageMask = $configuration['maskImages']['maskBottomImageMask']; } else { $maskBottomImageMask = NULL; @@ -127,6 +132,7 @@ class LocalCropScaleMaskHelper { } // The image onto the background $gifBuilder->combineExec($tempScale['m_bgImg'], $tempFileInfo[3], $tempScale['m_mask'], $temporaryFileName); + $tempFileInfo[3] = $temporaryFileName; // Unlink the temp-images... foreach ($tempScale as $tempFile) { if (@is_file($tempFile)) { diff --git a/typo3/sysext/core/Classes/Resource/Processing/LocalImageProcessor.php b/typo3/sysext/core/Classes/Resource/Processing/LocalImageProcessor.php index e10a7bb3c16..99214dabe7c 100644 --- a/typo3/sysext/core/Classes/Resource/Processing/LocalImageProcessor.php +++ b/typo3/sysext/core/Classes/Resource/Processing/LocalImageProcessor.php @@ -65,9 +65,7 @@ class LocalImageProcessor implements ProcessorInterface { $task->getTargetFile()->setUsesOriginalFile(); } elseif (file_exists($result['filePath'])) { $task->setExecuted(TRUE); - $graphicalFunctions = $this->getGraphicalFunctionsObject(); - $imageDimensions = $graphicalFunctions->getImageDimensions($result['filePath']); - + $imageDimensions = $this->getGraphicalFunctionsObject()->getImageDimensions($result['filePath']); $task->getTargetFile()->setName($task->getTargetFileName()); $task->getTargetFile()->updateProperties( array('width' => $imageDimensions[0], 'height' => $imageDimensions[1], 'size' => filesize($result['filePath']), 'checksum' => $task->getConfigurationChecksum()) diff --git a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php index 8b6590d2077..2334f689c40 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php +++ b/typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php @@ -16,6 +16,7 @@ namespace TYPO3\CMS\Frontend\ContentObject; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Versioning\VersionState; +use TYPO3\CMS\Frontend\Imaging\GifBuilder; /** * This class contains all main TypoScript features. @@ -1262,51 +1263,52 @@ class ContentObjectRenderer { public function cImage($file, $conf) { $info = $this->getImgResource($file, $conf['file.']); $GLOBALS['TSFE']->lastImageInfo = $info; - if (is_array($info)) { - if (is_file(PATH_site . $info['3'])) { - $source = GeneralUtility::rawUrlEncodeFP(GeneralUtility::png_to_gif_by_imagemagick($info[3])); - $source = $GLOBALS['TSFE']->absRefPrefix . $source; - } else { - $source = $info[3]; - } - - $layoutKey = $this->stdWrap($conf['layoutKey'], $conf['layoutKey.']); - $imageTagTemplate = $this->getImageTagTemplate($layoutKey, $conf); - $sourceCollection = $this->getImageSourceCollection($layoutKey, $conf, $file); - - // This array is used to collect the image-refs on the page... - $GLOBALS['TSFE']->imagesOnPage[] = $source; - $altParam = $this->getAltParam($conf); - $params = $this->stdWrapValue('params', $conf); - if ($params !== '' && $params{0} !== ' ') { - $params = ' ' . $params; - } - - $imageTagValues = array( - 'width' => $info[0], - 'height' => $info[1], - 'src' => htmlspecialchars($source), - 'params' => $params, - 'altParams' => $altParam, - 'border' => $this->getBorderAttr(' border="' . (int)$conf['border'] . '"'), - 'sourceCollection' => $sourceCollection, - 'selfClosingTagSlash' => (!empty($GLOBALS['TSFE']->xhtmlDoctype) ? ' /' : ''), - ); + if (!is_array($info)) { + return ''; + } + if (is_file(PATH_site . $info['3'])) { + $source = GeneralUtility::rawUrlEncodeFP(GeneralUtility::png_to_gif_by_imagemagick($info[3])); + $source = $GLOBALS['TSFE']->absRefPrefix . $source; + } else { + $source = $info[3]; + } + + $layoutKey = $this->stdWrap($conf['layoutKey'], $conf['layoutKey.']); + $imageTagTemplate = $this->getImageTagTemplate($layoutKey, $conf); + $sourceCollection = $this->getImageSourceCollection($layoutKey, $conf, $file); + + // This array is used to collect the image-refs on the page... + $GLOBALS['TSFE']->imagesOnPage[] = $source; + $altParam = $this->getAltParam($conf); + $params = $this->stdWrapValue('params', $conf); + if ($params !== '' && $params{0} !== ' ') { + $params = ' ' . $params; + } + + $imageTagValues = array( + 'width' => $info[0], + 'height' => $info[1], + 'src' => htmlspecialchars($source), + 'params' => $params, + 'altParams' => $altParam, + 'border' => $this->getBorderAttr(' border="' . (int)$conf['border'] . '"'), + 'sourceCollection' => $sourceCollection, + 'selfClosingTagSlash' => (!empty($GLOBALS['TSFE']->xhtmlDoctype) ? ' /' : ''), + ); - $theValue = $this->substituteMarkerArray($imageTagTemplate, $imageTagValues, '###|###', TRUE, TRUE); + $theValue = $this->substituteMarkerArray($imageTagTemplate, $imageTagValues, '###|###', TRUE, TRUE); - $linkWrap = isset($conf['linkWrap.']) ? $this->stdWrap($conf['linkWrap'], $conf['linkWrap.']) : $conf['linkWrap']; - if ($linkWrap) { - $theValue = $this->linkWrap($theValue, $linkWrap); - } elseif ($conf['imageLinkWrap']) { - $theValue = $this->imageLinkWrap($theValue, $info['originalFile'], $conf['imageLinkWrap.']); - } - $wrap = isset($conf['wrap.']) ? $this->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap']; - if ($wrap) { - $theValue = $this->wrap($theValue, $conf['wrap']); - } - return $theValue; + $linkWrap = isset($conf['linkWrap.']) ? $this->stdWrap($conf['linkWrap'], $conf['linkWrap.']) : $conf['linkWrap']; + if ($linkWrap) { + $theValue = $this->linkWrap($theValue, $linkWrap); + } elseif ($conf['imageLinkWrap']) { + $theValue = $this->imageLinkWrap($theValue, $info['originalFile'], $conf['imageLinkWrap.']); } + $wrap = isset($conf['wrap.']) ? $this->stdWrap($conf['wrap'], $conf['wrap.']) : $conf['wrap']; + if ($wrap) { + $theValue = $this->wrap($theValue, $conf['wrap']); + } + return $theValue; } /** @@ -1405,28 +1407,29 @@ class ContentObjectRenderer { } } $sourceInfo = $this->getImgResource($sourceRenderConfiguration['file'], $sourceRenderConfiguration['file.']); - $sourceConfiguration['width'] = $sourceInfo[0]; - $sourceConfiguration['height'] = $sourceInfo[1]; - $sourceConfiguration['src'] = htmlspecialchars($sourceInfo[3]); - $sourceConfiguration['selfClosingTagSlash'] = (!empty($GLOBALS['TSFE']->xhtmlDoctype) ? ' /' : ''); - - $oneSourceCollection = $this->substituteMarkerArray($sourceLayout, $sourceConfiguration, '###|###', TRUE, TRUE); - - if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'])) { - foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'] as $classData) { - $hookObject = GeneralUtility::getUserObj($classData); - if (!$hookObject instanceof ContentObjectOneSourceCollectionHookInterface) { - throw new \UnexpectedValueException( - '$hookObject must implement interface TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectOneSourceCollectionHookInterface', - 1380007853 - ); + if ($sourceInfo) { + $sourceConfiguration['width'] = $sourceInfo[0]; + $sourceConfiguration['height'] = $sourceInfo[1]; + $sourceConfiguration['src'] = htmlspecialchars($sourceInfo[3]); + $sourceConfiguration['selfClosingTagSlash'] = (!empty($GLOBALS['TSFE']->xhtmlDoctype) ? ' /' : ''); + + $oneSourceCollection = $this->substituteMarkerArray($sourceLayout, $sourceConfiguration, '###|###', TRUE, TRUE); + + if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'])) { + foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_content.php']['getImageSourceCollection'] as $classData) { + $hookObject = GeneralUtility::getUserObj($classData); + if (!$hookObject instanceof ContentObjectOneSourceCollectionHookInterface) { + throw new \UnexpectedValueException( + '$hookObject must implement interface TYPO3\\CMS\\Frontend\\ContentObject\\ContentObjectOneSourceCollectionHookInterface', + 1380007853 + ); + } + $oneSourceCollection = $hookObject->getOneSourceCollection((array) $sourceRenderConfiguration, (array) $sourceConfiguration, $oneSourceCollection, $this); } - /** @var $hookObject \TYPO3\CMS\Frontend\ContentObject\ContentObjectGetSingleHookInterface */ - $oneSourceCollection = $hookObject->getOneSourceCollection((array) $sourceRenderConfiguration, (array) $sourceConfiguration, $oneSourceCollection, $this); } - } - $sourceCollection .= $oneSourceCollection; + $sourceCollection .= $oneSourceCollection; + } } } return $sourceCollection; @@ -5190,11 +5193,22 @@ class ContentObjectRenderer { * In the latter case a GIFBUILDER image is returned; This means an image is made by TYPO3 from layers of elements as GIFBUILDER defines. * In the function IMG_RESOURCE() this function is called like $this->getImgResource($conf['file'], $conf['file.']); * + * Structure of the returned info array: + * 0 => width + * 1 => height + * 2 => file extension + * 3 => file name + * origFile => original file name + * origFile_mtime => original file mtime + * -- only available if processed via FAL: -- + * originalFile => original file object + * processedFile => processed file object + * fileCacheHash => checksum of processed file + * * @param string|\TYPO3\CMS\Core\Resource\File|\TYPO3\CMS\Core\Resource\FileReference $file A "imgResource" TypoScript data type. Either a TypoScript file resource, a file or a file reference object or the string GIFBUILDER. See description above. * @param array $fileArray TypoScript properties for the imgResource type - * @return array Returns info-array. info[origFile] = original file. [0]/[1] is w/h, [2] is file extension and [3] is the filename. + * @return array|NULL Returns info-array * @see IMG_RESOURCE(), cImage(), \TYPO3\CMS\Frontend\Imaging\GifBuilder - * @todo Define visibility */ public function getImgResource($file, $fileArray) { if (!is_array($fileArray)) { @@ -5202,6 +5216,7 @@ class ContentObjectRenderer { } $imageResource = NULL; if ($file === 'GIFBUILDER') { + /** @var GifBuilder $gifCreator */ $gifCreator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Imaging\\GifBuilder'); $gifCreator->init(); $theImage = ''; @@ -5247,7 +5262,7 @@ class ContentObjectRenderer { return NULL; } } - if ($fileObject instanceof \TYPO3\CMS\Core\Resource\FileInterface) { + if ($fileObject instanceof \TYPO3\CMS\Core\Resource\File) { $processingConfiguration = array(); $processingConfiguration['width'] = isset($fileArray['width.']) ? $this->stdWrap($fileArray['width'], $fileArray['width.']) : $fileArray['width']; $processingConfiguration['height'] = isset($fileArray['height.']) ? $this->stdWrap($fileArray['height'], $fileArray['height.']) : $fileArray['height']; @@ -5269,10 +5284,15 @@ class ContentObjectRenderer { // Must render mask images and include in hash-calculating // - otherwise we cannot be sure the filename is unique for the setup! if (is_array($maskArray)) { - $processingConfiguration['maskImages']['m_mask'] = $this->getImgResource($maskArray['mask'], $maskArray['mask.']); - $processingConfiguration['maskImages']['m_bgImg'] = $this->getImgResource($maskArray['bgImg'], $maskArray['bgImg.']); - $processingConfiguration['maskImages']['m_bottomImg'] = $this->getImgResource($maskArray['bottomImg'], $maskArray['bottomImg.']); - $processingConfiguration['maskImages']['m_bottomImg_mask'] = $this->getImgResource($maskArray['bottomImg_mask'], $maskArray['bottomImg_mask.']); + $mask = $this->getImgResource($maskArray['mask'], $maskArray['mask.']); + $bgImg = $this->getImgResource($maskArray['bgImg'], $maskArray['bgImg.']); + $bottomImg = $this->getImgResource($maskArray['bottomImg'], $maskArray['bottomImg.']); + $bottomImg_mask = $this->getImgResource($maskArray['bottomImg_mask'], $maskArray['bottomImg_mask.']); + + $processingConfiguration['maskImages']['maskImage'] = $mask['processedFile']; + $processingConfiguration['maskImages']['backgroundImage'] = $bgImg['processedFile']; + $processingConfiguration['maskImages']['maskBottomImage'] = $bottomImg['processedFile']; + $processingConfiguration['maskImages']['maskBottomImageMask'] = $bottomImg_mask['processedFile']; } if ($GLOBALS['TSFE']->config['config']['meaningfulTempFilePrefix']) { $processingConfiguration['useTargetFileNameAsPrefix'] = 1; @@ -5305,7 +5325,7 @@ class ContentObjectRenderer { $theImage = $GLOBALS['TSFE']->tmpl->getFileName($file); if ($theImage) { $gifCreator = GeneralUtility::makeInstance('TYPO3\\CMS\\Frontend\\Imaging\\GifBuilder'); - /** @var $gifCreator \TYPO3\CMS\Frontend\Imaging\GifBuilder */ + /** @var $gifCreator GifBuilder */ $gifCreator->init(); $info = $gifCreator->imageMagickConvert($theImage, 'WEB'); $info['origFile'] = $theImage; diff --git a/typo3/sysext/frontend/Classes/ContentObject/ImageResourceContentObject.php b/typo3/sysext/frontend/Classes/ContentObject/ImageResourceContentObject.php index b1bdc20cd59..167a250bc4e 100644 --- a/typo3/sysext/frontend/Classes/ContentObject/ImageResourceContentObject.php +++ b/typo3/sysext/frontend/Classes/ContentObject/ImageResourceContentObject.php @@ -29,8 +29,13 @@ class ImageResourceContentObject extends \TYPO3\CMS\Frontend\ContentObject\Abstr */ public function render($conf = array()) { $GLOBALS['TSFE']->lastImgResourceInfo = $this->cObj->getImgResource($conf['file'], $conf['file.']); - $imageResource = $GLOBALS['TSFE']->lastImgResourceInfo[3]; - $theValue = isset($conf['stdWrap.']) ? $this->cObj->stdWrap($imageResource, $conf['stdWrap.']) : $imageResource; + if ($GLOBALS['TSFE']->lastImgResourceInfo) { + $imageResource = $GLOBALS['TSFE']->lastImgResourceInfo[3]; + $theValue = isset($conf['stdWrap.']) ? $this->cObj->stdWrap($imageResource, $conf['stdWrap.']) : $imageResource; + } else { + $theValue = ''; + } + return $theValue; } diff --git a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php index 86a00f83eeb..9d13e6c7351 100644 --- a/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php +++ b/typo3/sysext/frontend/Classes/Imaging/GifBuilder.php @@ -645,7 +645,7 @@ class GifBuilder extends \TYPO3\CMS\Core\Imaging\GraphicalFunctions { * * @param string $file Filename value OR the string "GIFBUILDER", see documentation in TSref for the "datatype" called "imgResource * @param array $fileArray TypoScript properties passed to the function. Either GIFBUILDER properties or imgResource properties, depending on the value of $file (whether that is "GIFBUILDER" or a file reference) - * @return array Returns an array with file information if an image was returned. Otherwise FALSE. + * @return array|NULL Returns an array with file information from ContentObjectRenderer::getImgResource() * @access private * @see \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::getImgResource() * @todo Define visibility -- 2.20.1