Image Upload mit TYPO3

In diesem Blogbeitrag möchte ich Euch zeigen wie man in einer Typo3-Extension im Frontend einen Bild-Upload realisiert. Alle File-Operationen erfolgen in Typo3 mittels FAL (File Abstraction Layer). Zuerst werden wir ein Bild hochladen, den Inhalt des Bildes überprüfen und schließlich mittels extbase in der Datenbank(Repository) abspeichern.

Erstellt und getestet wurde nachfolgender Code mit Typo3 Version 7.6.16. Nachdem die einleitende Dokumentation zu FAL gelesen wurden, ist der erste Schritt die Erstellung eines Datenbankfeldes für das Abspeichern des Bildes.

Datenbank-Tabelle (ext_tables.sql)

## Table structure of table 'tx_vaimageupload_domain_model_item'#CREATE TABLE tx_vaimageupload_domain_model_item (    ........    image int(11) unsigned NOT NULL default '0',    ........);

Im Feld „image“ wird später unser Bild gespeichert bzw. die Referenz dazu (das eigentliche Bild ist in der sys_file Tabelle).

TCA-Konfiguration

Nun erfolgt die TCA-Konfiguration der Tabelle. Dazu wird die Datei „va_imageupload/Configuration/TCA/tx_vaimageupload_domain_model_item.php“ erzeugt und nachfolgende Konfiguration eingefügt:

return [    'ctrl' => [        'title' => 'Bild Upload',        'label' => 'uid',        ........        'columns' => array(            ........            'image' => array(                'exclude' => 1,                'label' => 'Bild',                'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(                    'document', array(                        'appearance' => array(                            'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:media.addFileReference'                        ),                        'foreign_types' => array(                            '0' => array(                                'showitem' => '--palette--;;filePalette'                        ),                        \TYPO3\CMS\Core\Resource\File::FILETYPE_APPLICATION => array(                            'showitem' => '--palette--;;filePalette'                        )                    ),                    'maxitems' => 1,                    'readOnly' => true,                    'foreign_match_fields' => [                        'fieldname' => 'image',                        'tablenames' => 'tx_vaimageupload_domain_model_item',                        'table_local' => 'sys_file'                        ]                    )                )            )    )];

Model

Hier noch das dazugehörige Model:

namespace Varioous\VaImageupload\Domain\Model; /** * Item */class Item extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {     /**     * image     *      * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference     */    protected $image = NULL;     function getImage() {        return $this->image;    }     function setImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $image) {        $this->image = $image;    } }

Bild Upload und Validierung

Damit haben wir bereits die Basis für den Image-Upload erzeugt. Jetzt folgt die tatsächliche Implementierung des File Uploads. Hierfür verwenden wir die Bibliothek „image-uploader“ von DhavalKapil (Link zu Github). Vorteil ist dass diese Bibliothek gleich einiges an Sicherheit mitliefert:

  • Überprüfung der Größe des Bildes
  • Mime-Type Check
  • Überprüfung auf unerlaubte bytes
  • md5 Hash als Dateinamen
  • und noch einiges mehr

Für die Überprüfung des Bildes wird ein eigener Validator verwendet. Weitere Informationen dazu findet man hier

Ist nun die Überprüfung des Bildes erfolgreich, wird das Bild auf dem Server gespeichert und die Verbindung zwischen der Datei und unserem Model (über FileReference) hergestellt. 

//create database item$databaseItem = new \Varioous\VaImageupload\Domain\Model\Item();$this->itemRepository->add($databaseItem);$persistenceManager->persistAll();                 //upload image$image = $this->request->getArgument('image');$imageUploadFolder = $this->settings['fileAdminFolder'] . '/' . $this->settings['userUploadFolder'] . '/' . $this->settings['imageUploadFolder'] . '/';$imageUploader = new \ImageUploader();//generate unique Filename$uniqueFilename = \Varioous\VaImageupload\Utility\ImageUtility::generateUniqueFilename($databaseItem->getUid());$imageUploader->setPath($imageUploadFolder);$imageUploader->setSalt($this->settings['imageSalt']);$imageFilePath = $imageUploader->upload($image, $uniqueFilename);                 //save images$databaseItem->setImage(\Varioous\VaImageupload\Utility\ImageUtility::getFileReference($imageFilePath));$this->itemRepository->update($databaseItem);$persistenceManager->persistAll();

Hier noch die Methode getFileRefenrece:

public static function getFileReference($filename) {        $objectManager = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Extbase\Object\ObjectManager');        $configurationManager = $objectManager->get('TYPO3\\CMS\Extbase\\Configuration\\ConfigurationManager');        $settings = $configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_SETTINGS, 'VaSocial', 'TxVaSocial');        $resourceFactory = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance();        $storage = $resourceFactory->getStorageObject(intval($settings['fileadminStorage']));        $file = $storage->getFile('/' . $settings['userUploadFolder'] . '/' . $settings['imageUploadFolder'] . '/' . $filename);        $newFileReference = $objectManager->get('Varioous\\VaSocial\\Domain\\Model\\FileReference');        $newFileReference->setFile($file);        return $newFileReference;    }

Hier die Funktion zum Generieren eines eindeutigen Dateinamen

public static function generateUniqueFilename($id) {        $s = strtoupper(md5(uniqid(rand(), true)));        $guidText = substr($s, 0, 8) . '-' .                substr($s, 8, 4) . '-' .                substr($s, 12, 4) . '-' .                $id . '-' .                md5(time()) . '-' .                substr($s, 16, 4) . '-' .                substr($s, 20);        return $guidText;    }

Und damit hat man bereits einen Bildupload im Frontend mittels Typo3 erstellt. Öffnet man nun im Typo3-Backend das erstellte Objekt, erhält man folgende Ansicht:

Image Upload mit TYPO3

Wenn wir nun in der Tabelle „tx_vaimageupload_domain_model_item“ nachsehen, ist im Feld „image“ der Wert „1“ eingetragen. In der „sys_file_reference“ Tabelle ist ein neuer Eintrag, suchen wir in der Spalte „tablenames“ nach dem Tabellen namen. Hier wird also die Referenz zu der „sys_file„-Tabelle hergestellt, wo auch ein Eintrag der neuen Datei erstellt wurde. Somit weiß Typo3 welche Datei zu welchem Datensatz gehört.

Frontend Ausgabe

Die Ausgabe im Frontend erfolgt analog wie wir es bereits von Typo3 kennen. Nach der Zuweisung der Objekte im Controller, wird über folgenden Befehl im Template das Bild dargestellt.

<f:if condition="{item.image}">  <f:image src="{item.image.uid}" treatIdAsReference="true" alt="Image"/></f:if>