‪TYPO3CMS  ‪main
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  public 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 
76  public function ‪__construct(array ‪$configuration = [])
77  {
78  parent::__construct(‪$configuration);
79  // The capabilities default of this driver. See CAPABILITY_* constants for possible values
80  $this->capabilities =
85  }
86 
96  {
97  $this->capabilities &= ‪$capabilities;
98 
100  }
101 
105  public function ‪processConfiguration()
106  {
107  $this->absoluteBasePath = $this->‪calculateBasePath($this->configuration);
108  $this->‪determineBaseUrl();
109  if ($this->baseUri === null) {
110  // remove public flag
111  $this->capabilities &= ~‪ResourceStorage::CAPABILITY_PUBLIC;
112  }
113  }
114 
119  public function ‪initialize()
120  {
121  }
122 
127  protected function ‪determineBaseUrl()
128  {
129  // only calculate baseURI if the storage does not enforce jumpUrl Script
131  if (!empty($this->configuration['baseUri'])) {
132  $this->baseUri = rtrim($this->configuration['baseUri'], '/') . '/';
133  } elseif (str_starts_with($this->absoluteBasePath, ‪Environment::getPublicPath())) {
134  // use site-relative URLs
135  $temporaryBaseUri = rtrim(‪PathUtility::stripPathSitePrefix($this->absoluteBasePath), '/');
136  if ($temporaryBaseUri !== '') {
137  $uriParts = explode('/', $temporaryBaseUri);
138  $uriParts = array_map('rawurlencode', $uriParts);
139  $temporaryBaseUri = implode('/', $uriParts) . '/';
140  }
141  $this->baseUri = $temporaryBaseUri;
142  }
143  }
144  }
145 
153  protected function ‪calculateBasePath(array ‪$configuration)
154  {
155  if (!array_key_exists('basePath', ‪$configuration) || empty(‪$configuration['basePath'])) {
156  throw new InvalidConfigurationException(
157  'Configuration must contain base path.',
158  1346510477
159  );
160  }
161 
162  if (!empty(‪$configuration['pathType']) && ‪$configuration['pathType'] === 'relative') {
163  $relativeBasePath = ‪$configuration['basePath'];
164  ‪$absoluteBasePath = ‪Environment::getPublicPath() . '/' . $relativeBasePath;
165  } else {
167  }
168  ‪$absoluteBasePath = $this->‪canonicalizeAndCheckFilePath($absoluteBasePath);
169  ‪$absoluteBasePath = rtrim(‪$absoluteBasePath, '/') . '/';
170  if (!is_dir(‪$absoluteBasePath)) {
171  throw new InvalidConfigurationException(
172  'Base path "' . ‪$absoluteBasePath . '" does not exist or is no directory.',
173  1299233097
174  );
175  }
176  return ‪$absoluteBasePath;
177  }
178 
186  public function ‪getPublicUrl(‪$identifier)
187  {
188  ‪$publicUrl = null;
189  if ($this->baseUri !== null) {
190  $uriParts = explode('/', ltrim(‪$identifier, '/'));
191  $uriParts = array_map('rawurlencode', $uriParts);
192  ‪$identifier = implode('/', $uriParts);
193  ‪$publicUrl = $this->baseUri . ‪$identifier;
194  }
195  return ‪$publicUrl;
196  }
197 
203  public function ‪getRootLevelFolder()
204  {
205  return '/';
206  }
207 
213  public function ‪getDefaultFolder()
214  {
215  ‪$identifier = '/user_upload/';
216  $createFolder = !$this->‪folderExists(‪$identifier);
217  if ($createFolder === true) {
218  ‪$identifier = $this->‪createFolder('user_upload');
219  }
220  return ‪$identifier;
221  }
222 
232  public function ‪createFolder($newFolderName, $parentFolderIdentifier = '', $recursive = false)
233  {
234  $parentFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
235  $newFolderName = trim($newFolderName, '/');
236  if ($recursive === false) {
237  $newFolderName = $this->‪sanitizeFileName($newFolderName);
238  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier . $newFolderName . '/');
239  ‪GeneralUtility::mkdir($this->‪getAbsolutePath($newIdentifier));
240  } else {
241  $parts = ‪GeneralUtility::trimExplode('/', $newFolderName);
242  $parts = array_map([$this, 'sanitizeFileName'], $parts);
243  $newFolderName = implode('/', $parts);
244  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier(
245  $parentFolderIdentifier . $newFolderName . '/'
246  );
247  ‪GeneralUtility::mkdir_deep($this->‪getAbsolutePath($newIdentifier));
248  }
249  return $newIdentifier;
250  }
251 
260  public function ‪getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract = [])
261  {
262  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
263  // don't use $this->fileExists() because we need the absolute path to the file anyways, so we can directly
264  // use PHP's filesystem method.
265  if (!file_exists($absoluteFilePath) || !is_file($absoluteFilePath)) {
266  throw new \InvalidArgumentException('File ' . $fileIdentifier . ' does not exist.', 1314516809);
267  }
268 
269  $dirPath = ‪PathUtility::dirname($fileIdentifier);
270  $dirPath = $this->‪canonicalizeAndCheckFolderIdentifier($dirPath);
271  return $this->‪extractFileInformation($absoluteFilePath, $dirPath, $propertiesToExtract);
272  }
273 
281  public function ‪getFolderInfoByIdentifier($folderIdentifier)
282  {
283  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
284 
285  if (!$this->‪folderExists($folderIdentifier)) {
286  throw new FolderDoesNotExistException(
287  'Folder "' . $folderIdentifier . '" does not exist.',
288  1314516810
289  );
290  }
291  $absolutePath = $this->‪getAbsolutePath($folderIdentifier);
292  return [
293  'identifier' => $folderIdentifier,
294  'name' => ‪PathUtility::basename($folderIdentifier),
295  'mtime' => filemtime($absolutePath),
296  'ctime' => filectime($absolutePath),
297  'storage' => ‪$this->storageUid,
298  ];
299  }
300 
313  public function ‪sanitizeFileName($fileName, $charset = 'utf-8')
314  {
315  if ($charset === 'utf-8') {
316  $fileName = \Normalizer::normalize((string)$fileName) ?: $fileName;
317  }
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 
359  protected function ‪getDirectoryItemList($folderIdentifier, $start, $numberOfItems, array $filterMethods, $includeFiles = true, $includeDirs = true, $recursive = false, $sort = '', $sortRev = false)
360  {
361  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
362  ‪$realPath = $this->‪getAbsolutePath($folderIdentifier);
363  if (!is_dir(‪$realPath)) {
364  throw new \InvalidArgumentException(
365  'Cannot list items in directory ' . $folderIdentifier . ' - does not exist or is no directory',
366  1314349666
367  );
368  }
369 
370  ‪$items = $this->‪retrieveFileAndFoldersInPath(‪$realPath, $recursive, $includeFiles, $includeDirs, $sort, $sortRev);
371  ‪$iterator = new \ArrayIterator(‪$items);
372  if (‪$iterator->count() === 0) {
373  return [];
374  }
375 
376  // $c is the counter for how many items we still have to fetch (-1 is unlimited)
377  ‪$c = $numberOfItems > 0 ? $numberOfItems : - 1;
378  ‪$items = [];
379  while (‪$iterator->valid() && ($numberOfItems === 0 || ‪$c > 0)) {
380  // $iteratorItem is the file or folder name
381  $iteratorItem = ‪$iterator->current();
382  // go on to the next iterator item now as we might skip this one early
383  ‪$iterator->next();
384 
385  try {
386  if (
388  $filterMethods,
389  $iteratorItem['name'],
390  $iteratorItem['identifier'],
391  $this->‪getParentFolderIdentifierOfIdentifier($iteratorItem['identifier'])
392  )
393  ) {
394  continue;
395  }
396  if ($start > 0) {
397  $start--;
398  } else {
399  // The identifier can also be an int-like string, resulting in int array keys.
400  ‪$items[$iteratorItem['identifier']] = $iteratorItem['identifier'];
401  // Decrement item counter to make sure we only return $numberOfItems
402  // we cannot do this earlier in the method (unlike moving the iterator forward) because we only add the
403  // item here
404  --‪$c;
405  }
406  } catch (InvalidPathException $e) {
407  }
408  }
409  return ‪$items;
410  }
411 
423  protected function ‪applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier)
424  {
425  foreach ($filterMethods as $filter) {
426  if (is_callable($filter)) {
427  $result = $filter($itemName, $itemIdentifier, $parentIdentifier, [], $this);
428  // We use -1 as the "don't include“ return value, for historic reasons,
429  // as call_user_func() used to return FALSE if calling the method failed.
430  if ($result === -1) {
431  return false;
432  }
433  if ($result === false) {
434  throw new \RuntimeException(
435  'Could not apply file/folder name filter ' . $filter[0] . '::' . $filter[1],
436  1476046425
437  );
438  }
439  }
440  }
441  return true;
442  }
443 
451  public function ‪getFileInFolder($fileName, $folderIdentifier)
452  {
453  return $this->‪canonicalizeAndCheckFileIdentifier($folderIdentifier . '/' . $fileName);
454  }
455 
472  public function ‪getFilesInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $filenameFilterCallbacks = [], $sort = '', $sortRev = false)
473  {
474  return $this->‪getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $filenameFilterCallbacks, true, false, $recursive, $sort, $sortRev);
475  }
476 
485  public function ‪countFilesInFolder($folderIdentifier, $recursive = false, array $filenameFilterCallbacks = [])
486  {
487  return count($this->‪getFilesInFolder($folderIdentifier, 0, 0, $recursive, $filenameFilterCallbacks));
488  }
489 
507  public function getFoldersInFolder($folderIdentifier, $start = 0, $numberOfItems = 0, $recursive = false, array $folderNameFilterCallbacks = [], $sort = '', $sortRev = false)
508  {
509  return $this->‪getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $folderNameFilterCallbacks, false, true, $recursive, $sort, $sortRev);
510  }
511 
520  public function ‪countFoldersInFolder($folderIdentifier, $recursive = false, array $folderNameFilterCallbacks = [])
521  {
522  return count($this->getFoldersInFolder($folderIdentifier, 0, 0, $recursive, $folderNameFilterCallbacks));
523  }
524 
540  protected function ‪retrieveFileAndFoldersInPath($path, $recursive = false, $includeFiles = true, $includeDirs = true, $sort = '', $sortRev = false)
541  {
542  $pathLength = strlen($this->‪getAbsoluteBasePath());
543  $iteratorMode = \FilesystemIterator::UNIX_PATHS | \FilesystemIterator::SKIP_DOTS | \FilesystemIterator::CURRENT_AS_FILEINFO | \FilesystemIterator::FOLLOW_SYMLINKS;
544  if ($recursive) {
545  ‪$iterator = new \RecursiveIteratorIterator(
546  new \RecursiveDirectoryIterator($path, $iteratorMode),
547  \RecursiveIteratorIterator::SELF_FIRST,
548  \RecursiveIteratorIterator::CATCH_GET_CHILD
549  );
550  } else {
551  ‪$iterator = new \RecursiveDirectoryIterator($path, $iteratorMode);
552  }
553 
554  $directoryEntries = [];
555  while (‪$iterator->valid()) {
557  $entry = ‪$iterator->current();
558  $isFile = $entry->isFile();
559  $isDirectory = $isFile ? false : $entry->isDir();
560  if (
561  (!$isFile && !$isDirectory) // skip non-files/non-folders
562  || ($isFile && !$includeFiles) // skip files if they are excluded
563  || ($isDirectory && !$includeDirs) // skip directories if they are excluded
564  || $entry->getFilename() === '' // skip empty entries
565  || !$entry->isReadable() // skip unreadable entries
566  ) {
567  ‪$iterator->next();
568  continue;
569  }
570  $entryIdentifier = '/' . substr($entry->getPathname(), $pathLength);
571  $entryName = ‪PathUtility::basename($entryIdentifier);
572  if ($isDirectory) {
573  $entryIdentifier .= '/';
574  }
575  $entryArray = [
576  'identifier' => $entryIdentifier,
577  'name' => $entryName,
578  'type' => $isDirectory ? 'dir' : 'file',
579  ];
580  $directoryEntries[$entryIdentifier] = $entryArray;
581  ‪$iterator->next();
582  }
583  return $this->‪sortDirectoryEntries($directoryEntries, $sort, $sortRev);
584  }
585 
599  protected function ‪sortDirectoryEntries($directoryEntries, $sort = '', $sortRev = false)
600  {
601  $entriesToSort = [];
602  foreach ($directoryEntries as $entryArray) {
603  ‪$dir = pathinfo($entryArray['name'], PATHINFO_DIRNAME) . '/';
604  $fullPath = $this->‪getAbsoluteBasePath() . $entryArray['identifier'];
605  switch ($sort) {
606  case 'size':
607  $sortingKey = '0';
608  if ($entryArray['type'] === 'file') {
609  $sortingKey = $this->‪getSpecificFileInformation($fullPath, ‪$dir, 'size');
610  }
611  // Add a character for a natural order sorting
612  $sortingKey .= 's';
613  break;
614  case 'rw':
615  $perms = $this->‪getPermissions($entryArray['identifier']);
616  $sortingKey = ($perms['r'] ? 'R' : '')
617  . ($perms['w'] ? 'W' : '');
618  break;
619  case 'fileext':
620  $sortingKey = pathinfo($entryArray['name'], PATHINFO_EXTENSION);
621  break;
622  case 'tstamp':
623  $sortingKey = $this->‪getSpecificFileInformation($fullPath, ‪$dir, 'mtime');
624  // Add a character for a natural order sorting
625  $sortingKey .= 't';
626  break;
627  case 'crdate':
628  $sortingKey = $this->‪getSpecificFileInformation($fullPath, ‪$dir, 'ctime');
629  // Add a character for a natural order sorting
630  $sortingKey .= 'c';
631  break;
632  case 'name':
633  case 'file':
634  default:
635  $sortingKey = $entryArray['name'];
636  }
637  $i = 0;
638  while (isset($entriesToSort[$sortingKey . $i])) {
639  $i++;
640  }
641  $entriesToSort[$sortingKey . $i] = $entryArray;
642  }
643  uksort($entriesToSort, 'strnatcasecmp');
644 
645  if ($sortRev) {
646  $entriesToSort = array_reverse($entriesToSort);
647  }
648 
649  return $entriesToSort;
650  }
651 
660  protected function ‪extractFileInformation($filePath, $containerPath, array $propertiesToExtract = [])
661  {
662  if (empty($propertiesToExtract)) {
663  $propertiesToExtract = [
664  'size', 'atime', 'mtime', 'ctime', 'mimetype', 'name', 'extension',
665  'identifier', 'identifier_hash', 'storage', 'folder_hash',
666  ];
667  }
668  $fileInformation = [];
669  foreach ($propertiesToExtract as $property) {
670  $fileInformation[$property] = $this->‪getSpecificFileInformation($filePath, $containerPath, $property);
671  }
672  return $fileInformation;
673  }
674 
685  public function ‪getSpecificFileInformation($fileIdentifier, $containerPath, $property)
686  {
687  ‪$identifier = $this->‪canonicalizeAndCheckFileIdentifier($containerPath . ‪PathUtility::basename($fileIdentifier));
688 
689  $fileInfo = GeneralUtility::makeInstance(FileInfo::class, $fileIdentifier);
690  switch ($property) {
691  case 'size':
692  return $fileInfo->getSize();
693  case 'atime':
694  return $fileInfo->getATime();
695  case 'mtime':
696  return $fileInfo->getMTime();
697  case 'ctime':
698  return $fileInfo->getCTime();
699  case 'name':
700  return ‪PathUtility::basename($fileIdentifier);
701  case 'extension':
702  return ‪PathUtility::pathinfo($fileIdentifier, PATHINFO_EXTENSION);
703  case 'mimetype':
704  return (string)$fileInfo->getMimeType();
705  case 'identifier':
706  return ‪$identifier;
707  case 'storage':
708  return ‪$this->storageUid;
709  case 'identifier_hash':
710  return $this->‪hashIdentifier(‪$identifier);
711  case 'folder_hash':
713  default:
714  throw new \InvalidArgumentException(sprintf('The information "%s" is not available.', $property), 1476047422);
715  }
716  }
717 
723  protected function ‪getAbsoluteBasePath()
724  {
726  }
727 
735  protected function ‪getAbsolutePath($fileIdentifier)
736  {
737  $relativeFilePath = ltrim($this->‪canonicalizeAndCheckFileIdentifier($fileIdentifier), '/');
738  $path = $this->absoluteBasePath . $relativeFilePath;
739  return $path;
740  }
741 
751  public function ‪hash($fileIdentifier, $hashAlgorithm)
752  {
753  if (!in_array($hashAlgorithm, $this->supportedHashAlgorithms)) {
754  throw new \InvalidArgumentException('Hash algorithm "' . $hashAlgorithm . '" is not supported.', 1304964032);
755  }
756  switch ($hashAlgorithm) {
757  case 'sha1':
758  $hash = sha1_file($this->‪getAbsolutePath($fileIdentifier));
759  break;
760  case 'md5':
761  $hash = md5_file($this->‪getAbsolutePath($fileIdentifier));
762  break;
763  default:
764  throw new \RuntimeException('Hash algorithm ' . $hashAlgorithm . ' is not implemented.', 1329644451);
765  }
766  return $hash;
767  }
768 
782  public function ‪addFile($localFilePath, $targetFolderIdentifier, $newFileName = '', $removeOriginal = true)
783  {
784  $localFilePath = $this->‪canonicalizeAndCheckFilePath($localFilePath);
785  // as for the "virtual storage" for backwards-compatibility, this check always fails, as the file probably lies under public web path
786  // thus, it is not checked here
787  // @todo is check in storage
788  if (str_starts_with($localFilePath, $this->absoluteBasePath) && $this->storageUid > 0) {
789  throw new \InvalidArgumentException('Cannot add a file that is already part of this storage.', 1314778269);
790  }
791  $newFileName = $this->‪sanitizeFileName($newFileName !== '' ? $newFileName : ‪PathUtility::basename($localFilePath));
792  $newFileIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier) . $newFileName;
793  $targetPath = $this->‪getAbsolutePath($newFileIdentifier);
794 
795  if ($removeOriginal) {
796  if (is_uploaded_file($localFilePath)) {
797  $result = move_uploaded_file($localFilePath, $targetPath);
798  } else {
799  $result = rename($localFilePath, $targetPath);
800  }
801  } else {
802  $result = copy($localFilePath, $targetPath);
803  }
804  if ($result === false || !file_exists($targetPath)) {
805  throw new \RuntimeException(
806  'Adding file ' . $localFilePath . ' at ' . $newFileIdentifier . ' failed.',
807  1476046453
808  );
809  }
810  clearstatcache();
811  // Change the permissions of the file
813  return $newFileIdentifier;
814  }
815 
823  public function ‪fileExists($fileIdentifier)
824  {
825  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
826  return is_file($absoluteFilePath);
827  }
828 
836  public function ‪fileExistsInFolder($fileName, $folderIdentifier)
837  {
838  ‪$identifier = $folderIdentifier . '/' . $fileName;
840  return $this->‪fileExists(‪$identifier);
841  }
842 
850  public function ‪folderExists($folderIdentifier)
851  {
852  $absoluteFilePath = $this->‪getAbsolutePath($folderIdentifier);
853  return is_dir($absoluteFilePath);
854  }
855 
863  public function ‪folderExistsInFolder($folderName, $folderIdentifier)
864  {
865  ‪$identifier = $folderIdentifier . '/' . $folderName;
867  return $this->‪folderExists(‪$identifier);
868  }
869 
877  public function ‪getFolderInFolder($folderName, $folderIdentifier)
878  {
879  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier . '/' . $folderName);
880  return $folderIdentifier;
881  }
882 
891  public function ‪replaceFile($fileIdentifier, $localFilePath)
892  {
893  $filePath = $this->‪getAbsolutePath($fileIdentifier);
894  if (is_uploaded_file($localFilePath)) {
895  $result = move_uploaded_file($localFilePath, $filePath);
896  } else {
897  $result = rename($localFilePath, $filePath);
898  }
900  if ($result === false) {
901  throw new \RuntimeException('Replacing file ' . $fileIdentifier . ' with ' . $localFilePath . ' failed.', 1315314711);
902  }
903  return $result;
904  }
905 
916  public function ‪copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName)
917  {
918  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
919  $newIdentifier = $targetFolderIdentifier . '/' . $fileName;
920  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($newIdentifier);
921 
922  $absoluteFilePath = $this->‪getAbsolutePath($newIdentifier);
923  copy($sourcePath, $absoluteFilePath);
924  ‪GeneralUtility::fixPermissions($absoluteFilePath);
925  return $newIdentifier;
926  }
927 
939  public function ‪moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName)
940  {
941  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
942  $targetIdentifier = $targetFolderIdentifier . '/' . $newFileName;
943  $targetIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($targetIdentifier);
944  $result = rename($sourcePath, $this->‪getAbsolutePath($targetIdentifier));
945  if ($result === false) {
946  throw new \RuntimeException('Moving file ' . $sourcePath . ' to ' . $targetIdentifier . ' failed.', 1315314712);
947  }
948  return $targetIdentifier;
949  }
950 
958  protected function ‪copyFileToTemporaryPath($fileIdentifier)
959  {
960  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
961  $temporaryPath = $this->‪getTemporaryPathForFile($fileIdentifier);
962  $result = copy($sourcePath, $temporaryPath);
963  touch($temporaryPath, (int)filemtime($sourcePath));
964  if ($result === false) {
965  throw new \RuntimeException(
966  'Copying file "' . $fileIdentifier . '" to temporary path "' . $temporaryPath . '" failed.',
967  1320577649
968  );
969  }
970  return $temporaryPath;
971  }
972 
981  protected function ‪recycleFileOrFolder($filePath, $recycleDirectory)
982  {
983  $destinationFile = $recycleDirectory . '/' . ‪PathUtility::basename($filePath);
984  if (file_exists($destinationFile)) {
985  $timeStamp = \DateTimeImmutable::createFromFormat('U.u', (string)microtime(true))->format('YmdHisu');
986  $destinationFile = $recycleDirectory . '/' . $timeStamp . '_' . ‪PathUtility::basename($filePath);
987  }
988  $result = rename($filePath, $destinationFile);
989  // Update the mtime for the file, so the recycler garbage collection task knows which files to delete
990  // Using ctime() is not possible there since this is not supported on Windows
991  if ($result) {
992  touch($destinationFile);
993  }
994  return $result;
995  }
996 
1007  protected function ‪createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier)
1008  {
1009  $identifierMap = [];
1010  $identifierMap[$sourceFolderIdentifier] = $targetFolderIdentifier;
1011  foreach ($filesAndFolders as $oldItem) {
1012  if ($oldItem['type'] === 'dir') {
1013  $oldIdentifier = $oldItem['identifier'];
1014  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier(
1015  str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
1016  );
1017  } else {
1018  $oldIdentifier = $oldItem['identifier'];
1019  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier(
1020  str_replace($sourceFolderIdentifier, $targetFolderIdentifier, $oldItem['identifier'])
1021  );
1022  }
1023  if (!file_exists($this->‪getAbsolutePath($newIdentifier))) {
1024  throw new FileOperationErrorException(
1025  sprintf('File "%1$s" was not found (should have been copied/moved from "%2$s").', $newIdentifier, $oldIdentifier),
1026  1330119453
1027  );
1028  }
1029  $identifierMap[$oldIdentifier] = $newIdentifier;
1030  }
1031  return $identifierMap;
1032  }
1033 
1044  public function ‪moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
1045  {
1046  $sourcePath = $this->‪getAbsolutePath($sourceFolderIdentifier);
1047  $relativeTargetPath = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
1048  $targetPath = $this->‪getAbsolutePath($relativeTargetPath);
1049  // get all files and folders we are going to move, to have a map for updating later.
1050  $filesAndFolders = $this->‪retrieveFileAndFoldersInPath($sourcePath, true);
1051  $result = rename($sourcePath, $targetPath);
1052  if ($result === false) {
1053  throw new \RuntimeException('Moving folder ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320711817);
1054  }
1055  // Create a mapping from old to new identifiers
1056  $identifierMap = $this->‪createIdentifierMap($filesAndFolders, $sourceFolderIdentifier, $relativeTargetPath);
1057  return $identifierMap;
1058  }
1059 
1070  public function ‪copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
1071  {
1072  // This target folder path already includes the topmost level, i.e. the folder this method knows as $folderToCopy.
1073  // We can thus rely on this folder being present and just create the subfolder we want to copy to.
1074  $newFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($targetFolderIdentifier . '/' . $newFolderName);
1075  $sourceFolderPath = $this->‪getAbsolutePath($sourceFolderIdentifier);
1076  $targetFolderPath = $this->‪getAbsolutePath($newFolderIdentifier);
1077 
1078  mkdir($targetFolderPath);
1079  ‪$iterator = new \RecursiveIteratorIterator(
1080  new \RecursiveDirectoryIterator($sourceFolderPath),
1081  \RecursiveIteratorIterator::SELF_FIRST,
1082  \RecursiveIteratorIterator::CATCH_GET_CHILD
1083  );
1084  // Rewind the iterator as this is important for some systems e.g. Windows
1085  ‪$iterator->rewind();
1086  while (‪$iterator->valid()) {
1088  $current = ‪$iterator->current();
1089  $fileName = $current->getFilename();
1090  $itemSubPath = GeneralUtility::fixWindowsFilePath(‪$iterator->getSubPathname());
1091  if ($current->isDir() && !($fileName === '..' || $fileName === '.')) {
1092  ‪GeneralUtility::mkdir($targetFolderPath . '/' . $itemSubPath);
1093  } elseif ($current->isFile()) {
1094  $copySourcePath = $sourceFolderPath . '/' . $itemSubPath;
1095  $copyTargetPath = $targetFolderPath . '/' . $itemSubPath;
1096  $result = copy($copySourcePath, $copyTargetPath);
1097  if ($result === false) {
1098  // rollback
1099  ‪GeneralUtility::rmdir($targetFolderIdentifier, true);
1100  throw new FileOperationErrorException(
1101  'Copying resource "' . $copySourcePath . '" to "' . $copyTargetPath . '" failed.',
1102  1330119452
1103  );
1104  }
1105  }
1106  ‪$iterator->next();
1107  }
1108  ‪GeneralUtility::fixPermissions($targetFolderPath, true);
1109  return true;
1110  }
1111 
1121  public function ‪renameFile($fileIdentifier, $newName)
1122  {
1123  // Makes sure the Path given as parameter is valid
1124  $newName = $this->‪sanitizeFileName($newName);
1125  $newIdentifier = rtrim(GeneralUtility::fixWindowsFilePath(‪PathUtility::dirname($fileIdentifier)), '/') . '/' . $newName;
1126  $newIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($newIdentifier);
1127  // The target should not exist already
1128  if ($this->‪fileExists($newIdentifier)) {
1129  throw new ExistingTargetFileNameException(
1130  'The target file "' . $newIdentifier . '" already exists.',
1131  1320291063
1132  );
1133  }
1134  $sourcePath = $this->‪getAbsolutePath($fileIdentifier);
1135  $targetPath = $this->‪getAbsolutePath($newIdentifier);
1136  $result = rename($sourcePath, $targetPath);
1137  if ($result === false) {
1138  throw new \RuntimeException('Renaming file ' . $sourcePath . ' to ' . $targetPath . ' failed.', 1320375115);
1139  }
1140  return $newIdentifier;
1141  }
1142 
1151  public function ‪renameFolder($folderIdentifier, $newName)
1152  {
1153  $folderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($folderIdentifier);
1154  $newName = $this->‪sanitizeFileName($newName);
1155 
1156  $newIdentifier = ‪PathUtility::dirname($folderIdentifier) . '/' . $newName;
1157  $newIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($newIdentifier);
1158 
1159  $sourcePath = $this->‪getAbsolutePath($folderIdentifier);
1160  $targetPath = $this->‪getAbsolutePath($newIdentifier);
1161  // get all files and folders we are going to move, to have a map for updating later.
1162  $filesAndFolders = $this->‪retrieveFileAndFoldersInPath($sourcePath, true);
1163  $result = rename($sourcePath, $targetPath);
1164  if ($result === false) {
1165  throw new \RuntimeException(sprintf('Renaming folder "%1$s" to "%2$s" failed."', $sourcePath, $targetPath), 1320375116);
1166  }
1167  try {
1168  // Create a mapping from old to new identifiers
1169  $identifierMap = $this->‪createIdentifierMap($filesAndFolders, $folderIdentifier, $newIdentifier);
1170  } catch (\Exception $e) {
1171  rename($targetPath, $sourcePath);
1172  throw new \RuntimeException(
1173  sprintf(
1174  'Creating filename mapping after renaming "%1$s" to "%2$s" failed. Reverted rename operation.\\n\\nOriginal error: %3$s"',
1175  $sourcePath,
1176  $targetPath,
1177  $e->getMessage()
1178  ),
1179  1334160746
1180  );
1181  }
1182  return $identifierMap;
1183  }
1184 
1194  public function ‪deleteFile($fileIdentifier)
1195  {
1196  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1197  $result = unlink($filePath);
1198 
1199  if ($result === false) {
1200  throw new \RuntimeException('Deletion of file ' . $fileIdentifier . ' failed.', 1320855304);
1201  }
1202  return $result;
1203  }
1204 
1214  public function ‪deleteFolder($folderIdentifier, $deleteRecursively = false)
1215  {
1216  $folderPath = $this->‪getAbsolutePath($folderIdentifier);
1217  $recycleDirectory = $this->‪getRecycleDirectory($folderPath);
1218  if (!empty($recycleDirectory) && $folderPath !== $recycleDirectory) {
1219  $result = $this->‪recycleFileOrFolder($folderPath, $recycleDirectory);
1220  } else {
1221  $result = ‪GeneralUtility::rmdir($folderPath, $deleteRecursively);
1222  }
1223  if ($result === false) {
1224  throw new FileOperationErrorException(
1225  'Deleting folder "' . $folderIdentifier . '" failed.',
1226  1330119451
1227  );
1228  }
1229  return $result;
1230  }
1231 
1238  public function ‪isFolderEmpty($folderIdentifier)
1239  {
1240  $path = $this->‪getAbsolutePath($folderIdentifier);
1241  $dirHandle = opendir($path);
1242  if ($dirHandle === false) {
1243  return true;
1244  }
1245  while ($entry = readdir($dirHandle)) {
1246  if ($entry !== '.' && $entry !== '..') {
1247  closedir($dirHandle);
1248  return false;
1249  }
1250  }
1251  closedir($dirHandle);
1252  return true;
1253  }
1254 
1265  public function ‪getFileForLocalProcessing($fileIdentifier, $writable = true)
1266  {
1267  if ($writable === false) {
1268  return $this->‪getAbsolutePath($fileIdentifier);
1269  }
1270  return $this->‪copyFileToTemporaryPath($fileIdentifier);
1271  }
1272 
1280  public function ‪getPermissions(‪$identifier)
1281  {
1282  $path = $this->‪getAbsolutePath(‪$identifier);
1283  $permissionBits = fileperms($path);
1284  if ($permissionBits === false) {
1285  throw new ResourcePermissionsUnavailableException('Error while fetching permissions for ' . $path, 1319455097);
1286  }
1287  return [
1288  'r' => (bool)is_readable($path),
1289  'w' => (bool)is_writable($path),
1290  ];
1291  }
1292 
1302  public function ‪isWithin($folderIdentifier, ‪$identifier)
1303  {
1304  $folderIdentifier = $this->‪canonicalizeAndCheckFileIdentifier($folderIdentifier);
1305  $entryIdentifier = $this->‪canonicalizeAndCheckFileIdentifier(‪$identifier);
1306  if ($folderIdentifier === $entryIdentifier) {
1307  return true;
1308  }
1309  // File identifier canonicalization will not modify a single slash so
1310  // we must not append another slash in that case.
1311  if ($folderIdentifier !== '/') {
1312  $folderIdentifier .= '/';
1313  }
1314  return str_starts_with($entryIdentifier, $folderIdentifier);
1315  }
1316 
1325  public function ‪createFile($fileName, $parentFolderIdentifier)
1326  {
1327  $fileName = $this->‪sanitizeFileName(ltrim($fileName, '/'));
1328  $parentFolderIdentifier = $this->‪canonicalizeAndCheckFolderIdentifier($parentFolderIdentifier);
1329  $fileIdentifier = $this->‪canonicalizeAndCheckFileIdentifier(
1330  $parentFolderIdentifier . $fileName
1331  );
1332  $absoluteFilePath = $this->‪getAbsolutePath($fileIdentifier);
1333  $result = touch($absoluteFilePath);
1334  ‪GeneralUtility::fixPermissions($absoluteFilePath);
1335  clearstatcache();
1336  if ($result !== true) {
1337  throw new \RuntimeException('Creating file ' . $fileIdentifier . ' failed.', 1320569854);
1338  }
1339  return $fileIdentifier;
1340  }
1341 
1351  public function ‪getFileContents($fileIdentifier)
1352  {
1353  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1354  return is_readable($filePath) ? (string)file_get_contents($filePath) : '';
1355  }
1356 
1365  public function ‪setFileContents($fileIdentifier, $contents)
1366  {
1367  $filePath = $this->‪getAbsolutePath($fileIdentifier);
1368  $result = file_put_contents($filePath, $contents);
1369 
1370  // Make sure later calls to filesize() etc. return correct values.
1371  clearstatcache(true, $filePath);
1372 
1373  if ($result === false) {
1374  throw new \RuntimeException('Setting contents of file "' . $fileIdentifier . '" failed.', 1325419305);
1375  }
1376  return $result;
1377  }
1378 
1385  public function ‪getRole($folderIdentifier)
1386  {
1387  $name = ‪PathUtility::basename($folderIdentifier);
1388  $role = $this->mappingFolderNameToRole[$name] ?? ‪FolderInterface::ROLE_DEFAULT;
1389  return $role;
1390  }
1391 
1399  public function ‪dumpFileContents(‪$identifier)
1400  {
1402  }
1407  public function ‪streamFile(string ‪$identifier, array $properties): ResponseInterface
1408  {
1409  $fileInfo = $this->‪getFileInfoByIdentifier($identifier, ['name', 'mimetype', 'mtime', 'size']);
1410  $downloadName = $properties['filename_overwrite'] ?? $fileInfo['name'] ?? '';
1411  $mimeType = $properties['mimetype_overwrite'] ?? $fileInfo['mimetype'] ?? '';
1412  $contentDisposition = ($properties['as_download'] ?? false) ? 'attachment' : 'inline';
1413 
1414  $filePath = $this->‪getAbsolutePath($this->‪canonicalizeAndCheckFileIdentifier($identifier));
1415 
1416  return new ‪Response(
1417  new ‪SelfEmittableLazyOpenStream($filePath),
1418  200,
1419  [
1420  'Content-Disposition' => $contentDisposition . '; filename="' . $downloadName . '"',
1421  'Content-Type' => $mimeType,
1422  'Content-Length' => (string)$fileInfo['size'],
1423  'Last-Modified' => gmdate('D, d M Y H:i:s', $fileInfo['mtime']) . ' GMT',
1424  // Cache-Control header is needed here to solve an issue with browser IE8 and lower
1425  // See for more information: http://support.microsoft.com/kb/323308
1426  'Cache-Control' => '',
1427  ]
1428  );
1429  }
1430 
1438  protected function ‪getRecycleDirectory($path)
1439  {
1440  $recyclerSubdirectory = array_search(‪FolderInterface::ROLE_RECYCLER, $this->mappingFolderNameToRole, true);
1441  if ($recyclerSubdirectory === false) {
1442  return '';
1443  }
1444  $rootDirectory = rtrim($this->‪getAbsolutePath($this->‪getRootLevelFolder()), '/');
1445  $searchDirectory = ‪PathUtility::dirname($path);
1446  // Check if file or folder to be deleted is inside a recycler directory
1447  if ($this->‪getRole($searchDirectory) === ‪FolderInterface::ROLE_RECYCLER) {
1448  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1449  // Check if file or folder to be deleted is inside the root recycler
1450  if ($searchDirectory == $rootDirectory) {
1451  return '';
1452  }
1453  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1454  }
1455  // Search for the closest recycler directory
1456  while ($searchDirectory) {
1457  $recycleDirectory = $searchDirectory . '/' . $recyclerSubdirectory;
1458  if (is_dir($recycleDirectory)) {
1459  return $recycleDirectory;
1460  }
1461  if ($searchDirectory === $rootDirectory) {
1462  return '';
1463  }
1464  $searchDirectory = ‪PathUtility::dirname($searchDirectory);
1465  }
1466 
1467  return '';
1468  }
1469 }
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\retrieveFileAndFoldersInPath
‪array retrieveFileAndFoldersInPath($path, $recursive=false, $includeFiles=true, $includeDirs=true, $sort='', $sortRev=false)
Definition: LocalDriver.php:536
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$items
‪while($iterator->valid() &&($numberOfItems===0|| $c > 0)) return $items
Definition: LocalDriver.php:375
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:916
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRole
‪string getRole($folderIdentifier)
Definition: LocalDriver.php:1381
‪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:72
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static stripPathSitePrefix(string $path)
Definition: PathUtility.php:428
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$absoluteBasePath
‪string $absoluteBasePath
Definition: LocalDriver.php:51
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\folderExistsInFolder
‪bool folderExistsInFolder($folderName, $folderIdentifier)
Definition: LocalDriver.php:859
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\deleteFolder
‪bool deleteFolder($folderIdentifier, $deleteRecursively=false)
Definition: LocalDriver.php:1210
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\canonicalizeAndCheckFilePath
‪string canonicalizeAndCheckFilePath($filePath)
Definition: AbstractHierarchicalFilesystemDriver.php:46
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\determineBaseUrl
‪determineBaseUrl()
Definition: LocalDriver.php:123
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\recycleFileOrFolder
‪bool recycleFileOrFolder($filePath, $recycleDirectory)
Definition: LocalDriver.php:977
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFilesInFolder
‪array getFilesInFolder($folderIdentifier, $start=0, $numberOfItems=0, $recursive=false, array $filenameFilterCallbacks=[], $sort='', $sortRev=false)
Definition: LocalDriver.php:468
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\streamFile
‪streamFile(string $identifier, array $properties)
Definition: LocalDriver.php:1403
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\addFile
‪string addFile($localFilePath, $targetFolderIdentifier, $newFileName='', $removeOriginal=true)
Definition: LocalDriver.php:778
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$realPath
‪$realPath
Definition: LocalDriver.php:358
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\canonicalizeAndCheckFileIdentifier
‪string canonicalizeAndCheckFileIdentifier($fileIdentifier)
Definition: AbstractHierarchicalFilesystemDriver.php:63
‪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:1117
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\countFilesInFolder
‪int countFilesInFolder($folderIdentifier, $recursive=false, array $filenameFilterCallbacks=[])
Definition: LocalDriver.php:481
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_DEFAULT
‪const ROLE_DEFAULT
Definition: FolderInterface.php:26
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver
Definition: LocalDriver.php:41
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFolderInfoByIdentifier
‪array getFolderInfoByIdentifier($folderIdentifier)
Definition: LocalDriver.php:277
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\extractFileInformation
‪array extractFileInformation($filePath, $containerPath, array $propertiesToExtract=[])
Definition: LocalDriver.php:656
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\hashIdentifier
‪string hashIdentifier($identifier)
Definition: AbstractDriver.php:140
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileForLocalProcessing
‪string getFileForLocalProcessing($fileIdentifier, $writable=true)
Definition: LocalDriver.php:1261
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\sortDirectoryEntries
‪array sortDirectoryEntries($directoryEntries, $sort='', $sortRev=false)
Definition: LocalDriver.php:595
‪TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
Definition: ExistingTargetFileNameException.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getDefaultFolder
‪string getDefaultFolder()
Definition: LocalDriver.php:209
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\isFolderEmpty
‪bool isFolderEmpty($folderIdentifier)
Definition: LocalDriver.php:1234
‪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:516
‪TYPO3\CMS\Core\Resource\Exception\ResourcePermissionsUnavailableException
Definition: ResourcePermissionsUnavailableException.php:26
‪$dir
‪$dir
Definition: validateRstFiles.php:257
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createFolder
‪string createFolder($newFolderName, $parentFolderIdentifier='', $recursive=false)
Definition: LocalDriver.php:228
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\deleteFile
‪bool deleteFile($fileIdentifier)
Definition: LocalDriver.php:1190
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getSpecificFileInformation
‪bool int string getSpecificFileInformation($fileIdentifier, $containerPath, $property)
Definition: LocalDriver.php:681
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getAbsolutePath
‪string getAbsolutePath($fileIdentifier)
Definition: LocalDriver.php:731
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static basename(string $path)
Definition: PathUtility.php:219
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\initialize
‪initialize()
Definition: LocalDriver.php:115
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_TEMPORARY
‪const ROLE_TEMPORARY
Definition: FolderInterface.php:29
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createFile
‪string createFile($fileName, $parentFolderIdentifier)
Definition: LocalDriver.php:1321
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRecycleDirectory
‪string getRecycleDirectory($path)
Definition: LocalDriver.php:1434
‪TYPO3\CMS\Webhooks\Message\$publicUrl
‪identifier readonly string readonly string $publicUrl
Definition: FileUpdatedMessage.php:36
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static dirname(string $path)
Definition: PathUtility.php:243
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\setFileContents
‪int setFileContents($fileIdentifier, $contents)
Definition: LocalDriver.php:1361
‪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:747
‪TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException
Definition: InvalidConfigurationException.php:24
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getPublicUrl
‪string null getPublicUrl($identifier)
Definition: LocalDriver.php:182
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\hasCapability
‪bool hasCapability($capability)
Definition: AbstractDriver.php:112
‪TYPO3\CMS\Core\Utility\GeneralUtility\fixPermissions
‪static mixed fixPermissions($path, $recursive=false)
Definition: GeneralUtility.php:1594
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$supportedHashAlgorithms
‪array $supportedHashAlgorithms
Definition: LocalDriver.php:57
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\canonicalizeAndCheckFolderIdentifier
‪array< string|int, getDirectoryItemList( $folderIdentifier, $start, $numberOfItems, array $filterMethods, $includeFiles=true, $includeDirs=true, $recursive=false, $sort='', $sortRev=false) { $folderIdentifier=$this-> canonicalizeAndCheckFolderIdentifier($folderIdentifier)
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir_deep
‪static mkdir_deep($directory)
Definition: GeneralUtility.php:1753
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\moveFileWithinStorage
‪string moveFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $newFileName)
Definition: LocalDriver.php:935
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\folderExists
‪bool folderExists($folderIdentifier)
Definition: LocalDriver.php:846
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileInfoByIdentifier
‪array getFileInfoByIdentifier($fileIdentifier, array $propertiesToExtract=[])
Definition: LocalDriver.php:256
‪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:91
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$iterator
‪$iterator
Definition: LocalDriver.php:367
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\dumpFileContents
‪dumpFileContents($identifier)
Definition: LocalDriver.php:1395
‪TYPO3\CMS\Core\Resource\Driver\AbstractDriver\getTemporaryPathForFile
‪non empty string getTemporaryPathForFile($fileIdentifier)
Definition: AbstractDriver.php:127
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_HIERARCHICAL_IDENTIFIERS
‪const CAPABILITY_HIERARCHICAL_IDENTIFIERS
Definition: ResourceStorageInterface.php:39
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\isWithin
‪bool isWithin($folderIdentifier, $identifier)
Definition: LocalDriver.php:1298
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_BROWSABLE
‪const CAPABILITY_BROWSABLE
Definition: ResourceStorageInterface.php:26
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getDirectoryItemList
‪array< string|int, getFoldersInFolder( $folderIdentifier, $start=0, $numberOfItems=0, $recursive=false, array $folderNameFilterCallbacks=[], $sort='', $sortRev=false) { return $this-> getDirectoryItemList($folderIdentifier, $start, $numberOfItems, $folderNameFilterCallbacks, false, true, $recursive, $sort, $sortRev)
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileContents
‪string getFileContents($fileIdentifier)
Definition: LocalDriver.php:1347
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFileToTemporaryPath
‪string copyFileToTemporaryPath($fileIdentifier)
Definition: LocalDriver.php:954
‪TYPO3\CMS\Core\Resource\Exception
Definition: Exception.php:22
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\processConfiguration
‪processConfiguration()
Definition: LocalDriver.php:101
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getAbsoluteBasePath
‪string getAbsoluteBasePath()
Definition: LocalDriver.php:719
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\createIdentifierMap
‪array createIdentifierMap(array $filesAndFolders, $sourceFolderIdentifier, $targetFolderIdentifier)
Definition: LocalDriver.php:1003
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:127
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\calculateBasePath
‪string calculateBasePath(array $configuration)
Definition: LocalDriver.php:149
‪TYPO3\CMS\Core\Resource\Driver
Definition: AbstractDriver.php:16
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFolderWithinStorage
‪bool copyFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
Definition: LocalDriver.php:1066
‪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:1806
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\replaceFile
‪bool replaceFile($fileIdentifier, $localFilePath)
Definition: LocalDriver.php:887
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_PUBLIC
‪const CAPABILITY_PUBLIC
Definition: ResourceStorageInterface.php:30
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\renameFolder
‪array renameFolder($folderIdentifier, $newName)
Definition: LocalDriver.php:1147
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$items
‪if(!is_dir($realPath)) $items
Definition: LocalDriver.php:366
‪TYPO3\CMS\Core\Resource\Driver\AbstractHierarchicalFilesystemDriver\getParentFolderIdentifierOfIdentifier
‪mixed getParentFolderIdentifierOfIdentifier($fileIdentifier)
Definition: AbstractHierarchicalFilesystemDriver.php:97
‪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:832
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\fileExists
‪bool fileExists($fileIdentifier)
Definition: LocalDriver.php:819
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\moveFolderWithinStorage
‪array moveFolderWithinStorage($sourceFolderIdentifier, $targetFolderIdentifier, $newFolderName)
Definition: LocalDriver.php:1040
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\applyFilterMethodsToDirectoryItem
‪bool applyFilterMethodsToDirectoryItem(array $filterMethods, $itemName, $itemIdentifier, $parentIdentifier)
Definition: LocalDriver.php:419
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFileInFolder
‪string getFileInFolder($fileName, $folderIdentifier)
Definition: LocalDriver.php:447
‪TYPO3\CMS\Core\Http\SelfEmittableLazyOpenStream
Definition: SelfEmittableLazyOpenStream.php:32
‪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:309
‪TYPO3\CMS\Core\Utility\GeneralUtility\mkdir
‪static bool mkdir($newFolder)
Definition: GeneralUtility.php:1736
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getPermissions
‪array getPermissions($identifier)
Definition: LocalDriver.php:1276
‪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\Exception\InvalidFileNameException
Definition: InvalidFileNameException.php:24
‪TYPO3\CMS\Core\Utility\PathUtility\pathinfo
‪static string string[] pathinfo(string $path, int $options=PATHINFO_ALL)
Definition: PathUtility.php:270
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getFolderInFolder
‪string getFolderInFolder($folderName, $folderIdentifier)
Definition: LocalDriver.php:873
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\CAPABILITY_WRITABLE
‪const CAPABILITY_WRITABLE
Definition: ResourceStorageInterface.php:35
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\$c
‪if($iterator->count()===0) $c
Definition: LocalDriver.php:373
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\getRootLevelFolder
‪string getRootLevelFolder()
Definition: LocalDriver.php:199
‪TYPO3\CMS\Core\Resource\Driver\LocalDriver\copyFileWithinStorage
‪string copyFileWithinStorage($fileIdentifier, $targetFolderIdentifier, $fileName)
Definition: LocalDriver.php:912