Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Symfony2: SonataAdminBundle - How can i get the object representing the current user inside an admin class?

I use the sonata-admin bundle. I have the relationship with the user (FOSUserBundle) in the PageEntity. I want to save the current user which create or change a page.

My guess is get the user object in postUpdate and postPersist methods of the admin class and this object transmit in setUser method.

But how to realize this?

On the google's group I saw

    public function setSecurityContext($securityContext) {
        $this->securityContext = $securityContext;
    }

    public function getSecurityContext() {
        return $this->securityContext;
    }

    public function prePersist($article) {
        $user = $this->getSecurityContext()->getToken()->getUser();

        $appunto->setOperatore($user->getUsername());
    }

but this doesn't work

like image 346
user3342506 Avatar asked Feb 27 '14 13:02

user3342506


3 Answers

Starting with symfony 2.8, you should use security.token_storage instead of security.context to retrieve the user. Use constructor injection to get it in your admin:

public function __construct(
    $code,
    $class,
    $baseControllerName,
    TokenStorageInterface $tokenStorage
) {
    parent::__construct($code, $class, $baseControllerName);
    $this->tokenStorage = $tokenStorage;
}

admin.yml :

    arguments:
        - ~
        - Your\Entity
        - ~
        - '@security.token_storage'

then use $this->tokenStorage->getToken()->getUser() to get the current user.

like image 157
greg0ire Avatar answered Oct 20 '22 14:10

greg0ire


I was dealing with this issue on the version 5.3.10 of symfony and 4.2 of sonata. The answer from greg0ire was really helpful, also this info from symfony docs, here is my approach:

In my case I was trying to set a custom query based on a property from User.

// ... 
use Symfony\Component\Security\Core\Security;

final class YourClassAdmin extends from AbstractAdmin {
    // ... 
    private $security;
    public function __construct($code, $class, $baseControllerName, Security $security)
    {
        parent::__construct($code, $class, $baseControllerName);
        // Avoid calling getUser() in the constructor: auth may not
        // be complete yet. Instead, store the entire Security object.
        $this->security = $security;
    }

    // customize the query used to generate the list
    protected function configureQuery(ProxyQueryInterface $query): ProxyQueryInterface 
    {
        $query = parent::configureQuery($query);
        $rootAlias = current($query->getRootAliases());
        // ..
        $user = $this->security->getUser();
        // ...    
        return $query;
    }

}
like image 21
laviku Avatar answered Oct 20 '22 14:10

laviku


In the admin class you can get the current logged in user like this:

$this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser()

EDIT based on feedback

And you are doing it this? Because this should work.

 /**
     * {@inheritdoc}
     */
    public function prePersist($object)
    {

$user = $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser();
        $object->setUser($user);
    }

    /**
     * {@inheritdoc}
     */
    public function preUpdate($object)
    {
$user = $this->getConfigurationPool()->getContainer()->get('security.token_storage')->getToken()->getUser();
        $object->setUser($user);
    }
like image 27
Baba Yaga Avatar answered Oct 20 '22 14:10

Baba Yaga