Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony Twig Extension breaks other service - Is templating done before security?

I am working on a Symfony 2.7 WebApp. One of the bundles I created includes a service that offer some user related stuff, e.g. userHasPurchases().

Problem is, that including a Twig Extesion breaks another service:

AppShopService

namespace AppShopBundle\Service;

use AppBundle\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
...

class AppShopService {
    protected $user;

    public function __construct(TokenStorageInterface $tokenStorage, ...) {
        $this->user = $tokenStorage->getToken() ? $tokenStorage->getToken()->getUser() : null;
        ...
    }

    public function userHasPurchases(User $user) {
        $user = $user ? $user : $this->user;
        $result = $user...
        return result;
    }
}

AppShopBundle\Resources\config\services.yml

services:
    app_shop.service:
        class: AppShopBundle\Service\AppShopService
        arguments: 
            - "@security.token_storage"
            - ...

So far everything works fine: The AppShopServices is created with the current user and userHasPurchases() work as expected.

Now I have add a Twig Extension to be able to use userHasPurchases() within my templates:

Twig Extension

namespace AppShopBundle\Twig;

use AppShopBundle\Service\AppShopService;

class AppShopExtension extends \Twig_Extension {
    private $shopService;

    public function __construct(AppShopService $shopService) {
        $this->shopService = $shopService;
    }

    public function getName() {
        return 'app_shop_bundle_extension';
    }

    public function getFunctions() {
        $functions = array();

        $functions[] = new \Twig_SimpleFunction('userHasPurchases', array(
                $this,
                'userHasPurchases'
            ));

        return $functions;
    }

    public function userHasPurchases($user) {
        return $this->shopService->userHasPurchases($user);
    }
}

Including Extension in AppShopBundle\Resources\config\services.yml

services:
    app_shop.service:
        class: AppShopBundle\Service\AppShopService
        arguments: 
            - "@security.token_storage"
            - ...

    app_shop.twig_extension:
        class: AppShopBundle\Twig\AppShopExtension
        arguments: 
          - "@app_shop.service"
        tags:
          - { name: twig.extension }

After icluding the Twig Extension, AppShopService and its method userHasPurchases does not work any more. Problem is, that the constructor of AppShopService does not set user anymore since $tokenStorage->getToken() now returns null.

How is this possible? I have changed nothing except including the Twig Extension. As soon as I remove the Twig Extension from services.yml everything works correctly again.

My only guess is, that the creation fo the Twig Extension is done before any security. But why?

Any idea what might be wrong here?

like image 387
Andrei Herford Avatar asked Oct 19 '22 11:10

Andrei Herford


1 Answers

don't interact with the tokenStorage in the constructor but only in the userHasPurchases method.

namespace AppShopBundle\Service;

use AppBundle\Entity\User;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
...

class AppShopService {
    protected $tokenStorage;

    public function __construct(TokenStorageInterface $tokenStorage, ...) {
        $this->tokenStorage = $tokenStorage;
    }

    public function userHasPurchases(User $user) {
        $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
        $result = $user...
        return result;
    }
}

Hope this help

like image 165
Matteo Avatar answered Oct 21 '22 05:10

Matteo