MDL-55025 report_stats: Use the new charting library
authorSimey Lameze <simey@moodle.com>
Fri, 15 Jul 2016 06:11:14 +0000 (14:11 +0800)
committerDan Poltawski <dan@moodle.com>
Mon, 25 Jul 2016 09:43:22 +0000 (10:43 +0100)
Part of MDL-54987 epic.

report/stats/graph.php
report/stats/locallib.php
report/stats/user.php

index 8505e33..c8af213 100644 (file)
  */
 
 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();
index 61fef28..84cad16 100644 (file)
@@ -206,9 +206,9 @@ function report_stats_report($course, $report, $mode, $user, $roleid, $time) {
 
 
             if ($mode == STATS_MODE_DETAILED) {
-                echo '<div class="graph"><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.$mode.'&amp;course='.$course->id.'&amp;time='.$time.'&amp;report='.$report.'&amp;userid='.$userid.'" alt="'.get_string('statisticsgraph').'" /></div>';
+                report_stats_print_chart($course->id, $report, $time, $mode, $userid);
             } else {
-                echo '<div class="graph"><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.$mode.'&amp;course='.$course->id.'&amp;time='.$time.'&amp;report='.$report.'&amp;roleid='.$roleid.'" alt="'.get_string('statisticsgraph').'" /></div>';
+                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);
+}
index 85841ea..e36c2b4 100644 (file)
@@ -137,7 +137,7 @@ if (empty($stats)) {
     print_error('nostatstodisplay', '', $CFG->wwwroot.'/course/user.php?id='.$course->id.'&user='.$user->id.'&mode=outline');
 }
 
-echo '<center><img src="'.$CFG->wwwroot.'/report/stats/graph.php?mode='.STATS_MODE_DETAILED.'&course='.$course->id.'&time='.$time.'&report='.STATS_REPORT_USER_VIEW.'&userid='.$user->id.'" alt="'.get_string('statisticsgraph').'" /></center>';
+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)));