自定义输入类型JSON验证

时间:2018-09-13 12:47:09

标签: php symfony

我正在构建自定义表单输入类型,我对如何在官方文档中进行验证感到有些困惑:https://symfony.com/doc/current/form/create_custom_field_type.html

我的字段类型基本上允许用户插入任意数量的值。它由JavaScript处理,并呈现为将值保存为JSON数组的隐藏输入。

enter image description here

脚本运行良好,现在我需要做的就是确保输入值包含有效的一维JSON数组,以防用户使用其浏览器的dev工具将其弄乱,我希望可以处理此问题通过输入类来最大化字段的可重用性。

我该如何实现?

这是我的输入法,但几乎是空的:

<?php

namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;

class ListType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([]);
    }

    public function getParent()
    {
        return HiddenType::class;
    }
}

谢谢

1 个答案:

答案 0 :(得分:2)

这是最终使用自定义验证器进行操作的方式,欢迎使用更好的解决方案:

namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;

use App\Validator\Constraints\SingleDimensionJSON();

class ListType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'constraints' => [
                new SingleDimensionJSON()
            ]
        ]);
    }

    public function getParent()
    {
        return HiddenType::class;
    }
}

验证器类:

namespace App\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Exception\UnexpectedTypeException;

class SingleDimensionJSON extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if ($value === null || $value === '') {
            return;
        }

        if (!is_string($value)) {
            throw new UnexpectedTypeException($value, 'string');
        }

        $toArray = json_decode($value, true);

        if ($toArray === null) {
            $this->context
                ->buildViolation($constraint->message)
                ->setParameter('{{ string }}', $value)
                ->addViolation()
            ;
            return;
        }
        foreach ($toArray as $item) {
            if (is_array($item)) {
                throw new InvalidArgumentException('Multi dimensional array isn\'t allowed');
            }
        }
}