Nachfolgend ein aktualisiertes Beispiel zum älteren Post "Extbase - FAL FileReference im Controller erzeugen" zum Erzeugen einer FAL FileReference und Hinzufügen der neuen FileReference zum Extbase Model. Dieses Beispiel basiert ebenfalls auf einer erweiterten Klasse "FileReference", welche in TYPO3 9 LTS für dieses Szenario leider immer noch erforderlich ist (aber vielleicht kommt das ja bald in den Core: https://forge.typo3.org/issues/88833).

In diesem Beispiel sind drei mögliche Varianten aufgeführt (Abschnitt "Extbase Controller"), wie vor der Erstellung der eigentlichen FileReference das Objekt "File" mit den Mitteln der TYPO3 Core API erzeugt werden kann.

Besonders wichtig ist, dass die TCA Konfiguration den "foreign_match_fields" Schlüssel enthält und dieser richtig definiert ist. Ebenso muss das Mapping der erweiterten FileReference via TypoScript gesetzt werden. Falsche Konfigurationen an dieser Stelle resultieren häufig in korrupten Einträgen in "sys_file_reference" (Spalten "tablenames" und "filedname" sind dann leer).

Extbase Model (FileReference)

<?php

namespace Vendor\Ext\Domain\Model;

/***************************************************************
 *  Copyright notice
 *
 *  (c) 2014 Helmut Hummel
 *
 *  All rights reserved
 *
 *  This script is part of the TYPO3 project. The TYPO3 project is
 *  free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  The GNU General Public License can be found at
 *  http://www.gnu.org/copyleft/gpl.html.
 *
 *  This script is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/

/**
 * Class FileReference
 */
class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference {

    /**
     * uid of a sys_file
     *
     * @var integer
     */
    protected $originalFileIdentifier;

    /**
     * setOriginalResource
     *
     * @param \TYPO3\CMS\Core\Resource\FileReference $originalResource
     * @return void
     */
    public function setOriginalResource(\TYPO3\CMS\Core\Resource\FileReference $originalResource) {
        $this->originalResource = $originalResource;
        $this->originalFileIdentifier = (int)$originalResource->getOriginalFile()->getUid();
    }

    /**
     * setFile
     *
     * @param \TYPO3\CMS\Core\Resource\File $falFile
     * @return void
     */
    public function setFile(\TYPO3\CMS\Core\Resource\File $falFile) {
        $this->originalFileIdentifier = (int)$falFile->getUid();
    }

}

Extbase Model (Person)

<?php

namespace Vendor\Ext\Domain\Model;

/**
 * Class Person
 */
class Person extends \TYPO3\CMS\Extbase\DomainObject\AbstractEntity {

    /**
     * image
     *
     * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference
     */
    protected $image = NULL;

    /**
     * Returns the image
     *
     * @return \TYPO3\CMS\Extbase\Domain\Model\FileReference $image
     */
    public function getImage() {
        return $this->image;
    }

    /**
     * Sets the image
     *
     * @param \TYPO3\CMS\Extbase\Domain\Model\FileReference $image
     * @return void
     */
    public function setImage(\TYPO3\CMS\Extbase\Domain\Model\FileReference $image) {
        $this->image = $image;
    }

}

Extbase Controller

<?php

namespace Vendor\Ext\Domain\Model;

/**
 * Class PersonController
 */
class PersonController  extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

   /**
    * personRepository
    *
    * @var \Vendor\Ext\Domain\Repository\PersonRepository
    * @inject
    */
    protected $personRepository;

    /**
     * Action addImage
     *
     * @param \Vendor\Ext\Domain\Model\Person $person
     * @return void
     */
    public function AddImageAction(\Vendor\Ext\Domain\Model\Person $person) {

        // A) File Objekt für bereits im Storage befindliche Datei erstellen (der Storage kennt sie aber noch nicht und sie soll da bleiben wo ist schon ist):
        $file = ResourceFactory::getInstance()->retrieveFileOrFolderObject('path_to_file');

        // B) File Objekt für (irgendwo) vorhandene Datei erstellen, die dabei in den Storage kopiert wird:
        $storage = ResourceFactory::getInstance()->getDefaultStorage();
        $file = $storage->getFolder('folder_name')->addFile('path_to_file');

        // C) File Objekt erstellen mit einer leeren Datei (also kein copy usw.), die später mit setContents() gefüllt wird:
        $storage = ResourceFactory::getInstance()->getDefaultStorage();
        $file = $storage->getFolder('folder_name')->createFile('path_to_file', $folder);

        // Und dann für alle 3 Varianten gleich, die Erzeugung der eigentlichen Dateireferenz:
        $fileReference = $this->objectManager->get(\Vendor\Ext\Domain\Model\FileReference::class);
        $fileReference->setFile($file);  

        // Hinzufügen der neuen FileReference zum Model
        $person->setImage($fileReference);

        $this->personRepository->update($person);

    }

}

