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