‪TYPO3CMS  11.5
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 
60  protected ‪$storageRepository;
61 
63  {
64  $this->storageRepository = ‪$storageRepository;
65  }
66 
78  public function ‪getDefaultStorage()
79  {
80  return $this->storageRepository->getDefaultStorage();
81  }
82 
95  public function ‪getStorageObject($uid, array $recordData = [], &$fileIdentifier = null)
96  {
97  return $this->storageRepository->getStorageObject($uid, $recordData, $fileIdentifier);
98  }
99 
110  public function ‪convertFlexFormDataToConfigurationArray($flexFormData)
111  {
112  $configuration = [];
113  if ($flexFormData) {
114  $flexFormService = GeneralUtility::makeInstance(FlexFormService::class);
115  $configuration = $flexFormService->convertFlexFormContentToArray($flexFormData);
116  }
117  return $configuration;
118  }
119 
129  public function ‪getCollectionObject($uid, array $recordData = [])
130  {
131  if (!is_numeric($uid)) {
132  throw new \InvalidArgumentException('The UID of collection has to be numeric. UID given: "' . $uid . '"', 1314085999);
133  }
134  if (!isset($this->collectionInstances[$uid])) {
135  // Get mount data if not already supplied as argument to this function
136  if (empty($recordData) || $recordData['uid'] !== $uid) {
137  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_collection');
138  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
139  $recordData = $queryBuilder->select('*')
140  ->from('sys_file_collection')
141  ->where(
142  $queryBuilder->expr()->eq(
143  'uid',
144  $queryBuilder->createNamedParameter($uid, ‪Connection::PARAM_INT)
145  )
146  )
147  ->executeQuery()
148  ->fetchAssociative();
149  if (empty($recordData)) {
150  throw new \InvalidArgumentException('No collection found for given UID: "' . $uid . '"', 1314085992);
151  }
152  }
153  $collectionObject = $this->‪createCollectionObject($recordData);
154  $this->collectionInstances[$uid] = $collectionObject;
155  }
156  return $this->collectionInstances[$uid];
157  }
158 
165  public function ‪createCollectionObject(array $collectionData)
166  {
167  $registry = GeneralUtility::makeInstance(FileCollectionRegistry::class);
168 
170  $class = $registry->getFileCollectionClass($collectionData['type']);
171 
172  return $class::create($collectionData);
173  }
174 
183  public function ‪createStorageObject(array $storageRecord, ?array $storageConfiguration = null)
184  {
185  return $this->storageRepository->createStorageObject($storageRecord, $storageConfiguration);
186  }
187 
197  public function ‪createFolderObject(ResourceStorage $storage, $identifier, $name)
198  {
199  return GeneralUtility::makeInstance(Folder::class, $storage, $identifier, $name);
200  }
201 
213  public function ‪getFileObject($uid, array $fileData = [])
214  {
215  if (!is_numeric($uid)) {
216  throw new \InvalidArgumentException('The UID of file has to be numeric. UID given: "' . $uid . '"', 1300096564);
217  }
218  if (empty($this->fileInstances[$uid])) {
219  // Fetches data in case $fileData is empty
220  if (empty($fileData)) {
221  $fileData = $this->‪getFileIndexRepository()->‪findOneByUid($uid);
222  if ($fileData === false) {
223  throw new FileDoesNotExistException('No file found for given UID: ' . $uid, 1317178604);
224  }
225  }
226  $this->fileInstances[$uid] = $this->‪createFileObject($fileData);
227  }
228  return $this->fileInstances[$uid];
229  }
230 
238  public function ‪getFileObjectFromCombinedIdentifier($identifier)
239  {
240  if (!is_string($identifier) || $identifier === '') {
241  throw new \InvalidArgumentException('Invalid file identifier given. It must be of type string and not empty. "' . gettype($identifier) . '" given.', 1401732564);
242  }
243  $parts = ‪GeneralUtility::trimExplode(':', $identifier);
244  if (count($parts) === 2) {
245  $storageUid = (int)$parts[0];
246  $fileIdentifier = $parts[1];
247  } else {
248  // We only got a path: Go into backwards compatibility mode and
249  // use virtual Storage (uid=0)
250  $storageUid = 0;
251  $fileIdentifier = $parts[0];
252  }
253  return $this->storageRepository->getStorageObject($storageUid, [], $fileIdentifier)
254  ->getFileByIdentifier($fileIdentifier);
255  }
256 
267  public function ‪getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
268  {
269  if (!($storage instanceof ResourceStorage)) {
270  $storage = $this->storageRepository->getStorageObject($storage, [], $fileIdentifier);
271  }
272  return $storage->getFileByIdentifier($fileIdentifier);
273  }
274 
295  public function ‪retrieveFileOrFolderObject($input)
296  {
297  // Remove Environment::getPublicPath() because absolute paths under Windows systems contain ':'
298  // This is done in all considered sub functions anyway
299  $input = str_replace(‪Environment::getPublicPath() . '/', '', (string)$input);
300 
301  if (str_starts_with($input, 'file:')) {
302  $input = substr($input, 5);
303  return $this->‪retrieveFileOrFolderObject($input);
304  }
306  return $this->‪getFileObject((int)$input);
307  }
308  if (strpos($input, ':') > 0) {
309  [$prefix] = explode(':', $input);
311  // path or folder in a valid storageUID
312  return $this->‪getObjectFromCombinedIdentifier($input);
313  }
314  if ($prefix === 'EXT') {
315  $absoluteFilePath = GeneralUtility::getFileAbsFileName($input);
316  if (empty($absoluteFilePath)) {
317  return null;
318  }
319  if (str_starts_with($absoluteFilePath, ‪Environment::getPublicPath())) {
320  $relativePath = ‪PathUtility::getRelativePath(‪Environment::getPublicPath() . '/', ‪PathUtility::dirname($absoluteFilePath)) . ‪PathUtility::basename($absoluteFilePath);
321  } else {
322  try {
323  $relativePath = ‪PathUtility::getPublicResourceWebPath($input);
324  } catch (\Throwable $e) {
325  throw new ResourceDoesNotExistException(sprintf('Tried to access a private resource file "%s" from fallback compatibility storage. This storage only handles public files.', $input), 1633777536);
326  }
327  }
328 
329  return $this->‪getFileObjectFromCombinedIdentifier($relativePath);
330  }
331  return null;
332  }
333  // this is a backwards-compatible way to access "0-storage" files or folders
334  // eliminate double slashes, /./ and /../
335  $input = ‪PathUtility::getCanonicalPath(ltrim($input, '/'));
336  if (@is_file(‪Environment::getPublicPath() . '/' . $input)) {
337  // only the local file
338  return $this->‪getFileObjectFromCombinedIdentifier($input);
339  }
340  // only the local path
341  return $this->‪getFolderObjectFromCombinedIdentifier($input);
342  }
343 
351  public function ‪getFolderObjectFromCombinedIdentifier($identifier)
352  {
353  $parts = ‪GeneralUtility::trimExplode(':', $identifier);
354  if (count($parts) === 2) {
355  $storageUid = (int)$parts[0];
356  $folderIdentifier = $parts[1];
357  } else {
358  // We only got a path: Go into backwards compatibility mode and
359  // use virtual Storage (uid=0)
360  $storageUid = 0;
361 
362  // please note that getStorageObject() might modify $folderIdentifier when
363  // auto-detecting the best-matching storage to use
364  $folderIdentifier = $parts[0];
365  // make sure to not use an absolute path, and remove Environment::getPublicPath if it is prepended
366  if (str_starts_with($folderIdentifier, ‪Environment::getPublicPath() . '/')) {
367  $folderIdentifier = ‪PathUtility::stripPathSitePrefix($parts[0]);
368  }
369  }
370  return $this->storageRepository->getStorageObject($storageUid, [], $folderIdentifier)->getFolder($folderIdentifier);
371  }
372 
380  public function ‪getStorageObjectFromCombinedIdentifier($identifier)
381  {
382  [$storageId, $objectIdentifier] = array_pad(‪GeneralUtility::trimExplode(':', $identifier), 2, null);
383  if (!‪MathUtility::canBeInterpretedAsInteger($storageId) && $objectIdentifier === null) {
384  return $this->storageRepository->findByUid(0);
385  }
386  return $this->storageRepository->findByUid((int)$storageId);
387  }
388 
397  public function ‪getObjectFromCombinedIdentifier($identifier)
398  {
399  [$storageId, $objectIdentifier] = array_pad(‪GeneralUtility::trimExplode(':', $identifier), 2, null);
400  if (!‪MathUtility::canBeInterpretedAsInteger($storageId) && $objectIdentifier === null) {
401  $objectIdentifier = $storageId;
402  $storageId = 0;
403  }
405  $storage = $this->storageRepository->findByUid($storageId);
406  if ($storage->hasFile($objectIdentifier)) {
407  return $storage->getFile($objectIdentifier);
408  }
409  if ($storage->hasFolder($objectIdentifier)) {
410  return $storage->getFolder($objectIdentifier);
411  }
412  }
413  throw new ResourceDoesNotExistException('Object with identifier "' . $identifier . '" does not exist in storage', 1329647780);
414  }
415 
424  public function ‪createFileObject(array $fileData, ?ResourceStorage $storage = null)
425  {
426  if (array_key_exists('storage', $fileData) && ‪MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
427  $storageObject = $this->storageRepository->findByUid((int)$fileData['storage']);
428  } elseif ($storage !== null) {
429  $storageObject = $storage;
430  $fileData['storage'] = $storage->‪getUid();
431  } else {
432  throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
433  }
434  $fileObject = GeneralUtility::makeInstance(File::class, $fileData, $storageObject);
435  return $fileObject;
436  }
437 
449  public function ‪getFileReferenceObject($uid, array $fileReferenceData = [], $raw = false)
450  {
451  if (!is_numeric($uid)) {
452  throw new \InvalidArgumentException(
453  'The reference UID for the file (sys_file_reference) has to be numeric. UID given: "' . $uid . '"',
454  1300086584
455  );
456  }
457  if (!($this->fileReferenceInstances[$uid] ?? false)) {
458  // Fetches data in case $fileData is empty
459  if (empty($fileReferenceData)) {
460  $fileReferenceData = $this->‪getFileReferenceData($uid, $raw);
461  if (!is_array($fileReferenceData)) {
462  throw new ResourceDoesNotExistException(
463  'No file reference (sys_file_reference) was found for given UID: "' . $uid . '"',
464  1317178794
465  );
466  }
467  }
468  $this->fileReferenceInstances[$uid] = $this->‪createFileReferenceObject($fileReferenceData);
469  }
470  return $this->fileReferenceInstances[$uid];
471  }
472 
481  public function ‪createFileReferenceObject(array $fileReferenceData)
482  {
483  $fileReferenceObject = GeneralUtility::makeInstance(FileReference::class, $fileReferenceData);
484  return $fileReferenceObject;
485  }
486 
494  protected function ‪getFileReferenceData($uid, $raw = false)
495  {
496  if (!$raw
497  && (‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
498  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isBackend()
499  ) {
500  $fileReferenceData = BackendUtility::getRecordWSOL('sys_file_reference', $uid);
501  } elseif (!$raw && is_object(‪$GLOBALS['TSFE'] ?? false)) {
502  $fileReferenceData = ‪$GLOBALS['TSFE']->sys_page->checkRecord('sys_file_reference', $uid);
503  } else {
504  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
505  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
506  $fileReferenceData = $queryBuilder->select('*')
507  ->from('sys_file_reference')
508  ->where(
509  $queryBuilder->expr()->eq(
510  'uid',
511  $queryBuilder->createNamedParameter($uid, ‪Connection::PARAM_INT)
512  )
513  )
514  ->executeQuery()
515  ->fetchAssociative();
516  }
517  return $fileReferenceData;
518  }
519 
525  protected function ‪getFileIndexRepository()
526  {
527  return GeneralUtility::makeInstance(FileIndexRepository::class);
528  }
529 }
‪TYPO3\CMS\Core\Http\ApplicationType\fromRequest
‪static static fromRequest(ServerRequestInterface $request)
Definition: ApplicationType.php:62
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:999
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileReferenceObject
‪FileReference createFileReferenceObject(array $fileReferenceData)
Definition: ResourceFactory.php:477
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository
Definition: FileIndexRepository.php:42
‪TYPO3\CMS\Core\Resource\ResourceFactory\getCollectionObject
‪Collection AbstractFileCollection getCollectionObject($uid, array $recordData=[])
Definition: ResourceFactory.php:125
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:25
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:49
‪TYPO3\CMS\Core\Utility\MathUtility\canBeInterpretedAsInteger
‪static bool canBeInterpretedAsInteger($var)
Definition: MathUtility.php:74
‪TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection
Definition: AbstractFileCollection.php:28
‪TYPO3\CMS\Core\Core\Environment\getPublicPath
‪static string getPublicPath()
Definition: Environment.php:206
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Core\Utility\PathUtility\dirname
‪static string dirname($path)
Definition: PathUtility.php:251
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static string stripPathSitePrefix($path)
Definition: PathUtility.php:445
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectByStorageAndIdentifier
‪File ProcessedFile null getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
Definition: ResourceFactory.php:263
‪TYPO3\CMS\Core\Resource\ResourceFactory\getObjectFromCombinedIdentifier
‪FileInterface Folder getObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:393
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObjectFromCombinedIdentifier
‪ResourceStorage getStorageObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:376
‪TYPO3\CMS\Core\Collection\AbstractRecordCollection
Definition: AbstractRecordCollection.php:40
‪TYPO3\CMS\Core\Collection\CollectionInterface
Definition: CollectionInterface.php:29
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePath
‪static string null getRelativePath($sourcePath, $targetPath)
Definition: PathUtility.php:134
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFolderObjectFromCombinedIdentifier
‪Folder getFolderObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:347
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:33
‪TYPO3\CMS\Core\Utility\PathUtility\getPublicResourceWebPath
‪static string getPublicResourceWebPath(string $resourcePath, bool $prefixWithSitePath=true)
Definition: PathUtility.php:98
‪TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
Definition: FileDoesNotExistException.php:21
‪TYPO3\CMS\Core\Resource\ResourceFactory\createCollectionObject
‪CollectionInterface< File > createCollectionObject(array $collectionData)
Definition: ResourceFactory.php:161
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath($path)
Definition: PathUtility.php:380
‪TYPO3\CMS\Core\Resource\ResourceFactory\$fileReferenceInstances
‪FileReference[] $fileReferenceInstances
Definition: ResourceFactory.php:52
‪TYPO3\CMS\Core\Http\ApplicationType
Definition: ApplicationType.php:52
‪TYPO3\CMS\Core\Utility\PathUtility\basename
‪static string basename($path)
Definition: PathUtility.php:226
‪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\Resource\ResourceFactory\createStorageObject
‪ResourceStorage createStorageObject(array $storageRecord, ?array $storageConfiguration=null)
Definition: ResourceFactory.php:179
‪TYPO3\CMS\Core\Resource\ResourceFactory\__construct
‪__construct(StorageRepository $storageRepository)
Definition: ResourceFactory.php:58
‪TYPO3\CMS\Core\Resource\ResourceFactory\convertFlexFormDataToConfigurationArray
‪array convertFlexFormDataToConfigurationArray($flexFormData)
Definition: ResourceFactory.php:106
‪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:23
‪TYPO3\CMS\Core\Resource\File
Definition: File.php:24
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceObject
‪FileReference getFileReferenceObject($uid, array $fileReferenceData=[], $raw=false)
Definition: ResourceFactory.php:445
‪TYPO3\CMS\Core\Resource\Collection\FileCollectionRegistry
Definition: FileCollectionRegistry.php:25
‪TYPO3\CMS\Core\Resource\AbstractFile\getUid
‪int getUid()
Definition: AbstractFile.php:203
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectFromCombinedIdentifier
‪File ProcessedFile null getFileObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:234
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:54
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:45
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileIndexRepository
‪FileIndexRepository getFileIndexRepository()
Definition: ResourceFactory.php:521
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:38
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFolderObject
‪Folder createFolderObject(ResourceStorage $storage, $identifier, $name)
Definition: ResourceFactory.php:193
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:125
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:83
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObject
‪ResourceStorage getStorageObject($uid, array $recordData=[], &$fileIdentifier=null)
Definition: ResourceFactory.php:91
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileObject
‪File createFileObject(array $fileData, ?ResourceStorage $storage=null)
Definition: ResourceFactory.php:420
‪$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:43
‪TYPO3\CMS\Core\Utility\MathUtility
Definition: MathUtility.php:22
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObject
‪File getFileObject($uid, array $fileData=[])
Definition: ResourceFactory.php:209
‪TYPO3\CMS\Core\Resource\ResourceFactory\getDefaultStorage
‪ResourceStorage null getDefaultStorage()
Definition: ResourceFactory.php:74
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Resource\ResourceFactory\$storageRepository
‪StorageRepository $storageRepository
Definition: ResourceFactory.php:56
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:291
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceData
‪array null getFileReferenceData($uid, $raw=false)
Definition: ResourceFactory.php:490