Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom Validator/Constraint with Arguments/Parameters in Symfony 2

I want to create a validator similar to the way GitHub handles deleting repositories. To confirm the delete, I need to enter the repo name. Here I want to confirm delete by entering the entity property "name". I will either need to pass the name to the constraint or access it in some way, how do I do that?

like image 219
Jiew Meng Avatar asked Nov 05 '22 00:11

Jiew Meng


1 Answers

you could indeed use a validator constraint to do that:

1: Create a delete form (directy or using a type):

    return $this->createFormBuilder($objectToDelete)
        ->add('comparisonName', 'text')
        ->setAttribute('validation_groups', array('delete'))
        ->getForm()
    ;

2: Add a public property comparisonName into your entity. (or use a proxy object), that will be mapped to the corresponding form field above.

3: Define a class level, callback validator constraint to compare both values:

/**
 * @Assert\Callback(methods={"isComparisonNameValid"}, groups={"delete"})
 */
class Entity 
{
    public $comparisonName;
    public $name;

    public function isComparisonNameValid(ExecutionContext $context)
    {
        if ($this->name !== $this->comparisonName) {
            $propertyPath = $context->getPropertyPath() . '.comparisonName';
            $context->addViolationAtPath(
                $propertyPath,
                'Invalid delete name', array(), null
            );
        }
    }
}

4: Display your form in your view:

<form action="{{ path('entity_delete', {'id': entity.id }) }}">
   {{ form_rest(deleteForm) }}
   <input type="hidden" name="_method value="DELETE" />
   <input type="submit" value="delete" />
</form>

5: To verify that the delete query is valid, use this in your controller:

    $form    = $this->createDeleteForm($object);
    $request = $this->getRequest();

    $form->bindRequest($request);
    if ($form->isValid()) {
        $this->removeObject($object);
        $this->getSession()->setFlash('success',
            $this->getDeleteFlashMessage($object)
        );
    }

    return $this->redirect($this->getListRoute());
like image 53
Florian Klein Avatar answered Nov 15 '22 08:11

Florian Klein