‪TYPO3CMS  9.5
ProcessedFile.php
Go to the documentation of this file.
1 <?php
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 
19 
42 {
43  /*********************************************
44  * FILE PROCESSING CONTEXTS
45  *********************************************/
50  const ‪CONTEXT_IMAGEPREVIEW = 'Image.Preview';
56  const ‪CONTEXT_IMAGECROPSCALEMASK = 'Image.CropScaleMask';
57 
63  protected ‪$taskType;
64 
68  protected ‪$task;
69 
73  protected ‪$taskTypeRegistry;
74 
81 
87  protected ‪$originalFile;
88 
96  protected ‪$originalFileSha1;
97 
104  protected ‪$updated = false;
105 
115  public function ‪__construct(‪File ‪$originalFile, ‪$taskType, array ‪$processingConfiguration, array $databaseRow = null)
116  {
117  $this->originalFile = ‪$originalFile;
118  $this->originalFileSha1 = $this->originalFile->‪getSha1();
120  $this->taskType = ‪$taskType;
121  $this->processingConfiguration = ‪$processingConfiguration;
122  if (is_array($databaseRow)) {
123  $this->‪reconstituteFromDatabaseRecord($databaseRow);
124  }
125  $this->taskTypeRegistry = GeneralUtility::makeInstance(Processing\TaskTypeRegistry::class);
126  }
127 
133  protected function ‪reconstituteFromDatabaseRecord(array $databaseRow)
134  {
135  $this->taskType = $this->taskType ?: $databaseRow['task_type'];
136  $this->processingConfiguration = $this->processingConfiguration ?: unserialize($databaseRow['configuration']);
137 
138  $this->originalFileSha1 = $databaseRow['originalfilesha1'];
139  $this->identifier = $databaseRow['identifier'];
140  $this->name = $databaseRow['name'];
141  $this->properties = $databaseRow;
142 
143  if (!empty($databaseRow['storage']) && (int)$this->storage->getUid() !== (int)$databaseRow['storage']) {
144  $this->storage = ‪ResourceFactory::getInstance()->‪getStorageObject($databaseRow['storage']);
145  }
146  }
147 
148  /********************************
149  * VARIOUS FILE PROPERTY GETTERS
150  ********************************/
151 
157  // @todo replace these usages with direct calls to the task object
158  public function ‪calculateChecksum()
159  {
160  return $this->‪getTask()->getConfigurationChecksum();
161  }
162 
163  /*******************
164  * CONTENTS RELATED
165  *******************/
172  public function ‪setContents($contents)
173  {
174  throw new \BadMethodCallException('Setting contents not possible for processed file.', 1305438528);
175  }
176 
183  public function ‪updateWithLocalFile($filePath)
184  {
185  if (empty($this->identifier)) {
186  throw new \RuntimeException('Cannot update original file!', 1350582054);
187  }
188  $processingFolder = $this->originalFile->getStorage()->getProcessingFolder($this->originalFile);
189  $addedFile = $this->storage->updateProcessedFile($filePath, $this, $processingFolder);
190 
191  // Update some related properties
192  $this->identifier = $addedFile->getIdentifier();
193  $this->originalFileSha1 = $this->originalFile->getSha1();
194  if ($addedFile instanceof ‪AbstractFile) {
195  $this->‪updateProperties($addedFile->getProperties());
196  }
197  $this->deleted = false;
198  $this->updated = true;
199  }
200 
201  /*****************************************
202  * STORAGE AND MANAGEMENT RELATED METHDOS
203  *****************************************/
209  public function ‪isIndexed()
210  {
211  // Processed files are never indexed; instead you might be looking for isPersisted()
212  return false;
213  }
214 
220  public function ‪isPersisted()
221  {
222  return is_array($this->properties) && array_key_exists('uid', $this->properties) && $this->properties['uid'] > 0;
223  }
224 
230  public function ‪isNew()
231  {
232  return !$this->‪isPersisted();
233  }
234 
241  public function ‪isUpdated()
242  {
243  return ‪$this->updated;
244  }
245 
251  public function ‪setName(‪$name)
252  {
253  // Remove the existing file, but only we actually have a name or the name has changed
254  if (!empty($this->name) && $this->name !== ‪$name && $this->‪exists()) {
255  $this->delete();
256  }
257 
258  $this->name = ‪$name;
259  // @todo this is a *weird* hack that will fail if the storage is non-hierarchical!
260  $this->identifier = $this->storage->getProcessingFolder($this->originalFile)->getIdentifier() . ‪$this->name;
261 
262  $this->updated = true;
263  }
264 
272  public function ‪exists()
273  {
274  if ($this->‪usesOriginalFile()) {
275  return $this->originalFile->exists();
276  }
277 
278  return parent::exists();
279  }
280 
281  /******************
282  * SPECIAL METHODS
283  ******************/
284 
290  public function ‪isProcessed()
291  {
292  return $this->updated || ($this->‪isPersisted() && !$this->‪needsReprocessing());
293  }
294 
300  public function ‪getOriginalFile()
301  {
302  return ‪$this->originalFile;
303  }
304 
314  public function ‪getIdentifier()
315  {
316  return (!$this->‪usesOriginalFile()) ? $this->identifier : $this->‪getOriginalFile()->‪getIdentifier();
317  }
318 
328  public function ‪getName()
329  {
330  if ($this->‪usesOriginalFile()) {
331  return $this->originalFile->getName();
332  }
333  return ‪$this->name;
334  }
335 
342  public function ‪updateProperties(array ‪$properties)
343  {
344  if (!is_array($this->properties)) {
345  $this->properties = [];
346  }
347 
348  if (array_key_exists('uid', ‪$properties) && ‪MathUtility::canBeInterpretedAsInteger(‪$properties['uid'])) {
349  $this->properties['uid'] = ‪$properties['uid'];
350  }
351 
352  // @todo we should have a blacklist of properties that might not be updated
353  $this->properties = array_merge($this->properties, ‪$properties);
354 
355  // @todo when should this update be done?
356  if (!$this->‪isUnchanged() && $this->‪exists()) {
357  $this->properties = array_merge($this->properties, $this->storage->getFileInfo($this));
358  }
359  }
360 
366  public function ‪toArray()
367  {
368  if ($this->‪usesOriginalFile()) {
369  ‪$properties = $this->originalFile->getProperties();
370  unset(‪$properties['uid']);
371  unset(‪$properties['pid']);
372  unset(‪$properties['identifier']);
373  unset(‪$properties['name']);
374 
375  // Use width + height set in processed file
376  ‪$properties['width'] = $this->properties['width'];
377  ‪$properties['height'] = $this->properties['height'];
378  } else {
380  ‪$properties['identifier'] = $this->‪getIdentifier();
381  ‪$properties['name'] = $this->‪getName();
382  }
383 
384  ‪$properties['configuration'] = serialize($this->processingConfiguration);
385 
386  return array_merge(‪$properties, [
387  'storage' => $this->‪getStorage()->‪getUid(),
388  'checksum' => $this->‪calculateChecksum(),
389  'task_type' => $this->taskType,
390  'configurationsha1' => sha1(‪$properties['configuration']),
391  'original' => $this->originalFile->getUid(),
392  'originalfilesha1' => $this->originalFileSha1
393  ]);
394  }
395 
401  protected function ‪isUnchanged()
402  {
403  return !$this->properties['width'] && $this->‪usesOriginalFile();
404  }
405 
409  public function ‪setUsesOriginalFile()
410  {
411  // @todo check if some of these properties can/should be set in a generic update method
412  $this->identifier = $this->originalFile->getIdentifier();
413  $this->updated = true;
414  $this->originalFileSha1 = $this->originalFile->getSha1();
415  }
416 
420  public function ‪usesOriginalFile()
421  {
422  return empty($this->identifier) || $this->identifier === $this->originalFile->getIdentifier();
423  }
424 
430  public function ‪isOutdated()
431  {
432  return $this->‪needsReprocessing();
433  }
434 
441  public function delete($force = false)
442  {
443  if (!$force && $this->‪isUnchanged()) {
444  return false;
445  }
446  // Only delete file when original isn't used
447  if (!$this->‪usesOriginalFile()) {
448  return parent::delete();
449  }
450  return true;
451  }
452 
460  public function ‪getProperty($key)
461  {
462  // The uid always (!) has to come from this file and never the original file (see getOriginalFile() to get this)
463  if ($this->‪isUnchanged() && $key !== 'uid') {
464  return $this->originalFile->getProperty($key);
465  }
466  return $this->properties[$key];
467  }
468 
474  public function ‪getUid()
475  {
476  return $this->properties['uid'];
477  }
478 
484  public function ‪needsReprocessing()
485  {
486  $fileMustBeRecreated = false;
487 
488  // if original is missing we can not reprocess the file
489  if ($this->originalFile->isMissing()) {
490  return false;
491  }
492 
493  // processedFile does not exist
494  if (!$this->‪usesOriginalFile() && !$this->‪exists()) {
495  $fileMustBeRecreated = true;
496  }
497 
498  // hash does not match
499  if (array_key_exists('checksum', $this->properties) && $this->‪calculateChecksum() !== $this->properties['checksum']) {
500  $fileMustBeRecreated = true;
501  }
502 
503  // original file changed
504  if ($this->originalFile->getSha1() !== $this->originalFileSha1) {
505  $fileMustBeRecreated = true;
506  }
507 
508  if (!array_key_exists('uid', $this->properties)) {
509  $fileMustBeRecreated = true;
510  }
511 
512  // remove outdated file
513  if ($fileMustBeRecreated && $this->‪exists()) {
514  $this->delete();
515  }
516  return $fileMustBeRecreated;
517  }
518 
524  public function ‪getProcessingConfiguration()
525  {
527  }
528 
534  public function ‪getTaskIdentifier()
535  {
536  return ‪$this->taskType;
537  }
538 
545  public function ‪getTask()
546  {
547  if ($this->task == null) {
548  $this->task = $this->taskTypeRegistry->getTaskForType($this->taskType, $this, $this->processingConfiguration);
549  }
550 
551  return ‪$this->task;
552  }
553 
560  {
561  ‪$name = $this->originalFile->getNameWithoutExtension();
562  ‪$name .= '_' . $this->originalFile->getUid();
563  ‪$name .= '_' . $this->‪calculateChecksum();
564 
565  return ‪$name;
566  }
567 
574  public function ‪getPublicUrl($relativeToCurrentScript = false)
575  {
576  if ($this->deleted) {
577  return null;
578  }
579  if ($this->‪usesOriginalFile()) {
580  return $this->‪getOriginalFile()->‪getPublicUrl($relativeToCurrentScript);
581  }
582  return $this->‪getStorage()->‪getPublicUrl($this, $relativeToCurrentScript);
583  }
584 }
‪TYPO3\CMS\Core\Resource\ProcessedFile\$taskTypeRegistry
‪Processing TaskTypeRegistry $taskTypeRegistry
Definition: ProcessedFile.php:70
‪TYPO3\CMS\Core\Resource\ProcessedFile\getOriginalFile
‪File getOriginalFile()
Definition: ProcessedFile.php:293
‪TYPO3\CMS\Core\Resource\ProcessedFile\CONTEXT_IMAGEPREVIEW
‪const CONTEXT_IMAGEPREVIEW
Definition: ProcessedFile.php:50
‪TYPO3\CMS\Core\Resource\ProcessedFile\usesOriginalFile
‪bool usesOriginalFile()
Definition: ProcessedFile.php:413
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:73
‪TYPO3\CMS\Core\Resource\ProcessedFile\getUid
‪int getUid()
Definition: ProcessedFile.php:467
‪TYPO3\CMS\Core\Resource\AbstractFile\getIdentifier
‪string getIdentifier()
Definition: AbstractFile.php:139
‪TYPO3\CMS\Core\Resource\File\getPublicUrl
‪string null getPublicUrl($relativeToCurrentScript=false)
Definition: File.php:360
‪TYPO3\CMS\Core\Resource\ResourceStorage\getPublicUrl
‪string null getPublicUrl(ResourceInterface $resourceObject, $relativeToCurrentScript=false)
Definition: ResourceStorage.php:1317
‪TYPO3\CMS\Core\Resource\Processing\TaskInterface
Definition: TaskInterface.php:31
‪TYPO3\CMS\Core\Resource\ProcessedFile\needsReprocessing
‪bool needsReprocessing()
Definition: ProcessedFile.php:477
‪TYPO3\CMS\Core\Resource\ProcessedFile\CONTEXT_IMAGECROPSCALEMASK
‪const CONTEXT_IMAGECROPSCALEMASK
Definition: ProcessedFile.php:56
‪TYPO3\CMS\Core\Resource\ResourceStorage\getProcessingFolder
‪Folder getProcessingFolder(File $file=null)
Definition: ResourceStorage.php:2999
‪TYPO3\CMS\Core\Resource\ProcessedFile\$processingConfiguration
‪array $processingConfiguration
Definition: ProcessedFile.php:76
‪TYPO3\CMS\Core\Resource\ProcessedFile\calculateChecksum
‪string calculateChecksum()
Definition: ProcessedFile.php:151
‪TYPO3\CMS\Core\Resource\ProcessedFile\isUnchanged
‪bool isUnchanged()
Definition: ProcessedFile.php:394
‪TYPO3\CMS\Core\Resource\ResourceFactory\getInstance
‪static ResourceFactory getInstance()
Definition: ResourceFactory.php:39
‪TYPO3\CMS\Core\Resource\ProcessedFile\$originalFileSha1
‪string $originalFileSha1
Definition: ProcessedFile.php:90
‪TYPO3\CMS\Core\Resource\ProcessedFile\setName
‪setName($name)
Definition: ProcessedFile.php:244
‪TYPO3\CMS\Core\Resource\ProcessedFile\exists
‪bool exists()
Definition: ProcessedFile.php:265
‪TYPO3\CMS\Core\Resource\ProcessedFile\setUsesOriginalFile
‪setUsesOriginalFile()
Definition: ProcessedFile.php:402
‪TYPO3\CMS\Core\Resource\Processing\TaskTypeRegistry
Definition: TaskTypeRegistry.php:24
‪TYPO3\CMS\Core\Resource\ProcessedFile\$updated
‪bool $updated
Definition: ProcessedFile.php:97
‪TYPO3\CMS\Core\Resource\ProcessedFile\getProcessingConfiguration
‪array getProcessingConfiguration()
Definition: ProcessedFile.php:517
‪TYPO3\CMS\Core\Resource\File\getSha1
‪string getSha1()
Definition: File.php:140
‪TYPO3\CMS\Core\Resource\ProcessedFile\generateProcessedFileNameWithoutExtension
‪string generateProcessedFileNameWithoutExtension()
Definition: ProcessedFile.php:552
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪ResourceStorage getStorage()
Definition: Folder.php:146
‪TYPO3\CMS\Core\Resource\ProcessedFile\toArray
‪array toArray()
Definition: ProcessedFile.php:359
‪TYPO3\CMS\Core\Resource\AbstractFile
Definition: AbstractFile.php:24
‪TYPO3\CMS\Core\Resource\ProcessedFile\getTaskIdentifier
‪string getTaskIdentifier()
Definition: ProcessedFile.php:527
‪TYPO3\CMS\Core\Resource\ProcessedFile\isProcessed
‪bool isProcessed()
Definition: ProcessedFile.php:283
‪TYPO3\CMS\Core\Resource\ProcessedFile\isUpdated
‪bool isUpdated()
Definition: ProcessedFile.php:234
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:23
‪TYPO3\CMS\Core\Resource\ProcessedFile\getPublicUrl
‪string null getPublicUrl($relativeToCurrentScript=false)
Definition: ProcessedFile.php:567
‪TYPO3\CMS\Core\Resource\AbstractFile\$name
‪string $name
Definition: AbstractFile.php:53
‪TYPO3\CMS\Core\Resource\ProcessedFile\setContents
‪setContents($contents)
Definition: ProcessedFile.php:165
‪TYPO3\CMS\Core\Resource\ProcessedFile\$task
‪Processing TaskInterface $task
Definition: ProcessedFile.php:66
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:37
‪TYPO3\CMS\Core\Resource\ProcessedFile\updateWithLocalFile
‪updateWithLocalFile($filePath)
Definition: ProcessedFile.php:176
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:42
‪TYPO3\CMS\Core\Resource\ProcessedFile\getProperty
‪mixed getProperty($key)
Definition: ProcessedFile.php:453
‪TYPO3\CMS\Core\Resource\ProcessedFile\getIdentifier
‪string getIdentifier()
Definition: ProcessedFile.php:307
‪TYPO3\CMS\Core\Resource\ProcessedFile\$originalFile
‪File $originalFile
Definition: ProcessedFile.php:82
‪TYPO3\CMS\Core\Resource\ProcessedFile\__construct
‪__construct(File $originalFile, $taskType, array $processingConfiguration, array $databaseRow=null)
Definition: ProcessedFile.php:108
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObject
‪ResourceStorage getStorageObject($uid, array $recordData=[], &$fileIdentifier=null)
Definition: ResourceFactory.php:131
‪TYPO3\CMS\Core\Resource\ProcessedFile\getTask
‪Processing TaskInterface getTask()
Definition: ProcessedFile.php:538
‪TYPO3\CMS\Core\Resource\ProcessedFile\reconstituteFromDatabaseRecord
‪reconstituteFromDatabaseRecord(array $databaseRow)
Definition: ProcessedFile.php:126
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:21
‪TYPO3\CMS\Core\Resource\AbstractFile\$properties
‪array $properties
Definition: AbstractFile.php:33
‪TYPO3\CMS\Core\Resource\ProcessedFile\isIndexed
‪bool isIndexed()
Definition: ProcessedFile.php:202
‪TYPO3\CMS\Core\Resource\ProcessedFile\isPersisted
‪bool isPersisted()
Definition: ProcessedFile.php:213
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:45
‪TYPO3\CMS\Core\Resource\ProcessedFile\updateProperties
‪updateProperties(array $properties)
Definition: ProcessedFile.php:335
‪TYPO3\CMS\Core\Resource\ProcessedFile\getName
‪string getName()
Definition: ProcessedFile.php:321
‪TYPO3\CMS\Core\Resource\ProcessedFile\$taskType
‪string $taskType
Definition: ProcessedFile.php:62
‪TYPO3\CMS\Core\Resource\ProcessedFile\isNew
‪bool isNew()
Definition: ProcessedFile.php:223
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪ResourceStorage getStorage()
Definition: AbstractFile.php:361
‪TYPO3\CMS\Core\Resource\ProcessedFile\isOutdated
‪bool isOutdated()
Definition: ProcessedFile.php:423