[BUGFIX] Invalid back path of ImageViewHelper in TYPO3 backend
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Service / ImageService.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Service;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Resource\FileInterface;
18 use TYPO3\CMS\Core\Resource\File;
19 use TYPO3\CMS\Core\Resource\FileReference;
20 use TYPO3\CMS\Core\Resource\ProcessedFile;
21 use TYPO3\CMS\Core\Utility\GeneralUtility;
22 use TYPO3\CMS\Core\Utility\MathUtility;
23
24 /**
25 * Service for processing images
26 */
27 class ImageService implements \TYPO3\CMS\Core\SingletonInterface {
28
29 /**
30 * @var \TYPO3\CMS\Core\Resource\ResourceFactory
31 * @inject
32 */
33 protected $resourceFactory;
34
35 /**
36 * @var \TYPO3\CMS\Extbase\Service\EnvironmentService
37 * @inject
38 */
39 protected $environmentService;
40
41 /**
42 * Create a processed file
43 *
44 * @param File|FileReference $image
45 * @param array $processingInstructions
46 * @return ProcessedFile
47 * @api
48 */
49 public function applyProcessingInstructions($image, $processingInstructions) {
50 if (is_callable(array($image, 'getOriginalFile'))) {
51 // Get the original file from the file reference
52 $image = $image->getOriginalFile();
53 }
54
55 $processedImage = $image->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $processingInstructions);
56 $this->setCompatibilityValues($processedImage);
57
58 return $processedImage;
59 }
60
61 /**
62 * Get public url of image depending on the environment
63 *
64 * @param FileInterface $image
65 * @return string
66 * @api
67 */
68 public function getImageUri(FileInterface $image) {
69 $imageUrl = $image->getPublicUrl();
70
71 // no prefix in case of an already fully qualified URL (having a schema)
72 if (strpos($imageUrl, '://')) {
73 $uriPrefix = '';
74 } elseif ($this->environmentService->isEnvironmentInFrontendMode()) {
75 $uriPrefix = $GLOBALS['TSFE']->absRefPrefix;
76 } else {
77 $uriPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
78 }
79
80 return $uriPrefix . $imageUrl;
81 }
82
83 /**
84 * Get File or FileReference object
85 *
86 * This method is a factory and compatibility method that does not belong to
87 * this service, but is put here for pragmatic reasons for the time being.
88 * It should be removed once we do not support string sources for images anymore.
89 *
90 * @param string $src
91 * @param mixed $image
92 * @param bool $treatIdAsReference
93 * @return FileInterface
94 * @throws \UnexpectedValueException
95 * @internal
96 */
97 public function getImage($src, $image, $treatIdAsReference) {
98 if (is_null($image)) {
99 $image = $this->getImageFromSourceString($src, $treatIdAsReference);
100 } elseif (is_callable(array($image, 'getOriginalResource'))) {
101 // We have a domain model, so we need to fetch the FAL resource object from there
102 $image = $image->getOriginalResource();
103 }
104
105 if (!($image instanceof File || $image instanceof FileReference)) {
106 throw new \UnexpectedValueException('Supplied file object type ' . get_class($image) . ' must be File or FileReference.', 1382687163);
107 }
108
109 return $image;
110 }
111
112 /**
113 * Get File or FileReference object by src
114 *
115 * @param string $src
116 * @param bool $treatIdAsReference
117 * @return FileInterface|FileReference|\TYPO3\CMS\Core\Resource\Folder
118 */
119 protected function getImageFromSourceString($src, $treatIdAsReference) {
120 if ($this->environmentService->isEnvironmentInBackendMode() && substr($src, 0, 3) === '../') {
121 $src = substr($src, 3);
122 }
123 if (MathUtility::canBeInterpretedAsInteger($src)) {
124 if ($treatIdAsReference) {
125 $image = $this->resourceFactory->getFileReferenceObject($src);
126 } else {
127 $image = $this->resourceFactory->getFileObject($src);
128 }
129 } else {
130 // We have a combined identifier or legacy (storage 0) path
131 $image = $this->resourceFactory->retrieveFileOrFolderObject($src);
132 }
133 return $image;
134 }
135
136 /**
137 * Set compatibility values to frontend controller object
138 * in case we are in frontend environment.
139 *
140 * @param ProcessedFile $processedImage
141 * @return void
142 */
143 protected function setCompatibilityValues(ProcessedFile $processedImage) {
144 if ($this->environmentService->isEnvironmentInFrontendMode()) {
145 $imageInfo = $this->getCompatibilityImageResourceValues($processedImage);
146 $GLOBALS['TSFE']->lastImageInfo = $imageInfo;
147 $GLOBALS['TSFE']->imagesOnPage[] = $imageInfo[3];
148 }
149 }
150
151 /**
152 * Calculates the compatibility values
153 * This is duplicate code taken from ContentObjectRenderer::getImgResource()
154 * Ideally we should get rid of this code in both places.
155 *
156 * @param ProcessedFile $processedImage
157 * @return array
158 */
159 protected function getCompatibilityImageResourceValues(ProcessedFile $processedImage) {
160 $hash = $processedImage->calculateChecksum();
161 if (isset($GLOBALS['TSFE']->tmpl->fileCache[$hash])) {
162 $compatibilityImageResourceValues = $GLOBALS['TSFE']->tmpl->fileCache[$hash];
163 } else {
164 $compatibilityImageResourceValues = array(
165 0 => $processedImage->getProperty('width'),
166 1 => $processedImage->getProperty('height'),
167 2 => $processedImage->getExtension(),
168 3 => $processedImage->getPublicUrl(),
169 'origFile' => $processedImage->getOriginalFile()->getPublicUrl(),
170 'origFile_mtime' => $processedImage->getOriginalFile()->getModificationTime(),
171 // This is needed by \TYPO3\CMS\Frontend\Imaging\GifBuilder,
172 // in order for the setup-array to create a unique filename hash.
173 'originalFile' => $processedImage->getOriginalFile(),
174 'processedFile' => $processedImage,
175 'fileCacheHash' => $hash
176 );
177 }
178 return $compatibilityImageResourceValues;
179 }
180
181 }