Как использовать разные контроллеры, в зависимости от роли пользователя, для одного и того же маршрута? - PullRequest
2 голосов
/ 25 февраля 2020

Я пытаюсь реализовать несколько контроллеров, которые прослушивают один маршрут /account.

Существует два контроллера, и только один из них должен быть выполнен для того URL, где выбор находится в пределах роли пользователя.

namespace AppBundle\Controller;

use AppBundle\Entity\Role;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;

/**
 * @Route("/account")
 */
abstract class DashboardController extends Controller
{
    protected $userRoles;

    public function __construct()
    {
        $this->userRoles = $this->getUser()->getRoles();
    }

    /**
     * Get all user roles
     */
    public function getRoles()
    {
        return $this->userRoles;
    }

    /**
     * Get user account type
     *
     * @return Role
     */
    public function getAccountType(): Role
    {
        $accountType = new Role();
        foreach ($this->userRoles as $role) {
            if(Role::ROLE_STUDENT == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_SCHOOL_REPRESENTATIVE == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_EMPLOYER == $role->getName()) {
                $accountType = $role;
            } else if(Role::ROLE_ADMIN == $role->getName()) {
                $accountType = $role;
            }
        }

        return $accountType;
    }
}
namespace AppBundle\Controller;

class CompanyDashboardController extends DashboardController
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @Route("/", name="dashboard_company_home", methods={"GET"})
     * @return Response
     */
    public function index()
    {
        return $this->render('dashboard/company/index.html.twig');
    }
}
namespace AppBundle\Controller;

class AdminDashboardController extends DashboardController
{

    public function __construct()
    {
        parent::__construct();
    }

    /**
     * @Route("/", name="dashboard_admin_home", methods={"GET"})
     * @return Response
     */
    public function index()
    {
        return $this->render('dashboard/admin/index.html.twig');
    }
}

Это то, что у меня так далеко.

1 Ответ

1 голос
/ 26 февраля 2020

Вы не можете сделать это с помощью объявлений "маршрута", поскольку прослушиватель маршрута выполняется с более высоким приоритетом, чем прослушиватель безопасности . И то, и другое происходит во время события KernelEvents::REQUEST, но маршрутизация происходит до брандмауэра.

Когда разрешается сопоставление маршрута с контроллером, у вас еще нет информации о пользователе (поэтому вы не можете просто присоединить другой слушатель и вводит пользовательскую информацию об объекте Request, поэтому его можно использовать в объявлении маршрута для выражения, соответствующего , например).

По сути, один маршрут, один контроллер. Если вы хотите иметь расходящиеся логи c для этих пользователей, вам придется применить их после того, как вы попадете в контроллер.

...