StofDoctrineExtensionsBundle icon indicating copy to clipboard operation
StofDoctrineExtensionsBundle copied to clipboard

Blameable and decoupled user entity and userinterface'd class

Open danaki opened this issue 5 years ago • 2 comments

Hi, I'm using decoupled Entity and Security user following this article https://stovepipe.systems/post/decoupling-your-security-user

Now my entity looks like:

class Batch {
// ....
    /**
     * @var User
     *
     * @Gedmo\Blameable(on="create")
     * @ORM\ManyToOne(targetEntity="User")
     */
    private $createdBy;
//...

where App\Entity\User is just an Entity and class App\Security\User\SecurityUser implements actual UserInterface.

Now, using Blameable, when I try to save the entity with the current user in related field, it produces error:

The class 'App\Security\User\SecurityUser' was not found in the chain configured namespaces App\Entity

Which is because of this line of code:

        if (null !== $token && $this->authorizationChecker->isGranted('IS_AUTHENTICATED_REMEMBERED')) {
            $this->blameableListener->setUserValue($token->getUser());
        }

$token->getUser() returns an object of class App\Security\User\SecurityUser not the Entity.

Can you please update the Blameable to inject and query Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface or use Symfony\Component\Security\Core\User\UserProviderInterface so that User entity'd be loaded from the database instead (of course if $token->getUser() returns not an entity).

danaki avatar Jan 06 '20 14:01 danaki

For those interested in workaround if this issue isn't be closed anytime soon:

<?php

namespace App\EventListener;

use App\Repository\UserRepository;
use Doctrine\Common\EventArgs;
use Gedmo\Exception\InvalidArgumentException;
use Gedmo\Blameable\BlameableListener as Base;
use Symfony\Component\Security\Core\User\UserInterface;

class BlameableListener extends Base
{
    protected function toUserEntity($args)
    {
        if ($this->user instanceof UserInterface) {
            $entityManager = $args->getEntityManager();
            $userRepository = $entityManager->getRepository("App\Entity\User");

            $this->user = $userRepository
                ->find($this->user->getId())
            ;
        }
    }

    public function onFlush(EventArgs $args)
    {
        $this->toUserEntity($args);
        parent::onFlush($args);
    }

    public function prePersist(EventArgs $args)
    {
        $this->toUserEntity($args);
        parent::prePersist($args);
    }
}

danaki avatar Jan 06 '20 14:01 danaki

Hi, @danaki Could you please perform a pull request?

antishov avatar Jan 10 '20 22:01 antishov