TYPO3 6.2 - 如何在前端 (FE) 创建 FileReference?
TYPO3 6.2 - how to create FileReference in frontend (FE)?
我有假设的 Zoo
扩展,其中我有 Animal
带有 photo
字段的模型和带有典型 CRUD 操作的前端 (FE) 插件。 photo
字段是典型的 FAL FileReference
并且它在具有常见 TCA IRRE 配置的后端 (BE) 中完美运行。
我能够成功上传文件到存储,它在Filelist模块中可见,我可以在我的动物编辑过程中在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
方法 (link) 也不起作用,因为它对 FE 用户不可用。
TL;DR
如何从现有(刚刚创建的)FAL 记录将 FileReference
添加到 Animal
模型?
你需要做几件事。这个 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) @derhansen 已经评论过了。
我不完全确定这是否是您需要的一切,所以请随意添加内容。这不使用您可能应该使用的 TypeConverter。这将打开更多的可能性,例如,可以很容易地实现文件引用的删除和替换。
您需要:
- 从文件对象创建一个 FAL 文件引用对象。这可以使用 FALs 资源工厂来完成。
- 将其包装在
\TYPO3\CMS\Extbase\Domain\Model\FileReference
中(方法 ->setOriginalResource
)
编辑: 从 TYPO3 6.2.11 和 7.2 开始,此步骤是不必要的,您可以直接使用 class \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
class 看起来像这样(取自伪造问题):
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,在配置部分(当然要适应您的 table 和字段名称):
'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);
不要告诉任何人你做了什么。
这是使用 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, []);
}
where $filedata =
$this->request->getArgument('file_input_field_name');
和
$obj = //Object of your model for which you are creating file
reference
这个例子不值得获奖,但它可能对你有帮助。它适用于 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 ));
}
我有假设的 Zoo
扩展,其中我有 Animal
带有 photo
字段的模型和带有典型 CRUD 操作的前端 (FE) 插件。 photo
字段是典型的 FAL FileReference
并且它在具有常见 TCA IRRE 配置的后端 (BE) 中完美运行。
我能够成功上传文件到存储,它在Filelist模块中可见,我可以在我的动物编辑过程中在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
方法 (link) 也不起作用,因为它对 FE 用户不可用。
TL;DR
如何从现有(刚刚创建的)FAL 记录将 FileReference
添加到 Animal
模型?
你需要做几件事。这个 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) @derhansen 已经评论过了。
我不完全确定这是否是您需要的一切,所以请随意添加内容。这不使用您可能应该使用的 TypeConverter。这将打开更多的可能性,例如,可以很容易地实现文件引用的删除和替换。
您需要:
- 从文件对象创建一个 FAL 文件引用对象。这可以使用 FALs 资源工厂来完成。
- 将其包装在
\TYPO3\CMS\Extbase\Domain\Model\FileReference
中(方法->setOriginalResource
) 编辑: 从 TYPO3 6.2.11 和 7.2 开始,此步骤是不必要的,您可以直接使用 class
\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
class 看起来像这样(取自伪造问题):
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,在配置部分(当然要适应您的 table 和字段名称):
'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);
不要告诉任何人你做了什么。
这是使用 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, []);
}
where $filedata = $this->request->getArgument('file_input_field_name');
和
$obj = //Object of your model for which you are creating file reference
这个例子不值得获奖,但它可能对你有帮助。它适用于 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 ));
}