‪TYPO3CMS  ‪main
ResourceStorage.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\EventDispatcher\EventDispatcherInterface;
19 use Psr\Http\Message\ResponseInterface;
20 use Psr\Http\Message\ServerRequestInterface;
30 use TYPO3\CMS\Core\Resource\Driver\DriverInterface;
94 
128 {
134  protected ‪$driver;
135 
141  protected ‪$storageRecord;
142 
148  protected ‪$configuration;
149 
153  protected ‪$fileProcessingService;
154 
163  protected ‪$evaluatePermissions = false;
164 
170  protected ‪$fileMounts = [];
171 
178  protected ‪$userPermissions = [];
179 
184 
188  protected ‪$eventDispatcher;
189 
193  protected ‪$processingFolder;
194 
201 
207  protected ‪$isOnline;
208 
212  protected ‪$isDefault = false;
213 
220 
224  public const ‪PROCESSING_FOLDER_LEVELS = 2;
225 
232  public function ‪__construct(DriverInterface ‪$driver, array ‪$storageRecord, EventDispatcherInterface ‪$eventDispatcher = null)
233  {
234  if (!isset(‪$storageRecord['uid'])) {
235  throw new \InvalidArgumentException(
236  '$storageRecord[\'uid\'] is unexpectedly not set',
237  1688920972
238  );
239  }
240 
241  $this->storageRecord = ‪$storageRecord;
242  $this->eventDispatcher = ‪$eventDispatcher ?? GeneralUtility::makeInstance(EventDispatcherInterface::class);
243  if (is_array(‪$storageRecord['configuration'] ?? null)) {
244  $this->configuration = ‪$storageRecord['configuration'];
245  } elseif (!empty(‪$storageRecord['configuration'] ?? '')) {
246  $this->configuration = GeneralUtility::makeInstance(FlexFormService::class)->convertFlexFormContentToArray(‪$storageRecord['configuration']);
247  } else {
248  $this->configuration = [];
249  }
250 
251  $capabilityBits = 0;
252  $capabilityBits += ($this->storageRecord['is_browsable'] ?? null ? ‪Capabilities::CAPABILITY_BROWSABLE : 0);
253  $capabilityBits += ($this->storageRecord['is_public'] ?? null ? ‪Capabilities::CAPABILITY_PUBLIC : 0);
254  $capabilityBits += ($this->storageRecord['is_writable'] ?? null ? ‪Capabilities::CAPABILITY_WRITABLE : 0);
255  // Always let the driver decide whether to set this capability
257 
258  $this->capabilities = new ‪Capabilities($capabilityBits);
259 
260  $this->driver = ‪$driver;
261  $this->driver->setStorageUid((int)‪$storageRecord['uid']);
262  $this->driver->mergeConfigurationCapabilities($this->capabilities);
263  try {
264  $this->driver->processConfiguration();
265  } catch (‪InvalidConfigurationException $e) {
266  // Configuration error
267  $this->‪isOnline = false;
268 
269  $message = sprintf(
270  'Failed initializing storage [%d] "%s", error: %s',
271  $this->‪getUid(),
272  $this->‪getName(),
273  $e->getMessage()
274  );
275 
276  // create a dedicated logger instance because we need a logger in the constructor
277  GeneralUtility::makeInstance(LogManager::class)->getLogger(static::class)->error($message);
278  }
279  $this->driver->initialize();
280  $this->capabilities = $this->driver->getCapabilities();
281 
282  $this->‪isDefault = (isset(‪$storageRecord['is_default']) && ‪$storageRecord['is_default'] == 1);
284  }
285 
291  public function ‪getConfiguration()
292  {
294  }
295 
299  public function ‪setConfiguration(array ‪$configuration)
300  {
301  $this->configuration = ‪$configuration;
302  }
303 
309  public function ‪getStorageRecord()
310  {
312  }
313 
319  public function ‪setDriver(DriverInterface ‪$driver)
320  {
321  $this->driver = ‪$driver;
322  return ‪$this;
323  }
324 
330  protected function ‪getDriver()
331  {
332  return ‪$this->driver;
333  }
334 
340  public function ‪getName()
341  {
342  return $this->storageRecord['name'];
343  }
344 
350  public function ‪getUid()
351  {
352  return (int)($this->storageRecord['uid'] ?? 0);
353  }
354 
360  public function ‪hasChildren()
361  {
362  return true;
363  }
364 
371  public function ‪isFallbackStorage(): bool
372  {
373  return $this->‪getUid() === 0;
374  }
375 
376  /*********************************
377  * Capabilities
378  ********************************/
382  public function ‪getCapabilities(): Capabilities
383  {
384  return ‪$this->capabilities;
385  }
386 
392  protected function ‪hasCapability(int $capability): bool
393  {
394  return $this->capabilities->hasCapability($capability);
395  }
396 
405  public function ‪isPublic()
406  {
408  }
409 
416  public function ‪isWritable()
417  {
419  }
420 
426  public function ‪isBrowsable()
427  {
429  }
430 
434  public function ‪hasHierarchicalIdentifiers(): bool
435  {
437  }
438 
446  public function ‪searchFiles(FileSearchDemand $searchDemand, Folder $folder = null, bool $useFilters = true): FileSearchResultInterface
447  {
448  $folder = $folder ?? $this->‪getRootLevelFolder();
449  if (!$folder->‪checkActionPermission('read')) {
450  return new EmptyFileSearchResult();
451  }
452 
453  return new DriverFilteredSearchResult(
455  $searchDemand->withFolder($folder)
456  ),
457  ‪$this->driver,
458  $useFilters ? ‪$this->getFileAndFolderNameFilters() : []
459  );
460  }
461 
467  public function ‪usesCaseSensitiveIdentifiers()
468  {
469  return $this->driver->isCaseSensitiveFileSystem();
470  }
471 
477  public function ‪isOnline()
478  {
479  if ($this->‪isOnline === null) {
480  if ($this->‪getUid() === 0) {
481  $this->‪isOnline = true;
482  }
483  // the storage is not marked as online for a longer time
484  if ($this->storageRecord['is_online'] == 0) {
485  $this->‪isOnline = false;
486  }
487  if ($this->‪isOnline !== false) {
488  if ((‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
489  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isFrontend()
490  ) {
491  // All files are ALWAYS available in the frontend
492  $this->‪isOnline = true;
493  } else {
494  // check if the storage is disabled temporary for now
495  $registryObject = GeneralUtility::makeInstance(Registry::class);
496  $offlineUntil = $registryObject->get('core', 'sys_file_storage-' . $this->‪getUid() . '-offline-until');
497  if ($offlineUntil && $offlineUntil > time()) {
498  $this->‪isOnline = false;
499  } else {
500  $this->‪isOnline = true;
501  }
502  }
503  }
504  }
505  return ‪$this->isOnline;
506  }
507 
513  public function ‪autoExtractMetadataEnabled()
514  {
515  return !empty($this->storageRecord['auto_extract_metadata']);
516  }
517 
525  public function ‪markAsPermanentlyOffline()
526  {
527  if ($this->‪getUid() > 0) {
528  // @todo: move this to the storage repository
529  GeneralUtility::makeInstance(ConnectionPool::class)
530  ->getConnectionForTable('sys_file_storage')
531  ->update(
532  'sys_file_storage',
533  ['is_online' => 0],
534  ['uid' => (int)$this->‪getUid()]
535  );
536  }
537  $this->storageRecord['is_online'] = 0;
538  $this->‪isOnline = false;
539  }
540 
547  public function ‪markAsTemporaryOffline()
548  {
549  $registryObject = GeneralUtility::makeInstance(Registry::class);
550  $registryObject->set('core', 'sys_file_storage-' . $this->‪getUid() . '-offline-until', time() + 60 * 5);
551  $this->storageRecord['is_online'] = 0;
552  $this->‪isOnline = false;
553  }
554 
555  /*********************************
556  * User Permissions / File Mounts
557  ********************************/
567  public function ‪addFileMount($folderIdentifier, $additionalData = [])
568  {
569  // check for the folder before we add it as a filemount
570  if ($this->driver->folderExists($folderIdentifier) === false) {
571  // if there is an error, this is important and should be handled
572  // as otherwise the user would see the whole storage without any restrictions for the filemounts
573  throw new ‪FolderDoesNotExistException('Folder for file mount ' . $folderIdentifier . ' does not exist.', 1334427099);
574  }
575  $data = $this->driver->getFolderInfoByIdentifier($folderIdentifier);
576  $folderObject = $this->‪createFolderObject($data['identifier'], $data['name']);
577  // Use the canonical identifier instead of the user provided one!
578  $folderIdentifier = $folderObject->getIdentifier();
579  if (
580  !empty($this->fileMounts[$folderIdentifier])
581  && empty($this->fileMounts[$folderIdentifier]['read_only'])
582  && !empty($additionalData['read_only'])
583  ) {
584  // Do not overwrite a regular mount with a read only mount
585  return;
586  }
587  if (empty($additionalData)) {
588  $additionalData = [
589  'path' => $folderIdentifier,
590  'title' => $folderIdentifier,
591  'folder' => $folderObject,
592  ];
593  } else {
594  $additionalData['folder'] = $folderObject;
595  if (!isset($additionalData['title'])) {
596  $additionalData['title'] = $folderIdentifier;
597  }
598  }
599  $this->fileMounts[$folderIdentifier] = $additionalData;
600  }
601 
607  public function ‪getFileMounts()
608  {
609  return ‪$this->fileMounts;
610  }
611 
620  public function ‪isWithinFileMountBoundaries($subject, $checkWriteAccess = false)
621  {
622  if (!$this->evaluatePermissions) {
623  return true;
624  }
625  $isWithinFileMount = false;
626  if (!$subject) {
627  $subject = $this->‪getRootLevelFolder();
628  }
629  ‪$identifier = $subject->getIdentifier();
630 
631  // Allow access to processing folder
633  $isWithinFileMount = true;
634  } else {
635  // Check if the identifier of the subject is within at
636  // least one of the file mounts
637  $writableFileMountAvailable = false;
638  foreach ($this->fileMounts as $fileMount) {
640  $folder = $fileMount['folder'];
641  if ($this->driver->isWithin($folder->‪getIdentifier(), ‪$identifier)) {
642  $isWithinFileMount = true;
643  if (!$checkWriteAccess) {
644  break;
645  }
646  if (empty($fileMount['read_only'])) {
647  $writableFileMountAvailable = true;
648  break;
649  }
650  }
651  }
652  $isWithinFileMount = $checkWriteAccess ? $writableFileMountAvailable : $isWithinFileMount;
653  }
654  return $isWithinFileMount;
655  }
656 
664  {
665  $this->evaluatePermissions = (bool)‪$evaluatePermissions;
666  }
667 
674  public function ‪getEvaluatePermissions()
675  {
677  }
678 
683  {
684  $this->userPermissions = ‪$userPermissions;
685  }
686 
695  public function ‪checkUserActionPermission($action, $type)
696  {
697  if (!$this->evaluatePermissions) {
698  return true;
699  }
700 
701  $allow = false;
702  if (!empty($this->userPermissions[strtolower($action) . ucfirst(strtolower($type))])) {
703  $allow = true;
704  }
705 
706  return $allow;
707  }
708 
721  public function ‪checkFileActionPermission($action, ‪FileInterface $file)
722  {
723  $isProcessedFile = $file instanceof ‪ProcessedFile;
724  // Check 1: Allow editing meta data of a file if it is in mount boundaries of a writable file mount
725  if ($action === 'editMeta') {
726  return !$isProcessedFile && $this->‪isWithinFileMountBoundaries($file, true);
727  }
728  // Check 2: Does the user have permission to perform the action? e.g. "readFile"
729  if (!$isProcessedFile && $this->‪checkUserActionPermission($action, 'File') === false) {
730  return false;
731  }
732  // Check 3: No action allowed on files for denied file extensions
733  if (!$this->‪checkValidFileExtension($file)) {
734  return false;
735  }
736  $isReadCheck = false;
737  if (in_array($action, ['read', 'copy', 'move', 'replace'], true)) {
738  $isReadCheck = true;
739  }
740  $isWriteCheck = false;
741  if (in_array($action, ['add', 'write', 'move', 'rename', 'replace', 'delete'], true)) {
742  $isWriteCheck = true;
743  }
744  // Check 4: Does the user have the right to perform the action?
745  // (= is he within the file mount borders)
746  if (!$isProcessedFile && !$this->‪isWithinFileMountBoundaries($file, $isWriteCheck)) {
747  return false;
748  }
749 
750  $isMissing = false;
751  if (!$isProcessedFile && $file instanceof ‪File) {
752  $isMissing = $file->isMissing();
753  }
754 
755  if ($this->driver->fileExists($file->‪getIdentifier()) === false) {
756  $file->setMissing(true);
757  $isMissing = true;
758  }
759 
760  // Check 5: Check the capabilities of the storage (and the driver)
761  if ($isWriteCheck && ($isMissing || !$this->‪isWritable())) {
762  return false;
763  }
764 
765  // Check 6: "File permissions" of the driver (only when file isn't marked as missing)
766  if (!$isMissing) {
767  $filePermissions = $this->driver->getPermissions($file->‪getIdentifier());
768  if ($isReadCheck && !$filePermissions['r']) {
769  return false;
770  }
771  if ($isWriteCheck && !$filePermissions['w']) {
772  return false;
773  }
774  }
775  return true;
776  }
777 
788  public function ‪checkFolderActionPermission($action, ‪Folder $folder = null)
789  {
790  // Check 1: Does the user have permission to perform the action? e.g. "writeFolder"
791  if ($this->‪checkUserActionPermission($action, 'Folder') === false) {
792  return false;
793  }
794 
795  // If we do not have a folder here, we cannot do further checks
796  if ($folder === null) {
797  return true;
798  }
799 
800  $isReadCheck = false;
801  if (in_array($action, ['read', 'copy'], true)) {
802  $isReadCheck = true;
803  }
804  $isWriteCheck = false;
805  if (in_array($action, ['add', 'move', 'write', 'delete', 'rename'], true)) {
806  $isWriteCheck = true;
807  }
808  // Check 2: Does the user has the right to perform the action?
809  // (= is he within the file mount borders)
810  if (!$this->‪isWithinFileMountBoundaries($folder, $isWriteCheck)) {
811  return false;
812  }
813  // Check 3: Check the capabilities of the storage (and the driver)
814  if ($isReadCheck && !$this->‪isBrowsable()) {
815  return false;
816  }
817  if ($isWriteCheck && !$this->‪isWritable()) {
818  return false;
819  }
820 
821  // Check 4: "Folder permissions" of the driver
822  $folderPermissions = $this->driver->getPermissions($folder->‪getIdentifier());
823  if ($isReadCheck && !$folderPermissions['r']) {
824  return false;
825  }
826  if ($isWriteCheck && !$folderPermissions['w']) {
827  return false;
828  }
829  return true;
830  }
831 
839  protected function ‪checkFileExtensionPermission($fileName)
840  {
841  $fileName = $this->driver->sanitizeFileName($fileName);
842  return GeneralUtility::makeInstance(FileNameValidator::class)->isValid($fileName);
843  }
844 
849  protected function ‪checkValidFileExtension(‪FileInterface $file): bool
850  {
851  $fileNameValidator = GeneralUtility::makeInstance(FileNameValidator::class);
852  return $fileNameValidator->isValid($file->‪getName()) &&
853  $fileNameValidator->isValid(basename($file->‪getIdentifier()));
854  }
855 
862  protected function ‪assureFolderReadPermission(‪Folder $folder = null)
863  {
864  if (!$this->‪checkFolderActionPermission('read', $folder)) {
865  if ($folder === null) {
867  'You are not allowed to read folders',
868  1430657869
869  );
870  }
871  throw new InsufficientFolderAccessPermissionsException(
872  'You are not allowed to access the given folder: "' . $folder->‪getName() . '"',
873  1375955684
874  );
875  }
876  }
877 
887  protected function ‪assureFolderDeletePermission(Folder $folder, $checkDeleteRecursively)
888  {
889  // Check user permissions for recursive deletion if it is requested
890  if ($checkDeleteRecursively && !$this->‪checkUserActionPermission('recursivedelete', 'Folder')) {
891  throw new InsufficientUserPermissionsException('You are not allowed to delete folders recursively', 1377779423);
892  }
893  // Check user action permission
894  if (!$this->‪checkFolderActionPermission('delete', $folder)) {
895  throw new InsufficientFolderAccessPermissionsException(
896  'You are not allowed to delete the given folder: "' . $folder->getName() . '"',
897  1377779039
898  );
899  }
900  // Check if the user has write permissions to folders
901  // Would be good if we could check for actual write permissions in the containing folder
902  // but we cannot since we have no access to the containing folder of this file.
903  if (!$this->‪checkUserActionPermission('write', 'Folder')) {
904  throw new ‪InsufficientFolderWritePermissionsException('Writing to folders is not allowed.', 1377779111);
905  }
906  }
907 
914  protected function ‪assureFileReadPermission(FileInterface $file)
915  {
916  if (!$this->‪checkFileActionPermission('read', $file)) {
917  throw new InsufficientFileAccessPermissionsException(
918  'You are not allowed to access that file: "' . $file->getName() . '"',
919  1375955429
920  );
921  }
922  if (!$this->‪checkValidFileExtension($file)) {
923  throw new IllegalFileExtensionException(
924  'You are not allowed to use that file extension. File: "' . $file->getName() . '"',
925  1375955430
926  );
927  }
928  }
929 
937  protected function ‪assureFileWritePermissions(FileInterface $file)
938  {
939  // Check if user is allowed to write the file and $file is writable
940  if (!$this->‪checkFileActionPermission('write', $file)) {
941  throw new ‪InsufficientFileWritePermissionsException('Writing to file "' . $file->getIdentifier() . '" is not allowed.', 1330121088);
942  }
943  if (!$this->‪checkValidFileExtension($file)) {
944  throw new ‪IllegalFileExtensionException('You are not allowed to edit a file with extension "' . $file->getExtension() . '"', 1366711933);
945  }
946  }
947 
954  protected function ‪assureFileReplacePermissions(FileInterface $file)
955  {
956  // Check if user is allowed to replace the file and $file is writable
957  if (!$this->‪checkFileActionPermission('replace', $file)) {
958  throw new InsufficientFileWritePermissionsException('Replacing file "' . $file->getIdentifier() . '" is not allowed.', 1436899571);
959  }
960  // Check if parentFolder is writable for the user
961  if (!$this->‪checkFolderActionPermission('write', $file->getParentFolder())) {
962  throw new ‪InsufficientFolderWritePermissionsException('You are not allowed to write to the target folder "' . $file->getIdentifier() . '"', 1436899572);
963  }
964  }
965 
973  protected function ‪assureFileDeletePermissions(FileInterface $file)
974  {
975  // Check for disallowed file extensions
976  if (!$this->‪checkValidFileExtension($file)) {
977  throw new IllegalFileExtensionException('You are not allowed to delete a file with extension "' . $file->getExtension() . '"', 1377778916);
978  }
979  // Check further permissions if file is not a processed file
980  if (!$file instanceof ProcessedFile) {
981  // Check if user is allowed to delete the file and $file is writable
982  if (!$this->‪checkFileActionPermission('delete', $file)) {
983  // Do not throw exception, if file is just missing.
984  // That way we make sure event "FileDeletionAspect" is still being called to remove the remaining records.
985  if ($file instanceof File && $file->isMissing()) {
986  return;
987  }
988  throw new InsufficientFileWritePermissionsException('You are not allowed to delete the file "' . $file->getIdentifier() . '"', 1319550425);
989  }
990  // Check if the user has write permissions to folders
991  // Would be good if we could check for actual write permissions in the containing folder
992  // but we cannot since we have no access to the containing folder of this file.
993  if (!$this->‪checkUserActionPermission('write', 'Folder')) {
994  throw new InsufficientFolderWritePermissionsException('Writing to folders is not allowed.', 1377778702);
995  }
996  }
997  }
998 
1010  protected function ‪assureFileAddPermissions($targetFolder, $targetFileName)
1011  {
1012  // Check for a valid file extension
1013  if (!$this->‪checkFileExtensionPermission($targetFileName)) {
1014  throw new ‪IllegalFileExtensionException('Extension of file name is not allowed in "' . $targetFileName . '"!', 1322120271);
1015  }
1016  // Makes sure the user is allowed to upload
1017  if (!$this->‪checkUserActionPermission('add', 'File')) {
1018  throw new InsufficientUserPermissionsException('You are not allowed to add files to this storage "' . $this->‪getUid() . '"', 1376992145);
1019  }
1020  // Check if targetFolder is writable
1021  if (!$this->‪checkFolderActionPermission('write', $targetFolder)) {
1022  throw new InsufficientFolderWritePermissionsException('You are not allowed to write to the target folder "' . $targetFolder->getIdentifier() . '"', 1322120356);
1023  }
1024  }
1025 
1041  protected function ‪assureFileUploadPermissions($localFilePath, $targetFolder, $targetFileName, $uploadedFileSize)
1042  {
1043  // Makes sure this is an uploaded file
1044  if (!is_uploaded_file($localFilePath)) {
1045  throw new UploadException('The upload has failed, no uploaded file found!', 1322110455);
1046  }
1047  // Max upload size (kb) for files.
1048  $maxUploadFileSize = GeneralUtility::getMaxUploadFileSize() * 1024;
1049  if ($maxUploadFileSize > 0 && $uploadedFileSize >= $maxUploadFileSize) {
1050  unlink($localFilePath);
1051  throw new UploadSizeException('The uploaded file exceeds the size-limit of ' . $maxUploadFileSize . ' bytes', 1322110041);
1052  }
1053  $this->‪assureFileAddPermissions($targetFolder, $targetFileName);
1054  }
1055 
1065  protected function ‪assureFileMovePermissions(FileInterface $file, Folder $targetFolder, $targetFileName)
1066  {
1067  // Check if targetFolder is within this storage
1068  if ($this->‪getUid() !== $targetFolder->getStorage()->getUid()) {
1069  throw new \RuntimeException('The target folder is not in the same storage. Target folder given: "' . $targetFolder->getIdentifier() . '"', 1422553107);
1070  }
1071  // Check for a valid file extension
1072  if (!$this->‪checkFileExtensionPermission($targetFileName)) {
1073  throw new IllegalFileExtensionException('Extension of file name is not allowed in "' . $targetFileName . '"!', 1378243279);
1074  }
1075  // Check if user is allowed to move and $file is readable and writable
1076  if (!$file->getStorage()->checkFileActionPermission('move', $file)) {
1077  throw new InsufficientUserPermissionsException('You are not allowed to move files to storage "' . $this->‪getUid() . '"', 1319219349);
1078  }
1079  // Check if target folder is writable
1080  if (!$this->‪checkFolderActionPermission('write', $targetFolder)) {
1081  throw new ‪InsufficientFolderAccessPermissionsException('You are not allowed to write to the target folder "' . $targetFolder->getIdentifier() . '"', 1319219350);
1082  }
1083  }
1084 
1094  protected function ‪assureFileRenamePermissions(FileInterface $file, $targetFileName)
1095  {
1096  // Check if file extension is allowed
1097  if (!$this->‪checkFileExtensionPermission($targetFileName) || !$this->‪checkValidFileExtension($file)) {
1098  throw new IllegalFileExtensionException('You are not allowed to rename a file with this extension. File given: "' . $file->getName() . '"', 1371466663);
1099  }
1100  // Check if user is allowed to rename
1101  if (!$this->‪checkFileActionPermission('rename', $file)) {
1102  throw new InsufficientUserPermissionsException('You are not allowed to rename files. File given: "' . $file->getName() . '"', 1319219351);
1103  }
1104  // Check if the user is allowed to write to folders
1105  // Although it would be good to check, we cannot check here if the folder actually is writable
1106  // because we do not know in which folder the file resides.
1107  // So we rely on the driver to throw an exception in case the renaming failed.
1108  if (!$this->‪checkFolderActionPermission('write')) {
1109  throw new InsufficientFileWritePermissionsException('You are not allowed to write to folders', 1319219352);
1110  }
1111  }
1125  protected function ‪assureFileCopyPermissions(‪FileInterface $file, ‪Folder $targetFolder, $targetFileName)
1126  {
1127  // Check if targetFolder is within this storage, this should never happen
1128  if ($this->‪getUid() != $targetFolder->‪getStorage()->getUid()) {
1129  throw new ‪Exception('The operation of the folder cannot be called by this storage "' . $this->‪getUid() . '"', 1319550405);
1130  }
1131  // Check if user is allowed to copy
1132  if (!$file->‪getStorage()->checkFileActionPermission('copy', $file)) {
1133  throw new ‪InsufficientFileReadPermissionsException('You are not allowed to copy the file "' . $file->‪getIdentifier() . '"', 1319550426);
1134  }
1135  // Check if targetFolder is writable
1136  if (!$this->‪checkFolderActionPermission('write', $targetFolder)) {
1137  throw new ‪InsufficientFolderWritePermissionsException('You are not allowed to write to the target folder "' . $targetFolder->‪getIdentifier() . '"', 1319550435);
1138  }
1139  // Check for a valid file extension
1140  if (!$this->‪checkFileExtensionPermission($targetFileName) || !$this->‪checkValidFileExtension($file)) {
1141  throw new ‪IllegalFileExtensionException('You are not allowed to copy a file of that type.', 1319553317);
1142  }
1143  }
1157  protected function ‪assureFolderCopyPermissions(‪FolderInterface $folderToCopy, ‪FolderInterface $targetParentFolder)
1158  {
1159  // Check if targetFolder is within this storage, this should never happen
1160  if ($this->‪getUid() !== $targetParentFolder->‪getStorage()->getUid()) {
1161  throw new ‪Exception('The operation of the folder cannot be called by this storage "' . $this->‪getUid() . '"', 1377777624);
1162  }
1163  if (!$folderToCopy instanceof ‪Folder) {
1164  throw new \RuntimeException('The folder "' . $folderToCopy->‪getIdentifier() . '" to copy is not of type folder.', 1384209020);
1165  }
1166  // Check if user is allowed to copy and the folder is readable
1167  if (!$folderToCopy->‪getStorage()->checkFolderActionPermission('copy', $folderToCopy)) {
1168  throw new ‪InsufficientFileReadPermissionsException('You are not allowed to copy the folder "' . $folderToCopy->‪getIdentifier() . '"', 1377777629);
1169  }
1170  if (!$targetParentFolder instanceof ‪Folder) {
1171  throw new \RuntimeException('The target folder "' . $targetParentFolder->‪getIdentifier() . '" is not of type folder.', 1384209021);
1172  }
1173  // Check if targetFolder is writable
1174  if (!$this->‪checkFolderActionPermission('write', $targetParentFolder)) {
1175  throw new ‪InsufficientFolderWritePermissionsException('You are not allowed to write to the target folder "' . $targetParentFolder->‪getIdentifier() . '"', 1377777635);
1176  }
1177  }
1191  protected function ‪assureFolderMovePermissions(‪FolderInterface $folderToMove, ‪FolderInterface $targetParentFolder)
1192  {
1193  // Check if targetFolder is within this storage, this should never happen
1194  if ($this->‪getUid() !== $targetParentFolder->‪getStorage()->getUid()) {
1195  throw new \InvalidArgumentException('Cannot move a folder into a folder that does not belong to this storage.', 1325777289);
1196  }
1197  if (!$folderToMove instanceof ‪Folder) {
1198  throw new \RuntimeException('The folder "' . $folderToMove->‪getIdentifier() . '" to move is not of type Folder.', 1384209022);
1199  }
1200  // Check if user is allowed to move and the folder is writable
1201  // In fact we would need to check if the parent folder of the folder to move is writable also
1202  // But as of now we cannot extract the parent folder from this folder
1203  if (!$folderToMove->‪getStorage()->checkFolderActionPermission('move', $folderToMove)) {
1204  throw new ‪InsufficientFileReadPermissionsException('You are not allowed to copy the folder "' . $folderToMove->‪getIdentifier() . '"', 1377778045);
1205  }
1206  if (!$targetParentFolder instanceof ‪Folder) {
1207  throw new \RuntimeException('The target folder "' . $targetParentFolder->‪getIdentifier() . '" is not of type Folder.', 1384209023);
1208  }
1209  // Check if targetFolder is writable
1210  if (!$this->‪checkFolderActionPermission('write', $targetParentFolder)) {
1211  throw new ‪InsufficientFolderWritePermissionsException('You are not allowed to write to the target folder "' . $targetParentFolder->‪getIdentifier() . '"', 1377778049);
1212  }
1213  }
1214 
1223  public function ‪sanitizeFileName($fileName, Folder $targetFolder = null)
1224  {
1225  $targetFolder = $targetFolder ?: $this->‪getDefaultFolder();
1226  $fileName = $this->driver->sanitizeFileName($fileName);
1227 
1228  // The file name could be changed by an event listener
1229  $fileName = $this->eventDispatcher->dispatch(
1230  new SanitizeFileNameEvent($fileName, $targetFolder, ‪$this, $this->driver)
1231  )->getFileName();
1232 
1233  return $fileName;
1234  }
1235 
1236  /********************
1237  * FILE ACTIONS
1238  ********************/
1253  public function ‪addFile($localFilePath, Folder $targetFolder, $targetFileName = '', $conflictMode = ‪DuplicationBehavior::RENAME, $removeOriginal = true)
1254  {
1255  $localFilePath = ‪PathUtility::getCanonicalPath($localFilePath);
1256  // File is not available locally NOR is it an uploaded file
1257  if (!is_uploaded_file($localFilePath) && !file_exists($localFilePath)) {
1258  throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1319552745);
1259  }
1260 
1261  if (!$conflictMode instanceof ‪DuplicationBehavior) {
1262  trigger_error(
1263  'Using the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in ResourceStorage->addFile()'
1264  . ' will stop working in TYPO3 v14.0. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
1265  E_USER_DEPRECATED
1266  );
1267  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
1268  }
1269 
1270  $targetFileName = $this->‪sanitizeFileName($targetFileName ?: ‪PathUtility::basename($localFilePath), $targetFolder);
1271 
1272  $targetFileName = $this->eventDispatcher->dispatch(
1273  new BeforeFileAddedEvent($targetFileName, $localFilePath, $targetFolder, ‪$this, $this->driver)
1274  )->getFileName();
1275 
1276  $this->‪assureFileAddPermissions($targetFolder, $targetFileName);
1277 
1278  $replaceExisting = false;
1279  if ($conflictMode === ‪DuplicationBehavior::CANCEL && $this->driver->fileExistsInFolder($targetFileName, $targetFolder->getIdentifier())) {
1280  throw new ExistingTargetFileNameException('File "' . $targetFileName . '" already exists in folder ' . $targetFolder->getIdentifier(), 1322121068);
1281  }
1282  if ($conflictMode === ‪DuplicationBehavior::RENAME) {
1283  $targetFileName = $this->‪getUniqueName($targetFolder, $targetFileName);
1284  } elseif ($conflictMode === ‪DuplicationBehavior::REPLACE && $this->driver->fileExistsInFolder($targetFileName, $targetFolder->getIdentifier())) {
1285  $replaceExisting = true;
1286  }
1287 
1288  $fileIdentifier = $this->driver->addFile($localFilePath, $targetFolder->getIdentifier(), $targetFileName, $removeOriginal);
1289  $file = $this->‪getFileByIdentifier($fileIdentifier);
1290 
1291  if ($replaceExisting && $file instanceof File) {
1292  $this->‪getIndexer()->‪updateIndexEntry($file);
1293  }
1294 
1295  $this->eventDispatcher->dispatch(
1296  new ‪AfterFileAddedEvent($file, $targetFolder)
1297  );
1298  return $file;
1299  }
1300 
1309  public function ‪updateProcessedFile($localFilePath, ‪ProcessedFile $processedFile, ‪Folder ‪$processingFolder = null)
1310  {
1311  if (!file_exists($localFilePath)) {
1312  throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1319552746);
1313  }
1314  if (‪$processingFolder === null) {
1316  }
1317  $fileIdentifier = $this->driver->addFile($localFilePath, ‪$processingFolder->‪getIdentifier(), $processedFile->‪getName());
1318  // @todo check if we have to update the processed file other then the identifier
1319  $processedFile->‪setIdentifier($fileIdentifier);
1320  return $processedFile;
1321  }
1322 
1330  public function ‪hashFile(‪FileInterface $fileObject, $hash)
1331  {
1332  return $this->‪hashFileByIdentifier($fileObject->‪getIdentifier(), $hash);
1333  }
1334 
1343  public function ‪hashFileByIdentifier($fileIdentifier, $hash)
1344  {
1345  $hash = $this->driver->hash($fileIdentifier, $hash);
1346  if (!is_string($hash) || $hash === '') {
1347  throw new ‪InvalidHashException('Hash has to be non-empty string.', 1551950301);
1348  }
1349  return $hash;
1350  }
1351 
1360  public function ‪hashFileIdentifier($file)
1361  {
1362  if ($file instanceof FileInterface) {
1364  $file = $file->getIdentifier();
1365  }
1366  return $this->driver->hashIdentifier($file);
1367  }
1368 
1378  public function ‪getPublicUrl(ResourceInterface $resourceObject)
1379  {
1380  ‪$publicUrl = null;
1381  if ($this->‪isOnline()) {
1382  // Pre-process the public URL by an accordant event
1383  $event = new GeneratePublicUrlForResourceEvent($resourceObject, ‪$this, $this->driver);
1384  ‪$publicUrl = $this->eventDispatcher->dispatch($event)->getPublicUrl();
1385  if (
1386  ‪$publicUrl === null
1387  && $resourceObject instanceof File
1388  && ($helper = GeneralUtility::makeInstance(OnlineMediaHelperRegistry::class)->getOnlineMediaHelper($resourceObject)) !== false
1389  ) {
1390  ‪$publicUrl = $helper->getPublicUrl($resourceObject);
1391  }
1392 
1393  // If an event listener did not handle the URL generation, use the default way to determine public URL
1394  if (‪$publicUrl === null) {
1396  ‪$publicUrl = $this->driver->getPublicUrl($resourceObject->getIdentifier());
1397  }
1398 
1399  if (‪$publicUrl === null && $resourceObject instanceof FileInterface) {
1400  $queryParameterArray = ['eID' => 'dumpFile', 't' => ''];
1401  if ($resourceObject instanceof File) {
1402  $queryParameterArray['f'] = $resourceObject->getUid();
1403  $queryParameterArray['t'] = 'f';
1404  } elseif ($resourceObject instanceof ProcessedFile) {
1405  $queryParameterArray['p'] = $resourceObject->getUid();
1406  $queryParameterArray['t'] = 'p';
1407  }
1409  $queryParameterArray['token'] = ‪GeneralUtility::hmac(implode('|', $queryParameterArray), 'resourceStorageDumpFile');
1410  ‪$publicUrl = GeneralUtility::locationHeaderUrl(‪PathUtility::getAbsoluteWebPath(‪Environment::getPublicPath() . '/index.php'));
1411  ‪$publicUrl .= '?' . http_build_query($queryParameterArray, '', '&', PHP_QUERY_RFC3986);
1412  }
1413  }
1414  }
1415  return ‪$publicUrl;
1416  }
1417 
1421  public function ‪processFile(File|FileReference $fileObject, string $context, array ‪$configuration): ProcessedFile
1422  {
1423  if ($fileObject->getStorage() !== ‪$this) {
1424  throw new \InvalidArgumentException('Cannot process files of foreign storage', 1353401835);
1425  }
1426  return $this->‪getFileProcessingService()->‪processFile($fileObject, $context, $this->driver, ‪$configuration);
1427  }
1428 
1435  public function ‪getFileForLocalProcessing(‪FileInterface $fileObject, $writable = true)
1436  {
1437  $filePath = $this->driver->getFileForLocalProcessing($fileObject->‪getIdentifier(), $writable);
1438  return $filePath;
1439  }
1440 
1447  public function ‪getFile(‪$identifier)
1448  {
1449  $file = $this->‪getFileByIdentifier(‪$identifier);
1450  if (!$this->driver->fileExists(‪$identifier)) {
1451  $file->setMissing(true);
1452  }
1453  return $file;
1454  }
1455 
1463  public function ‪getFileByIdentifier(string $fileIdentifier)
1464  {
1465  if (!$this->‪isWithinProcessingFolder($fileIdentifier)) {
1466  $fileData = $this->‪getFileIndexRepository()->‪findOneByStorageAndIdentifier(‪$this, $fileIdentifier);
1467  if ($fileData === false) {
1468  return $this->‪getIndexer()->‪createIndexEntry($fileIdentifier);
1469  }
1470  return $this->‪getResourceFactoryInstance()->getFileObject($fileData['uid'], $fileData);
1471  }
1472  return $this->‪getProcessedFileRepository()->findByStorageAndIdentifier(‪$this, $fileIdentifier);
1473  }
1474 
1476  {
1477  return GeneralUtility::makeInstance(ProcessedFileRepository::class);
1478  }
1479 
1486  public function ‪getFileInfo(FileInterface $fileObject)
1487  {
1488  return $this->‪getFileInfoByIdentifier($fileObject->getIdentifier());
1489  }
1490 
1498  public function ‪getFileInfoByIdentifier(‪$identifier, array $propertiesToExtract = [])
1499  {
1500  return $this->driver->getFileInfoByIdentifier(‪$identifier, $propertiesToExtract);
1501  }
1502 
1506  public function ‪unsetFileAndFolderNameFilters()
1507  {
1508  $this->‪fileAndFolderNameFilters = [];
1509  }
1510 
1515  {
1516  $this->‪fileAndFolderNameFilters = ‪$GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['defaultFilterCallbacks'];
1517  }
1518 
1525  public function getImportExportFilter(): array
1526  {
1527  $filter = GeneralUtility::makeInstance(ImportExportFilter::class);
1528 
1529  return [$filter, 'filterImportExportFilesAndFolders'];
1530  }
1531 
1537  public function ‪getFileAndFolderNameFilters()
1538  {
1539  return array_merge($this->‪fileAndFolderNameFilters, [$this->getImportExportFilter()]);
1540  }
1545  public function setFileAndFolderNameFilters(array $filters)
1546  {
1547  $this->‪fileAndFolderNameFilters = $filters;
1548  return ‪$this;
1549  }
1550 
1554  public function ‪addFileAndFolderNameFilter($filter)
1555  {
1556  $this->‪fileAndFolderNameFilters[] = $filter;
1557  }
1558 
1564  public function ‪getFolderIdentifierFromFileIdentifier($fileIdentifier)
1565  {
1566  return $this->driver->getParentFolderIdentifierOfIdentifier($fileIdentifier);
1567  }
1568 
1575  public function ‪getFileInFolder($fileName, Folder $folder)
1576  {
1577  ‪$identifier = $this->driver->getFileInFolder($fileName, $folder->getIdentifier());
1578  return $this->‪getFileByIdentifier(‪$identifier);
1579  }
1580 
1595  public function ‪getFilesInFolder(Folder $folder, $start = 0, $maxNumberOfItems = 0, $useFilters = true, $recursive = false, $sort = '', $sortRev = false)
1596  {
1597  $this->‪assureFolderReadPermission($folder);
1598 
1599  $rows = $this->‪getFileIndexRepository()->‪findByFolder($folder);
1600 
1601  $filters = $useFilters == true ? $this->‪getFileAndFolderNameFilters() : [];
1602  $fileIdentifiers = array_values($this->driver->getFilesInFolder($folder->getIdentifier(), $start, $maxNumberOfItems, $recursive, $filters, $sort, $sortRev));
1603 
1604  $items = [];
1605  foreach ($fileIdentifiers as ‪$identifier) {
1606  if (isset($rows[‪$identifier])) {
1607  $fileObject = $this->‪getFileFactory()->‪getFileObject($rows[‪$identifier]['uid'], $rows[‪$identifier]);
1608  } else {
1609  $fileObject = $this->‪getFileByIdentifier($identifier);
1610  }
1611  if ($fileObject instanceof FileInterface) {
1612  $key = $fileObject->‪getName();
1613  while (isset($items[$key])) {
1614  $key .= 'z';
1615  }
1616  $items[$key] = $fileObject;
1617  }
1618  }
1619 
1620  return $items;
1621  }
1622 
1629  public function ‪getFileIdentifiersInFolder($folderIdentifier, $useFilters = true, $recursive = false)
1630  {
1631  $filters = $useFilters == true ? $this->‪getFileAndFolderNameFilters() : [];
1632  return $this->driver->getFilesInFolder($folderIdentifier, 0, 0, $recursive, $filters);
1633  }
1634 
1641  public function ‪countFilesInFolder(‪Folder $folder, $useFilters = true, $recursive = false)
1642  {
1643  $this->‪assureFolderReadPermission($folder);
1644  $filters = $useFilters ? $this->‪getFileAndFolderNameFilters() : [];
1645  return $this->driver->countFilesInFolder($folder->‪getIdentifier(), $recursive, $filters);
1646  }
1647 
1654  public function ‪getFolderIdentifiersInFolder($folderIdentifier, $useFilters = true, $recursive = false)
1655  {
1656  $filters = $useFilters == true ? $this->‪getFileAndFolderNameFilters() : [];
1657  return $this->driver->getFoldersInFolder($folderIdentifier, 0, 0, $recursive, $filters);
1658  }
1659 
1666  public function ‪hasFile(‪$identifier)
1667  {
1668  // Allow if identifier is in processing folder
1669  if (!$this->‪isWithinProcessingFolder($identifier)) {
1671  }
1672  return $this->driver->fileExists(‪$identifier);
1673  }
1674 
1680  public function ‪getProcessingFolders()
1681  {
1682  if ($this->processingFolders === null) {
1683  $this->processingFolders = [];
1684  $this->processingFolders[] = $this->‪getProcessingFolder();
1685  $storageRepository = GeneralUtility::makeInstance(StorageRepository::class);
1686  $allStorages = $storageRepository->findAll();
1687  foreach ($allStorages as $storage) {
1688  // To circumvent the permission check of the folder, we use the factory to create it "manually" instead of directly using $storage->getProcessingFolder()
1689  // See #66695 for details
1690  [$storageUid, $processingFolderIdentifier] = array_pad(‪GeneralUtility::trimExplode(':', $storage->getStorageRecord()['processingfolder'] ?? ''), 2, null);
1691  if (empty($processingFolderIdentifier) || (int)$storageUid !== $this->‪getUid()) {
1692  continue;
1693  }
1694  $potentialProcessingFolder = $this->‪createFolderObject($processingFolderIdentifier, $processingFolderIdentifier);
1695  if ($potentialProcessingFolder->getStorage() === ‪$this && $potentialProcessingFolder->getIdentifier() !== ‪$this->getProcessingFolder()->getIdentifier()) {
1696  $this->processingFolders[] = $potentialProcessingFolder;
1697  }
1698  }
1699  }
1700 
1702  }
1703 
1710  public function ‪isProcessingFolder(Folder $folder)
1711  {
1712  $isProcessingFolder = false;
1713  foreach ($this->‪getProcessingFolders() as ‪$processingFolder) {
1714  if ($folder->getCombinedIdentifier() === ‪$processingFolder->‪getCombinedIdentifier()) {
1715  $isProcessingFolder = true;
1716  break;
1717  }
1718  }
1719  return $isProcessingFolder;
1720  }
1721 
1728  public function ‪hasFileInFolder($fileName, Folder $folder)
1729  {
1730  $this->‪assureFolderReadPermission($folder);
1731  return $this->driver->fileExistsInFolder($fileName, $folder->getIdentifier());
1732  }
1733 
1742  public function ‪getFileContents($file)
1743  {
1744  $this->‪assureFileReadPermission($file);
1745  return $this->driver->getFileContents($file->getIdentifier());
1746  }
1747 
1755  public function ‪streamFile(
1756  ‪FileInterface $file,
1757  bool $asDownload = false,
1758  string $alternativeFilename = null,
1759  string $overrideMimeType = null
1760  ): ResponseInterface {
1761  $this->‪assureFileReadPermission($file);
1762  if (!$this->driver instanceof ‪StreamableDriverInterface) {
1763  return $this->‪getPseudoStream($file, $asDownload, $alternativeFilename, $overrideMimeType);
1764  }
1765 
1766  $properties = [
1767  'as_download' => $asDownload,
1768  'filename_overwrite' => $alternativeFilename,
1769  'mimetype_overwrite' => $overrideMimeType,
1770  ];
1771  return $this->driver->streamFile($file->‪getIdentifier(), $properties);
1772  }
1773 
1782  protected function ‪getPseudoStream(
1783  ‪FileInterface $file,
1784  bool $asDownload = false,
1785  string $alternativeFilename = null,
1786  string $overrideMimeType = null
1787  ) {
1788  $downloadName = $alternativeFilename ?: $file->‪getName();
1789  $contentDisposition = $asDownload ? 'attachment' : 'inline';
1790 
1791  $stream = new ‪FalDumpFileContentsDecoratorStream($file->‪getIdentifier(), ‪$this->driver, $file->getSize());
1792  $fileInfo = $this->driver->getFileInfoByIdentifier($file->‪getIdentifier(), ['mtime']);
1793  $headers = [
1794  'Content-Disposition' => $contentDisposition . '; filename="' . $downloadName . '"',
1795  'Content-Type' => $overrideMimeType ?: $file->getMimeType(),
1796  'Content-Length' => (string)$file->getSize(),
1797  'Last-Modified' => gmdate('D, d M Y H:i:s', array_pop($fileInfo)) . ' GMT',
1798  // Cache-Control header is needed here to solve an issue with browser IE8 and lower
1799  // See for more information: http://support.microsoft.com/kb/323308
1800  'Cache-Control' => '',
1801  ];
1802 
1803  return new ‪Response($stream, 200, $headers);
1804  }
1805 
1816  public function ‪setFileContents(‪AbstractFile $file, $contents)
1817  {
1818  // Check if user is allowed to edit
1819  $this->‪assureFileWritePermissions($file);
1820  $this->eventDispatcher->dispatch(
1821  new ‪BeforeFileContentsSetEvent($file, $contents)
1822  );
1823  // Call driver method to update the file and update file index entry afterwards
1824  $result = $this->driver->setFileContents($file->‪getIdentifier(), $contents);
1825  if ($file instanceof ‪File) {
1826  $this->‪getIndexer()->‪updateIndexEntry($file);
1827  }
1828  $this->eventDispatcher->dispatch(
1829  new AfterFileContentsSetEvent($file, $contents)
1830  );
1831  return $result;
1832  }
1846  public function ‪createFile($fileName, ‪Folder $targetFolderObject)
1847  {
1848  $this->‪assureFileAddPermissions($targetFolderObject, $fileName);
1849  $this->eventDispatcher->dispatch(
1850  new ‪BeforeFileCreatedEvent($fileName, $targetFolderObject)
1851  );
1852  $newFileIdentifier = $this->driver->createFile($fileName, $targetFolderObject->‪getIdentifier());
1853  $this->eventDispatcher->dispatch(
1854  new ‪AfterFileCreatedEvent($newFileIdentifier, $targetFolderObject)
1855  );
1856  return $this->‪getFileByIdentifier($newFileIdentifier);
1857  }
1858 
1867  public function ‪deleteFile($fileObject)
1868  {
1869  $this->‪assureFileDeletePermissions($fileObject);
1870 
1871  $this->eventDispatcher->dispatch(
1872  new ‪BeforeFileDeletedEvent($fileObject)
1873  );
1874  $deleted = true;
1875 
1876  if ($this->driver->fileExists($fileObject->‪getIdentifier())) {
1877  // Disable permission check to find nearest recycler and move file without errors
1878  $currentPermissions = ‪$this->evaluatePermissions;
1879  $this->evaluatePermissions = false;
1880 
1881  $recyclerFolder = $this->‪getNearestRecyclerFolder($fileObject);
1882  if ($recyclerFolder === null) {
1883  $result = $this->driver->deleteFile($fileObject->‪getIdentifier());
1884  } else {
1885  $result = $this->‪moveFile($fileObject, $recyclerFolder);
1886  $deleted = false;
1887  }
1888 
1889  $this->evaluatePermissions = $currentPermissions;
1890 
1891  if (!$result) {
1892  throw new FileOperationErrorException('Deleting the file "' . $fileObject->‪getIdentifier() . '\' failed.', 1329831691);
1893  }
1894  }
1895  // Mark the file object as deleted
1896  if ($deleted && $fileObject instanceof AbstractFile) {
1897  $fileObject->setDeleted();
1898  }
1899 
1900  $this->eventDispatcher->dispatch(
1901  new AfterFileDeletedEvent($fileObject)
1902  );
1903 
1904  return true;
1905  }
1906 
1920  public function copyFile(FileInterface $file, Folder $targetFolder, $targetFileName = null, $conflictMode = DuplicationBehavior::RENAME)
1921  {
1922  if (!$conflictMode instanceof DuplicationBehavior) {
1923  trigger_error(
1924  'Using the non-native enumeration ‪TYPO3\CMS\Core\Resource\‪DuplicationBehavior in ResourceStorage->copyFile()'
1925  . ' will stop working in ‪TYPO3 v14.0. Use native ‪TYPO3\CMS\Core\Resource\Enum\‪DuplicationBehavior instead.',
1926  E_USER_DEPRECATED
1927  );
1928  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? DuplicationBehavior::getDefaultDuplicationBehaviour();
1929  }
1930  if ($targetFileName === null) {
1931  $targetFileName = $file->getName();
1932  }
1933  $sanitizedTargetFileName = $this->driver->sanitizeFileName($targetFileName);
1934  $this->assureFileCopyPermissions($file, $targetFolder, $sanitizedTargetFileName);
1935 
1936  $this->eventDispatcher->dispatch(
1937  new BeforeFileCopiedEvent($file, $targetFolder)
1938  );
1939 
1940  // File exists and we should abort, let's abort
1941  ‪if ($conflictMode === ‪DuplicationBehavior::CANCEL && $targetFolder->hasFile($sanitizedTargetFileName)) {
1942  throw new ExistingTargetFileNameException('The target file already exists.', 1320291064);
1943  }
1944  // File exists and we should find another name, let's find another one
1945  ‪if ($conflictMode === ‪DuplicationBehavior::RENAME && $targetFolder->hasFile($sanitizedTargetFileName)) {
1946  $sanitizedTargetFileName = $this->getUniqueName($targetFolder, $sanitizedTargetFileName);
1947  }
1948  $sourceStorage = $file->‪getStorage();
1949  // Call driver method to create a new file from an existing file object,
1950  // and return the new file object
1951  ‪if ($sourceStorage === ‪$this) {
1952  $newFileObjectIdentifier = $this->driver->copyFileWithinStorage($file->‪getIdentifier(), $targetFolder->getIdentifier(), $sanitizedTargetFileName);
1953  } else {
1954  $tempPath = $file->‪getForLocalProcessing();
1955  $newFileObjectIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $sanitizedTargetFileName);
1956  }
1957  $newFileObject = $this->‪getFileByIdentifier($newFileObjectIdentifier);
1958 
1959  // In case we deal with a file, also copy corresponding metadata
1960  if ($file instanceof File && $newFileObject !== null) {
1961  $metaDataAspect = $newFileObject->getMetaData();
1962  // Add meta data of file while keeping existing properties like "file", "uid", etc.
1963  $metaDataAspect->add(array_replace($file->getMetaData()->get(), $metaDataAspect->get()));
1964  $metaDataAspect->save();
1965  }
1966 
1967  $this->eventDispatcher->dispatch(
1968  new AfterFileCopiedEvent($file, $targetFolder, $newFileObjectIdentifier, $newFileObject)
1969  );
1970  return $newFileObject;
1971  }
1972 
1989  public function ‪moveFile($file, $targetFolder, $targetFileName = null, $conflictMode = ‪DuplicationBehavior::RENAME)
1990  {
1991  if (!$conflictMode instanceof ‪DuplicationBehavior) {
1992  trigger_error(
1993  'Using the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in ResourceStorage->moveFile()'
1994  . ' will not work in TYPO3 v14.0 anymore. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
1995  E_USER_DEPRECATED
1996  );
1997  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
1998  }
1999  if ($targetFileName === null) {
2000  $targetFileName = $file->‪getName();
2001  }
2002  $originalFolder = $file->‪getParentFolder();
2003  $sanitizedTargetFileName = $this->driver->sanitizeFileName($targetFileName);
2004  $this->‪assureFileMovePermissions($file, $targetFolder, $sanitizedTargetFileName);
2005  if ($targetFolder->hasFile($sanitizedTargetFileName)) {
2006  // File exists and we should abort, let's abort
2007  if ($conflictMode === ‪DuplicationBehavior::RENAME) {
2008  $sanitizedTargetFileName = $this->‪getUniqueName($targetFolder, $sanitizedTargetFileName);
2009  } elseif ($conflictMode === ‪DuplicationBehavior::CANCEL) {
2010  throw new ExistingTargetFileNameException('The target file already exists', 1329850997);
2011  }
2012  }
2013  $this->eventDispatcher->dispatch(
2014  new BeforeFileMovedEvent($file, $targetFolder, $sanitizedTargetFileName)
2015  );
2016  $sourceStorage = $file->‪getStorage();
2017  // Call driver method to move the file and update the index entry
2018  try {
2019  if ($sourceStorage === ‪$this) {
2020  $newIdentifier = $this->driver->moveFileWithinStorage($file->‪getIdentifier(), $targetFolder->getIdentifier(), $sanitizedTargetFileName);
2021  if (!$file instanceof AbstractFile) {
2022  throw new \RuntimeException('The given file is not of type AbstractFile.', 1384209025);
2023  }
2024  $file->‪updateProperties(['identifier' => $newIdentifier]);
2025  } else {
2026  $tempPath = $file->‪getForLocalProcessing();
2027  $newIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $sanitizedTargetFileName);
2028 
2029  // Disable permission check to find nearest recycler and move file without errors
2030  $currentPermissions = $sourceStorage->evaluatePermissions;
2031  $sourceStorage->evaluatePermissions = false;
2032 
2033  $recyclerFolder = $sourceStorage->getNearestRecyclerFolder($file);
2034  if ($recyclerFolder === null) {
2035  $sourceStorage->driver->deleteFile($file->‪getIdentifier());
2036  } else {
2037  $sourceStorage->moveFile($file, $recyclerFolder);
2038  }
2039  $sourceStorage->evaluatePermissions = $currentPermissions;
2040  if ($file instanceof File) {
2041  $file->‪updateProperties(['storage' => $this->‪getUid(), 'identifier' => $newIdentifier]);
2042  }
2043  }
2044  if ($file instanceof File) {
2045  $this->‪getIndexer()->‪updateIndexEntry($file);
2046  }
2047  } catch (\‪TYPO3\CMS\Core\Exception $e) {
2048  echo $e->getMessage();
2049  }
2050  $this->eventDispatcher->dispatch(
2051  new AfterFileMovedEvent($file, $targetFolder, $originalFolder)
2052  );
2053  return $file;
2054  }
2055 
2066  public function ‪renameFile($file, $targetFileName, $conflictMode = ‪DuplicationBehavior::RENAME)
2067  {
2068  $sanitizedTargetFileName = $this->driver->sanitizeFileName($targetFileName);
2069  // The new name should be different from the current.
2070  if ($file->‪getName() === $sanitizedTargetFileName) {
2071  return $file;
2072  }
2073  $this->‪assureFileRenamePermissions($file, $sanitizedTargetFileName);
2074  $this->eventDispatcher->dispatch(
2075  new BeforeFileRenamedEvent($file, $sanitizedTargetFileName)
2076  );
2077 
2078  if (!$conflictMode instanceof ‪DuplicationBehavior) {
2079  trigger_error(
2080  'Using the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in ResourceStorage->renameFile()'
2081  . ' will not work in TYPO3 v14.0 anymore. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
2082  E_USER_DEPRECATED
2083  );
2084  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
2085  }
2086 
2087  // Call driver method to rename the file and update the index entry
2088  try {
2089  $newIdentifier = $this->driver->renameFile($file->‪getIdentifier(), $sanitizedTargetFileName);
2090  if ($file instanceof File) {
2091  $file->‪updateProperties(['identifier' => $newIdentifier]);
2092  $this->‪getIndexer()->‪updateIndexEntry($file);
2093  }
2094  } catch (ExistingTargetFileNameException $exception) {
2095  if ($conflictMode === ‪DuplicationBehavior::RENAME) {
2096  $newName = $this->‪getUniqueName($file->‪getParentFolder(), $sanitizedTargetFileName);
2097  $file = $this->‪renameFile($file, $newName);
2098  } elseif ($conflictMode === ‪DuplicationBehavior::CANCEL) {
2099  throw $exception;
2100  } elseif ($conflictMode === ‪DuplicationBehavior::REPLACE) {
2101  $sourceFileIdentifier = substr($file->‪getCombinedIdentifier(), 0, (int)strrpos($file->‪getCombinedIdentifier(), '/') + 1) . $sanitizedTargetFileName;
2102  $sourceFile = $this->‪getResourceFactoryInstance()->getFileObjectFromCombinedIdentifier($sourceFileIdentifier);
2103  $file = $this->‪replaceFile($sourceFile, ‪Environment::getPublicPath() . '/' . $file->‪getPublicUrl());
2104  }
2105  } catch (\RuntimeException $e) {
2106  }
2107 
2108  $this->eventDispatcher->dispatch(
2109  new AfterFileRenamedEvent($file, $sanitizedTargetFileName)
2110  );
2111 
2112  return $file;
2113  }
2114 
2125  public function ‪replaceFile(‪FileInterface $file, $localFilePath)
2126  {
2127  $this->‪assureFileReplacePermissions($file);
2128  if (!file_exists($localFilePath)) {
2129  throw new \InvalidArgumentException('File "' . $localFilePath . '" does not exist.', 1325842622);
2130  }
2131  $this->eventDispatcher->dispatch(
2132  new BeforeFileReplacedEvent($file, $localFilePath)
2133  );
2134  $this->driver->replaceFile($file->‪getIdentifier(), $localFilePath);
2135  if ($file instanceof File) {
2136  $this->‪getIndexer()->‪updateIndexEntry($file);
2137  }
2138  $this->eventDispatcher->dispatch(
2139  new AfterFileReplacedEvent($file, $localFilePath)
2140  );
2141  return $file;
2142  }
2143 
2154  public function ‪addUploadedFile(array|‪UploadedFile $uploadedFileData, ‪Folder $targetFolder = null, $targetFileName = null, $conflictMode = ‪DuplicationBehavior::CANCEL)
2155  {
2156  if (!$conflictMode instanceof ‪DuplicationBehavior) {
2157  trigger_error(
2158  'Using the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in ResourceStorage->addUploadedFile()'
2159  . ' will not work in TYPO3 v14.0 anymore. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
2160  E_USER_DEPRECATED
2161  );
2162  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
2163  }
2164  if ($uploadedFileData instanceof UploadedFile) {
2165  $localFilePath = $uploadedFileData->‪getTemporaryFileName();
2166  if ($targetFileName === null) {
2167  $targetFileName = $uploadedFileData->‪getClientFilename();
2168  }
2169  $size = $uploadedFileData->‪getSize();
2170  } else {
2171  $localFilePath = $uploadedFileData['tmp_name'];
2172  if ($targetFileName === null) {
2173  $targetFileName = \Normalizer::normalize($uploadedFileData['name']);
2174  }
2175  $size = $uploadedFileData['size'];
2176  }
2177  if ($targetFolder === null) {
2178  $targetFolder = $this->‪getDefaultFolder();
2179  }
2180 
2181  $targetFileName = $this->driver->sanitizeFileName($targetFileName);
2182 
2183  $this->‪assureFileUploadPermissions($localFilePath, $targetFolder, $targetFileName, $size);
2184  if ($this->‪hasFileInFolder($targetFileName, $targetFolder) && $conflictMode === ‪DuplicationBehavior::REPLACE) {
2185  $file = $this->‪getFileInFolder($targetFileName, $targetFolder);
2186  $resultObject = $this->‪replaceFile($file, $localFilePath);
2187  } else {
2188  $resultObject = $this->‪addFile($localFilePath, $targetFolder, $targetFileName, $conflictMode);
2189  }
2190  return $resultObject;
2191  }
2192 
2193  /********************
2194  * FOLDER ACTIONS
2195  ********************/
2201  protected function ‪getAllFileObjectsInFolder(Folder $folder)
2202  {
2203  $files = [];
2204  $folderQueue = [$folder];
2205  while (!empty($folderQueue)) {
2206  $folder = array_shift($folderQueue);
2207  foreach ($folder->getSubfolders() as $subfolder) {
2208  $folderQueue[] = $subfolder;
2209  }
2210  foreach ($folder->getFiles() as $file) {
2212  $files[$file->getIdentifier()] = $file;
2213  }
2214  }
2215 
2216  return $files;
2217  }
2218 
2234  public function ‪moveFolder(Folder $folderToMove, Folder $targetParentFolder, $newFolderName = null, $conflictMode = ‪DuplicationBehavior::RENAME)
2235  {
2236  // @todo add tests
2237  $this->‪assureFolderMovePermissions($folderToMove, $targetParentFolder);
2238  $sourceStorage = $folderToMove->getStorage();
2239  $sanitizedNewFolderName = $this->driver->sanitizeFileName($newFolderName ?: $folderToMove->getName());
2240  // @todo check if folder already exists in $targetParentFolder, handle this conflict then
2241  $this->eventDispatcher->dispatch(
2242  new BeforeFolderMovedEvent($folderToMove, $targetParentFolder, $sanitizedNewFolderName)
2243  );
2244  // Get all file objects now so we are able to update them after moving the folder
2245  $fileObjects = $this->‪getAllFileObjectsInFolder($folderToMove);
2246  if ($sourceStorage === ‪$this) {
2247  if ($this->‪isWithinFolder($folderToMove, $targetParentFolder)) {
2248  throw new InvalidTargetFolderException(
2249  sprintf(
2250  'Cannot move folder "%s" into target folder "%s", because the target folder is already within the folder to be moved!',
2251  $folderToMove->getName(),
2252  $targetParentFolder->getName()
2253  ),
2254  1422723050
2255  );
2256  }
2257  $fileMappings = $this->driver->moveFolderWithinStorage($folderToMove->getIdentifier(), $targetParentFolder->getIdentifier(), $sanitizedNewFolderName);
2258  } else {
2259  $fileMappings = $this->‪moveFolderBetweenStorages($folderToMove, $targetParentFolder, $sanitizedNewFolderName);
2260  }
2261  // Update the identifier and storage of all file objects
2262  foreach ($fileObjects as $oldIdentifier => $fileObject) {
2263  $newIdentifier = $fileMappings[$oldIdentifier];
2264  $fileObject->updateProperties(['storage' => $this->‪getUid(), 'identifier' => $newIdentifier]);
2265  $this->‪getIndexer()->‪updateIndexEntry($fileObject);
2266  }
2267  $returnObject = $this->‪getFolder($fileMappings[$folderToMove->getIdentifier()]);
2269  $this->eventDispatcher->dispatch(
2270  new ‪AfterFolderMovedEvent($folderToMove, $targetParentFolder, $returnObject)
2271  );
2272  return $returnObject;
2273  }
2274 
2281  protected function ‪moveFolderBetweenStorages(‪Folder $folderToMove, ‪Folder $targetParentFolder, $newFolderName)
2282  {
2283  throw new ‪NotImplementedMethodException('Not yet implemented', 1476046361);
2284  }
2285 
2297  public function ‪copyFolder(‪FolderInterface $folderToCopy, ‪FolderInterface $targetParentFolder, $newFolderName = null, $conflictMode = ‪DuplicationBehavior::RENAME)
2298  {
2299  if (!$conflictMode instanceof ‪DuplicationBehavior) {
2300  trigger_error(
2301  'Using the non-native enumeration TYPO3\CMS\Core\Resource\DuplicationBehavior in ResourceStorage->copyFolder()'
2302  . ' will not work in TYPO3 v14.0 anymore. Use native TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior instead.',
2303  E_USER_DEPRECATED
2304  );
2305  $conflictMode = DuplicationBehavior::tryFrom($conflictMode) ?? ‪DuplicationBehavior::getDefaultDuplicationBehaviour();
2306  }
2307  $this->‪assureFolderCopyPermissions($folderToCopy, $targetParentFolder);
2308  $returnObject = null;
2309  $sanitizedNewFolderName = $this->driver->sanitizeFileName($newFolderName ?: $folderToCopy->‪getName());
2310  if ($folderToCopy instanceof Folder && $targetParentFolder instanceof Folder) {
2311  $this->eventDispatcher->dispatch(
2312  new BeforeFolderCopiedEvent($folderToCopy, $targetParentFolder, $sanitizedNewFolderName)
2313  );
2314  }
2315  if ($conflictMode === ‪DuplicationBehavior::CANCEL && ($targetParentFolder->‪hasFolder($sanitizedNewFolderName) || $targetParentFolder->‪hasFile($sanitizedNewFolderName))) {
2316  throw new InvalidTargetFolderException(
2317  sprintf(
2318  'Cannot copy folder "%s" into target folder "%s", because there is already a folder or file with that name in the target folder!',
2319  $sanitizedNewFolderName,
2320  $targetParentFolder->‪getIdentifier()
2321  ),
2322  1422723059
2323  );
2324  }
2325  // Folder exists and we should find another name, let's find another one
2326  if ($conflictMode === ‪DuplicationBehavior::RENAME && ($targetParentFolder->‪hasFolder($sanitizedNewFolderName) || $targetParentFolder->‪hasFile($sanitizedNewFolderName))) {
2327  $sanitizedNewFolderName = $this->‪getUniqueName($targetParentFolder, $sanitizedNewFolderName);
2328  }
2329  $sourceStorage = $folderToCopy->‪getStorage();
2330  // call driver method to move the file
2331  // that also updates the file object properties
2332  if ($sourceStorage === ‪$this) {
2333  $this->driver->copyFolderWithinStorage($folderToCopy->‪getIdentifier(), $targetParentFolder->‪getIdentifier(), $sanitizedNewFolderName);
2334  $returnObject = $this->‪getFolder($targetParentFolder->‪getSubfolder($sanitizedNewFolderName)->getIdentifier());
2335  } else {
2336  $this->‪copyFolderBetweenStorages($folderToCopy, $targetParentFolder, $sanitizedNewFolderName);
2337  }
2338  if ($folderToCopy instanceof Folder && $targetParentFolder instanceof Folder) {
2339  $this->eventDispatcher->dispatch(
2340  new ‪AfterFolderCopiedEvent($folderToCopy, $targetParentFolder, $returnObject)
2341  );
2342  }
2343  return $returnObject;
2344  }
2345 
2352  protected function ‪copyFolderBetweenStorages(FolderInterface $folderToCopy, FolderInterface $targetParentFolder, $newFolderName)
2353  {
2354  throw new ‪NotImplementedMethodException('Not yet implemented.', 1476046386);
2355  }
2356 
2366  public function ‪renameFolder($folderObject, $newName)
2367  {
2368  // Renaming the folder should check if the parent folder is writable
2369  // We cannot do this however because we cannot extract the parent folder from a folder currently
2370  if (!$this->‪checkFolderActionPermission('rename', $folderObject)) {
2371  throw new ‪InsufficientUserPermissionsException('You are not allowed to rename the folder "' . $folderObject->getIdentifier() . '\'', 1357811441);
2372  }
2373 
2374  $sanitizedNewName = $this->driver->sanitizeFileName($newName);
2375  if ($this->driver->folderExistsInFolder($sanitizedNewName, $folderObject->getIdentifier())) {
2376  throw new \InvalidArgumentException('The folder ' . $sanitizedNewName . ' already exists in folder ' . $folderObject->getIdentifier(), 1325418870);
2377  }
2378  $this->eventDispatcher->dispatch(
2379  new BeforeFolderRenamedEvent($folderObject, $sanitizedNewName)
2380  );
2381  $fileObjects = $this->‪getAllFileObjectsInFolder($folderObject);
2382  $fileMappings = $this->driver->renameFolder($folderObject->getIdentifier(), $sanitizedNewName);
2383  // Update the identifier of all file objects
2384  foreach ($fileObjects as $oldIdentifier => $fileObject) {
2385  $newIdentifier = $fileMappings[$oldIdentifier];
2386  $fileObject->updateProperties(['identifier' => $newIdentifier]);
2387  $this->‪getIndexer()->‪updateIndexEntry($fileObject);
2388  }
2389  $returnObject = $this->‪getFolder($fileMappings[$folderObject->getIdentifier()]);
2390 
2391  $this->eventDispatcher->dispatch(
2392  new AfterFolderRenamedEvent($returnObject, $folderObject)
2393  );
2394  return $returnObject;
2395  }
2409  public function ‪deleteFolder($folderObject, $deleteRecursively = false)
2410  {
2411  $isEmpty = $this->driver->isFolderEmpty($folderObject->getIdentifier());
2412  $this->‪assureFolderDeletePermission($folderObject, $deleteRecursively && !$isEmpty);
2413  if (!$isEmpty && !$deleteRecursively) {
2414  throw new \RuntimeException('Could not delete folder "' . $folderObject->getIdentifier() . '" because it is not empty.', 1325952534);
2415  }
2416 
2417  $this->eventDispatcher->dispatch(
2418  new ‪BeforeFolderDeletedEvent($folderObject)
2419  );
2420 
2421  foreach ($this->‪getFilesInFolder($folderObject, 0, 0, false, $deleteRecursively) as $file) {
2422  $this->‪deleteFile($file);
2423  }
2424 
2425  $result = $this->driver->deleteFolder($folderObject->getIdentifier(), $deleteRecursively);
2426 
2427  $this->eventDispatcher->dispatch(
2428  new ‪AfterFolderDeletedEvent($folderObject, $result)
2429  );
2430  return $result;
2431  }
2432 
2442  public function ‪getFolderInFolder($folderName, ‪Folder $parentFolder, $returnInaccessibleFolderObject = false)
2443  {
2444  $folderIdentifier = $this->driver->getFolderInFolder($folderName, $parentFolder->‪getIdentifier());
2445  return $this->‪getFolder($folderIdentifier, $returnInaccessibleFolderObject);
2446  }
2447 
2461  public function getFoldersInFolder(Folder $folder, $start = 0, $maxNumberOfItems = 0, $useFilters = true, $recursive = false, $sort = '', $sortRev = false)
2462  {
2463  $filters = $useFilters == true ? $this->‪getFileAndFolderNameFilters() : [];
2464 
2465  ‪$folderIdentifiers = $this->driver->getFoldersInFolder($folder->getIdentifier(), $start, $maxNumberOfItems, $recursive, $filters, $sort, $sortRev);
2466 
2467  // Exclude processing folders
2468  foreach ($this->‪getProcessingFolders() as ‪$processingFolder) {
2469  $processingIdentifier = ‪$processingFolder->‪getIdentifier();
2470  if (isset(‪$folderIdentifiers[$processingIdentifier])) {
2471  unset(‪$folderIdentifiers[$processingIdentifier]);
2472  }
2473  }
2474 
2475  ‪$folders = [];
2476  foreach (‪$folderIdentifiers as $folderIdentifier) {
2477  // The folder identifier can also be an int-like string, resulting in int array keys.
2478  ‪$folders[$folderIdentifier] = $this->‪getFolder($folderIdentifier, true);
2479  }
2480  return ‪$folders;
2481  }
2482 
2489  public function ‪countFoldersInFolder(‪Folder $folder, $useFilters = true, $recursive = false)
2490  {
2491  $this->‪assureFolderReadPermission($folder);
2492  $filters = $useFilters ? $this->‪getFileAndFolderNameFilters() : [];
2493  return $this->driver->countFoldersInFolder($folder->‪getIdentifier(), $recursive, $filters);
2494  }
2495 
2502  public function ‪hasFolder(‪$identifier)
2503  {
2505  return $this->driver->folderExists(‪$identifier);
2506  }
2507 
2514  public function ‪hasFolderInFolder($folderName, Folder $folder)
2515  {
2516  $this->‪assureFolderReadPermission($folder);
2517  return $this->driver->folderExistsInFolder($folderName, $folder->getIdentifier());
2518  }
2519 
2533  public function ‪createFolder($folderName, Folder $parentFolder = null)
2534  {
2535  if ($parentFolder === null) {
2536  $parentFolder = $this->‪getRootLevelFolder();
2537  } elseif (!$this->driver->folderExists($parentFolder->getIdentifier())) {
2538  throw new \InvalidArgumentException('Parent folder "' . $parentFolder->getIdentifier() . '" does not exist.', 1325689164);
2539  }
2540  if (!$this->‪checkFolderActionPermission('add', $parentFolder)) {
2541  throw new InsufficientFolderWritePermissionsException('You are not allowed to create directories in the folder "' . $parentFolder->getIdentifier() . '"', 1323059807);
2542  }
2543  if ($this->driver->folderExistsInFolder($folderName, $parentFolder->getIdentifier())) {
2544  throw new ExistingTargetFolderException('Folder "' . $folderName . '" already exists.', 1423347324);
2545  }
2546 
2547  $this->eventDispatcher->dispatch(
2548  new BeforeFolderAddedEvent($parentFolder, $folderName)
2549  );
2550 
2551  $newFolder = $this->‪getDriver()->createFolder($folderName, $parentFolder->getIdentifier(), true);
2552  $newFolder = $this->‪getFolder($newFolder);
2554  $this->eventDispatcher->dispatch(
2555  new ‪AfterFolderAddedEvent($newFolder)
2556  );
2557 
2558  return $newFolder;
2559  }
2560 
2566  public function ‪getFolderInfo(‪Folder $folder)
2567  {
2568  return $this->driver->getFolderInfoByIdentifier($folder->‪getIdentifier());
2569  }
2570 
2576  public function ‪getDefaultFolder()
2577  {
2578  return $this->‪getFolder($this->driver->getDefaultFolder());
2579  }
2580 
2589  public function ‪getFolder(‪$identifier, $returnInaccessibleFolderObject = false)
2590  {
2591  $data = $this->driver->getFolderInfoByIdentifier(‪$identifier);
2592  $folder = $this->‪createFolderObject($data['identifier'], $data['name']);
2593 
2594  try {
2595  $this->‪assureFolderReadPermission($folder);
2596  } catch (InsufficientFolderAccessPermissionsException $e) {
2597  $folder = null;
2598  if ($returnInaccessibleFolderObject) {
2599  // if parent folder is readable return inaccessible folder object
2600  $parentPermissions = $this->driver->getPermissions($this->driver->getParentFolderIdentifierOfIdentifier(‪$identifier));
2601  if ($parentPermissions['r']) {
2602  $folder = GeneralUtility::makeInstance(
2603  InaccessibleFolder::class,
2604  ‪$this,
2605  $data['identifier'],
2606  $data['name']
2607  );
2608  }
2609  }
2610 
2611  if ($folder === null) {
2612  throw $e;
2613  }
2614  }
2615  return $folder;
2616  }
2617 
2625  {
2626  $inProcessingFolder = false;
2627  foreach ($this->‪getProcessingFolders() as ‪$processingFolder) {
2629  $inProcessingFolder = true;
2630  break;
2631  }
2632  }
2633  return $inProcessingFolder;
2634  }
2635 
2642  public function ‪isWithinFolder(Folder $folder, ResourceInterface $resource)
2643  {
2644  if ($folder->getStorage() !== ‪$this) {
2645  throw new \InvalidArgumentException('Given folder "' . $folder->getIdentifier() . '" is not part of this storage!', 1422709241);
2646  }
2647  if ($folder->getStorage() !== $resource->getStorage()) {
2648  return false;
2649  }
2650  return $this->driver->isWithin($folder->getIdentifier(), $resource->getIdentifier());
2651  }
2652 
2660  public function ‪getRootLevelFolder(bool $respectFileMounts = true): Folder
2661  {
2662  if ($respectFileMounts && !empty($this->fileMounts)) {
2663  $mount = reset($this->fileMounts);
2664  $rootLevelFolder = $mount['folder'] ?? null;
2665  if ($rootLevelFolder instanceof Folder) {
2666  return $rootLevelFolder;
2667  }
2668  }
2669  return $this->‪createFolderObject($this->driver->getRootLevelFolder(), '');
2670  }
2671 
2686  protected function ‪getUniqueName(FolderInterface $folder, $theFile, $dontCheckForUnique = false)
2687  {
2688  $maxNumber = 99;
2689  // Fetches info about path, name, extension of $theFile
2690  $origFileInfo = ‪PathUtility::pathinfo($theFile);
2691  // Check if the file exists and if not - return the fileName...
2692  // The destinations file
2693  $theDestFile = $origFileInfo['basename'];
2694  // If the file does NOT exist we return this fileName
2695  if ($dontCheckForUnique || (!$this->driver->fileExistsInFolder($theDestFile, $folder->getIdentifier()) && !‪$this->driver->folderExistsInFolder($theDestFile, $folder->getIdentifier()))) {
2696  return $theDestFile;
2697  }
2698  // Well the fileName in its pure form existed. Now we try to append
2699  // numbers / unique-strings and see if we can find an available fileName
2700  // This removes _xx if appended to the file
2701  $theTempFileBody = preg_replace('/_[0-9][0-9]$/', '', $origFileInfo['filename']);
2702  $theOrigExt = ($origFileInfo['extension'] ?? '') ? '.' . $origFileInfo['extension'] : '';
2703  for ($a = 1; $a <= $maxNumber + 1; $a++) {
2704  // First we try to append numbers
2705  if ($a <= $maxNumber) {
2706  $insert = '_' . sprintf('%02d', $a);
2707  } else {
2708  $insert = '_' . substr(md5(‪StringUtility::getUniqueId()), 0, 6);
2709  }
2710  $theTestFile = $theTempFileBody . $insert . $theOrigExt;
2711  // The destinations file
2712  $theDestFile = $theTestFile;
2713  // If the file does NOT exist we return this fileName
2714  if (!$this->driver->fileExistsInFolder($theDestFile, $folder->getIdentifier()) && !‪$this->driver->folderExistsInFolder($theDestFile, $folder->getIdentifier())) {
2715  return $theDestFile;
2716  }
2717  }
2718  throw new \RuntimeException('Last possible name "' . $theDestFile . '" is already taken.', 1325194291);
2719  }
2720 
2724  protected function ‪getFileFactory()
2725  {
2726  return GeneralUtility::makeInstance(ResourceFactory::class);
2727  }
2728 
2732  protected function ‪getFileIndexRepository()
2733  {
2734  return GeneralUtility::makeInstance(FileIndexRepository::class);
2735  }
2736 
2740  protected function ‪getFileProcessingService()
2741  {
2742  if (!$this->fileProcessingService) {
2743  $this->fileProcessingService = GeneralUtility::makeInstance(FileProcessingService::class);
2744  }
2746  }
2747 
2754  public function ‪getRole(‪FolderInterface $folder)
2755  {
2756  $folderRole = ‪FolderInterface::ROLE_DEFAULT;
2757  ‪$identifier = $folder->‪getIdentifier();
2758  if (method_exists($this->driver, 'getRole')) {
2759  $folderRole = $this->driver->getRole($folder->‪getIdentifier());
2760  }
2761  if (isset($this->fileMounts[‪$identifier])) {
2762  $folderRole = ‪FolderInterface::ROLE_MOUNT;
2763 
2764  if (!empty($this->fileMounts[‪$identifier]['read_only'])) {
2766  }
2767  if ($this->fileMounts[‪$identifier]['user_mount'] ?? false) {
2769  }
2770  }
2771  if ($folder instanceof Folder && $this->‪isProcessingFolder($folder)) {
2773  }
2774 
2775  return $folderRole;
2776  }
2777 
2785  public function ‪getProcessingFolder(File $file = null)
2786  {
2787  // If a file is given, make sure to return the processing folder of the correct storage
2788  if ($file !== null && $file->‪getStorage()->getUid() !== ‪$this->getUid()) {
2789  return $file->‪getStorage()->getProcessingFolder($file);
2790  }
2791  if (!isset($this->processingFolder)) {
2793  if (!empty($this->storageRecord['processingfolder'])) {
2794  ‪$processingFolder = $this->storageRecord['processingfolder'];
2795  }
2796  try {
2797  if (str_contains(‪$processingFolder, ':')) {
2798  [$storageUid, $processingFolderIdentifier] = explode(':', ‪$processingFolder, 2);
2799  $storage = GeneralUtility::makeInstance(StorageRepository::class)->findByUid((int)$storageUid);
2800  if ($storage->hasFolder($processingFolderIdentifier)) {
2801  $this->processingFolder = $storage->getFolder($processingFolderIdentifier);
2802  } else {
2803  $rootFolder = $storage->getRootLevelFolder(false);
2804  $currentEvaluatePermissions = $storage->getEvaluatePermissions();
2805  $storage->setEvaluatePermissions(false);
2806  $this->processingFolder = $storage->createFolder(
2807  ltrim($processingFolderIdentifier, '/'),
2808  $rootFolder
2809  );
2810  $storage->setEvaluatePermissions($currentEvaluatePermissions);
2811  }
2812  } else {
2813  if ($this->driver->folderExists(‪$processingFolder) === false) {
2814  $rootFolder = $this->‪getRootLevelFolder(false);
2815  try {
2816  $currentEvaluatePermissions = ‪$this->evaluatePermissions;
2817  $this->evaluatePermissions = false;
2818  $this->processingFolder = $this->‪createFolder(
2819  $processingFolder,
2820  $rootFolder
2821  );
2822  $this->evaluatePermissions = $currentEvaluatePermissions;
2823  } catch (\InvalidArgumentException $e) {
2824  $this->processingFolder = GeneralUtility::makeInstance(
2825  InaccessibleFolder::class,
2826  ‪$this,
2829  );
2830  }
2831  } else {
2832  $data = $this->driver->getFolderInfoByIdentifier(‪$processingFolder);
2833  $this->processingFolder = $this->‪createFolderObject($data['identifier'], $data['name']);
2834  }
2835  }
2836  } catch (InsufficientFolderWritePermissionsException|ResourcePermissionsUnavailableException $e) {
2837  $this->processingFolder = GeneralUtility::makeInstance(
2838  InaccessibleFolder::class,
2839  ‪$this,
2842  );
2843  }
2844  }
2845 
2847  if (!empty($file)) {
2849  }
2850  return ‪$processingFolder;
2851  }
2852 
2860  protected function ‪getNestedProcessingFolder(File $file, Folder $rootProcessingFolder)
2861  {
2862  ‪$processingFolder = $rootProcessingFolder;
2863  $nestedFolderNames = $this->‪getNamesForNestedProcessingFolder(
2864  $file->getIdentifier(),
2865  self::PROCESSING_FOLDER_LEVELS
2866  );
2867 
2868  try {
2869  foreach ($nestedFolderNames as $folderName) {
2870  if (‪$processingFolder->‪hasFolder($folderName)) {
2872  } else {
2873  $currentEvaluatePermissions = ‪$processingFolder->‪getStorage()->getEvaluatePermissions();
2874  ‪$processingFolder->‪getStorage()->setEvaluatePermissions(false);
2876  ‪$processingFolder->‪getStorage()->setEvaluatePermissions($currentEvaluatePermissions);
2877  }
2878  }
2880  }
2881 
2882  return ‪$processingFolder;
2883  }
2884 
2892  protected function ‪getNamesForNestedProcessingFolder($fileIdentifier, $levels)
2893  {
2894  $names = [];
2895  if ($levels === 0) {
2896  return $names;
2897  }
2898  $hash = md5($fileIdentifier);
2899  for ($i = 1; $i <= $levels; $i++) {
2900  $names[] = substr($hash, $i, 1);
2901  }
2902  return $names;
2903  }
2904 
2910  public function ‪getDriverType()
2911  {
2912  return $this->storageRecord['driver'];
2913  }
2914 
2920  protected function ‪getIndexer()
2921  {
2922  return GeneralUtility::makeInstance(Indexer::class, ‪$this);
2923  }
2924 
2928  public function ‪setDefault(‪$isDefault)
2929  {
2930  $this->‪isDefault = (bool)‪$isDefault;
2931  }
2932 
2936  public function ‪isDefault()
2937  {
2938  return ‪$this->isDefault;
2939  }
2940 
2942  {
2943  return GeneralUtility::makeInstance(ResourceFactory::class);
2944  }
2945 
2946  protected function ‪getBackendUser(): BackendUserAuthentication
2947  {
2948  return ‪$GLOBALS['BE_USER'];
2949  }
2950 
2962  protected function ‪getNearestRecyclerFolder(‪FileInterface $file)
2963  {
2964  if ($file instanceof ‪ProcessedFile) {
2965  return null;
2966  }
2967  // if the storage is not browsable we cannot fetch the parent folder of the file so no recycler handling is possible
2968  if (!$this->‪isBrowsable()) {
2969  return null;
2970  }
2971 
2972  $recyclerFolder = null;
2973  $folder = $file->‪getParentFolder();
2974 
2975  do {
2976  if ($folder->getRole() === ‪FolderInterface::ROLE_RECYCLER) {
2977  break;
2978  }
2979 
2980  foreach ($folder->‪getSubfolders() as $subFolder) {
2981  if ($subFolder->getRole() === ‪FolderInterface::ROLE_RECYCLER) {
2982  $recyclerFolder = $subFolder;
2983  break;
2984  }
2985  }
2986 
2987  $parentFolder = $folder->‪getParentFolder();
2988  $isFolderLoop = $folder->‪getIdentifier() === $parentFolder->getIdentifier();
2989  $folder = $parentFolder;
2990  } while ($recyclerFolder === null && !$isFolderLoop);
2991 
2992  return $recyclerFolder;
2993  }
2994 
3002  protected function ‪createFolderObject(string ‪$identifier, string $name)
3003  {
3004  return GeneralUtility::makeInstance(Folder::class, ‪$this, ‪$identifier, $name);
3005  }
3006 }
‪TYPO3\CMS\Core\Resource\Event\BeforeFolderRenamedEvent
Definition: BeforeFolderRenamedEvent.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\processFile
‪processFile(File|FileReference $fileObject, string $context, array $configuration)
Definition: ResourceStorage.php:1408
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileProcessingService
‪Service FileProcessingService getFileProcessingService()
Definition: ResourceStorage.php:2727
‪TYPO3\CMS\Core\Resource\ResourceStorage\$fileAndFolderNameFilters
‪array $fileAndFolderNameFilters
Definition: ResourceStorage.php:206
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileByIdentifier
‪File ProcessedFile null getFileByIdentifier(string $fileIdentifier)
Definition: ResourceStorage.php:1450
‪TYPO3\CMS\Core\Resource\ResourceStorage\getBackendUser
‪getBackendUser()
Definition: ResourceStorage.php:2933
‪TYPO3\CMS\Core\Resource\Search\Result\EmptyFileSearchResult
Definition: EmptyFileSearchResult.php:24
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath(string $path)
Definition: PathUtility.php:364
‪TYPO3\CMS\Core\Resource\Event\BeforeFolderDeletedEvent
Definition: BeforeFolderDeletedEvent.php:28
‪TYPO3\CMS\Core\Resource\ProcessedFileRepository
Definition: ProcessedFileRepository.php:39
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFileWritePermissionsException
Definition: InsufficientFileWritePermissionsException.php:21
‪TYPO3\CMS\Core\Resource\Exception\InsufficientUserPermissionsException
Definition: InsufficientUserPermissionsException.php:23
‪TYPO3\CMS\Core\Resource\ResourceStorage\renameFolder
‪Folder renameFolder($folderObject, $newName)
Definition: ResourceStorage.php:2353
‪TYPO3\CMS\Core\Resource\Event\BeforeFileCopiedEvent
Definition: BeforeFileCopiedEvent.php:30
‪TYPO3\CMS\Core\Resource\ResourceStorage\deleteFolder
‪bool deleteFolder($folderObject, $deleteRecursively=false)
Definition: ResourceStorage.php:2396
‪TYPO3\CMS\Core\Resource\ResourceInterface\getIdentifier
‪getIdentifier()
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:44
‪TYPO3\CMS\Core\Resource\Event\BeforeFileCreatedEvent
Definition: BeforeFileCreatedEvent.php:29
‪TYPO3\CMS\Core\Resource\ResourceStorage\addFileAndFolderNameFilter
‪addFileAndFolderNameFilter($filter)
Definition: ResourceStorage.php:1541
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Resource\Capabilities\CAPABILITY_PUBLIC
‪const CAPABILITY_PUBLIC
Definition: Capabilities.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage\resetFileAndFolderNameFiltersToDefault
‪resetFileAndFolderNameFiltersToDefault()
Definition: ResourceStorage.php:1501
‪TYPO3\CMS\Core\Resource\ResourceStorage\countFilesInFolder
‪int countFilesInFolder(Folder $folder, $useFilters=true, $recursive=false)
Definition: ResourceStorage.php:1628
‪TYPO3\CMS\Core\Resource\FolderInterface\getSubfolder
‪getSubfolder(string $name)
‪TYPO3\CMS\Core\Resource\OnlineMedia\Helpers\OnlineMediaHelperRegistry
Definition: OnlineMediaHelperRegistry.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileInfo
‪array getFileInfo(FileInterface $fileObject)
Definition: ResourceStorage.php:1473
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface
Definition: ResourceStorageInterface.php:22
‪TYPO3\CMS\Core\Resource\Exception\ExistingTargetFolderException
Definition: ExistingTargetFolderException.php:23
‪TYPO3\CMS\Core\Resource\ResourceStorage\markAsTemporaryOffline
‪markAsTemporaryOffline()
Definition: ResourceStorage.php:534
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:337
‪TYPO3\CMS\Core\Resource\DuplicationBehavior
Definition: DuplicationBehavior.php:25
‪TYPO3\CMS\Core\Resource\ResourceStorage\setUserPermissions
‪setUserPermissions(array $userPermissions)
Definition: ResourceStorage.php:669
‪TYPO3\CMS\Core\Resource\Event\BeforeFileReplacedEvent
Definition: BeforeFileReplacedEvent.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileInfoByIdentifier
‪array getFileInfoByIdentifier($identifier, array $propertiesToExtract=[])
Definition: ResourceStorage.php:1485
‪TYPO3\CMS\Core\Resource\AbstractFile\getForLocalProcessing
‪non empty string getForLocalProcessing(bool $writable=true)
Definition: AbstractFile.php:576
‪TYPO3\CMS\Core\Resource\ResourceStorage\getEvaluatePermissions
‪bool getEvaluatePermissions()
Definition: ResourceStorage.php:661
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolderInFolder
‪Folder InaccessibleFolder getFolderInFolder($folderName, Folder $parentFolder, $returnInaccessibleFolderObject=false)
Definition: ResourceStorage.php:2429
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\CANCEL
‪const CANCEL
Definition: DuplicationBehavior.php:47
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileReplacePermissions
‪assureFileReplacePermissions(FileInterface $file)
Definition: ResourceStorage.php:941
‪TYPO3\CMS\Core\Resource\ResourceStorage\PROCESSING_FOLDER_LEVELS
‪const PROCESSING_FOLDER_LEVELS
Definition: ResourceStorage.php:211
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFileReadPermissionsException
Definition: InsufficientFileReadPermissionsException.php:21
‪TYPO3\CMS\Core\Resource\ResourceStorage\getDefaultFolder
‪Folder getDefaultFolder()
Definition: ResourceStorage.php:2563
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:26
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException
Definition: InsufficientFolderAccessPermissionsException.php:23
‪TYPO3\CMS\Core\Resource\ResourceInterface\getName
‪getName()
‪TYPO3\CMS\Core\Resource\ResourceStorage\moveFolder
‪Folder moveFolder(Folder $folderToMove, Folder $targetParentFolder, $newFolderName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: ResourceStorage.php:2221
‪TYPO3\CMS\Core\Resource\ResourceStorage\getDriverType
‪string getDriverType()
Definition: ResourceStorage.php:2897
‪TYPO3\CMS\Core\Resource\ResourceStorage\getRootLevelFolder
‪getRootLevelFolder(bool $respectFileMounts=true)
Definition: ResourceStorage.php:2647
‪TYPO3\CMS\Core\Resource\ResourceStorage\searchFiles
‪searchFiles(FileSearchDemand $searchDemand, Folder $folder=null, bool $useFilters=true)
Definition: ResourceStorage.php:433
‪TYPO3\CMS\Core\Resource\FolderInterface\hasFolder
‪hasFolder(string $name)
‪TYPO3\CMS\Core\Resource\Security\FileNameValidator
Definition: FileNameValidator.php:25
‪TYPO3\CMS\Core\Resource\Capabilities
Definition: Capabilities.php:23
‪TYPO3\CMS\Core\Resource\AbstractFile\getParentFolder
‪getParentFolder()
Definition: AbstractFile.php:594
‪TYPO3\CMS\Core\Resource\ResourceStorage\$storageRecord
‪array $storageRecord
Definition: ResourceStorage.php:139
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_DEFAULT
‪const ROLE_DEFAULT
Definition: FolderInterface.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\checkFileExtensionPermission
‪bool checkFileExtensionPermission($fileName)
Definition: ResourceStorage.php:826
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFilesInFolder
‪File[] getFilesInFolder(Folder $folder, $start=0, $maxNumberOfItems=0, $useFilters=true, $recursive=false, $sort='', $sortRev=false)
Definition: ResourceStorage.php:1582
‪TYPO3\CMS\Core\Resource\ResourceStorage\getStorageRecord
‪array getStorageRecord()
Definition: ResourceStorage.php:296
‪TYPO3
‪TYPO3\CMS\Core\Resource\Event\AfterFolderMovedEvent
Definition: AfterFolderMovedEvent.php:29
‪TYPO3\CMS\Core\Resource\Event\BeforeFileDeletedEvent
Definition: BeforeFileDeletedEvent.php:28
‪TYPO3\CMS\Core\Resource\Index\Indexer
Definition: Indexer.php:35
‪TYPO3\CMS\Core\Resource\ResourceStorage\getProcessingFolder
‪Folder getProcessingFolder(File $file=null)
Definition: ResourceStorage.php:2772
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileFactory
‪ResourceFactory getFileFactory()
Definition: ResourceStorage.php:2711
‪TYPO3\CMS\Core\Resource\ResourceStorage\addFileMount
‪addFileMount($folderIdentifier, $additionalData=[])
Definition: ResourceStorage.php:554
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Resource\ResourceStorage\getResourceFactoryInstance
‪getResourceFactoryInstance()
Definition: ResourceStorage.php:2928
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Core\Resource\ResourceStorage\$configuration
‪array $configuration
Definition: ResourceStorage.php:145
‪TYPO3\CMS\Core\Resource\Folder\getSubfolders
‪getSubfolders($start=0, $numberOfItems=0, $filterMode=self::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, $recursive=false)
Definition: Folder.php:267
‪TYPO3\CMS\Core\Resource\ResourceStorage\copyFolderBetweenStorages
‪copyFolderBetweenStorages(FolderInterface $folderToCopy, FolderInterface $targetParentFolder, $newFolderName)
Definition: ResourceStorage.php:2339
‪TYPO3\CMS\Core\Resource\Event\AfterFolderCopiedEvent
Definition: AfterFolderCopiedEvent.php:29
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolder
‪Folder InaccessibleFolder getFolder($identifier, $returnInaccessibleFolderObject=false)
Definition: ResourceStorage.php:2576
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolderIdentifierFromFileIdentifier
‪string getFolderIdentifierFromFileIdentifier($fileIdentifier)
Definition: ResourceStorage.php:1551
‪TYPO3\CMS\Core\Resource\ResourceStorage\replaceFile
‪FileInterface replaceFile(FileInterface $file, $localFilePath)
Definition: ResourceStorage.php:2112
‪TYPO3\CMS\Core\Resource\ResourceInterface\getStorage
‪getStorage()
‪TYPO3\CMS\Core\Resource\ResourceStorage\renameFile
‪FileInterface renameFile($file, $targetFileName, $conflictMode=DuplicationBehavior::RENAME)
Definition: ResourceStorage.php:2053
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFile
‪FileInterface getFile($identifier)
Definition: ResourceStorage.php:1434
‪TYPO3\CMS\Core\Resource\Event\BeforeFileRenamedEvent
Definition: BeforeFileRenamedEvent.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\copyFile
‪FileInterface copyFile(FileInterface $file, Folder $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: ResourceStorage.php:1907
‪TYPO3\CMS\Core\Resource\ResourceStorage\getDriver
‪Driver DriverInterface getDriver()
Definition: ResourceStorage.php:317
‪TYPO3\CMS\Core\Resource\ResourceStorage\$isOnline
‪bool $isOnline
Definition: ResourceStorage.php:196
‪TYPO3\CMS\Core\Resource\Event\AfterFileCreatedEvent
Definition: AfterFileCreatedEvent.php:29
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:37
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFileByIdentifier
‪string hashFileByIdentifier($fileIdentifier, $hash)
Definition: ResourceStorage.php:1330
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand\withFolder
‪withFolder(Folder $folder)
Definition: FileSearchDemand.php:118
‪TYPO3\CMS\Core\Resource\ResourceStorage\fileAndFolderNameFilters
‪array< int, function getImportExportFilter():array { $filter=GeneralUtility::makeInstance(ImportExportFilter::class);return[ $filter, 'filterImportExportFilesAndFolders'];} public array function getFileAndFolderNameFilters() { return array_merge( $this->fileAndFolderNameFilters,[ $this->getImportExportFilter()]);} public $this function setFileAndFolderNameFilters(array $filters) { $this-> fileAndFolderNameFilters
Definition: ResourceStorage.php:1534
‪TYPO3\CMS\Core\Resource\Exception\ExistingTargetFileNameException
Definition: ExistingTargetFileNameException.php:23
‪TYPO3\CMS\Core\Resource\ResourceStorageInterface\DEFAULT_ProcessingFolder
‪const DEFAULT_ProcessingFolder
Definition: ResourceStorageInterface.php:26
‪TYPO3\CMS\Core\Resource\FolderInterface\getSubfolders
‪getSubfolders()
‪TYPO3\CMS\Core\Resource\AbstractFile\getName
‪getName()
Definition: AbstractFile.php:157
‪TYPO3\CMS\Core\Resource\ResourceStorage\getProcessingFolders
‪Folder[] getProcessingFolders()
Definition: ResourceStorage.php:1667
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileIdentifiersInFolder
‪array getFileIdentifiersInFolder($folderIdentifier, $useFilters=true, $recursive=false)
Definition: ResourceStorage.php:1616
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findByFolder
‪array null findByFolder(Folder $folder)
Definition: FileIndexRepository.php:174
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolderInfo
‪array getFolderInfo(Folder $folder)
Definition: ResourceStorage.php:2553
‪TYPO3\CMS\Core\Resource\Index\Indexer\updateIndexEntry
‪updateIndexEntry(File $fileObject)
Definition: Indexer.php:93
‪TYPO3\CMS\Core\Resource\ResourceStorage\getProcessedFileRepository
‪getProcessedFileRepository()
Definition: ResourceStorage.php:1462
‪TYPO3\CMS\Core\Resource\Event\BeforeFileMovedEvent
Definition: BeforeFileMovedEvent.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFolder
‪bool hasFolder($identifier)
Definition: ResourceStorage.php:2489
‪TYPO3\CMS\Core\Resource\Event\AfterFolderAddedEvent
Definition: AfterFolderAddedEvent.php:28
‪TYPO3\CMS\Core\Resource\Exception\ResourcePermissionsUnavailableException
Definition: ResourcePermissionsUnavailableException.php:25
‪TYPO3\CMS\Core\Resource\ResourceStorage\isWithinFileMountBoundaries
‪bool isWithinFileMountBoundaries($subject, $checkWriteAccess=false)
Definition: ResourceStorage.php:607
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileContents
‪string getFileContents($file)
Definition: ResourceStorage.php:1729
‪TYPO3\CMS\Core\Resource\ResourceStorage\isDefault
‪bool isDefault()
Definition: ResourceStorage.php:2923
‪TYPO3\CMS\Core\Resource\ResourceStorage\isProcessingFolder
‪bool isProcessingFolder(Folder $folder)
Definition: ResourceStorage.php:1697
‪TYPO3\CMS\Core\Resource\Exception\IllegalFileExtensionException
Definition: IllegalFileExtensionException.php:23
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static basename(string $path)
Definition: PathUtility.php:219
‪TYPO3\CMS\Core\Resource\ResourceStorage\addUploadedFile
‪FileInterface addUploadedFile(array|UploadedFile $uploadedFileData, Folder $targetFolder=null, $targetFileName=null, $conflictMode=DuplicationBehavior::CANCEL)
Definition: ResourceStorage.php:2141
‪TYPO3\CMS\Core\Resource\Event\AfterFileMovedEvent
Definition: AfterFileMovedEvent.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileInFolder
‪File ProcessedFile null getFileInFolder($fileName, Folder $folder)
Definition: ResourceStorage.php:1562
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFile
‪bool hasFile($identifier)
Definition: ResourceStorage.php:1653
‪TYPO3\CMS\Core\Resource\ResourceStorage\setFileContents
‪int setFileContents(AbstractFile $file, $contents)
Definition: ResourceStorage.php:1803
‪TYPO3\CMS\Core\Resource\Capabilities\CAPABILITY_HIERARCHICAL_IDENTIFIERS
‪const CAPABILITY_HIERARCHICAL_IDENTIFIERS
Definition: Capabilities.php:40
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFileAccessPermissionsException
Definition: InsufficientFileAccessPermissionsException.php:23
‪TYPO3\CMS\Core\Resource\Exception\InvalidTargetFolderException
Definition: InvalidTargetFolderException.php:23
‪TYPO3\CMS\Core\Resource\Event\AfterFolderRenamedEvent
Definition: AfterFolderRenamedEvent.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\$folderIdentifiers
‪$folderIdentifiers
Definition: ResourceStorage.php:2452
‪TYPO3\CMS\Core\Resource\Exception\UploadException
Definition: UploadException.php:21
‪TYPO3\CMS\Core\Service\FlexFormService
Definition: FlexFormService.php:25
‪TYPO3\CMS\Core\Resource\Event\GeneratePublicUrlForResourceEvent
Definition: GeneratePublicUrlForResourceEvent.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage\$processingFolder
‪Folder null $processingFolder
Definition: ResourceStorage.php:184
‪TYPO3\CMS\Core\Utility\PathUtility\getAbsoluteWebPath
‪static string getAbsoluteWebPath(string $targetPath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:52
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFileIdentifier
‪string hashFileIdentifier($file)
Definition: ResourceStorage.php:1347
‪TYPO3\CMS\Core\Resource\Folder\getParentFolder
‪getParentFolder()
Definition: Folder.php:553
‪TYPO3\CMS\Core\Resource\ResourceStorage\addFile
‪FileInterface addFile($localFilePath, Folder $targetFolder, $targetFileName='', $conflictMode=DuplicationBehavior::RENAME, $removeOriginal=true)
Definition: ResourceStorage.php:1240
‪TYPO3\CMS\Webhooks\Message\$publicUrl
‪identifier readonly string readonly string $publicUrl
Definition: FileUpdatedMessage.php:36
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileAndFolderNameFilters
‪array< string|int, getFoldersInFolder(Folder $folder, $start=0, $maxNumberOfItems=0, $useFilters=true, $recursive=false, $sort='', $sortRev=false) { $filters=$useFilters==true ? $this-> getFileAndFolderNameFilters()
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileReadPermission
‪assureFileReadPermission(FileInterface $file)
Definition: ResourceStorage.php:901
‪TYPO3\CMS\Core\Resource\Folder\getSubfolder
‪getSubfolder(string $name)
Definition: Folder.php:252
‪TYPO3\CMS\Core\Resource\ResourceStorage\$driver
‪Driver DriverInterface $driver
Definition: ResourceStorage.php:133
‪TYPO3\CMS\Core\Resource\ResourceStorage\isOnline
‪bool isOnline()
Definition: ResourceStorage.php:464
‪TYPO3\CMS\Core\Resource\InaccessibleFolder
Definition: InaccessibleFolder.php:30
‪TYPO3\CMS\Core\Resource\ResourceStorage\checkFolderActionPermission
‪bool checkFolderActionPermission($action, Folder $folder=null)
Definition: ResourceStorage.php:775
‪TYPO3\CMS\Core\Http\Response
Definition: Response.php:32
‪TYPO3\CMS\Core\Resource\Enum\getDefaultDuplicationBehaviour
‪@ getDefaultDuplicationBehaviour
Definition: DuplicationBehavior.php:53
‪TYPO3\CMS\Core\Resource\ResourceStorage\setEvaluatePermissions
‪setEvaluatePermissions($evaluatePermissions)
Definition: ResourceStorage.php:650
‪TYPO3\CMS\Core\Resource\ResourceStorage\streamFile
‪streamFile(FileInterface $file, bool $asDownload=false, string $alternativeFilename=null, string $overrideMimeType=null)
Definition: ResourceStorage.php:1742
‪TYPO3\CMS\Core\Resource\ResourceStorage\moveFile
‪FileInterface moveFile($file, $targetFolder, $targetFileName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: ResourceStorage.php:1976
‪TYPO3\CMS\Core\Resource\AbstractFile
Definition: AbstractFile.php:29
‪TYPO3\CMS\Core\Resource\ResourceStorage\getRole
‪string getRole(FolderInterface $folder)
Definition: ResourceStorage.php:2741
‪TYPO3\CMS\Core\Resource\ResourceStorage\markAsPermanentlyOffline
‪markAsPermanentlyOffline()
Definition: ResourceStorage.php:512
‪TYPO3\CMS\Core\Resource\AbstractFile\setIdentifier
‪$this setIdentifier($identifier)
Definition: AbstractFile.php:406
‪TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException
Definition: InvalidConfigurationException.php:23
‪TYPO3\CMS\Core\Resource\ResourceStorage\getAllFileObjectsInFolder
‪File[] getAllFileObjectsInFolder(Folder $folder)
Definition: ResourceStorage.php:2188
‪TYPO3\CMS\Core\Resource\Capabilities\CAPABILITY_BROWSABLE
‪const CAPABILITY_BROWSABLE
Definition: Capabilities.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileMovePermissions
‪assureFileMovePermissions(FileInterface $file, Folder $targetFolder, $targetFileName)
Definition: ResourceStorage.php:1052
‪TYPO3\CMS\Core\Resource\Search\Result\FileSearchResult
Definition: FileSearchResult.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage\getCapabilities
‪getCapabilities()
Definition: ResourceStorage.php:369
‪TYPO3\CMS\Core\Resource\Event\BeforeFolderAddedEvent
Definition: BeforeFolderAddedEvent.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileAddPermissions
‪assureFileAddPermissions($targetFolder, $targetFileName)
Definition: ResourceStorage.php:997
‪TYPO3\CMS\Core\Resource\ResourceStorage\__construct
‪__construct(DriverInterface $driver, array $storageRecord, EventDispatcherInterface $eventDispatcher=null)
Definition: ResourceStorage.php:219
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileForLocalProcessing
‪string getFileForLocalProcessing(FileInterface $fileObject, $writable=true)
Definition: ResourceStorage.php:1422
‪TYPO3\CMS\Core\Resource\AbstractFile\getPublicUrl
‪string null getPublicUrl()
Definition: AbstractFile.php:558
‪TYPO3\CMS\Core\Resource\ResourceStorage\isBrowsable
‪bool isBrowsable()
Definition: ResourceStorage.php:413
‪TYPO3\CMS\Core\Resource\ResourceStorage\createFolder
‪Folder createFolder($folderName, Folder $parentFolder=null)
Definition: ResourceStorage.php:2520
‪TYPO3\CMS\Core\Resource\Folder\createFolder
‪Folder createFolder($folderName)
Definition: Folder.php:358
‪TYPO3\CMS\Core\Resource\Search\FileSearchDemand
Definition: FileSearchDemand.php:26
‪TYPO3\CMS\Core\Resource\Search\Result\DriverFilteredSearchResult
Definition: DriverFilteredSearchResult.php:29
‪TYPO3\CMS\Core\Resource\Exception\UploadSizeException
Definition: UploadSizeException.php:21
‪TYPO3\CMS\Core\Resource\AbstractFile\getStorage
‪int< 0, getSize():int { if( $this->deleted) { throw new \RuntimeException( 'File has been deleted.', 1329821480);} if(empty( $this->properties[ 'size'])) { $fileInfo=$this-> getStorage() -> getFileInfoByIdentifier($this->getIdentifier(), ['size'])
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:42
‪TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException
Definition: FolderDoesNotExistException.php:21
‪TYPO3\CMS\Core\Resource\ResourceStorage\createFile
‪FileInterface createFile($fileName, Folder $targetFolderObject)
Definition: ResourceStorage.php:1833
‪TYPO3\CMS\Core\Resource\Event\AfterFileRenamedEvent
Definition: AfterFileRenamedEvent.php:27
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Core\Http\UploadedFile\getClientFilename
‪string null getClientFilename()
Definition: UploadedFile.php:227
‪TYPO3\CMS\Core\Resource\ResourceStorage\isWithinFolder
‪bool isWithinFolder(Folder $folder, ResourceInterface $resource)
Definition: ResourceStorage.php:2629
‪TYPO3\CMS\Core\Resource\Event\AfterFileContentsSetEvent
Definition: AfterFileContentsSetEvent.php:28
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\RENAME
‪const RENAME
Definition: DuplicationBehavior.php:33
‪TYPO3\CMS\Core\Resource\Folder\getStorage
‪getStorage()
Definition: Folder.php:139
‪TYPO3\CMS\Core\Resource\Folder\checkActionPermission
‪bool checkActionPermission($action)
Definition: Folder.php:442
‪TYPO3\CMS\Core\Resource\ResourceStorage\autoExtractMetadataEnabled
‪bool autoExtractMetadataEnabled()
Definition: ResourceStorage.php:500
‪TYPO3\CMS\Core\Resource\Service\FileProcessingService\processFile
‪processFile(File|FileReference $fileObject, string $taskType, DriverInterface $driver, array $configuration)
Definition: FileProcessingService.php:53
‪TYPO3\CMS\Core\Utility\GeneralUtility\hmac
‪static string hmac($input, $additionalSecret='')
Definition: GeneralUtility.php:474
‪TYPO3\CMS\Core\Resource\FolderInterface\hasFile
‪hasFile(string $name)
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileDeletePermissions
‪assureFileDeletePermissions(FileInterface $file)
Definition: ResourceStorage.php:960
‪TYPO3\CMS\Core\Resource\ResourceStorage\getConfiguration
‪array getConfiguration()
Definition: ResourceStorage.php:278
‪TYPO3\CMS\Core\Resource\AbstractFile\getCombinedIdentifier
‪string getCombinedIdentifier()
Definition: AbstractFile.php:418
‪TYPO3\CMS\Core\Resource\Event\AfterFileCopiedEvent
Definition: AfterFileCopiedEvent.php:30
‪TYPO3\CMS\Core\Resource\Enum\DuplicationBehavior
‪DuplicationBehavior
Definition: DuplicationBehavior.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasChildren
‪bool hasChildren()
Definition: ResourceStorage.php:347
‪TYPO3\CMS\Core\Resource\ResourceInterface\getParentFolder
‪getParentFolder()
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:61
‪TYPO3\CMS\Core\Resource\Folder\getName
‪getName()
Definition: Folder.php:89
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileMounts
‪array getFileMounts()
Definition: ResourceStorage.php:594
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_PROCESSING
‪const ROLE_PROCESSING
Definition: FolderInterface.php:30
‪TYPO3\CMS\Core\Resource\Folder\getRole
‪string getRole()
Definition: Folder.php:539
‪TYPO3\CMS\Core\Resource\ResourceStorage\isWithinProcessingFolder
‪bool isWithinProcessingFolder($identifier)
Definition: ResourceStorage.php:2611
‪TYPO3\CMS\Core\Resource\Index\Indexer\createIndexEntry
‪createIndexEntry($identifier)
Definition: Indexer.php:65
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasHierarchicalIdentifiers
‪hasHierarchicalIdentifiers()
Definition: ResourceStorage.php:421
‪TYPO3\CMS\Core\Resource\ResourceStorage\moveFolderBetweenStorages
‪moveFolderBetweenStorages(Folder $folderToMove, Folder $targetParentFolder, $newFolderName)
Definition: ResourceStorage.php:2268
‪TYPO3\CMS\Core\Resource\ResourceStorage\$eventDispatcher
‪EventDispatcherInterface $eventDispatcher
Definition: ResourceStorage.php:180
‪TYPO3\CMS\Core\Resource\Folder\getFiles
‪TYPO3 CMS Core Resource File[] getFiles($start=0, $numberOfItems=0, $filterMode=self::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, $recursive=false, $sort='', $sortRev=false)
Definition: Folder.php:202
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFolderCopyPermissions
‪assureFolderCopyPermissions(FolderInterface $folderToCopy, FolderInterface $targetParentFolder)
Definition: ResourceStorage.php:1144
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_MOUNT
‪const ROLE_MOUNT
Definition: FolderInterface.php:33
‪TYPO3\CMS\Core\Resource\ResourceStorage\$fileProcessingService
‪Service FileProcessingService $fileProcessingService
Definition: ResourceStorage.php:149
‪TYPO3\CMS\Core\Resource\ResourceStorage\getNamesForNestedProcessingFolder
‪string[] getNamesForNestedProcessingFolder($fileIdentifier, $levels)
Definition: ResourceStorage.php:2879
‪TYPO3\CMS\Core\Resource\ResourceStorage\$folders
‪foreach($folderIdentifiers as $folderIdentifier) return $folders
Definition: ResourceStorage.php:2463
‪TYPO3\CMS\Core\Resource\Search\Result\FileSearchResultInterface
Definition: FileSearchResultInterface.php:24
‪TYPO3\CMS\Core\Resource\ResourceStorage\sanitizeFileName
‪string sanitizeFileName($fileName, Folder $targetFolder=null)
Definition: ResourceStorage.php:1210
‪TYPO3\CMS\Core\Resource\Capabilities\CAPABILITY_WRITABLE
‪const CAPABILITY_WRITABLE
Definition: Capabilities.php:36
‪TYPO3\CMS\Core\Resource\ResourceStorage\createFolderObject
‪Folder createFolderObject(string $identifier, string $name)
Definition: ResourceStorage.php:2989
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_USER_MOUNT
‪const ROLE_USER_MOUNT
Definition: FolderInterface.php:35
‪TYPO3\CMS\Core\Resource\ResourceStorage\$isDefault
‪bool $isDefault
Definition: ResourceStorage.php:200
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:47
‪TYPO3\CMS\Core\Resource\ResourceStorage\$this
‪return $this
Definition: ResourceStorage.php:1535
‪TYPO3\CMS\Core\Resource\ResourceStorage\$processingFolders
‪Folder[] $processingFolders
Definition: ResourceStorage.php:190
‪TYPO3\CMS\Core\Resource\Event\BeforeFileAddedEvent
Definition: BeforeFileAddedEvent.php:30
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFolderReadPermission
‪assureFolderReadPermission(Folder $folder=null)
Definition: ResourceStorage.php:849
‪TYPO3\CMS\Core\Resource\ResourceStorage\usesCaseSensitiveIdentifiers
‪bool usesCaseSensitiveIdentifiers()
Definition: ResourceStorage.php:454
‪TYPO3\CMS\Core\Resource\Exception
Definition: Exception.php:21
‪TYPO3\CMS\Core\Http\FalDumpFileContentsDecoratorStream
Definition: FalDumpFileContentsDecoratorStream.php:33
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFileInFolder
‪bool hasFileInFolder($fileName, Folder $folder)
Definition: ResourceStorage.php:1715
‪TYPO3\CMS\Core\Resource\ResourceStorage\$capabilities
‪Capabilities $capabilities
Definition: ResourceStorage.php:176
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_READONLY_MOUNT
‪const ROLE_READONLY_MOUNT
Definition: FolderInterface.php:34
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileCopyPermissions
‪assureFileCopyPermissions(FileInterface $file, Folder $targetFolder, $targetFileName)
Definition: ResourceStorage.php:1112
‪TYPO3\CMS\Core\Resource\ResourceStorage\$evaluatePermissions
‪bool $evaluatePermissions
Definition: ResourceStorage.php:158
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:128
‪TYPO3\CMS\Core\Resource\ResourceStorage\setDriver
‪ResourceStorage setDriver(DriverInterface $driver)
Definition: ResourceStorage.php:306
‪TYPO3\CMS\Core\Resource\Event\BeforeFolderCopiedEvent
Definition: BeforeFolderCopiedEvent.php:27
‪TYPO3\CMS\Core\Resource\ResourceStorage\getPseudoStream
‪ResponseInterface getPseudoStream(FileInterface $file, bool $asDownload=false, string $alternativeFilename=null, string $overrideMimeType=null)
Definition: ResourceStorage.php:1769
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFolderMovePermissions
‪assureFolderMovePermissions(FolderInterface $folderToMove, FolderInterface $targetParentFolder)
Definition: ResourceStorage.php:1178
‪TYPO3\CMS\Core\Resource\ResourceStorage\isPublic
‪bool isPublic()
Definition: ResourceStorage.php:392
‪TYPO3\CMS\Core\Resource\ProcessedFile\getOriginalFile
‪getOriginalFile()
Definition: ProcessedFile.php:273
‪TYPO3\CMS\Core\Log\LogManager
Definition: LogManager.php:33
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪if
‪if(PHP_SAPI !=='cli')
Definition: checkNamespaceIntegrity.php:27
‪TYPO3\CMS\Core\Resource\Folder\hasFolder
‪hasFolder(string $name)
Definition: Folder.php:431
‪TYPO3\CMS\Core\Http\UploadedFile
Definition: UploadedFile.php:34
‪TYPO3\CMS\Core\Resource\ResourceStorage\getNearestRecyclerFolder
‪Folder null getNearestRecyclerFolder(FileInterface $file)
Definition: ResourceStorage.php:2949
‪TYPO3\CMS\Core\Resource\ResourceStorage\countFoldersInFolder
‪int countFoldersInFolder(Folder $folder, $useFilters=true, $recursive=false)
Definition: ResourceStorage.php:2476
‪TYPO3\CMS\Core\Resource\FolderInterface\ROLE_RECYCLER
‪const ROLE_RECYCLER
Definition: FolderInterface.php:29
‪TYPO3\CMS\Core\Resource\Exception\InsufficientFolderWritePermissionsException
Definition: InsufficientFolderWritePermissionsException.php:21
‪TYPO3\CMS\Core\Resource\FolderInterface
Definition: FolderInterface.php:24
‪TYPO3\CMS\Core\Resource\ResourceStorage\hashFile
‪string hashFile(FileInterface $fileObject, $hash)
Definition: ResourceStorage.php:1317
‪TYPO3\CMS\Core\Resource\ResourceStorage\setConfiguration
‪setConfiguration(array $configuration)
Definition: ResourceStorage.php:286
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObject
‪File getFileObject($uid, array $fileData=[])
Definition: ResourceFactory.php:193
‪TYPO3\CMS\Core\Resource\ResourceStorage\updateProcessedFile
‪FileInterface updateProcessedFile($localFilePath, ProcessedFile $processedFile, Folder $processingFolder=null)
Definition: ResourceStorage.php:1296
‪TYPO3\CMS\Core\Resource\ResourceStorage\checkValidFileExtension
‪checkValidFileExtension(FileInterface $file)
Definition: ResourceStorage.php:836
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileRenamePermissions
‪assureFileRenamePermissions(FileInterface $file, $targetFileName)
Definition: ResourceStorage.php:1081
‪TYPO3\CMS\Core\Utility\Exception\NotImplementedMethodException
Definition: NotImplementedMethodException.php:26
‪TYPO3\CMS\Core\Resource\Filter\ImportExportFilter
Definition: ImportExportFilter.php:31
‪TYPO3\CMS\Core\Resource\ResourceStorage\$folders
‪foreach($this->getProcessingFolders() as $processingFolder) $folders
Definition: ResourceStorage.php:2462
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileWritePermissions
‪assureFileWritePermissions(FileInterface $file)
Definition: ResourceStorage.php:924
‪TYPO3\CMS\Core\Resource\Folder\getIdentifier
‪non empty string getIdentifier()
Definition: Folder.php:150
‪TYPO3\CMS\Core\Resource\DuplicationBehavior\REPLACE
‪const REPLACE
Definition: DuplicationBehavior.php:40
‪TYPO3\CMS\Core\Resource\ResourceInterface
Definition: ResourceInterface.php:21
‪TYPO3\CMS\Core\Resource\ResourceStorage\isWritable
‪bool isWritable()
Definition: ResourceStorage.php:403
‪TYPO3\CMS\Core\Resource\Folder\getCombinedIdentifier
‪string getCombinedIdentifier()
Definition: Folder.php:166
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Core\Resource\ResourceStorage\$userPermissions
‪array $userPermissions
Definition: ResourceStorage.php:171
‪TYPO3\CMS\Core\Resource\Service\FileProcessingService
Definition: FileProcessingService.php:46
‪TYPO3\CMS\Core\Resource\ResourceStorage\isFallbackStorage
‪isFallbackStorage()
Definition: ResourceStorage.php:358
‪TYPO3\CMS\Core\Resource\Event\SanitizeFileNameEvent
Definition: SanitizeFileNameEvent.php:29
‪TYPO3\CMS\Core\Resource\AbstractFile\updateProperties
‪updateProperties(array $properties)
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Resource\ResourceStorage\unsetFileAndFolderNameFilters
‪unsetFileAndFolderNameFilters()
Definition: ResourceStorage.php:1493
‪TYPO3\CMS\Core\Resource\Event\BeforeFolderMovedEvent
Definition: BeforeFolderMovedEvent.php:28
‪TYPO3\CMS\Core\Resource\ProcessedFile\getName
‪non empty string getName()
Definition: ProcessedFile.php:301
‪TYPO3\CMS\Core\Resource\ResourceStorage\checkFileActionPermission
‪bool checkFileActionPermission($action, FileInterface $file)
Definition: ResourceStorage.php:708
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasCapability
‪hasCapability(int $capability)
Definition: ResourceStorage.php:379
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Resource\Exception\FileOperationErrorException
Definition: FileOperationErrorException.php:21
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolderIdentifiersInFolder
‪array getFolderIdentifiersInFolder($folderIdentifier, $useFilters=true, $recursive=false)
Definition: ResourceStorage.php:1641
‪TYPO3\CMS\Core\Resource\Event\AfterFileReplacedEvent
Definition: AfterFileReplacedEvent.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\checkUserActionPermission
‪bool checkUserActionPermission($action, $type)
Definition: ResourceStorage.php:682
‪TYPO3\CMS\Core\Resource\Event\AfterFolderDeletedEvent
Definition: AfterFolderDeletedEvent.php:27
‪TYPO3\CMS\Core\Http\UploadedFile\getTemporaryFileName
‪getTemporaryFileName()
Definition: UploadedFile.php:238
‪TYPO3\CMS\Core\Resource\FileReference\getStorage
‪getStorage()
Definition: FileReference.php:351
‪TYPO3\CMS\Core\Resource\Event\AfterFileDeletedEvent
Definition: AfterFileDeletedEvent.php:29
‪TYPO3\CMS\Core\Resource\Driver\StreamableDriverInterface
Definition: StreamableDriverInterface.php:29
‪TYPO3\CMS\Core\Resource\ResourceStorage\getPublicUrl
‪string null getPublicUrl(ResourceInterface $resourceObject)
Definition: ResourceStorage.php:1365
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUniqueName
‪string getUniqueName(FolderInterface $folder, $theFile, $dontCheckForUnique=false)
Definition: ResourceStorage.php:2673
‪TYPO3\CMS\Core\Resource\AbstractFile\getIdentifier
‪getIdentifier()
Definition: AbstractFile.php:144
‪TYPO3\CMS\Core\Resource\ResourceStorage\deleteFile
‪bool deleteFile($fileObject)
Definition: ResourceStorage.php:1854
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFolderDeletePermission
‪assureFolderDeletePermission(Folder $folder, $checkDeleteRecursively)
Definition: ResourceStorage.php:874
‪TYPO3\CMS\Core\Resource\Exception\InvalidHashException
Definition: InvalidHashException.php:26
‪TYPO3\CMS\Core\Resource\Event\BeforeFileContentsSetEvent
Definition: BeforeFileContentsSetEvent.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\getIndexer
‪Index Indexer getIndexer()
Definition: ResourceStorage.php:2907
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFolderInFolder
‪bool hasFolderInFolder($folderName, Folder $folder)
Definition: ResourceStorage.php:2501
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileIndexRepository
‪Index FileIndexRepository getFileIndexRepository()
Definition: ResourceStorage.php:2719
‪TYPO3\CMS\Core\Utility\PathUtility\pathinfo
‪static string string[] pathinfo(string $path, int $options=PATHINFO_ALL)
Definition: PathUtility.php:270
‪TYPO3\CMS\Core\Resource\ResourceStorage\copyFolder
‪Folder copyFolder(FolderInterface $folderToCopy, FolderInterface $targetParentFolder, $newFolderName=null, $conflictMode=DuplicationBehavior::RENAME)
Definition: ResourceStorage.php:2284
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode(string $delim, string $string, bool $removeEmptyValues=false, int $limit=0)
Definition: GeneralUtility.php:817
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:56
‪TYPO3\CMS\Core\Resource\Event\AfterFileAddedEvent
Definition: AfterFileAddedEvent.php:30
‪TYPO3\CMS\Core\Resource\ResourceStorage\setDefault
‪setDefault($isDefault)
Definition: ResourceStorage.php:2915
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByStorageAndIdentifier
‪array bool findOneByStorageAndIdentifier(ResourceStorage $storage, $identifier)
Definition: FileIndexRepository.php:124
‪TYPO3\CMS\Core\Resource\ResourceStorage\getName
‪string getName()
Definition: ResourceStorage.php:327
‪TYPO3\CMS\Core\Resource\ResourceStorage\$fileMounts
‪array $fileMounts
Definition: ResourceStorage.php:164
‪TYPO3\CMS\Core\Resource\ResourceStorage\assureFileUploadPermissions
‪assureFileUploadPermissions($localFilePath, $targetFolder, $targetFileName, $uploadedFileSize)
Definition: ResourceStorage.php:1028
‪TYPO3\CMS\Core\Resource\ResourceStorage\getNestedProcessingFolder
‪Folder getNestedProcessingFolder(File $file, Folder $rootProcessingFolder)
Definition: ResourceStorage.php:2847
‪TYPO3\CMS\Core\Http\UploadedFile\getSize
‪int null getSize()
Definition: UploadedFile.php:193