Keeping track of users/guests

On the one hand, there is piwik and other tracking tools. But they usually only track "total users per day".
If you want to track users in real time, you can easily set up something yourself.

We need to set up a model + controller + views for "online_activities".
In the admin backend we can then track the users currently online – and where they are.

The sql table could look like:

CREATE TABLE IF NOT EXISTS `online_activities` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `session_id` varchar(64) collate utf8_unicode_ci NOT NULL,
  `user_id` int(10) unsigned NOT NULL default '0',
  `created` datetime NOT NULL,
  `modified` datetime NOT NULL,
  `ip` varchar(39) collate utf8_unicode_ci NOT NULL,
  `host` varchar(128) collate utf8_unicode_ci NOT NULL,
  `last_page_url` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'last page user has been visiting',
  `agent` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'browser',
  `clicked_from` varchar(255) collate utf8_unicode_ci NOT NULL COMMENT 'referer',
  PRIMARY KEY  (`id`),
  KEY `user_id` (`user_id`)
);

Be aware that it can be prohibited in some countries to log ip/host etc.

You need then to create an update method in your model using session_id() as identifier.
If you track logged in users as well, i would also make sure rows with several browsers (and therefore different session_ids() would not count twice. They should then have the same user_id.
Similar, it is with bots (the session_id() changes all the time, the ip/host should stay the same, though).

public function update($where = null, $from = null) {
    $where = '/'.$where; # from(=referer) has already one / at the beginning
    if ($where === '//') { # the homepage would just be /
        $where = '/';
    }
    ...
    $record = $this->find('first', array('conditions'=>array('session_id'=>session_id())));
    if (empty($record)) {
        # new entry
        ...
    } else {
        # update existing one
        ...
    }
}

I have a highly customized method, so its not much of use to display it here. I am sure you can come up with the missing lines of code.

Finally:
This little piece of code should be in the beforeRender() method:

$this->OnlineActivity->update($this->params['url']['url'], $this->referer());

Display users as online

You can easily query the users that are currently online (last activity < 1 min) for example.
For low traffic sites you could also combine the above update() method with AJAX posts every few seconds – this way you could also tell if the person has the website still open (activity < x seconds). This is not a good approach for high traffic websites, though.

Final remarks

Don’t forget to clean the table every now and then. Depending on the traffic it can grow very very fast.

2 Comments

  1. I think the

     if (empty($user))

    should be

     if (empty($record))

    instead, because of

     $record = $this->find...

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.