Symfony3 - How to activate validation.yml

Hello,

While validation through annotations works fine, I can’t activate validation through validation.yml file.

In my app/config/config.yml, I changed this line :

framework:
    validation:      { enabled: true, enable_annotations: false }

My src/AppBundle/Entity/TaskSetClass.php will call the validator:

use Symfony\Component\Validator\Constraints as Assert;

My src/AppBundle/Resources/config/validation.yml is :

# src/AppBundle/Resources/config/validation.yml
AppBundle\Entity\TaskSetClass:
    properties:
        taskName:
            - NotBlank: ~
        dueDate:
            - NotBlank: ~
            - Type: \DateTime

I emptied the cache, restarted symfony, nope. Nearly all tutorials will use annotations. Did anyone encountered this issue ?

Best regards,

MC

Tried this solution : http://stackoverflow.com/questions/26159910/symfony-2-validation-yml-has-no-effect along with this doc : http://symfony.com/doc/current/bundles/extension.html

Added a app/src/Appbundle/DependencyInjection/AppExtension.php file :

<?php
// src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
/* */
class AppExtension extends Extension
	{
	public function load(array $configs, ContainerBuilder $container)
		{
		// Services
		$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../../Resources/config'));
		$loader->load('services.yml');
		// Validation
		$yamlMappingFiles = $container->getParameter('validator.mapping.loader.yaml_files_loader.mapping_files');
		$yamlMappingFiles[] = __DIR__.'/../../Resources/config/validation.yml';
		$container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $yamlMappingFiles);
		}
	}

Now, when I try to submit an empty form, I have this error message :

ClassNotFoundException in AppExtension.php line 21: Attempted to load class “YamlFileLoader” from namespace “AppBundle\DependencyInjection\Loader”.
Did you forget a “use” statement for e.g. “Symfony\Component\Routing\Loader\YamlFileLoader”, “Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader”, “Symfony\Component\Validator\Mapping\Loader\YamlFileLoader”, “Symfony\Component\Translation\Loader\YamlFileLoader” or “Symfony\Component\DependencyInjection\Loader\YamlFileLoader”?

… Still, I use the correct file :

use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader;

Not trying to be overly snarky but your Symfony journey will be far more successful if you read the docs and follow the examples.

You are not snarky. I know snarks well, and I’m currently hunting one. The doc is not as helpful as it should be. I learn by mistakes, and I know others will benefit from them. Ad augusta per angusta.

However, in these pages https://gist.github.com/K-Phoen/6974497 and http://symfony.com/doc/current/components/dependency_injection.html, the authors used :

use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;

and then :

$loader = new YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));

Hence my confusion on the /YamlFileLoader + Loader\ parts.

The service part works fine now. But… another error message popped up :

ParameterNotFoundException in ParameterBag.php line 84: You have requested a non-existent parameter “validator.mapping.loader.yaml_files_loader.mapping_files”.

I rechecked the paths, added a line to build the container. The file is now

<?php
// src/AppBundle/DependencyInjection/AppExtension.php
namespace AppBundle\DependencyInjection;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\Config\FileLocator;
/* */
class AppExtension extends Extension
	{
	public function load(array $configs, ContainerBuilder $container)
		{
		$container = new ContainerBuilder();
		// Services
		$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../../../app/config'));
		$loader->load('services.yml');
		// Validation
		$yamlMappingFiles = $container->getParameter('validator.mapping.loader.yaml_files_loader.mapping_files');
		$yamlMappingFiles[] = __DIR__.'/../../../app/Resources/config/validation.yml';
		$container->setParameter('validator.mapping.loader.yaml_files_loader.mapping_files', $yamlMappingFiles);
		}
	}

I checked in $container, and no forementioned parameter (why ? Should there be one ? If so, why is it missing ? No useful google occurence of this parameter…), so I commented the getParameter line, and no more error message.

But still no validation. I got back to :

An exception occurred while executing ‘INSERT INTO tasks (task_name, task_due_date) VALUES (?, ?)’ with params [null, “2011-01-01 00:00:00”]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column ‘task_name’ cannot be null

So, no validation, the form is valid in any case… Puzzling.

In my form controller, I checked for errors with the validator (http://symfony.com/doc/current/validation.html)

                [...]
		if($form->isSubmitted())
			{
			if($form->isValid())
				{
				$validator = $this->get('validator');
				$errors = $validator->validate($taskSet);
				echo'<pre>';
				var_dump($errors);
				echo'</pre>';
				die();
                                [...]

No error shows up, so the validation.yml file is either not loaded, or ignored.

I checked if any constraint existed on my entity :

$metadata = $this->container
                 ->get('validator')
                 ->getMetadataFor('AppBundle\Entity\TaskSetClass');
echo'<pre>';
print_r($metadata);
echo'</pre>';
die();

It returned :

Symfony\Component\Validator\Mapping\ClassMetadata Object
(
    [name] => AppBundle\Entity\TaskSetClass
    [defaultGroup] => TaskSetClass
    [members] => Array
        (
        )

    [properties] => Array
        (
        )

    [getters] => Array
        (
        )

    [groupSequence] => Array
        (
        )

    [groupSequenceProvider] => 
    [traversalStrategy] => 1
    [reflClass:Symfony\Component\Validator\Mapping\ClassMetadata:private] => ReflectionClass Object
        (
            [name] => AppBundle\Entity\TaskSetClass
        )

    [constraints] => Array
        (
        )

    [constraintsByGroup] => Array
        (
        )

    [cascadingStrategy] => 1
)

So, no constraints are ever loaded, right ?

A dump of the container after loading the file in appExtension.php shows the command has succeeded :

	[parameterBag:protected] => Symfony\Component\DependencyInjection\ParameterBag\ParameterBag Object
		(
		[parameters:protected] => Array
			(
			[validator.mapping.loader.yaml_files_loader.mapping_files] => Array
				(
				[0] => /mnt/400Go/www/sy1/app/Resources/config/validation.yml
				)
			)
		[resolved:protected] => 
		)

So, loaded, but ignored.

You are making it too complicated. No need for dependency injection extensions for basic validations.

Make a fresh project. Follow the docs with the sample entity. Notice that there are often tabs in the documentation show you the yaml format. Get just this one entity working without adding anything else.

Once you have a working solution then you might be able to figure out what is going on in your current project.

Yes, the DependencyInjection part is a little overdone, but the whole project (less than 200 lines) works fine. The routing and the templates are ok. If I enter valid data in the form, I got them neat in the database table.

The sole issue is when I enter invalid data, namely leaving the name field empty. This break the constraint in the validation.yml, yet the form controller $form->isValid() regards the data as valid. Right after the isValid() test, if I perform a

$constraints = $this->get('validator')
                    ->getMetadataFor(TaskSetClass::class)
                    ->findConstraints('Default');
echo'<pre>Constraints : ';
print_r($constraints);
echo'</pre>';
die();

… the constrains array is empty.

Then, the data is sent by doctrine to the database. As the name field of the table (created via php bin/console doctrine:schema:update --force) is NOT NULL, mysql issues an error message.

Validation should work, but is ignored.

Thanks for your help anyway. Not always easy with messy newbies like me.

I got it working, but I can’t say I’m that proud of me.

My validation file is

# src/AppBundle/Resources/config/validation.yml
AppBundle\Entity\TaskSetClass:
    properties:
        taskName:
            - NotBlank: {message: "Please provide a task name."}
            - Type: string
        taskDueDate:
            - NotBlank: ~
            - Type: \DateTime

Except I had put it into /app/Resources/config…

Did I really lose two days of my 51th year on Earth due to that ? Yes, I did it.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.