TYPO3 10.4.6:图片上传尺寸及宽高比验证器未触发问题求助
问题解决步骤
一、验证器注册说明
在TYPO3 10.4中,Extbase自定义验证器不需要在ext_localconf.php或tt_content中手动注册,只要满足以下两个条件即可被系统识别:
- 验证器类文件路径与命名空间严格匹配:例如
My\Namespace\Validation\Validator\ImageDimensionsValidator对应扩展目录下的Classes/Validation/Validator/ImageDimensionsValidator.php - Model中
@Validate注解引用的类名完全正确(注意命名空间大小写)
二、修复验证器不触发的核心问题
1. 修正注解的引号解析问题
你的Model注解中使用了转义引号",会导致TYPO3无法正确识别验证器类名和配置选项,改为普通双引号即可:
/** * @var \TYPO3\CMS\Extbase\Domain\Model\FileReference * @TYPO3\CMS\Extbase\Annotation\Validate("My\Namespace\Validation\Validator\ImageDimensionsValidator", options={"maxWidth":1000, "maxHeight":1000}) * @Cascade("remove") */ protected $attachedFile = null;
2. 修正图片路径获取逻辑
PathUtility::getAbsoluteWebPath()返回的是网站根相对的URL路径,而getimagesize()需要服务器绝对路径,改用GeneralUtility::getFileAbsFileName()获取正确路径:
// 替换原文件路径获取代码 $filePath = GeneralUtility::getFileAbsFileName($file->getIdentifier()); if (!file_exists($filePath)) { $this->addError('图片文件不存在.', 1620729250); return; } $imageSize = getimagesize($filePath);
3. 确认验证触发时机
- 前端Extbase表单场景:确保控制器Action中调用了验证逻辑,比如使用
$this->arguments['yourModel']->validate(),或表单正确绑定Model - 后端记录编辑场景:Extbase的
@Validate注解不会自动触发后端验证,需通过TCA配置额外实现(见下文补充)
三、添加16:9宽高比验证逻辑
修改验证器的isValid()方法,补充宽高比检查逻辑(允许±0.01的误差,避免因图片像素取整导致的误判):
protected function isValid($value) { if (!$value instanceof \TYPO3\CMS\Core\Resource\FileReference) { $this->addError('无效的文件类型.', 1620729249); return; } $file = $value->getOriginalFile(); $filePath = GeneralUtility::getFileAbsFileName($file->getIdentifier()); if (!file_exists($filePath)) { $this->addError('图片文件不存在.', 1620729250); return; } $imageSize = getimagesize($filePath); if (!$imageSize) { $this->addError('无法读取图片尺寸信息.', 1620729251); return; } $maxWidth = $this->options['maxWidth']; $maxHeight = $this->options['maxHeight']; // 检查尺寸上限 if ($imageSize[0] > $maxWidth || $imageSize[1] > $maxHeight) { $this->addError( sprintf( '图片尺寸过大,允许的最大尺寸为 %dx%d 像素.', $maxWidth, $maxHeight ), 1620729248 ); } // 检查16:9宽高比 $expectedRatio = 16 / 9; $actualRatio = $imageSize[0] / $imageSize[1]; if (abs($actualRatio - $expectedRatio) > 0.01) { $this->addError( sprintf( '图片宽高比必须为16:9,当前比例为 %.2f:1(%dx%d).', $actualRatio, $imageSize[0], $imageSize[1] ), 1620729252 ); } }
四、后端记录验证补充(可选)
如果需要在后端编辑记录时也触发验证,需通过TCA配置实现:
- 在扩展的
Configuration/TCA/Overrides/your_table.php中添加:
$GLOBALS['TCA']['your_table']['columns']['attached_file']['config']['overrideChildTca']['columns']['uid_local']['config']['appearance']['elementBrowserAllowed'] = 'jpg,jpeg,png'; $GLOBALS['TCA']['your_table']['columns']['attached_file']['config']['eval'] = 'trim,myImageValidation';
- 在
ext_localconf.php中注册后端验证类:
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tce']['formevals']['myImageValidation'] = \My\Namespace\Validation\Backend\ImageDimensionsEval::class;
- 创建后端验证类
Classes/Validation/Backend/ImageDimensionsEval.php:
namespace My\Namespace\Validation\Backend; use TYPO3\CMS\Core\Resource\FileRepository; use TYPO3\CMS\Core\Utility\GeneralUtility; class ImageDimensionsEval implements \TYPO3\CMS\Core\DataHandling\DataHandler\FieldValidatorInterface { public function validateField(array $parameters) { $fileUid = $parameters['value']; if (!$fileUid) { return ''; } $fileRepository = GeneralUtility::makeInstance(FileRepository::class); $file = $fileRepository->findByUid((int)$fileUid); if (!$file || !$file->isImage()) { return '仅允许上传图片文件.'; } $filePath = GeneralUtility::getFileAbsFileName($file->getIdentifier()); $imageSize = getimagesize($filePath); if (!$imageSize) { return '无法读取图片尺寸信息.'; } $maxWidth = 1000; $maxHeight = 1000; if ($imageSize[0] > $maxWidth || $imageSize[1] > $maxHeight) { return sprintf('图片尺寸过大,允许的最大尺寸为 %dx%d 像素.', $maxWidth, $maxHeight); } $expectedRatio = 16 / 9; $actualRatio = $imageSize[0] / $imageSize[1]; if (abs($actualRatio - $expectedRatio) > 0.01) { return sprintf('图片宽高比必须为16:9,当前比例为 %.2f:1.', $actualRatio); } return ''; } }
内容的提问来源于stack exchange,提问作者EmWe
相关产品推荐
相关产品推荐

