gpt4 book ai didi

symfony - 验证不存在于表单中但存在于实体中的字段

转载 作者:行者123 更新时间:2023-12-04 12:42:07 24 4
gpt4 key购买 nike

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

此表单绑定(bind)到用户实体,即在我的表单类型类中:

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

实体 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;

//...

但是,如果我构建一个只有用户名但没有 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...

在表单类型中,我将其添加到我的 buildForm方法:
$builder->add('nicename', 'hidden');

但是我觉得这很不优雅,给 Controller 留下了一些负担(从请求对象中提取,放入数据,然后将其放回请求对象,哎哟!),如果用户要检查隐藏字段,则可以看到生成的 HTML 的源代码。

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

我无法更改备份用户实体的表架构,并且我想保留 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;

表格类型:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Some\Bundle\Entity\User',
'validation_groups' => array('register', 'Default')
));
}

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

虽然,我发现这还不够(很抱歉我没有把它放在我原来的问题中),因为当我坚持时,我需要在我的 Controller 中这样做:
$user->setNicename($user->getUsername());

作为奖励,我通过添加 Form Event Subscriber 将其从 Controller 移动到表单类型级别。

在表格类型 buildForm方法:
$builder->addEventSubscriber(new RegisterPostBindListener($builder->getFormFactory()));

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

最佳答案

我认为你应该使用 validation groups .

关于symfony - 验证不存在于表单中但存在于实体中的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13262868/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com