‪TYPO3CMS  ‪main
ResourceFactory.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Http\Message\ServerRequestInterface;
19 use TYPO3\CMS\Backend\Utility\BackendUtility;
36 
41 {
45  protected ‪$collectionInstances = [];
46 
50  protected ‪$fileInstances = [];
51 
55  protected ‪$fileReferenceInstances = [];
56 
57  public function ‪__construct(
58  protected readonly ‪StorageRepository $storageRepository,
59  ) {
60  }
61 
73  public function ‪getDefaultStorage()
74  {
75  return $this->storageRepository->getDefaultStorage();
76  }
77 
90  public function ‪getStorageObject(‪$uid, array $recordData = [], &$fileIdentifier = null)
91  {
92  return $this->storageRepository->getStorageObject(‪$uid, $recordData, $fileIdentifier);
93  }
94 
105  public function ‪convertFlexFormDataToConfigurationArray($flexFormData)
106  {
107  $configuration = [];
108  if ($flexFormData) {
109  $flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
110  $configuration = $flexFormService->convertFlexFormContentToArray($flexFormData);
111  }
112  return $configuration;
113  }
114 
124  public function ‪getCollectionObject(‪$uid, array $recordData = [])
125  {
126  if (!is_numeric(‪$uid)) {
127  throw new \InvalidArgumentException('The UID of collection has to be numeric. UID given: "' . ‪$uid . '"', 1314085999);
128  }
129  if (!isset($this->collectionInstances[‪$uid])) {
130  // Get mount data if not already supplied as argument to this function
131  if (empty($recordData) || $recordData['uid'] !== ‪$uid) {
132  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_collection');
133  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
134  $recordData = $queryBuilder->select('*')
135  ->from('sys_file_collection')
136  ->where(
137  $queryBuilder->expr()->eq(
138  'uid',
139  $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)
140  )
141  )
142  ->executeQuery()
143  ->fetchAssociative();
144  if (empty($recordData)) {
145  throw new \InvalidArgumentException('No collection found for given UID: "' . ‪$uid . '"', 1314085992);
146  }
147  }
148  $collectionObject = $this->‪createCollectionObject($recordData);
149  $this->collectionInstances[‪$uid] = $collectionObject;
150  }
151  return $this->collectionInstances[‪$uid];
152  }
153 
160  public function ‪createCollectionObject(array $collectionData)
161  {
162  $registry = GeneralUtility::makeInstance(FileCollectionRegistry::class);
163 
165  $class = $registry->getFileCollectionClass($collectionData['type']);
166 
167  return $class::create($collectionData);
168  }
169 
179  public function ‪createFolderObject(‪ResourceStorage $storage, ‪$identifier, $name)
180  {
181  return GeneralUtility::makeInstance(Folder::class, $storage, ‪$identifier, $name);
182  }
183 
195  public function ‪getFileObject(‪$uid, array $fileData = [])
196  {
197  if (!is_numeric(‪$uid)) {
198  throw new \InvalidArgumentException('The UID of file has to be numeric. UID given: "' . ‪$uid . '"', 1300096564);
199  }
200  if (empty($this->fileInstances[‪$uid])) {
201  // Fetches data in case $fileData is empty
202  if (empty($fileData)) {
203  $fileData = $this->‪getFileIndexRepository()->‪findOneByUid($uid);
204  if ($fileData === false) {
205  throw new ‪FileDoesNotExistException('No file found for given UID: ' . ‪$uid, 1317178604);
206  }
207  }
208  $this->fileInstances[‪$uid] = $this->‪createFileObject($fileData);
209  }
210  return $this->fileInstances[‪$uid];
211  }
212 
221  {
222  if (!is_string(‪$identifier) || ‪$identifier === '') {
223  throw new \InvalidArgumentException('Invalid file identifier given. It must be of type string and not empty. "' . gettype(‪$identifier) . '" given.', 1401732564);
224  }
225  $parts = GeneralUtility::trimExplode(':', ‪$identifier);
226  if (count($parts) === 2) {
227  $storageUid = (int)$parts[0];
228  $fileIdentifier = $parts[1];
229  } else {
230  // We only got a path: Go into backwards compatibility mode and
231  // use virtual Storage (uid=0)
232  $storageUid = 0;
233  $fileIdentifier = $parts[0];
234  }
235  return $this->storageRepository->getStorageObject($storageUid, [], $fileIdentifier)
236  ->getFileByIdentifier($fileIdentifier);
237  }
238 
249  public function ‪getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
250  {
251  if (!($storage instanceof ‪ResourceStorage)) {
252  $storage = $this->storageRepository->getStorageObject($storage, [], $fileIdentifier);
253  }
254  return $storage->‪getFileByIdentifier($fileIdentifier);
255  }
256 
277  public function ‪retrieveFileOrFolderObject($input)
278  {
279  // Remove Environment::getPublicPath() because absolute paths under Windows systems contain ':'
280  // This is done in all considered sub functions anyway
281  $input = str_replace(‪Environment::getPublicPath() . '/', '', (string)$input);
282 
283  if (str_starts_with($input, 'file:')) {
284  $input = substr($input, 5);
285  return $this->‪retrieveFileOrFolderObject($input);
286  }
288  return $this->‪getFileObject((int)$input);
289  }
290  if (strpos($input, ':') > 0) {
291  [$prefix] = explode(':', $input);
293  // path or folder in a valid storageUID
294  return $this->‪getObjectFromCombinedIdentifier($input);
295  }
296  if ($prefix === 'EXT') {
297  $absoluteFilePath = GeneralUtility::getFileAbsFileName($input);
298  if (empty($absoluteFilePath)) {
299  return null;
300  }
301  if (str_starts_with($absoluteFilePath, ‪Environment::getPublicPath())) {
302  $relativePath = ‪PathUtility::getRelativePath(‪Environment::getPublicPath() . '/', ‪PathUtility::dirname($absoluteFilePath)) . ‪PathUtility::basename($absoluteFilePath);
303  } else {
304  try {
305  $relativePath = ‪PathUtility::getPublicResourceWebPath($input);
306  } catch (\Throwable $e) {
307  throw new ‪ResourceDoesNotExistException(sprintf('Tried to access a private resource file "%s" from fallback compatibility storage. This storage only handles public files.', $input), 1633777536);
308  }
309  }
310 
311  return $this->‪getFileObjectFromCombinedIdentifier($relativePath);
312  }
313  return null;
314  }
315  // this is a backwards-compatible way to access "0-storage" files or folders
316  // eliminate double slashes, /./ and /../
317  $input = ‪PathUtility::getCanonicalPath(ltrim($input, '/'));
318  if (@is_file(‪Environment::getPublicPath() . '/' . $input)) {
319  // only the local file
320  return $this->‪getFileObjectFromCombinedIdentifier($input);
321  }
322  // only the local path
323  return $this->‪getFolderObjectFromCombinedIdentifier($input);
324  }
325 
334  {
335  $parts = GeneralUtility::trimExplode(':', ‪$identifier);
336  if (count($parts) === 2) {
337  $storageUid = (int)$parts[0];
338  $folderIdentifier = $parts[1];
339  } else {
340  // We only got a path: Go into backwards compatibility mode and
341  // use virtual Storage (uid=0)
342  $storageUid = 0;
343 
344  // please note that getStorageObject() might modify $folderIdentifier when
345  // auto-detecting the best-matching storage to use
346  $folderIdentifier = $parts[0];
347  // make sure to not use an absolute path, and remove Environment::getPublicPath if it is prepended
348  if (str_starts_with($folderIdentifier, ‪Environment::getPublicPath() . '/')) {
349  $folderIdentifier = ‪PathUtility::stripPathSitePrefix($parts[0]);
350  }
351  }
352  return $this->storageRepository->getStorageObject($storageUid, [], $folderIdentifier)->getFolder($folderIdentifier);
353  }
354 
363  {
364  $parts = GeneralUtility::trimExplode(':', ‪$identifier);
365  $storageUid = count($parts) === 2 ? $parts[0] : null;
366  return $this->storageRepository->findByUid($storageUid);
367  }
368 
378  {
379  [$storageId, $objectIdentifier] = GeneralUtility::trimExplode(':', ‪$identifier);
380  $storage = $this->storageRepository->findByUid($storageId);
381  if ($storage->‪hasFile($objectIdentifier)) {
382  return $storage->‪getFile($objectIdentifier);
383  }
384  if ($storage->‪hasFolder($objectIdentifier)) {
385  return $storage->‪getFolder($objectIdentifier);
386  }
387  throw new ‪ResourceDoesNotExistException('Object with identifier "' . ‪$identifier . '" does not exist in storage', 1329647780);
388  }
389 
396  public function ‪createFileObject(array $fileData, ‪ResourceStorage $storage = null)
397  {
398  if (array_key_exists('storage', $fileData) && ‪MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
399  $storageObject = $this->storageRepository->findByUid((int)$fileData['storage']);
400  } elseif ($storage !== null) {
401  $storageObject = $storage;
402  $fileData['storage'] = $storage->‪getUid();
403  } else {
404  throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
405  }
406  $fileObject = GeneralUtility::makeInstance(File::class, $fileData, $storageObject);
407  return $fileObject;
408  }
409 
421  public function ‪getFileReferenceObject(‪$uid, array $fileReferenceData = [], $raw = false)
422  {
423  if (!is_numeric(‪$uid)) {
424  throw new \InvalidArgumentException(
425  'The reference UID for the file (sys_file_reference) has to be numeric. UID given: "' . ‪$uid . '"',
426  1300086584
427  );
428  }
429  if (!($this->fileReferenceInstances[‪$uid] ?? false)) {
430  // Fetches data in case $fileData is empty
431  if (empty($fileReferenceData)) {
432  $fileReferenceData = $this->‪getFileReferenceData($uid, $raw);
433  if (!is_array($fileReferenceData)) {
435  'No file reference (sys_file_reference) was found for given UID: "' . ‪$uid . '"',
436  1317178794
437  );
438  }
439  }
440  $this->fileReferenceInstances[‪$uid] = $this->‪createFileReferenceObject($fileReferenceData);
441  }
442  return $this->fileReferenceInstances[‪$uid];
443  }
444 
452  public function ‪createFileReferenceObject(array $fileReferenceData)
453  {
454  $fileReferenceObject = GeneralUtility::makeInstance(FileReference::class, $fileReferenceData);
455  return $fileReferenceObject;
456  }
457 
465  protected function ‪getFileReferenceData(‪$uid, $raw = false)
466  {
467  if (!$raw
468  && (‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
469  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isBackend()
470  ) {
471  $fileReferenceData = BackendUtility::getRecordWSOL('sys_file_reference', ‪$uid);
472  } elseif (!$raw && is_object(‪$GLOBALS['TSFE'] ?? false)) {
473  $fileReferenceData = ‪$GLOBALS['TSFE']->sys_page->checkRecord('sys_file_reference', ‪$uid);
474  } else {
475  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
476  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
477  $fileReferenceData = $queryBuilder->select('*')
478  ->from('sys_file_reference')
479  ->where(
480  $queryBuilder->expr()->eq(
481  'uid',
482  $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)
483  )
484  )
485  ->executeQuery()
486  ->fetchAssociative();
487  }
488  return $fileReferenceData;
489  }
490 
496  protected function ‪getFileIndexRepository()
497  {
498  return GeneralUtility::makeInstance(FileIndexRepository::class);
499  }
500 }
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFileByIdentifier
‪File ProcessedFile null getFileByIdentifier(string $fileIdentifier)
Definition: ResourceStorage.php:1417
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath(string $path)
Definition: PathUtility.php:364
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileReferenceObject
‪FileReference createFileReferenceObject(array $fileReferenceData)
Definition: ResourceFactory.php:449
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static stripPathSitePrefix(string $path)
Definition: PathUtility.php:428
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:44
‪TYPO3\CMS\Core\Resource\ResourceFactory\getCollectionObject
‪Collection AbstractFileCollection getCollectionObject($uid, array $recordData=[])
Definition: ResourceFactory.php:121
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:46
‪TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection
Definition: AbstractFileCollection.php:28
‪TYPO3\CMS\Core\Resource\ResourceStorage\getUid
‪int getUid()
Definition: ResourceStorage.php:336
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileObject
‪File createFileObject(array $fileData, ResourceStorage $storage=null)
Definition: ResourceFactory.php:393
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:24
‪TYPO3\CMS\Core\Resource\ResourceFactory\__construct
‪__construct(protected readonly StorageRepository $storageRepository,)
Definition: ResourceFactory.php:54
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectByStorageAndIdentifier
‪File ProcessedFile null getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
Definition: ResourceFactory.php:246
‪TYPO3\CMS\Core\Resource\ResourceFactory\getObjectFromCombinedIdentifier
‪FileInterface Folder getObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:374
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObjectFromCombinedIdentifier
‪ResourceStorage getStorageObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:359
‪TYPO3\CMS\Core\Collection\AbstractRecordCollection
Definition: AbstractRecordCollection.php:40
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static getPublicPath()
Definition: Environment.php:187
‪TYPO3\CMS\Core\Collection\CollectionInterface
Definition: CollectionInterface.php:29
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFolder
‪Folder InaccessibleFolder getFolder($identifier, $returnInaccessibleFolderObject=false)
Definition: ResourceStorage.php:2501
‪TYPO3\CMS\Core\Resource\ResourceStorage\getFile
‪FileInterface getFile($identifier)
Definition: ResourceStorage.php:1401
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFolderObjectFromCombinedIdentifier
‪Folder getFolderObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:330
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:35
‪TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
Definition: FileDoesNotExistException.php:22
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFolder
‪bool hasFolder($identifier)
Definition: ResourceStorage.php:2414
‪TYPO3\CMS\Core\Resource\ResourceFactory\createCollectionObject
‪CollectionInterface< File > createCollectionObject(array $collectionData)
Definition: ResourceFactory.php:157
‪TYPO3\CMS\Core\Resource\ResourceFactory\$fileReferenceInstances
‪FileReference[] $fileReferenceInstances
Definition: ResourceFactory.php:52
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static basename(string $path)
Definition: PathUtility.php:219
‪TYPO3\CMS\Core\Resource\ResourceStorage\hasFile
‪bool hasFile($identifier)
Definition: ResourceStorage.php:1620
‪TYPO3\CMS\Core\Resource\ResourceFactory\$fileInstances
‪File[] $fileInstances
Definition: ResourceFactory.php:48
‪TYPO3\CMS\Core\Service\FlexFormService
Definition: FlexFormService.php:25
‪TYPO3\CMS\Core\Resource\ResourceFactory\$collectionInstances
‪array< int, CollectionInterface< File > > $collectionInstances
Definition: ResourceFactory.php:44
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger(mixed $var)
Definition: MathUtility.php:69
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static dirname(string $path)
Definition: PathUtility.php:243
‪TYPO3\CMS\Core\Utility\PathUtility\getPublicResourceWebPath
‪static getPublicResourceWebPath(string $resourcePath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:97
‪TYPO3\CMS\Core\Resource\ResourceFactory\convertFlexFormDataToConfigurationArray
‪array convertFlexFormDataToConfigurationArray($flexFormData)
Definition: ResourceFactory.php:102
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePath
‪static getRelativePath(string $sourcePath, string $targetPath)
Definition: PathUtility.php:129
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:37
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:41
‪TYPO3\CMS\Core\Resource\StorageRepository
Definition: StorageRepository.php:38
‪TYPO3\CMS\Core\Resource\Exception\ResourceDoesNotExistException
Definition: ResourceDoesNotExistException.php:24
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:26
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceObject
‪FileReference getFileReferenceObject($uid, array $fileReferenceData=[], $raw=false)
Definition: ResourceFactory.php:418
‪TYPO3\CMS\Core\Resource\Collection\FileCollectionRegistry
Definition: FileCollectionRegistry.php:25
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectFromCombinedIdentifier
‪File ProcessedFile null getFileObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:217
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:47
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪return MathUtility::canBeInterpretedAsInteger($size) ?(int) $size int getUid()
Definition: AbstractFile.php:188
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileIndexRepository
‪FileIndexRepository getFileIndexRepository()
Definition: ResourceFactory.php:493
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:35
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFolderObject
‪Folder createFolderObject(ResourceStorage $storage, $identifier, $name)
Definition: ResourceFactory.php:176
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:127
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:73
‪TYPO3\CMS\Webhooks\Message\$uid
‪identifier readonly int $uid
Definition: PageModificationMessage.php:35
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObject
‪ResourceStorage getStorageObject($uid, array $recordData=[], &$fileIdentifier=null)
Definition: ResourceFactory.php:87
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:23
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction
Definition: DeletedRestriction.php:28
‪TYPO3\CMS\Core\Core\Environment
Definition: Environment.php:41
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:24
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObject
‪File getFileObject($uid, array $fileData=[])
Definition: ResourceFactory.php:192
‪TYPO3\CMS\Core\Resource\ResourceFactory\getDefaultStorage
‪ResourceStorage null getDefaultStorage()
Definition: ResourceFactory.php:70
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:274
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:56
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceData
‪array null getFileReferenceData($uid, $raw=false)
Definition: ResourceFactory.php:462