1

I'm in a symfony 2.8 project. Another developer wrote a Voter to check if a user has the permissions or not for a specific task. I already use this function in a controller without problems but now I'm writing a service to get a dynamic menu and I don't know how to access to the method isGranted:

Error: Attempted to call an undefined method named "isGranted" of class.

namespace NameSpaceQuestion\Question\Service;

use Doctrine\ORM\EntityManager;

class MenuBuilder
{

    private $areasTools;
    public $menuItems = array();
    private $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function createMenuCourse($course,$mode,$user)
    {
        $repository = $this->em->getRepository('eBundle:AreasTools');
        $areas = $repository->findAll();
        //Retrieve every area from the db
        $itemsMenu = array();

        foreach ($areas as $area) {

            //If the user has permissions the area is included in the menu and proceed to check the tools that belong to the current area
            if($this->isGranted( $mode,$area,$user ) ){
                $itemsMenu[$area->getName()] = array();
                $toolsPerCourse = $this->em->getRepository('eBundle:CourseTool')->findByAreaToolAndCourse($area, $course);
                foreach ($toolsPerCourse as $toolCourse) {
                    //If the user has permissions the tool is included in the menu under the respective Area
                    if( ($this->isGranted( $mode,$toolCourse,$user ) )){
                        array_push($itemsMenu[$area->getName()], $toolCourse->getName());
                    }
                }

            }
        }

        return $itemsMenu;
    }
}
Stephan Vierkant
  • 9,674
  • 8
  • 61
  • 97
MC_
  • 13
  • 2
  • 3

2 Answers2

4

You'll have to use Dependency Injection to get the AuthorizationChecker in your MenuBuilder class. You can read about it here: http://symfony.com/doc/current/cookbook/security/securing_services.html

Because it looks like you're already injecting the EntityManager, just add the AuthorizationChecker to your code:

use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;

class MenuBuilder
{

    protected $authorizationChecker;

    public function __construct(EntityManager $em, AuthorizationCheckerInterface $authorizationChecker)
    {
        $this->authorizationChecker = $authorizationChecker;
        $this->em = $em;
    }

    function createMenuCourse()
    {
         if ( $this->authorizationChecker->isGranted('EDIT',$user) ) {
               //build menu
         }
    }
}
Community
  • 1
  • 1
Stephan Vierkant
  • 9,674
  • 8
  • 61
  • 97
1

First thing to understand is that the Symfony base controller has a number of helper functions such as isGranted implemented. But of course, if you are not inside of a controller then you don't have access to them. On the other hand, it's instructive to look at the base class and copy out the needed functionality.

The isGranted functionality relies on a authorization checker service which you will need to inject into your menu builder resulting in something like:

class MenuBuilder
{
    private $em;
    private $authorizationChecker;

    public function __construct(
        EntityManager $em, 
        $authorizationChecker // security.authorization_checker
    ) {
        $this->em = $em;
        $this->authorizationChecker = $authorizationChecker;
    }    
    protected function isGranted($attributes, $object = null)
    {
        return $this->authorizationChecker->isGranted($attributes, $object);
    }

Darn it. Stephan beat me by one minute. Must learn to type faster.

Cerad
  • 48,157
  • 8
  • 90
  • 92