TYPO3 6.2 - how to create FileReference in frontend (FE)?

extbase, fal, file-upload, typo3, typo3-6.2.x

Solution

You need to do several things. This issue on forge is where I got the info, and some stuff is taken out of Helmut Hummels frontend upload example (and the accompanying blogpost) which @derhansen already commented.

I'm not entirely sure if this is everything you need, so feel free to add things. This does not use a TypeConverter, which you should probably do. That would open further possibilities, for example it would be easily possible to implement deletion and replacement of file references.

You need to:

- Create a FAL file reference object from the File object. This can be done using FALs resource factory.

- Wrap it in a `\TYPO3\CMS\Extbase\Domain\Model\FileReference` (method `->setOriginalResource`)

EDIT: This step is unnecessary as of TYPO3 6.2.11 and 7.2, you can directly use the class `\TYPO3\CMS\Extbase\Domain\Model\FileReference`.

But, because the extbase model misses a field (`$uidLocal`) in 6.2.10rc1, that won't work. You need to inherit from the extbase model, add that field, and fill it. Don't forget to add a mapping in TypoScript to map your own model to `sys_file_reference`.

config.tx_extbase.persistence.classes.Zoo\Zoo\Domain\Model\FileReference.mapping.tableName = sys_file_reference

The class would look like this (taken from the forge issue):

 class FileReference extends \TYPO3\CMS\Extbase\Domain\Model\FileReference {

     /**
      * We need this property so that the Extbase persistence can properly persist the object
      *
      * @var integer
      */
      protected $uidLocal;

      /**
       * @param \TYPO3\CMS\Core\Resource\ResourceInterface $originalResource
       */
      public function setOriginalResource(\TYPO3\CMS\Core\Resource\ResourceInterface $originalResource) {
          $this->originalResource = $originalResource;
          $this->uidLocal = (int)$originalResource->getUid();
      }
  }

Add this to the TCA of the image field, in the config-section (adapt to your table and field names of course):

'foreign_match_fields' => array(
    'fieldname' => 'photo',
    'tablenames' => 'tx_zoo_domain_model_animal',
    'table_local' => 'sys_file',
),

EDIT: Use `\TYPO3\CMS\Extbase\Domain\Model\FileReference` in this step if on TYPO3 6.2.11 or 7.2 or above.

So at the end add the created `$fileRef` instead of `$fileObject`

$fileRef = GeneralUtility::makeInstance('\Zoo\Zoo\Domain\Model\FileReference');
$fileRef->setOriginalResource($fileObject);

$animal->addPhoto($fileRef);

Don't tell anyone what you have done.

Problem

I have the hypothetical `Zoo` extension in which I've `Animal` model with `photo` field and FrontEnd (FE) plugin with typical CRUD actions. `photo` field is typical FAL's `FileReference` and it works perfectly in backend (BE) with common TCA IRRE config. I'm able to successful upload the file to the storage, it's visible in the Filelist module, and I can use it in BE during my Animal editing, anyway I can't create `FileReference` within my FE plugin. My current approach looks like this: ``` /** * @param \Zoo\Zoo\Domain\Model\Animal $animal */ public function updateAction(\Zoo\Zoo\Domain\Model\Animal $animal) { // It reads proper uploaded `photo` from form's $_FILES $file = $this->getFromFILES('tx_zoo_animal', 'photo'); if ($file && is_array($file) && $file['error'] == 0) { /** @type $storageRepository \TYPO3\CMS\Core\Resource\StorageRepository */ $storageRepository = GeneralUtility::makeInstance('\TYPO3\CMS\Core\Resource\StorageRepository'); $storage = $storageRepository->findByUid(5); // TODO: make target storage configurable // This adds uploaded file to the storage perfectly $fileObject = $storage->addFile($file['tmp_name'], $storage->getRootLevelFolder(), $file['name']); // Here I stuck... below line doesn't work (throws Exception no. 1 :/) // It's 'cause $fileObject is type of FileInterface and FileReference is required $animal->addPhoto($fileObject); } $this->animalRepository->update($animal); $this->redirect('list'); } ``` anyway attempt to create reference by this line throws exception: ``` $animal->addPhoto($fileObject); ``` How can I resolve this? Checked: `DataHandler` approach (link) won't work also, as it's unavailable for FE users. TL;DR How to add `FileReference` to `Animal` model from existing (just created) FAL record?

Original source