Do something when user auto logout

Hi there,

i would like to set the user to offline on auto logout. Can anybody tell me how i can call a own function at auto logout the user? I hope you understand my problem.

Thank you for help.

Yii::$app->user->on(\yii\web\User::EVENT_BEFORE_LOGOUT, function($event){
    $user = $event->owner->identity;
    $user->status = 'offline';
    $user->save(false);
});
1 Like

Thank you very much Stefano for your help. This is very interesting.

I found another way for me. I store now the sessions in the DB and save the session id in the user table after login.

I have a look if the user session id is active or not. Then i show the actuelle user state in dashboard.

When you need to “Listen” to some events happening and respond to them, Yii have great support for events. You can even raise your own and catch them.

You can do the catching in config or even best in the Bootstrap

Thank you very much. I’ll take a look.

The solution with the sessions is not optimal because yii dosn’t delete old sessions from db table if the user close the browser without logout.

But i think the problem is the same with events. When the user closed the browser without logout, the event function can not called and the user stay online.

With the sessions in the db i can call a crontab-job who clean the db table. I can delete all sessions they inactive since 30 minutes or something.

Hello Stefano,

can you tell me, where must i insert the code? Is this in config/web.php like https://www.yiiframework.com/doc/guide/2.0/en/structure-applications#bootstrap

Thank you for your help.

I suspect there is a better way (some type of best practice I’m not following), but I like my event configuration centralized instead of distributed throughout models, etc. I have a file config/bootstrap-events.php that looks like this:

$eventConfigs = [
    /**
     * This allows us to replace our placeholders, e.g., #FIXED_APPOINTMENT_S#, with
     * the actual value.
     */
    [
        'class' => \yii\web\Response::class,
        'event' => \yii\web\Response::EVENT_AFTER_PREPARE,
        'handler' => \common\eventBus\listeners\RunOnResponseAfterPrepare::class,
    ],
    /**
     * Queue Events
     */
    [
        'class' => \yii\queue\Queue::class,
        'event' => \yii\queue\Queue::EVENT_BEFORE_EXEC,
        'handler' => \common\eventBus\listeners\RunQueueEventBeforeExec::class,
    ],
...
   ],
];

foreach ($eventConfigs as $eventConfig) {
    \yii\base\Event::on($eventConfig['class'], $eventConfig['event'], function ($event) use ($eventConfig) {
        (new $eventConfig['handler']())->handle($event);
    });
}

At the bottom of config/bootstrap.php, I have:

require_once 'bootstrap-events.php';

If somebody is reading this and what I’m doing is a bad idea, by all means let me know.

Sorry I was off the forum for some time. You create Boostrap class and then register events in there

<?php
namespace app\bootup;

class EventsBoostrap extends \yii\base\BootstrapInterface
{
    public function bootstrap($app)
    {
        $app->on(\yii\web\User::EVENT_BEFORE_LOGOUT, function($event){
            $user = $event->owner->identity;
            $user->status = 'offline';
            $user->save(false);
        });
    }
}


//config/web
$config = [
    'id' => 'basic',
    'name' => Yii::t('app', '{app} - Your Business Assistant', ['app' => 'Adiuta']),
    'basePath' => dirname(__DIR__),
    'bootstrap' => ['log', 'app\bootup\EventsBoostrap'],
];

I can’t even understand what you are doing. But have given an example above. Take a look at it!