Home > Software engineering >  How can I use the current login user in a symfony form?
How can I use the current login user in a symfony form?

Time:01-30

I trying to do a form that use the login user to fill a EntityType and use it like the 'author'

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
    $builder
           ->add('Title')
            >add('Comment')
        ->add('Author', EntityType::class, [
        'class' => User::class,
        'choice_label' => ['name']
        ]);
    }

I tried to do it but I can't find the way to do it

CodePudding user response:

This can be done on the individual action basis, from your controller as mentioned by SubCore. However, if you want it always work automatically from anywhere you persist the entity use an event listener.

Here is one I used in a Symfony 4.4.8 project that sets the current user in an entity's createdBy/editedBy field:

namespace App\EventListener;

use App\Application\Sonata\UserBundle\Entity\User;
use App\Entity\CMSPage;
use Doctrine\Persistence\Event\LifecycleEventArgs;
use Symfony\Component\Security\Core\Security;

class CMSPageListener
{
  private $security;

  public function __construct(Security $security)
  {
    // Avoid calling getUser() in the constructor: auth may not
    // be complete yet. Instead, store the entire Security object.
    $this->security = $security;
  }

  // the entity listener methods receive two arguments:
  // the entity instance and the lifecycle event
  public function preUpdate(CMSPage $page, LifecycleEventArgs $event)
  {
    // returns User object or null if not authenticated
    $user = $this->fetchCurrentUser($event);

    $page
      ->setEditedBy($user)
      ->setUpdatedAt(new \DateTime())
    ;
  }

  public function prePersist(CMSPage $page, LifecycleEventArgs $event)
  {
    $now = new \DateTime();
    if (null === $page->getCreatedBy()) {
      $page->setCreatedBy($this->fetchCurrentUser($event));
    }
    $page
      ->setCreatedAt($now)
      ->setUpdatedAt($now)
    ;
  }

  public function fetchCurrentUser(LifecycleEventArgs $event)
  {
    // returns User object or null if not authenticated
    $coreUser = $this->security->getUser();
    /** @var User $user */
    $user = $event->getObjectManager()->getRepository(User::class)->findOneBy([
      'username' => $coreUser->getUsername(),
    ])
    ;

    return $user;
  }
}

And here is the config/services.yaml

    App\EventListener\CMSPageListener:
        tags:
            -
                # these are the basic options that define the entity listener
                name: 'doctrine.orm.entity_listener'
                event: 'preUpdate'
                entity: 'App\Entity\CMSPage'

                # set the 'lazy' option to TRUE to only instantiate listeners when they are used
                lazy: true

                # you can also associate an entity listener to a specific entity manager
                #entity_manager: 'custom'

                # by default, Symfony looks for a method called after the event (e.g. postUpdate())
                # if it doesn't exist, it tries to execute the '__invoke()' method, but you can
                # configure a custom method name with the 'method' option
                #method: 'checkUserChanges'
            - { name: 'doctrine.orm.entity_listener', event: 'prePersist', entity: 'App\Entity\CMSPage', lazy: true }
  • Related