simpler database and session.
[platal.git] / classes / LoggerView.php
CommitLineData
c4271d38 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 */
27class LoggerView {
28 /** Retrieves the available days for a given year and month.
29 * Obtain a list of days of the given month in the given year
30 * that are within the range of dates that we have log entries for.
31 *
32 * @param integer year
33 * @param integer month
34 * @return array days in that month we have log entries covering.
35 * @private
36 */
37 function _getDays($year, $month)
38 {
39 global $globals;
40
41 // give a 'no filter' option
42 $days[0] = __("all");
43
44 if ($year && $month) {
45 $day_max = Array(-1, 31, checkdate(2, 29, $year) ? 29 : 28 , 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
46 $res = XDB::query("SELECT YEAR (MAX(start)), YEAR (MIN(start)),
47 MONTH(MAX(start)), MONTH(MIN(start)),
48 DAYOFMONTH(MAX(start)),
49 DAYOFMONTH(MIN(start))
50 FROM {$globals->table_log_sessions}");
51 list($ymax, $ymin, $mmax, $mmin, $dmax, $dmin) = $res->fetchOneRow();
52
53 if (($year < $ymin) || ($year == $ymin && $month < $mmin)) {
54 return array();
55 }
56
57 if (($year > $ymax) || ($year == $ymax && $month > $mmax)) {
58 return array();
59 }
60
61 $min = ($year==$ymin && $month==$mmin) ? intval($dmin) : 1;
62 $max = ($year==$ymax && $month==$mmax) ? intval($dmax) : $day_max[$month];
63
64 for($i = $min; $i<=$max; $i++) {
65 $days[$i] = $i;
66 }
67 }
68 return $days;
69 }
70
71
72 /** Retrieves the available months for a given year.
73 * Obtains a list of month numbers that are within the timeframe that
74 * we have log entries for.
75 *
76 * @param integer year
77 * @return array List of month numbers we have log info for.
78 * @private
79 */
80 function _getMonths($year)
81 {
82 global $globals;
83
84 // give a 'no filter' option
85 $months[0] = __("all");
86
87 if ($year) {
88 $res = XDB::query("SELECT YEAR (MAX(start)), YEAR (MIN(start)),
89 MONTH(MAX(start)), MONTH(MIN(start))
90 FROM {$globals->table_log_sessions}");
91 list($ymax, $ymin, $mmax, $mmin) = $res->fetchOneRow();
92
93 if (($year < $ymin) || ($year > $ymax)) {
94 return array();
95 }
96
97 $min = $year == $ymin ? intval($mmin) : 1;
98 $max = $year == $ymax ? intval($mmax) : 12;
99
100 for($i = $min; $i<=$max; $i++) {
101 $months[$i] = $i;
102 }
103 }
104 return $months;
105 }
106
107
108 /** Retrieves the username for a given authentication method and user id.
109 * This function caches the results of the lookups to avoid uncecessary
110 * database requests.
111 *
112 * @return the matching username.
113 * @private
114 */
115 function _getUsername($auth, $uid) {
116 global $globals;
117 static $cache;
118
119 if (!isset($cache[$auth][$uid])) {
120 $res = XDB::query('SELECT alias FROM aliases
121 WHERE id = {?} AND type="a_vie"', $uid);
122 $cache[$auth][$uid] = $res->fetchOneCell();
123 }
124
125 return $cache[$auth][$uid];
126 }
127
128
129 /** Retrieves the available years.
130 * Obtains a list of years that we have log entries covering.
131 *
132 * @return array years we have log entries for.
133 * @private
134 */
135 function _getYears()
136 {
137 global $globals;
138
139 // give a 'no filter' option
140 $years[0] = __("all");
141
142 // retrieve available years
143 $res = XDB::query("select YEAR(MAX(start)), YEAR(MIN(start)) FROM {$globals->table_log_sessions}");
144 list($max, $min) = $res->fetchOneRow();
145
146 for($i = intval($min); $i<=$max; $i++) {
147 $years[$i] = $i;
148 }
149 return $years;
150 }
151
152
153 /** Make a where clause to get a user's sessions.
154 * Prepare the where clause request that will retrieve the sessions.
155 *
156 * @param $year INTEGER Only get log entries made during the given year.
157 * @param $month INTEGER Only get log entries made during the given month.
158 * @param $day INTEGER Only get log entries made during the given day.
159 * @param $auth INTEGER Only get log entries with the given authentication type.
160 * @param $uid INTEGER Only get log entries referring to the given user ID.
161 *
162 * @return STRING the WHERE clause of a query, including the 'WHERE' keyword
163 * @private
164 */
165 function _makeWhere($year, $month, $day, $auth, $uid)
166 {
167 // start constructing the "where" clause
168 $where = array();
169
170 if ($auth)
171 array_push($where, "auth='$auth'");
172
173 if ($uid)
174 array_push($where, "uid='$uid'");
175
176 // we were given at least a year
177 if ($year) {
178 if ($day) {
179 $dmin = mktime(0, 0, 0, $month, $day, $year);
180 $dmax = mktime(0, 0, 0, $month, $day+1, $year);
181 } elseif ($month) {
182 $dmin = mktime(0, 0, 0, $month, 1, $year);
183 $dmax = mktime(0, 0, 0, $month+1, 1, $year);
184 } else {
185 $dmin = mktime(0, 0, 0, 1, 1, $year);
186 $dmax = mktime(0, 0, 0, 1, 1, $year+1);
187 }
188 $where[] = "start >= " . date("Ymd000000", $dmin);
189 $where[] = "start < " . date("Ymd000000", $dmax);
190 }
191
192 if (!empty($where)) {
193 return ' WHERE ' . implode($where, " AND ");
194 } else {
195 return '';
196 }
197 // WE know it's totally reversed, so better use array_reverse than a SORT BY start DESC
198 }
199
200
201 /** Run the log viewer and fill out the Smarty variables for display.
202 *
203 * @param page the page that will display the viewer's data
204 * @param outputvar the Smarty variable to which we should assign the output
205 * @param template the template to use for display
206 */
207 function run(&$page, $outputvar='', $template='')
208 {
209 global $globals;
210
211 if (isset($_REQUEST['logsess'])) {
212
213 // we are viewing a session
214 $res = XDB::query("SELECT host, ip, browser, auth, uid, sauth, suid
215 FROM {$globals->table_log_sessions}
216 WHERE id =".$_REQUEST['logsess']);
217
218 $sarr = $res->fetchOneAssoc();
219
220 $sarr['username'] = $this->_getUsername($sarr['auth'], $sarr['uid']);
221 if ($sarr['suid']) {
222 $sarr['suer'] = $this->_getUsername($sarr['sauth'], $sarr['suid']);
223 }
224 $page->assign('session', $sarr);
225
226 $res = XDB::iterator("SELECT a.text, e.data, UNIX_TIMESTAMP(e.stamp) AS stamp
227 FROM {$globals->table_log_events} AS e
228 LEFT JOIN {$globals->table_log_actions} AS a ON e.action=a.id
229 WHERE e.session='{$_REQUEST['logsess']}'");
230 while ($myarr = $res->next()) {
231 $page->append('events', $myarr);
232 }
233
234 } else {
235
236 // we are browsing the available sessions
237 $logauth = isset($_REQUEST['logauth']) ? $_REQUEST['logauth'] : '';
238 $loguser = isset($_REQUEST['loguser']) ? $_REQUEST['loguser'] : '';
239
240 $res = XDB::query('SELECT id FROM aliases WHERE alias={?}',
241 Env::v('loguser'));
242 $loguid = $res->fetchOneCell();
243
244 if ($loguid) {
245 $year = isset($_REQUEST['year']) ? $_REQUEST['year'] : 0;
246 $month = isset($_REQUEST['month']) ? $_REQUEST['month'] : 0;
247 $day = isset($_REQUEST['day']) ? $_REQUEST['day'] : 0;
248 } else {
249 $year = isset($_REQUEST['year']) ? $_REQUEST['year'] : date("Y");
250 $month = isset($_REQUEST['month']) ? $_REQUEST['month'] : date("m");
251 $day = isset($_REQUEST['day']) ? $_REQUEST['day'] : date("d");
252 }
253
254 if (!$year) $month = 0;
255 if (!$month) $day = 0;
256
257 // smarty assignments
258 // retrieve available years
259 $page->assign('years', $this->_getYears());
260 $page->assign('year', $year);
261
262 // retrieve available months for the current year
263 $page->assign('months', $this->_getMonths($year));
264 $page->assign('month', $month);
265
266 // retrieve available days for the current year and month
267 $page->assign('days', $this->_getDays($year, $month));
268 $page->assign('day', $day);
269
270 // retrieve available auths
271 $auths = array('all', 'native' => 'X.org');
272 $page->assign('auths', $auths);
273
274 $page->assign('logauth', $logauth);
275 $page->assign('loguser', $loguser);
276 // smarty assignments
277
278 if ($loguid || $year) {
279
280 // get the requested sessions
281 $where = $this->_makeWhere($year, $month, $day, $logauth, $loguid);
282 $select = "SELECT id, UNIX_TIMESTAMP(start) as start, auth, uid
283 FROM {$globals->table_log_sessions} AS s
284 $where
285 ORDER BY start DESC";
286 $res = XDB::iterator($select);
287
288 $sessions = array();
289 $odd = false;
290 while ($mysess = $res->next()) {
291 $mysess['username'] = $this->_getUsername($mysess['auth'], $mysess['uid']);
292 // pretty label for auth method
293 $mysess['lauth'] = $auths[$mysess['auth']];
294 // summary of events
295 $mysess['events'] = array();
296 // actions
297 $mysess['actions'] = array(
298 array(__("view session"), "admin/logger?logsess={$mysess['id']}"),
299 array(__("user's log"), "admin/logger?logauth={$mysess['auth']}&amp;loguser={$mysess['username']}")
300 );
301
302 $mysess['class'] = $odd ? "odd" : "even";
303 $sessions[$mysess['id']] = $mysess;
304 $odd = !$odd;
305 }
306 array_reverse($sessions);
307
308 // attach events
309 $sql = "SELECT s.id, a.text
310 FROM {$globals->table_log_sessions} AS s
311 LEFT JOIN {$globals->table_log_events} AS e ON(e.session=s.id)
312 INNER JOIN {$globals->table_log_actions} AS a ON(a.id=e.action)
313 $where";
314
315 $res = XDB::iterator($sql);
316 while ($event = $res->next()) {
317 array_push($sessions[$event['id']]['events'], $event['text']);
318 }
319 $page->assign_by_ref('sessions', $sessions);
320 } else {
321 $page->assign('msg_nofilters', __("Please select a year and/or a user."));
322 }
323 }
324
325 // translations
326 $page->assign('msg_session_properties', __("session properties"));
327 $page->assign('msg_user', __("user"));
328 $page->assign('msg_host', __("host"));
329 $page->assign('msg_browser', __("browser"));
330 $page->assign('msg_date', __("date"));
331 $page->assign('msg_action', __("action"));
332 $page->assign('msg_data', __("data"));
333 $page->assign('msg_filter_by', __("filter by"));
334 $page->assign('msg_start', __("start"));
335 $page->assign('msg_summary', __("summary"));
336 $page->assign('msg_actions', __("actions"));
337 $page->assign('msg_year', __("year"));
338 $page->assign('msg_month', __("month"));
339 $page->assign('msg_day', __("day"));
340 $page->assign('msg_submit', __("Submit"));
341
342 // if requested, assign the content to be displayed
343 if (!empty($outputvar)) {
344 $page->assign($outputvar, $page->fetch($template));
345 }
346
347 $page->changeTpl('logger-view.tpl');
348 }
349
350}
351
352?>