TYPO3 6.2 - 如何在前端(FE)创建文件引用(FileReference)?

7
我有一个假设的Zoo扩展程序,其中我有一个带有photo字段的Animal模型和一个带有典型CRUD操作的前端(FE)插件。 photo字段是典型的FAL的FileReference类型,在后端(BE)中与常见的TCA IRRE配置完美配合使用。
我能够成功地将文件上传到存储中,在文件列表模块中可见,并且在我的动物编辑期间可以在BE中使用它,但是我无法在我的FE插件中创建FileReference
我目前的方法看起来像这样:
/**
 * @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');
}

无论如何,试图通过这行代码创建引用都会抛出异常:

$animal->addPhoto($fileObject);

我该如何解决这个问题?

检查过了:DataHandler方法的途径(链接)也行不通,因为它对前端用户不可用。

简述

如何从已有的FAL记录中添加FileReferenceAnimal模型中?


1
你有没有查看 http://insight.helhum.io/post/85015526410/file-upload-using-extbase-and-fal-in-typo3-6-2 - 这是一种不同的方法,与你在 uploadAction 中的代码不同,它使用通用类型转换器将上传的文件(或文件)转换为对象,直接在创建 Animal 模型时使用。在前端和后端都能完美运行。 - derhansen
@derhansen 谢谢,这是在谷歌搜索时看到的第一件事,说实话,我希望有更简单的解决方案来处理这样一个...基本的问题,无论如何,我需要深入挖掘Helmut的poc。 - biesior
3个回答

13

你需要做几件事情。我从Forge上的这个问题获取了信息,还参考了Helmut Hummel的前端上传示例(以及相应的博客文章),其中@derhansen已经发表评论。

我不确定这是否是你所需的全部内容,所以随时可以添加。这里没有使用TypeConverter,你应该使用它。这将打开更多的可能性,例如轻松实现文件引用的删除和替换。

你需要:

  • 使用FAL资源工厂从文件对象创建一个FAL文件引用对象。
  • 将其包装在\TYPO3\CMS\Extbase\Domain\Model\FileReference(方法->setOriginalResource)中
  • 编辑:自TYPO3 6.2.11和7.2起,此步骤无需执行,您可以直接使用\TYPO3\CMS\Extbase\Domain\Model\FileReference类。

    但是,因为extbase模型在6.2.10rc1中缺少一个字段($uidLocal),所以那样做行不通。您需要继承自extbase模型,添加该字段并填充它。不要忘记在TypoScript中添加一个映射,将您自己的模型映射到sys_file_reference

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

这个类的样子会像这样(摘自 Forge 的问题):

 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();
      }
  }
  • 将以下内容添加到图像字段的TCA中config部分中(当然要根据您的表格和字段名称进行适当调整):

  • 'foreign_match_fields' => array(
        'fieldname' => 'photo',
        'tablenames' => 'tx_zoo_domain_model_animal',
        'table_local' => 'sys_file',
    ),
    
  • 编辑:如果使用 TYPO3 6.2.11 或 7.2 或更高版本,请在此步骤中使用\TYPO3\CMS\Extbase\Domain\Model\FileReference

    因此,在最后添加所创建的$fileRef而不是$fileObject

  • $fileRef = GeneralUtility::makeInstance('\Zoo\Zoo\Domain\Model\FileReference');
    $fileRef->setOriginalResource($fileObject);
    
    $animal->addPhoto($fileRef);
    
  • 不要告诉任何人你所做的事情。


  • 好的,我不会告诉任何人 ;) 最后我意识到过去完全错过了TypeConverters。 - biesior
    #biesior 的问题和 #Jost 的回答拯救了我的一天。我按照所有步骤操作,创建了一个新文件 FileRefence.php 在我的模型下。在删除 typo3temp 后,一切都正常工作;同时我还不得不更改我的模型中的 set 方法。非常感谢你们两位绅士 :) - Ghanshyam Gohel
    昨天它再次拯救了我的一天 ;) - biesior

    0

    这个例子可能不会赢得美丽奖,但它可能对你有所帮助。 它可以在7.6.x中正常工作。

    private function uploadLogo(){
    
       $file['name']    = $_FILES['logo']['name'];
       $file['type']    = $_FILES['logo']['type'];
       $file['tmp_name']  = $_FILES['logo']['tmp_name'];
       $file['size']    = $_FILES['logo']['size'];
    
       // Store the image
       $resourceFactory = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance();
       $storage = $resourceFactory->getDefaultStorage();
    
       $saveFolder = $storage->getFolder('logo-companies/');
       $newFile = $storage->addFile(
         $file['tmp_name'],
         $saveFolder,
         $file['name']
       );
    
       // remove earlier refereces
       $GLOBALS['TYPO3_DB']->exec_DELETEquery('sys_file_reference', 'uid_foreign = '. $this->getCurrentUserCompanyID());
    
       $addressRecord = $this->getUserCompanyAddressRecord();
    
       // Create new reference
       $data = array(
         'table_local' => 'sys_file',
         'uid_local' => $newFile->getUid(),
         'tablenames' => 'tt_address',
         'uid_foreign' => $addressRecord['uid'],
         'fieldname' => 'image',
         'pid' => $addressRecord['pid']
       );
    
       $GLOBALS['TYPO3_DB']->exec_INSERTquery('sys_file_reference', $data);
       $newId = $GLOBALS['TYPO3_DB']->sql_insert_id();
    
       $where = "tt_address.uid = ".$addressRecord['uid'];
       $GLOBALS['TYPO3_DB']->exec_UPDATEquery('tt_address', $where, array('image' => $newId ));
    }
    

    0
    这是一个完整的函数,使用FAL上传文件并创建filereference在TYPO3中。
    /**
     * Function to upload file and create file reference
     *
     * @var array $fileData
     * @var mixed $obj foreing model object
     *
     * @return void
     */
    private function uploadAndCreateFileReference($fileData, $obj) {
        $storageUid = 2;
        $resourceFactory = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance();
    
        //Adding file to storage
        $storage = $resourceFactory->getStorageObject($storageUid);
        if (!is_object($storage)) {
            $storage = $resourceFactory->getDefaultStorage();
        }
    
        $file = $storage->addFile(
              $fileData['tmp_name'],
              $storage->getRootLevelFolder(),
              $fileData['name']
        );
    
    
        //Creating file reference
        $newId = uniqid('NEW_');
        $data = [];
        $data['sys_file_reference'][$newId] = [
            'table_local' => 'sys_file',
            'uid_local' => $file->getUid(),
            'tablenames' => 'tx_imageupload_domain_model_upload', //foreign table name
            'uid_foreign' => $obj->getUid(),
            'fieldname' => 'image', //field name of foreign table
            'pid' => $obj->getPid(),
        ];
        $data['tx_imageupload_domain_model_upload'][$obj->getUid()] = [
            'image' => $newId,
        ];
    
        $dataHandler = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(
            'TYPO3\CMS\Core\DataHandling\DataHandler'
        );
        $dataHandler->start($data, []);
    }   
    

    其中 $filedata = $this->request->getArgument('file_input_field_name');

    以及

    $obj = //您正在创建文件引用的模型对象


    感谢分享!我遇到了错误 Fatal error: Call to a member function writelog() on null in /var/www/typo3_src-7.6.15/typo3/sysext/core/Classes/DataHandling/DataHandler.php on line 8138,并在 TYPO3 forge 上找到了以下问题:https://forge.typo3.org/issues/75805。难道是我的操作有误吗?为什么这个对你有效但对我无效呢? :-) - chris

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接