Description
Description
Hello,
I am having some issue to extends the validator.expression_language
service with new expression. I hope I didn't miss how to do that in the documentation somewhere. 🤔
I am trying to use the When
constraint and my expression would be count(this.getParent()["suppliers"].getData()) == 1
. (let me know if there is a better way as my form is not mapped to a class, there is not information in the documentation about that case)
The count
function does not exist in the validator.expression_language
context. So I created a compiler pass in order to add it:
$container->getDefinition('validator.expression_language')
->addMethodCall('registerProvider', [new Reference(ArrayCountExpression::class)]);
Would it be nice to be able to tag the service like #[ValidatorExpressionFunctionProvider]
or something like that to be able to extends le validator language. It might be interesting to add that to the security language too? 🤔
We could imagine an improvement with interface to implement like
interface ValidatorExpressionFunctionInterface
{
public function compiler($str): string;
public function evaluator($arguments, $str);
}
Each services implementing this interface would be added to the validator expression language interpreter.
Example
<?php
namespace App\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
use Symfony\Component\ExpressionLanguage\SyntaxError;
#[ValidatorExpressionFunctionProvider]
class ArrayCountExpression implements ExpressionFunctionProviderInterface
{
public function getFunctions(): array
{
return [
// I know, wrong example, but you get the idea ;-)
new ExpressionFunction('count', function ($array): int {
return sprintf('count(%1$s)', $array);
}, function ($arguments, $array): int {
if (!is_array($array)) {
// I know, wrong exception... :-)
throw new SyntaxError('The argument passed to count is not an array.');
}
return \count($array);
}),
];
}
}