Optional embed form in Symfony 2

前端 未结 5 1929
予麋鹿
予麋鹿 2021-01-16 11:00

I have two entities in my system: Person and Phone as the following code.

class Person
{
    /**
     * @ORM\\Id
     * @ORM\\Colum         


        
相关标签:
5条回答
  • 2021-01-16 11:14

    Do this:

    First on your phone entity, declare the fields as "nullable" like this:

    /**
     * @ORM\Column(type="integer", nullable=true)
     */
    private $countryCode;
    

    This will allow these fields to have a null value.

    Then you need to declare a validator that will check if either none of the fields or all of them are filled

    class Phone {
    
    ...
    /**
     * @Assert\True(message = "Phone must be empty of fill all fields")
     */
    public function isPhoneOK()
    {
        // check if no field is null or all of them are
        // return false if these conditions are not met
    }
    
    0 讨论(0)
  • 2021-01-16 11:17

    It is also possible to use a very simple data Transformer to solve this problem.

    1. Create your Phone data transformer :

      class PhoneTransformer implements DataTransformerInterface
      {
          public function transform($phone)
          {
              if (is_null($phone))
                  return new Phone();
      
              return $phone;
          }
      
          public function reverseTransform($phone)
          {
              if (is_null($phone))
                  return null;
      
              if (!$phone->getType() && !$phone->getCountryCode() /* ... Test if phone is not valid here */)
                  return null;
      
              return $phone;
      }
      
    2. Then simply prepend this transformer in your PhoneType form :

      class PhoneType extends AbstractType
      {
          public function buildForm(FormBuilder $builder, array $options)
          {
              $builder
                  /* Add fields here :
                  ->add( ... )
                  */
                  ->prependNormTransformer(new PhoneTransformer())
              ;
          }
      }
      

    See http://symfony.com/doc/2.0/cookbook/form/data_transformers.html for more details on how implement data transformers.

    0 讨论(0)
  • 2021-01-16 11:18

    I would try this method:

    create additional method in your Phone entity which validates if all fields are null or all fields are not null (these two cases are correct) - and then return true. If some fields are null and some aren't return false. Add an assert annotation to your new method - this will be your new constraint.

    /**
     * @Assert\True(message = "Fill all fields or leave all them blank")
     */
    

    And this should work.

    For more information look here: http://symfony.com/doc/master/book/validation.html#getters

    edit:

    Try this one:

    define your custom validation method (this one which check if any of phone fields is filled) as Callback (at the top of the class):

     * @Assert\Callback(methods={"checkPhoneFields"})
     */
     class Phone {
    

    Next you mark field wich have to be validated with validation group, eg.

    /**
     * @ORM\Column(type="string", length=16, groups={"phone_validation"})
     */
    private $number;
    

    And the last thing, in your custom constraint method you need to switch on "phone_validation" group if any of field isn't empty:

    public function checkPhoneFields(ExecutionContext $context) {
        if (/* fields are not empty */) {
            $context->getGraphWalker()->walkReference($this, 'phone_validation', $context->getPropertyPath(), true);
        }
    

    And that should work.

    0 讨论(0)
  • 2021-01-16 11:35

    frankie567's answer was useful to me. For symfony >= 3.0:

    /**
     *
     * @Assert\Callback()
     */
    public function validatePhone(ExecutionContextInterface $context)
    {
        if (/* Fields are not empty */)
        {
            $validator = $context->getValidator();
    
            $validator->inContext($context)
                ->atPath('phone')
                // you can pass custom validation instead of null, like new Assert\Valid()
                ->validate($this->getPhone(), null, array('phone_validation'));   
        }
    }
    
    0 讨论(0)
  • 2021-01-16 11:38

    For those passing by, with newer versions of Symfony you can do :

    /**
     *
     * @Assert\Callback()
     */
    public function validatePhone(ExecutionContextInterface $context)
    {
        if (/* Fields are not empty */)
        {
            $context->validate($this->getPhone(), 'phone', array("phone_validation"));
        }
    }
    
    0 讨论(0)
提交回复
热议问题