1

How do you configure Symfony2 Validator to use annotations outside of Core?

In core you would do the following:

$container->loadFromExtension('framework', array(
  'validation' => array(
    'enable_annotations' => true,
  ),
));

Taken from: http://symfony.com/doc/2.0/book/validation.html#configuration

For now to make validation work the rules are set within the method loadValidatorMetadata(ClassMetadata $metadata), it works but I prefer annotations.

Example Entity with validation annotations and alternative php method to set validation rules:

<?php

namespace Foo\BarBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints as Assert;


/**
 * @ORM\Entity(repositoryClass="Foo\BarBundle\Entity\Repository\FooRepository")
 * @ORM\Table(name="foo")
 */
class Foo {


    /**
     * @ORM\Column(type="integer", name="bar")
     * @Assert\Type(
     *     type="integer",
     *     message="The value {{ value }} is not a valid {{ type }}."
     * )
     */
    protected $bar;


    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('bar', new Assert\Type(array(
            'type'    => 'integer',
            'message' => 'The value {{ value }} is not a valid {{ type }}.',
        )));
    }    
}

Update 1

The issue now seems to be that the annotations are not being autoloaded correctly.

I load the annotations in to the namespace with:

\Doctrine\Common\Annotations\AnnotationRegistry
::registerAutoloadNamespace("Symfony\Component\Validator\Constraints\\", __DIR__.'/vendor/symfony/validator');

Then when it tries to autoload the annotations it looks for /vendor/symfony/validator/Symfony/Component/Validator/Constraints/Length.php which does not exist. The file is actually located at /vendor/symfony/validator/Constraints/Length.php

I could create a registerLoader() but would rather fix the code. When using Validator within Symfony2 Core that file location would be correct.

How do I make it autoload correctly or get composer to install Symfony2 components to the same location as core?

lookbadgers
  • 988
  • 9
  • 31
  • I have integrated Symfony\Validator to Nette\DI, you can [find some inspiration there](https://github.com/Symnedi/Validator/blob/master/src/DI/ValidatorExtension.php). – Tomas Votruba Jul 07 '15 at 14:21
  • Did you had a look at https://github.com/symfony/Validator#usage , move a bit down to annotations. Please don't forget to download the doctrine/annotation library etc which are needed dependencies. – Hari K T Jul 07 '15 at 17:50

2 Answers2

5

You need to register the Autoloader with AnnotationRegistry, so where ever you require vendor/autoload, for example bootstrap.php add the registerLoader().

//Composer libraries
$loader = require_once 'vendor/autoload.php';

\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader([$loader, 'loadClass']);

Turns out the solution is quite straight forward.

lookbadgers
  • 988
  • 9
  • 31
2

The accepted answer provides a solution without giving any explaination regarding the failure.

The reason is simple. The default annotation loader which is provided by the Doctrine\Common\Annotations\AnnotationRegistry only handle PSR-0 namespaces, while the Symfony\Component\Validator\Constraints is a PSR-4 namespace. Thus, the loader fail to load the class. Registering the composer auloader with the AnnotationRegistry::registerLoader method solves the problem because that autoloader handle the PSR-4 namespaces.

You can refer to this question to get more detaits about PSR-0 and PSR-4 differences: What is the difference between PSR-0 and PSR-4?

Community
  • 1
  • 1
  • Since I stumbled upon this issue I'd like to add, that Doctrine by default does not autoload **any** annotations outside it's own library. Default annotation engine specifies a single file indicating which annotations can be used (so it's not really in issue with PSR-0 or PSR-4). See [Doctrine Configuration.php](https://github.com/doctrine/doctrine2/blob/6dcb97a/lib/Doctrine/ORM/Configuration.php#L154) – SteveB Aug 10 '16 at 07:42