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
/**
18
 * This file contains functions used by the log reports
19
 *
20
 * This files lists the functions that are used during the log report generation.
21
 *
22
 * @package    report_log
23
 * @copyright  1999 onwards Martin Dougiamas (http://dougiamas.com)
24
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25
 */
26
 
27
defined('MOODLE_INTERNAL') || die;
28
 
29
if (!defined('REPORT_LOG_MAX_DISPLAY')) {
30
    define('REPORT_LOG_MAX_DISPLAY', 150); // days
31
}
32
 
33
require_once(__DIR__.'/lib.php');
34
 
35
/**
36
 * This function is used to generate and display the log activity graph
37
 *
38
 * @global stdClass $CFG
39
 * @param  stdClass $course course instance
40
 * @param  int|stdClass    $user id/object of the user whose logs are needed
41
 * @param  string $typeormode type of logs graph needed (usercourse.png/userday.png) or the mode (today, all).
42
 * @param  int $date timestamp in GMT (seconds since epoch)
43
 * @param  string $logreader Log reader.
44
 * @return void
45
 */
46
function report_log_print_graph($course, $user, $typeormode, $date=0, $logreader='') {
47
    global $CFG, $OUTPUT;
48
 
49
    if (!is_object($user)) {
50
        $user = core_user::get_user($user);
51
    }
52
 
53
    $logmanager = get_log_manager();
54
    $readers = $logmanager->get_readers();
55
 
56
    if (empty($logreader)) {
57
        $reader = reset($readers);
58
    } else {
59
        $reader = $readers[$logreader];
60
    }
61
    // If reader is not a sql_internal_table_reader and not legacy store then don't show graph.
62
    if (!($reader instanceof \core\log\sql_internal_table_reader)) {
63
        return array();
64
    }
65
    $coursecontext = context_course::instance($course->id);
66
 
67
    $a = new stdClass();
68
    $a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
69
    $a->username = fullname($user, true);
70
 
71
    if ($typeormode == 'today' || $typeormode == 'userday.png') {
72
        $logs = report_log_usertoday_data($course, $user, $date, $logreader);
73
        $title = get_string("hitsoncoursetoday", "", $a);
74
    } else if ($typeormode == 'all' || $typeormode == 'usercourse.png') {
75
        $logs = report_log_userall_data($course, $user, $logreader);
76
        $title = get_string("hitsoncourse", "", $a);
77
    }
78
 
79
    if (!empty($CFG->preferlinegraphs)) {
80
        $chart = new \core\chart_line();
81
    } else {
82
        $chart = new \core\chart_bar();
83
    }
84
 
85
    $series = new \core\chart_series(get_string("hits"), $logs['series']);
86
    $chart->add_series($series);
87
    $chart->set_title($title);
88
    $chart->set_labels($logs['labels']);
89
    $yaxis = $chart->get_yaxis(0, true);
90
    $yaxis->set_label(get_string("hits"));
91
    $yaxis->set_stepsize(max(1, round(max($logs['series']) / 10)));
92
 
93
    echo $OUTPUT->render($chart);
94
}
95
 
96
/**
97
 * Select all log records for a given course and user
98
 *
99
 * @param int $userid The id of the user as found in the 'user' table.
100
 * @param int $courseid The id of the course as found in the 'course' table.
101
 * @param string $coursestart unix timestamp representing course start date and time.
102
 * @param string $logreader log reader to use.
103
 * @return array
104
 */
