-
Notifications
You must be signed in to change notification settings - Fork 407
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[BACKPORT] [TASK] Backport Extbase FileUpload for v12 (#4808)
This backports PR #4808 for TYPO3 v12 and hints at the v13 changes only.
- Loading branch information
1 parent
7c8f77a
commit 288ef0d
Showing
8 changed files
with
280 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
Documentation/ExtensionArchitecture/Extbase/Reference/FileUpload.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
.. include:: /Includes.rst.txt | ||
|
||
.. index:: Extbase, FileUpload | ||
|
||
.. _extbase_fileupload: | ||
|
||
=========== | ||
File upload | ||
=========== | ||
|
||
Implementing file uploads / attachments to Extbase domain models | ||
has always been a bit of a challenge. | ||
|
||
While it is straight-forward to access an existing file reference in a domain model, | ||
writing new files to the :ref:`FAL (File Access Layer) <t3coreapi:using-fal>` | ||
takes more effort. | ||
|
||
.. _extbase_fileupload_accessing: | ||
|
||
Accessing a file reference in an Extbase domain model | ||
----------------------------------------------------- | ||
|
||
You need two components for the structural information: the Domain | ||
Model definition and the TCA entry. | ||
|
||
The domain model definition: | ||
|
||
.. literalinclude:: _FileUpload/_Blog.php | ||
:caption: EXT:my_extension/Classes/Domain/Model/Blog.php | ||
|
||
and the TCA definition: | ||
|
||
.. literalinclude:: _FileUpload/_tx_myextension_domain_model_blog.php | ||
:caption: EXT:my_extension/Configuration/TCA/tx_myextension_domain_model_blog.php | ||
|
||
Once this is set up, you can create/edit records through the TYPO3 | ||
backend (for example via :guilabel:`Web > List`), attach a single or | ||
multiple files in it. Then using a normal | ||
controller and Fluid template, you can display an image. | ||
|
||
The relevant Extbase controller part: | ||
|
||
.. literalinclude:: _FileUpload/_BlogController.php | ||
:caption: EXT:my_extension/Classes/Controller/BlogController.php | ||
|
||
and the corresponding Fluid template: | ||
|
||
.. literalinclude:: _FileUpload/_Show.html | ||
:caption: EXT:my_extension/Resources/Private/Templates/Blog/Show.html | ||
|
||
On the PHP side within controllers, you can use the usual | ||
:php:`$blogItem->getSingleFile()` and :php:`$blogItem->getMultipleFiles()` | ||
Extbase getters to retrieve the FileReference object. | ||
|
||
.. _extbase_fileupload_writing: | ||
|
||
Writing FileReference entries | ||
----------------------------- | ||
|
||
.. _extbase_fileupload_writing-manual: | ||
|
||
Manual handling | ||
............... | ||
|
||
.. versionchanged:: 13.3 | ||
With TYPO3 v13.3 | ||
:ref:`Feature: #103511 - Introduce Extbase file upload and deletion handling <changelog:feature-103511-1711894330>` | ||
was introduced and allows a simplified file upload handling. See | ||
:ref:`<t3coreapi/13:extbase_fileupload_writing-manual>` for details. | ||
|
||
With TYPO3 versions 12.4 and below, attaching files to an Extbase domain model | ||
is only possible by either: | ||
|
||
* Manually evaluate the :php:`$_FILES` data, process and validate the data, | ||
use raw QueryBuilder write actions on :sql:`sys_file` and :sql:`sys_file_reference` | ||
to persist the files quickly, or use at least some API methods: | ||
|
||
.. literalinclude:: _FileUpload/_ApiUpload.php | ||
:caption: EXT:my_extension/Classes/Controller/BlogController.php, excerpt | ||
|
||
Instead of raw access to :php:`$_FILES`, starting with TYPO3 v12 the recommendation | ||
is to utilize the :ref:`UploadedFile objects instead of $_FILES <changelog:breaking-97214>`. | ||
In that case, validators can be used for custom UploadedFile objects to specify restrictions | ||
on file types, file sizes and image dimensions. | ||
|
||
* Use (or better: adapt) a more complex implementation by using Extbase TypeConverters, | ||
as provided by `Helmut Hummel's EXT:upload_example <https://github.com/helhum/upload_example>`__. | ||
This extension is no longer maintained and will not work without larger adaptation for | ||
TYPO3 v12 compatibility. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,6 +20,7 @@ Extbase reference | |
TypoScriptConfiguration | ||
Annotations | ||
Validation | ||
FileUpload | ||
Caching | ||
Localization | ||
UriArguments |
57 changes: 57 additions & 0 deletions
57
Documentation/ExtensionArchitecture/Extbase/Reference/_FileUpload/_ApiUpload.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MyVendor\MyExtension\Controller; | ||
|
||
use MyVendor\MyExtension\Domain\Model\Blog; | ||
use MyVendor\MyExtension\Domain\Repository\BlogRepository; | ||
use TYPO3\CMS\Core\Resource\DuplicationBehavior; | ||
use TYPO3\CMS\Core\Resource\ResourceFactory; | ||
use TYPO3\CMS\Core\Utility\GeneralUtility; | ||
use TYPO3\CMS\Core\Utility\StringUtility; | ||
use TYPO3\CMS\Extbase\Domain\Model\FileReference; | ||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; | ||
|
||
class BlogController extends ActionController | ||
{ | ||
public function __construct( | ||
protected ResourceFactory $resourceFactory, | ||
protected BlogRepository $blogRepository, | ||
) {} | ||
|
||
public function attachFileUpload(Blog $blog): void | ||
{ | ||
$falIdentifier = '1:/your_storage'; | ||
$yourFile = '/path/to/uploaded/file.jpg'; | ||
|
||
// Attach the file to the wanted storage | ||
$falFolder = $this->resourceFactory->retrieveFileOrFolderObject($falIdentifier); | ||
$fileObject = $falFolder->addFile( | ||
$yourFile, | ||
basename($yourFile), | ||
DuplicationBehavior::REPLACE, | ||
); | ||
|
||
// Initialize a new storage object | ||
$newObject = [ | ||
'uid_local' => $fileObject->getUid(), | ||
'uid_foreign' => StringUtility::getUniqueId('NEW'), | ||
'uid' => StringUtility::getUniqueId('NEW'), | ||
'crop' => null, | ||
]; | ||
|
||
// Create the FileReference Object | ||
$fileReference = $this->resourceFactory->createFileReferenceObject($newObject); | ||
|
||
// Port the FileReference Object to an Extbase FileReference | ||
$fileReferenceObject = GeneralUtility::makeInstance(FileReference::class); | ||
$fileReferenceObject->setOriginalResource($fileReference); | ||
|
||
// Persist the created file reference object to our Blog model | ||
$blog->setSingleFile($fileReferenceObject); | ||
$this->blogRepository->update($blog); | ||
|
||
// Note: For multiple files, a wrapping ObjectStorage would be needed | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
Documentation/ExtensionArchitecture/Extbase/Reference/_FileUpload/_Blog.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MyVendor\MyExtension\Domain\Model; | ||
|
||
use TYPO3\CMS\Extbase\Domain\Model\FileReference; | ||
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity; | ||
use TYPO3\CMS\Extbase\Persistence\ObjectStorage; | ||
|
||
class Blog extends AbstractEntity | ||
{ | ||
// A single file | ||
protected ?FileReference $singleFile = null; | ||
|
||
/** | ||
* A collection of files. | ||
* @var ObjectStorage<FileReference> | ||
*/ | ||
protected ObjectStorage $multipleFiles; | ||
|
||
// When using ObjectStorages, it is vital to initialize these. | ||
public function __construct() | ||
{ | ||
$this->multipleFiles = new ObjectStorage(); | ||
} | ||
|
||
/** | ||
* Called again with initialize object, as fetching an entity from the DB does not use the constructor | ||
*/ | ||
public function initializeObject(): void | ||
{ | ||
$this->multipleFiles = $this->multipleFiles ?? new ObjectStorage(); | ||
} | ||
|
||
// Typical getters | ||
public function getSingleFile(): ?FileReference | ||
{ | ||
return $this->singleFile; | ||
} | ||
|
||
/** | ||
* @return ObjectStorage|FileReference[] | ||
*/ | ||
public function getMultipleFiles(): ObjectStorage | ||
{ | ||
return $this->multipleFiles; | ||
} | ||
|
||
// For later examples, the setters: | ||
public function setSingleFile(?FileReference $singleFile): void | ||
{ | ||
$this->singleFile = $singleFile; | ||
} | ||
|
||
public function setMultipleFiles(ObjectStorage $files): void | ||
{ | ||
$this->multipleFiles = $files; | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
Documentation/ExtensionArchitecture/Extbase/Reference/_FileUpload/_BlogController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace MyVendor\MyExtension\Controller; | ||
|
||
use MyVendor\MyExtension\Domain\Model\Blog; | ||
use MyVendor\MyExtension\Domain\Repository\BlogRepository; | ||
use Psr\Http\Message\ResponseInterface; | ||
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController; | ||
|
||
class BlogController extends ActionController | ||
{ | ||
public function __construct(protected readonly BlogRepository $blogRepository) | ||
{ | ||
// Note: The repository is a standard extbase repository, nothing specific | ||
// to this example. | ||
} | ||
|
||
public function showAction(Blog $blog): ResponseInterface | ||
{ | ||
$this->view->assign('blog', $blog); | ||
|
||
return $this->htmlResponse(); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
Documentation/ExtensionArchitecture/Extbase/Reference/_FileUpload/_Show.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" | ||
data-namespace-typo3-fluid="true"> | ||
|
||
<f:layout name="Default" /> | ||
|
||
<f:section name="main"> | ||
<p>Single image:</p> | ||
<f:image image="{blog.singleFile.originalFile}" /> | ||
|
||
<p>Multiple images:</p> | ||
<f:for each="{blog.multipleFiles}" as="image"> | ||
<f:image image="{image.originalFile}" /> | ||
</f:for> | ||
|
||
<p>Access first image of multiple images:</p> | ||
<f:image image="{blog.multipleFiles[0].originalFile}" /> | ||
</f:section> |
27 changes: 27 additions & 0 deletions
27
...ExtensionArchitecture/Extbase/Reference/_FileUpload/_tx_myextension_domain_model_blog.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?php | ||
|
||
return [ | ||
'ctrl' => [ | ||
// .. usual TCA fields | ||
], | ||
'columns' => [ | ||
// ... usual TCA columns | ||
'singleFile' => [ | ||
'exclude' => true, | ||
'label' => 'Single file', | ||
'config' => [ | ||
'type' => 'file', | ||
'maxitems' => 1, | ||
'allowed' => 'common-image-types', | ||
], | ||
], | ||
'multipleFiles' => [ | ||
'exclude' => true, | ||
'label' => 'Multiple files', | ||
'config' => [ | ||
'type' => 'file', | ||
'allowed' => 'common-image-types', | ||
], | ||
], | ||
], | ||
]; |