addFileObject($this->resourceFactory->getFileObject($fileUid)); } catch (Exception $e) { $this->logger->warning( 'The file with uid "' . $fileUid . '" could not be found and won\'t be included in frontend output', ['exception' => $e] ); } } } /** * Add files to the collection from a relation. * * @param string $relationTable The table of the relation (e.g. tt_content or pages) * @param string $relationField The field which holds the files (e.g. media or images) * @param array $referenceRecord the record which is referencing the files */ public function addFilesFromRelation(string $relationTable, string $relationField, array $referenceRecord): void { $fileReferences = $this->getFileReferences($relationTable, $relationField, $referenceRecord); if (!empty($fileReferences)) { $this->addFileObjects($fileReferences); } } /** * Add files from UIDs of a reference. */ public function addFileReferences(array $fileReferenceUids = []): void { foreach ($fileReferenceUids as $fileReferenceUid) { $fileObject = $this->resourceFactory->getFileReferenceObject((int)$fileReferenceUid); $this->addFileObject($fileObject); } } /** * Add files to the collection from multiple file collections. */ public function addFilesFromFileCollections(array $fileCollectionUids = []): void { foreach ($fileCollectionUids as $fileCollectionUid) { $this->addFilesFromFileCollection((int)$fileCollectionUid); } } /** * Add files to the collection from one single file collection. */ public function addFilesFromFileCollection(int $fileCollectionUid): void { if ($fileCollectionUid <= 0) { return; } try { $fileCollection = $this->fileCollectionRepository->findByUid($fileCollectionUid); if ($fileCollection instanceof AbstractFileCollection) { $fileCollection->loadContents(); $files = $fileCollection->getItems(); $this->addFileObjects($files); } } catch (Exception $e) { $this->logger->warning( 'The file-collection with uid "' . $fileCollectionUid . '" could not be found or contents could not be loaded and won\'t be included in frontend output.', ['exception' => $e] ); } } /** * Add files to the collection from multiple folders. * * @param array $folderIdentifiers The folder identifiers * @param bool $recursive Add files recursive from given folders */ public function addFilesFromFolders(array $folderIdentifiers, bool $recursive = false): void { foreach ($folderIdentifiers as $folderIdentifier) { $this->addFilesFromFolder($folderIdentifier, $recursive); } } /** * Add files to the collection from one single folder. * * @param string $folderIdentifier The folder identifier * @param bool $recursive Add files recursive from given folders */ public function addFilesFromFolder(string $folderIdentifier, bool $recursive = false): void { if ($folderIdentifier) { try { if (str_starts_with($folderIdentifier, 't3://folder')) { // a t3://folder link to a folder in FAL $data = $this->linkService->resolveByStringRepresentation($folderIdentifier); $folder = $data['folder']; } else { $folder = $this->resourceFactory->getFolderObjectFromCombinedIdentifier($folderIdentifier); } if ($folder instanceof Folder) { $files = $folder->getFiles(0, 0, Folder::FILTER_MODE_USE_OWN_AND_STORAGE_FILTERS, $recursive); $this->addFileObjects(array_values($files)); } } catch (Exception $e) { $this->logger->warning('The folder with identifier "{folder}" could not be found and won\'t be included in frontend output', [ 'folder' => $folderIdentifier, 'exception' => $e, ]); } } } /** * Sort the file objects based on a property. * * @param string $sortingProperty The sorting property * @param 'ascending'|'descending'|'random' $sortingOrder The sorting order */ public function sort(string $sortingProperty = '', string $sortingOrder = 'ascending'): void { $sortingOrder = strtolower($sortingOrder); if ($sortingProperty !== '' && count($this->files) > 1) { $sortMultiplier = in_array($sortingOrder, ['descending', 'desc'], true) ? -1 : 1; @usort( $this->files, static function ( FileInterface $a, FileInterface $b ) use ($sortingProperty, $sortMultiplier) { if ($a->hasProperty($sortingProperty) && $b->hasProperty($sortingProperty)) { return strnatcasecmp((string)$a->getProperty($sortingProperty), (string)$b->getProperty($sortingProperty)) * $sortMultiplier; } return 0; } ); switch ($sortingOrder) { case 'random': case 'rand': shuffle($this->files); break; } } } /** * Add a file object to the collection. */ public function addFileObject(FileInterface $file): void { $this->files[] = $file; } /** * Add multiple file objects to the collection. * * @param FileInterface[] $files The file objects */ public function addFileObjects(array $files): void { $this->files = array_merge($this->files, $files); } /** * Final getter method to fetch the accumulated data. */ public function getFiles(): array { return $this->files; } public function count(): int { return count($this->files); } /** * Gets file references for a given record field, also deal with translated elements, * where file references could be attached. * * @param string $tableName Name of the table * @param string $fieldName Name of the field * @param array $element The parent element referencing to files */ protected function getFileReferences(string $tableName, string $fieldName, array $element): array { $currentId = !empty($element['uid']) ? (int)$element['uid'] : 0; // Fetch the references of the default element try { $references = $this->fileRepository->findByRelation($tableName, $fieldName, $currentId); } catch (FileDoesNotExistException $e) { /** * We just catch the exception here * Reasoning: There is nothing an editor or even admin could do */ return []; } catch (\InvalidArgumentException $e) { /** * The storage does not exist anymore * Log the exception message for admins as they maybe can restore the storage */ $this->logger->error('{exception_message}: table: {table}, field: {field}, currentId: {current_id}', [ 'table' => $tableName, 'field' => $fieldName, 'currentId' => $currentId, 'exception' => $e, ]); return []; } $localizedId = $element['_computed']['localizedUid'] ?? $element['_LOCALIZED_UID'] ?? null; if ($localizedId !== null && $this->tcaSchemaFactory->get($tableName)->isLanguageAware()) { $localizedReferences = $this->fileRepository->findByRelation($tableName, $fieldName, (int)$localizedId); $references = $localizedReferences; } return $references; } }