Symfony2 form validation based on two fields

前端 未结 5 2046
醉梦人生
醉梦人生 2020-12-05 05:04

I am currently developing a Website in which user may buy gift cards. I am using a three step form using the CraueFormFlow bundle and everything is concerning the steps. I a

相关标签:
5条回答
  • 2020-12-05 05:36

    This is how I've done this in my validation constraints, to check credit card validity with expiration month and year properties.

    In this class, I check the value of expirationYear property and compare it with value of expirationMonth property got from contextObject.

    /**
     * Method to validate
     * 
     * @param string                                  $value      Property value    
     * @param \Symfony\Component\Validator\Constraint $constraint All properties
     * 
     * @return boolean
     */
    public function validate($value, Constraint $constraint)
    {
        $date               = getdate();
        $year               = (string) $date['year'];
        $month              = (string) $date['mon'];
    
        $yearLastDigits     = substr($year, 2);
        $monthLastDigits    = $month;
        $otherFieldValue    = $this->context->getRoot()->get('expirationMonth')->getData();
    
        if (!empty($otherFieldValue) && ($value <= $yearLastDigits) && 
                ($otherFieldValue <= $monthLastDigits)) {
            $this->context->addViolation(
                $constraint->message,
                array('%string%' => $value)
            );            
            return false;            
        }
    
        return true;
    }
    

    Of course, you have to authorize class and properties constraints in your getTargets method, form the main constraint file.

    /**
     * Get class constraints and properties
     * 
     * @return array
     */
    public function getTargets()
    {
        return array(self::CLASS_CONSTRAINT, self::PROPERTY_CONSTRAINT);
    } 
    

    Further explanations and complete tutorial here: http://creativcoders.wordpress.com/2014/07/19/symfony2-two-fields-comparison-with-custom-validation-constraints/

    0 讨论(0)
  • 2020-12-05 05:44

    You have many solutions for this.

    The easiest one is to add a Callback constraint to your model class.

    Another way to do it would be to create your custom constraint and its associated validator. You have a cookbook explaining how to create a custom validation constrain. This is the best approach to do it.

    As your constraint does not apply to a property but to a class, you must specify it overriding the the ->getTargets() method of your constraint class:

    class MyConstraint extends Constraint
    {
        // ...
    
        public function getTargets()
        {
            return Constraint::CLASS_CONSTRAINT;
        }
    }
    

    So the value passed as $value argument of the ->isValid() method will contain values of the whole class and not only of a single property.

    0 讨论(0)
  • 2020-12-05 05:53

    I'd suggest using Expression constraint. This constraint can be applied on form field or (preferably) in entity:

       /**
         * @var int
         * @Assert\Type(type="integer")
         */
        private $amountGiftCards25;
    
        /**
         * @var int
         * @Assert\Type(type="integer")
         * @Assert\Expression(expression="this.getAmountGiftCards25() > 0 or value > 0", message="Please choose amount of gift cards.")
         */
        private $amountGiftCards50;
    
    0 讨论(0)
  • 2020-12-05 05:54

    When you don't have a data class attached to your form you can implement dependent constraints in forms like this:

        $startRangeCallback = function ($object, ExecutionContextInterface $context) use ($form)
        {
            $data = $form->getData();
            $rangeEnd = $data['range_end'];
            if($object && $rangeEnd){
                if ($object->getTimestamp() > $rangeEnd->getTimestamp()) {
                    $context->addViolation('Start date should be before end date!', array(), null);
                }
            }
    
        };
    
        $form->add('range_start', 'bootstrap_datepicker', array(
                'format' => 'dd-MM-yyyy',
                'required' => false,
                'attr' => array('class' => "col-xs-2"),
                'calendar_weeks' => true,
                'clear_btn' => true,
                'constraints' => array(
                    new Callback(array($startRangeCallback)),
                )
            )
        );
    
        $form->add('range_end', 'bootstrap_datepicker', array(
                'format' => 'dd-MM-yyyy',
                'required' => false,
                'attr' => array('class' => "col-xs-2"),
                'calendar_weeks' => true,
                'clear_btn' => true,
    
            )
        );
    
    0 讨论(0)
  • 2020-12-05 05:55

    Use Regular expression inorder to prevent Zero

    In your Entity class write down the below override function , and specify your property which you need to validate.

    The below example is for validating a pincode ,here in pincode field I admit only numbers 0-9 combinations upto 10 digits .

    " ^\d+$ " this is the regular expression I used to prevent other characters.

    For overriding this function you must include the below classes

    use Symfony\Component\Validator\Mapping\ClassMetadata;// for overriding function loadValidatorMetadata()
    
    use Symfony\Component\Validator\Constraints\NotBlank;// for notblank constrain
    
    use Symfony\Component\Validator\Constraints\Email;//for email constrain
    
    use Symfony\Component\Validator\Constraints\MinLength;// for minimum length
    
    use Symfony\Component\Validator\Constraints\MaxLength; // for maximum length
    
    use Symfony\Component\Validator\Constraints\Choice; // for choice fields
    
    use Symfony\Component\Validator\Constraints\Regex; // for regular expression
    
    
    
    public static function loadValidatorMetadata(ClassMetadata $metadata)
        {
            $metadata->addPropertyConstraint('pincode', new NotBlank(array('message' => 'Does not blank')));
            $metadata->addPropertyConstraint('pincode', new Regex(array('pattern'=>'/^\d+$/','message' => 'must be number')));
            $metadata->addPropertyConstraint('pincode', new MaxLength(array('limit'=>'6','message' => 'must maximum 6 digits')));
            $metadata->addPropertyConstraint('pincode', new MinLength(array('limit'=>'6','message' => 'must minimum 6 digits')));
    
    
        }
    

    Not forget these all must

    included in your Entity class

    that you have to validate. So in your case use a proper regular expression which does not permit '0'.

    Happy coding

    0 讨论(0)
提交回复
热议问题