phpvalidationsymfonysymfony-formssymfony-components

For Symfony Validator Component is it possible to force validation to fail from a class that implements EventSubscriberInterface


I have the following code;

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add(
        $builder->create(
            'href', 
            'url', 
            $this->getOptionsForUrlWidget('Website URL')
            )->addEventSubscriber(new GetResolvedUrlListener())
        )
...

My method GetResolvedUrlListener does a curl request to discover the correct protocol and final address (following redirects) to determine the correct url.

I would like it to cause validation to fail if the curl request does not receive a successful HTTP response. So if the supplied url is not reachable, it should not save.

Can this be done in a class that implements the EventSubscriberInterface? Should I rather add a new constraint and validate the supplied url twice?


Solution

  • You should add a constraint, but you don't necessarily have to validate it twice, you could create a central service that resolves these urls but also keeps them for itself in two $validUrls and $invalidUrls properties, you can then use this service in both your event listener and in your validation constraint, the service can look something like this:

    class UrlValidator{
    
        protected $validUrls = array();
        protected $invalidUrls = array();
    
        public function resolve($url){
            // we have validated this url before, and it wasn't valid
            if(isset($this->invalidUrls[$url])
                return false;
            // we have validated this url before, so we can return true or the resolved value
            if(isset($this->validUrls[$url])
                return $this->validUrls[$url];
    
            else{
            // do the curl request, and set $this->validUrls[$urls] or $this->invalidUrls[$url] accordingly
            }
        }
    }