TYPO3: Editors with individual user_upload folders

TYPO3: Editors with individual user_upload folders

Perhaps you're familiar with this client requirement? Editors should be able to add videos using the "Add media by URL" button. But the files shouldn't be located in fileadmin/user_upload/, but rather in a custom folder? We'll show you how to do that.

We have already received this request three times from customers in the higher education sector, and I think this information could be quite useful for some of them.

Show the "Add media by URL" button for your file field

First, a few potential pitfalls if the “Add media by URL” button isn't visible to editors:

  • Make sure the editor has access to fileadmin/user_upload/ (or another storage location – e.g., 3:/user_upload/).
  • In the TCA, you should set “fileByUrlAllowed” to true (if it isn't already).
'assets' => [ 'label' => 'File', 'config' => [ 'type' => 'file', 'maxitems' => 1, 'allowed' => 'mp4, webm, youtube, vimeo, ard', 'appearance' => [ 'fileUploadAllowed' => true, 'fileByUrlAllowed' => true, ], ...

Individual user_upload folder via User TSConfig

Of course, the location of the upload folder can be set via User TSConfig in the backend user group or directly for the user (here as an example via Condition only for PID==1):

[page["uid"] == 1] options.defaultUploadFolder = 1:/page_upload/ [end]

Set individual user_upload folders for each user

However, if you have a large number of backend users on your system, you might want to set these folders automatically.

Using an EventListener, you can override the default behavior and assign each user their own folder. In this example, the backend user with the username “alexander.kellner” automatically receives the folder 1:/user__alexander_kellner/ as their default upload folder.

<?php declare(strict_types=1); namespace In2code\In2template\EventListener\Backend\Resource; use TYPO3\CMS\Core\Attribute\AsEventListener; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; use TYPO3\CMS\Core\Resource\Event\AfterDefaultUploadFolderWasResolvedEvent; use TYPO3\CMS\Core\Resource\Exception\FolderDoesNotExistException; use TYPO3\CMS\Core\Resource\ResourceFactory; /** * Add individual user_upload folder for editors like "fileadmin/user__alexander_kellner" */ #[AsEventListener( identifier: 'in2template/defaultuploadfolder', )] final readonly class DefaultUploadFolderResolver { private const int STORAGE_USERUPLOAD = 1; public const string FOLDER_PREFIX = 'user__'; public function __construct(private ResourceFactory $resourceFactory, private Context $context) { } public function __invoke(AfterDefaultUploadFolderWasResolvedEvent $event): void { $storage = $this->resourceFactory->getStorageObject(self::STORAGE_USERUPLOAD); $folderName = self::FOLDER_PREFIX . $storage->sanitizeFileName($this->getUsername()); try { $folder = $this->resourceFactory->getFolderObjectFromCombinedIdentifier( self::STORAGE_USERUPLOAD . ':/' . $folderName . '/' ); } catch (FolderDoesNotExistException) { if ($storage->hasFolder($folderName) === false) { $folder = $storage->createFolder($folderName); } else { $folder = $storage->getFolder($folderName); } } $event->setUploadFolder($folder); } /** * @return string * @SuppressWarnings(PHPMD.Superglobals) */ private function getUsername(): string { try { $username = $this->context->getPropertyFromAspect('backend.user', 'username'); } catch (AspectNotFoundException $e) { $username = $GLOBALS['BE_USER']->user['username'] ?? 'default'; } return str_replace('.', '_', $username); } }

Automatically hide folders for editors from other users

If your client wants to restrict editors to their own upload folders for data protection reasons, you can achieve this with a FAL filter.

Register this in the ext_localconf.php file of your site package:

$GLOBALS['TYPO3_CONF_VARS']['SYS']['fal']['defaultFilterCallbacks'][] = [ GeneralUtility::makeInstance(UserFolderFilter::class), 'filterUserFolders', ];

The filter file for this is:

<?php declare(strict_types=1); namespace In2code\In2template\Backend\Resource\Filter; use In2code\In2template\EventListener\Backend\Resource\DefaultUploadFolderResolver; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; /** * Filter to restrict visibility of user folders to only the current users folder for non-admins. */ final readonly class UserFolderFilter { public function __construct(private Context $context) { } public function filterUserFolders(string $itemName): int|bool { if ($this->isAdministrator() === false && $this->isUserFolder($itemName)) { if ($itemName !== DefaultUploadFolderResolver::FOLDER_PREFIX . $this->getUsername()) { return -1; } } return true; } private function isUserFolder(string $folderName): bool { return str_starts_with($folderName, DefaultUploadFolderResolver::FOLDER_PREFIX); } private function isAdministrator(): bool { return $this->context->getPropertyFromAspect('backend.user', 'isAdmin'); } /** * @SuppressWarnings(PHPMD.Superglobals) */ private function getUsername(): string { try { $username = $this->context->getPropertyFromAspect('backend.user', 'username'); } catch (AspectNotFoundException $e) { $username = $GLOBALS['BE_USER']->user['username'] ?? 'default'; } return str_replace('.', '_', $username); } }
Alexander Kellner

Alex Kellner

Alex Kellner is not only known for his many TYPO3 extensions such as powermail, femanager or lux, but also for his community work. He is also happy to give administration or development training courses or workshops.

Alexander Kellner  |  Management & COO

TYPO3: Finding unused files in fileadmin

Do you want to delete unused or orphaned files in fileadmin or another storage location? Unfortunately, there's no direct core functionality for this. But a small command in your site package can...

Go to news

TYPO3: Finding pages in mixed mode

In TYPO3, Mixed Mode refers to translated pages that contain content only partially related to the corresponding content in the main language. This is indicated in the backend by an error message. But...

Go to news

Extbase Extensions: Think extensibility with data, site and language

Today, I have a small request for the TYPO3 extension authors out there: Make sure your extensions are extensible. This will also promote the distribution of the corresponding plugins.

Go to news

SQL: Show all tables sorted by size in descending order

Lately I've been using the SQL command more often to find out which tables in the TYPO3 database are the largest. I've published the snippet once.

Go to news

TYPO3 12 with CKEditor 5: Styles in a single selection

If you set a link in the RTE in TYPO3, you may have to choose between different link classes, for example to create buttons in the frontend. What's new in TYPO3 12 is that you can select not just one...

Go to news

Null-Safe Operator in the TYPO3 area

With the introduction of PHP8, problems with undefined arrays or variables in general can arise in many places. Here are a few examples and simple solutions.

Go to news