具有依赖关系的silex表单验证

时间:2013-05-30 20:32:52

标签: php forms validation symfony silex

我使用包含一些复选框和文本字段的silex框架构建了一个表单。用户必须至少检查一个复选框或在文本字段中写入内容。现在我不知道如何验证这样的依赖关系或更好地放置验证逻辑。我可以为单个字段添加约束,但是如何实现复选框验证的依赖项或文本字段?

这是我在控制器类中的验证代码。

public function validateAction(Request $request, Application $app)
{
    $form = $app['form.factory']->create(new ApplicationForm());
    $form->bind($request);
    if ($form->isValid()) {
        return $app->json(array(
            'success' => true,
        ));
    }
}

ApplicationForm类看起来像这样(简化):

class ApplicationForm extends AbstractType {
    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add('crafts', 'choice', array(
                'choices' => array(
                    array('drywall'     => 'Drywall'),
                    array('painter'     => 'Painter'),
                    array('plasterer'   => 'Plasterer'),
                    array('carpenter'   => 'Carpenter'),
                    array('electrician' => 'Electrician'),
                    array('plumber'     => 'Plumber'),
                    array('tiler'       => 'Tiler'),
                    array('bricklayer'  => 'Bricklayer'),
                ),
                'multiple' => true,
                'expanded' => true,
                'required' => false,
            ))
            ->add('craftsOther', 'text', array(
                'attr' => array('class' => 'textinput', 'placeholder' => 'Other', 'maxlength' => 256),
                'constraints' => array(
                    new Assert\Length(array('max' => 256, 'maxMessage' => $this->_errorMessages['crafts_other_max'])),
                ),
                'required' => false,
            ));
    }
}

任何想法如何以优雅的方式做到这一点?

1 个答案:

答案 0 :(得分:0)

您可以向表单本身添加约束,而不仅仅是单个字段。您可以在选项中传递一组约束:

这是一个工作示例,在提交时检查两个字段是否相等。

<?php

require_once __DIR__.'/../vendor/autoload.php';

use Silex\Application;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Constraints as Assert;

$app = new Application();

$app['debug'] = true;
$app->register(new \Silex\Provider\FormServiceProvider());
$app->register(new Silex\Provider\TranslationServiceProvider(), array('translator.domains' => array(),));
$app->register(new Silex\Provider\ValidatorServiceProvider());
$app->register(new Silex\Provider\TwigServiceProvider());

class ExampleFormType extends AbstractType
{

    public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('apple')
            ->add('banana')
            ->add('submit', SubmitType::class);
    }

    public function configureOptions(\Symfony\Component\OptionsResolver\OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'constraints' => [
                new Assert\Callback(function (array $data, ExecutionContextInterface $context) {
                    if ($data['apple'] === $data['banana']) {
                        $context
                            ->buildViolation('Apple and Banana cannot be the same')
                            ->atPath('apple')
                            ->addViolation();
                    }
                }),
            ],
        ]);
    }
}

$app->match('/', function (Request $request, Application $app) {
    $form = $app['form.factory']->create(ExampleFormType::class)->handleRequest($request);
    if ($form->isValid()) {
        echo "Valid Submission";
    }

    return $app['twig']->createTemplate('{{ form(form) }}')->render([
        'form' => $form->createView(),
    ]);
})->method('GET|POST');

$app->run();