Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
// This file is part of Moodle - http://moodle.org/
3
//
4
// Moodle is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8
//
9
// Moodle is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13
//
14
// You should have received a copy of the GNU General Public License
15
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
16
 
17
defined('MOODLE_INTERNAL') || die();
18
 
19
// Default session time limit in seconds.
20
define('BLOCK_DEDICATION_DEFAULT_SESSION_LIMIT', 60 * 60);
21
// Ignore sessions with a duration less than defined value in seconds.
22
define('BLOCK_DEDICATION_IGNORE_SESSION_TIME', 59);
23
// Default regeneration time in seconds.
24
define('BLOCK_DEDICATION_DEFAULT_REGEN_TIME', 60 * 15);
25
 
26
/**
27
 * Generate dedication reports based in passed params.
28
 */
29
class block_dedication_manager {
30
 
31
    protected $course;
32
    protected $mintime;
33
    protected $maxtime;
34
    protected $limit;
35
 
36
    public function __construct($course, $mintime, $maxtime, $limit) {
37
        $this->course = $course;
38
        $this->mintime = $mintime;
39
        $this->maxtime = $maxtime;
40
        $this->limit = $limit;
41
    }
42
 
43
    public function get_students_dedication($students) {
44
        global $DB;
45
 
46
        $rows = array();
47
 
48
        $where = 'courseid = :courseid AND userid = :userid AND timecreated >= :mintime AND timecreated <= :maxtime';
49
        $params = array(
50
            'courseid' => $this->course->id,
51
            'userid' => 0,
52
            'mintime' => $this->mintime,
53
            'maxtime' => $this->maxtime
54
        );
55
 
56
        $perioddays = ($this->maxtime - $this->mintime) / DAYSECS;
57
 
58
        foreach ($students as $user) {
59
            $daysconnected = array();
60
            $params['userid'] = $user->id;
61
            $logs = block_dedication_utils::get_events_select($where, $params);
62
 
63
            if ($logs) {
64
                $previouslog = array_shift($logs);
65
                $previouslogtime = $previouslog->time;
66
                $sessionstart = $previouslog->time;
67
                $dedication = 0;
68
                $daysconnected[date('Y-m-d', $previouslog->time)] = 1;
69
 
70
                foreach ($logs as $log) {
71
                    if (($log->time - $previouslogtime) > $this->limit) {
72
                        $dedication += $previouslogtime - $sessionstart;
73
                        $sessionstart = $log->time;
74
                    }
75
                    $previouslogtime = $log->time;
76
                    $daysconnected[date('Y-m-d', $log->time)] = 1;
77
                }
78
                $dedication += $previouslogtime - $sessionstart;
79
            } else {
80
                $dedication = 0;
81
            }
82
            $groups = groups_get_user_groups($this->course->id, $user->id);
83
            $group = !empty($groups) && !empty($groups[0]) ? $groups[0][0] : 0;
84
            $rows[] = (object) array(
85
                'user' => $user,
86
                'groupid' => $group,
87
                'dedicationtime' => $dedication,
88
                'connectionratio' => round(count($daysconnected) / $perioddays, 2),
89
            );
90
        }
91
 
92
        return $rows;
93
    }
94
 
95
    public function download_students_dedication($rows) {
96
        $groups = groups_get_all_groups($this->course->id);
97
 
98
        $headers = array(
99
            array(
100
                get_string('sincerow', 'block_dedication'),
101
                userdate($this->mintime),
102
                get_string('torow', 'block_dedication'),
103
                userdate($this->maxtime),
104
                get_string('perioddiffrow', 'block_dedication'),
105
                format_time($this->maxtime - $this->mintime),
106
            ),
107
            array(''),
108
            array(
109
                get_string('firstname'),
110
                get_string('lastname'),
111
                get_string('group'),
112
                get_string('dedicationrow', 'block_dedication') . ' (' . get_string('mins') . ')',
113
                get_string('dedicationrow', 'block_dedication'),
114
                get_string('connectionratiorow', 'block_dedication'),
115
            ),
116
        );
117
 
118
        foreach ($rows as $index => $row) {
119
            $rows[$index] = array(
120
                $row->user->firstname,
121
                $row->user->lastname,
122
                isset($groups[$row->groupid]) ? $groups[$row->groupid]->name : '',
123
                round($row->dedicationtime / MINSECS),
124
                block_dedication_utils::format_dedication($row->dedicationtime),
125
                $row->connectionratio,
126
            );
127
        }
128
 
129
        $rows = array_merge($headers, $rows);
130
 
131
        return block_dedication_utils::generate_download("{$this->course->shortname}_dedication", $rows);
132
    }
133
 
134
    public function get_user_dedication($user, $simple = false) {
135
        $where = 'courseid = :courseid AND userid = :userid AND timecreated >= :mintime AND timecreated <= :maxtime';
136
        $params = array(
137
            'courseid' => $this->course->id,
138
            'userid' => $user->id,
139
            'mintime' => $this->mintime,
140
            'maxtime' => $this->maxtime
141
        );
142
        $logs = block_dedication_utils::get_events_select($where, $params);
143
 
144
        if ($simple) {
145
            // Return total dedication time in seconds.
146
            $total = 0;
147
 
148
            if ($logs) {
149
                $previouslog = array_shift($logs);
150
                $previouslogtime = $previouslog->time;
151
                $sessionstart = $previouslogtime;
152
 
153
                foreach ($logs as $log) {
154
                    if (($log->time - $previouslogtime) > $this->limit) {
155
                        $dedication = $previouslogtime - $sessionstart;
156
                        $total += $dedication;
157
                        $sessionstart = $log->time;
158
                    }
159
                    $previouslogtime = $log->time;
160
                }
161
                $dedication = $previouslogtime - $sessionstart;
162
                $total += $dedication;
163
            }
164
 
165
            return $total;
166
 
167
        } else {
168
            // Return user sessions with details.
169
            $rows = array();
170
 
171
            if ($logs) {
172
                $previouslog = array_shift($logs);
173
                $previouslogtime = $previouslog->time;
174
                $sessionstart = $previouslogtime;
175
                $ips = array($previouslog->ip => true);
176
 
177
                foreach ($logs as $log) {
178
                    if (($log->time - $previouslogtime) > $this->limit) {
179
                        $dedication = $previouslogtime - $sessionstart;
180
 
181
                        // Ignore sessions with a really short duration.
182
                        if ($dedication > BLOCK_DEDICATION_IGNORE_SESSION_TIME) {
183
                            $rows[] = (object) array('start_date' => $sessionstart, 'dedicationtime' => $dedication, 'ips' => array_keys($ips));
184
                            $ips = array();
185
                        }
186
                        $sessionstart = $log->time;
187
                    }
188
                    $previouslogtime = $log->time;
189
                    $ips[$log->ip] = true;
190
                }
191
 
192
                $dedication = $previouslogtime - $sessionstart;
193
 
194
                // Ignore sessions with a really short duration.
195
                if ($dedication > BLOCK_DEDICATION_IGNORE_SESSION_TIME) {
196
                    $rows[] = (object) array('start_date' => $sessionstart, 'dedicationtime' => $dedication, 'ips' => array_keys($ips));
197
                }
198
            }
199
 
200
            return $rows;
201
        }
202
    }
203
 
204
    /**
205
     * Downloads user dedication with passed data.
206
     * @param $user
207
     * @return MoodleExcelWorkbook
208
     */
209
    public function download_user_dedication($user) {
210
        $headers = array(
211
            array(
212
                get_string('sincerow', 'block_dedication'),
213
                userdate($this->mintime),
214
                get_string('torow', 'block_dedication'),
215
                userdate($this->maxtime),
216
                get_string('perioddiffrow', 'block_dedication'),
217
                format_time($this->maxtime - $this->mintime),
218
            ),
219
            array(''),
220
            array(
221
                get_string('firstname'),
222
                get_string('lastname'),
223
                get_string('sessionstart', 'block_dedication'),
224
                get_string('dedicationrow', 'block_dedication') . ' ' . get_string('secs'),
225
                get_string('sessionduration', 'block_dedication'),
226
                'IP',
227
            )
228
        );
229
 
230
        $rows = $this->get_user_dedication($user);
231
        foreach ($rows as $index => $row) {
232
            $rows[$index] = array(
233
                $user->firstname,
234
                $user->lastname,
235
                userdate($row->start_date),
236
                $row->dedicationtime,
237
                block_dedication_utils::format_dedication($row->dedicationtime),
238
                implode(', ', $row->ips),
239
            );
240
        }
241
 
242
        $rows = array_merge($headers, $rows);
243
 
244
        return block_dedication_utils::generate_download("{$this->course->shortname}_dedication", $rows);
245
    }
246
 
247
}
248
 
