duanliexi1052 2015-04-06 11:15
浏览 28
已采纳

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

I got a blog plateform, with an entity Category this entity has associated to it

  • a name
  • an icon (small 40*40 png)

as the file is very small and mime-type assured to be always png, I've decided to store the file content as a Base64 encoded string in the entity/database

this way the page can be rendered at once without needing to do extra request for very small files (same for the API call GET /api/categories ). for pre-loaded data it works pretty well. The problem come when I want to edit one category

I've created a form with a file type for the icon

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)
    ;
}

the data transformer being

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));
    }
}

but when i submit the form with a valid image, the form fails in the profiler, in form section i can see

Symfony\Component\Validator\ConstraintViolation Object(Symfony\Component\Form\Form).data.icon = THE_BASE_64_OF_THE_FILE

is it because the data is transformed before the validation happpens ?

  • how to modify this code to make it pass the validation
  • something i need to wrap my head around is what is going to happen when i will edit if the user upload no new image, how can the image be preserved ?
  • 写回答

1条回答 默认 最新

  • dongpu3792 2015-04-07 13:52
    关注

    my current solution is to have two fields for the icon in my entity

    /**
     * @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;
    

    (with the appropriate getter and setter)

    then to have my data transformer for the WHOLE class Category

    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;
        }
    }
    

    and then in my CategoryType to associate the data transformer to the whole channel

    /**
     * @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)
        ;
    }
    

    the validation still happen after the data transform, but now it's no more a problem , as the entity will not be persisted if the form is not valid

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 stata安慰剂检验作图但是真实值不出现在图上
  • ¥15 c程序不知道为什么得不到结果
  • ¥40 复杂的限制性的商函数处理
  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题