--- /dev/null
+<?php // $Id$
+
+require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
+
+$courseid = required_param('id', PARAM_INT);
+$action = required_param('action', PARAM_ALPHA);
+$eid = required_param('eid', PARAM_ALPHANUM);
+
+/// Make sure they can even access this course
+if (!$course = get_record('course', 'id', $courseid)) {
+ print_error('nocourseid');
+}
+require_login($course);
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+
+// default return url
+$gpr = new grade_plugin_return();
+$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/edit/tree.php?id='.$course->id);
+
+// get the grading tree object
+$gtree = new grade_tree($courseid, false, false);
+
+// what are we working with?
+if (!$element = $gtree->locate_element($eid)) {
+ error('Incorrect element id!', $returnurl);
+}
+$object = $element['object'];
+
+
+switch ($action) {
+ case 'hide':
+ if ($eid and confirm_sesskey()) {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
+ error('No permission to hide!', $returnurl);
+ }
+ $object->set_hidden(1);
+ }
+ break;
+
+ case 'show':
+ if ($eid and confirm_sesskey()) {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
+ error('No permission to show!', $returnurl);
+ }
+ $object->set_hidden(0);
+ }
+ break;
+
+ case 'lock':
+ if ($eid and confirm_sesskey()) {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context)) {
+ error('No permission to lock!', $returnurl);
+ }
+ $object->set_locked(1);
+ }
+ break;
+
+ case 'unlock':
+ if ($eid and confirm_sesskey()) {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context)) {
+ error('No permission to unlock!', $returnurl);
+ }
+ $object->set_locked(0);
+ }
+ break;
+}
+
+redirect($returnurl);
+//redirect($returnurl, 'debug delay', 5);
+
+?>
\ No newline at end of file
<?php //$Id$
+
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
-require_once $CFG->libdir.'/gradelib.php';
require_once 'calculation_form.php';
$courseid = required_param('courseid', PARAM_INT);
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
-require_once $CFG->libdir.'/gradelib.php';
require_once 'category_form.php';
$courseid = required_param('courseid', PARAM_INT);
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
-require_once $CFG->libdir.'/gradelib.php';
require_once 'grade_form.php';
$courseid = required_param('courseid', PARAM_INT);
<?php //$Id$
+
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
require_once $CFG->dirroot.'/grade/report/lib.php';
-require_once $CFG->libdir.'/gradelib.php';
require_once 'item_form.php';
$courseid = required_param('courseid', PARAM_INT);
-<?php
-// $Id$
+<?php // $Id$
///////////////////////////////////////////////////////////////////////////
// //
require_once '../../config.php';
require_once $CFG->dirroot.'/grade/lib.php';
-require_once $CFG->libdir.'/gradelib.php';
$courseid = required_param('id', PARAM_INT);
$action = optional_param('action', 0, PARAM_ALPHA);
}
require_login($course);
-
$context = get_context_instance(CONTEXT_COURSE, $course->id);
-//require_capability() here!!
+require_capability('moodle/grade:manage', $context);
+
+/// return tracking object
+$gpr = new grade_plugin_return(array('type'=>'edit', 'courseid'=>$courseid));
+$returnurl = $gpr->get_return_url(null);
-// default return url
-$returnurl = 'tree.php?id='.$course->id;
+//first make sure we have proper final grades - we need it for locking changes
+grade_regrade_final_grades($courseid);
// get the grading tree object
// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
if (!$element = $gtree->locate_element($eid)) {
error('Incorrect element id!', $returnurl);
}
- $object = $element['object'];
+ $object = $element['object'];
}
$moving = false;
switch ($action) {
- case 'edit':
- if ($eid and confirm_sesskey()) {
- if ($element['type'] == 'category') {
- redirect('category.php?courseid='.$course->id.'&id='.$object->id);
- } else {
- redirect('item.php?courseid='.$course->id.'&id='.$object->id);
- }
- }
- break;
-
case 'delete':
if ($eid) {
$confirm = optional_param('confirm', 0, PARAM_BOOL);
}
break;
- case 'hide':
- if ($eid and confirm_sesskey()) {
- $object->set_hidden(1);
- redirect($returnurl);
- }
- break;
-
- case 'show':
- if ($eid and confirm_sesskey()) {
- $object->set_hidden(0);
- redirect($returnurl);
- }
- break;
-
- case 'lock':
- if ($eid and confirm_sesskey()) {
- //TODO: add error handling in redirect
- $object->set_locked(1);
- redirect($returnurl);
- }
- break;
-
- case 'unlock':
- if ($eid and confirm_sesskey()) {
- $object->set_locked(0);
- redirect($returnurl);
- }
- break;
-
default:
break;
}
print_box_start('gradetreebox generalbox');
echo '<ul id="grade_tree">';
-print_grade_tree($gtree->top_element, $moving);
+print_grade_tree($gtree, $gtree->top_element, $moving, $gpr);
echo '</ul>';
print_box_end();
-function print_grade_tree($element, $moving) {
+function print_grade_tree(&$gtree, $element, $moving, &$gpr) {
global $CFG, $COURSE;
/// fetch needed strings
$strmove = get_string('move');
$strmovehere = get_string('movehere');
- $stredit = get_string('edit');
$strdelete = get_string('delete');
- $strhide = get_string('hide');
- $strshow = get_string('show');
- $strlock = get_string('lock', 'grades');
- $strunlock = get_string('unlock', 'grades');
$object = $element['object'];
$eid = $element['eid'];
/// prepare actions
- $actions = '<a href="tree.php?id='.$COURSE->id.'&action=edit&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" title="'.$stredit.'"/></a>';
+ $actions = $gtree->get_edit_icon($element, $gpr);
if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) {
$actions .= '<a href="tree.php?id='.$COURSE->id.'&action=delete&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" title="'.$strdelete.'"/></a>';
$actions .= '<a href="tree.php?id='.$COURSE->id.'&action=moveselect&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/move.gif" class="iconsmall" alt="'.$strmove.'" title="'.$strmove.'"/></a>';
}
- if ($object->is_locked()) {
- $actions .= '<a href="tree.php?id='.$COURSE->id.'&action=unlock&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/unlock.gif" class="iconsmall" alt="'.$strunlock.'" title="'.$strunlock.'"/></a>';
- } else {
- $actions .= '<a href="tree.php?id='.$COURSE->id.'&action=lock&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/lock.gif" class="iconsmall" alt="'.$strlock.'" title="'.$strlock.'"/></a>';
- }
+ $actions .= $gtree->get_locking_icon($element, $gpr);
+ $name = $object->get_name();
if ($object->is_hidden()) {
- $name = '<span class="dimmed_text">'.$object->get_name().'</span>';
- $actions .= '<a href="tree.php?id='.$COURSE->id.'&action=show&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" title="'.$strshow.'"/></a>';
- } else {
- $name = $object->get_name();
- $actions .= '<a href="tree.php?id='.$COURSE->id.'&action=hide&eid='.$eid.'&sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$strhide.'" title="'.$strhide.'"/></a>';
+ $name = '<span class="dimmed_text">'.$name.'</span>';
}
+ $actions .= $gtree->get_hiding_icon($element, $gpr);
/// prepare icon
$icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>';
echo '<li class="'.$element['type'].'">'.$icon.$name.$actions;
echo '<ul class="catlevel'.$element['depth'].'">';
foreach($element['children'] as $child_el) {
- print_grade_tree($child_el, $moving);
+ print_grade_tree($gtree, $child_el, $moving, $gpr);
}
echo '</ul></li>';
if ($element['depth'] > 1) {
<?php //$Id$
+require_once $CFG->libdir.'/gradelib.php';
+
/**
* Print grading plugin selection popup form.
*
}
/// editing scripts - not real plugins
- if (true) { //TODO: add proper capability here
+ if (has_capability('moodle/grade:manage', $context)) { //TODO: add proper capability here
$menu['edit']='--'.get_string('edit');
$url = 'edit/tree.php?id='.$courseid;
if ($active_type == 'edit' and $active_plugin == 'tree' ) {
}
/**
- * Utility class used for return tracking when using edit and other forms from grade plubins
+ * Utility class used for return tracking when using edit and other forms in grade plugins
*/
class grade_plugin_return {
var $type;
* @return array options
*/
function get_options() {
- if (empty($this->type) or empty($this->plugin)) {
+ if (empty($this->type)) {
return array();
}
$params = array();
- $params['plugin'] = $this->plugin;
+ if (!empty($this->plugin)) {
+ $params['plugin'] = $this->plugin;
+ }
if (!empty($this->courseid)) {
$params['id'] = $this->courseid;
function get_return_url($default, $extras=null) {
global $CFG;
+ if ($this->type == 'edit') {
+ return $CFG->wwwroot.'/grade/edit/tree.php?id='.$this->courseid;
+ }
+
if (empty($this->type) or empty($this->plugin)) {
return $default;
}
foreach($extras as $key=>$value) {
$url .= $glue.$key.'='.$value;
$glue = '&';
- }
+ }
}
return $url;
* @return string
*/
function get_form_fields() {
- if (empty($this->type) or empty($this->plugin)) {
+ if (empty($this->type)) {
return '';
}
$result = '<input type="hidden" name="gpr_type" value="'.$this->type.'" />';
- $result .= '<input type="hidden" name="gpr_plugin" value="'.$this->plugin.'" />';
+
+ if (!empty($this->plugin)) {
+ $result .= '<input type="hidden" name="gpr_plugin" value="'.$this->plugin.'" />';
+ }
if (!empty($this->courseid)) {
$result .= '<input type="hidden" name="gpr_courseid" value="'.$this->courseid.'" />';
* @return void
*/
function add_mform_elements(&$mform) {
- if (empty($this->type) or empty($this->plugin)) {
+ if (empty($this->type)) {
return;
}
$mform->addElement('hidden', 'gpr_type', $this->type);
$mform->setType('gpr_type', PARAM_SAFEDIR);
- $mform->addElement('hidden', 'gpr_plugin', $this->plugin);
- $mform->setType('gpr_plugin', PARAM_SAFEDIR);
+ if (!empty($this->plugin)) {
+ $mform->addElement('hidden', 'gpr_plugin', $this->plugin);
+ $mform->setType('gpr_plugin', PARAM_SAFEDIR);
+ }
if (!empty($this->courseid)) {
$mform->addElement('hidden', 'gpr_courseid', $this->courseid);
* @return string $url with erturn tracking params
*/
function add_url_params($url) {
- if (empty($this->type) or empty($this->plugin)) {
+ if (empty($this->type)) {
return $url;
}
$url .= '&gpr_type='.$this->type;
}
- $url .= '&gpr_plugin='.$this->plugin;
+ if (!empty($this->plugin)) {
+ $url .= '&gpr_plugin='.$this->plugin;
+ }
if (!empty($this->courseid)) {
$url .= '&gpr_courseid='.$this->courseid;
return $url;
}
}
+
+
+/**
+ * This class represents a complete tree of categories, grade_items and final grades,
+ * organises as an array primarily, but which can also be converted to other formats.
+ * It has simple method calls with complex implementations, allowing for easy insertion,
+ * deletion and moving of items and categories within the tree.
+ */
+class grade_tree {
+
+ /**
+ * The basic representation of the tree as a hierarchical, 3-tiered array.
+ * @var object $top_element
+ */
+ var $top_element;
+
+ /**
+ * A string of GET URL variables, namely courseid and sesskey, used in most URLs built by this class.
+ * @var string $commonvars
+ */
+ var $commonvars;
+
+ /**
+ * 2D array of grade items and categories
+ */
+ var $levels;
+
+ /**
+ * Constructor, retrieves and stores a hierarchical array of all grade_category and grade_item
+ * objects for the given courseid. Full objects are instantiated.
+ * and renumbering.
+ * @param int $courseid
+ * @param boolean $fillers include fillers and colspans, make the levels var "rectangular"
+ * @param boolean $category_grade_last category grade item is the last child
+ * @param boolean $aggregation_view Either full view (0) or compact view (1)
+ */
+ function grade_tree($courseid, $fillers=true, $category_grade_last=false,
+ $aggregation_view=GRADE_REPORT_AGGREGATION_VIEW_FULL) {
+ global $USER, $CFG;
+
+ $this->courseid = $courseid;
+ $this->commonvars = "&sesskey=$USER->sesskey&id=$this->courseid";
+ $this->levels = array();
+
+ // get course grade tree
+ $this->top_element = grade_category::fetch_course_tree($courseid, true);
+
+ if ($category_grade_last) {
+ grade_tree::category_grade_last($this->top_element);
+ }
+
+ if ($fillers) {
+ // inject fake categories == fillers
+ grade_tree::inject_fillers($this->top_element, 0);
+ // add colspans to categories and fillers
+ grade_tree::inject_colspans($this->top_element);
+ }
+
+ grade_tree::fill_levels($this->levels, $this->top_element, 0);
+ }
+
+
+ /**
+ * Static recursive helper - makes the grade_item for category the last children
+ * @static
+ * @param array $element The seed of the recursion
+ * @return void
+ */
+ function category_grade_last(&$element) {
+ if (empty($element['children'])) {
+ return;
+ }
+ if (count($element['children']) < 2) {
+ return;
+ }
+ $category_item = reset($element['children']);
+ $order = key($element['children']);
+ unset($element['children'][$order]);
+ $element['children'][$order] =& $category_item;
+ foreach ($element['children'] as $sortorder=>$child) {
+ grade_tree::category_grade_last($element['children'][$sortorder]);
+ }
+ }
+
+ /**
+ * Static recursive helper - fills the levels array, useful when accessing tree elements of one level
+ * @static
+ * @param int $levels
+ * @param array $element The seed of the recursion
+ * @param int $depth
+ * @return void
+ */
+ function fill_levels(&$levels, &$element, $depth) {
+ if (!array_key_exists($depth, $levels)) {
+ $levels[$depth] = array();
+ }
+
+ // prepare unique identifier
+ if ($element['type'] == 'category') {
+ $element['eid'] = 'c'.$element['object']->id;
+ } else if (in_array($element['type'], array('item', 'courseitem', 'categoryitem'))) {
+ $element['eid'] = 'i'.$element['object']->id;
+ }
+
+ $levels[$depth][] =& $element;
+ $depth++;
+ if (empty($element['children'])) {
+ return;
+ }
+ $prev = 0;
+ foreach ($element['children'] as $sortorder=>$child) {
+ grade_tree::fill_levels($levels, $element['children'][$sortorder], $depth);
+ $element['children'][$sortorder]['prev'] = $prev;
+ $element['children'][$sortorder]['next'] = 0;
+ if ($prev) {
+ $element['children'][$prev]['next'] = $sortorder;
+ }
+ $prev = $sortorder;
+ }
+ }
+
+ /**
+ * Static recursive helper - makes full tree (all leafes are at the same level)
+ */
+ function inject_fillers(&$element, $depth) {
+ $depth++;
+
+ if (empty($element['children'])) {
+ return $depth;
+ }
+ $chdepths = array();
+ $chids = array_keys($element['children']);
+ $last_child = end($chids);
+ $first_child = reset($chids);
+
+ foreach ($chids as $chid) {
+ $chdepths[$chid] = grade_tree::inject_fillers($element['children'][$chid], $depth);
+ }
+ arsort($chdepths);
+
+ $maxdepth = reset($chdepths);
+ foreach ($chdepths as $chid=>$chd) {
+ if ($chd == $maxdepth) {
+ continue;
+ }
+ for ($i=0; $i < $maxdepth-$chd; $i++) {
+ if ($chid == $first_child) {
+ $type = 'fillerfirst';
+ } else if ($chid == $last_child) {
+ $type = 'fillerlast';
+ } else {
+ $type = 'filler';
+ }
+ $oldchild =& $element['children'][$chid];
+ $element['children'][$chid] = array('object'=>'filler', 'type'=>$type, 'eid'=>'', 'depth'=>$element['object']->depth,'children'=>array($oldchild));
+ }
+ }
+
+ return $maxdepth;
+ }
+
+ /**
+ * Static recursive helper - add colspan information into categories
+ */
+ function inject_colspans(&$element) {
+ if (empty($element['children'])) {
+ return 1;
+ }
+ $count = 0;
+ foreach ($element['children'] as $key=>$child) {
+ $count += grade_tree::inject_colspans($element['children'][$key]);
+ }
+ $element['colspan'] = $count;
+ return $count;
+ }
+
+ /**
+ * Parses the array in search of a given eid and returns a element object with
+ * information about the element it has found.
+ * @param int $eid
+ * @return object element
+ */
+ function locate_element($eid) {
+ if (strpos($eid, 'g') === 0) {
+ // it is a grade construct a new object
+ $id = (int)substr($eid, 1);
+ if (!$grade = grade_grade::fetch(array('id'=>$id))) {
+ return null;
+ }
+ //extra security check - the grade item must be in this tree
+ if (!$item_el = $this->locate_element('i'.$grade->itemid)) {
+ return null;
+ }
+ $grade->grade_item =& $item_el['object']; // this may speedup grade_grade methods!
+ return array('eid'=>'g'.$id,'object'=>$grade, 'type'=>'grade');
+ }
+
+ // it is a category or item
+ foreach ($this->levels as $row) {
+ foreach ($row as $element) {
+ if ($element['type'] == 'filler') {
+ continue;
+ }
+ if ($element['eid'] == $eid) {
+ return $element;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Return edit icon for give element
+ * @param object $element
+ * @return string
+ */
+ function get_edit_icon($element, $gpr) {
+ global $CFG;
+
+ $context = get_context_instance(CONTEXT_COURSE, $this->courseid);
+ if (!has_capability('moodle/grade:manage', $context)) {
+ return '';
+ }
+
+ $object = $element['object'];
+
+ switch ($element['type']) {
+ case 'item':
+ case 'categoryitem':
+ case 'courseitem':
+ $url = $CFG->wwwroot.'/grade/edit/item.php?courseid='.$this->courseid.'&id='.$object->id;
+ $url = $gpr->add_url_params($url);
+ break;
+
+ case 'category':
+ $url = $CFG->wwwroot.'/grade/edit/category.php?courseid='.$this->courseid.'&id='.$object->id;
+ $url = $gpr->add_url_params($url);
+ break;
+
+ case 'grade':
+ //TODO: improve dealing with new grades
+ $url = $CFG->wwwroot.'/grade/edit/grade.php?courseid='.$this->courseid.'&id='.$object->id;
+ $url = $gpr->add_url_params($url);
+ break;
+
+ default:
+ $url = null;
+ }
+
+ if ($url) {
+ $stredit = get_string('edit');
+ return '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" title="'.$stredit.'"/></a>';
+
+ } else {
+ return '';
+ }
+ }
+
+ /**
+ * Return hiding icon for give element
+ * @param object $element
+ * @return string
+ */
+ function get_hiding_icon($element, $gpr) {
+ global $CFG;
+
+ $context = get_context_instance(CONTEXT_COURSE, $this->courseid);
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
+ return '';
+ }
+
+ if ($element['object']->is_hidden()) {
+ $strshow = get_string('show');
+ $url = $CFG->wwwroot.'/grade/edit/action.php?id='.$this->courseid.'&action=show&sesskey='.sesskey().'&eid='.$element['eid'];
+ $url = $gpr->add_url_params($url);
+ $action = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" title="'.$strshow.'"/></a>';
+
+ } else {
+ $strhide = get_string('hide');
+ $url = $CFG->wwwroot.'/grade/edit/action.php?id='.$this->courseid.'&action=hide&sesskey='.sesskey().'&eid='.$element['eid'];
+ $url = $gpr->add_url_params($url);
+ $action = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$strhide.'" title="'.$strhide.'"/></a>';
+ }
+ return $action;
+ }
+
+ /**
+ * Return locking icon for give element
+ * @param object $element
+ * @return string
+ */
+ function get_locking_icon($element, $gpr) {
+ global $CFG;
+
+ $context = get_context_instance(CONTEXT_COURSE, $this->courseid);
+
+ if ($element['object']->is_locked()) {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context)) {
+ return '';
+ }
+ $strunlock = get_string('unlock', 'grades');
+ $url = $CFG->wwwroot.'/grade/edit/action.php?id='.$this->courseid.'&action=unlock&sesskey='.sesskey().'&eid='.$element['eid'];
+ $url = $gpr->add_url_params($url);
+ $action = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/unlock.gif" class="iconsmall" alt="'.$strunlock.'" title="'.$strunlock.'"/></a>';
+
+ } else {
+ if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context)) {
+ return '';
+ }
+ $strlock = get_string('lock', 'grades');
+ $url = $CFG->wwwroot.'/grade/edit/action.php?id='.$this->courseid.'&action=lock&sesskey='.sesskey().'&eid='.$element['eid'];
+ $url = $gpr->add_url_params($url);
+ $action = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/lock.gif" class="iconsmall" alt="'.$strlock.'" title="'.$strlock.'"/></a>';
+ }
+ return $action;
+ }
+
+}
+
?>
$report->load_final_grades();
/// Print header
-print_header_simple($strgrades.':'.$reportname, ':'.$strgrades, $navigation,
+print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation,
'', '', true, $buttons, navmenu($course));
/// Print the plugin selector at the top
} else if (in_array('user', $reports)) {
$last = 'user';
-
+
} else {
$last = reset($reports);
}
} else if (has_capability('moodle/grade:view', $usercontext) and $course->showgrades) {
// ok - can view grades of this user- parent most probably
-
+
} else {
$acces = false;
}
/// Print header
-print_header_simple($strgrades.':'.$reportname, ':'.$strgrades, $navigation,
+print_header_simple($strgrades.': '.$reportname, ': '.$strgrades, $navigation,
'', '', true, '', navmenu($course));
/// Print the plugin selector at the top
// Create a report instance
$report = new grade_report_user($courseid, $gpr, $context, $userid);
-
+
$gradetotal = 0;
$gradesum = 0;
-
+
// print the page
print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
-
+
if ($report->fill_table()) {
echo $report->print_table(true);
}
+++ /dev/null
-<?php // $Id$
-
-///////////////////////////////////////////////////////////////////////////
-// //
-// NOTICE OF COPYRIGHT //
-// //
-// Moodle - Modular Object-Oriented Dynamic Learning Environment //
-// http://moodle.com //
-// //
-// Copyright (C) 2001-2003 Martin Dougiamas http://dougiamas.com //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation; either version 2 of the License, or //
-// (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License for more details: //
-// //
-// http://www.gnu.org/copyleft/gpl.html //
-// //
-///////////////////////////////////////////////////////////////////////////
-
-require_once $CFG->libdir . '/gradelib.php';
-
-/**
- * This class represents a complete tree of categories, grade_items and final grades,
- * organises as an array primarily, but which can also be converted to other formats.
- * It has simple method calls with complex implementations, allowing for easy insertion,
- * deletion and moving of items and categories within the tree.
- */
-class grade_tree {
-
- /**
- * The basic representation of the tree as a hierarchical, 3-tiered array.
- * @var object $top_element
- */
- var $top_element;
-
- /**
- * A string of GET URL variables, namely courseid and sesskey, used in most URLs built by this class.
- * @var string $commonvars
- */
- var $commonvars;
-
- /**
- * 2D array of grade items and categories
- */
- var $levels;
-
- /**
- * Constructor, retrieves and stores a hierarchical array of all grade_category and grade_item
- * objects for the given courseid. Full objects are instantiated.
- * and renumbering.
- * @param int $courseid
- * @param boolean $fillers include fillers and colspans, make the levels var "rectangular"
- * @param boolean $category_grade_last category grade item is the last child
- * @param boolean $aggregation_view Either full view (0) or compact view (1)
- */
- function grade_tree($courseid, $fillers=true, $category_grade_last=false,
- $aggregation_view=GRADE_REPORT_AGGREGATION_VIEW_FULL) {
- global $USER;
-
- $this->courseid = $courseid;
- $this->commonvars = "&sesskey=$USER->sesskey&id=$this->courseid";
- $this->levels = array();
-
- // get course grade tree
- $this->top_element = grade_category::fetch_course_tree($courseid, true);
-
- if ($category_grade_last) {
- grade_tree::category_grade_last($this->top_element);
- }
-
- if ($fillers) {
- // inject fake categories == fillers
- grade_tree::inject_fillers($this->top_element, 0);
- // add colspans to categories and fillers
- grade_tree::inject_colspans($this->top_element);
- }
-
- grade_tree::fill_levels($this->levels, $this->top_element, 0);
- }
-
-
- /**
- * Static recursive helper - makes the grade_item for category the last children
- * @static
- * @param array $element The seed of the recursion
- * @return void
- */
- function category_grade_last(&$element) {
- if (empty($element['children'])) {
- return;
- }
- if (count($element['children']) < 2) {
- return;
- }
- $category_item = reset($element['children']);
- $order = key($element['children']);
- unset($element['children'][$order]);
- $element['children'][$order] =& $category_item;
- foreach ($element['children'] as $sortorder=>$child) {
- grade_tree::category_grade_last($element['children'][$sortorder]);
- }
- }
-
- /**
- * Static recursive helper - fills the levels array, useful when accessing tree elements of one level
- * @static
- * @param int $levels
- * @param array $element The seed of the recursion
- * @param int $depth
- * @return void
- */
- function fill_levels(&$levels, &$element, $depth) {
- if (!array_key_exists($depth, $levels)) {
- $levels[$depth] = array();
- }
-
- // prepare unique identifier
- if ($element['type'] == 'category') {
- $element['eid'] = 'c'.$element['object']->id;
- } else if (in_array($element['type'], array('item', 'courseitem', 'categoryitem'))) {
- $element['eid'] = 'i'.$element['object']->id;
- }
-
- $levels[$depth][] =& $element;
- $depth++;
- if (empty($element['children'])) {
- return;
- }
- $prev = 0;
- foreach ($element['children'] as $sortorder=>$child) {
- grade_tree::fill_levels($levels, $element['children'][$sortorder], $depth);
- $element['children'][$sortorder]['prev'] = $prev;
- $element['children'][$sortorder]['next'] = 0;
- if ($prev) {
- $element['children'][$prev]['next'] = $sortorder;
- }
- $prev = $sortorder;
- }
- }
-
- /**
- * Static recursive helper - makes full tree (all leafes are at the same level)
- */
- function inject_fillers(&$element, $depth) {
- $depth++;
-
- if (empty($element['children'])) {
- return $depth;
- }
- $chdepths = array();
- $chids = array_keys($element['children']);
- $last_child = end($chids);
- $first_child = reset($chids);
-
- foreach ($chids as $chid) {
- $chdepths[$chid] = grade_tree::inject_fillers($element['children'][$chid], $depth);
- }
- arsort($chdepths);
-
- $maxdepth = reset($chdepths);
- foreach ($chdepths as $chid=>$chd) {
- if ($chd == $maxdepth) {
- continue;
- }
- for ($i=0; $i < $maxdepth-$chd; $i++) {
- if ($chid == $first_child) {
- $type = 'fillerfirst';
- } else if ($chid == $last_child) {
- $type = 'fillerlast';
- } else {
- $type = 'filler';
- }
- $oldchild =& $element['children'][$chid];
- $element['children'][$chid] = array('object'=>'filler', 'type'=>$type, 'eid'=>'', 'depth'=>$element['object']->depth,'children'=>array($oldchild));
- }
- }
-
- return $maxdepth;
- }
-
- /**
- * Static recursive helper - add colspan information into categories
- */
- function inject_colspans(&$element) {
- if (empty($element['children'])) {
- return 1;
- }
- $count = 0;
- foreach ($element['children'] as $key=>$child) {
- $count += grade_tree::inject_colspans($element['children'][$key]);
- }
- $element['colspan'] = $count;
- return $count;
- }
-
- /**
- * Parses the array in search of a given eid and returns a element object with
- * information about the element it has found.
- * @param int $eid
- * @return object element
- */
- function locate_element($eid) {
- if (strpos($eid, 'g') === 0) {
- // it is a grade construct a new object
- $id = (int)substr($eid, 1);
- if (!$grade = grade_grade::fetch(array('id'=>$id))) {
- return null;
- }
- //extra security check - the grade item must be in this tree
- if (!$item_el = $this->locate_element('i'.$grade->itemid)) {
- return null;
- }
- $grade->grade_item =& $item_el['object']; // this may speedup grade_grade methods!
- return array('eid'=>'g'.$id,'object'=>$grade, 'type'=>'grade');
- }
-
- // it is a category or item
- foreach ($this->levels as $row) {
- foreach ($row as $element) {
- if ($element['type'] == 'filler') {
- continue;
- }
- if ($element['eid'] == $eid) {
- return $element;
- }
- }
- }
-
- return null;
- }
-
-}
+++ /dev/null
-<?php // $Id$
-
-///////////////////////////////////////////////////////////////////////////
-// //
-// NOTICE OF COPYRIGHT //
-// //
-// Moodle - Modular Object-Oriented Dynamic Learning Environment //
-// http://moodle.org //
-// //
-// Copyright (C) 1999-2004 Martin Dougiamas http://dougiamas.com //
-// //
-// This program is free software; you can redistribute it and/or modify //
-// it under the terms of the GNU General Public License as published by //
-// the Free Software Foundation; either version 2 of the License, or //
-// (at your option) any later version. //
-// //
-// This program is distributed in the hope that it will be useful, //
-// but WITHOUT ANY WARRANTY; without even the implied warranty of //
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
-// GNU General Public License for more details: //
-// //
-// http://www.gnu.org/copyleft/gpl.html //
-// //
-///////////////////////////////////////////////////////////////////////////
-
-/**
- * Unit tests for grade_tree object.
- *
- * @author nicolas@moodle.com
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package moodlecore
- */
-
-if (!defined('MOODLE_INTERNAL')) {
- die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
-}
-
-require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
-
-class grade_tree_test extends grade_test {
-
- function test_grade_tree_locate_element() {
- //TODO: add test
- }
-
- function test_grade_tree_constructor() {
- $tree = new grade_tree($this->courseid);
-
- }
-}
require_once($CFG->libdir . '/grade/grade_scale.php');
require_once($CFG->libdir . '/grade/grade_outcome.php');
require_once($CFG->libdir . '/grade/grade_grade_text.php');
-require_once($CFG->libdir . '/grade/grade_tree.php');
/***** PUBLIC GRADE API *****/