event-handlingzend-framework2zfcuser

capturing the login event in zendframework 2


I want to capture the loggin event in zendframework2 and then update the database when the user last logged in.

i am aware that if i do the following in the onBootstrap(MVCEvent $e) of my module i will be able to capture the event etc:

$eventManager = $e->getApplication()->getEventManager();
            $em           = $eventManager->getSharedManager();
            $em->attach(
                'ZfcUser\Authentication\Adapter\AdapterChain',
                'authenticate',
                function($e)
                {
                    $id = $e->getIdentity();

   }
            );

this will give me the Id of the user. however, the confusion is how i can then update my database from the bootstrap. i mean, i dont have access to the entity manager in my bootstrap and i am not sure how to transport it there. the entity manager is held in the service config file.

i.e getServiceConfig()

'Members\Model\WorkerTable' => function($sm) {
                    $db = $sm->get('doctrine.entitymanager.orm_default');
                    $table = new Model\MemberTable($db);
                    return $table;
                },   

.

with the above settings i am able to access the entity manager in my MemberTable class

so, a simple solution would be to transfer the loggin event manager to my ** MemberTable class** where i would use my entity manager to update the database.

issue, i am not sure how to set this up:

$eventManager = $e->getApplication()->getEventManager();
                $em           = $eventManager->getSharedManager();

i mean, i dont know how to get the variable $e into the MemberTable class so that i can access the eventManger and the sharedManager.

in summary; the issues are twofold.

  1. how do i get the entity manager into the bootstrap function

alternatively

  1. how do i get the eventManager and shared eventmanager into a normal class so that i can call the eventmanger in a class that already contains the entity manager

Solution

  • Well, all you have to do is to retrieve the service manager this way:

    $serviceManager = $e->getApplication()->getServiceManager();
    

    and then get your entity manager like this:

    $entityManager = $serviceManager->get('Members\Model\WorkerTable');
    

    Does it solve your problem?

    The answer to the second question

    To bring a variable into the closure from outside you can use "use" operator like so:

    function() use ($myVar){
        // some code
    }
    

    So, in your case I would do:

    $eventManager = $e->getApplication()->getEventManager();
            $em = $eventManager->getSharedManager();
            $em->attach(
                'ZfcUser\Authentication\Adapter\AdapterChain',
                'authenticate',
                function($e) use ($entityManager){
                    $id = $e->getIdentity();
    
                }
            );
    

    If you are planning to have a lot of code inside your closure I would suggest to put it into a separate class and make it invokable. For instance,

    class YourClosureCode
    {
        private $entityManager;
    
        public function __construct($eventManager)
        {
            $this->eventManager = $eventManager;
        }
    
        public function __invoke(EventInterface $e)
        {
           // put your closure code here
        }
    }
    

    Then a slight modification here:

     $eventManager = $e->getApplication()->getEventManager();
            $em = $eventManager->getSharedManager();
            $em->attach(
                'ZfcUser\Authentication\Adapter\AdapterChain',
                'authenticate',
                new YourClosureCode($entityManager);
            );