编辑:这是一个github,其中包含重现问题的完整代码
我有以下实体
class Place
{
use Traits\HasId;
/**
* Used for form.
*
* @Assert\Image(
* mimeTypes = {"image/png", "image/jpeg"},
* minWidth = 50,
* maxWidth = 1000,
* minHeight = 50,
* maxHeight = 1000,
* maxSize = "1M"
* )
*/
private $imageFile = null;
/**
* @ORM\OneToOne(targetEntity="MyImage", orphanRemoval=true, cascade={"persist"})
*/
protected $image;
}
使用以下表格
class AdminPlaceType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$transformer = new HasImageTransformer();
$builder->add('imageFile')->addModelTransformer($transformer);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(['data_class' => 'AppBundle\Entity\Place']);
}
}
以下型号变压器
class HasImageTransformer implements DataTransformerInterface
{
public function transform($hasImage)
{
return $hasImage;
}
/**
* reverse transforms.
*/
public function reverseTransform($hasImage)
{
$file = $hasImage->getImageFile();
$myImage = new MyImage();
$myImage->setData(file_get_contents($file->getPathName()))
$myImage->setMimeType($file->getMimeType());
$hasImage->setImage($myImage);
}
}
我可以上传正确的图片,表格正确保存在数据库中。
但是,如果我提交的图像不正确(例如.txt文件),表单仍会保存在数据库中而不会出现任何错误
但是,如果我从表单中删除addModelTransformer
,那么我得到了正确的验证错误
此文件不是有效图片
由于我的变换器没有修改原始的imageFile
字段,我想知道是什么原因导致了这个问题。
我正在使用php7和symfony3.3.4
答案 0 :(得分:3)
答案实际上非常愚蠢
原因是我忘记了reverseTransform
/**
* reverse transforms.
*/
public function reverseTransform($hasImage)
{
$file = $hasImage->getImageFile();
$myImage = new MyImage();
$myImage->setData(file_get_contents($file->getPathName()))
$myImage->setMimeType($file->getMimeType());
$hasImage->setImage($myImage);
// this was missing :(
return $hasImage;
}
这导致表单模型中的整个实体被转换为“null”但是实体本身没有被销毁,因为我仍然在控制器中引用它,因为它是通过标准
public function createAction(Request $request)
{
$place = new Place();
$form = $this->createForm(AdminPlaceType::class, $place);
$form->handleRequest($request);
}
所以$place
包含正确的数据,而null
表单没有触发验证....
答案 1 :(得分:2)
您的变压器正在用UploadFile
实体替换File
或MyImage
对象。我认为您的MyImage
未延伸File
或UploadFile
。这不是变压器的预期用途。变压器将一个输入更改为另一种输入类型。
我建议删除变压器并将变压器的代码添加到Place->setImageFile
。然后,您将按预期进行imageFile验证,每次使用其他文件更改图像时,即使不使用表单,也会重新创建MyImage
。
如果您真的想在表单代码中而不是在Place实体代码中执行此操作,则应使用 FormEvents https://symfony.com/doc/current/form/events.html FormEvents :: POST_SET_DATA < / p>
答案 2 :(得分:0)
要导致验证错误,请抛出TransformationFailedException。但是,您传递给此例外的消息不会显示给用户。您将使用invalid_message选项设置该消息(请参阅下文)。 https://symfony.com/doc/current/form/data_transformers.html