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 6 years ago • 2 comments

Hi, I'm using decoupled Entity and security user like it's described here https://stovepipe.systems/post/decoupling-your-security-user

The reason for that is that I want to keep domain separated following DDD principles.

Now my entity looks like:

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

while class 'App\Security\User\SecurityUser' implements actual UserInterface.

When I try to save the entity, it produces an 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. Is it possible to override this behavior introducing a configuration option?

danaki avatar Jan 02 '20 15:01 danaki

It is not possible without overriding BlameableListener, but additionaly you need compiler pass if you need to inject custom dependencies, for example using process function from your app kernel. You will need to inject them using setters instead of constructors because of endless loop:

    /**
     * You can modify the container here before it is dumped to PHP code.
     */
    public function process(ContainerBuilder $container): void
    {
        $container
            ->getDefinition('stof_doctrine_extensions.listener.blameable')
            ->addMethodCall('setEntityManager', [$container->getDefinition(EntityManagerInterface::class)])
        ;
    }

Custom blameable listener need to extend default class, example of it:

class BlameableListenerDecorator extends BlameableListener
{
    /**
     * @var EntityManagerInterface
     */
    private $em;

    public function setEntityManager(EntityManagerInterface $em): void
    {
        $this->em = $em;
    }

    public function setUserValue($user): void
    {
        if ($user instanceof CustomUser) {
            $user = $this->em->find(UserEntity::class, $user->getId());
        }

        parent::setUserValue($user);
    }
}

BTW Consider moving to supported fork https://github.com/antishov/StofDoctrineExtensionsBundle

mleczakm avatar Jan 03 '20 23:01 mleczakm

Didn't know about the fork. Ok, I'll reopen this issue there.

danaki avatar Jan 06 '20 13:01 danaki