7

我有一个假设的Zoo扩展,其中我使用具有典型 CRUD 操作Animal的字段和前端 (FE) 插件进行建模。字段是典型的 FAL ,它在具有通用 TCA IRRE 配置的后端 (BE) 中完美运行。photophotoFileReference

我能够成功地将文件上传到存储中,它在Filelist模块中可见,并且我可以在动物编辑期间在 BE 中使用它,无论如何我无法FileReference在我的 FE 插件中创建。

我目前的方法如下所示:

/**
 * @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方法(链接)也不起作用,因为它对 FE 用户不可用。

TL;博士

如何从现有(刚刚创建的)FAL 记录添加FileReference到模型?Animal

4

3 回答 3

13

你需要做几件事。Forge 上的这个问题是我获得信息的地方,其中一些内容取自@derhansen 已经评论过的Helmut Hummels 前端上传示例(以及随附的博文)。

我不完全确定这是否是您需要的一切,所以请随意添加。这不使用 TypeConverter,您可能应该这样做。这将开辟更多的可能性,例如,很容易实现文件引用的删除和替换。

你需要:

  • 从 File 对象创建一个 FAL 文件引用对象。这可以使用 FAL 资源工厂来完成。
  • 将其包装在\TYPO3\CMS\Extbase\Domain\Model\FileReference(method ->setOriginalResource)中
  • 编辑:从 TYPO3 6.2.11 和 7.2 开始,此步骤是不必要的,您可以直接使用 class \TYPO3\CMS\Extbase\Domain\Model\FileReference

    但是,因为 extbase 模型$uidLocal在 6.2.10rc1 中缺少一个字段 ( ),所以这不起作用。您需要从 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 中(当然要适应您的表和字段名称):

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

    所以最后添加创建的$fileRef而不是$fileObject

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

于 2015-02-25T09:19:58.127 回答
0

这是使用 FAL 在 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 = //您正在为其创建文件引用的模型的对象

于 2017-01-19T07:14:16.520 回答
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 ));
}
于 2018-03-06T11:44:31.120 回答