Project

General

Profile

Epic #103022

Updated by Torben Hansen 3 months ago

h2. Current state 

 There is currently no "official way" how extbase file upload should be performed. Since 2014, there is the TypeConverter approach, which Helmut Hummel published on GitHub and which is used by TYPO3 users and also the TYPO3 form extension. That approach for handling file uploads has however never become something the TYPO3 core did support officially (e.g. by providing a TypeConverter extension authors can use in their projects), most likely because a TypeConverter should not be responsible to handle uploaded files and other backdraws (see https://review.typo3.org/c/Packages/TYPO3.CMS/+/37898). Users using the TypeConverter approach do face the following challenges: 

 * Much code in @initialize*Action@ is required for configuration, validation and property mapping configuration 
 * Debugging can be hard 
 * Deleting existing files and extbase file relations is complicated 
 * Handling multiple file uploads is not supported and must be implemented through another TypeConverter 
 * A custom TypeConverter needs to be created manually and must often be adapted on TYPO3 major updates 
 * Custom TypeConverter created by inexperienced users may introduce security issues 

 For TYPO3 v12, it is currently not possible to use a TypeConverter for file upload due to a bug (https://forge.typo3.org/issues/102271). For TYPO3 v13, code to map file uploads to extbase arguments has been removed, making it impossible to use a TypeConverter for file upload handling. 

 h2. The idea 

 Extbase file upload handling is a process, which should have a clear API in terms of validation, file handling and object mapping. This API should support the following aspects: 

 * Handle file upload for one or multiple files 
 * Move uploaded file(s) to target folder 
 * Create new extbase file relation(s) for uploaded file(s) which an be mapped to configurable object properties 
 * Ensure, that only files passed the configured validation rules will be processed 
 * Deletions for uploaded files and removal of file relations 
 * Getter to retrieve processed uploaded files for further usage 
 * PSR-14 events for developers to customize logic (e.g. target file name) 

 The file upload validation should provide the following aspects: 

 * Validator can be used via annotation (usage uncomfortable due to too many options) or via new API (preferred) 
 * Allows to validate uploaded files by Extbase property name or uploadedFiles attribute 
 * Rules for: required, max files, file size and mime types.  
 * PHP files should be denied in general 

 The new API and validator must be covered with tests and must be well documented.  

 *Possible example usage for an Extbase action* 

 <pre> 
 public function initializeUpdateAction(): void updateAction(Data $data): ResponseInterface 
 { 
     $this->extbaseFileUpload->addConfiguration( $extbaseFileUpload = GeneralUtility::makeInstance(ExtbaseFileUpload::class); 
     $fileUploadConfiguration = (new ExtbaseFileUploadConfigurationContainer()) 
         ->add( 
             (new ExtbaseFileUploadConfiguration()) 
             
                 ->for(objectName: 'data', property: 'file') 
             
                 ->validation([ 
                 
                     'required' => true, 
                 
                     'maxFiles' => 1, 
                 
                     'fileSize' => ['min' => '100k', 'max' => '2m'], 
                 
                     'mimeTypes' => ['image/jpeg'] 
             
                 ]) 
             
                 ->moveTo('1:/user_upload/folder/', overwriteExisting: true, addRandomFilePrefix: true) 
             
                 ->createFileReference(true, removeExisting: true) 
         ); 

     if ($extbaseFileUpload->validateFileUploads($this->request, $fileUploadConfiguration)) { 
         // Processes all configurations in the file upload configuration container, moves files and  
         // creates relations to the given object 
         $extbaseFileUpload->processUploadedFiles($this->request, objectName: 'data', object: $data); 

         // Processes file deletions by evaluating HMAC signed request parameters 
         $extbaseFileUpload->processFileDeletions($this->request); 
     ); 
 } 

 public function updateAction(Data $data): ResponseInterface 
 else { 
         // Returns a ForwardResponse to the previous action including validation errors 
         return $extbaseFileUpload->getValidationFailedResponse(); 
     } 

     $this->dataRepository->update($data); 

     return $this->redirect('list'); 
 } 
 </pre> 

 Possible technical implementation (TBD) 

 * Extbase file upload API is always available in @ActionController@ 
 * Validation can maybe also be defined on property basis (e.g. @FileUploadValidator@) 
 * Move uploaded file(s) to temporary folder, if other validation errors occur 
 * Garbage collection for temporary uploaded files 
 * Property mapping through TypeConverter and/or new extbase file upload API

Back