I already created a provider with a security function. Following the doc, i created my own ExpressionLanguage class and registered the provider.
namespace AppBundle\ExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
class ExpressionLanguage extends BaseExpressionLanguage
{
public function __construct(ParserCacheInterface $parser = null, array $providers = array())
{
// prepend the default provider to let users override it easily
array_unshift($providers, new AppExpressionLanguageProvider());
parent::__construct($parser, $providers);
}
}
I'm using the same function lowercase
that is in the doc. But now, i have no ideia how to register the ExpressionLanguage class to be loaded in my Symfony project.
I get this error every time i try to load a page with the custom function in the annotation:
The function "lowercase" does not exist around position 26.
I'm using Symfony 2.7.5.
The tag security.expression_language_provider
is only used to add language providers to the expression language used in symfonys security component, or more specifically in the ExpressionVoter.
The @Security-Annotation of the FrameworkBundle uses a different instance of the expression language, which has no knowledge of the language providers you created.
To be able to use custom language providers in the @Security-Annotation, I solved this using the following compiler pass:
<?php
namespace ApiBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Reference;
/**
* This compiler pass adds language providers tagged
* with security.expression_language_provider to the
* expression language used in the framework extra bundle.
*
* This allows to use custom expression language functions
* in the @Security-Annotation.
*
* Symfony\Bundle\FrameworkBundle\DependencyInection\Compiler\AddExpressionLanguageProvidersPass
* does the same, but only for the security.expression_language
* which is used in the ExpressionVoter.
*/
class AddExpressionLanguageProvidersPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if ($container->has('sensio_framework_extra.security.expression_language')) {
$definition = $container->findDefinition('sensio_framework_extra.security.expression_language');
foreach ($container->findTaggedServiceIds('security.expression_language_provider') as $id => $attributes) {
$definition->addMethodCall('registerProvider', array(new Reference($id)));
}
}
}
}
This way, the expression languages used by the ExpressionVoter and FrameworkBundle are both configured using the same language providers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With