add a 'makePath' method to Diogenes_Barrel
[diogenes.git] / include / diogenes / diogenes.logger-view.inc.php
... / ...
CommitLineData
1<?php
2/*
3 * Copyright (C) 2003-2004 Polytechnique.org
4 * http://opensource.polytechnique.org/
5 *
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.
10 *
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.
15 *
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
19 */
20
21
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.
26 *
27 * TODO: give an example of how to use the class
28 */
29class DiogenesLoggerView {
30 /** Handle to the database.
31 */
32 var $dbh;
33
34 /** The constructor.
35 */
36 function DiogenesLoggerView()
37 {
38 global $globals;
39 if (!is_object($globals->db))
40 die("\$globals->db is not an object!");
41 $this->dbh =& $globals->db;
42 }
43
44
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.
49 *
50 * @return assoc array of (method => label) pairs.
51 * @private
52 */
53 function _getAuths()
54 {
55 global $globals;
56
57 // give a 'no filter' option
58 $auths[0] = __("all");
59
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;
66 return $auths;
67 }
68
69
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.
73 *
74 * @param integer year
75 * @param integer month
76 * @return array days in that month we have log entries covering.
77 * @private
78 */
79 function _getDays($year,$month)
80 {
81 global $globals;
82
83 // give a 'no filter' option
84 $days[0] = __("all");
85
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);
95
96 if (($year < $ymin) || ($year == $ymin && $month < $mmin))
97 {
98 return array();
99 }
100
101 if (($year > $ymax) || ($year == $ymax && $month > $mmax))
102 {
103 return array();
104 }
105
106 $min = ($year==$ymin && $month==$mmin) ? intval($dmin) : 1;
107 $max = ($year==$ymax && $month==$mmax) ? intval($dmax) : $day_max[$month];
108
109 for($i = $min; $i<=$max; $i++)
110 $days[$i] = $i;
111 }
112 return $days;
113 }
114
115
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.
119 *
120 * @param integer year
121 * @return array List of month numbers we have log info for.
122 * @private
123 */
124 function _getMonths($year)
125 {
126 global $globals;
127
128 // give a 'no filter' option
129 $months[0] = __("all");
130
131 if ($year) {
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);
137
138 if (($year < $ymin) || ($year > $ymax))
139 {
140 return array();
141 }
142
143 $min = $year == $ymin ? intval($mmin) : 1;
144 $max = $year == $ymax ? intval($mmax) : 12;
145
146 for($i = $min; $i<=$max; $i++)
147 $months[$i] = $i;
148 }
149 return $months;
150 }
151
152
153 /** Retrieves the username for a given authentication method and user id.
154 * This function caches the results of the lookups to avoid uncecessary
155 * database requests.
156 *
157 * @return the matching username.
158 * @private
159 */
160 function _getUsername($auth, $uid) {
161 global $globals;
162 static $cache;
163
164 if (!isset($cache[$auth][$uid]))
165 $cache[$auth][$uid] = call_user_func(array($globals->session,'getUsername'),$auth,$uid);
166
167 return $cache[$auth][$uid];
168 }
169
170
171 /** Retrieves the available years.
172 * Obtains a list of years that we have log entries covering.
173 *
174 * @return array years we have log entries for.
175 * @private
176 */
177 function _getYears()
178 {
179 global $globals;
180
181 // give a 'no filter' option
182 $years[0] = __("all");
183
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);
188
189 for($i = intval($min); $i<=$max; $i++)
190 $years[$i] = $i;
191 return $years;
192 }
193
194
195 /** Make a where clause to get a user's sessions.
196 * Prepare the where clause request that will retrieve the sessions.
197 *
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.
203 *
204 * @return STRING the WHERE clause of a query, including the 'WHERE' keyword
205 * @private
206 */
207 function _makeWhere($year,$month,$day,$auth,$uid)
208 {
209 global $globals;
210
211 // start constructing the "where" clause
212 $where = array();
213
214 if ($auth)
215 array_push($where, "auth='$auth'");
216
217 if ($uid)
218 array_push($where, "uid='$uid'");
219
220 // we were given at least a year
221 if ($year) {
222 if ($day) {
223 $dmin = mktime(0, 0, 0, $month, $day, $year);
224 $dmax = mktime(0, 0, 0, $month, $day+1,$year);
225 } elseif ($month) {
226 $dmin = mktime(0, 0, 0, $month, 1, $year);
227 $dmax = mktime(0, 0, 0, $month+1, 1, $year);
228 } else {
229 $dmin = mktime(0, 0, 0, 1, 1, $year);
230 $dmax = mktime(0, 0, 0, 1, 1, $year+1);
231 }
232 $where[] = "start >= " . date("Ymd000000",$dmin);
233 $where[] = "start < " . date("Ymd000000", $dmax);
234 }
235
236 if (!empty($where))
237 return ' WHERE ' . implode($where," AND ");
238 else
239 return '';
240 // WE know it's totally reversed, so better use array_reverse than a SORT BY start DESC
241 }
242
243
244 /** Run the log viewer and fill out the Smarty variables for display.
245 *
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
249 */
250 function run(&$page,$outputvar='',$template='')
251 {
252 global $globals;
253
254 if (isset($_REQUEST['logsess'])) {
255
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);
261
262 $sarr['username'] = $this->_getUsername($sarr['auth'],$sarr['uid']);
263 if ($sarr['suid'])
264 $sarr['suer'] = $this->_getUsername($sarr['sauth'],$sarr['suid']);
265 $page->assign('session',$sarr);
266
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);
274
275 } else {
276
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 = '';
282
283 if ($loguid) {
284 $year = isset($_REQUEST['year']) ? $_REQUEST['year'] : 0;
285 $month = isset($_REQUEST['month']) ? $_REQUEST['month'] : 0;
286 $day = isset($_REQUEST['day']) ? $_REQUEST['day'] : 0;
287 } else {
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");
291 }
292
293 if (!$year) $month = 0;
294 if (!$month) $day = 0;
295
296 // smarty assignments
297 // retrieve available years
298 $page->assign('years',$this->_getYears());
299 $page->assign('year',$year);
300
301 // retrieve available months for the current year
302 $page->assign('months',$this->_getMonths($year));
303 $page->assign('month',$month);
304
305 // retrieve available days for the current year and month
306 $page->assign('days',$this->_getDays($year,$month));
307 $page->assign('day',$day);
308
309 // retrieve available auths
310 $auths = $this->_getAuths();
311 $page->assign('auths',$auths);
312
313 $page->assign('logauth',$logauth);
314 $page->assign('loguser',$loguser);
315 // smarty assignments
316
317 if($loguid || $year) {
318
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
323 $where
324 ORDER BY start DESC";
325 $res = $globals->db->query($select);
326
327 $sessions = array();
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']];
332 // summary of events
333 $mysess['events'] = array();
334 // actions
335 $mysess['actions'] = array(
336 array(__("view session"),"?logsess={$mysess['id']}"),
337 array(__("user's log"),"?logauth={$mysess['auth']}&amp;loguser={$mysess['username']}")
338 );
339
340 $sessions[$mysess['id']] = $mysess;
341 }
342 mysql_free_result($res);
343 array_reverse($sessions);
344
345 // attach events
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)
350 $where";
351
352 $res = $globals->db->query($sql);
353 while( $event = mysql_fetch_assoc($res) ) {
354 array_push($sessions[$event['id']]['events'],$event['text']);
355 }
356 mysql_free_result($res);
357 $page->assign_by_ref('sessions',$sessions);
358 } else {
359 $page->assign('msg_nofilters', __("Please select a year and/or a user."));
360 }
361 }
362
363 // translations
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"));
379
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));
385 }
386 }
387
388}
389
390?>