‪TYPO3CMS  ‪main
AbstractFile.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
24 
28 abstract class ‪AbstractFile implements ‪FileInterface
29 {
39  protected array ‪$properties = [];
40 
46  protected ‪$storage;
47 
55  protected ‪$identifier;
56 
62  protected ‪$name;
63 
69  protected ‪$deleted = false;
70 
75  public const ‪FILETYPE_UNKNOWN = 0;
76 
82  public const ‪FILETYPE_TEXT = 1;
83 
89  public const ‪FILETYPE_IMAGE = 2;
90 
96  public const ‪FILETYPE_AUDIO = 3;
97 
103  public const ‪FILETYPE_VIDEO = 4;
104 
110  public const ‪FILETYPE_APPLICATION = 5;
111 
112  /******************
113  * VARIOUS FILE PROPERTY GETTERS
114  ******************/
120  public function ‪hasProperty(string $key): bool
121  {
122  return array_key_exists($key, $this->‪properties);
123  }
124 
130  public function ‪getProperty(string $key): mixed
131  {
132  if ($this->‪hasProperty($key)) {
133  return $this->‪properties[$key];
134  }
135  return null;
136  }
137 
143  public function getProperties()
144  {
145  return ‪$this->properties;
146  }
147 
148  public function ‪getIdentifier(): string
149  {
150  return ‪$this->identifier;
151  }
152 
156  public function ‪getHashedIdentifier(): string
157  {
158  return $this->‪properties['identifier_hash'];
159  }
160 
161  public function ‪getName(): string
162  {
163  // Do not check if file has been deleted because we might need the
164  // name for undeleting it.
165  return ‪$this->name;
166  }
167 
171  public function ‪getNameWithoutExtension(): string
172  {
173  return ‪PathUtility::pathinfo($this->‪getName(), PATHINFO_FILENAME);
174  }
175 
180  public function getSize(): int
181  {
182  if ($this->deleted) {
183  throw new \RuntimeException('File has been deleted.', 1329821480);
184  }
185  if (empty($this->‪properties['size'])) {
186  $fileInfo = $this->‪getStorage()->getFileInfoByIdentifier($this->‪getIdentifier(), ['size']);
187  ‪$size = array_pop($fileInfo);
188  } else {
189  ‪$size = $this->‪properties['size'];
190  }
192  }
193 
199  public function ‪getUid()
200  {
201  return (int)$this->‪getProperty('uid');
202  }
203 
210  public function ‪getSha1(): string
211  {
212  if ($this->deleted) {
213  throw new \RuntimeException('File has been deleted.', 1329821481);
214  }
215  return $this->‪getStorage()->hashFile($this, 'sha1');
216  }
217 
223  public function ‪getCreationTime(): int
224  {
225  if ($this->deleted) {
226  throw new \RuntimeException('File has been deleted.', 1329821487);
227  }
228  return (int)$this->‪getProperty('creation_date');
229  }
230 
236  public function ‪getModificationTime(): int
237  {
238  if ($this->deleted) {
239  throw new \RuntimeException('File has been deleted.', 1329821488);
240  }
241  return (int)$this->‪getProperty('modification_date');
242  }
243 
247  public function ‪getExtension(): string
248  {
249  $pathinfo = ‪PathUtility::pathinfo($this->‪getName());
250 
251  $extension = strtolower($pathinfo['extension'] ?? '');
252 
253  return $extension;
254  }
255 
261  public function ‪getMimeType(): string
262  {
263  if ($this->‪properties['mime_type'] ?? false) {
264  return $this->‪properties['mime_type'];
265  }
266  $fileInfo = $this->‪getStorage()->getFileInfoByIdentifier($this->‪getIdentifier(), ['mimetype']);
267  return array_pop($fileInfo);
268  }
269 
284  #[\ReturnTypeWillChange]
285  public function ‪getType()
286  {
287  // this basically extracts the mimetype and guess the filetype based
288  // on the first part of the mimetype works for 99% of all cases, and
289  // we don't need to make an SQL statement like EXT:media does currently
290  if (!($this->‪properties['type'] ?? false)) {
291  $this->‪properties['type'] = ‪FileType::tryFromMimeType($this->‪getMimeType())->value;
292  }
293  return (int)$this->‪properties['type'];
294  }
295 
296  public function ‪isType(‪FileType $fileType): bool
297  {
298  return FileType::tryFrom($this->‪getType()) === $fileType;
299  }
300 
305  public function ‪isImage(): bool
306  {
307  return ‪GeneralUtility::inList(strtolower(‪$GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] ?? ''), $this->‪getExtension()) && $this->getSize() > 0;
308  }
309 
314  public function ‪isMediaFile(): bool
315  {
316  return ‪GeneralUtility::inList(strtolower(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['mediafile_ext'] ?? ''), $this->‪getExtension()) && $this->getSize() > 0;
317  }
318 
324  public function ‪isTextFile(): bool
325  {
326  return ‪GeneralUtility::inList(strtolower(‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['textfile_ext'] ?? ''), $this->‪getExtension());
327  }
328  /******************
329  * CONTENTS RELATED
330  ******************/
336  public function ‪getContents(): string
337  {
338  if ($this->deleted) {
339  throw new \RuntimeException('File has been deleted.', 1329821479);
340  }
341  return $this->‪getStorage()->getFileContents($this);
342  }
343 
350  public function ‪setContents(string $contents): self
351  {
352  if ($this->deleted) {
353  throw new \RuntimeException('File has been deleted.', 1329821478);
354  }
355  $this->‪getStorage()->setFileContents($this, $contents);
356  return $this;
357  }
358 
359  /****************************************
360  * STORAGE AND MANAGEMENT RELATED METHODS
361  ****************************************/
362 
366  public function ‪getStorage(): ‪ResourceStorage
367  {
368  if ($this->storage === null) {
369  throw new \RuntimeException('You\'re using fileObjects without a storage.', 1381570091);
370  }
371  return ‪$this->storage;
372  }
373 
381  public function ‪exists()
382  {
383  if ($this->deleted) {
384  return false;
385  }
386  return $this->storage->hasFile($this->‪getIdentifier());
387  }
388 
396  public function ‪setStorage(ResourceStorage ‪$storage)
397  {
398  $this->storage = ‪$storage;
399  $this->‪properties['storage'] = $storage->getUid();
400  return $this;
401  }
402 
410  public function ‪setIdentifier(‪$identifier)
411  {
412  $this->identifier = ‪$identifier;
413  return $this;
414  }
415 
422  public function ‪getCombinedIdentifier()
423  {
424  if (!empty($this->‪properties['storage']) && ‪MathUtility::canBeInterpretedAsInteger($this->‪properties['storage'])) {
425  $combinedIdentifier = $this->‪properties['storage'] . ':' . $this->‪getIdentifier();
426  } else {
427  $combinedIdentifier = $this->‪getStorage()->‪getUid() . ':' . $this->‪getIdentifier();
428  }
429  return $combinedIdentifier;
430  }
431 
435  public function delete(): bool
436  {
437  // The storage will mark this file as deleted
438  $wasDeleted = $this->‪getStorage()->deleteFile($this);
439 
440  // Unset all properties when deleting the file, as they will be stale anyway
441  // This needs to happen AFTER the storage deleted the file, because the storage
442  // emits a signal, which passes the file object to the slots, which may need
443  // all file properties of the deleted file.
444  $this->‪properties = [];
445 
446  return $wasDeleted;
447  }
448 
453  public function ‪setDeleted()
454  {
455  $this->deleted = true;
456  }
457 
463  public function ‪isDeleted()
464  {
465  return ‪$this->deleted;
466  }
467 
475  public function ‪rename(string $newName, $conflictMode = ‪DuplicationBehavior::RENAME): FileInterface
476  {
477  if ($this->deleted) {
478  throw new \RuntimeException('File has been deleted.', 1329821482);
479  }
480 
481  if (!$conflictMode instanceof ‪DuplicationBehavior) {
482  trigger_error(
483  'Using a string of the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in AbstractFile->rename()'
484  . ' will stop working in TYPO3 v14.0. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
485  E_USER_DEPRECATED
486  );
487  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
488  }
489 
490  return $this->‪getStorage()->renameFile($this, $newName, $conflictMode);
491  }
492 
504  public function ‪copyTo(Folder $targetFolder, $targetFileName = null, $conflictMode = ‪DuplicationBehavior::RENAME)
505  {
506  if ($this->deleted) {
507  throw new \RuntimeException('File has been deleted.', 1329821483);
508  }
509 
510  if (!$conflictMode instanceof ‪DuplicationBehavior) {
511  trigger_error(
512  'Using a string of the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in AbstractFile->copyTo()'
513  . ' will stop working in TYPO3 v14.0. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
514  E_USER_DEPRECATED
515  );
516  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
517  }
518 
519  return $targetFolder->getStorage()->copyFile($this, $targetFolder, $targetFileName, $conflictMode);
520  }
521 
533  public function ‪moveTo(Folder $targetFolder, $targetFileName = null, $conflictMode = ‪DuplicationBehavior::RENAME)
534  {
535  if ($this->deleted) {
536  throw new \RuntimeException('File has been deleted.', 1329821484);
537  }
538 
539  if (!$conflictMode instanceof ‪DuplicationBehavior) {
540  trigger_error(
541  'Using a string of the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in AbstractFile->moveTo()'
542  . ' will stop working in TYPO3 v14.0. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
543  E_USER_DEPRECATED
544  );
545  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
546  }
547 
548  return $targetFolder->getStorage()->moveFile($this, $targetFolder, $targetFileName, $conflictMode);
549  }
550 
551  /*****************
552  * SPECIAL METHODS
553  *****************/
562  public function ‪getPublicUrl(): ?string
563  {
564  if ($this->deleted) {
565  return null;
566  }
567  return $this->‪getStorage()->‪getPublicUrl($this);
568  }
569 
580  public function ‪getForLocalProcessing(bool $writable = true): string
581  {
582  if ($this->deleted) {
583  throw new \RuntimeException('File has been deleted.', 1329821486);
584  }
585  return $this->‪getStorage()->getFileForLocalProcessing($this, $writable);
586  }
587 
588  /***********************
589  * INDEX RELATED METHODS
590  ***********************/
596  abstract public function ‪updateProperties(array ‪$properties);
597 
598  public function ‪getParentFolder(): FolderInterface
599  {
600  return $this->‪getStorage()->getFolder($this->‪getStorage()->getFolderIdentifierFromFileIdentifier($this->‪getIdentifier()));
601  }
602 }
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_UNKNOWN
‪const FILETYPE_UNKNOWN
Definition: AbstractFile.php:71
‪TYPO3\CMS\Core\Resource\AbstractFile\getType
‪int getType()
Definition: AbstractFile.php:281
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Resource\AbstractFile\$identifier
‪string $identifier
Definition: AbstractFile.php:53
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:337
‪TYPO3\CMS\Core\Resource\DuplicationBehavior
Definition: DuplicationBehavior.php:25
‪TYPO3\CMS\Core\Resource\AbstractFile\getForLocalProcessing
‪non empty string getForLocalProcessing(bool $writable=true)
Definition: AbstractFile.php:576
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_VIDEO
‪const FILETYPE_VIDEO
Definition: AbstractFile.php:99
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:26
‪TYPO3\CMS\Core\Resource\AbstractFile\exists
‪bool exists()
Definition: AbstractFile.php:377
‪TYPO3\CMS\Core\Resource\AbstractFile\getParentFolder
‪getParentFolder()
Definition: AbstractFile.php:594
‪TYPO3\CMS\Core\Resource\AbstractFile\getSha1
‪non empty string getSha1()
Definition: AbstractFile.php:206
‪TYPO3\CMS\Core\Resource\AbstractFile\getHashedIdentifier
‪non empty string getHashedIdentifier()
Definition: AbstractFile.php:152
‪TYPO3\CMS\Core\Resource\AbstractFile\getExtension
‪getExtension()
Definition: AbstractFile.php:243
‪TYPO3\CMS\Core\Resource\AbstractFile\$size
‪$size
Definition: AbstractFile.php:183
‪TYPO3\CMS\Core\Resource\AbstractFile\getName
‪getName()
Definition: AbstractFile.php:157
‪TYPO3\CMS\Core\Resource\AbstractFile\isImage
‪bool isImage()
Definition: AbstractFile.php:301
‪TYPO3\CMS\Core\Resource\AbstractFile\isDeleted
‪bool isDeleted()
Definition: AbstractFile.php:459
‪TYPO3\CMS\Core\Resource\AbstractFile\moveTo
‪File moveTo(Folder $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: AbstractFile.php:529
‪TYPO3\CMS\Core\Resource\AbstractFile\setStorage
‪$this setStorage(ResourceStorage $storage)
Definition: AbstractFile.php:392
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_IMAGE
‪const FILETYPE_IMAGE
Definition: AbstractFile.php:85
‪TYPO3\CMS\Core\Resource\AbstractFile\properties
‪array< non-empty-string, function getProperties() { return $this-> properties
Definition: AbstractFile.php:141
‪TYPO3\CMS\Core\Resource\tryFromMimeType
‪@ tryFromMimeType
Definition: FileType.php:57
‪TYPO3\CMS\Core\Resource\AbstractFile\isType
‪isType(FileType $fileType)
Definition: AbstractFile.php:292
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Core\Resource\AbstractFile\setDeleted
‪setDeleted()
Definition: AbstractFile.php:449
‪TYPO3\CMS\Core\Resource\AbstractFile\setContents
‪$this setContents(string $contents)
Definition: AbstractFile.php:346
‪TYPO3\CMS\Core\Resource\AbstractFile\rename
‪rename(string $newName, $conflictMode=DuplicationBehavior::RENAME)
Definition: AbstractFile.php:471
‪TYPO3\CMS\Core\Resource\Enum\getDefaultDuplicationBehaviour
‪@ getDefaultDuplicationBehaviour
Definition: DuplicationBehavior.php:53
‪TYPO3\CMS\Core\Resource\AbstractFile
Definition: AbstractFile.php:29
‪TYPO3\CMS\Core\Resource\AbstractFile\setIdentifier
‪$this setIdentifier($identifier)
Definition: AbstractFile.php:406
‪TYPO3\CMS\Core\Resource\File\getPublicUrl
‪getPublicUrl()
Definition: File.php:301
‪TYPO3\CMS\Core\Resource\AbstractFile\getPublicUrl
‪string null getPublicUrl()
Definition: AbstractFile.php:558
‪TYPO3\CMS\Core\Resource\AbstractFile\$deleted
‪bool $deleted
Definition: AbstractFile.php:65
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪int< 0, getSize():int { if( $this->deleted) { throw new \RuntimeException( 'File has been deleted.', 1329821480);} if(empty( $this->properties[ 'size'])) { $fileInfo=$this-> getStorage() -> getFileInfoByIdentifier($this->getIdentifier(), ['size'])
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Core\Resource\AbstractFile\getProperty
‪getProperty(string $key)
Definition: AbstractFile.php:126
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Core\Resource\AbstractFile\hasProperty
‪hasProperty(string $key)
Definition: AbstractFile.php:116
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\RENAME
‪const RENAME
Definition: DuplicationBehavior.php:33
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪getStorage()
Definition: Folder.php:139
‪TYPO3\CMS\Core\Resource\AbstractFile\copyTo
‪File copyTo(Folder $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: AbstractFile.php:500
‪TYPO3\CMS\Core\Resource\AbstractFile\getCombinedIdentifier
‪string getCombinedIdentifier()
Definition: AbstractFile.php:418
‪TYPO3\CMS\Core\Resource\AbstractFile\$name
‪string $name
Definition: AbstractFile.php:59
‪TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior
‪DuplicationBehavior
Definition: DuplicationBehavior.php:28
‪TYPO3\CMS\Core\Resource\AbstractFile\getMimeType
‪non empty string getMimeType()
Definition: AbstractFile.php:257
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_AUDIO
‪const FILETYPE_AUDIO
Definition: AbstractFile.php:92
‪TYPO3\CMS\Core\Resource\AbstractFile\getCreationTime
‪getCreationTime()
Definition: AbstractFile.php:219
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_TEXT
‪const FILETYPE_TEXT
Definition: AbstractFile.php:78
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪return MathUtility::canBeInterpretedAsInteger($size) ?(int) $size int getUid()
Definition: AbstractFile.php:195
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:128
‪TYPO3\CMS\Core\Resource\AbstractFile\getNameWithoutExtension
‪getNameWithoutExtension()
Definition: AbstractFile.php:167
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Resource\FolderInterface
Definition: FolderInterface.php:24
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Resource\AbstractFile\FILETYPE_APPLICATION
‪const FILETYPE_APPLICATION
Definition: AbstractFile.php:106
‪TYPO3\CMS\Core\Resource\AbstractFile\isTextFile
‪bool isTextFile()
Definition: AbstractFile.php:320
‪TYPO3\CMS\Core\Utility\GeneralUtility\inList
‪static bool inList($list, $item)
Definition: GeneralUtility.php:421
‪TYPO3\CMS\Core\Resource\AbstractFile\$properties
‪array $properties
Definition: AbstractFile.php:39
‪TYPO3\CMS\Core\Resource\FileType
‪FileType
Definition: FileType.php:21
‪TYPO3\CMS\Core\Resource\AbstractFile\getContents
‪getContents()
Definition: AbstractFile.php:332
‪TYPO3\CMS\Core\Resource\AbstractFile\updateProperties
‪updateProperties(array $properties)
‪TYPO3\CMS\Core\Resource\AbstractFile\$storage
‪ResourceStorage null $storage
Definition: AbstractFile.php:45
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\AbstractFile\getModificationTime
‪getModificationTime()
Definition: AbstractFile.php:232
‪TYPO3\CMS\Core\Resource\AbstractFile\isMediaFile
‪bool isMediaFile()
Definition: AbstractFile.php:310
‪TYPO3\CMS\Core\Resource\AbstractFile\getIdentifier
‪getIdentifier()
Definition: AbstractFile.php:144
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪getStorage()
Definition: AbstractFile.php:362
‪TYPO3\CMS\Core\Utility\PathUtility\pathinfo
‪static string string[] pathinfo(string $path, int $options=PATHINFO_ALL)
Definition: PathUtility.php:270