[TASK] Do not generate new processed file if it already exists
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Resource / Processing / LocalImageProcessor.php
1 <?php
2 namespace TYPO3\CMS\Core\Resource\Processing;
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\Utility\GeneralUtility;
18
19 /**
20 * Processes Local Images files
21 */
22 class LocalImageProcessor implements ProcessorInterface {
23
24 /**
25 * @var \TYPO3\CMS\Core\Log\Logger
26 */
27 protected $logger;
28
29 /**
30 * Constructor
31 */
32 public function __construct() {
33 /** @var $logManager \TYPO3\CMS\Core\Log\LogManager */
34 $logManager = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Log\LogManager::class);
35 $this->logger = $logManager->getLogger(__CLASS__);
36 }
37
38 /**
39 * Returns TRUE if this processor can process the given task.
40 *
41 * @param TaskInterface $task
42 * @return bool
43 */
44 public function canProcessTask(TaskInterface $task) {
45 $canProcessTask = $task->getType() === 'Image';
46 $canProcessTask = $canProcessTask & in_array($task->getName(), array('Preview', 'CropScaleMask'));
47 return $canProcessTask;
48 }
49
50 /**
51 * Processes the given task.
52 *
53 * @param TaskInterface $task
54 * @throws \InvalidArgumentException
55 */
56 public function processTask(TaskInterface $task) {
57 if (!$this->canProcessTask($task)) {
58 throw new \InvalidArgumentException('Cannot process task of type "' . $task->getType() . '.' . $task->getName() . '"', 1350570621);
59 }
60 if ($this->checkForExistingTargetFile($task)) {
61 return;
62 }
63 $helper = $this->getHelperByTaskName($task->getName());
64 try {
65 $result = $helper->process($task);
66 if ($result === NULL) {
67 $task->setExecuted(TRUE);
68 $task->getTargetFile()->setUsesOriginalFile();
69 } elseif (!empty($result['filePath']) && file_exists($result['filePath'])) {
70 $task->setExecuted(TRUE);
71 $imageDimensions = $this->getGraphicalFunctionsObject()->getImageDimensions($result['filePath']);
72 $task->getTargetFile()->setName($task->getTargetFileName());
73 $task->getTargetFile()->updateProperties(
74 array('width' => $imageDimensions[0], 'height' => $imageDimensions[1], 'size' => filesize($result['filePath']), 'checksum' => $task->getConfigurationChecksum())
75 );
76 $task->getTargetFile()->updateWithLocalFile($result['filePath']);
77
78 // New dimensions + no new file (for instance svg)
79 } elseif (!empty($result['width']) && !empty($result['height']) && empty($result['filePath'])) {
80 $task->setExecuted(TRUE);
81 $task->getTargetFile()->setUsesOriginalFile();
82 $task->getTargetFile()->updateProperties(
83 array('width' => $result['width'], 'height' => $result['height'], 'size' => $task->getSourceFile()->getSize(), 'checksum' => $task->getConfigurationChecksum())
84 );
85
86 // Seems we have no valid processing result
87 } else {
88 $task->setExecuted(FALSE);
89 }
90 } catch (\Exception $e) {
91 $task->setExecuted(FALSE);
92 }
93 }
94
95 /**
96 * Check if the to be processed target file already exists
97 * if exist take info from that file and mark task as done
98 *
99 * @param TaskInterface $task
100 * @return bool
101 */
102 protected function checkForExistingTargetFile(TaskInterface $task) {
103 $processingFolder = $task->getTargetFile()->getStorage()->getProcessingFolder();
104 $storage = $task->getTargetFile()->getStorage();
105 // @todo: make proper use of the FAL API, see https://forge.typo3.org/issues/67126
106 if ($processingFolder->hasFile($task->getTargetFileName()) && $storage->getDriverType() === 'Local') {
107 $processedFileIdentifier = rtrim($processingFolder->getIdentifier(), '/') . '/' . $task->getTargetFileName();
108 $configuration = $storage->getConfiguration();
109 if ($configuration['pathType'] === 'relative') {
110 $absoluteBasePath = PATH_site . $configuration['basePath'];
111 } else {
112 $absoluteBasePath = $configuration['basePath'];
113 }
114 $targetFile = $absoluteBasePath . ltrim($processedFileIdentifier, '/');
115
116 $task->setExecuted(TRUE);
117 $imageDimensions = $this->getGraphicalFunctionsObject()->getImageDimensions($targetFile);
118 $task->getTargetFile()->setName($task->getTargetFileName());
119 $properties = array(
120 'width' => $imageDimensions[0],
121 'height' => $imageDimensions[1],
122 'size' => filesize($targetFile),
123 'checksum' => $task->getConfigurationChecksum()
124 );
125 $task->getTargetFile()->updateProperties($properties);
126
127 return TRUE;
128 } else {
129 return FALSE;
130 }
131 }
132
133 /**
134 * @param string $taskName
135 * @return LocalCropScaleMaskHelper|LocalPreviewHelper
136 * @throws \InvalidArgumentException
137 */
138 protected function getHelperByTaskName($taskName) {
139 switch ($taskName) {
140 case 'Preview':
141 $helper = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Processing\LocalPreviewHelper::class, $this);
142 break;
143 case 'CropScaleMask':
144 $helper = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Resource\Processing\LocalCropScaleMaskHelper::class, $this);
145 break;
146 default:
147 throw new \InvalidArgumentException('Cannot find helper for task name: "' . $taskName . '"', 1353401352);
148 }
149
150 return $helper;
151 }
152
153 /**
154 * Creates error image based on gfx/notfound_thumb.png
155 * Requires GD lib enabled, otherwise it will exit with the three
156 * textstrings outputted as text. Outputs the image stream to browser and exits!
157 *
158 * @param string $filename Name of the file
159 * @param string $textline1 Text line 1
160 * @param string $textline2 Text line 2
161 * @param string $textline3 Text line 3
162 * @return void
163 * @throws \RuntimeException
164 *
165 * @deprecated since TYPO3 CMS 7, will be removed in TYPO3 CMS 8. Use \TYPO3\CMS\Core\Imaging\GraphicalFunctions::getTemporaryImageWithText() instead.
166 */
167 public function getTemporaryImageWithText($filename, $textline1, $textline2, $textline3) {
168 GeneralUtility::logDeprecatedFunction();
169 $graphicalFunctions = $this->getGraphicalFunctionsObject();
170 $graphicalFunctions->getTemporaryImageWithText($filename, $textline1, $textline2, $textline3);
171 }
172
173 /**
174 * @return \TYPO3\CMS\Core\Imaging\GraphicalFunctions
175 */
176 protected function getGraphicalFunctionsObject() {
177 static $graphicalFunctionsObject = NULL;
178
179 if ($graphicalFunctionsObject === NULL) {
180 $graphicalFunctionsObject = GeneralUtility::makeInstance(\TYPO3\CMS\Core\Imaging\GraphicalFunctions::class);
181 }
182
183 return $graphicalFunctionsObject;
184 }
185
186 }