TYPO3 v11自定义扩展(Extension Builder)前端文件上传问题
解决TYPO3前端表单文件上传关联自定义模型的问题
错误原因分析
你遇到的错误是因为Extbase属性映射机制将上传的文件名误认为是FileReference的UID。TYPO3中自定义模型的文件字段实际关联的是sys_file_reference记录,而非直接存储文件本身,前端直接用property="file"无法自动处理新上传文件的关联逻辑。
解决方案步骤
1. 修正前端表单
表单必须添加enctype="multipart/form-data"以支持文件上传,同时将上传字段的名称改为独立标识(而非直接绑定模型属性):
<f:form action="create" enctype="multipart/form-data" object="{newAnnouncements}" name="newAnnouncements"> <!-- 其他表单字段 --> <f:form.upload name="fileUpload" /> <f:form.submit value="提交" /> </f:form>
2. 调整控制器createAction逻辑
需要手动处理上传文件,创建FileReference并关联到你的Announcements模型。首先注入必要的TYPO3资源服务:
use TYPO3\CMS\Core\Resource\ResourceFactory; use TYPO3\CMS\Core\Resource\StorageRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Domain\Model\FileReference; use TYPO3\CMS\Extbase\Persistence\Generic\PersistenceManager; /** * @var ResourceFactory */ protected $resourceFactory; /** * @var StorageRepository */ protected $storageRepository; /** * @var PersistenceManager */ protected $persistenceManager; public function injectResourceFactory(ResourceFactory $resourceFactory) { $this->resourceFactory = $resourceFactory; } public function injectStorageRepository(StorageRepository $storageRepository) { $this->storageRepository = $storageRepository; } public function injectPersistenceManager(PersistenceManager $persistenceManager) { $this->persistenceManager = $persistenceManager; }
然后修改createAction处理文件上传:
public function createAction(\YourVendor\YourExtension\Domain\Model\Announcements $newAnnouncements, \Psr\Http\Message\UploadedFileInterface $fileUpload = null) { // 处理上传的有效文件 if ($fileUpload !== null && $fileUpload->getError() === UPLOAD_ERR_OK) { // 获取默认文件存储(对应fileadmin) $storage = $this->storageRepository->getDefaultStorage(); // 将文件上传到存储的默认文件夹 $uploadedFile = $storage->addFile( $fileUpload->getStream()->getMetadata('uri'), $storage->getDefaultFolder(), $fileUpload->getClientFilename(), true // 允许覆盖同名文件 ); // 创建FileReference对象并关联上传的文件 $fileReference = GeneralUtility::makeInstance(FileReference::class); $fileReference->setOriginalResource($uploadedFile); // 将FileReference绑定到Announcements模型 $newAnnouncements->setFile($fileReference); } $this->announcementsRepository->add($newAnnouncements); // 强制持久化,确保FileReference关联生效 $this->persistenceManager->persistAll(); $this->redirect('list'); }
3. 验证模型属性定义
确保Announcements模型的file属性类型正确:
/** * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference|null */ protected $file = null; /** * @param \TYPO3\CMS\Extbase\Domain\Model\FileReference $file */ public function setFile(\TYPO3\CMS\Extbase\Domain\Model\FileReference $file = null) { $this->file = $file; } /** * @return \TYPO3\CMS\Extbase\Domain\Model\FileReference|null */ public function getFile() { return $this->file; }
内容的提问来源于stack exchange,提问作者Salim Dziri IMBUS
相关产品推荐
相关产品推荐

