2012-11-07 15 views
6

में मेरे पास उपयोगकर्ता पंजीकरण के लिए एक फॉर्म है, और केवल उपयोगकर्ता नाम फ़ील्ड मौजूद है। और मेरे रूप में, मैं उपयोगकर्ता को उपयोगकर्ता नाम केवल उपयोगकर्ता को अनुमति देना चाहता हूं। निकनाम नाम पंजीकरण के उपयोगकर्ता नाम के समान होगा।फ़ील्ड का सत्यापन फॉर्म में मौजूद नहीं है लेकिन एंटीटी

यह फार्म अर्थात, मेरे प्रपत्र प्रकार कक्षा में, एक उपयोगकर्ता इकाई के लिए बाध्य किया जाता है:

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; 

    //... 

हालांकि, अगर मैं सत्यापन अर्थात $form->isValid() पर केवल उपयोगकर्ता नाम नहीं बल्कि Nicename साथ एक रूप है, का निर्माण यह मान्य करने के लिए विफल रहता है।

इस बाईपास के लिए, मैं के साथ आने के बाद:

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'); 

लेकिन मैं यह बहुत असजीला मिल जाए, कुछ छोड़ नियंत्रक को बोझ (अनुरोध ऑब्जेक्ट से निकालें, डेटा में डालें, और इसे वापस ऑब्जेक्ट में डाल दें, आउच!), और यदि उपयोगकर्ता जेनरेट किए गए HTML के स्रोत कोड का निरीक्षण करना चाहते हैं तो उपयोगकर्ता छुपा फ़ील्ड देख सकता है।

क्या वैसे भी कम से कम किसी भी नियंत्रक को फॉर्म प्रकार का उपयोग करने की आवश्यकता नहीं है, जबकि इकाई की बाधाओं को बनाए रखते हुए उपरोक्त चीजों की आवश्यकता नहीं है?

मैं तालिका स्कीमा को नहीं बदल सकता जो उपयोगकर्ता इकाई का बैक अप लेता है, और मैं नोटब्लैंक बाधा को रखना चाहता हूं।


संपादित करें: लंबे परेशानी के बाद, मैं मान्यता समूहों का उपयोग करने का फैसला किया है और यह काम किया।

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

के रूप में एक बोनस, मैं नियंत्रक से ले जाने के buildForm विधि प्रपत्र प्रकार में एक Form Event Subscriber

जोड़कर प्रकार स्तर फार्म करने के लिए:

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

उत्तर

2

मुझे लगता है कि आप validation groups उपयोग करना चाहिए: तुम भी एक PrePersist शर्त यह है कि आपके Nicename चर initialises परिभाषित कर सकते हैं।

0

अपने प्रयोक्ता इकाई में आप बता सकते हैं जो क्षेत्र व्यर्थ हो सकता है:

/** 
*@ORM\Column(type="string", length=100, nullable=TRUE) 
*/ 
protected $someVar; 

इस तरह आपके विचार नियंत्रकों कुछ करने की ज़रूरत नहीं है।

उल्लेख करने के लिए भूल गए।

// you need to first tell your User entity class it has LifeCycleCallBacks: 

/** 
* @ORM\Entity() 
* @ORM\HasLifecycleCallbacks() 
*/ 
class User 
{ 

    ... 

    /** 
    *@ORM\PrePersist 
    */ 
    public function cloneName() 
    { 
     $this->nicename = $this->username; 
    } 
} 
+0

मैं निरर्थक सेट नहीं कर सकता क्योंकि वह इकाई उस तालिका पर आधारित है जिसका स्कीमा मैं नहीं बदल सकता। ... निश्चित रूप से मैं कर सकता था लेकिन मैं लगातार जारी रखने पर एसक्यूएल त्रुटियों का जोखिम उठाऊंगा। – luiges90

+0

आपकी इकाई के __construct() फ़ंक्शन में, क्या आप पूरी त्रुटि को रोकने के लिए इकाई को कुछ डिफ़ॉल्ट मान दे सकते हैं। – Zhang

+0

मैं वास्तव में इकाई के लिए नोटब्लैंक प्रतिबंध रखना चाहता हूं। मैंने आपके रास्ते का उपयोग करने की कोशिश की लेकिन केवल तभी काम करें जब क्षेत्र के लिए '@ कॉन्स्ट्रेन \ NotBlank() 'नहीं है। – luiges90

0

इस मामले में, आपको एक कस्टम सत्यापन नियम बनाने के लिए Callback दावा का उपयोग करना चाहिए।

संबंधित मुद्दे