fab / media-upload
Fluid widget for mass uploading files on the Frontend using HTML5 techniques powered by Fine Uploader - http://fineuploader.com/
Installs: 25 943
Dependents: 1
Suggesters: 0
Security: 0
Stars: 19
Watchers: 5
Forks: 23
Open Issues: 19
Language:JavaScript
Type:typo3-cms-extension
Requires
- typo3/cms-core: ^11.5
Replaces
- fab/media_upload: 3.0.4
- typo3-ter/media_upload: 3.0.4
README
This extension for TYPO3 CMS provides a Fluid widget for (mass) uploading media on the Frontend using HTML5 techniques.
Once selected by the User, the Media will be directly uploaded to a temporary space within typo3temp
.
After the form is posted, uploaded File can be retrieved by an UploadService
.
If the form has a "show" step before the final submission, the uploaded images can be displayed by another widget.
The file upload is handled by Fine Uploader which is a Javascript plugin aiming to bring a user-friendly file-uploading experience over the web. The plugin relies on HTML5 technology which enables Drag & Drop from the Desktop. File transfer is achieved by Ajax if supported. If not, a fall back method with classical file upload is used by posting the file. (Though, the legacy approach still need to be tested more thoroughly).
After a file has been uploaded, the user can validate and possibly remove it from the list.
Installation
The installation is completed in two steps. Install the extension as normal in the Extension Manager. Then, load the JavaScript / CSS for the pages that will contain the upload widget. The extension assumes jQuery to be loaded:
# CSS EXT:media_upload/Resources/Public/Build/media_upload.min.css # JavaScript EXT:media_upload/Resources/Public/Build/media_upload.min.js
Upload Widget
You can make use of a Media Upload widget. Syntax is as follows:
# Minimum syntax <mu:widget.upload storage="1"/> {namespace mu=Fab\MediaUpload\ViewHelpers} # With some more attributes... We assume we have a property "images" in our model # and this value could be something different like "documents" or whatever. <mu:widget.upload allowedExtensions="jpg, png" storage="1" property="images"/> # Required attributes: # -------------------- # # - storage # Default values: # --------------- # # The Storage identifier to get some automatic settings, such as allowedExtensions, default NULL. # storage = 1 # # Allowed extension to be uploaded. Override the allowed extension list from the storage. default NULL. # allowedExtensions = "jpg, png" # # Maximum size allowed by the plugin, default 0. # maximumSize = # # The unit used for computing the maximumSize, default Mo. # sizeUnit = Mo # # Maximum items to be uploaded, default 10. # maximumItems = 10 # # The property to be used for retrieving the uploaded images, default NULL. # property = foo
To see the uploaded images in a second step:
<mu:widget.showUploaded /> <mu:widget.showUploaded property="images" /> # The property to be used for retrieving the uploaded images, default NULL. # property = foo
Upload Service
Once files have been uploaded on the Frontend and are placed in a temporary directory, we have to to retrieve them and store them into their final location. This code can be used in your controller:
/** * @var \Fab\MediaUpload\Service\UploadFileService * @inject */ protected $uploadFileService; /** * @return void */ public function createAction() { /** @var array $uploadedFiles */ $uploadedFiles = $this->uploadFileService->getUploadedFiles() # A property name is needed in case specified in the Fluid Widget # <mu:widget.upload property="images"/> $uploadedFiles = $this->uploadFileService->getUploadedFiles('images') # Process uploaded files and move them into a Resource Storage (FAL) foreach($uploadedFiles as $uploadedFile) { /** @var \Fab\MediaUpload\UploadedFile $uploadedFile */ $uploadedFile->getTemporaryFileNameAndPath(); $storage = GeneralUtility::makeInstance(ResourceFactory::class)->getStorageObject(1); /** @var File $file */ $file = $storage->addFile( $uploadedFile->getTemporaryFileNameAndPath(), $storage->getRootLevelFolder(), $uploadedFile->getFileName(), \TYPO3\CMS\Core\Resource\DuplicationBehavior::RENAME ); # Note: Use method `addUploadedFile` instead of `addFile` if file is uploaded # via a regular "input" control instead of the upload widget (fine uploader plugin) # $file = $storage->addUploadedFile() $fileReference = $this->objectManager->get(\YourVendor\YourExtensionKey\Domain\Model\FileReference::class); $fileReference->setFile($file); $yourDomainObject->addImages($fileReference); } ... }
File Configuration in FAL
How to configure a field / property of type file?
SQL
CREATE TABLE tx_domain_model_foo ( images varchar(255) DEFAULT '' NOT NULL, );
TCA
$TCA['tx_domain_model_foo'] = array( 'images' => array( 'label' => 'Images', 'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig( 'images', array( 'appearance' => array( 'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:images.addFileReference' ), 'minitems' => 0, 'maxitems' => 1, ), $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] ), ), );
Model
Your domain model, should then contain the method addImages
for the purpose of $yourDomainObject->addImages($fileReference);
. See code above in the Upload Service.
/** * Images * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> */ protected $images; public function addImages(\TYPO3\CMS\Extbase\Domain\Model\FileReference $image) { $this->images->attach($image); }
File Reference Model
We must extend the FileReference for the purpose of $fileReference->setFile($file);`
. See code above in the Upload Service.
namespace YourVendor\YourExtensionKey\Domain\Model; class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference { /** * @params \TYPO3\CMS\Core\Resource\File $file */ public function setFile(\TYPO3\CMS\Core\Resource\File $file) { $this->originalFileIdentifier = (int)$file->getUid(); } }
Configuration Extbase Persistence
- ::
Finally we must configure the persistence layer of Extbase. Instead of configuration via typoscript, you now have to create the followin php file: "YourExtensionFolder"ConfigurationExtbasePersistanceClasses.php see: https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/10.0/Breaking-87623-ReplaceConfigpersistenceclassesTyposcriptConfiguration.html
<?php declare(strict_types=1); return [
- YourVendorYourExtensionKeyDomainModelFileReference::class => [
'tableName' => 'sys_file_reference', 'properties' => [
- 'originalFileIdentifier' => [
- 'fieldName' => 'uid_local',
],
],
],
];
Security
By default Media Upload require a Frontend User to be authenticated. This can be adjusted according to your needs by selecting only allowed Frontend User Group. This behaviour can be configured by TypoScript.
plugin.tx_mediaupload { settings { # "*", means every authenticated User can upload. (default) # "1,2", means every User belonging of Frontend Groups 1 and 2 are allowed. # no value, everybody can upload. No authentication is required. Caution!! allowedFrontendGroups = * } }
The TYPO3 Behavior of Restriction of allowed / denied Filetypes has changed.
Scheduler tasks
The temporary files contained within typo3temp
can be flushed from time to time.
It could be files are left aside if the user has not finalized the upload.
The Command can be used via a scheduler task with a low redundancy, once per week as instance:
# List all temporary files ./vendor/bin/typo3cms mediaupload:removeTempFiles rundry # Remove them. ./vendor/bin/typo3cms mediaupload:removeTempFiles
Building assets in development
The extension provides JS / CSS bundles which included all the necessary code. If you need to make a new build for those JS / CSS files, consider that Bower and Grunt must be installed on your system as prerequisite.
Install the required Web Components:
cd typo3conf/ext/media_upload # This will populate the directory Resources/Public/WebComponents. bower install # Install the necessary NodeJS package. npm install
Then you must build Fine Uploader from the source:
cd Resources/Private/BowerComponents/fine-uploader # Install the necessary NodeJS package inside "fine-uploader". npm install # Do the packaging works. It will create a "_dist" directory containing the build. grunt package
Finally, you can run the Grunt of the extension to generate a build:
cd typo3conf/ext/media_upload grunt build
While developing, you can use the watch
which will generate the build as you edit files:
grunt watch
Version 3.x Breacking Changes
When upgrading vom Version prior 3 to vesion 3 and cahngeing TPO3 version from 9 to 10, the configuration of the extbase persistance mapping needs to be changed from typoscript to a php class. see section: Configuration Extbase Persistence
The scheduler Tasks should now be run via TYPO3 Commandline command.
Todos for the future
replace signal Slot calls with PSR-14 middleware requests