diff --git a/report/stats/graph.php b/report/stats/graph.php index 8505e33ac96..c8af213aceb 100644 --- a/report/stats/graph.php +++ b/report/stats/graph.php @@ -24,159 +24,7 @@ */ require('../../config.php'); -require_once($CFG->dirroot.'/report/stats/locallib.php'); -require_once($CFG->dirroot.'/lib/graphlib.php'); - -$courseid = required_param('course', PARAM_INT); -$report = required_param('report', PARAM_INT); -$time = required_param('time', PARAM_INT); -$mode = required_param('mode', PARAM_INT); -$userid = optional_param('userid', 0, PARAM_INT); -$roleid = optional_param('roleid',0,PARAM_INT); - -$url = new moodle_url('/report/stats/graph.php', array('course'=>$courseid, 'report'=>$report, 'time'=>$time, 'mode'=>$mode, 'userid'=>$userid, 'roleid'=>$roleid)); -$PAGE->set_url($url); - -$course = $DB->get_record("course", array("id"=>$courseid), '*', MUST_EXIST); -$coursecontext = context_course::instance($course->id); -$PAGE->set_context($coursecontext); - -if (!empty($userid)) { - $user = $DB->get_record('user', array('id'=>$userid, 'deleted'=>0), '*', MUST_EXIST); - $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); - } - - if (!report_stats_can_access_user_report($user, $course, true)) { - require_capability('report/stats:view', $coursecontext); - } -} else if ($mode === STATS_MODE_DETAILED) { - print_error('invaliduser'); -} else { - require_capability('report/stats:view', $coursecontext); -} - -stats_check_uptodate($course->id); - -$param = stats_get_parameters($time,$report,$course->id,$mode); - -if (!empty($userid)) { - $param->table = 'user_'.$param->table; -} - -// TODO: cleanup this ugly mess! -$sql = 'SELECT '.((empty($param->fieldscomplete)) ? 'id,roleid,timeend,' : '').$param->fields -.' FROM {stats_'.$param->table.'} WHERE ' -.(($course->id == SITEID) ? '' : ' courseid = '.$course->id.' AND ') - .((!empty($userid)) ? ' userid = '.$userid.' AND ' : '') - .((!empty($roleid)) ? ' roleid = '.$roleid.' AND ' : '') - . ((!empty($param->stattype)) ? ' stattype = \''.$param->stattype.'\' AND ' : '') - .' timeend >= '.$param->timeafter -.' '.$param->extras -.' ORDER BY timeend DESC'; - -$stats = $DB->get_records_sql($sql, $param->params); - -$stats = stats_fix_zeros($stats,$param->timeafter,$param->table,(!empty($param->line2)),(!empty($param->line3))); - -$stats = array_reverse($stats); - -$graph = new graph(750,400); - -$graph->parameter['legend'] = 'outside-right'; -$graph->parameter['legend_size'] = 10; -$graph->parameter['x_axis_angle'] = 90; -$graph->parameter['title'] = false; // moodle will do a nicer job. -$graph->y_tick_labels = null; - -if (empty($param->crosstab)) { - foreach ($stats as $stat) { - $graph->x_data[] = userdate($stat->timeend,get_string('strftimedate'),$CFG->timezone); - $graph->y_data['line1'][] = $stat->line1; - if (isset($stat->line2)) { - $graph->y_data['line2'][] = $stat->line2; - } - if (isset($stat->line3)) { - $graph->y_data['line3'][] = $stat->line3; - } - } - $graph->y_order = array('line1'); - $graph->y_format['line1'] = array('colour' => 'blue','line' => 'line','legend' => $param->line1); - if (!empty($param->line2)) { - $graph->y_order[] = 'line2'; - $graph->y_format['line2'] = array('colour' => 'green','line' => 'line','legend' => $param->line2); - } - if (!empty($param->line3)) { - $graph->y_order[] = 'line3'; - $graph->y_format['line3'] = array('colour' => 'red','line' => 'line','legend' => $param->line3); - } - $graph->y_tick_labels = false; - -} else { - $data = array(); - $times = array(); - $roles = array(); - $missedlines = array(); - $rolenames = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS, true); - foreach ($stats as $stat) { - $data[$stat->roleid][$stat->timeend] = $stat->line1; - if (!empty($stat->zerofixed)) { - $missedlines[] = $stat->timeend; - } - if ($stat->roleid != 0) { - if (!array_key_exists($stat->roleid,$roles)) { - $roles[$stat->roleid] = $rolenames[$stat->roleid]; - } - } else { - if (!array_key_exists($stat->roleid,$roles)) { - $roles[$stat->roleid] = get_string('all'); - } - } - if (!array_key_exists($stat->timeend,$times)) { - $times[$stat->timeend] = userdate($stat->timeend,get_string('strftimedate'),$CFG->timezone); - } - } - foreach (array_keys($times) as $t) { - foreach ($data as $roleid => $stuff) { - if (!array_key_exists($t, $stuff)) { - $data[$roleid][$t] = 0; - } - } - } - - $roleid = 0; - krsort($roles); // the same sorting as in table below graph - - $colors = array('green', 'blue', 'red', 'purple', 'yellow', 'olive', 'navy', 'maroon', 'gray', 'ltred', 'ltltred', 'ltgreen', 'ltltgreen', 'orange', 'ltorange', 'ltltorange', 'lime', 'ltblue', 'ltltblue', 'fuchsia', 'aqua', 'grayF0', 'grayEE', 'grayDD', 'grayCC', 'gray33', 'gray66', 'gray99'); - $colorindex = 0; - - foreach ($roles as $roleid=>$rname) { - ksort($data[$roleid]); - $graph->y_order[] = $roleid+1; - if ($roleid) { - $color = $colors[$colorindex++]; - $colorindex = $colorindex % count($colors); - } else { - $color = 'black'; - } - $graph->y_format[$roleid+1] = array('colour' => $color, 'line' => 'line','legend' => $rname); - } - foreach (array_keys($data[$roleid]) as $time) { - $graph->x_data[] = $times[$time]; - } - foreach ($data as $roleid => $t) { - foreach ($t as $time => $data) { - $graph->y_data[$roleid+1][] = $data; - } - } -} - -$graph->draw_stack(); +require_once($CFG->libdir . '/filelib.php'); +debugging('This way of generating the chart is deprecated, refer to report_stats_print_chart().', DEBUG_DEVELOPER); +send_file_not_found(); diff --git a/report/stats/locallib.php b/report/stats/locallib.php index 61fef2818db..84cad1651be 100644 --- a/report/stats/locallib.php +++ b/report/stats/locallib.php @@ -206,9 +206,9 @@ function report_stats_report($course, $report, $mode, $user, $roleid, $time) { if ($mode == STATS_MODE_DETAILED) { - echo '
'.get_string('statisticsgraph').'
'; + report_stats_print_chart($course->id, $report, $time, $mode, $userid); } else { - echo '
'.get_string('statisticsgraph').'
'; + report_stats_print_chart($course->id, $report, $time, $mode, null, $roleid); } $table = new html_table(); @@ -312,4 +312,115 @@ function report_stats_report($course, $report, $mode, $user, $roleid, $time) { echo html_writer::table($table); } } -} \ No newline at end of file +} + +/** + * Fetch statistics data and generate a line chart. + * + * The statistic chart can be view, posts separated by roles and dates. + * + * @param int $courseid course id. + * @param int $report the report type constant eg. STATS_REPORT_LOGINS as defined on statslib. + * @param int $time timestamp of the selected time period. + * @param int $mode the report mode, eg. STATS_MODE_DETAILED as defined on statslib. + * @param int $userid selected user id. + * @param int $roleid selected role id. + */ +function report_stats_print_chart($courseid, $report, $time, $mode, $userid = 0, $roleid = 0) { + global $DB, $CFG, $OUTPUT; + + $course = $DB->get_record("course", array("id" => $courseid), '*', MUST_EXIST); + $coursecontext = context_course::instance($course->id); + + stats_check_uptodate($course->id); + + $param = stats_get_parameters($time, $report, $course->id, $mode); + + if (!empty($userid)) { + $param->table = 'user_' . $param->table; + } + + // TODO: cleanup this ugly mess. + $sql = 'SELECT '.((empty($param->fieldscomplete)) ? 'id,roleid,timeend,' : '').$param->fields + .' FROM {stats_'.$param->table.'} WHERE ' + .(($course->id == SITEID) ? '' : ' courseid = '.$course->id.' AND ') + .((!empty($userid)) ? ' userid = '.$userid.' AND ' : '') + .((!empty($roleid)) ? ' roleid = '.$roleid.' AND ' : '') + . ((!empty($param->stattype)) ? ' stattype = \''.$param->stattype.'\' AND ' : '') + .' timeend >= '.$param->timeafter + .' '.$param->extras + .' ORDER BY timeend DESC'; + $stats = $DB->get_records_sql($sql, $param->params); + $stats = stats_fix_zeros($stats, $param->timeafter, $param->table, (!empty($param->line2)), + (!empty($param->line3))); + $stats = array_reverse($stats); + + $chart = new \core\chart_line(); + if (empty($param->crosstab)) { + $data = []; + $times = []; + foreach ($stats as $stat) { + // Build the array of formatted times indexed by timestamp used as labels. + if (!array_key_exists($stat->timeend, $times)) { + $times[$stat->timeend] = userdate($stat->timeend, get_string('strftimedate'), $CFG->timezone); + + // Just add the data if the time hasn't been added yet. + // The number of lines of data must match the number of labels. + $data['line1'][] = $stat->line1; + if (isset($stat->line2)) { + $data['line2'][] = $stat->line2; + } + if (isset($stat->line3)) { + $data['line3'][] = $stat->line3; + } + } + } + foreach ($data as $line => $serie) { + $series = new \core\chart_series($param->{$line}, array_values($serie)); + $chart->add_series($series); + } + } else { + $data = array(); + $times = array(); + $roles = array(); + $missedlines = array(); + $rolenames = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS, true); + + foreach ($stats as $stat) { + $data[$stat->roleid][$stat->timeend] = $stat->line1; + if (!empty($stat->zerofixed)) { + $missedlines[] = $stat->timeend; + } + if ($stat->roleid != 0) { + if (!array_key_exists($stat->roleid,$roles)) { + $roles[$stat->roleid] = $rolenames[$stat->roleid]; + } + } else { + if (!array_key_exists($stat->roleid,$roles)) { + $roles[$stat->roleid] = get_string('all'); + } + } + + // Build the array of formatted times indexed by timestamp used as labels. + if (!array_key_exists($stat->timeend, $times)) { + $times[$stat->timeend] = userdate($stat->timeend, get_string('strftimedate'), $CFG->timezone); + } + } + // Fill empty days with zero to avoid chart errors. + foreach (array_keys($times) as $t) { + foreach ($data as $roleid => $stuff) { + if (!array_key_exists($t, $stuff)) { + $data[$roleid][$t] = 0; + } + } + } + krsort($roles); + foreach ($roles as $roleid => $rolename) { + ksort($data[$roleid]); + $series = new \core\chart_series($rolename, array_values($data[$roleid])); + $chart->add_series($series); + } + } + $chart->set_labels(array_values($times)); + echo $OUTPUT->render_chart($chart, false); +} diff --git a/report/stats/user.php b/report/stats/user.php index 85841ea5357..e36c2b4bc21 100644 --- a/report/stats/user.php +++ b/report/stats/user.php @@ -137,7 +137,7 @@ if (empty($stats)) { print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/user.php?id='.$course->id.'&user='.$user->id.'&mode=outline'); } -echo '
'.get_string('statisticsgraph').'
'; +report_stats_print_chart($course->id, STATS_REPORT_USER_VIEW, $time, STATS_MODE_DETAILED, $user->id); // What the heck is this about? -- MD $stats = stats_fix_zeros($stats,$param->timeafter,$param->table,(!empty($param->line2)),(!empty($param->line3)));