2015-07-12 59 views
2

在我的Symfony2應用程序中,我有一個具有2個子表單的訂閱使用相同的實體地址。 我正在尋找解決方案來驗證第二個窗體只有當複選框未選中。由於子表單屬於同一實體,所以驗證約束是相同的。斷言\有效的實體cannont採取組參數,這樣我就可以「T使用此解決方案。2具有不同驗證的相同實體的子表單Symfony2

SubscriptionType.php

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('billingAddress', new AddressType()) 
     ->add('shippingSame', 'checkbox', array(
       'mapped' => false, 
       'data' => true, 
     )) 
     ->add('shippingAddress', new AddressType()) 
    ;  
} 

Adress.php實體

class Address 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="firstname", type="string", length=255, nullable=false) 
    * @Assert\NotBlank() 
    */ 
    private $firstname; 

    /** 
    * @var string 
    * 
    * @ORM\Column(name="line1", type="string", length=255, nullable=false) 
    * @Assert\NotBlank() 
    */ 
    private $line1; 
} 

Suscription.php Entiry

class Subscription 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="id", type="integer") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    private $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop\Address") 
    * @ORM\JoinColumn(nullable=false) 
    */ 
    private $billingAddress; 

    /** 
    * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Shop\Address") 
    * @ORM\JoinColumn(nullable=false) 
    */ 
    private $shippingAddress; 
} 

所以,我想驗證第二個地址只有當未映射的複選框未選中。

感謝您的幫助!

回答

0

處理未映射字段的唯一方法是直接訪問表單數據,這就違背了驗證的目的。要使用symfony的Validator組件,您必須使複選框映射。只需將此字段添加到您的實體,您不必將其映射到數據庫。

/** 
* @var bool 
*/ 
private $shippingSame; 

/** 
* @return bool 
*/ 
public function isShippingSame() 
{ 
    return $this->shippingSame; 
} 

/** 
* @param bool $shippingSame 
*/ 
public function setShippingSame($shippingSame) 
{ 
    $this->shippingSame = $shippingSame; 
} 

然後你就可以輕鬆地訪問它在@Assert\Callback()

public function validateShipping(ExecutionContextInterface $context) 
{ 
    if ($this->isShippingSame()) { 
     $isValid = ... ; // do the validation 
     if (!$isValid) { 
      $context 
       ->buildViolation('Shipping address is not valid!') 
       ->atPath('shippingAddress') 
       ->addViolation(); 
     } 
    } 
} 
0

您可以使用表格Validation Groups features

你需要一些先進的邏輯來確定確認團組(根據提交的數據),可以將validation_groups選項設置爲一個數組回調如下:

SubscriptionType.php

use Symfony\Component\Form\FormInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 

// before the 2.7 version this method is called setDefaultOptions 
public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'validation_groups' => function (FormInterface $form) { 
      $data = $form->getData(); 

      if (true == $data->shippingSame) { 
       return array('validate_only_billing_address'); 
      } 

      return array('validate_shipping_billing_address'); 
     }, 
    )); 
} 

並添加您實體中的正確驗證組註釋。

希望得到這個幫助。讓我知道你是否需要更多建議。

+0

感謝您的解決方案,但由於實體是同爲2子窗體時,確認團組將是相同的(因爲定義在實體類註釋),所以我們可以我認爲不要使用groups_validation。 – Nbalive16

+0

Hi @ Nbalive16與文檔[您可以根據提交的數據更改羣組](http://symfony.com/doc/current/book/forms.html#validation-groups)手風琴,我經常使用此功能。順便說一句,回調方法也是一個解決方案。 – Matteo

+1

是的,我們可以根據數據更改組,但組是使用註釋定義到實體類文件中的。由於我的實體(以及我的領域)對於2個子表單是相同的,因此定義和使用2個不同的組是不可能的。無論如何,非常感謝您的幫助;) – Nbalive16

0
$resolver->setDefaults(array(
    'validation_groups' => function (FormInterface $form) { 

     if (true == $form->get('shippingSame')->getData()) { 
      return array('validate_only_billing_address'); 
     } 

     return array('validate_shipping_billing_address'); 
    }, 
)); 

我改變了get()屬性。 也許只是一個版本差異(老實說,我沒有調查) 實際上我運行在最後的v2.7.1上。

希望這可以幫助別人