mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-10579 more capability checks in grades code + refactoring of grade_tree
This commit is contained in:
parent
5d71ece008
commit
7a6b7acf76
72
grade/edit/action.php
Normal file
72
grade/edit/action.php
Normal file
@ -0,0 +1,72 @@
|
||||
<?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);
|
||||
|
||||
?>
|
@ -1,7 +1,7 @@
|
||||
<?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);
|
||||
|
@ -3,7 +3,6 @@
|
||||
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);
|
||||
|
@ -2,7 +2,6 @@
|
||||
|
||||
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);
|
||||
|
@ -1,8 +1,8 @@
|
||||
<?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);
|
||||
|
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
// $Id$
|
||||
<?php // $Id$
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
@ -26,7 +25,6 @@
|
||||
|
||||
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);
|
||||
@ -40,12 +38,15 @@ if (!$course = get_record('course', 'id', $courseid)) {
|
||||
}
|
||||
|
||||
require_login($course);
|
||||
|
||||
$context = get_context_instance(CONTEXT_COURSE, $course->id);
|
||||
//require_capability() here!!
|
||||
require_capability('moodle/grade:manage', $context);
|
||||
|
||||
// default return url
|
||||
$returnurl = 'tree.php?id='.$course->id;
|
||||
/// return tracking object
|
||||
$gpr = new grade_plugin_return(array('type'=>'edit', 'courseid'=>$courseid));
|
||||
$returnurl = $gpr->get_return_url(null);
|
||||
|
||||
//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!
|
||||
@ -59,7 +60,7 @@ if (empty($eid)) {
|
||||
if (!$element = $gtree->locate_element($eid)) {
|
||||
error('Incorrect element id!', $returnurl);
|
||||
}
|
||||
$object = $element['object'];
|
||||
$object = $element['object'];
|
||||
}
|
||||
|
||||
|
||||
@ -74,16 +75,6 @@ $navigation = build_navigation($nav);
|
||||
$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);
|
||||
@ -135,35 +126,6 @@ switch ($action) {
|
||||
}
|
||||
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;
|
||||
}
|
||||
@ -178,7 +140,7 @@ print_heading(get_string('categoriesedit', 'grades'));
|
||||
|
||||
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();
|
||||
|
||||
@ -198,43 +160,32 @@ die;
|
||||
|
||||
|
||||
|
||||
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=""/>';
|
||||
@ -275,7 +226,7 @@ function print_grade_tree($element, $moving) {
|
||||
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) {
|
||||
|
359
grade/lib.php
359
grade/lib.php
@ -1,5 +1,7 @@
|
||||
<?php //$Id$
|
||||
|
||||
require_once $CFG->libdir.'/gradelib.php';
|
||||
|
||||
/**
|
||||
* Print grading plugin selection popup form.
|
||||
*
|
||||
@ -91,7 +93,7 @@ function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $r
|
||||
}
|
||||
|
||||
/// 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' ) {
|
||||
@ -105,7 +107,7 @@ function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $r
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@ -140,13 +142,15 @@ class grade_plugin_return {
|
||||
* @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;
|
||||
@ -171,6 +175,10 @@ class grade_plugin_return {
|
||||
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;
|
||||
}
|
||||
@ -197,7 +205,7 @@ class grade_plugin_return {
|
||||
foreach($extras as $key=>$value) {
|
||||
$url .= $glue.$key.'='.$value;
|
||||
$glue = '&';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $url;
|
||||
@ -208,12 +216,15 @@ class grade_plugin_return {
|
||||
* @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.'" />';
|
||||
@ -234,15 +245,17 @@ class grade_plugin_return {
|
||||
* @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);
|
||||
@ -266,7 +279,7 @@ class grade_plugin_return {
|
||||
* @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;
|
||||
}
|
||||
|
||||
@ -276,7 +289,9 @@ class grade_plugin_return {
|
||||
$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;
|
||||
@ -293,4 +308,324 @@ class grade_plugin_return {
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
?>
|
||||
|
@ -127,7 +127,7 @@ $numusers = $report->get_numusers();
|
||||
$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
|
||||
|
@ -66,7 +66,7 @@ if (empty($last)) {
|
||||
|
||||
} else if (in_array('user', $reports)) {
|
||||
$last = 'user';
|
||||
|
||||
|
||||
} else {
|
||||
$last = reset($reports);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ if (has_capability('moodle/grade:viewall', $context)) {
|
||||
|
||||
} else if (has_capability('moodle/grade:view', $usercontext) and $course->showgrades) {
|
||||
// ok - can view grades of this user- parent most probably
|
||||
|
||||
|
||||
} else {
|
||||
$acces = false;
|
||||
}
|
||||
@ -77,7 +77,7 @@ $navigation = build_navigation($navlinks);
|
||||
|
||||
|
||||
/// 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
|
||||
@ -90,13 +90,13 @@ if ($access) {
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
@ -1,238 +0,0 @@
|
||||
<?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;
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
<?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);
|
||||
|
||||
}
|
||||
}
|
@ -91,7 +91,6 @@ require_once($CFG->libdir . '/grade/grade_grade.php');
|
||||
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 *****/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user