3 * Copyright (C) 2003-2004 Polytechnique.org
4 * http://opensource.polytechnique.org/
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /** A class for viewing user activity.
23 * Allows the examination of user sessions. Can produce a list of sessions
24 * matching by date, user, or authentication method, and can drill down to
25 * a detailed list of actions performed in a session.
27 * TODO: give an example of how to use the class
29 class DiogenesLoggerView
{
30 /** Handle to the database.
36 function DiogenesLoggerView()
39 if (!is_object($globals->db
))
40 die("\$globals->db is not an object!");
41 $this->dbh
=& $globals->db
;
45 /** Retrieves the available authentication mechanisms.
46 * There are several different ways of authenticating users to diogenes,
47 * including doing it ourselves, and delegating the task to an external
48 * mechanism. This method gets the list of permissable methods.
50 * @return assoc array of (method => label) pairs.
57 // give a 'no filter' option
58 $auths[0] = __("all");
60 $res = $this->dbh
->query("describe {$globals->table_log_sessions} auth");
61 list(,$type) = mysql_fetch_row($res);
62 mysql_free_result($res);
63 $types = preg_split("/(enum\\('|','|'\\))/", $type, -1, PREG_SPLIT_NO_EMPTY
);
64 foreach ($types as $type)
65 $auths[$type] = isset($globals->tlabel
[$type]) ?
$globals->tlabel
[$type] : $type;
70 /** Retrieves the available days for a given year and month.
71 * Obtain a list of days of the given month in the given year
72 * that are within the range of dates that we have log entries for.
75 * @param integer month
76 * @return array days in that month we have log entries covering.
79 function _getDays($year,$month)
83 // give a 'no filter' option
86 if ($year && $month) {
87 $day_max = Array(-1, 31,checkdate(2,29,$year) ?
29 : 28 ,31,30,31,30,31,31,30,31,30,31);
88 $res = $this->dbh
->query("SELECT YEAR (MAX(start)), YEAR (MIN(start)),
89 MONTH(MAX(start)), MONTH(MIN(start)),
90 DAYOFMONTH(MAX(start)),
91 DAYOFMONTH(MIN(start))
92 FROM {$globals->table_log_sessions}");
93 list($ymax,$ymin,$mmax,$mmin,$dmax,$dmin) = mysql_fetch_row($res);
94 mysql_free_result($res);
96 if (($year < $ymin) ||
($year == $ymin && $month < $mmin))
101 if (($year > $ymax) ||
($year == $ymax && $month > $mmax))
106 $min = ($year==$ymin && $month==$mmin) ?
intval($dmin) : 1;
107 $max = ($year==$ymax && $month==$mmax) ?
intval($dmax) : $day_max[$month];
109 for($i = $min; $i<=$max; $i++
)
116 /** Retrieves the available months for a given year.
117 * Obtains a list of month numbers that are within the timeframe that
118 * we have log entries for.
120 * @param integer year
121 * @return array List of month numbers we have log info for.
124 function _getMonths($year)
128 // give a 'no filter' option
129 $months[0] = __("all");
132 $res = $this->dbh
->query("SELECT YEAR (MAX(start)), YEAR (MIN(start)),
133 MONTH(MAX(start)), MONTH(MIN(start))
134 FROM {$globals->table_log_sessions}");
135 list($ymax,$ymin,$mmax,$mmin) = mysql_fetch_row($res);
136 mysql_free_result($res);
138 if (($year < $ymin) ||
($year > $ymax))
143 $min = $year == $ymin ?
intval($mmin) : 1;
144 $max = $year == $ymax ?
intval($mmax) : 12;
146 for($i = $min; $i<=$max; $i++
)
153 /** Retrieves the username for a given authentication method and user id.
154 * This function caches the results of the lookups to avoid uncecessary
157 * @return the matching username.
160 function _getUsername($auth, $uid) {
164 if (!isset($cache[$auth][$uid]))
165 $cache[$auth][$uid] = call_user_func(array($globals->session
,'getUsername'),$auth,$uid);
167 return $cache[$auth][$uid];
171 /** Retrieves the available years.
172 * Obtains a list of years that we have log entries covering.
174 * @return array years we have log entries for.
181 // give a 'no filter' option
182 $years[0] = __("all");
184 // retrieve available years
185 $res = $this->dbh
->query("select YEAR(MAX(start)),YEAR(MIN(start)) FROM {$globals->table_log_sessions}");
186 list($max,$min) = mysql_fetch_row($res);
187 mysql_free_result($res);
189 for($i = intval($min); $i<=$max; $i++
)
195 /** Make a where clause to get a user's sessions.
196 * Prepare the where clause request that will retrieve the sessions.
198 * @param $year INTEGER Only get log entries made during the given year.
199 * @param $month INTEGER Only get log entries made during the given month.
200 * @param $day INTEGER Only get log entries made during the given day.
201 * @param $auth INTEGER Only get log entries with the given authentication type.
202 * @param $uid INTEGER Only get log entries referring to the given user ID.
204 * @return STRING the WHERE clause of a query, including the 'WHERE' keyword
207 function _makeWhere($year,$month,$day,$auth,$uid)
211 // start constructing the "where" clause
215 array_push($where, "auth='$auth'");
218 array_push($where, "uid='$uid'");
220 // we were given at least a year
223 $dmin = mktime(0, 0, 0, $month, $day, $year);
224 $dmax = mktime(0, 0, 0, $month, $day+
1,$year);
226 $dmin = mktime(0, 0, 0, $month, 1, $year);
227 $dmax = mktime(0, 0, 0, $month+
1, 1, $year);
229 $dmin = mktime(0, 0, 0, 1, 1, $year);
230 $dmax = mktime(0, 0, 0, 1, 1, $year+
1);
232 $where[] = "start >= " . date("Ymd000000",$dmin);
233 $where[] = "start < " . date("Ymd000000", $dmax);
237 return ' WHERE ' . implode($where," AND ");
240 // WE know it's totally reversed, so better use array_reverse than a SORT BY start DESC
244 /** Run the log viewer and fill out the Smarty variables for display.
246 * @param page the page that will display the viewer's data
247 * @param outputvar the Smarty variable to which we should assign the output
248 * @param template the template to use for display
250 function run(&$page,$outputvar='',$template='')
254 if (isset($_REQUEST['logsess'])) {
256 // we are viewing a session
257 $res=$this->dbh
->query("SELECT host,ip,browser,auth,uid,sauth,suid
258 FROM {$globals->table_log_sessions}
259 WHERE id =".$_REQUEST['logsess']);
260 $sarr = mysql_fetch_assoc($res);
262 $sarr['username'] = $this->_getUsername($sarr['auth'],$sarr['uid']);
264 $sarr['suer'] = $this->_getUsername($sarr['sauth'],$sarr['suid']);
265 $page->assign('session',$sarr);
267 $res=$this->dbh
->query("SELECT a.text,e.data,UNIX_TIMESTAMP(e.stamp) AS stamp
268 FROM {$globals->table_log_events} AS e
269 LEFT JOIN {$globals->table_log_actions} AS a ON e.action=a.id
270 WHERE e.session='{$_REQUEST['logsess']}'");
271 while ($myarr = mysql_fetch_assoc($res))
272 $page->append('events',$myarr);
273 mysql_free_result($res);
277 // we are browsing the available sessions
278 $logauth = isset($_REQUEST['logauth']) ?
$_REQUEST['logauth'] : '';
279 $loguser = isset($_REQUEST['loguser']) ?
$_REQUEST['loguser'] : '';
280 $loguid = ($logauth && $loguser)?
call_user_func(array($globals->session
,'getUserId'),$logauth,$_REQUEST['loguser']) : '';
281 if (!$loguid) $loguser = '';
284 $year = isset($_REQUEST['year']) ?
$_REQUEST['year'] : 0;
285 $month = isset($_REQUEST['month']) ?
$_REQUEST['month'] : 0;
286 $day = isset($_REQUEST['day']) ?
$_REQUEST['day'] : 0;
288 $year = isset($_REQUEST['year']) ?
$_REQUEST['year'] : date("Y");
289 $month = isset($_REQUEST['month']) ?
$_REQUEST['month'] : date("m");
290 $day = isset($_REQUEST['day']) ?
$_REQUEST['day'] : date("d");
293 if (!$year) $month = 0;
294 if (!$month) $day = 0;
296 // smarty assignments
297 // retrieve available years
298 $page->assign('years',$this->_getYears());
299 $page->assign('year',$year);
301 // retrieve available months for the current year
302 $page->assign('months',$this->_getMonths($year));
303 $page->assign('month',$month);
305 // retrieve available days for the current year and month
306 $page->assign('days',$this->_getDays($year,$month));
307 $page->assign('day',$day);
309 // retrieve available auths
310 $auths = $this->_getAuths();
311 $page->assign('auths',$auths);
313 $page->assign('logauth',$logauth);
314 $page->assign('loguser',$loguser);
315 // smarty assignments
317 if($loguid ||
$year) {
319 // get the requested sessions
320 $where = $this->_makeWhere($year,$month,$day,$logauth,$loguid);
321 $select = "SELECT id,UNIX_TIMESTAMP(start) as start,auth,uid
322 FROM {$globals->table_log_sessions} AS s
324 ORDER BY start DESC";
325 $res = $globals->db
->query($select);
328 while ( $mysess = mysql_fetch_assoc($res) ) {
329 $mysess['username'] = $this->_getUsername($mysess['auth'],$mysess['uid']);
330 // pretty label for auth method
331 $mysess['lauth'] = $auths[$mysess['auth']];
333 $mysess['events'] = array();
335 $mysess['actions'] = array(
336 array(__("view session"),"?logsess={$mysess['id']}"),
337 array(__("user's log"),"?logauth={$mysess['auth']}&loguser={$mysess['username']}")
340 $sessions[$mysess['id']] = $mysess;
342 mysql_free_result($res);
343 array_reverse($sessions);
346 $sql = "SELECT s.id, a.text
347 FROM {$globals->table_log_sessions} AS s
348 LEFT JOIN {$globals->table_log_events} AS e ON(e.session=s.id)
349 INNER JOIN {$globals->table_log_actions} AS a ON(a.id=e.action)
352 $res = $globals->db
->query($sql);
353 while( $event = mysql_fetch_assoc($res) ) {
354 array_push($sessions[$event['id']]['events'],$event['text']);
356 mysql_free_result($res);
357 $page->assign_by_ref('sessions',$sessions);
359 $page->assign('msg_nofilters', __("Please select a year and/or a user."));
364 $page->assign('msg_session_properties', __("session properties"));
365 $page->assign('msg_user', __("user"));
366 $page->assign('msg_host', __("host"));
367 $page->assign('msg_browser', __("browser"));
368 $page->assign('msg_date', __("date"));
369 $page->assign('msg_action', __("action"));
370 $page->assign('msg_data', __("data"));
371 $page->assign('msg_filter_by', __("filter by"));
372 $page->assign('msg_start', __("start"));
373 $page->assign('msg_summary', __("summary"));
374 $page->assign('msg_actions', __("actions"));
375 $page->assign('msg_year', __("year"));
376 $page->assign('msg_month', __("month"));
377 $page->assign('msg_day', __("day"));
378 $page->assign('msg_submit', __("Submit"));
380 // if requested, assign the content to be displayed
381 if (!empty($outputvar)) {
382 if (empty($template))
383 $template = $globals->libroot
."/templates/logger-view.tpl";
384 $page->assign($outputvar, $page->fetch($template));