Skip to content

Conversation

samuel4x4
Copy link

@samuel4x4 samuel4x4 commented Jan 9, 2017

It seems that Symfony 2.7 still needs an alias for the service declared for a custom constraint. Otherwise, it's not loaded as a service from the container, so the dependencies are not injected.

A. Failing example, without alias

Service declaration:

validator.custom_less_than:
    class: AppBundle\Validator\Constraints\CustomLessThanValidator
    arguments: ['@service_container']
    tags:
        - { name: validator.constraint_validator}

Constraint:

class CustomLessThan extends Constraint
{
	public $message = 'The value should be lett than "%lessThan%".';
}

Validator:

class CustomLessThanValidator extends ConstraintValidator 
{
	use ContainerAwareTrait;

	public function __construct(ContainerInterface $service_container)
	{
		$this->setContainer($service_container);
	}

	public function validate($value, Constraint $constraint)
	{
		$lessThanValue = $this->container->getParameter('less_than_value');
			   
		if ($value > $lessThanValue)
		{
			$this->context->buildViolation($constraint->message)
					->setParameter('%lessThan%', $lessThanValue)
					->addViolation();
		}
	}
}

Result:

Catchable Fatal Error: Argument 1 passed to AppBundle\Validator\Constraints\CustomLessThanValidator::__construct() must be an instance of Symfony\Component\DependencyInjection\Container, none given, called in vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory.php on line 71 and defined
500 Internal Server Error - ContextErrorException

B. Working example, using alias

Service declaration:

validator.custom_less_than:
    class: AppBundle\Validator\Constraints\CustomLessThanValidator
    arguments: ['@service_container']
    tags:
        - { name: validator.constraint_validator, alias: 'alias.validator.custom_less_than' }

Constraint:

class CustomLessThan extends Constraint
{
	public $message = 'The value should be lett than "%lessThan%".';

	public function validatedBy()
	{
		return 'alias.validator.custom_less_than';
	}
}

Validator:

class CustomLessThanValidator extends ConstraintValidator 
{
	use ContainerAwareTrait;

	public function __construct(ContainerInterface $service_container)
	{
		$this->setContainer($service_container);
	}

	public function validate($value, Constraint $constraint)
	{
		$lessThanValue = $this->container->getParameter('less_than_value');
			   
		if ($value > $lessThanValue)
		{
			$this->context->buildViolation($constraint->message)
					->setParameter('%lessThan%', $lessThanValue)
					->addViolation();
		}
	}
}

Result:

No exception, the field is validated, the constraint message is displayed, containing the parameters value taken from Container

It seems that Symfony 2.7 still needs an alias for the service declared for a custom constraints. Otherwise, it's not loaded as a service from the container, so the dependencies are not injected.
@xabbuh
Copy link
Member

xabbuh commented Jan 12, 2017

This should not be necessary. Can you show an minimal example that would fail without the alias?

@samuel4x4
Copy link
Author

Hi @xabbuh, please check the PR description, I put there some examples. Thanks.

@xabbuh
Copy link
Member

xabbuh commented Jan 12, 2017

@samuel4x4 Are your constraint and the validator in the same namespace? Could you fork the Symfony Standard Edition and make the changes that are needed to reproduce your issue?

@samuel4x4
Copy link
Author

Hi @xabbuh, I'm not sure I understand your request. I get that exception on my project based on Symfony 2.7.9 framework, as it is, nothing is changed on it. What should should I change if I fork it? Thanks.

@xabbuh
Copy link
Member

xabbuh commented Jan 13, 2017

Well, we do not have access to your project to reproduce your issue. But if you can take the default Symfony Standard Edition and make the changes that replicate the behaviour in your application, we should be able to help you. By the way, the displayed error message has been improved in more recent 2.7 releases. Maybe that can help you too.

@samuel4x4
Copy link
Author

Hi @xabbuh, I hoped the provided code lines will clarify the issue. If they're not enough, I'll create a project in on GitHub based on Symfony Standard Edition 2.7.9, then I'll create a simple form with a custom constraint that should replicate my issue.

@xabbuh
Copy link
Member

xabbuh commented Jan 17, 2017

@samuel4x4 Sorry, unfortunately it's not. So it would indeed be great if you could that.

@xabbuh
Copy link
Member

xabbuh commented Feb 10, 2017

@samuel4x4 Did you manage to get further with your issue?

@javiereguiluz
Copy link
Member

There's some confusion about this "alias" thing. See symfony/symfony#21610 for an explanation about this feature. I'm closing this as duplicated of #6610 which we're trying to fix in #7489. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants