How to use different controllers, depending on the user role, for the same route?

Nick :

I'm trying to implement multiple controllers which listens to one route /account.

There are two controllers and only one should be executed on that URL where the choice lies within user's role.

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');
    }
}

That's what I've got so far.

yivi :

You can't do this with "route" declarations, since the route listener is executed with higher priority than the security listener. Both happen during the KernelEvents::REQUEST event, but routing comes before firewall.

When the route to controller mapping is being resolved, you do not have yet user information (which is why you can't simply attach another a listener and inject the user information on the Request object, so it's available to use in the route declaration for expression matching, for example).

Basically, one route, one controller. If you want to have diverging logic for these users, you'll have to apply it after you get into the controller.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=11921&siteId=1