105
function report_log_usercourse($userid, $courseid, $coursestart, $logreader = '') {
106
    global $DB;
107
 
108
    $logmanager = get_log_manager();
109
    $readers = $logmanager->get_readers();
110
    if (empty($logreader)) {
111
        $reader = reset($readers);
112
    } else {
113
        $reader = $readers[$logreader];
114
    }
115
 
116
    // If reader is not a sql_internal_table_reader and not legacy store then return.
117
    if (!($reader instanceof \core\log\sql_internal_table_reader)) {
118
        return array();
119
    }
120
 
121
    $coursestart = (int)$coursestart; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY.
122
    $logtable = $reader->get_internal_log_table_name();
123
    $timefield = 'timecreated';
124
    $coursefield = 'courseid';
125
    $nonanonymous = 'AND anonymous = 0';
126
 
127
    $params = array();
128
    $courseselect = '';
129
    if ($courseid) {
130
        $courseselect = "AND $coursefield = :courseid";
131
        $params['courseid'] = $courseid;
132
    }
133
    $params['userid'] = $userid;
134
    return $DB->get_records_sql("SELECT FLOOR(($timefield - $coursestart)/" . DAYSECS . ") AS day, COUNT(*) AS num
135
                                   FROM {" . $logtable . "}
136
                                  WHERE userid = :userid
137
                                        AND $timefield > $coursestart $courseselect $nonanonymous
138
                               GROUP BY FLOOR(($timefield - $coursestart)/" . DAYSECS .")", $params);
139
}
140
 
141
/**
142
 * Select all log records for a given course, user, and day
143
 *
144
 * @param int $userid The id of the user as found in the 'user' table.
145
 * @param int $courseid The id of the course as found in the 'course' table.
146
 * @param string $daystart unix timestamp of the start of the day for which the logs needs to be retrived
147
 * @param string $logreader log reader to use.
148
 * @return array
149
 */
150
function report_log_userday($userid, $courseid, $daystart, $logreader = '') {
151
    global $DB;
152
    $logmanager = get_log_manager();
153
    $readers = $logmanager->get_readers();
154
    if (empty($logreader)) {
155
        $reader = reset($readers);
156
    } else {
157
        $reader = $readers[$logreader];
158
    }
159
 
160
    // If reader is not a sql_internal_table_reader and not legacy store then return.
161
    if (!($reader instanceof \core\log\sql_internal_table_reader)) {
162
        return array();
163
    }
164
 
165
    $daystart = (int)$daystart; // Note: unfortunately pg complains if you use name parameter or column alias in GROUP BY.
166
 
167
    $logtable = $reader->get_internal_log_table_name();
168
    $timefield = 'timecreated';
169
    $coursefield = 'courseid';
170
    $nonanonymous = 'AND anonymous = 0';
171
    $params = array('userid' => $userid);
172
 
173
    $courseselect = '';
174
    if ($courseid) {
175
        $courseselect = "AND $coursefield = :courseid";
176
        $params['courseid'] = $courseid;
177
    }
178
    return $DB->get_records_sql("SELECT FLOOR(($timefield - $daystart)/" . HOURSECS . ") AS hour, COUNT(*) AS num
179
                                   FROM {" . $logtable . "}
180
                                  WHERE userid = :userid
181
                                        AND $timefield > $daystart $courseselect $nonanonymous
182
                               GROUP BY FLOOR(($timefield - $daystart)/" . HOURSECS . ") ", $params);
183
}
184
 
185
/**
186
 * This function is used to generate and display Mnet selector form
187
 *
188
 * @global stdClass $USER
189
 * @global stdClass $CFG
190
 * @global stdClass $SITE
191
 * @global moodle_database $DB
192
 * @global core_renderer $OUTPUT
193
 * @global stdClass $SESSION
194
 * @uses CONTEXT_SYSTEM
195
 * @uses COURSE_MAX_COURSES_PER_DROPDOWN
196
 * @uses CONTEXT_COURSE
197
 * @uses SEPARATEGROUPS
198
 * @param  int      $hostid host id
199
 * @param  stdClass $course course instance
200
 * @param  int      $selecteduser id of the selected user
201
 * @param  string   $selecteddate Date selected
202
 * @param  string   $modname course_module->id
203
 * @param  string   $modid number or 'site_errors'
204
 * @param  string   $modaction an action as recorded in the logs
205
 * @param  int      $selectedgroup Group to display
206
 * @param  int      $showcourses whether to show courses if we're over our limit.
207
 * @param  int      $showusers whether to show users if we're over our limit.
208
 * @param  string   $logformat Format of the logs (downloadascsv, showashtml, downloadasods, downloadasexcel)
209
 * @return void
210
 */
211
function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0, $selecteddate='today',
212
                                 $modname="", $modid=0, $modaction='', $selectedgroup=-1, $showcourses=0, $showusers=0, $logformat='showashtml') {
213
 
214
    global $USER, $CFG, $SITE, $DB, $OUTPUT, $SESSION;
215
    require_once $CFG->dirroot.'/mnet/peer.php';
216
 
217
    $mnet_peer = new mnet_peer();
218
    $mnet_peer->set_id($hostid);
219
 
220
    $sql = "SELECT DISTINCT course, hostid, coursename FROM {mnet_log}";
221
    $courses = $DB->get_records_sql($sql);
222
    $remotecoursecount = count($courses);
223
 
224
    // first check to see if we can override showcourses and showusers
225
    $numcourses = $remotecoursecount + $DB->count_records('course');
226
    if ($numcourses < COURSE_MAX_COURSES_PER_DROPDOWN && !$showcourses) {
227
        $showcourses = 1;
228
    }
229
 
230
    $sitecontext = context_system::instance();
231
 
232
    // Context for remote data is always SITE
233
    // Groups for remote data are always OFF
234
    if ($hostid == $CFG->mnet_localhost_id) {
235
        $context = context_course::instance($course->id);
236
 
237
        /// Setup for group handling.
238
        if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/site:accessallgroups', $context)) {
239
            $selectedgroup = -1;
240
            $showgroups = false;
241
        } else if ($course->groupmode) {
242
            $showgroups = true;
243
        } else {
244
            $selectedgroup = 0;
245
            $showgroups = false;
246
        }
247
 
248
        if ($selectedgroup === -1) {
249
            if (isset($SESSION->currentgroup[$course->id])) {
250
                $selectedgroup =  $SESSION->currentgroup[$course->id];
251
            } else {
252
                $selectedgroup = groups_get_all_groups($course->id, $USER->id);
253
                if (is_array($selectedgroup)) {
254
                    $selectedgroup = array_shift(array_keys($selectedgroup));
255
                    $SESSION->currentgroup[$course->id] = $selectedgroup;
256
                } else {
257
                    $selectedgroup = 0;
258
                }
259
            }
260
        }
261
 
262
    } else {
263
        $context = $sitecontext;
264
    }
265
 
266
    // Get all the possible users
267
    $users = array();
268
 
269
    // Define limitfrom and limitnum for queries below
270
    // If $showusers is enabled... don't apply limitfrom and limitnum
271
    $limitfrom = empty($showusers) ? 0 : '';
272
    $limitnum  = empty($showusers) ? COURSE_MAX_USERS_PER_DROPDOWN + 1 : '';
273
 
274
    // If looking at a different host, we're interested in all our site users
275
    if ($hostid == $CFG->mnet_localhost_id && $course->id != SITEID) {
276
        $userfieldsapi = \core_user\fields::for_name();
277
        $courseusers = get_enrolled_users($context, '', $selectedgroup, 'u.id, ' .
278
                $userfieldsapi->get_sql('u', false, '', '', false)->selects,
279
                null, $limitfrom, $limitnum);
280
    } else {
281
        // this may be a lot of users :-(
282
        $userfieldsapi = \core_user\fields::for_name();
283
        $courseusers = $DB->get_records('user', array('deleted' => 0), 'lastaccess DESC', 'id, ' .
284
                $userfieldsapi->get_sql('', false, '', '', false)->selects,
285
                $limitfrom, $limitnum);
286
    }
287
 
288
    if (count($courseusers) < COURSE_MAX_USERS_PER_DROPDOWN && !$showusers) {
289
        $showusers = 1;
290
    }
291
 
292
    if ($showusers) {
293
        if ($courseusers) {
294
            foreach ($courseusers as $courseuser) {
295
                $users[$courseuser->id] = fullname($courseuser, has_capability('moodle/site:viewfullnames', $context));
296
            }
297
        }
298
        $users[$CFG->siteguest] = get_string('guestuser');
299
    }
300
 
301
    // Get all the hosts that have log records
302
    $sql = "select distinct
303
                h.id,
304
                h.name
305
            from
306
                {mnet_host} h,
307
                {mnet_log} l
308
            where
309
                h.id = l.hostid
310
            order by
311
                h.name";
312
 
313
    if ($hosts = $DB->get_records_sql($sql)) {
314
        foreach($hosts as $host) {
315
            $hostarray[$host->id] = $host->name;
316
        }
317
    }
318
 
319
    $hostarray[$CFG->mnet_localhost_id] = $SITE->fullname;
320
    asort($hostarray);
321
 
322
    $dropdown = array();
323
 
324
    foreach($hostarray as $hostid => $name) {
325
        $courses = array();
326
        $sites = array();
327
        if ($CFG->mnet_localhost_id == $hostid) {
328
            if (has_capability('report/log:view', $sitecontext) && $showcourses) {
329
                if ($ccc = $DB->get_records("course", null, "fullname","id,shortname,fullname,category")) {
330
                    foreach ($ccc as $cc) {
331
                        if ($cc->id == SITEID) {
332
                            $sites["$hostid/$cc->id"]   = format_string($cc->fullname).' ('.get_string('site').')';
333
                        } else {
334
                            $courses["$hostid/$cc->id"] = format_string(get_course_display_name_for_list($cc));
335
                        }
336
                    }
337
                }
338
            }
339
        } else {
340
            if (has_capability('report/log:view', $sitecontext) && $showcourses) {
341
                $sql = "SELECT DISTINCT course, coursename FROM {mnet_log} where hostid = ?";
342
                if ($ccc = $DB->get_records_sql($sql, array($hostid))) {
343
                    foreach ($ccc as $cc) {
344
                        if (1 == $cc->course) { // TODO: this might be wrong - site course may have another id
345
                            $sites["$hostid/$cc->course"]   = $cc->coursename.' ('.get_string('site').')';
346
                        } else {
347
                            $courses["$hostid/$cc->course"] = $cc->coursename;
348
                        }
349
                    }
350
                }
351
            }
352
        }
353
 
354
        asort($courses);
355
        $dropdown[] = array($name=>($sites + $courses));
356
    }
357
 
358
 
359
    $activities = array();
360
    $selectedactivity = "";
361
 
362
    $modinfo = get_fast_modinfo($course);
363
    if (!empty($modinfo->cms)) {
364
        $section = 0;
365
        $thissection = array();
366
        foreach ($modinfo->cms as $cm) {
367
            // Exclude activities that aren't visible or have no view link (e.g. label). Account for folder being displayed inline.
368
            if (!$cm->uservisible || (!$cm->has_view() && strcmp($cm->modname, 'folder') !== 0)) {
369
                continue;
370
            }
371
            if ($cm->sectionnum > 0 and $section <> $cm->sectionnum) {
372
                $activities[] = $thissection;
373
                $thissection = array();
374
            }
375
            $section = $cm->sectionnum;
376
            $modname = strip_tags($cm->get_formatted_name());
377
            if (core_text::strlen($modname) > 55) {
378
                $modname = core_text::substr($modname, 0, 50)."...";
379
            }
380
            if (!$cm->visible) {
381
                $modname = "(".$modname.")";
382
            }
383
            $key = get_section_name($course, $cm->sectionnum);
384
            if (!isset($thissection[$key])) {
385
                $thissection[$key] = array();
386
            }
387
            $thissection[$key][$cm->id] = $modname;
388
 
389
            if ($cm->id == $modid) {
390
                $selectedactivity = "$cm->id";
391
            }
392
        }
393
        if (!empty($thissection)) {
394
            $activities[] = $thissection;
395
        }
396
    }
397
 
398
    if (has_capability('report/log:view', $sitecontext) && !$course->category) {
399
        $activities["site_errors"] = get_string("siteerrors");
400
        if ($modid === "site_errors") {
401
            $selectedactivity = "site_errors";
402
        }
403
    }
404
 
405
    $strftimedate = get_string("strftimedate");
406
    $strftimedaydate = get_string("strftimedaydate");
407
 
408
    asort($users);
409
 
410
    // Prepare the list of action options.
411
    $actions = array(
412
        'view' => get_string('view'),
413
        'add' => get_string('add'),
414
        'update' => get_string('update'),
415
        'delete' => get_string('delete'),
416
        '-view' => get_string('allchanges')
417
    );
418
 
419
    // Get all the possible dates
420
    // Note that we are keeping track of real (GMT) time and user time
421
    // User time is only used in displays - all calcs and passing is GMT
422
 
423
    $timenow = time(); // GMT
424
 
425
    // What day is it now for the user, and when is midnight that day (in GMT).
426
    $timemidnight = $today = usergetmidnight($timenow);
427
 
428
    // Put today up the top of the list
429
    $dates = array(
430
        "0" => get_string('alldays'),
431
        "$timemidnight" => get_string("today").", ".userdate($timenow, $strftimedate)
432
    );
433
 
434
    if (!$course->startdate or ($course->startdate > $timenow)) {
435
        $course->startdate = $course->timecreated;
436
    }
437
 
438
    $numdates = 1;
439
    while ($timemidnight > $course->startdate and $numdates < 365) {
440
        $timemidnight = $timemidnight - 86400;
441
        $timenow = $timenow - 86400;
442
        $dates["$timemidnight"] = userdate($timenow, $strftimedaydate);
443
        $numdates++;
444
    }
445
 
446
    if ($selecteddate === "today") {
447
        $selecteddate = $today;
448
    }
449
 
450
    echo "<form class=\"logselectform\" action=\"$CFG->wwwroot/report/log/index.php\" method=\"get\">\n";
451
    echo "<div>\n";//invisible fieldset here breaks wrapping
452
    echo "<input type=\"hidden\" name=\"chooselog\" value=\"1\" />\n";
453
    echo "<input type=\"hidden\" name=\"showusers\" value=\"$showusers\" />\n";
454
    echo "<input type=\"hidden\" name=\"showcourses\" value=\"$showcourses\" />\n";
455
    if (has_capability('report/log:view', $sitecontext) && $showcourses) {
456
        $cid = empty($course->id)? '1' : $course->id;
457
        echo html_writer::label(get_string('selectacoursesite'), 'menuhost_course', false, array('class' => 'accesshide'));
458
        echo html_writer::select($dropdown, "host_course", $hostid.'/'.$cid);
459
    } else {
460
        $courses = array();
461
        $courses[$course->id] = get_course_display_name_for_list($course) . ((empty($course->category)) ? ' ('.get_string('site').') ' : '');
462
        echo html_writer::label(get_string('selectacourse'), 'menuid', false, array('class' => 'accesshide'));
463
        echo html_writer::select($courses,"id",$course->id, false);
464
        if (has_capability('report/log:view', $sitecontext)) {
465
            $a = new stdClass();
466
            $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
467
                ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showcourses=1&showusers=$showusers";
468
            print_string('logtoomanycourses','moodle',$a);
469
        }
470
    }
471
 
472
    if ($showgroups) {
473
        if ($cgroups = groups_get_all_groups($course->id)) {
474
            foreach ($cgroups as $cgroup) {
475
                $groups[$cgroup->id] = $cgroup->name;
476
            }
477
        }
478
        else {
479
            $groups = array();
480
        }
481
        echo html_writer::label(get_string('selectagroup'), 'menugroup', false, array('class' => 'accesshide'));
482
        echo html_writer::select($groups, "group", $selectedgroup, get_string("allgroups"));
483
    }
484
 
485
    if ($showusers) {
486
        echo html_writer::label(get_string('participantslist'), 'menuuser', false, array('class' => 'accesshide'));
487
        echo html_writer::select($users, "user", $selecteduser, get_string("allparticipants"));
488
    }
489
    else {
490
        $users = array();
491
        if (!empty($selecteduser)) {
492
            $user = $DB->get_record('user', array('id'=>$selecteduser));
493
            $users[$selecteduser] = fullname($user);
494
        }
495
        else {
496
            $users[0] = get_string('allparticipants');
497
        }
498
        echo html_writer::label(get_string('participantslist'), 'menuuser', false, array('class' => 'accesshide'));
499
        echo html_writer::select($users, "user", $selecteduser, false);
500
        $a = new stdClass();
501
        $a->url = "$CFG->wwwroot/report/log/index.php?chooselog=0&group=$selectedgroup&user=$selecteduser"
502
            ."&id=$course->id&date=$selecteddate&modid=$selectedactivity&showusers=1&showcourses=$showcourses";
503
        print_string('logtoomanyusers','moodle',$a);
504
    }
505
 
506
    echo html_writer::label(get_string('date'), 'menudate', false, array('class' => 'accesshide'));
507
    echo html_writer::select($dates, "date", $selecteddate, false);
508
    echo html_writer::label(get_string('showreports'), 'menumodid', false, array('class' => 'accesshide'));
509
    echo html_writer::select($activities, "modid", $selectedactivity, get_string("allactivities"));
510
    echo html_writer::label(get_string('actions'), 'menumodaction', false, array('class' => 'accesshide'));
511
    echo html_writer::select($actions, 'modaction', $modaction, get_string("allactions"));
512
 
513
    $logformats = array('showashtml' => get_string('displayonpage'),
514
                        'downloadascsv' => get_string('downloadtext'),
515
                        'downloadasods' => get_string('downloadods'),
516
                        'downloadasexcel' => get_string('downloadexcel'));
517
    echo html_writer::label(get_string('logsformat', 'report_log'), 'menulogformat', false, array('class' => 'accesshide'));
518
    echo html_writer::select($logformats, 'logformat', $logformat, false);
519
    echo '<input type="submit" value="'.get_string('gettheselogs').'" />';
520
    echo '</div>';
521
    echo '</form>';
522
}
523
 
