Search code examples
phpsymfonysymfony-2.7

Symfony: Decorating a service when user has x role


I have been looking for an answer to this question, but I can not seem to find it anywhere.

I have currently defined a decorator service that decorates the translator service. I however want to decorate the translator service only when the user has a certain role.

services.yml

services:
    app.my_translator_decorator:
        class: MyBundle\MyTranslatorDecorator
        decorates: translator
        arguments: ['@app.my_translator_decorator.inner']
        public:    false

MyTranslatorDecorator.php

class MyTranslatorDecorator {

    /**
     * @var TranslatorInterface
     */
    private $translator;

    /**
     * @param TranslatorInterface $translator
     */
    public function __construct(TranslatorInterface $translator)
    {
        $this->translator = $translator;
    }

    // more code...

}

Solution

  • The container is "compiled" before the runtime. You can't decorate a service depending of the context, it will always be decorated.

    However, in your decorator, you can add a guard clause to not execute your custom code if not necessary.

    Service definition:

    services:
        app.my_translator_decorator:
            class:     AppBundle\MyTranslatorDecorator
            decorates: translator
            arguments: ['@app.my_translator_decorator.inner', '@security.authorization_checker']
            public:    false
    

    Decorator:

    <?php
    
    namespace AppBundle;
    
    use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
    use Symfony\Component\Translation\TranslatorInterface;
    
    class MyTranslatorDecorator implements TranslatorInterface
    {
        private $translator;
        private $authorizationChecker;
    
        public function __construct(TranslatorInterface $translator, AuthorizationCheckerInterface $authorizationChecker)
        {
            $this->translator = $translator;
            $this->authorizationChecker = $authorizationChecker;
        }
    
        public function trans($id, array $parameters = [], $domain = null, $locale = null)
        {
            if (!$this->authorizationChecker->isGranted('ROLE_ADMIN')) {
                return $this->translator->trans($id, $parameters, $domain, $locale);
            }
    
            // return custom translation here
        }
    
        // implement other methods
    }