‪TYPO3CMS  10.4
LocalDriver.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Http\Message\ResponseInterface;
36 
41 {
45  const ‪UNSAFE_FILENAME_CHARACTER_EXPRESSION = '\\x00-\\x2C\\/\\x3A-\\x3F\\x5B-\\x60\\x7B-\\xBF';
46 
52  protected ‪$absoluteBasePath;
53 
59  protected ‪$supportedHashAlgorithms = ['sha1', 'md5'];
60 
67  protected ‪$baseUri;
68 
70  protected ‪$mappingFolderNameToRole = [
71  '_recycler_' => ‪FolderInterface::ROLE_RECYCLER,
73  'user_upload' => ‪FolderInterface::ROLE_USERUPLOAD,
74  ];
75 
79  public function ‪__construct(array ‪$configuration = [])
80  {
81  parent::__construct(‪$configuration);
82  // The capabilities default of this driver. See CAPABILITY_* constants for possible values
83  $this->capabilities =
88  }
89 
99  {
100  $this->capabilities &= ‪$capabilities;
101 
102  return ‪$this->capabilities;
103  }
104 
108  public function ‪processConfiguration()
109  {
110  $this->absoluteBasePath = $this->‪calculateBasePath($this->configuration);
111  $this->‪determineBaseUrl();
112  if ($this->baseUri === null) {
113  // remove public flag
114  $this->capabilities &= ~‪ResourceStorage::CAPABILITY_PUBLIC;
115  }
116  }
117 
122  public function ‪initialize()
123  {
124  }
125 
130  protected function ‪determineBaseUrl()
131  {
132  // only calculate baseURI if the storage does not enforce jumpUrl Script
134  if (!empty($this->configuration['baseUri'])) {
135  $this->baseUri = rtrim($this->configuration['baseUri'], '/') . '/';
136  } elseif (GeneralUtility::isFirstPartOfStr($this->absoluteBasePath, ‪Environment::getPublicPath())) {
137  // use site-relative URLs
138  $temporaryBaseUri = rtrim(‪PathUtility::stripPathSitePrefix($this->absoluteBasePath), '/');
139  if ($temporaryBaseUri !== '') {
140  $uriParts = explode('/', $temporaryBaseUri);
141  $uriParts = array_map('rawurlencode', $uriParts);
142  $temporaryBaseUri = implode('/', $uriParts) . '/';
143  }
144  $this->baseUri = $temporaryBaseUri;
145  }
146  }
147  }
148 
157  protected function ‪calculateBasePath(array ‪$configuration)
158  {
159  if (!array_key_exists('basePath', ‪$configuration) || empty(‪$configuration['basePath'])) {
160  throw new InvalidConfigurationException(
161  'Configuration must contain base path.',
162  1346510477
163  );
164  }
165 
166  if (!empty(‪$configuration['pathType']) && ‪$configuration['pathType'] === 'relative') {
167  $relativeBasePath = ‪$configuration['basePath'];
168  ‪$absoluteBasePath = ‪Environment::getPublicPath() . '/' . $relativeBasePath;
169  } else {
171  }
173  ‪$absoluteBasePath = rtrim(‪$absoluteBasePath, '/') . '/';
174  if (!is_dir(‪$absoluteBasePath)) {
175  throw new InvalidConfigurationException(
176  'Base path "' . ‪$absoluteBasePath . '" does not exist or is no directory.',
177  1299233097
178  );
179  }
180  return ‪$absoluteBasePath;
181  }
182 
190  public function ‪getPublicUrl($identifier)
191  {
192  $publicUrl = null;
193  if ($this->baseUri !== null) {
194  $uriParts = explode('/', ltrim($identifier, '/'));
195  $uriParts = array_map('rawurlencode', $uriParts);
196  $identifier = implode('/', $uriParts);
197  $publicUrl = $this->baseUri . $identifier;
198  }
199  return $publicUrl;
200  }
201 
207  public function ‪getRootLevelFolder()
208  {
209  return '/';
210  }
211 
217  public function ‪getDefaultFolder()
218  {
219  $identifier = '/user_upload/';
220  $createFolder = !$this->‪folderExists($identifier);
221  if ($createFolder === true) {
222  $identifier = $this->‪createFolder('user_upload');
223  }
224  return $identifier;
225  }
226 
236  public function ‪createFolder($newFolderName, $parentFolderIdentifier = '', $recursive = false)
237  {
238  $parentFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
239  $newFolderName = trim($newFolderName, '/');
240  if ($recursive === false) {
241  $newFolderName = $this->‪sanitizeFileName($newFolderName);
242  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier . $newFolderName . '/');
243  ‪GeneralUtility::mkdir($this->‪getAbsolutePath($newIdentifier));
244  } else {
245  $parts = ‪GeneralUtility::trimExplode('/', $newFolderName);
246  $parts = array_map([$this, 'sanitizeFileName'], $parts);
247  $newFolderName = implode('/', $parts);
248  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier(
249  $parentFolderIdentifier . $newFolderName . '/'
250  );
251  ‪GeneralUtility::mkdir_deep($this->‪getAbsolutePath($newIdentifier));
252  }
253  return $newIdentifier;
254  }
255 
264  public function ‪getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract = [])
265  {
266  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
267  // don't use $this->fileExists() because we need the absolute path to the file anyways, so we can directly
268  // use PHP's filesystem method.
269  if (!file_exists($absoluteFilePath) || !is_file($absoluteFilePath)) {
270  throw new \InvalidArgumentException('File ' . $fileIdentifier . ' does not exist.', 1314516809);
271  }
272 
273  $dirPath = ‪PathUtility::dirname($fileIdentifier);
274  $dirPath = $this->‪canonicalizeAndCheckFolderIdentifier($dirPath);
275  return $this->‪extractFileInformation($absoluteFilePath, $dirPath, $propertiesToExtract);
276  }
277 
285  public function ‪getFolderInfoByIdentifier($folderIdentifier)
286  {
287  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
288 
289  if (!$this->‪folderExists($folderIdentifier)) {
290  throw new FolderDoesNotExistException(
291  'Folder "' . $folderIdentifier . '" does not exist.',
292  1314516810
293  );
294  }
295  $absolutePath = $this->‪getAbsolutePath($folderIdentifier);
296  return [
297  'identifier' => $folderIdentifier,
298  'name' => ‪PathUtility::basename($folderIdentifier),
299  'mtime' => filemtime($absolutePath),
300  'ctime' => filectime($absolutePath),
301  'storage' => ‪$this->storageUid
302  ];
303  }
304 
317  public function ‪sanitizeFileName($fileName, $charset = 'utf-8')
318  {
319  // Handle UTF-8 characters
320  if (‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['UTF8filesystem']) {
321  // Allow ".", "-", 0-9, a-z, A-Z and everything beyond U+C0 (latin capital letter a with grave)
322  $cleanFileName = (string)preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . ']/u', '_', trim($fileName));
323  } else {
324  $fileName = GeneralUtility::makeInstance(CharsetConverter::class)->specCharsToASCII($charset, $fileName);
325  // Replace unwanted characters with underscores
326  $cleanFileName = (string)preg_replace('/[' . self::UNSAFE_FILENAME_CHARACTER_EXPRESSION . '\\xC0-\\xFF]/', '_', trim($fileName));
327  }
328  // Strip trailing dots and return
329  $cleanFileName = rtrim($cleanFileName, '.');
330  if ($cleanFileName === '') {
331  throw new InvalidFileNameException(
332  'File name ' . $fileName . ' is invalid.',
333  1320288991
334  );
335  }
336  return $cleanFileName;
337  }
338 
358  protected function ‪getDirectoryItemList($folderIdentifier, $start = 0, $numberOfItems = 0, array $filterMethods, $includeFiles = true, $includeDirs = true, $recursive = false, $sort = '', $sortRev = false)
359  {
360  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
361  $realPath = $this->‪getAbsolutePath($folderIdentifier);
362  if (!is_dir($realPath)) {
363  throw new \InvalidArgumentException(
364  'Cannot list items in directory ' . $folderIdentifier . ' - does not exist or is no directory',
365  1314349666
366  );
367  }
368 
369  $items = $this->‪retrieveFileAndFoldersInPath($realPath, $recursive, $includeFiles, $includeDirs, $sort, $sortRev);
370  $iterator = new \ArrayIterator($items);
371  if ($iterator->count() === 0) {
372  return [];
373  }
374 
375  // $c is the counter for how many items we still have to fetch (-1 is unlimited)
376  $c = $numberOfItems > 0 ? $numberOfItems : - 1;
377  $items = [];
378  while ($iterator->valid() && ($numberOfItems === 0 || $c > 0)) {
379  // $iteratorItem is the file or folder name
380  $iteratorItem = $iterator->current();
381  // go on to the next iterator item now as we might skip this one early
382  $iterator->next();
383 
384  try {
385  if (
387  $filterMethods,
388  $iteratorItem['name'],
389  $iteratorItem['identifier'],
390  $this->‪getParentFolderIdentifierOfIdentifier($iteratorItem['identifier'])
391  )
392  ) {
393  continue;
394  }
395  if ($start > 0) {
396  $start--;
397  } else {
398  $items[$iteratorItem['identifier']] = $iteratorItem['identifier'];
399  // Decrement item counter to make sure we only return $numberOfItems
400  // we cannot do this earlier in the method (unlike moving the iterator forward) because we only add the
401  // item here
402  --$c;
403  }
404  } catch (InvalidPathException $e) {
405  }
406  }
407  return $items;
408  }
409 
421  protected function ‪applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier)
422  {
423  foreach ($filterMethods as $filter) {
424  if (is_callable($filter)) {
425  $result = call_user_func($filter, $itemName, $itemIdentifier, $parentIdentifier, [], $this);
426  // We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
427  // If calling the method succeeded and thus we can't use that as a return value.
428  if ($result === -1) {
429  return false;
430  }
431  if ($result === false) {
432  throw new \RuntimeException(
433  'Could not apply file/folder name filter ' . $filter[0] . '::' . $filter[1],
434  1476046425
435  );
436  }
437  }
438  }
439  return true;
440  }
441 
449  public function ‪getFileInFolder($fileName, $folderIdentifier)
450  {
451  return $this->‪canonicalizeAndCheckFileIdentifier($folderIdentifier . '/' . $fileName);
452  }
453 
470  public function ‪getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $filenameFilterCallbacks = [], $sort = '', $sortRev = false)
471  {
472  return $this->‪getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $filenameFilterCallbacks, true, false, $recursive, $sort, $sortRev);
473  }
474 
483  public function ‪countFilesInFolder($folderIdentifier, $recursive = false, array $filenameFilterCallbacks = [])
484  {
485  return count($this->‪getFilesInFolder($folderIdentifier, 0, 0, $recursive, $filenameFilterCallbacks));
486  }
487 
504  public function ‪getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $folderNameFilterCallbacks = [], $sort = '', $sortRev = false)
505  {
506  return $this->‪getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $folderNameFilterCallbacks, false, true, $recursive, $sort, $sortRev);
507  }
508 
517  public function ‪countFoldersInFolder($folderIdentifier, $recursive = false, array $folderNameFilterCallbacks = [])
518  {
519  return count($this->‪getFoldersInFolder($folderIdentifier, 0, 0, $recursive, $folderNameFilterCallbacks));
520  }
521 
537  protected function ‪retrieveFileAndFoldersInPath($path, $recursive = false, $includeFiles = true, $includeDirs = true, $sort = '', $sortRev = false)
538  {
539  $pathLength = strlen($this->‪getAbsoluteBasePath());
540  $iteratorMode = \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::FOLLOW_SYMLINKS;
541  if ($recursive) {
542  $iterator = new \RecursiveIteratorIterator(
543  new \RecursiveDirectoryIterator($path, $iteratorMode),
544  \RecursiveIteratorIterator::SELF_FIRST,
545  \RecursiveIteratorIterator::CATCH_GET_CHILD
546  );
547  } else {
548  $iterator = new \RecursiveDirectoryIterator($path, $iteratorMode);
549  }
550 
551  $directoryEntries = [];
552  while ($iterator->valid()) {
554  $entry = $iterator->current();
555  $isFile = $entry->isFile();
556  $isDirectory = $isFile ? false : $entry->isDir();
557  if (
558  (!$isFile && !$isDirectory) // skip non-files/non-folders
559  || ($isFile && !$includeFiles) // skip files if they are excluded
560  || ($isDirectory && !$includeDirs) // skip directories if they are excluded
561  || $entry->getFilename() === '' // skip empty entries
562  || !$entry->isReadable() // skip unreadable entries
563  ) {
564  $iterator->next();
565  continue;
566  }
567  $entryIdentifier = '/' . substr($entry->getPathname(), $pathLength);
568  $entryName = ‪PathUtility::basename($entryIdentifier);
569  if ($isDirectory) {
570  $entryIdentifier .= '/';
571  }
572  $entryArray = [
573  'identifier' => $entryIdentifier,
574  'name' => $entryName,
575  'type' => $isDirectory ? 'dir' : 'file'
576  ];
577  $directoryEntries[$entryIdentifier] = $entryArray;
578  $iterator->next();
579  }
580  return $this->‪sortDirectoryEntries($directoryEntries, $sort, $sortRev);
581  }
582 
596  protected function ‪sortDirectoryEntries($directoryEntries, $sort = '', $sortRev = false)
597  {
598  $entriesToSort = [];
599  foreach ($directoryEntries as $entryArray) {
600  ‪$dir = pathinfo($entryArray['name'], PATHINFO_DIRNAME) . '/';
601  $fullPath = $this->‪getAbsoluteBasePath() . $entryArray['identifier'];
602  switch ($sort) {
603  case 'size':
604  $sortingKey = '0';
605  if ($entryArray['type'] === 'file') {
606  $sortingKey = $this->‪getSpecificFileInformation($fullPath, ‪$dir, 'size');
607  }
608  // Add a character for a natural order sorting
609  $sortingKey .= 's';
610  break;
611  case 'rw':
612  $perms = $this->‪getPermissions($entryArray['identifier']);
613  $sortingKey = ($perms['r'] ? 'R' : '')
614  . ($perms['w'] ? 'W' : '');
615  break;
616  case 'fileext':
617  $sortingKey = pathinfo($entryArray['name'], PATHINFO_EXTENSION);
618  break;
619  case 'tstamp':
620  $sortingKey = $this->‪getSpecificFileInformation($fullPath, ‪$dir, 'mtime');
621  // Add a character for a natural order sorting
622  $sortingKey .= 't';
623  break;
624  case 'name':
625  case 'file':
626  default:
627  $sortingKey = $entryArray['name'];
628  }
629  $i = 0;
630  while (isset($entriesToSort[$sortingKey . $i])) {
631  $i++;
632  }
633  $entriesToSort[$sortingKey . $i] = $entryArray;
634  }
635  uksort($entriesToSort, 'strnatcasecmp');
636 
637  if ($sortRev) {
638  $entriesToSort = array_reverse($entriesToSort);
639  }
640 
641  return $entriesToSort;
642  }
643 
652  protected function ‪extractFileInformation($filePath, $containerPath, array $propertiesToExtract = [])
653  {
654  if (empty($propertiesToExtract)) {
655  $propertiesToExtract = [
656  'size', 'atime', 'mtime', 'ctime', 'mimetype', 'name', 'extension',
657  'identifier', 'identifier_hash', 'storage', 'folder_hash'
658  ];
659  }
660  $fileInformation = [];
661  foreach ($propertiesToExtract as $property) {
662  $fileInformation[$property] = $this->‪getSpecificFileInformation($filePath, $containerPath, $property);
663  }
664  return $fileInformation;
665  }
666 
677  public function ‪getSpecificFileInformation($fileIdentifier, $containerPath, $property)
678  {
679  $identifier = $this->‪canonicalizeAndCheckFileIdentifier($containerPath . ‪PathUtility::basename($fileIdentifier));
680 
682  $fileInfo = GeneralUtility::makeInstance(FileInfo::class, $fileIdentifier);
683  switch ($property) {
684  case 'size':
685  return $fileInfo->getSize();
686  case 'atime':
687  return $fileInfo->getATime();
688  case 'mtime':
689  return $fileInfo->getMTime();
690  case 'ctime':
691  return $fileInfo->getCTime();
692  case 'name':
693  return ‪PathUtility::basename($fileIdentifier);
694  case 'extension':
695  return ‪PathUtility::pathinfo($fileIdentifier, PATHINFO_EXTENSION);
696  case 'mimetype':
697  return (string)$fileInfo->getMimeType();
698  case 'identifier':
699  return $identifier;
700  case 'storage':
701  return ‪$this->storageUid;
702  case 'identifier_hash':
703  return $this->‪hashIdentifier($identifier);
704  case 'folder_hash':
705  return $this->‪hashIdentifier($this->‪getParentFolderIdentifierOfIdentifier($identifier));
706  default:
707  throw new \InvalidArgumentException(sprintf('The information "%s" is not available.', $property), 1476047422);
708  }
709  }
710 
716  protected function ‪getAbsoluteBasePath()
717  {
719  }
720 
728  protected function ‪getAbsolutePath($fileIdentifier)
729  {
730  $relativeFilePath = ltrim($this->‪canonicalizeAndCheckFileIdentifier($fileIdentifier), '/');
731  $path = $this->absoluteBasePath . $relativeFilePath;
732  return $path;
733  }
734 
744  public function ‪hash($fileIdentifier, $hashAlgorithm)
745  {
746  if (!in_array($hashAlgorithm, $this->supportedHashAlgorithms)) {
747  throw new \InvalidArgumentException('Hash algorithm "' . $hashAlgorithm . '" is not supported.', 1304964032);
748  }
749  switch ($hashAlgorithm) {
750  case 'sha1':
751  $hash = sha1_file($this->‪getAbsolutePath($fileIdentifier));
752  break;
753  case 'md5':
754  $hash = md5_file($this->‪getAbsolutePath($fileIdentifier));
755  break;
756  default:
757  throw new \RuntimeException('Hash algorithm ' . $hashAlgorithm . ' is not implemented.', 1329644451);
758  }
759  return $hash;
760  }
761 
775  public function ‪addFile($localFilePath, $targetFolderIdentifier, $newFileName = '', $removeOriginal = true)
776  {
777  $localFilePath = $this->‪canonicalizeAndCheckFilePath($localFilePath);
778  // as for the "virtual storage" for backwards-compatibility, this check always fails, as the file probably lies under public web path
779  // thus, it is not checked here
780  // @todo is check in storage
781  if (GeneralUtility::isFirstPartOfStr($localFilePath, $this->absoluteBasePath) && $this->storageUid > 0) {
782  throw new \InvalidArgumentException('Cannot add a file that is already part of this storage.', 1314778269);
783  }
784  $newFileName = $this->‪sanitizeFileName($newFileName !== '' ? $newFileName : ‪PathUtility::basename($localFilePath));
785  $newFileIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier) . $newFileName;
786  $targetPath = $this->‪getAbsolutePath($newFileIdentifier);
787 
788  if ($removeOriginal) {
789  if (is_uploaded_file($localFilePath)) {
790  $result = move_uploaded_file($localFilePath, $targetPath);
791  } else {
792  $result = rename($localFilePath, $targetPath);
793  }
794  } else {
795  $result = copy($localFilePath, $targetPath);
796  }
797  if ($result === false || !file_exists($targetPath)) {
798  throw new \RuntimeException(
799  'Adding file ' . $localFilePath . ' at ' . $newFileIdentifier . ' failed.',
800  1476046453
801  );
802  }
803  clearstatcache();
804  // Change the permissions of the file
806  return $newFileIdentifier;
807  }
808 
816  public function ‪fileExists($fileIdentifier)
817  {
818  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
819  return is_file($absoluteFilePath);
820  }
821 
829  public function ‪fileExistsInFolder($fileName, $folderIdentifier)
830  {
831  $identifier = $folderIdentifier . '/' . $fileName;
832  $identifier = $this->‪canonicalizeAndCheckFileIdentifier($identifier);
833  return $this->‪fileExists($identifier);
834  }
835 
843  public function ‪folderExists($folderIdentifier)
844  {
845  $absoluteFilePath = $this->‪getAbsolutePath($folderIdentifier);
846  return is_dir($absoluteFilePath);
847  }
848 
856  public function ‪folderExistsInFolder($folderName, $folderIdentifier)
857  {
858  $identifier = $folderIdentifier . '/' . $folderName;
859  $identifier = $this->‪canonicalizeAndCheckFolderIdentifier($identifier);
860  return $this->‪folderExists($identifier);
861  }
862 
870  public function ‪getFolderInFolder($folderName, $folderIdentifier)
871  {
872  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier . '/' . $folderName);
873  return $folderIdentifier;
874  }
875 
884  public function ‪replaceFile($fileIdentifier, $localFilePath)
885  {
886  $filePath = $this->‪getAbsolutePath($fileIdentifier);
887  if (is_uploaded_file($localFilePath)) {
888  $result = move_uploaded_file($localFilePath, $filePath);
889  } else {
890  $result = rename($localFilePath, $filePath);
891  }
893  if ($result === false) {
894  throw new \RuntimeException('Replacing file ' . $fileIdentifier . ' with ' . $localFilePath . ' failed.', 1315314711);
895  }
896  return $result;
897  }
898 
909  public function ‪copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName)
910  {
911  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
912  $newIdentifier = $targetFolderIdentifier . '/' . $fileName;
913  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($newIdentifier);
914 
915  $absoluteFilePath = $this->‪getAbsolutePath($newIdentifier);
916  copy($sourcePath, $absoluteFilePath);
917  ‪GeneralUtility::fixPermissions($absoluteFilePath);
918  return $newIdentifier;
919  }
920 
932  public function ‪moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName)
933  {
934  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
935  $targetIdentifier = $targetFolderIdentifier . '/' . $newFileName;
936  $targetIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($targetIdentifier);
937  $result = rename($sourcePath, $this->‪getAbsolutePath($targetIdentifier));
938  if ($result === false) {
939  throw new \RuntimeException('Moving file ' . $sourcePath . ' to ' . $targetIdentifier . ' failed.', 1315314712);
940  }
941  return $targetIdentifier;
942  }
943 
951  protected function ‪copyFileToTemporaryPath($fileIdentifier)
952  {
953  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
954  $temporaryPath = $this->‪getTemporaryPathForFile($fileIdentifier);
955  $result = copy($sourcePath, $temporaryPath);
956  touch($temporaryPath, (int)filemtime($sourcePath));
957  if ($result === false) {
958  throw new \RuntimeException(
959  'Copying file "' . $fileIdentifier . '" to temporary path "' . $temporaryPath . '" failed.',
960  1320577649
961  );
962  }
963  return $temporaryPath;
964  }
965 
974  protected function ‪recycleFileOrFolder($filePath, $recycleDirectory)
975  {
976  $destinationFile = $recycleDirectory . '/' . ‪PathUtility::basename($filePath);
977  if (file_exists($destinationFile)) {
978  $timeStamp = \DateTimeImmutable::createFromFormat('U.u', (string)microtime(true))->format('YmdHisu');
979  $destinationFile = $recycleDirectory . '/' . $timeStamp . '_' . ‪PathUtility::basename($filePath);
980  }
981  $result = rename($filePath, $destinationFile);
982  // Update the mtime for the file, so the recycler garbage collection task knows which files to delete
983  // Using ctime() is not possible there since this is not supported on Windows
984  if ($result) {
985  touch($destinationFile);
986  }
987  return $result;
988  }
989 
1001  protected function ‪createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier)
1002  {
1003  $identifierMap = [];
1004  $identifierMap[$sourceFolderIdentifier] = $targetFolderIdentifier;
1005  foreach ($filesAndFolders as $oldItem) {
1006  if ($oldItem['type'] === 'dir') {
1007  $oldIdentifier = $oldItem['identifier'];
1008  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier(
1009  str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
1010  );
1011  } else {
1012  $oldIdentifier = $oldItem['identifier'];
1013  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier(
1014  str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
1015  );
1016  }
1017  if (!file_exists($this->‪getAbsolutePath($newIdentifier))) {
1018  throw new FileOperationErrorException(
1019  sprintf('File "%1$s" was not found (should have been copied/moved from "%2$s").', $newIdentifier, $oldIdentifier),
1020  1330119453
1021  );
1022  }
1023  $identifierMap[$oldIdentifier] = $newIdentifier;
1024  }
1025  return $identifierMap;
1026  }
1027 
1038  public function ‪moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
1039  {
1040  $sourcePath = $this->‪getAbsolutePath($sourceFolderIdentifier);
1041  $relativeTargetPath = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
1042  $targetPath = $this->‪getAbsolutePath($relativeTargetPath);
1043  // get all files and folders we are going to move, to have a map for updating later.
1044  $filesAndFolders = $this->‪retrieveFileAndFoldersInPath($sourcePath, true);
1045  $result = rename($sourcePath, $targetPath);
1046  if ($result === false) {
1047  throw new \RuntimeException('Moving folder ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320711817);
1048  }
1049  // Create a mapping from old to new identifiers
1050  $identifierMap = $this->‪createIdentifierMap($filesAndFolders, $sourceFolderIdentifier, $relativeTargetPath);
1051  return $identifierMap;
1052  }
1053 
1064  public function ‪copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
1065  {
1066  // This target folder path already includes the topmost level, i.e. the folder this method knows as $folderToCopy.
1067  // We can thus rely on this folder being present and just create the subfolder we want to copy to.
1068  $newFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
1069  $sourceFolderPath = $this->‪getAbsolutePath($sourceFolderIdentifier);
1070  $targetFolderPath = $this->‪getAbsolutePath($newFolderIdentifier);
1071 
1072  mkdir($targetFolderPath);
1074  $iterator = new \RecursiveIteratorIterator(
1075  new \RecursiveDirectoryIterator($sourceFolderPath),
1076  \RecursiveIteratorIterator::SELF_FIRST,
1077  \RecursiveIteratorIterator::CATCH_GET_CHILD
1078  );
1079  // Rewind the iterator as this is important for some systems e.g. Windows
1080  $iterator->rewind();
1081  while ($iterator->valid()) {
1083  $current = $iterator->current();
1084  $fileName = $current->getFilename();
1085  $itemSubPath = GeneralUtility::fixWindowsFilePath($iterator->getSubPathname());
1086  if ($current->isDir() && !($fileName === '..' || $fileName === '.')) {
1087  ‪GeneralUtility::mkdir($targetFolderPath . '/' . $itemSubPath);
1088  } elseif ($current->isFile()) {
1089  $copySourcePath = $sourceFolderPath . '/' . $itemSubPath;
1090  $copyTargetPath = $targetFolderPath . '/' . $itemSubPath;
1091  $result = copy($copySourcePath, $copyTargetPath);
1092  if ($result === false) {
1093  // rollback
1094  ‪GeneralUtility::rmdir($targetFolderIdentifier, true);
1095  throw new FileOperationErrorException(
1096  'Copying resource "' . $copySourcePath . '" to "' . $copyTargetPath . '" failed.',
1097  1330119452
1098  );
1099  }
1100  }
1101  $iterator->next();
1102  }
1103  ‪GeneralUtility::fixPermissions($targetFolderPath, true);
1104  return true;
1105  }
1106 
1116  public function ‪renameFile($fileIdentifier, $newName)
1117  {
1118  // Makes sure the Path given as parameter is valid
1119  $newName = $this->‪sanitizeFileName($newName);
1120  $newIdentifier = rtrim(GeneralUtility::fixWindowsFilePath(‪PathUtility::dirname($fileIdentifier)), '/') . '/' . $newName;
1121  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($newIdentifier);
1122  // The target should not exist already
1123  if ($this->‪fileExists($newIdentifier)) {
1124  throw new ExistingTargetFileNameException(
1125  'The target file "' . $newIdentifier . '" already exists.',
1126  1320291063
1127  );
1128  }
1129  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
1130  $targetPath = $this->‪getAbsolutePath($newIdentifier);
1131  $result = rename($sourcePath, $targetPath);
1132  if ($result === false) {
1133  throw new \RuntimeException('Renaming file ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320375115);
1134  }
1135  return $newIdentifier;
1136  }
1137 
1146  public function ‪renameFolder($folderIdentifier, $newName)
1147  {
1148  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
1149  $newName = $this->‪sanitizeFileName($newName);
1150 
1151  $newIdentifier = ‪PathUtility::dirname($folderIdentifier) . '/' . $newName;
1152  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($newIdentifier);
1153 
1154  $sourcePath = $this->‪getAbsolutePath($folderIdentifier);
1155  $targetPath = $this->‪getAbsolutePath($newIdentifier);
1156  // get all files and folders we are going to move, to have a map for updating later.
1157  $filesAndFolders = $this->‪retrieveFileAndFoldersInPath($sourcePath, true);
1158  $result = rename($sourcePath, $targetPath);
1159  if ($result === false) {
1160  throw new \RuntimeException(sprintf('Renaming folder "%1$s" to "%2$s" failed."', $sourcePath, $targetPath), 1320375116);
1161  }
1162  try {
1163  // Create a mapping from old to new identifiers
1164  $identifierMap = $this->‪createIdentifierMap($filesAndFolders, $folderIdentifier, $newIdentifier);
1165  } catch (\Exception $e) {
1166  rename($targetPath, $sourcePath);
1167  throw new \RuntimeException(
1168  sprintf(
1169  'Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"',
1170  $sourcePath,
1171  $targetPath,
1172  $e->getMessage()
1173  ),
1174  1334160746
1175  );
1176  }
1177  return $identifierMap;
1178  }
1179 
1189  public function ‪deleteFile($fileIdentifier)
1190  {
1191  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1192  $result = unlink($filePath);
1193 
1194  if ($result === false) {
1195  throw new \RuntimeException('Deletion of file ' . $fileIdentifier . ' failed.', 1320855304);
1196  }
1197  return $result;
1198  }
1199 
1209  public function ‪deleteFolder($folderIdentifier, $deleteRecursively = false)
1210  {
1211  $folderPath = $this->‪getAbsolutePath($folderIdentifier);
1212  $recycleDirectory = $this->‪getRecycleDirectory($folderPath);
1213  if (!empty($recycleDirectory) && $folderPath !== $recycleDirectory) {
1214  $result = $this->‪recycleFileOrFolder($folderPath, $recycleDirectory);
1215  } else {
1216  $result = ‪GeneralUtility::rmdir($folderPath, $deleteRecursively);
1217  }
1218  if ($result === false) {
1219  throw new FileOperationErrorException(
1220  'Deleting folder "' . $folderIdentifier . '" failed.',
1221  1330119451
1222  );
1223  }
1224  return $result;
1225  }
1226 
1233  public function ‪isFolderEmpty($folderIdentifier)
1234  {
1235  $path = $this->‪getAbsolutePath($folderIdentifier);
1236  $dirHandle = opendir($path);
1237  if ($dirHandle === false) {
1238  return true;
1239  }
1240  while ($entry = readdir($dirHandle)) {
1241  if ($entry !== '.' && $entry !== '..') {
1242  closedir($dirHandle);
1243  return false;
1244  }
1245  }
1246  closedir($dirHandle);
1247  return true;
1248  }
1249 
1260  public function ‪getFileForLocalProcessing($fileIdentifier, $writable = true)
1261  {
1262  if ($writable === false) {
1263  return $this->‪getAbsolutePath($fileIdentifier);
1264  }
1265  return $this->‪copyFileToTemporaryPath($fileIdentifier);
1266  }
1267 
1275  public function ‪getPermissions($identifier)
1276  {
1277  $path = $this->‪getAbsolutePath($identifier);
1278  $permissionBits = fileperms($path);
1279  if ($permissionBits === false) {
1280  throw new ResourcePermissionsUnavailableException('Error while fetching permissions for ' . $path, 1319455097);
1281  }
1282  return [
1283  'r' => (bool)is_readable($path),
1284  'w' => (bool)is_writable($path)
1285  ];
1286  }
1287 
1297  public function ‪isWithin($folderIdentifier, $identifier)
1298  {
1299  $folderIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($folderIdentifier);
1300  $entryIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($identifier);
1301  if ($folderIdentifier === $entryIdentifier) {
1302  return true;
1303  }
1304  // File identifier canonicalization will not modify a single slash so
1305  // we must not append another slash in that case.
1306  if ($folderIdentifier !== '/') {
1307  $folderIdentifier .= '/';
1308  }
1309  return GeneralUtility::isFirstPartOfStr($entryIdentifier, $folderIdentifier);
1310  }
1311 
1320  public function ‪createFile($fileName, $parentFolderIdentifier)
1321  {
1322  $fileName = $this->‪sanitizeFileName(ltrim($fileName, '/'));
1323  $parentFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
1324  $fileIdentifier = $this->‪canonicalizeAndCheckFileIdentifier(
1325  $parentFolderIdentifier . $fileName
1326  );
1327  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
1328  $result = touch($absoluteFilePath);
1329  ‪GeneralUtility::fixPermissions($absoluteFilePath);
1330  clearstatcache();
1331  if ($result !== true) {
1332  throw new \RuntimeException('Creating file ' . $fileIdentifier . ' failed.', 1320569854);
1333  }
1334  return $fileIdentifier;
1335  }
1336 
1346  public function ‪getFileContents($fileIdentifier)
1347  {
1348  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1349  return file_get_contents($filePath);
1350  }
1351 
1360  public function ‪setFileContents($fileIdentifier, $contents)
1361  {
1362  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1363  $result = file_put_contents($filePath, $contents);
1364 
1365  // Make sure later calls to filesize() etc. return correct values.
1366  clearstatcache(true, $filePath);
1367 
1368  if ($result === false) {
1369  throw new \RuntimeException('Setting contents of file "' . $fileIdentifier . '" failed.', 1325419305);
1370  }
1371  return $result;
1372  }
1373 
1380  public function ‪getRole($folderIdentifier)
1381  {
1382  $name = ‪PathUtility::basename($folderIdentifier);
1383  $role = $this->mappingFolderNameToRole[$name] ?? ‪FolderInterface::ROLE_DEFAULT;
1384  return $role;
1385  }
1386 
1394  public function ‪dumpFileContents($identifier)
1395  {
1396  readfile($this->‪getAbsolutePath($this->‪canonicalizeAndCheckFileIdentifier($identifier)), false);
1397  }
1398 
1406  public function ‪streamFile(string $identifier, array $properties): ResponseInterface
1407  {
1408  $fileInfo = $this->‪getFileInfoByIdentifier($identifier, ['name', 'mimetype', 'mtime', 'size']);
1409  $downloadName = $properties['filename_overwrite'] ?? $fileInfo['name'] ?? '';
1410  $mimeType = $properties['mimetype_overwrite'] ?? $fileInfo['mimetype'] ?? '';
1411  $contentDisposition = ($properties['as_download'] ?? false) ? 'attachment' : 'inline';
1412 
1413  $filePath = $this->‪getAbsolutePath($this->‪canonicalizeAndCheckFileIdentifier($identifier));
1414 
1415  return new Response(
1416  new SelfEmittableLazyOpenStream($filePath),
1417  200,
1418  [
1419  'Content-Disposition' => $contentDisposition . '; filename="' . $downloadName . '"',
1420  'Content-Type' => $mimeType,
1421  'Content-Length' => (string)$fileInfo['size'],
1422  'Last-Modified' => gmdate('D, d M Y H:i:s', $fileInfo['mtime']) . ' GMT',
1423  // Cache-Control header is needed here to solve an issue with browser IE8 and lower
1424  // See for more information: http://support.microsoft.com/kb/323308
1425  'Cache-Control' => '',
1426  ]
1427  );
1428  }
1429 
1437  protected function ‪getRecycleDirectory($path)
1438  {
1439  $recyclerSubdirectory = array_search(‪FolderInterface::ROLE_RECYCLER, $this->mappingFolderNameToRole, true);
1440  if ($recyclerSubdirectory === false) {
1441  return '';
1442  }
1443  $rootDirectory = rtrim($this->‪getAbsolutePath($this->‪getRootLevelFolder()), '/');
1444  $searchDirectory = ‪PathUtility::dirname($path);
1445  // Check if file or folder to be deleted is inside a recycler directory
1446  if ($this->‪getRole($searchDirectory) === ‪FolderInterface::ROLE_RECYCLER) {
1447  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1448  // Check if file or folder to be deleted is inside the root recycler
1449  if ($searchDirectory == $rootDirectory) {
1450  return '';
1451  }
1452  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1453  }
1454  // Search for the closest recycler directory
1455  while ($searchDirectory) {
1456  $recycleDirectory = $searchDirectory . '/' . $recyclerSubdirectory;
1457  if (is_dir($recycleDirectory)) {
1458  return $recycleDirectory;
1459  }
1460  if ($searchDirectory === $rootDirectory) {
1461  return '';
1462  }
1463  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1464  }
1465 
1466  return '';
1467  }
1468 }
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\retrieveFileAndFoldersInPath
‪array retrieveFileAndFoldersInPath($path, $recursive=false, $includeFiles=true, $includeDirs=true, $sort='', $sortRev=false)
Definition: LocalDriver.php:533
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRole
‪string getRole($folderIdentifier)
Definition: LocalDriver.php:1376
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\$capabilities
‪int $capabilities
Definition: AbstractDriver.php:34
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\__construct
‪__construct(array $configuration=[])
Definition: LocalDriver.php:75
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$absoluteBasePath
‪string $absoluteBasePath
Definition: LocalDriver.php:51
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\folderExistsInFolder
‪bool folderExistsInFolder($folderName, $folderIdentifier)
Definition: LocalDriver.php:852
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\deleteFolder
‪bool deleteFolder($folderIdentifier, $deleteRecursively=false)
Definition: LocalDriver.php:1205
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\canonicalizeAndCheckFilePath
‪string canonicalizeAndCheckFilePath($filePath)
Definition: AbstractHierarchicalFilesystemDriver.php:46
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:180
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\determineBaseUrl
‪determineBaseUrl()
Definition: LocalDriver.php:126
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\recycleFileOrFolder
‪bool recycleFileOrFolder($filePath, $recycleDirectory)
Definition: LocalDriver.php:970
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFilesInFolder
‪array getFilesInFolder($folderIdentifier, $start=0, $numberOfItems=0, $recursive=false, array $filenameFilterCallbacks=[], $sort='', $sortRev=false)
Definition: LocalDriver.php:466
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\canonicalizeAndCheckFolderIdentifier
‪string canonicalizeAndCheckFolderIdentifier($folderPath)
Definition: AbstractHierarchicalFilesystemDriver.php:83
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\addFile
‪string addFile($localFilePath, $targetFolderIdentifier, $newFileName='', $removeOriginal=true)
Definition: LocalDriver.php:771
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\canonicalizeAndCheckFileIdentifier
‪string canonicalizeAndCheckFileIdentifier($fileIdentifier)
Definition: AbstractHierarchicalFilesystemDriver.php:65
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:186
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\$configuration
‪array $configuration
Definition: AbstractDriver.php:54
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver
Definition: AbstractHierarchicalFilesystemDriver.php:26
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\renameFile
‪string renameFile($fileIdentifier, $newName)
Definition: LocalDriver.php:1112
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\countFilesInFolder
‪int countFilesInFolder($folderIdentifier, $recursive=false, array $filenameFilterCallbacks=[])
Definition: LocalDriver.php:479
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_DEFAULT
‪const ROLE_DEFAULT
Definition: FolderInterface.php:26
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:372
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver
Definition: LocalDriver.php:41
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFolderInfoByIdentifier
‪array getFolderInfoByIdentifier($folderIdentifier)
Definition: LocalDriver.php:281
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\extractFileInformation
‪array extractFileInformation($filePath, $containerPath, array $propertiesToExtract=[])
Definition: LocalDriver.php:648
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\hashIdentifier
‪string hashIdentifier($identifier)
Definition: AbstractDriver.php:142
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\streamFile
‪ResponseInterface streamFile(string $identifier, array $properties)
Definition: LocalDriver.php:1402
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileForLocalProcessing
‪string getFileForLocalProcessing($fileIdentifier, $writable=true)
Definition: LocalDriver.php:1256
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\sortDirectoryEntries
‪array sortDirectoryEntries($directoryEntries, $sort='', $sortRev=false)
Definition: LocalDriver.php:592
‪TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
Definition: ExistingTargetFileNameException.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getDefaultFolder
‪string getDefaultFolder()
Definition: LocalDriver.php:213
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\isFolderEmpty
‪bool isFolderEmpty($folderIdentifier)
Definition: LocalDriver.php:1229
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_USERUPLOAD
‪const ROLE_USERUPLOAD
Definition: FolderInterface.php:30
‪TYPO3\CMS\Core\Charset\CharsetConverter
Definition: CharsetConverter.php:54
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\countFoldersInFolder
‪int countFoldersInFolder($folderIdentifier, $recursive=false, array $folderNameFilterCallbacks=[])
Definition: LocalDriver.php:513
‪TYPO3\CMS\Core\Resource\Exception\ResourcePermissionsUnavailableException
Definition: ResourcePermissionsUnavailableException.php:26
‪$dir
‪$dir
Definition: validateRstFiles.php:213
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createFolder
‪string createFolder($newFolderName, $parentFolderIdentifier='', $recursive=false)
Definition: LocalDriver.php:232
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\deleteFile
‪bool deleteFile($fileIdentifier)
Definition: LocalDriver.php:1185
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getSpecificFileInformation
‪bool int string getSpecificFileInformation($fileIdentifier, $containerPath, $property)
Definition: LocalDriver.php:673
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getAbsolutePath
‪string getAbsolutePath($fileIdentifier)
Definition: LocalDriver.php:724
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static string basename($path)
Definition: PathUtility.php:165
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\initialize
‪initialize()
Definition: LocalDriver.php:118
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_TEMPORARY
‪const ROLE_TEMPORARY
Definition: FolderInterface.php:29
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\getTemporaryPathForFile
‪string getTemporaryPathForFile($fileIdentifier)
Definition: AbstractDriver.php:129
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createFile
‪string createFile($fileName, $parentFolderIdentifier)
Definition: LocalDriver.php:1316
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRecycleDirectory
‪string getRecycleDirectory($path)
Definition: LocalDriver.php:1433
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\setFileContents
‪int setFileContents($fileIdentifier, $contents)
Definition: LocalDriver.php:1356
‪TYPO3\CMS\Core\Http\Response
Definition: Response.php:30
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$baseUri
‪string $baseUri
Definition: LocalDriver.php:64
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\hash
‪string hash($fileIdentifier, $hashAlgorithm)
Definition: LocalDriver.php:740
‪TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException
Definition: InvalidConfigurationException.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getPublicUrl
‪string null getPublicUrl($identifier)
Definition: LocalDriver.php:186
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\hasCapability
‪bool hasCapability($capability)
Definition: AbstractDriver.php:114
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixPermissions
‪static mixed fixPermissions($path, $recursive=false)
Definition: GeneralUtility.php:1863
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$supportedHashAlgorithms
‪array $supportedHashAlgorithms
Definition: LocalDriver.php:57
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:2022
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\moveFileWithinStorage
‪string moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName)
Definition: LocalDriver.php:928
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\folderExists
‪bool folderExists($folderIdentifier)
Definition: LocalDriver.php:839
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileInfoByIdentifier
‪array getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract=[])
Definition: LocalDriver.php:260
‪TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException
Definition: FolderDoesNotExistException.php:22
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$mappingFolderNameToRole
‪array $mappingFolderNameToRole
Definition: LocalDriver.php:66
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\mergeConfigurationCapabilities
‪int mergeConfigurationCapabilities($capabilities)
Definition: LocalDriver.php:94
‪TYPO3\CMS\Core\Utility\PathUtility\pathinfo
‪static string string[] pathinfo($path, $options=null)
Definition: PathUtility.php:208
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\dumpFileContents
‪dumpFileContents($identifier)
Definition: LocalDriver.php:1390
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_HIERARCHICAL_IDENTIFIERS
‪const CAPABILITY_HIERARCHICAL_IDENTIFIERS
Definition: ResourceStorageInterface.php:179
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\isWithin
‪bool isWithin($folderIdentifier, $identifier)
Definition: LocalDriver.php:1293
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static string[] trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:1059
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_BROWSABLE
‪const CAPABILITY_BROWSABLE
Definition: ResourceStorageInterface.php:166
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileContents
‪string getFileContents($fileIdentifier)
Definition: LocalDriver.php:1342
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFileToTemporaryPath
‪string copyFileToTemporaryPath($fileIdentifier)
Definition: LocalDriver.php:947
‪TYPO3\CMS\Core\Resource\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\processConfiguration
‪processConfiguration()
Definition: LocalDriver.php:104
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getAbsoluteBasePath
‪string getAbsoluteBasePath()
Definition: LocalDriver.php:712
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createIdentifierMap
‪array createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier)
Definition: LocalDriver.php:997
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:122
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\calculateBasePath
‪string calculateBasePath(array $configuration)
Definition: LocalDriver.php:153
‪TYPO3\CMS\Core\Resource\Driver
Definition: AbstractDriver.php:16
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:5
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:40
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFolderWithinStorage
‪bool copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
Definition: LocalDriver.php:1060
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_RECYCLER
‪const ROLE_RECYCLER
Definition: FolderInterface.php:27
‪TYPO3\CMS\Core\Resource\FolderInterface
Definition: FolderInterface.php:22
‪TYPO3\CMS\Core\Type\File\FileInfo
Definition: FileInfo.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility\rmdir
‪static bool rmdir($path, $removeNonEmpty=false)
Definition: GeneralUtility.php:2075
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\replaceFile
‪bool replaceFile($fileIdentifier, $localFilePath)
Definition: LocalDriver.php:880
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_PUBLIC
‪const CAPABILITY_PUBLIC
Definition: ResourceStorageInterface.php:170
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getDirectoryItemList
‪array getDirectoryItemList($folderIdentifier, $start=0, $numberOfItems=0, array $filterMethods, $includeFiles=true, $includeDirs=true, $recursive=false, $sort='', $sortRev=false)
Definition: LocalDriver.php:354
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\renameFolder
‪array renameFolder($folderIdentifier, $newName)
Definition: LocalDriver.php:1142
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\getParentFolderIdentifierOfIdentifier
‪mixed getParentFolderIdentifierOfIdentifier($fileIdentifier)
Definition: AbstractHierarchicalFilesystemDriver.php:99
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\$storageUid
‪int $storageUid
Definition: AbstractDriver.php:40
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\fileExistsInFolder
‪bool fileExistsInFolder($fileName, $folderIdentifier)
Definition: LocalDriver.php:825
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\fileExists
‪bool fileExists($fileIdentifier)
Definition: LocalDriver.php:812
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\moveFolderWithinStorage
‪array moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
Definition: LocalDriver.php:1034
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\applyFilterMethodsToDirectoryItem
‪bool applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier)
Definition: LocalDriver.php:417
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:46
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileInFolder
‪string getFileInFolder($fileName, $folderIdentifier)
Definition: LocalDriver.php:445
‪TYPO3\CMS\Core\Http\SelfEmittableLazyOpenStream
Definition: SelfEmittableLazyOpenStream.php:30
‪TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException
Definition: FileOperationErrorException.php:22
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\UNSAFE_FILENAME_CHARACTER_EXPRESSION
‪const UNSAFE_FILENAME_CHARACTER_EXPRESSION
Definition: LocalDriver.php:45
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\sanitizeFileName
‪string sanitizeFileName($fileName, $charset='utf-8')
Definition: LocalDriver.php:313
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir
‪static bool mkdir($newFolder)
Definition: GeneralUtility.php:2005
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getPermissions
‪array getPermissions($identifier)
Definition: LocalDriver.php:1271
‪TYPO3\CMS\Core\Resource\Exception\InvalidPathException
Definition: InvalidPathException.php:24
‪TYPO3\CMS\Core\Resource\Driver\StreamableDriverInterface
Definition: StreamableDriverInterface.php:29
‪TYPO3\CMS\Core\Resource\Exception
Definition: AbstractFileOperationException.php:16
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFoldersInFolder
‪array getFoldersInFolder($folderIdentifier, $start=0, $numberOfItems=0, $recursive=false, array $folderNameFilterCallbacks=[], $sort='', $sortRev=false)
Definition: LocalDriver.php:500
‪TYPO3\CMS\Core\Resource\Exception\InvalidFileNameException
Definition: InvalidFileNameException.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFolderInFolder
‪string getFolderInFolder($folderName, $folderIdentifier)
Definition: LocalDriver.php:866
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_WRITABLE
‪const CAPABILITY_WRITABLE
Definition: ResourceStorageInterface.php:175
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRootLevelFolder
‪string getRootLevelFolder()
Definition: LocalDriver.php:203
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFileWithinStorage
‪string copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName)
Definition: LocalDriver.php:905