TYPO3 CMS  TYPO3_8-7
AbstractFile.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 
23 abstract class AbstractFile implements FileInterface
24 {
34  protected $properties;
35 
41  protected $storage = null;
42 
50  protected $identifier;
51 
57  protected $name;
58 
64  protected $deleted = false;
65 
69  const FILETYPE_UNKNOWN = 0;
70 
75  const FILETYPE_TEXT = 1;
76 
81  const FILETYPE_IMAGE = 2;
82 
87  const FILETYPE_AUDIO = 3;
88 
93  const FILETYPE_VIDEO = 4;
94 
100 
101  /******************
102  * VARIOUS FILE PROPERTY GETTERS
103  ******************/
110  public function hasProperty($key)
111  {
112  return array_key_exists($key, $this->properties);
113  }
114 
121  public function getProperty($key)
122  {
123  if ($this->hasProperty($key)) {
124  return $this->properties[$key];
125  }
126  return null;
127  }
128 
134  public function getProperties()
135  {
136  return $this->properties;
137  }
138 
144  public function getIdentifier()
145  {
146  return $this->identifier;
147  }
148 
154  public function getHashedIdentifier()
155  {
156  return $this->properties['identifier_hash'];
157  }
158 
164  public function getName()
165  {
166  // Do not check if file has been deleted because we might need the
167  // name for undeleting it.
168  return $this->name;
169  }
170 
176  public function getNameWithoutExtension()
177  {
178  return PathUtility::pathinfo($this->getName(), PATHINFO_FILENAME);
179  }
180 
187  public function getSize()
188  {
189  if ($this->deleted) {
190  throw new \RuntimeException('File has been deleted.', 1329821480);
191  }
192  if (empty($this->properties['size'])) {
193  $size = array_pop($this->getStorage()->getFileInfoByIdentifier($this->getIdentifier(), ['size']));
194  } else {
195  $size = $this->properties['size'];
196  }
197  return $size ? (int)$size : null;
198  }
199 
205  public function getUid()
206  {
207  return (int)$this->getProperty('uid');
208  }
209 
216  public function getSha1()
217  {
218  if ($this->deleted) {
219  throw new \RuntimeException('File has been deleted.', 1329821481);
220  }
221  return $this->getStorage()->hashFile($this, 'sha1');
222  }
223 
230  public function getCreationTime()
231  {
232  if ($this->deleted) {
233  throw new \RuntimeException('File has been deleted.', 1329821487);
234  }
235  return (int)$this->getProperty('creation_date');
236  }
237 
244  public function getModificationTime()
245  {
246  if ($this->deleted) {
247  throw new \RuntimeException('File has been deleted.', 1329821488);
248  }
249  return (int)$this->getProperty('modification_date');
250  }
251 
257  public function getExtension()
258  {
259  $pathinfo = PathUtility::pathinfo($this->getName());
260 
261  $extension = strtolower($pathinfo['extension']);
262 
263  return $extension;
264  }
265 
271  public function getMimeType()
272  {
273  return $this->properties['mime_type'] ?: array_pop($this->getStorage()->getFileInfoByIdentifier($this->getIdentifier(), ['mimetype']));
274  }
275 
289  public function getType()
290  {
291  // this basically extracts the mimetype and guess the filetype based
292  // on the first part of the mimetype works for 99% of all cases, and
293  // we don't need to make an SQL statement like EXT:media does currently
294  if (!$this->properties['type']) {
295  $mimeType = $this->getMimeType();
296  list($fileType) = explode('/', $mimeType);
297  switch (strtolower($fileType)) {
298  case 'text':
299  $this->properties['type'] = self::FILETYPE_TEXT;
300  break;
301  case 'image':
302  $this->properties['type'] = self::FILETYPE_IMAGE;
303  break;
304  case 'audio':
305  $this->properties['type'] = self::FILETYPE_AUDIO;
306  break;
307  case 'video':
308  $this->properties['type'] = self::FILETYPE_VIDEO;
309  break;
310  case 'application':
311 
312  case 'software':
313  $this->properties['type'] = self::FILETYPE_APPLICATION;
314  break;
315  default:
316  $this->properties['type'] = self::FILETYPE_UNKNOWN;
317  }
318  }
319  return (int)$this->properties['type'];
320  }
321 
322  /******************
323  * CONTENTS RELATED
324  ******************/
331  public function getContents()
332  {
333  if ($this->deleted) {
334  throw new \RuntimeException('File has been deleted.', 1329821479);
335  }
336  return $this->getStorage()->getFileContents($this);
337  }
338 
347  public function setContents($contents)
348  {
349  if ($this->deleted) {
350  throw new \RuntimeException('File has been deleted.', 1329821478);
351  }
352  $this->getStorage()->setFileContents($this, $contents);
353  return $this;
354  }
355 
356  /****************************************
357  * STORAGE AND MANAGEMENT RELATED METHDOS
358  ****************************************/
359 
366  public function getStorage()
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 
398  {
399  $this->storage = $storage;
400  $this->properties['storage'] = $storage->getUid();
401  return $this;
402  }
403 
411  public function setIdentifier($identifier)
412  {
413  $this->identifier = $identifier;
414  return $this;
415  }
416 
423  public function getCombinedIdentifier()
424  {
425  if (is_array($this->properties) && MathUtility::canBeInterpretedAsInteger($this->properties['storage'])) {
426  $combinedIdentifier = $this->properties['storage'] . ':' . $this->getIdentifier();
427  } else {
428  $combinedIdentifier = $this->getStorage()->getUid() . ':' . $this->getIdentifier();
429  }
430  return $combinedIdentifier;
431  }
432 
438  public function delete()
439  {
440  // The storage will mark this file as deleted
441  $wasDeleted = $this->getStorage()->deleteFile($this);
442 
443  // Unset all properties when deleting the file, as they will be stale anyway
444  // This needs to happen AFTER the storage deleted the file, because the storage
445  // emits a signal, which passes the file object to the slots, which may need
446  // all file properties of the deleted file.
447  $this->properties = [];
448 
449  return $wasDeleted;
450  }
451 
456  public function setDeleted()
457  {
458  $this->deleted = true;
459  }
460 
466  public function isDeleted()
467  {
468  return $this->deleted;
469  }
470 
479  public function rename($newName, $conflictMode = DuplicationBehavior::RENAME)
480  {
481  if ($this->deleted) {
482  throw new \RuntimeException('File has been deleted.', 1329821482);
483  }
484  return $this->getStorage()->renameFile($this, $newName, $conflictMode);
485  }
486 
497  public function copyTo(Folder $targetFolder, $targetFileName = null, $conflictMode = DuplicationBehavior::RENAME)
498  {
499  if ($this->deleted) {
500  throw new \RuntimeException('File has been deleted.', 1329821483);
501  }
502  return $targetFolder->getStorage()->copyFile($this, $targetFolder, $targetFileName, $conflictMode);
503  }
504 
515  public function moveTo(Folder $targetFolder, $targetFileName = null, $conflictMode = DuplicationBehavior::RENAME)
516  {
517  if ($this->deleted) {
518  throw new \RuntimeException('File has been deleted.', 1329821484);
519  }
520  return $targetFolder->getStorage()->moveFile($this, $targetFolder, $targetFileName, $conflictMode);
521  }
522 
523  /*****************
524  * SPECIAL METHODS
525  *****************/
535  public function getPublicUrl($relativeToCurrentScript = false)
536  {
537  if ($this->deleted) {
538  return null;
539  }
540  return $this->getStorage()->getPublicUrl($this, $relativeToCurrentScript);
541  }
542 
553  public function getForLocalProcessing($writable = true)
554  {
555  if ($this->deleted) {
556  throw new \RuntimeException('File has been deleted.', 1329821486);
557  }
558  return $this->getStorage()->getFileForLocalProcessing($this, $writable);
559  }
560 
561  /***********************
562  * INDEX RELATED METHODS
563  ***********************/
571  abstract public function updateProperties(array $properties);
572 
578  public function getParentFolder()
579  {
580  return $this->getStorage()->getFolder($this->getStorage()->getFolderIdentifierFromFileIdentifier($this->getIdentifier()));
581  }
582 }
moveTo(Folder $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
copyTo(Folder $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
rename($newName, $conflictMode=DuplicationBehavior::RENAME)
static pathinfo($path, $options=null)
setStorage(ResourceStorage $storage)
getPublicUrl($relativeToCurrentScript=false)