diff --git a/lib/pluginlib.php b/lib/pluginlib.php index 9d788a765edf2..06fa73e10dd9b 100644 --- a/lib/pluginlib.php +++ b/lib/pluginlib.php @@ -465,7 +465,8 @@ public static function standard_plugins_list($type) { 'scormreport' => array( 'basic', - 'interactions' + 'interactions', + 'graphs' ), 'theme' => array( diff --git a/mod/scorm/report/graphs/graph.php b/mod/scorm/report/graphs/graph.php new file mode 100644 index 0000000000000..914d978f1beba --- /dev/null +++ b/mod/scorm/report/graphs/graph.php @@ -0,0 +1,188 @@ +. +/** + * Core Report class of graphs reporting plugin + * + * @package scormreport_graphs + * @copyright 2012 Ankit Kumar Agarwal + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + + +require_once(dirname(__FILE__) . '/../../../../config.php'); +require_once($CFG->libdir . '/graphlib.php'); +require_once($CFG->dirroot.'/mod/scorm/report/reportlib.php'); +require_once($CFG->dirroot.'/mod/scorm/locallib.php'); + +$scoid = required_param('scoid', PARAM_INT);// sco ID + +$sco = $DB->get_record('scorm_scoes', array('id'=>$scoid), '*', MUST_EXIST); +$scorm = $DB->get_record('scorm', array('id'=>$sco->scorm), '*', MUST_EXIST); +$cm = get_coursemodule_from_instance('scorm', $scorm->id, 0, false, MUST_EXIST); +$course = $DB->get_record('course', array('id'=>$scorm->course), '*', MUST_EXIST); + + +// Capability Checks +require_login($course, false, $cm); +$contextmodule = context_module::instance($cm->id); +require_capability('mod/scorm:viewreport', $contextmodule); + +// find out current groups mode +$currentgroup = groups_get_activity_group($cm, true); + +// Group Check +if (empty($currentgroup)) { + // all users who can attempt scoes + if (!$students = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', '', '', '', '', '', '', false)) { + echo $OUTPUT->notification(get_string('nostudentsyet')); + $nostudents = true; + $allowedlist = ''; + } else { + $allowedlist = array_keys($students); + } +} else { + // all users who can attempt scoes and who are in the currently selected group + if (!$groupstudents = get_users_by_capability($contextmodule, 'mod/scorm:savetrack', '', '', '', '', $currentgroup, '', false)) { + echo $OUTPUT->notification(get_string('nostudentsingroup')); + $nostudents = true; + $groupstudents = array(); + } + $allowedlist = array_keys($groupstudents); +} + +$params = array(); +list($usql, $params) = $DB->get_in_or_equal($allowedlist); +$params[] = $scoid; + +// Construct the SQL +$select = 'SELECT DISTINCT '.$DB->sql_concat('st.userid', '\'#\'', 'COALESCE(st.attempt, 0)').' AS uniqueid, '; +$select .= 'st.userid AS userid, st.scormid AS scormid, st.attempt AS attempt, st.scoid AS scoid '; +$from = 'FROM {scorm_scoes_track} st '; +$where = ' WHERE st.userid ' .$usql. ' and st.scoid = ?'; +$attempts = $DB->get_records_sql($select.$from.$where, $params); +// Determine Sco keys to be used +if (scorm_version_check($scorm->version, SCORM_13)) { + $maxkey = 'cmi.score.max'; + $minkey = 'cmi.score.min'; + $scorekey = 'cmi.score.raw'; +} else { + $maxkey = 'cmi.core.score.max'; + $minkey = 'cmi.core.score.min'; + $scorekey = 'cmi.core.score.raw'; +} +$bands = 11; +$bandwidth = 10; + +// Determine maximum % secured for each user. +$usergrades = array(); +$graphdata = array(); +for ($i = 0; $i < $bands; $i++) { + $graphdata[$i] = 0; +} +foreach ($attempts as $attempt) { + if ($trackdata = scorm_get_tracks($scoid, $attempt->userid, $attempt->attempt)) { + if (isset($trackdata->$scorekey)) { + $score = $trackdata->$scorekey; + if (!isset($trackdata->$minkey) || empty($trackdata->$minkey)) { + $minmark = 0; + } else { + $minmark = $trackdata->$minkey; + } + if (!isset($trackdata->$maxkey) || empty($trackdata->$maxkey)) { + $maxmark = 100; + } else { + $maxmark = $trackdata->$maxkey; + } + $range = ($maxmark - $minmark); + if (empty($range)) { + continue; + } + $percent = round((($score*100)/$range), 2); + if (empty($usergrades[$attempt->userid]) || !isset($usergrades[$attempt->userid]) || ($percent > $usergrades[$attempt->userid]) || ($usergrades[$attempt->userid] === '*')) { + $usergrades[$attempt->userid] = $percent; + } + unset($percent); + } else { + // User has made an attempt but either SCO was not able to record the score or something else is broken in SCO + if (!isset($usergrades[$attempt->userid])) { + $usergrades[$attempt->userid] = '*'; + } + } + } +} + +$bandlabels[] = get_string('invaliddata', 'scormreport_graphs'); +for ($i = 1; $i <= $bands-1; $i++) { + $bandlabels[] = ($i - 1) * $bandwidth . ' - ' . $i * $bandwidth; +} +// Recording all users who attempted the SCO,but resulting data was invalid. +foreach ($usergrades as $userpercent) { + if ($userpercent === '*') { + $graphdata[0]++; + } else { + $gradeband = floor($userpercent/10); + if ($gradeband != ($bands - 1)) { + $gradeband++; + } + $graphdata[$gradeband]++; + } +} + +$line = new graph(800, 600); +$line->parameter['title'] = ''; +$line->parameter['y_label_left'] = get_string('participants', 'scormreport_graphs'); +$line->parameter['x_label'] = get_string('percent', 'scormreport_graphs'); +$line->parameter['y_label_angle'] = 90; +$line->parameter['x_label_angle'] = 0; +$line->parameter['x_axis_angle'] = 60; + +//following two lines seem to silence notice warnings from graphlib.php +$line->y_tick_labels = null; +$line->offset_relation = null; + +$line->parameter['bar_size'] = 1; +// don't forget to increase spacing so that graph doesn't become one big block of colour +$line->parameter['bar_spacing'] = 10; +$line->x_data = $bandlabels; + +$line->y_format['allusers'] = array( + 'colour' => 'red', + 'bar' => 'fill', + 'shadow_offset' => 1, + 'legend' => get_string('allparticipants') +); +ksort($graphdata); +$line->y_data['allusers'] = $graphdata; +$line->y_order = array('allusers'); + +$ymax = max($line->y_data['allusers']); +$line->parameter['y_min_left'] = 0; // start at 0 +$line->parameter['y_max_left'] = $ymax; +$line->parameter['y_decimal_left'] = 0; // 2 decimal places for y axis. + +//pick a sensible number of gridlines depending on max value on graph. +$gridlines = $ymax; +while ($gridlines >= 10) { + if ($gridlines >= 50) { + $gridlines /= 5; + } else { + $gridlines /= 2; + } +} + +$line->parameter['y_axis_gridlines'] = $gridlines + 1; + +$line->draw(); diff --git a/mod/scorm/report/graphs/lang/en/scormreport_graphs.php b/mod/scorm/report/graphs/lang/en/scormreport_graphs.php new file mode 100644 index 0000000000000..f15cc6e904786 --- /dev/null +++ b/mod/scorm/report/graphs/lang/en/scormreport_graphs.php @@ -0,0 +1,31 @@ +. + +/** + * Strings for component 'scorm_basic' report plugin + * + * @package scormreport_graphs + * @copyright 2012 Ankit Kumar Agarwal + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +$string['participants'] = 'Number of Participants'; +$string['pluginname'] = 'Graph Report'; +$string['percent'] = 'Percent(%) Secured'; +$string['invaliddata'] = 'Not Enough Data'; + + + diff --git a/mod/scorm/report/graphs/report.php b/mod/scorm/report/graphs/report.php new file mode 100644 index 0000000000000..d9d532b103c80 --- /dev/null +++ b/mod/scorm/report/graphs/report.php @@ -0,0 +1,63 @@ +. +/** + * Core Report class of graphs reporting plugin + * + * @package scormreport_graphs + * @copyright 2012 Ankit Kumar Agarwal + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); +/** + * Main class to control the graphs reporting + * + * @package scormreport_graphs + * @copyright 2012 Ankit Kumar Agarwal + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +class scorm_graphs_report extends scorm_default_report { + /** + * Displays the full report + * + * @param stdClass $scorm full SCORM object + * @param stdClass $cm - full course_module object + * @param stdClass $course - full course object + * @param string $download - type of download being requested + */ + function display($scorm, $cm, $course, $download) { + global $DB, $OUTPUT, $PAGE; + + if ($groupmode = groups_get_activity_groupmode($cm)) { // Groups are being used + groups_print_activity_menu($cm, new moodle_url($PAGE->url)); + } + + if ($scoes = $DB->get_records('scorm_scoes', array("scorm"=>$scorm->id), 'id')) { + foreach ($scoes as $sco) { + if ($sco->launch != '') { + $imageurl = new moodle_url('/mod/scorm/report/graphs/graph.php', + array('scoid' => $sco->id)); + $graphname = $sco->title; + echo $OUTPUT->heading($graphname); + echo html_writer::tag('div', html_writer::empty_tag('img', + array('src' => $imageurl, 'alt' => $graphname)), + array('class' => 'graph')); + } + } + } + } +} diff --git a/mod/scorm/report/graphs/version.php b/mod/scorm/report/graphs/version.php new file mode 100644 index 0000000000000..19b6c13242b4b --- /dev/null +++ b/mod/scorm/report/graphs/version.php @@ -0,0 +1,30 @@ +. + + +/** + * Defines the version of scormreport_graphs + * + * @package scormreport_graphs + * @copyright 2012 Ankit Kumar Agarwal + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +defined('MOODLE_INTERNAL') || die(); + +$plugin->version = 2012021000; // The current plugin version (Date: YYYYMMDDXX) +$plugin->requires = 2011120500; // Requires this Moodle version +$plugin->component = 'scormreport_graphs'; // Full name of the plugin (used for diagnostics)