‪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;
37 
42 {
46  protected ‪$collectionInstances = [];
47 
51  protected ‪$fileInstances = [];
52 
56  protected array ‪$fileReferenceInstances = [];
57 
58  public function ‪__construct(
59  protected readonly ‪StorageRepository $storageRepository,
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  }
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  {
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  [$storageId, $objectIdentifier] = array_pad(‪GeneralUtility::trimExplode(':', ‪$identifier), 2, null);
365  if (!‪MathUtility::canBeInterpretedAsInteger($storageId) && $objectIdentifier === null) {
366  return $this->storageRepository->findByUid(0);
367  }
368  return $this->storageRepository->findByUid((int)$storageId);
369  }
370 
380  {
381  [$storageId, $objectIdentifier] = array_pad(‪GeneralUtility::trimExplode(':', ‪$identifier), 2, null);
382  if (!‪MathUtility::canBeInterpretedAsInteger($storageId) && $objectIdentifier === null) {
383  $objectIdentifier = $storageId;
384  $storageId = 0;
385  }
387  $storage = $this->storageRepository->findByUid($storageId);
388  if ($storage->hasFile($objectIdentifier)) {
389  return $storage->getFile($objectIdentifier);
390  }
391  if ($storage->hasFolder($objectIdentifier)) {
392  return $storage->getFolder($objectIdentifier);
393  }
394  }
395  throw new ResourceDoesNotExistException('Object with identifier "' . ‪$identifier . '" does not exist in storage', 1329647780);
396  }
397 
404  public function ‪createFileObject(array $fileData, ResourceStorage $storage = null)
405  {
406  if (array_key_exists('storage', $fileData) && ‪MathUtility::canBeInterpretedAsInteger($fileData['storage'])) {
407  $storageObject = $this->storageRepository->findByUid((int)$fileData['storage']);
408  } elseif ($storage !== null) {
409  $storageObject = $storage;
410  $fileData['storage'] = $storage->‪getUid();
411  } else {
412  throw new \RuntimeException('A file needs to reside in a Storage', 1381570997);
413  }
414  $fileObject = GeneralUtility::makeInstance(File::class, $fileData, $storageObject);
415  return $fileObject;
416  }
417 
427  public function ‪getFileReferenceObject(int ‪$uid, array $fileReferenceData = [], bool $raw = false): FileReference
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)) {
434  throw new ResourceDoesNotExistException(
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 
450  public function ‪createFileReferenceObject(array $fileReferenceData): FileReference
451  {
452  return GeneralUtility::makeInstance(FileReference::class, $fileReferenceData);
453  }
454 
462  protected function ‪getFileReferenceData(int ‪$uid, bool $raw = false): ?array
463  {
464  $request = ‪$GLOBALS['TYPO3_REQUEST'] ?? null;
465  if (!$raw
466  && $request instanceof ServerRequestInterface
467  && ‪ApplicationType::fromRequest($request)->isBackend()
468  ) {
469  $fileReferenceData = BackendUtility::getRecordWSOL('sys_file_reference', ‪$uid);
470  } elseif (!$raw
471  && $request instanceof ServerRequestInterface
472  && ‪ApplicationType::fromRequest($request)->isFrontend()
473  ) {
474  $fileReferenceData = GeneralUtility::makeInstance(PageRepository::class)->checkRecord('sys_file_reference', ‪$uid);
475  } else {
476  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('sys_file_reference');
477  $queryBuilder->getRestrictions()->removeAll()->add(GeneralUtility::makeInstance(DeletedRestriction::class));
478  $fileReferenceData = $queryBuilder->select('*')
479  ->from('sys_file_reference')
480  ->where(
481  $queryBuilder->expr()->eq(
482  'uid',
483  $queryBuilder->createNamedParameter(‪$uid, ‪Connection::PARAM_INT)
484  )
485  )
486  ->executeQuery()
487  ->fetchAssociative();
488  }
489  return $fileReferenceData;
490  }
491 
497  protected function ‪getFileIndexRepository()
498  {
499  return GeneralUtility::makeInstance(FileIndexRepository::class);
500  }
501 }
‪TYPO3\CMS\Core\Utility\PathUtility\getCanonicalPath
‪static string getCanonicalPath(string $path)
Definition: PathUtility.php:364
‪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:122
‪TYPO3\CMS\Core\Utility\PathUtility
Definition: PathUtility.php:27
‪TYPO3\CMS\Core\Database\Connection\PARAM_INT
‪const PARAM_INT
Definition: Connection.php:52
‪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:402
‪TYPO3\CMS\Core\Resource\FileInterface
Definition: FileInterface.php:26
‪TYPO3\CMS\Core\Resource\ResourceFactory\__construct
‪__construct(protected readonly StorageRepository $storageRepository,)
Definition: ResourceFactory.php:56
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectByStorageAndIdentifier
‪File ProcessedFile null getFileObjectByStorageAndIdentifier($storage, &$fileIdentifier)
Definition: ResourceFactory.php:247
‪TYPO3\CMS\Core\Resource\ResourceFactory\getObjectFromCombinedIdentifier
‪FileInterface Folder getObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:377
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceData
‪array null getFileReferenceData(int $uid, bool $raw=false)
Definition: ResourceFactory.php:460
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObjectFromCombinedIdentifier
‪ResourceStorage getStorageObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:360
‪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:28
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFolderObjectFromCombinedIdentifier
‪Folder getFolderObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:331
‪TYPO3\CMS\Core\Resource\FileReference
Definition: FileReference.php:37
‪TYPO3\CMS\Core\Resource\Exception\FileDoesNotExistException
Definition: FileDoesNotExistException.php:21
‪TYPO3\CMS\Core\Resource\ResourceFactory\createCollectionObject
‪CollectionInterface< File > createCollectionObject(array $collectionData)
Definition: ResourceFactory.php:158
‪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:49
‪TYPO3\CMS\Core\Service\FlexFormService
Definition: FlexFormService.php:25
‪TYPO3\CMS\Core\Resource\ResourceFactory\$collectionInstances
‪array< int, CollectionInterface< File > > $collectionInstances
Definition: ResourceFactory.php:45
‪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:103
‪TYPO3\CMS\Core\Utility\PathUtility\getRelativePath
‪static getRelativePath(string $sourcePath, string $targetPath)
Definition: PathUtility.php:129
‪TYPO3\CMS\Core\Resource\Folder
Definition: Folder.php:38
‪TYPO3\CMS\Core\Resource\ResourceFactory
Definition: ResourceFactory.php:42
‪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:26
‪TYPO3\CMS\Core\Resource\Collection\FileCollectionRegistry
Definition: FileCollectionRegistry.php:25
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileObjectFromCombinedIdentifier
‪File ProcessedFile null getFileObjectFromCombinedIdentifier($identifier)
Definition: ResourceFactory.php:218
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFileReferenceObject
‪createFileReferenceObject(array $fileReferenceData)
Definition: ResourceFactory.php:448
‪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:195
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileIndexRepository
‪FileIndexRepository getFileIndexRepository()
Definition: ResourceFactory.php:495
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\Resource\ResourceFactory\createFolderObject
‪Folder createFolderObject(ResourceStorage $storage, $identifier, $name)
Definition: ResourceFactory.php:177
‪TYPO3\CMS\Core\Resource\ResourceStorage
Definition: ResourceStorage.php:129
‪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\$fileReferenceInstances
‪array $fileReferenceInstances
Definition: ResourceFactory.php:54
‪TYPO3\CMS\Core\Resource\ResourceFactory\getStorageObject
‪ResourceStorage getStorageObject($uid, array $recordData=[], &$fileIdentifier=null)
Definition: ResourceFactory.php:88
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪$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:193
‪TYPO3\CMS\Core\Resource\ResourceFactory\getDefaultStorage
‪ResourceStorage null getDefaultStorage()
Definition: ResourceFactory.php:71
‪TYPO3\CMS\Core\Resource\ResourceFactory\getFileReferenceObject
‪getFileReferenceObject(int $uid, array $fileReferenceData=[], bool $raw=false)
Definition: ResourceFactory.php:425
‪TYPO3\CMS\Core\Http\fromRequest
‪@ fromRequest
Definition: ApplicationType.php:66
‪TYPO3\CMS\Core\Domain\Repository\PageRepository
Definition: PageRepository.php:69
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Resource\ResourceFactory\retrieveFileOrFolderObject
‪File Folder null retrieveFileOrFolderObject($input)
Definition: ResourceFactory.php:275
‪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\Http\ApplicationType
‪ApplicationType
Definition: ApplicationType.php:55