524
/**
525
 * Fetch logs since the start of the courses and structure in series and labels to be sent to Chart API.
526
 *
527
 * @param stdClass $course the course object
528
 * @param stdClass $user user object
529
 * @param string $logreader the log reader where the logs are.
530
 * @return array structured array to be sent to chart API, split in two indexes (series and labels).
531
 */
532
function report_log_userall_data($course, $user, $logreader) {
533
    global $CFG;
534
    $site = get_site();
535
    $timenow = time();
536
    $logs = [];
537
    if ($course->id == $site->id) {
538
        $courseselect = 0;
539
    } else {
540
        $courseselect = $course->id;
541
    }
542
 
543
    $maxseconds = REPORT_LOG_MAX_DISPLAY * 3600 * 24;  // Seconds.
544
    if ($timenow - $course->startdate > $maxseconds) {
545
        $course->startdate = $timenow - $maxseconds;
546
    }
547
 
548
    if (!empty($CFG->loglifetime)) {
549
        $maxseconds = $CFG->loglifetime * 3600 * 24;  // Seconds.
550
        if ($timenow - $course->startdate > $maxseconds) {
551
            $course->startdate = $timenow - $maxseconds;
552
        }
553
    }
554
 
555
    $timestart = $coursestart = usergetmidnight($course->startdate);
556
 
557
    $i = 0;
558
    $logs['series'][$i] = 0;
559
    $logs['labels'][$i] = 0;
560
    while ($timestart < $timenow) {
561
        $timefinish = $timestart + 86400;
562
        $logs['labels'][$i] = userdate($timestart, "%a %d %b");
563
        $logs['series'][$i] = 0;
564
        $i++;
565
        $timestart = $timefinish;
566
    }
567
    $rawlogs = report_log_usercourse($user->id, $courseselect, $coursestart, $logreader);
568
 
569
    foreach ($rawlogs as $rawlog) {
570
        if (isset($logs['labels'][$rawlog->day])) {
571
            $logs['series'][$rawlog->day] = $rawlog->num;
572
        }
573
    }
574
 
575
    return $logs;
576
}
577
 
