1

I want to get current logged user in form event but for some reason I can't get it to work.

I used services to inject token_storage and create constructor method to fetch token storage instance but I got error right at constructor:

Type error: Argument 1 passed to AdminBundle\Form\EventListener\CompanyFieldSubscriber::__construct() must implement interface Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface, none given

I am not sure what is the problem and how to fix it. Does someone knows where is the problem?

EDIT 1:

I think that I found out where is the problem but I can't find "good" solution. I call this event in form type in this way:

->addEventSubscriber(new CompanyFieldSubscriber());

Problem is that I am not using 'service/dependency injection' to create event and I am sending nothing to constructor. That's why I have this error (not 100% sure to be hones).

Since I have around 20-30 forms and new forms will come in time I need to create service for each form that requires user (or token_storage) instance and as a argument call token_storage or this event subscriber as a argument of service.

I know that it will work if I create each form as a service and pass required data as arguments but is there way to process this "automatically" without creating new service for every form that needs to have some user data interaction in form events?

EDIT 2:

As suggested I tried to change event subscriber constructor but I got same error with different class name.

New code:

use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;

public function __construct(TokenStorage $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
    }

New error:

Type error: Argument 1 passed to AdminBundle\Form\EventListener\CompanyFieldSubscriber::__construct() must be an instance of Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage, none given

This is code I am using:

Services:

admin.form.event_listener.company:
    class:  AdminBundle\Form\EventListener\CompanyFieldSubscriber
    arguments: ['@security.token_storage']
    tags:
        - { name: form.event_listener }

Event Listener:

namespace AdminBundle\Form\EventListener;

use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class CompanyFieldSubscriber implements EventSubscriberInterface
{
    private $tokenStorage;

    private $user;

    public function __construct(TokenStorageInterface $tokenStorage)
    {
        $this->tokenStorage = $tokenStorage;
        $this->user = $this->tokenStorage->getToken()->getUser();
    }

    public static function getSubscribedEvents()
    {
        return [
            FormEvents::PRE_SET_DATA => 'preSetData',
            FormEvents::PRE_SUBMIT => 'preSubmitData',

        ];
    }

    public function preSetData(FormEvent $event)
    {

        $form = $event->getForm();

        if (in_array("ROLE_SUPER_ADMIN", $this->user->getRoles())) {
            $form->add('company', EntityType::class, [
                'class' => 'AppBundle:Company',
                'choice_label' => 'name'
            ]);
        }
    }

    public function preSubmitData(FormEvent $event)
    {

        $form = $event->getForm();
        $bus = $form->getData();


        if (!in_array("ROLE_SUPER_ADMIN", $this->user->getRoles())) {
            $bus->setCompany($this->user->getCompany());

        }
    }
}
user2496520
  • 881
  • 4
  • 13
  • 36

2 Answers2

0

You call subscriber in wrong way when you use:

new CompanyFieldSubscriber()

You do not pass TokenStorageInterface to subscriber constructor. Call it as a service, if it is in controller then:

->addEventSubscriber($this->get('admin.form.event_listener.company'));

if it is in form than pass from controller to form

$this->get('admin.form.event_listener.company') 

as option and then use it in form

Eimsas
  • 492
  • 6
  • 21
  • Thank you for your comment @Eimsas . I will try your code but I am not sure that problem is there. I followed tutorial on symfony website and they inject current logged user same way I inject but they do that in form type. – user2496520 May 25 '17 at 06:21
  • everything is ok with injection, you just use wrong object, you use interface instead of token storage itself – Eimsas May 25 '17 at 06:23
  • I tried your code and same error shows up with different class name error. I think that problem lies in calling event subrsivber. Will update my original question to provide more info – user2496520 May 25 '17 at 06:25
  • NO problem is with token storage read the error: "must implement interface Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface, none given" in the services.yml you inject Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage and in the Subscriber you use use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; Maybe you forgot to change in constructor from TokenStorageInterface to TokenStorage – Eimsas May 25 '17 at 06:32
  • I used new code you provided and same error pops up with different class name . Check my updated post. I think that it will be more clear now. Also, thank you for your time. – user2496520 May 25 '17 at 06:40
  • In your updated answer I still see use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; – Eimsas May 25 '17 at 06:40
  • Eimsas sorry I didn't provided code you suggested. I edited my post with code you provide and with new error message. – user2496520 May 25 '17 at 06:46
0

for Symfony >= 4

use Symfony\Component\Security\Core\Security;

class ExampleService
{
    private $security;

    public function __construct(Security $security)
    {
        $this->security = $security;
    }

    public function someMethod()
    {
        $user = $this->security->getUser();
    }
}

See doc: https://symfony.com/doc/current/security.html#fetching-the-user-from-a-service

Serhii Vasko
  • 383
  • 4
  • 11