TYPO3 6.2 - как создать FileReference во внешнем интерфейсе (FE)?

У меня есть гипотетическое расширение Zoo, в котором есть модель Animal с полем photo и плагин FrontEnd (FE) с типичными действиями CRUD. Поле photo является типичным полем FileReference FAL и отлично работает в бэкенде (BE) с общей конфигурацией TCA IRRE.

Я могу успешно загрузить файл в хранилище, он виден в модуле Filelist, и я могу использовать его в BE во время редактирования Animal, в любом случае я не могу создать 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;DR

Как добавить FileReference в Animal модель из существующей (только что созданной) записи FAL?


person biesior    schedule 24.02.2015    source источник
comment
Проверяли ли вы понимание .helhum.io/post/85015526410/ — это подход, отличный от вашего кода в uploadAction, поскольку он использует общий преобразователь типов для преобразования вашего загруженного файла (или файлов) в объект, который непосредственно используется при создании вашего Animal модель. Отлично работает как в FE, так и в BE.   -  person derhansen    schedule 25.02.2015
comment
@derhansen thx, это первое, что вы видите, когда гуглите, TBH, я надеялся, что есть более простое решение для такой ... базовой вещи, во всяком случае, как я вижу, мне нужно копнуть глубже в POC Хельмута.   -  person biesior    schedule 25.02.2015


Ответы (3)


Вам нужно сделать несколько вещей. Эта ошибка на forge — источник информации, а кое-что взято из Пример загрузки интерфейса Helmut Hummelsсопровождающий пост в блоге), который @derhansen уже прокомментировал.

Я не совсем уверен, что это все, что вам нужно, поэтому не стесняйтесь добавлять вещи. Это не использует TypeConverter, что вы, вероятно, должны сделать. Это открыло бы дополнительные возможности, например, можно было бы легко реализовать удаление и замену ссылок на файлы.

Тебе нужно:

  • Создайте объект ссылки на файл FAL из объекта File. Это можно сделать с помощью фабрики ресурсов FAL.
  • Заверните его в \TYPO3\CMS\Extbase\Domain\Model\FileReference (метод ->setOriginalResource)
  • EDIT: Этот шаг не нужен, начиная с TYPO3 6.2.11 и 7.2, вы можете напрямую использовать класс \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
    

    Класс будет выглядеть так (взято из выпуска кузницы):

     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',
    ),
    
  • EDIT: используйте \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);
    
  • Не рассказывай никому о том, что ты сделал.

person Jost    schedule 25.02.2015
comment
Йост, хорошо, я никому не скажу ;) Наконец я понял, что полностью скучал по TypeConverters в прошлом. - person biesior; 25.02.2015
comment
#biesior ваш вопрос и #Jost ваш ответ, спасите мой день. Я выполнил все шаги, создаю новый файл FileRefence.php под моей моделью. Все работает после удаления typo3temp ;) также мне нужно изменить метод set в модели. Спасибо вам обоим, джентльмены :) - person Ghanshyam Gohel; 21.11.2015
comment
На самом деле это снова спасло мой день вчера;) - person biesior; 22.11.2015

Вот полная функция для загрузки файла в TYPO3 с использованием FAL и создания ссылки на файл.

/**
 * 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 = //Объект вашей модели, для которого вы создаете ссылку на файл

person Mihir Bhatt    schedule 19.01.2017
comment
Спасибо, что поделился! Я получаю сообщение об ошибке 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.typo3.org/issues/75805. Я делаю что-то не так, или почему это работает для вас, а не для меня? :-) - person chris; 29.01.2017

Этот пример не заслуживает награды за красоту, но он может вам помочь. Работает в 7.6.х

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 ));
}
person mipmip    schedule 06.03.2018