验证不在表单中但在实体中的字段

lui*_*s90 7 symfony-forms symfony

我有一个用户注册表单,表单中只有用户名字段.在我的表单中,我希望只允许用户输入用户名.Nicename与注册时的用户名相同.

此表单绑定到User实体,即在我的表单类型类中:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Some\Bundle\Entity\User',
    ));
}
Run Code Online (Sandbox Code Playgroud)

实体User,具有为username和nicename设置的NotBlank约束.

namespace Some\Bundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Constraints;

//...

class User
{
    //...

    /**
     * @var string $username
     *
     * @ORM\Column(name="user_login", type="string", length=60, unique=true)
     * @Constraints\NotBlank()
     */
    private $username;

    /**
     * @var string $nicename
     *
     * @ORM\Column(name="user_nicename", type="string", length=64)
     * @Constraints\NotBlank()
     */
    private $nicename;

    //...
Run Code Online (Sandbox Code Playgroud)

但是,如果我构建一个只有用户名而不是nicename的表单,则在验证时即$form->isValid()无法验证.

为了绕过这个,我想出了以下内容:

namespace Some\Bundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Some\Bundle\Form\Type\RegisterType;
//...

class UserController extends Controller
{
   //...
public function registerAction()
{
    //...
    $request = $this->getRequest();
    $form = $this->createForm(new RegisterType());

    if ($request->getMethod() == 'POST') {
        // force set nicename to username.
        $registerFields = $request->request->get('register');
        $registerFields['nicename'] = $registerFields['username'];
        $request->request->set('register', $registerFields);

        $form->bind($request);

        if ($form->isValid()) {
            $user = $form->getData();
            //persist $user, etc...
Run Code Online (Sandbox Code Playgroud)

在表单类型中,我将其添加到我的buildForm方法:

$builder->add('nicename', 'hidden');
Run Code Online (Sandbox Code Playgroud)

但我发现这非常不优雅,给控制器留下了一些负担(从请求对象中提取,放入数据,然后将其放回请求对象中,哎哟!),如果他要检查隐藏字段,用户可以看到隐藏字段生成的HTML的源代码.

无论如何,至少任何使用表单类型的控制器都不需要执行上述操作,同时保留实体约束吗?

我无法更改备份User实体的表模式,我想保留NotBlank约束.


编辑:经过长时间的麻烦,我决定使用验证组,它的工作原理.

class User
{
//...

/**
 * @var string $username
 *
 * @ORM\Column(name="user_login", type="string", length=60, unique=true)
 * @Constraints\NotBlank(groups={"register", "edit"})
 */
private $username;

/**
 * @var string $nicename
 *
 * @ORM\Column(name="user_nicename", type="string", length=64)
 * @Constraints\NotBlank(groups={"edit"})
 */
private $nicename;
Run Code Online (Sandbox Code Playgroud)

表格类型:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Some\Bundle\Entity\User',
        'validation_groups' => array('register', 'Default')
    ));
}
Run Code Online (Sandbox Code Playgroud)

'Default'是必需的,或者它忽略了我在表单类型buildForm方法中添加的所有其他约束...请注意,它区分大小写:'default'不起作用.

虽然,我发现它还不够(对不起,我没有把它放在原来的问题中),因为当我坚持时,我需要在我的控制器中执行此操作:

$user->setNicename($user->getUsername());
Run Code Online (Sandbox Code Playgroud)

作为奖励,我通过添加表单事件订阅者将其从控制器移动到表单类型级别

在表单类型buildForm方法中:

$builder->addEventSubscriber(new RegisterPostBindListener($builder->getFormFactory()));
Run Code Online (Sandbox Code Playgroud)

和RegisterPostBindListener类

<?php
namespace Some\Bundle\Form\EventListener;

use Symfony\Component\Form\Event\DataEvent;
use Symfony\Component\Form\FormFactoryInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\FormEvents;

class RegisterPostBindListener implements EventSubscriberInterface
{

public function __construct(FormFactoryInterface $factory)
{

}

public static function getSubscribedEvents()
{
    return array(FormEvents::POST_BIND => 'setNames');
}

public function setNames(DataEvent $event)
{
    $data = $event->getData();

    $data->setNicename($data->getUsername());
}
}
Run Code Online (Sandbox Code Playgroud)

1ed*_*1ed 2

我认为你应该使用验证组