249
/**
250
 * Utils functions used by block dedication.
251
 */
252
class block_dedication_utils {
253
 
254
    public static $logstores = array('logstore_standard', 'logstore_legacy');
255
 
256
    /**
257
     * Return formatted events from logstores.
258
     * @param string $selectwhere
259
     * @param array $params
260
     * @return array
261
     */
262
    public static function get_events_select($selectwhere, array $params) {
263
        $return = array();
264
 
265
        static $allreaders = null;
266
 
267
        if (is_null($allreaders)) {
268
            $allreaders = get_log_manager()->get_readers();
269
        }
270
 
271
        $processedreaders = 0;
272
 
273
        foreach (self::$logstores as $name) {
274
            if (isset($allreaders[$name])) {
275
                $reader = $allreaders[$name];
276
                $events = $reader->get_events_select($selectwhere, $params, 'timecreated ASC', 0, 0);
277
                foreach ($events as $event) {
278
                    // Note: see \core\event\base to view base class of event.
279
                    $obj = new stdClass();
280
                    $obj->time = $event->timecreated;
281
                    $obj->ip = $event->get_logextra()['ip'];
282
                    $return[] = $obj;
283
                }
284
                if (!empty($events)) {
285
                    $processedreaders++;
286
                }
287
            }
288
        }
289
 
290
        // Sort mixed array by time ascending again only when more of a reader has added events to return array.
291
        if ($processedreaders > 1) {
292
            usort($return, function($a, $b) {
293
                return $a->time > $b->time;
294
            });
295
        }
296
 
297
        return $return;
298
    }
299
 
300
    /**
301
     * Formats time based in Moodle function format_time($totalsecs).
302
     * @param int $totalsecs
303
     * @return string
304
     */
305
    public static function format_dedication($totalsecs) {
306
        $totalsecs = abs($totalsecs);
307
 
308
        $str = new stdClass();
309
        $str->hour = get_string('hour');
310
        $str->hours = get_string('hours');
311
        $str->min = get_string('min');
312
        $str->mins = get_string('mins');
313
        $str->sec = get_string('sec');
314
        $str->secs = get_string('secs');
315
 
316
        $hours = floor($totalsecs / HOURSECS);
317
        $remainder = $totalsecs - ($hours * HOURSECS);
318
        $mins = floor($remainder / MINSECS);
319
        $secs = round($remainder - ($mins * MINSECS), 2);
320
 
321
        $ss = ($secs == 1) ? $str->sec : $str->secs;
322
        $sm = ($mins == 1) ? $str->min : $str->mins;
323
        $sh = ($hours == 1) ? $str->hour : $str->hours;
324
 
325
        $ohours = '';
326
        $omins = '';
327
        $osecs = '';
328
 
329
        if ($hours) {
330
            $ohours = $hours . ' ' . $sh;
331
        }
332
        if ($mins) {
333
            $omins = $mins . ' ' . $sm;
334
        }
335
        if ($secs) {
336
            $osecs = $secs . ' ' . $ss;
337
        }
338
 
339
        if ($hours) {
340
            return trim($ohours . ' ' . $omins);
341
        }
342
        if ($mins) {
343
            return trim($omins . ' ' . $osecs);
344
        }
345
        if ($secs) {
346
            return $osecs;
347
        }
348
        return get_string('none');
349
    }
350
 
351
    /**
352
     * @param string[] $ips
353
     * @return string
354
     */
355
    public static function format_ips($ips) {
356
        return implode(', ', array_map('block_dedication_utils::link_ip', $ips));
357
    }
358
 
359
    /**
360
     * Generates a linkable ip.
361
     * @param string $ip
362
     * @return string
363
     */
364
    public static function link_ip($ip) {
365
        return html_writer::link("http://en.utrace.de/?query=$ip", $ip, array('target' => '_blank'));
366
    }
367
 
368
    /**
369
     * Return table styles based on current theme.
370
     * @return array
371
     */
372
    public static function get_table_styles() {
373
        global $PAGE;
374
 
375
        // Twitter Bootstrap styling.
376
        $is_bootstrap_theme = ($PAGE->theme->name === 'boost') || count(array_intersect(array('boost', 'bootstrapbase'), $PAGE->theme->parents)) > 0;
377
        if ($is_bootstrap_theme) {
378
            $styles = array(
379
                'table_class' => 'table table-bordered table-hover table-sm table-condensed table-dedication',
380
                'header_style' => 'background-color: #333; color: #fff;'
381
            );
382
        } else {
383
            $styles = array(
384
                'table_class' => 'table-dedication',
385
                'header_style' => ''
386
            );
387
        }
388
 
389
        return $styles;
390
    }
391
 
392
    /**
393
     * Generates generic Excel file for download.
394
     * @param string $downloadname
395
     * @param array $rows
396
     * @return MoodleExcelWorkbook
397
     * @throws coding_exception
398
     */
399
    public static function generate_download($downloadname, $rows) {
400
        global $CFG;
401
 
402
        require_once($CFG->libdir . '/excellib.class.php');
403
 
404
        $workbook = new MoodleExcelWorkbook(clean_filename($downloadname));
405
 
406
        $myxls = $workbook->add_worksheet(get_string('pluginname', 'block_dedication'));
407
 
408
        $rowcount = 0;
409
        foreach ($rows as $row) {
410
            foreach ($row as $index => $content) {
411
                $myxls->write($rowcount, $index, $content);
412
            }
413
            $rowcount++;
414
        }
415
 
416
        $workbook->close();
417
 
418
        return $workbook;
419
    }
420
}