578
/**
579
 * Fetch logs of the current day and structure in series and labels to be sent to Chart API.
580
 *
581
 * @param stdClass $course the course object
582
 * @param stdClass $user user object
583
 * @param int $date A time of a day (in GMT).
584
 * @param string $logreader the log reader where the logs are.
585
 * @return array $logs structured array to be sent to chart API, split in two indexes (series and labels).
586
 */
587
function report_log_usertoday_data($course, $user, $date, $logreader) {
588
    $site = get_site();
589
    $logs = [];
590
 
591
    if ($course->id == $site->id) {
592
        $courseselect = 0;
593
    } else {
594
        $courseselect = $course->id;
595
    }
596
 
597
    if ($date) {
598
        $daystart = usergetmidnight($date);
599
    } else {
600
        $daystart = usergetmidnight(time());
601
    }
602
 
603
    for ($i = 0; $i <= 23; $i++) {
604
        $hour = $daystart + $i * 3600;
605
        $logs['series'][$i] = 0;
606
        $logs['labels'][$i] = userdate($hour, "%H:00");
607
    }
608
 
609
    $rawlogs = report_log_userday($user->id, $courseselect, $daystart, $logreader);
610
 
611
    foreach ($rawlogs as $rawlog) {
612
        if (isset($logs['labels'][$rawlog->hour])) {
613
            $logs['series'][$rawlog->hour] = $rawlog->num;
614
        }
615
    }
616
 
617
    return $logs;
618
}