user18419618
user18419618

Reputation: 41

Symfony get current User entity in controller

I'm beginner in Symfony (6.1) and sometimes I need to get the current User in my controllers.

The way I use for the moment is :

$user = $userRepository->find($this->getUser()->getId());

But they are a better way ?

Because $this->getUser() give me the UserInterface and I need the User entity. screenshot example

Thanks to read me

Upvotes: 0

Views: 6874

Answers (3)

Dirk J. Faber
Dirk J. Faber

Reputation: 4701

Using $this->getUser() will get you the current user (that implements UserInterface). The getUser() method lives in AbstractController.php that is part of the Symfony FrameworkBundle. You could extend this controller if you really want to change the getUser() method to not use the UserInterface, but I think it would be better to simply change the typehint of the function (setUser) you call (in your screenshot -please write this out next time-) to use the UserInterface. Something like this:

public function setUser(UserInterface $user) 
{
    //....
}

Edit: After consideration, thanks to Cerad's valid point below, it is probably best to use setUser(User $user) given that you might use another class that implements UserInterface. Then either use var annations to tell your IDE which class you use, like so:

/** @var User $user */
$user = $this->getUser();

Or extend AbstractController so that it has a getUser method with a User return type like so:

namespace App\Controller;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

class BaseController extends AbstractController
{
    protected function getUser(): ?User
    {
        if (!$this->container->has('security.token_storage')) {
            throw new \LogicException('The SecurityBundle is not registered in your application. Try running "composer require symfony/security-bundle".');
        }

        if (null === $token = $this->container->get('security.token_storage')->getToken()) {
            return null;
        }

        return $token->getUser();
    }
}

or maybe even better, like this:

/**
 * @return User|null
 */
protected function getUser(): ?UserInterface
{
    return parent::getUser();
}

Upvotes: 3

Cerad
Cerad

Reputation: 48865

I'm a bit puzzled by some of the other answers so it might be that I am the one who is confused. The basic problem is that getUser is typehinted to return an UserInterface but the actual User object is needed. My solution is to explicitly tell the IDE what getUser is actually returning:

use App\Entity\User; # or whetever the application defined user is

class MyController extends AbstractController 
{
    public function someMethod() 
    {
        /** @var User */
        $user = $this->getUser();

And everyone, especially the IDE, is happy.

Once again you need to do what is basically a typecast because the security system really only cares about the UserInterface and does not worry about anything else the user might have. Hence we have:

class AbstractController {
   protected function getUser(): ?UserInterface {

A bit off-topic but I am looking forward to the day when this bit of annotation is no longer needed and replace with something like:

    User $user = $this->getUser();

Upvotes: 1

Lubna Altungi
Lubna Altungi

Reputation: 92

You have many ways to get your current user, please try this one:

$creditCard= new creditCard();
$creditCard->setUser($this->getUser());

Or this one:

$creditCard= $this->get('security.token_storage')->getToken()->getUser();

Upvotes: 0

Related Questions