Symfony2 base64 in Entity to File in Form(和反向)使用DataTransformer

时间:2015-04-06 11:15:34

标签: php forms validation symfony

我有一个博客平台,该实体与之关联的实体{{1}

  • 一个名字
  • 一个图标(小40 * 40 png)

由于文件非常小且mime-type确保始终为png,我决定将文件内容存储为实体/数据库中的Base64编码字符串

通过这种方式,可以立即呈现页面,而无需对非常小的文件执行额外请求(对于API调用Category也是如此)。对于预加载的数据,它工作得很好。当我想编辑一个类别

时会出现问题

我已经为图标

创建了一个包含文件类型的表单
GET /api/categories

数据转换器

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new FileToBase64Transformer();

    $iconField = $builder->create('iconColor', 'file', ['required' => false]);
    $iconField->addModelTransformer($transformer);

    $builder
        ->add('title')
        ->add($iconField)
    ;
}

但是当我提交带有效图片的表单时,表单会失败 在分析器中,在表格部分我可以看到

class FileToBase64Transformer implements DataTransformerInterface { public function transform($base64) { return null; } public function reverseTransform($file) { if (is_null($file)) { return null; } return base64_encode(file_get_contents($file)); } }

是因为数据在验证之前被转换了吗?

  • 如何修改此代码以使其通过验证
  • 我需要解决的问题是当我编辑用户上传没有新图像时会发生什么,如何保存图像?

1 个答案:

答案 0 :(得分:3)

我目前的解决方案是在我的实体中为图标设置两个字段

/**
 * @Constraints\Image(
 *      maxWidth = 40,
 *      maxHeight = 40,
 *      allowSquare = true,
 *      mimeTypes = "image/png",
 * )
 */
private $iconFile = null;

/**
 * Base64 of the icon in color version
 *
 * @var string
 *
 * @ORM\Column(name="icon_color", type="text", nullable=true)
 */
private $icon = null;

(使用适当的getter和setter)

然后将我的数据转换器用于WHOLE类别

class FileToBase64Transformer implements DataTransformerInterface
{
    /**
     * Transforms an object (file) to a base64.
     *
     * @param  $file
     * @return string
     */
    public function transform($channel)
    {
        return $channel;
    }

    /**
     * reverse transforms
     *
     */
    public function reverseTransform($categoryl)
    {
        $iconFile = $category->getIconFile();
        if (!is_null($iconFile)) {
            $channel->setIcon(
                base64_encode(file_get_contents($iconFile))
            );
        }
        return $channel;
    }
}

然后在我的CategoryType中将数据转换器关联到整个通道

/**
 * @param FormBuilderInterface $builder
 * @param array $options
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $transformer = new FileToBase64Transformer();

    $builder
        ->add('title')
        ->add('theme_color')
        ->add('type')
        ->add('iconFile')
        ->addModelTransformer($transformer)
    ;
}

验证仍然在数据转换后发生,但现在不再是问题,因为如果表单无效,实体将不会被保留