我有一個用於用戶註冊的表單,並且只有用戶名字段存在於表單中。而在我的表格中,我希望允許用戶只輸入用戶名。 Nicename與註冊用戶名相同。驗證字段不在表單中,但在實體中
這種形式的綁定到用戶的實體,即,在我的形式類型的類:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Some\Bundle\Entity\User',
));
}
實體用戶,其中有一個NotBlank約束兩者的用戶名和nicename設置。
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...
而在形式I型內容添加到我的buildForm
方法:
$builder->add('nicename', 'hidden');
但我覺得這是非常不雅,留下一些對控制器的負擔(從請求對象中提取,放入數據,並將其放回請求對象,哎!),如果用戶要檢查生成的HTML的源代碼,用戶可以看到隱藏的字段。
反正是有至少能使用表單類型不需要做這樣的事情上面,同時保留了實體約束任何控制器?
我無法改變它備份用戶實體表模式,我想保持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'
不起作用。
雖然,我覺得這是不夠的(和抱歉,我沒有把它放在我原來的問題),因爲當我堅持,我需要做這在我的控制器:
$user->setNicename($user->getUsername());
由於獎勵,我移動此從控制器通過添加Form Event Subscriber
在形式類型buildForm
法形成類型級別:
$builder->addEventSubscriber(new RegisterPostBindListener($builder->getFormFactory()));
而RegisterPostBindListen呃類
<?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());
}
}
我不能設置爲空,因爲該實體是基於我的模式無法更改的表。 ......當然我可以,但我會冒着SQL錯誤持續存在。 – luiges90
在你實體的__construct()函數中,你能簡單地給實體一些默認值來防止NULL錯誤。 – Zhang
我想保留實體的NotBlank約束。我試過用你的方式,但只有在該字段沒有'@Constraints \ NotBlank()'時才能工作。 – luiges90