FAL Upload im Frontend

In der Vergangenheit wurde empfohlen, auch hier auf dieser Seite, ein eigenes File Reference Model zu mappen und die File Referenz "zu Fuß" aufzubauen. Das ist theoretisch weiterhin möglich, auch wenn ich inzwischen davon abrate.

Warum???
Das ganze Mapping und die eigenen File und File Reference Models / Repositories sind eigentlich überflüssig. Viel elegenater geht das Ganze über die process datamap Funktion. Dies ist (Stand Okt 2015) auch rudimentär im TYPO3 Wiki beschrieben -> Link hier.

Doch zunächst zu den Basics:


Mit FAL (File Abstraktion Layer) gibt es für jede Datei die über das Back- oder Frontend hochgeladen wurde einen sys_file Datensatz. Dieser beinhaltet unter anderem den Dateinamen und den Speicherort (sowie Metadaten und einiges andere mehr).

Wird jetzt in einem Contentelement diese Datei - z.B. als Bildelement - eingebunden, erfolgt die Verknüpfung nicht direkt auf die Datei oder auf den sys_file Datensatzt, sondern es wird ein Realtionsdatensatz aufgebaut indem der sys_file Datensatz und der Link zum Contentelement enthalten ist - die sogenannte file_reference.

Demnach müssen wir bei einem Frontend upload folgende Schritte ausführen:

1. Datei auf den Server hochladen, ggf. Validierung des Dateityps vornehmen
2. Den sys_file Datensatz erzeugen, der Informationen über Dateinamen, Speicherort etc. enthält
3. Den sys_file Datensatz mit unserem Model Daten verküpfen, sprich die file_reference erstellen.

Doch zunächst einen Blick auf ein Beispiel Fluid Formular mit uploadfunktion:

<f:form method="post" action="saveForm" name="form" object="{form}" 
        enctype="multipart/form-data" noCacheHash="true" >

    <div class="row-image">
        Bild hochladen:
        <f:form.upload name="formimage[0]"  />
    </div>
    <f:form.submit class="btn btn-default " value="Eintrag absenden" />

</f:form>

Datei auf dem Server speichern - sys_file Model erzeugen

Die Controllerfunktion zum speichern unseres Formulars könnte dann so aussehen:

 /**
 * Adds an entry
 * @var Vendor\MyExtension\Domain\Model\User $formdata
 */
public function saveFormAction(Vendor\MyExtension\Domain\Model\User $formdata) {

    //Store your normal form stuff 
    //you don't need to do anything with your image field here!
    //Persist your new model, that we have a valid uid


    //declare the new image path in fileadmin
    //if not exists, it will automaticly added
    $newImagePath = 'my_image_folder';

    //\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($_FILES);

    //image Handling
    if ($_FILES['tx_myExtension_myPlugin']['name']['formimage'][0]) {

        //be careful - you should validate the file type! This is not included here       
        $tmpName = $_FILES['tx_myExtension_myPlugin']['name']['formimage'][0];
        $tmpFile  = $_FILES['tx_myExtension_myPlugin']['tmp_name']['formimage'][0]

        $storageRepository = $this->objectManager->get('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
        $storage = $storageRepository->findByUid('1'); //this is the fileadmin storage
        //build the new storage folder
        $targetFolder = $storage->createFolder($newImagePath);

        //file name, be shure that this is unique
        $newFileName = $tmpName;

        //build sys_file
        $movedNewFile = $storage->addFile($originalFilePath, $targetFolder, $newFileName);
        $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\PersistenceManager')->persistAll();

        //now we build the file reference
        //see private function anotiations!
        $this->buildRelations($myModel->getUid(), $movedNewFile, 'image', 'tx_myextension_domain_model_mymodel', $storagePid);
    }
}            

Die file_reference mit process_datamap Funktion erstellen

    /**
     * Build relations for FAL
     * 
     * @param int    $newStorageUid //The UID of the  model
     * @param array  $file //The file model of the image
     * @param string $field //the name of the relation field
     * @param string $table //the table of the model
     */
    private function buildRelations($newStorageUid, $file, $field, $table, $storagePid) {

        $data = array();
        $data['sys_file_reference']['NEW1234'] = array(
            'uid_local' => $file->getUid(),
            'uid_foreign' => $newStorageUid, // uid of your content record or own model
            'tablenames' => $table, //tca table name
            'fieldname' => $field, //see tca for fieldname
            'pid' => $storagePid,
            'table_local' => 'sys_file',
        );
        $data[$table][$newStorageUid] = array('image' => 'NEW1234'); //this is needed, i dont know why :( but not stored in tables

        /** @var \TYPO3\CMS\Core\DataHandling\DataHandler $tce */
        $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\CMS\Core\DataHandling\DataHandler'); // create TCE instance
        $tce->start($data, array());
        $tce->process_datamap();
    }

Weitere Artikel zu diesem Thema:

Empfehlenswerte Lektüre:

TYPO3 Extbase: Moderne Extension-Entwicklung für TYPO3

Ein nahezu perfektes Buch für TYPO3 Extensionentwickler die mit Extbase und Fluid beginnen, aber auch erfahrene Entwickler finden noch Anregungen um ihre eigene Arbeit ständig zu verbessern. Sehr ausführlich, kurzweilig, kein Lesestoff für die Couch sondern eher ein Mitmachbuch das Spaß und Unterstützung bei der eigenen Extensionentwicklung bietet.

Kommentare

keine Kommentare vorhanden


Kommentar verfassen

Die Email Adresse wird nicht veröffentlicht.