symfony получение дополнительных методов пользователя из сессии в AbstractController

Примечание: проверено на Symfony 7

Задача

Есть класс контроллера:

namespace App\Controller;

// ...

use App\Entity\Post;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[Route('/post')]
class PostController extends AbstractController
{
    // ...
 
    #[IsGranted('ROLE_USER')]
    #[Route('/new', name: 'app_post_new', methods: 'POST')]
    public function new(Request $request): Response
    {
        $post = new Post();

        // ...

        $post->setUserId($this->getUser()->getId());

        // ...

    }
}

Есть сущность пользователя:

namespace MyNamespace;

use Symfony\Component\Security\Core\User\UserInterface;

class User implements UserInterface
{
    private $id;
    
    private $username;

    private $roles = [];

    public function getId(): int
    {
        return $this->id;
    }

    // ...

}

В методе new() контроллера PostController, строке 22, мы хотим установить id авторизованного пользователя, автора поста. Такой код работает, но IDE подсвечивает getId() в этой строке как ошибку и выводит сообщение наподобие "Undefined method 'getId'." Если перейти к объявлению метода getUser() абстрактного контроллера, то увидим, что тип возвращаемого значения ?UserInterface. UserInterface содержит только 3 метода: getRoles(), eraseCredentials() и getUserIdentifier(). Они будут доступны в подсказках IDE при вводе $this->getUser()->... в строке 22 контроллера PostController. UserInterface не содержит метода getId(), из-за чего и выдается ошибка в IDE.

Варианты решения

Решение 1

В пользоватетельский PostController добавить в зависимости атрибут CurrentUser и класс пользователя:

use MyNamespace\User;
use Symfony\Component\Security\Http\Attribute\CurrentUser;

Далее изменить метод new():

    #[IsGranted('ROLE_USER')]
    #[Route('/new', name: 'app_post_new', methods: 'POST')]
    public function new(Request $request, #[CurrentUser] User $user): Response
    {
        $post = new Post();

        // ...

        $post->setUserId($user->getId());

        // ...

    }

Решение 2

В PostController добавить в зависимости класс пользователя:

use MyNamespace\User;

и добавить аннотацию:

/**
* @method User getUser()
*/
#[Route('/post')]
class PostController extends AbstractController
{
    // ...
}

которая заменяет тип возвращаемого значения встроенного метода getUser() контроллера AbstractController.
Возможен и дугой вариант такого решения - создать дополнительный контроллер, например:

namespace App\Controller;

use MyNamespace\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

/**
* @method User getUser()
*/
class BaseController extends AbstractController
{
}

Далее наследовать свои контроллеры от BaseController вместо AbstractController.

Источники

Key Words for FKN + antitotal forum (CS VSU):