Dateien und Bilder mit Extbase 6.1 upload/download via FAL (File Abstraction Layer)

FAL File Abstraktion Layer mit Extbase 6.1, Datei upload

FAL File Abstraktion Layer das mit Extbase 6.1 viel Neues erfahren hat, möchte ich hier kurz erläutern.

Das Beispiel ist ein File Upload, vom Frontend ins Backend.
Dabei geht es um einen Datensatz mit einem Attribut 'Datei':

'file' => array(
      'exclude' => 0,
      'label' => 'file',
        'config' => array(
        'maxitems' => 999,
        'type' => 'inline',
        'foreign_table' => 'sys_file_reference',
        'foreign_field' => 'uid_foreign',
        'foreign_sortby' => 'sorting_foreign',
        'foreign_table_field' => 'tablenames',
        'foreign_match_fields' => array(
          'fieldname' => 'file'
        ),
        'foreign_label' => 'uid_local',
        'foreign_selector' => 'uid_local',
        'foreign_selector_fieldTcaOverride' => array(
          'config' => array(
            'appearance' => array(
              'elementBrowserType' => 'file',
              'elementBrowserAllowed' => 'doc,pdf'
            )
          )
        ),
        'filter' => array(
          array(
            'userFunc' => 'TYPO3\\CMS\\Core\\Resource\\Filter\\FileExtensionFilter->filterInlineChildren',
            'parameters' => array(
              'allowedFileExtensions' => 'doc,pdf',
              'disallowedFileExtensions' => ''
            )
          )
        ),
        'appearance' => array(
          'createNewRelationLinkTitle' => 'LLL:EXT:cms/locallang_ttc.xlf:media.addFileReference',
          'useSortable' => TRUE,
          'collapseAll' => 1,
          'expandSingle' => 1,
          'headerThumbnail' => array(
            'field' => 'uid_local',
            'width' => '64',
            'height' => '64',
          ),
          'showPossibleLocalizationRecords' => TRUE,
          'showRemovedLocalizationRecords' => TRUE,
          'showSynchronizationLink' => TRUE,
          'enabledControls' => array(
            'info' => TRUE,
            'new' => TRUE,
            'dragdrop' => TRUE,
            'sort' => TRUE,
            'hide' => TRUE,
            'delete' => TRUE,
            'localize' => TRUE,
          ),
        ),
        'behaviour' => array(
          'localizationMode' => 'select',
          'localizeChildrenAtParentLocalization' => TRUE,
        ),
      ),
    ),   
Ins TCA, entweder via BE im"Installation", in der Extension im ext_tables oder in der eigenen TCA Datei:
/**
 * file
 *
 * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference>
 */
protected $file;  


  /**
 * Returns the file
 *
 * @return \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $file
 */
public function getFile() {
  return $this->file;
}

/**
 * Sets the file
 *
 * @param \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\Domain\Model\FileReference> $file
 * @return void
 */
public function setFile($file) {
  $this->file = $file;
}
...im Model der MVC Struktur, die Getter und Setter.
/**
 * initialize create action
 * allow creation of submodel company
 */
public function initializeAction() {
    if ($this->arguments->hasArgument('newFALExample')) {
        $this->arguments->getArgument('newFALExample')->getPropertyMappingConfiguration()->setTargetTypeForSubProperty('file', 'array');
        $this->arguments->getArgument('newFALExample')->getPropertyMappingConfiguration()->allowCreationForSubProperty('file');               
    }
}       
im Cotroller bei mir noch notwendig:
$this->darlehenRepository->add($newObjekt);

// Datesatz speichern persistent machen um die uid zu bekommen
$persistenceManager = $this->objectManager->get('Tx_Extbase_Persistence_Manager');
$persistenceManager->persistAll();

$UserDates = $newObjekt->getUserDates();
$datarecordUid = $UserDates->getUid();

foreach ($_FILES['tx_fileen_listview']['name'] as $filetype=> $value) {  

 if($value=="" || $value==" "){die;}

  ///////////////////////////////////// file UPLOAD START///////////////////////////////////////

 $name = $_FILES['tx_fileen_listview']['name'][$filetype];
 $tmp_name = $_FILES['tx_fileen_listview']['tmp_name'][$filetype];

 // file uploaden                          
 $storageRepository = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\StorageRepository');
 $storage = $storageRepository->findByUid(4);
 $fileObject = $storage->addFile($tmp_name, $storage->getRootLevelFolder(), $name);

 // bestücke Variabeln
 $filename = $fileObject->getIdentifier(); // filenamen auslesen        
 $tablename = 'fe_users';
 $fieldname = 'file';
 $pages_uid = '13'; // Frontendseite wo das Objekt erstellt wird

 // erzeuge filereferenz
 $data = array();
 $data['sys_file_reference'][$filename] = array(
     'uid_local' => $fileObject->getUid(),
     'uid_foreign' => $datarecordUid, // uid Inhaltselement oder Datensatz
     'tablenames' => $tablename,
     'fieldname' => $fieldname,
     'pid' => $pages_uid, // Frontendseite wo die Aktion ausgeführt wird
     'table_local' => 'sys_file',
 );
 $data[$tablename][962532] = array($fieldname => $filename); // set to the number of images?

 $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('t3lib_TCEmain');
 $tce->start($data, array(), $new_BE_USER);           
 $tce->process_datamap();
}
 ///////////////////////////////////// file UPLOAD ENDE///////////////////////////////////////
und nun im Controller
<f:form.upload property="file"  /> 
und zum Schluss das HTML Formularfeld für das Template oder Partials