Commit 6cf5e0f2 authored by Simey Lameze's avatar Simey Lameze Committed by Dan Poltawski
Browse files

MDL-54998 report_log: Convert log report graphs to the new API

Part of MDL-54987 epic.
parent 8bc4583f
......@@ -20,227 +20,13 @@
* Generates an image representing the log data in a graphical manner for a user.
*
* @package report_log
* @deprecated since 3.2
* @copyright 1999 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require("../../config.php");
require_once("$CFG->libdir/graphlib.php");
require_once($CFG->dirroot.'/report/log/locallib.php');
$id = required_param('id', PARAM_INT); // Course ID.
$type = required_param('type', PARAM_FILE); // Graph Type.
$user = required_param('user', PARAM_INT); // Student ID.
$date = optional_param('date', 0, PARAM_INT); // A time of a day (in GMT).
$logreader = optional_param('logreader', '', PARAM_COMPONENT);
$url = new moodle_url('/report/log/graph.php', array('id' => $id, 'type' => $type, 'user' => $user, 'date' => $date,
'logreader' => $logreader));
$PAGE->set_url($url);
if ($type !== "usercourse.png" and $type !== "userday.png") {
$type = 'userday.png';
}
$course = $DB->get_record("course", array("id" => $id), '*', MUST_EXIST);
$user = $DB->get_record("user", array("id" => $user, 'deleted' => 0), '*', MUST_EXIST);
$coursecontext = context_course::instance($course->id);
$personalcontext = context_user::instance($user->id);
if ($USER->id != $user->id and has_capability('moodle/user:viewuseractivitiesreport', $personalcontext)
and !is_enrolled($coursecontext, $USER) and is_enrolled($coursecontext, $user)) {
//TODO: do not require parents to be enrolled in courses - this is a hack!
require_login();
$PAGE->set_course($course);
} else {
require_login($course);
}
list($all, $today) = report_log_can_access_user_report($user, $course);
if ($type === "userday.png") {
if (!$today) {
require_capability('report/log:viewtoday', $coursecontext);
}
} else {
if (!$all) {
require_capability('report/log:view', $coursecontext);
}
}
$logs = array();
$timenow = time();
if ($type === "usercourse.png") {
$site = get_site();
if ($course->id == $site->id) {
$courseselect = 0;
} else {
$courseselect = $course->id;
}
$maxseconds = REPORT_LOG_MAX_DISPLAY * 3600 * 24; // Seconds.
if ($timenow - $course->startdate > $maxseconds) {
$course->startdate = $timenow - $maxseconds;
}
if (!empty($CFG->loglifetime)) {
$maxseconds = $CFG->loglifetime * 3600 * 24; // Seconds.
if ($timenow - $course->startdate > $maxseconds) {
$course->startdate = $timenow - $maxseconds;
}
}
$timestart = $coursestart = usergetmidnight($course->startdate);
if ((($timenow - $timestart) / 86400.0) > 40) {
$reducedays = 7;
} else {
$reducedays = 0;
}
$days = array();
$i = 0;
while ($timestart < $timenow) {
$timefinish = $timestart + 86400;
if ($reducedays) {
if ($i % $reducedays) {
$days[$i] = "";
} else {
$days[$i] = userdate($timestart, "%a %d %b");
}
} else {
$days[$i] = userdate($timestart, "%a %d %b");
}
$logs[$i] = 0;
$i++;
$timestart = $timefinish;
}
$rawlogs = report_log_usercourse($user->id, $courseselect, $coursestart, $logreader);
foreach ($rawlogs as $rawlog) {
$logs[$rawlog->day] = $rawlog->num;
}
$graph = new graph(750, 400);
if (empty($rawlogs)) {
$graph->parameter['y_axis_gridlines'] = 2;
$graph->parameter['y_max_left'] = 1;
}
$a = new stdClass();
$a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
$a->username = fullname($user, true);
$graph->parameter['title'] = get_string("hitsoncourse", "", $a);
$graph->x_data = $days;
$graph->y_data['logs'] = $logs;
$graph->y_order = array('logs');
// Make sure the Y-axis gridlines correspond to the integer values.
if (count($logs) && ($ymax = max($logs)) && ($graph->parameter['y_axis_gridlines'] > 1)) {
if ($ymax < $graph->parameter['y_axis_gridlines'] - 1) {
$graph->parameter['y_axis_gridlines'] = $ymax + 1;
} else if ($ymax % ($graph->parameter['y_axis_gridlines'] - 1)) {
$graph->parameter['y_max_left'] = $graph->parameter['y_max_right'] =
ceil($ymax/($graph->parameter['y_axis_gridlines'] - 1)) * ($graph->parameter['y_axis_gridlines'] - 1);
}
}
if (!empty($CFG->preferlinegraphs)) {
$graph->y_format['logs'] = array('colour' => 'blue', 'line' => 'line');
} else {
$graph->y_format['logs'] = array('colour' => 'blue', 'bar' => 'fill', 'bar_size' => 0.6);
$graph->parameter['bar_spacing'] = 0;
}
$graph->parameter['y_label_left'] = get_string("hits");
$graph->parameter['label_size'] = "12";
$graph->parameter['x_axis_angle'] = 90;
$graph->parameter['x_label_angle'] = 0;
$graph->parameter['tick_length'] = 0;
$graph->parameter['shadow'] = 'none';
error_reporting(5); // Ignore most warnings such as font problems etc.
$graph->draw_stack();
} else {
$site = get_site();
if ($course->id == $site->id) {
$courseselect = 0;
} else {
$courseselect = $course->id;
}
if ($date) {
$daystart = usergetmidnight($date);
} else {
$daystart = usergetmidnight(time());
}
$dayfinish = $daystart + 86400;
$hours = array();
for ($i = 0; $i <= 23; $i++) {
$logs[$i] = 0;
$hour = $daystart + $i * 3600;
$hours[$i] = $i;
}
$rawlogs = report_log_userday($user->id, $courseselect, $daystart, $logreader);
foreach ($rawlogs as $rawlog) {
$logs[$rawlog->hour] = $rawlog->num;
}
$graph = new graph(750, 400);
if (empty($rawlogs)) {
$graph->parameter['y_axis_gridlines'] = 2;
$graph->parameter['y_max_left'] = 1;
}
$a = new stdClass();
$a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
$a->username = fullname($user, true);
$graph->parameter['title'] = get_string("hitsoncoursetoday", "", $a);
$graph->x_data = $hours;
$graph->y_data['logs'] = $logs;
$graph->y_order = array('logs');
// Make sure the Y-axis gridlines correspond to the integer values.
if (count($logs) && ($ymax = max($logs)) && ($graph->parameter['y_axis_gridlines'] > 1)) {
if ($ymax < $graph->parameter['y_axis_gridlines'] - 1) {
$graph->parameter['y_axis_gridlines'] = $ymax + 1;
} else if ($ymax % ($graph->parameter['y_axis_gridlines'] - 1)) {
$graph->parameter['y_max_left'] = $graph->parameter['y_max_right'] =
ceil($ymax/($graph->parameter['y_axis_gridlines'] - 1)) * ($graph->parameter['y_axis_gridlines'] - 1);
}
}
if (!empty($CFG->preferlinegraphs)) {
$graph->y_format['logs'] = array('colour' => 'blue', 'line' => 'line');
} else {
$graph->y_format['logs'] = array('colour' => 'blue', 'bar' => 'fill', 'bar_size' => 0.9);
}
$graph->parameter['y_label_left'] = get_string("hits");
$graph->parameter['label_size'] = "12";
$graph->parameter['x_axis_angle'] = 0;
$graph->parameter['x_label_angle'] = 0;
$graph->parameter['shadow'] = 'none';
error_reporting(5); // Ignore most warnings such as font problems etc.
$graph->draw_stack();
}
require_once($CFG->libdir . '/filelib.php');
debugging('This way of generating the chart is deprecated, refer to report_log_print_graph().', DEBUG_DEVELOPER);
send_file_not_found();
......@@ -37,13 +37,19 @@ require_once(__DIR__.'/lib.php');
*
* @global stdClass $CFG
* @param stdClass $course course instance
* @param int $userid id of the user whose logs are needed
* @param string $type type of logs graph needed (usercourse.png/userday.png)
* @param int $date timestamp in GMT (seconds since epoch)
* @param int|stdClass $user id/object of the user whose logs are needed
* @param string $typeormode type of logs graph needed (usercourse.png/userday.png) or the mode (today, all).
* @param int $date timestamp in GMT (seconds since epoch)
* @param string $logreader Log reader.
* @return void
*/
function report_log_print_graph($course, $userid, $type, $date=0, $logreader='') {
function report_log_print_graph($course, $user, $typeormode, $date=0, $logreader='') {
global $CFG, $OUTPUT;
if (!is_object($user)) {
$user = core_user::get_user($user);
}
$logmanager = get_log_manager();
$readers = $logmanager->get_readers();
......@@ -56,10 +62,35 @@ function report_log_print_graph($course, $userid, $type, $date=0, $logreader='')
if (!($reader instanceof \core\log\sql_internal_table_reader) && !($reader instanceof logstore_legacy\log\store)) {
return array();
}
$coursecontext = context_course::instance($course->id);
$a = new stdClass();
$a->coursename = format_string($course->shortname, true, array('context' => $coursecontext));
$a->username = fullname($user, true);
if ($typeormode == 'today' || $typeormode == 'userday.png') {
$logs = report_log_usertoday_data($course, $user, $date, $logreader);
$title = get_string("hitsoncoursetoday", "", $a);
} elseif ($typeormode == 'all' || $typeormode == 'usercourse.png') {
$logs = report_log_userall_data($course, $user, $logreader);
$title = get_string("hitsoncourse", "", $a);
}
$url = new moodle_url('/report/log/graph.php', array('id' => $course->id, 'user' => $userid, 'type' => $type,
'date' => $date, 'logreader' => $logreader));
echo html_writer::empty_tag('img', array('src' => $url, 'alt' => ''));
if (!empty($CFG->preferlinegraphs)) {
$chart = new \core\chart_line();
} else {
$chart = new \core\chart_bar();
}
$series = new \core\chart_series(get_string("hits"), $logs['series']);
$chart->add_series($series);
$chart->set_title($title);
$chart->set_labels($logs['labels']);
$yaxis = $chart->get_yaxis(0, true);
$yaxis->set_label(get_string("hits"));
$yaxis->set_stepsize(max(1, round(max($logs['series']) / 10)));
echo $OUTPUT->render($chart);
}
/**
......@@ -500,3 +531,93 @@ function report_log_print_mnet_selector_form($hostid, $course, $selecteduser=0,
echo '</div>';
echo '</form>';
}
/**
* Fetch logs since the start of the courses and structure in series and labels to be sent to Chart API.
*
* @param stdClass $course the course object
* @param stdClass $user user object
* @param string $logreader the log reader where the logs are.
* @return array structured array to be sent to chart API, split in two indexes (series and labels).
*/
function report_log_userall_data($course, $user, $logreader) {
global $CFG;
$site = get_site();
$timenow = time();
$logs = [];
if ($course->id == $site->id) {
$courseselect = 0;
} else {
$courseselect = $course->id;
}
$maxseconds = REPORT_LOG_MAX_DISPLAY * 3600 * 24; // Seconds.
if ($timenow - $course->startdate > $maxseconds) {
$course->startdate = $timenow - $maxseconds;
}
if (!empty($CFG->loglifetime)) {
$maxseconds = $CFG->loglifetime * 3600 * 24; // Seconds.
if ($timenow - $course->startdate > $maxseconds) {
$course->startdate = $timenow - $maxseconds;
}
}
$timestart = $coursestart = usergetmidnight($course->startdate);
$i = 0;
while ($timestart < $timenow) {
$timefinish = $timestart + 86400;
$logs['labels'][$i] = userdate($timestart, "%a %d %b");
$logs['series'][$i] = 0;
$i++;
$timestart = $timefinish;
}
$rawlogs = report_log_usercourse($user->id, $courseselect, $coursestart, $logreader);
foreach ($rawlogs as $rawlog) {
$logs['series'][$rawlog->day] = $rawlog->num;
}
return $logs;
}
/**
* Fetch logs of the current day and structure in series and labels to be sent to Chart API.
*
* @param stdClass $course the course object
* @param stdClass $user user object
* @param int $date A time of a day (in GMT).
* @param string $logreader the log reader where the logs are.
* @return array $logs structured array to be sent to chart API, split in two indexes (series and labels).
*/
function report_log_usertoday_data($course, $user, $date, $logreader) {
$site = get_site();
$logs = [];
if ($course->id == $site->id) {
$courseselect = 0;
} else {
$courseselect = $course->id;
}
if ($date) {
$daystart = usergetmidnight($date);
} else {
$daystart = usergetmidnight(time());
}
for ($i = 0; $i <= 23; $i++) {
$hour = $daystart + $i * 3600;
$logs['series'][$i] = 0;
$logs['labels'][$i] = userdate($hour, "%H:00");
}
$rawlogs = report_log_userday($user->id, $courseselect, $daystart, $logreader);
foreach ($rawlogs as $rawlog) {
$logs['series'][$rawlog->hour] = $rawlog->num;
}
return $logs;
}
......@@ -126,17 +126,14 @@ if (!empty($reportlog->selectedlogreader)) {
echo $output->reader_selector($reportlog);
if ($mode === 'today') {
echo '<div class="graph">';
report_log_print_graph($course, $user->id, "userday.png", 0, $logreader);
echo '</div>';
echo $output->render($reportlog);
} else {
echo '<div class="graph">';
report_log_print_graph($course, $user->id, "usercourse.png", 0, $logreader);
echo '</div>';
if ($mode === 'all') {
$reportlog->selecteddate = 0;
echo $output->render($reportlog);
}
// Print the graphic chart accordingly to the mode (all, today).
echo '<div class="graph">';
report_log_print_graph($course, $user, $mode, 0, $logreader);
echo '</div>';
echo $output->render($reportlog);
echo $OUTPUT->footer();
\ No newline at end of file
......@@ -3,6 +3,9 @@ information provided here is intended especially for developers.
=== 3.2 ===
* Callback delete_course is deprecated and should be replaced with observer for event \core\event\course_content_deleted
* The report_log_print_graph signature and behaviour has changed to generate charts using
the new Chart API. The third argument has been renamed to $typeormode and it accepts
the type (usercourse.png, userday.png) or the mode (today, all).
=== 2.7 ===
* How to migrate reports accessing table 'log':
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment