Symfony2 : get security.context inside entity class

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-12 16:05:13

问题


Is it possible to get security.context inside an entity class?

I know the following doesn't work. I don't know how to implement the $user part.

/**
 * Set createdAt
 *
 * @ORM\PrePersist
 */
public function setCreatedAt()
{
    $user = $this->get('security.context')->getToken()->getUser();

    $this->owner = $user->getId();
    $this->createdAt = new \DateTime();
    $this->updatedAt = new \DateTime();
}

回答1:


For datetimes:

For the timestamps you are probably best of using the @hasLifeCycleCallback annotation and some additional methods marked as @prePersist and @preUpdate. For created you could even just do it in the __constructor itself.

Note that you must use @preUpdate for the $updatedAt property, @prePersist is only for new entities.

If you have a lot of entities that need this, you might consider a Doctrine2 listener to prevent repeated code.

For ownership properties:

If you always want to set the ownership of an entity to the "currently logged in user", you are probably best of using a Doctrine2 listener or subscriber. This way you don't have to add this logic to your controller, or wherever you need to create an entity.

http://symfony.com/doc/current/cookbook/doctrine/event_listeners_subscribers.html http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#onflush

Create a listener-service as documented, make sure it gets the security-context using the constructor. Set it to the event onFlush, this way you can adjust the entity just prior to actual saving. This is the best event to handle this kind of thing.

Make sure you follow the footnotes in the onFlush chapter on the Doctrine documentation, otherwise the last-minute-change won't be picked up by Doctrine.

Your listener should probably look something like:

class FlushExampleListener
{
    public function onFlush(OnFlushEventArgs $eventArgs)
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof YourClass) {
                // change owner
                $entity->setOwner($this->securityContext->getToken()->getUser());
                // tell doctrine you changed it
                $uow->recomputeSingleEntityChangeSet($em->getClassMetadata(get_class($entity)), $entity);
            }
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {
            if ($entity instanceof YourClass) {
                // change owner
                $entity->setOwner($this->securityContext->getToken()->getUser());
                // tell doctrine you changed it
                $uow->recomputeSingleEntityChangeSet($em->getClassMetadata(get_class($entity)), $entity);
            }
        }
    }
}

Please note that this does not check if a user is actually logged in...




回答2:


Indeed this is wrong.

Keep it simple, you want to set the owner of your entity when creating it? Pass it to your entity constructor and set it there.

Side note I'd recommend using a prePersist and preUpdate lifecycle callback to handle entity timestamps. This lib (php 5.4+) offers very easy set of tools to implement such features: https://github.com/KnpLabs/DoctrineBehaviors



来源:https://stackoverflow.com/questions/28421153/symfony2-get-security-context-inside-entity-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!