patspam
|
Date: 2/22/2007 7:28 pm · Subject: Re: Logged-in Time
I found it was easy to achieve if you add 2 extra columns to userLoginLog: a sessionId and a lastPageViewed timestamp. If you arrange for lastPageViewed to be updated on every request (as per lastPageView in userSession) then you can determine the length of any session. Here's my patch. I've bolded relevant sections where possible: 1. Add the extra columns to the database: alter table userLoginLog add column sessionId varchar(22); alter table userLoginLog add column lastPageViewed int(11);
2. Modify the _logLogin function in Auth.pm (starts at line 94) so that the sessionId and current time (for lastPageViewed) get written to userLoginLog at user login:
sub _logLogin { my $self = shift; $self->session->db->write("insert into userLoginLog values (?,?,?,?,?,?,?)", [ $_[0], $_[1], $self->session->datetime->time(), $self->session->env->getIp, $self->session->env->get("HTTP_USER_AGENT"), $self->session->getId, $self->session->datetime->time()] ); } 3. Add a single line to the www_viewLoginHistory function in Var.pm (at line 188) so that lastPageViewed gets updated: $session->db->write("update userLoginLog set lastPageViewed=? where sessionId=?", [$session->datetime->time(), $sessionId]);
4. Modify the www_viewLoginHistory function in LoginHistory (starts at line 36) to display sessionId, lastPageViewed and Session Length along with other data in table:
sub www_viewLoginHistory { my $session = shift; return $session->privilege->adminOnly() unless ($session->user->isInGroup(3)); my ($output, $p, @row, $i, $sth, %data); my $i18n = WebGUI::International->new($session); tie %data, 'Tie::CPHash'; $sth = $session->db->read("select * from users,userLoginLog where users.userId=userLoginLog.userId order by userLoginLog.timeStamp desc"); while (%data = $sth->hash) { $data{username} = $i18n->get('unknown user') if ($data{userId} eq "0"); $row[$i] = '<tr class="tableData"><td>'.$data{username}.' ('.$data{userId}.')</td>'; $row[$i] .= '<td>'.$data{status}.'</td>'; $row[$i] .= '<td>'.$session->datetime->epochToHuman($data{timeStamp},"%H:%n%p %M/%D/%y").'</td>'; $row[$i] .= '<td>'.$data{ipAddress}.'</td>'; $row[$i] .= '<td>'.$data{userAgent}.'</td>'; $row[$i] .= '<td>'.$data{sessionId}.'</td>'; if ($data{lastPageViewed}) { $row[$i] .= '<td>'.$session->datetime->epochToHuman($data{lastPageViewed},"%H:%n%p %M/%D/%y").'</td>'; my ($interval, $units) = $session->datetime->secondsToInterval($data{lastPageViewed} - $data{timeStamp}); $row[$i] .= "<td>$interval $units</td></tr>"; } else { $row[$i] .= "<td></td>"; $row[$i] .= "<td></td></tr>"; } $i++; } $sth->finish; $p = WebGUI::Paginator->new($session,$session->url->page('op=viewLoginHistory')); $p->setDataByArrayRef(\@row); $output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">'; $output .= '<tr class="tableHeader"><td>'.$i18n->get(428).'</td>'; $output .= '<td>'.$i18n->get(434).'</td>'; $output .= '<td>'.$i18n->get(429).'</td>'; $output .= '<td>'.$i18n->get(431).'</td>'; $output .= '<td>'.$i18n->get(433).'</td>'; $output .= '<td>Session ID</td>'; $output .= '<td>Last Page Viewed</td>'; $output .= '<td>Session Length</td></tr>'; $output .= $p->getPage($session->form->process("pn")); $output .= '</table>'; $output .= $p->getBar($session->form->process("pn")); return WebGUI::AdminConsole->new($session,"loginHistory")->render($output); }
5. Modify the www_listUsers function in User (starts at line 554) to output lastPageViewed and Session Length along with other data in table:
sub www_listUsers { my $session = shift; unless ($session->user->isInGroup(3)) { if ($session->user->isInGroup(11)) { return www_editUser($session, undef, "new"); } return $session->privilege->adminOnly(); } my %status; my $i18n = WebGUI::International->new($session); my $output = getUserSearchForm($session,"listUsers"); my ($userCount) = $session->db->quickArray("select count(*) from users"); return _submenu($session,{workarea => $output}) unless ($session->form->process("doit") || $userCount<250 || $session->form->process("pn") > 1); tie %status, 'Tie::IxHash'; %status = ( Active => $i18n->get(817), Deactivated => $i18n->get(818), Selfdestructed => $i18n->get(819) ); $output .= '<table border="1" cellpadding="5" cellspacing="0" align="center">'; $output .= '<tr> <td class="tableHeader">'.$i18n->get(816).'</td> <td class="tableHeader">'.$i18n->get(50).'</td> <td class="tableHeader">'.$i18n->get(56).'</td> <td class="tableHeader">'.$i18n->get(453).'</td> <td class="tableHeader">'.$i18n->get(454).'</td> <td class="tableHeader">'.$i18n->get(429).'</td> <td class="tableHeader">'.$i18n->get(434).'</td> <td class="tableHeader">Last Page Viewed</td> <td class="tableHeader">Session Length</td> </tr>'; my $p = doUserSearch($session,"listUsers",1); foreach my $data (@{$p->getPageData}) { $output .= '<tr class="tableData">'; $output .= '<td>'.$status{$data->{status}}.'</td>'; $output .= '<td><a href="'.$session->url->page('op=editUser;uid='.$data->{userId}) .'">'.$data->{username}.'</a></td>'; $output .= '<td class="tableData">'.$data->{email}.'</td>'; $output .= '<td class="tableData">'.$session->datetime->epochToHuman($data->{dateCreated},"%z").'</td>'; $output .= '<td class="tableData">'.$session->datetime->epochToHuman($data->{lastUpdated},"%z").'</td>'; my ($lastLoginStatus, $lastLogin, $lastPageViewed) = $session->db->quickArray("select status,timeStamp,lastPageViewed from userLoginLog where userId=".$session->db->quote($data->{userId})." order by timeStamp DESC"); if ($lastLogin) { $output .= '<td class="tableData">'.$session->datetime->epochToHuman($lastLogin).'</td>'; } else { $output .= '<td class="tableData"> - </td>'; } if ($lastLoginStatus) { $output .= '<td class="tableData">'.$lastLoginStatus.'</td>'; } else { $output .= '<td class="tableData"> - </td>'; } if ($lastPageViewed) { $output .= '<td class="tableData"> '.$session->datetime->epochToHuman($lastPageViewed).'</td>'; my ($interval, $units) = $session->datetime->secondsToInterval($lastPageViewed - $lastLogin); $output .= "<td class='tableData'>$interval $units</td></tr>"; } else { $output .= "<td class='tableData'> - </td>"; $output .= "<td class='tableData'> - </td></tr>"; } $output .= '</tr>'; } $output .= '</table>'; $p->setAlphabeticalKey('username'); $output .= $p->getBarTraditional; my $submenu = _submenu($session, { workarea => $output, help => "users manage" }); return $submenu; }
That's all. Some comments: - The session length information could be used in more places to display useful info such as totaly logged in time etc..
- It's worth pointing out that I haven't used i18n variables for the column headers.
- If you used this information to display total logged in time then you'd probably want to turn off the CleanLoginHistory workflow activity.
Cheers, Patrick
|