TYPO3前端环境下FAL资源引用与属性值的上传及更新问题
TYPO3 FAL文件引用更新问题:存在则更新元属性,不存在则新建
当前处理TYPO3包含FAL图片的记录更新时,新增文件能正常生成FileReference,但更新操作会创建新的引用而非修改现有对象,需要实现存在FileReference则更新其元属性,不存在则新建的逻辑。
现有更新操作代码
$obj = $this->mediaAlbumRepository->findByUid(GeneralUtility::_GP('album')); $obj->setTitle(GeneralUtility::_GP('title')); $obj->setDescription(GeneralUtility::_GP('description')); $obj->setWebdescription(GeneralUtility::_GP('webdescription')); $obj->setType(GeneralUtility::_GP('type')); $obj->setDatetime(new \DateTime()); $obj->setGalleryOwner($this->user['uid']); $assetsMetaData = GeneralUtility::_GP('imgMetaData'); $utilityObj = GeneralUtility::makeInstance(UploadAssetsProviderUtility::class); $fileObj = $utilityObj->processAssets($_FILES, $assetsMetaData, $uploadFolderId); $fileObjStorage = GeneralUtility::makeInstance(ObjectStorage::class); foreach($fileObj as $item) { $fileObjStorage->attach($item); } if(GeneralUtility::_GP('type') == 'static') { $obj->setFiles($fileObjStorage); } $this->mediaAlbumRepository->update($obj);
UploadAssetsProviderUtility中的uploadFile方法代码
/** * Create file reference object * * @param UploadedFile $fileImage * @param Folder $uploadFolder * @param String $uploadFolderId * @param Array $metainfo * @return FileReference $fileReference */ protected function uploadFile($fileImage, $uploadFolder, $uploadFolderId, $fileMeta = []): FileReference { [$storageId, $storagePath] = explode(':', $uploadFolderId, 2); $storage = $this->resourceFactory->getStorageObject($storageId); $fileReference = GeneralUtility::makeInstance( FileReference::class, $assetProp, $this->resourceFactory ); if(is_array($fileImage)) { $file = $storage->addFile( $fileImage['tmp_name'], $uploadFolder, $fileImage['name'] ); $assetProp = [ 'uid_local' => $file->getUid(), 'uid_foreign' => StringUtility::getUniqueId('NEW_'), 'uid' => StringUtility::getUniqueId('NEW_'), 'crop' => null, ]; $metaTitle = $fileImage['falMetaData']['title'] ? $fileImage['falMetaData']['title'] : $fileImage['name']; $metaAlt = $fileImage['falMetaData']['alt'] ? $fileImage['falMetaData']['alt'] : $fileImage['name']; $metaLink = $fileImage['falMetaData']['link'] ? $fileImage['falMetaData']['link'] : ''; $metaDescription = $fileImage['falMetaData']['description'] ? $fileImage['falMetaData']['description'] : ''; $fileReference->setOriginalResource($file); } else { // here $metainfo->uid has existing Filereference UID if already exist and find Filereference object $fileImage = $this->resourceFactory->getFileReferenceObject($metainfo->uid); $properies = $fileImage->getReferenceProperties(); $metaTitle = $fileMeta['falMetaData']['title'] ? $fileMeta['falMetaData']['title'] : $fileMeta['name']; $metaAlt = $fileMeta['falMetaData']['alt'] ? $fileMeta['falMetaData']['alt'] : $fileMeta['name']; $metaLink = $fileMeta['falMetaData']['link'] ? $fileMeta['falMetaData']['link'] : ''; $metaDescription = $fileMeta['falMetaData']['description'] ? $fileMeta['falMetaData']['description'] : ''; $fileReference->setUidLocal($properies['uid_local']); } $fileReference->setTitle($metaTitle); $fileReference->setAlternative($metaAlt); $fileReference->setDescription($metaDescription); $fileReference->setLink($metaLink); $fileReference->setTableLocal('sys_file'); $fileReference->setTablenames($this->foreignTable); return $fileReference; }
问题核心与修复方案
核心问题
更新分支中,代码重新实例化了新的FileReference对象,而非直接修改已加载的原有引用对象,导致保存时生成新记录而非更新旧记录。
修复步骤
- 区分新建/更新逻辑,直接操作原对象
处理已有引用时,直接使用加载的原FileReference对象更新属性,不再新建实例。 - 修正变量顺序与取值逻辑
调整$assetProp定义位置,避免实例化时变量未定义;修复元数据取值的变量混淆问题。 - 保留原有引用的默认值
更新元属性时,若前端未传递新值,保留原有引用的属性值,避免覆盖为空。
修改后的uploadFile方法
/** * 创建或更新文件引用对象 * * @param mixed $fileImage 新上传的文件数组或已有引用的UID * @param Folder $uploadFolder * @param string $uploadFolderId * @param array $fileMeta 元数据 * @return FileReference */ protected function uploadFile($fileImage, $uploadFolder, $uploadFolderId, $fileMeta = []): FileReference { [$storageId, $storagePath] = explode(':', $uploadFolderId, 2); $storage = $this->resourceFactory->getStorageObject($storageId); $fileReference = null; // 处理新上传文件:新建FileReference if (is_array($fileImage)) { $file = $storage->addFile( $fileImage['tmp_name'], $uploadFolder, $fileImage['name'] ); $assetProp = [ 'uid_local' => $file->getUid(), 'uid_foreign' => StringUtility::getUniqueId('NEW_'), 'uid' => StringUtility::getUniqueId('NEW_'), 'crop' => null, ]; $fileReference = GeneralUtility::makeInstance( FileReference::class, $assetProp, $this->resourceFactory ); $fileReference->setOriginalResource($file); // 提取元数据,无值则用文件名 $metaTitle = $fileImage['falMetaData']['title'] ?? $fileImage['name']; $metaAlt = $fileImage['falMetaData']['alt'] ?? $fileImage['name']; $metaLink = $fileImage['falMetaData']['link'] ?? ''; $metaDescription = $fileImage['falMetaData']['description'] ?? ''; } else { // 处理已有引用:加载原对象并更新属性 $fileReference = $this->resourceFactory->getFileReferenceObject($fileImage); // 提取元数据,无值则保留原引用的属性 $metaTitle = $fileMeta['falMetaData']['title'] ?? $fileReference->getTitle(); $metaAlt = $fileMeta['falMetaData']['alt'] ?? $fileReference->getAlternative(); $metaLink = $fileMeta['falMetaData']['link'] ?? $fileReference->getLink(); $metaDescription = $fileMeta['falMetaData']['description'] ?? $fileReference->getDescription(); } // 统一设置元属性 $fileReference->setTitle($metaTitle); $fileReference->setAlternative($metaAlt); $fileReference->setDescription($metaDescription); $fileReference->setLink($metaLink); $fileReference->setTableLocal('sys_file'); $fileReference->setTablenames($this->foreignTable); return $fileReference; }
主逻辑补充说明
确保$assetsMetaData传递了已有FileReference的UID,让uploadFile能正确识别更新操作;同时ObjectStorage要包含所有需要保留的引用(更新后的+新增的),避免丢失未修改的原有引用。
内容的提问来源于stack exchange,提问作者Geee
相关产品推荐
相关产品推荐

