‪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 
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 
184  public function ‪createFolderObject(ResourceStorage $storage, ‪$identifier, $name)
185  {
186  return GeneralUtility::makeInstance(Folder::class, $storage, ‪$identifier, $name);
187  }
188 
200  public function ‪getFileObject(‪$uid, array $fileData = [])
201  {
202  if (!is_numeric(‪$uid)) {
203  throw new \InvalidArgumentException('The UID of file has to be numeric. UID given: "' . ‪$uid . '"', 1300096564);
204  }
205  if (empty($this->fileInstances[‪$uid])) {
206  // Fetches data in case $fileData is empty
207  if (empty($fileData)) {
208  $fileData = $this->‪getFileIndexRepository()->‪findOneByUid($uid);
209  if ($fileData === false) {
210  throw new FileDoesNotExistException('No file found for given UID: ' . ‪$uid, 1317178604);
211  }
212  }
213  $this->fileInstances[‪$uid] = $this->‪createFileObject($fileData);
214  }
215  return $this->fileInstances[‪$uid];
216  }
217 
226  {
227  if (!is_string(‪$identifier) || ‪$identifier === '') {
228  throw new \InvalidArgumentException('Invalid file identifier given. It must be of type string and not empty. "' . gettype(‪$identifier) . '" given.', 1401732564);
229  }
231  if (count($parts) === 2) {
232  $storageUid = (int)$parts[0];
233  $fileIdentifier = $parts[1];
234  } else {
235  // We only got a path: Go into backwards compatibility mode and
236  // use virtual Storage (uid=0)
237  $storageUid = 0;
238  $fileIdentifier = $parts[0];
239  }
240  return $this->storageRepository->getStorageObject($storageUid, [], $fileIdentifier)
241  ->getFileByIdentifier($fileIdentifier);
242  }
243 
254  public function ‪getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
255  {
256  if (!($storage instanceof ResourceStorage)) {
257  $storage = $this->storageRepository->getStorageObject($storage, [], $fileIdentifier);
258  }
259  return $storage->getFileByIdentifier($fileIdentifier);
260  }
261 
282  public function ‪retrieveFileOrFolderObject($input)
283  {
284  // Remove Environment::getPublicPath() because absolute paths under Windows systems contain ':'
285  // This is done in all considered sub functions anyway
286  $input = str_replace(‪Environment::getPublicPath() . '/', '', (string)$input);
287 
288  if (str_starts_with($input, 'file:')) {
289  $input = substr($input, 5);
290  return $this->‪retrieveFileOrFolderObject($input);
291  }
293  return $this->‪getFileObject((int)$input);
294  }
295  if (strpos($input, ':') > 0) {
296  [$prefix] = explode(':', $input);
298  // path or folder in a valid storageUID
299  return $this->‪getObjectFromCombinedIdentifier($input);
300  }
301  if ($prefix === 'EXT') {
302  $absoluteFilePath = GeneralUtility::getFileAbsFileName($input);
303  if (empty($absoluteFilePath)) {
304  return null;
305  }
306  if (str_starts_with($absoluteFilePath, ‪Environment::getPublicPath())) {
307  $relativePath = ‪PathUtility::getRelativePath(‪Environment::getPublicPath() . '/', ‪PathUtility::dirname($absoluteFilePath)) . ‪PathUtility::basename($absoluteFilePath);
308  } else {
309  try {
310  $relativePath = ‪PathUtility::getPublicResourceWebPath($input);
311  } catch (\Throwable $e) {
312  throw new ResourceDoesNotExistException(sprintf('Tried to access a private resource file "%s" from fallback compatibility storage. This storage only handles public files.', $input), 1633777536);
313  }
314  }
315 
316  return $this->‪getFileObjectFromCombinedIdentifier($relativePath);
317  }
318  return null;
319  }
320  // this is a backwards-compatible way to access "0-storage" files or folders
321  // eliminate double slashes, /./ and /../
322  $input = ‪PathUtility::getCanonicalPath(ltrim($input, '/'));
323  if (@is_file(‪Environment::getPublicPath() . '/' . $input)) {
324  // only the local file
325  return $this->‪getFileObjectFromCombinedIdentifier($input);
326  }
327  // only the local path
328  return $this->‪getFolderObjectFromCombinedIdentifier($input);
329  }
330 
339  {
341  if (count($parts) === 2) {
342  $storageUid = (int)$parts[0];
343  $folderIdentifier = $parts[1];
344  } else {
345  // We only got a path: Go into backwards compatibility mode and
346  // use virtual Storage (uid=0)
347  $storageUid = 0;
348 
349  // please note that getStorageObject() might modify $folderIdentifier when
350  // auto-detecting the best-matching storage to use
351  $folderIdentifier = $parts[0];
352  // make sure to not use an absolute path, and remove Environment::getPublicPath if it is prepended
353  if (str_starts_with($folderIdentifier, ‪Environment::getPublicPath() . '/')) {
354  $folderIdentifier = ‪PathUtility::stripPathSitePrefix($parts[0]);
355  }
356  }
357  return $this->storageRepository->getStorageObject($storageUid, [], $folderIdentifier)->getFolder($folderIdentifier);
358  }
359 
368  {
370  $storageUid = count($parts) === 2 ? $parts[0] : null;
371  return $this->storageRepository->findByUid($storageUid);
372  }
373 
383  {
384  [$storageId, $objectIdentifier] = ‪GeneralUtility::trimExplode(':', ‪$identifier);
385  $storage = $this->storageRepository->findByUid($storageId);
386  if ($storage->hasFile($objectIdentifier)) {
387  return $storage->getFile($objectIdentifier);
388  }
389  if ($storage->hasFolder($objectIdentifier)) {
390  return $storage->getFolder($objectIdentifier);
391  }
392  throw new ResourceDoesNotExistException('Object with identifier "' . ‪$identifier . '" does not exist in storage', 1329647780);
393  }
394 
401  public function ‪createFileObject(array $fileData, ResourceStorage $storage = null)
402  {
403  if (array_key_exists('storage', $fileData) && ‪MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
404  $storageObject = $this->storageRepository->findByUid((int)$fileData['storage']);
405  } elseif ($storage !== null) {
406  $storageObject = $storage;
407  $fileData['storage'] = $storage->‪getUid();
408  } else {
409  throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
410  }
411  $fileObject = GeneralUtility::makeInstance(File::class, $fileData, $storageObject);
412  return $fileObject;
413  }
414 
426  public function ‪getFileReferenceObject(‪$uid, array $fileReferenceData = [], $raw = false)
427  {
428  if (!is_numeric(‪$uid)) {
429  throw new \InvalidArgumentException(
430  'The reference UID for the file (sys_file_reference) has to be numeric. UID given: "' . ‪$uid . '"',
431  1300086584
432  );
433  }
434  if (!($this->fileReferenceInstances[‪$uid] ?? false)) {
435  // Fetches data in case $fileData is empty
436  if (empty($fileReferenceData)) {
437  $fileReferenceData = $this->‪getFileReferenceData($uid, $raw);
438  if (!is_array($fileReferenceData)) {
439  throw new ResourceDoesNotExistException(
440  'No file reference (sys_file_reference) was found for given UID: "' . ‪$uid . '"',
441  1317178794
442  );
443  }
444  }
445  $this->fileReferenceInstances[‪$uid] = $this->‪createFileReferenceObject($fileReferenceData);
446  }
447  return $this->fileReferenceInstances[‪$uid];
448  }
449 
457  public function ‪createFileReferenceObject(array $fileReferenceData)
458  {
459  $fileReferenceObject = GeneralUtility::makeInstance(FileReference::class, $fileReferenceData);
460  return $fileReferenceObject;
461  }
462 
470  protected function ‪getFileReferenceData(‪$uid, $raw = false)
471  {
472  if (!$raw
473  && (‪$GLOBALS['TYPO3_REQUEST'] ?? null) instanceof ServerRequestInterface
474  && ‪ApplicationType::fromRequest(‪$GLOBALS['TYPO3_REQUEST'])->isBackend()
475  ) {
476  $fileReferenceData = BackendUtility::getRecordWSOL('sys_file_reference', ‪$uid);
477  } elseif (!$raw && is_object(‪$GLOBALS['TSFE'] ?? false)) {
478  $fileReferenceData = ‪$GLOBALS['TSFE']->sys_page->checkRecord('sys_file_reference', ‪$uid);
479  } else {
480  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
481  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
482  $fileReferenceData = $queryBuilder->select('*')
483  ->from('sys_file_reference')
484  ->where(
485  $queryBuilder->expr()->eq(
486  'uid',
487  $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)
488  )
489  )
490  ->executeQuery()
491  ->fetchAssociative();
492  }
493  return $fileReferenceData;
494  }
495 
501  protected function ‪getFileIndexRepository()
502  {
503  return GeneralUtility::makeInstance(FileIndexRepository::class);
504  }
505 }
‪TYPO3\CMS\Core\Utility\GeneralUtility\trimExplode
‪static list< string > trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
Definition: GeneralUtility.php:916
‪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:453
‪TYPO3\CMS\Core\Utility\PathUtility\stripPathSitePrefix
‪static stripPathSitePrefix(string $path)
Definition: PathUtility.php:428
‪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:27
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:47
‪TYPO3\CMS\Core\Resource\Collection\AbstractFileCollection
Definition: AbstractFileCollection.php:28
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileObject
‪File createFileObject(array $fileData, ResourceStorage $storage=null)
Definition: ResourceFactory.php:397
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:22
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectByStorageAndIdentifier
‪File ProcessedFile null getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
Definition: ResourceFactory.php:250
‪TYPO3\CMS\Core\Resource\ResourceFactory\getObjectFromCombinedIdentifier
‪FileInterface Folder getObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:378
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObjectFromCombinedIdentifier
‪ResourceStorage getStorageObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:363
‪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\ResourceFactory\getFolderObjectFromCombinedIdentifier
‪Folder getFolderObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:334
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:33
‪TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
Definition: FileDoesNotExistException.php:22
‪TYPO3\CMS\Core\Resource\ResourceFactory\createCollectionObject
‪CollectionInterface< File > createCollectionObject(array $collectionData)
Definition: ResourceFactory.php:161
‪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\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\Resource\ResourceFactory\__construct
‪__construct(StorageRepository $storageRepository)
Definition: ResourceFactory.php:58
‪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:106
‪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:24
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceObject
‪FileReference getFileReferenceObject($uid, array $fileReferenceData=[], $raw=false)
Definition: ResourceFactory.php:422
‪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:221
‪TYPO3\CMS\Core\Resource
Definition: generateMimeTypes.php:52
‪TYPO3\CMS\Core\Resource\ProcessedFile
Definition: ProcessedFile.php:45
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileIndexRepository
‪FileIndexRepository getFileIndexRepository()
Definition: ResourceFactory.php:497
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:36
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFolderObject
‪Folder createFolderObject(ResourceStorage $storage, $identifier, $name)
Definition: ResourceFactory.php:180
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:127
‪TYPO3\CMS\Core\Resource\Index\FileIndexRepository\findOneByUid
‪array false findOneByUid($fileUid)
Definition: FileIndexRepository.php:71
‪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:91
‪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:196
‪TYPO3\CMS\Core\Resource\ResourceFactory\getDefaultStorage
‪ResourceStorage null getDefaultStorage()
Definition: ResourceFactory.php:74
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:67
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:51
‪TYPO3\CMS\Core\Resource\ResourceFactory\$storageRepository
‪StorageRepository $storageRepository
Definition: ResourceFactory.php:56
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:51
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:278
‪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:466