TCA Konfiguration (Person)

'image' => [
    'exclude' => 1,
    'label' => 'LLL:EXT:ext/Resources/Private/Language/locallang_db.xlf:tx_ext_domain_model_person.image',
    'config' => \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::getFileFieldTCAConfig(
        'image',
        [
            'minitems' => 0,
            'maxitems' => 1,
            'foreign_match_fields' => [
                'fieldname' => 'image',
                'tablenames' => 'tx_ext_domain_model_person',
                'table_local' => 'sys_file',
            ],
        ],
        $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']
    ),
],

TypoScript Konfiguration (Mapping der FileReference)

config.tx_extbase {
    persistence {
        classes {
            Vendor\Ext\Domain\Model\FileReference {
                mapping {
                        tableName = sys_file_reference
                    columns {
                        uid_local.mapOnProperty = originalFileIdentifier
                    }
                }
            }
        }
        objects {
            TYPO3\CMS\Extbase\Domain\Model\FileReference.className = Vendor\Ext\Domain\Model\FileReference
        }
        updateReferenceIndex = 1
    }
}




Kommentare

Wolle schrieb am 02.04.2020:
Danke für die Anleitung, die mir sehr weitergeholfen hat.

Zwei Hinweise:

1. Anstelle von:
$fileReference = $objectManager->get(\Vendor\Ext\Domain\Model\FileReference::class);
muss es bei mir heissen:
$fileReference = $this->objectManager->get(\Vendor\Ext\Domain\Model\FileReference::class);

2. Aus der FileReference.php musste ich Funktion setOriginalResource löschen, da ich sonst die folgende Fehlermeldung bekomme:
(1/1) #1476107295 TYPO3\CMS\Core\Error\Exception
PHP Warning: Declaration of Vendor\Ext\Domain\Model\FileReference::setOriginalResource(TYPO3\CMS\Core\Resource\FileReference $originalResource) should be compatible with TYPO3\CMS\Extbase\Domain\Model\FileReference::setOriginalResource(TYPO3\CMS\Core\Resource\ResourceInterface $originalResource) in /home/vhosts/myserver.de/typo3conf/ext/Ext/Classes/Domain/Model/FileReference.php line 62

Sven Burkert schrieb am 11.07.2021:
Danke für den hilfreichen Artikel, der mich in die richtige Richtung geleitet hat.
Allerdings funktioniert es so in TYPO3 10 nicht mehr, dort habe ich mir die Lösung von EXT:news abgeschaut.

Andy Wesely schrieb am 07.09.2021:
Danke für die Anleitung!

Ich ergänze es mal für TYPO3 10, da mir keine sauberere Lösung bekannt ist.

Mit dem Wegfall der TypoScript-Extbase-Konfiguration für das Mapping, muss die Datei Configuration/Extbase/Persistence/Classes.php mit folgendem Inhalt angelegt werden.
Dann funktioniert das Beispiel auch unter 10:

return [
\TYPO3\CMS\Extbase\Domain\Model\FileReference::class => [
'subclasses' => [
\Vendor\Ext\Domain\Model\FileReference::class
]
],
\Vendor\Ext\Domain\Model\FileReference::class => [
'tableName' => 'sys_file_reference',
'properties' => [
'originalFileIdentifier' => [
'fieldName' => 'uid_local'
]
]
]
];

Zu 2. von Wolle: Hier muss in TYPO3 10 die Methoden-Signatur der erweiterten Klasse entsprechen, also:
public function setOriginalResource(\TYPO3\CMS\Core\Resource\ResourceInterface $originalResource)


Nico schrieb am 20.11.2022:
Hi,
Danke dafür. Ich nutze das Script schon seit einigen Jahren, allerdings in TYPO3 11 aktualisiert sich einfach der ReferenceIndex nicht mehr. Hat hier jemand ggf. eine Lösung?

Ich habe es in der Classes.php wie folgt versucht aber die verknüpften Bilder zeigen in der Dateiliste nach wie vor "-" statt die Anzahl der Verknüpfungen.

'tableName' => 'sys_file_reference',
'updateReferenceIndex'=>1,
'properties' => [
'originalFileIdentifier' => [
'fieldName' => 'uid_local'
]
]