[TASK] Streamline phpdoc annotations in EXT:extbase
[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\LinkHandling\LinkService;
18 use TYPO3\CMS\Core\Resource\File;
19 use TYPO3\CMS\Core\Resource\FileInterface;
20 use TYPO3\CMS\Core\Resource\FileReference;
21 use TYPO3\CMS\Core\Resource\ProcessedFile;
22 use TYPO3\CMS\Core\Resource\ResourceFactory;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\CMS\Core\Utility\MathUtility;
25
26 /**
27 * Service for processing images
28 */
29 class ImageService implements \TYPO3\CMS\Core\SingletonInterface
30 {
31 /**
32 * @var ResourceFactory
33 */
34 protected $resourceFactory;
35
36 /**
37 * @var EnvironmentService
38 */
39 protected $environmentService;
40
41 /**
42 * ImageService constructor.
43 *
44 * @param EnvironmentService|null $environmentService
45 * @param ResourceFactory|null $resourceFactory
46 */
47 public function __construct(EnvironmentService $environmentService = null, ResourceFactory $resourceFactory = null)
48 {
49 $this->environmentService = $environmentService ?? GeneralUtility::makeInstance(EnvironmentService::class);
50 $this->resourceFactory = $resourceFactory ?? ResourceFactory::getInstance();
51 }
52
53 /**
54 * Create a processed file
55 *
56 * @param FileInterface|FileReference $image
57 * @param array $processingInstructions
58 * @return ProcessedFile
59 */
60 public function applyProcessingInstructions($image, $processingInstructions)
61 {
62 if (is_callable([$image, 'getOriginalFile'])) {
63 // Get the original file from the file reference
64 $image = $image->getOriginalFile();
65 }
66
67 $processedImage = $image->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $processingInstructions);
68 $this->setCompatibilityValues($processedImage);
69
70 return $processedImage;
71 }
72
73 /**
74 * Get public url of image depending on the environment
75 *
76 * @param FileInterface $image
77 * @param bool|false $absolute Force absolute URL
78 * @return string
79 */
80 public function getImageUri(FileInterface $image, $absolute = false)
81 {
82 $imageUrl = $image->getPublicUrl();
83 $parsedUrl = parse_url($imageUrl);
84 // no prefix in case of an already fully qualified URL
85 if (isset($parsedUrl['host'])) {
86 $uriPrefix = '';
87 } elseif ($this->environmentService->isEnvironmentInFrontendMode()) {
88 $uriPrefix = $GLOBALS['TSFE']->absRefPrefix;
89 } else {
90 $uriPrefix = GeneralUtility::getIndpEnv('TYPO3_SITE_PATH');
91 }
92
93 if ($absolute) {
94 // If full URL has no scheme we add the same scheme as used by the site
95 // so we have an absolute URL also usable outside of browser scope (e.g. in an email message)
96 if (isset($parsedUrl['host']) && !isset($parsedUrl['scheme'])) {
97 $uriPrefix = (GeneralUtility::getIndpEnv('TYPO3_SSL') ? 'https:' : 'http:') . $uriPrefix;
98 }
99 return GeneralUtility::locationHeaderUrl($uriPrefix . $imageUrl);
100 }
101 return $uriPrefix . $imageUrl;
102 }
103
104 /**
105 * Get File or FileReference object
106 *
107 * This method is a factory and compatibility method that does not belong to
108 * this service, but is put here for pragmatic reasons for the time being.
109 * It should be removed once we do not support string sources for images anymore.
110 *
111 * @param string $src
112 * @param mixed $image
113 * @param bool $treatIdAsReference
114 * @return FileInterface|FileReference
115 * @throws \UnexpectedValueException
116 * @internal
117 */
118 public function getImage($src, $image, $treatIdAsReference)
119 {
120 if ($image === null) {
121 $image = $this->getImageFromSourceString($src, $treatIdAsReference);
122 } elseif (is_callable([$image, 'getOriginalResource'])) {
123 // We have a domain model, so we need to fetch the FAL resource object from there
124 $image = $image->getOriginalResource();
125 }
126
127 if (!($image instanceof File || $image instanceof FileReference)) {
128 $class = is_object($image) ? get_class($image) : 'null';
129 throw new \UnexpectedValueException('Supplied file object type ' . $class . ' for ' . $src . ' must be File or FileReference.', 1382687163);
130 }
131
132 return $image;
133 }
134
135 /**
136 * Get File or FileReference object by src
137 *
138 * @param string $src
139 * @param bool $treatIdAsReference
140 * @return FileInterface|FileReference|\TYPO3\CMS\Core\Resource\Folder
141 */
142 protected function getImageFromSourceString($src, $treatIdAsReference)
143 {
144 if ($this->environmentService->isEnvironmentInBackendMode() && strpos($src, '../') === 0) {
145 $src = substr($src, 3);
146 }
147 if (MathUtility::canBeInterpretedAsInteger($src)) {
148 if ($treatIdAsReference) {
149 $image = $this->resourceFactory->getFileReferenceObject($src);
150 } else {
151 $image = $this->resourceFactory->getFileObject($src);
152 }
153 } elseif (strpos($src, 't3://file') === 0) {
154 // We have a t3://file link to a file in FAL
155 $linkService = GeneralUtility::makeInstance(LinkService::class);
156 $data = $linkService->resolveByStringRepresentation($src);
157 $image = $data['file'];
158 } else {
159 // We have a combined identifier or legacy (storage 0) path
160 $image = $this->resourceFactory->retrieveFileOrFolderObject($src);
161 }
162 return $image;
163 }
164
165 /**
166 * Set compatibility values to frontend controller object
167 * in case we are in frontend environment.
168 *
169 * @param ProcessedFile $processedImage
170 */
171 protected function setCompatibilityValues(ProcessedFile $processedImage)
172 {
173 if ($this->environmentService->isEnvironmentInFrontendMode()) {
174 $GLOBALS['TSFE']->lastImageInfo = $this->getCompatibilityImageResourceValues($processedImage);
175 $GLOBALS['TSFE']->imagesOnPage[] = $processedImage->getPublicUrl();
176 }
177 }
178
179 /**
180 * Calculates the compatibility values
181 * This is duplicate code taken from ContentObjectRenderer::getImgResource()
182 * Ideally we should get rid of this code in both places.
183 *
184 * @param ProcessedFile $processedImage
185 * @return array
186 */
187 protected function getCompatibilityImageResourceValues(ProcessedFile $processedImage)
188 {
189 return [
190 0 => $processedImage->getProperty('width'),
191 1 => $processedImage->getProperty('height'),
192 2 => $processedImage->getExtension(),
193 3 => $processedImage->getPublicUrl(),
194 'origFile' => $processedImage->getOriginalFile()->getPublicUrl(),
195 'origFile_mtime' => $processedImage->getOriginalFile()->getModificationTime(),
196 // This is needed by \TYPO3\CMS\Frontend\Imaging\GifBuilder,
197 // in order for the setup-array to create a unique filename hash.
198 'originalFile' => $processedImage->getOriginalFile(),
199 'processedFile' => $processedImage
200 ];
201 }
202 }