]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-9629 fixed regressions in grade reports caused by my previous commits, added...
authorskodak <skodak>
Sat, 30 Jun 2007 21:12:47 +0000 (21:12 +0000)
committerskodak <skodak>
Sat, 30 Jun 2007 21:12:47 +0000 (21:12 +0000)
16 files changed:
grade/report/grader/category.php
grade/report/grader/edit_category.php [new file with mode: 0644]
grade/report/grader/edit_category_form.php [new file with mode: 0644]
grade/report/grader/edit_item.php [new file with mode: 0644]
grade/report/grader/edit_item_form.php [new file with mode: 0644]
grade/report/grader/index.php
lib/db/install.xml
lib/db/upgrade.php
lib/grade/grade_category.php
lib/grade/grade_item.php
lib/grade/grade_tree.php
lib/gradelib.php
lib/simpletest/grade/simpletest/testgradecategory.php
lib/simpletest/grade/simpletest/testgradetree.php
pix/i/category_grade.gif [new file with mode: 0755]
version.php

index bd62841bc64e640496896a397eb5716330053008..2c3dc5167aefb3e9638e041a777bd4f5c2707965 100644 (file)
 //          http://www.gnu.org/copyleft/gpl.html                         //
 //                                                                       //
 ///////////////////////////////////////////////////////////////////////////
-set_time_limit(0);
+
 require_once '../../../config.php';
-require_once $CFG->libdir . '/grade/grade_tree.php';
-require_once $CFG->libdir . '/gradelib.php';
-
-/**
- * Returns a HTML list with sorting arrows and insert boxes. This is a recursive method.
- * @param int $level The level of recursion
- * @param array $elements The elements to display in a list. Defaults to this->tree_array
- * @param int $source_sortorder A source sortorder, given when an element needs to be moved or inserted.
- * @param string $action 'move' or 'insert'
- * @param string $source_type 'topcat', 'subcat' or 'item'
- * @return string HTML code
- */
-function get_edit_tree($gtree, $level = 1, $elements = NULL, $source_sortorder = NULL, $action = NULL, $source_type = NULL) {
-       global $CFG;
-       global $USER;
-
-       $strmove = get_string("move");
-       $strmoveup = get_string("moveup");
-       $strmovedown = get_string("movedown");
-       $strmovehere = get_string("movehere");
-       $strcancel = get_string("cancel");
-       $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');
-       $strnewcategory = get_string("newcategory", 'grades');
-       $strcategoryname = get_string("categoryname", 'grades');
-       $strcreatecategory = get_string("createcategory", 'grades');
-       $strsubcategory = get_string("subcategory", 'grades');
-       $stritems = get_string("items", 'grades');
-       $strcategories = get_string("categories", 'grades');
-
-       $list = '';
-       $closing_form_tags = '';
-
-       if (empty ($elements)) {
-               $list .= '<form action="category.php" method="post">' . "\n";
-               $list .= '<ul id="grade_edit_tree">' . "\n";
-               $elements = $gtree->tree_array['children'];
-
-               $element_type_options = '<select name="element_type">' . "\n";
-               $element_type_options .= "<option value=\"items\">$stritems</option><option value=\"categories\">$strcategories</option>\n";
-               $element_type_options .= "</select>\n";
-
-               $strforelementtypes = get_string("forelementtypes", 'grades', $element_type_options);
-
-               $closing_form_tags .= '<fieldset><legend>' . $strnewcategory . '</legend>' . "\n";
-               $closing_form_tags .= '<input type="hidden" name="sesskey" value="' . $USER->sesskey . '" />' . "\n";
-               $closing_form_tags .= '<input type="hidden" name="id" value="' . $gtree->courseid . '" />' . "\n";
-               $closing_form_tags .= '<input type="hidden" name="action" value="create" />' . "\n";
-               $closing_form_tags .= '<label for="category_name">' . $strcategoryname . '</label>' . "\n";
-               $closing_form_tags .= '<input id="category_name" type="text" name="category_name" size="40" />' . "\n";
-               $closing_form_tags .= '<input type="submit" value="' . $strcreatecategory . '" />' . "\n";
-               $closing_form_tags .= $strforelementtypes;
-               $closing_form_tags .= '</fieldset>' . "\n";
-               $closing_form_tags .= "</form>\n";
-       } else {
-               $list = '<ul class="level' . $level . 'children">' . "\n";
-       }
-
-       $first = true;
-       $count = 1;
-       $last = false;
-       $last_sortorder = null;
-
-       if (count($elements) == 1) {
-               $last = true;
-       }
-
-       foreach ($elements as $sortorder => $element) {
-               $object = $element['object'];
-        $previous_sortorder = $element['prev'];
-        $next_sortorder     = $element['next'];
-
-               $object_name = $object->get_name();
-               $object_class = get_class($object);
-               $object_parent = $object->get_parent_id();
-               $element_type = $gtree->get_element_type($element);
-
-               $highlight_class = '';
-
-               if ($source_sortorder == $sortorder && !empty ($action)) {
-                       $highlight_class = ' selected_element ';
-               }
-
-               // Prepare item icon if appropriate
-               $module_icon = '';
-               if (!empty ($object->itemmodule)) {
-                       $module_icon = '<div class="moduleicon">' . '<label for="checkbox_select_' . $sortorder . '">' . '<img src="' . $CFG->modpixpath . '/' . $object->itemmodule . '/icon.gif" alt="' . $object->itemmodule . '" title="' . $object->itemmodule . '" /></label></div>';
-               }
-
-               // Add dimmed_text span around object name if set to hidden
-               $hide_show = 'hide';
-               if ($object->is_hidden()) {
-                       $object_name = '<span class="dimmed_text">' . $object_name . '</span>';
-                       $hide_show = 'show';
-               }
-
-               // Prepare lock/unlock string
-               $lock_unlock = 'lock';
-               if ($object->is_locked()) {
-                       $lock_unlock = 'unlock';
-               }
-
-               // Prepare select checkbox for subcats and items
-               $select_checkbox = '';
-               if ($element_type != 'topcat') {
-                       $group = 'items';
-                       if ($element_type == 'subcat') {
-                               $group = 'categories';
-                       }
-
-                       $select_checkbox = '<div class="select_checkbox">' . "\n" . '<input id="checkbox_select_' . $sortorder . '" type="checkbox" name="' . $group . '[' . $sortorder . ']" />' . "\n" . '</div>' . "\n";
-
-                       // Add a label around the object name to trigger the checkbox
-                       $object_name = '<label for="checkbox_select_' . $sortorder . '">' . $object_name . '</label>';
-               }
-
-               $list .= '<li class="level' . $level . 'element sortorder' . $object->get_sortorder() . $highlight_class . '">' . "\n" . $select_checkbox . $module_icon . $object_name;
-
-               $list .= '<div class="icons">' . "\n";
-
-               // Print up arrow
-               if (!$first) {
-                       $list .= '<a href="category.php?' . "source=$sortorder&amp;moveup={$previous_sortorder}$gtree->commonvars\">\n";
-                       $list .= '<img src="' . $CFG->pixpath . '/t/up.gif" class="iconsmall" ' . 'alt="' . $strmoveup . '" title="' . $strmoveup . '" /></a>' . "\n";
-               } else {
-                       $list .= '<img src="' . $CFG->wwwroot . '/pix/spacer.gif" class="iconsmall" alt="" /> ' . "\n";
-               }
-
-               // Print down arrow
-               if (!$last) {
-                       $list .= '<a href="category.php?' . "source=$sortorder&amp;movedown={$next_sortorder}$gtree->commonvars\">\n";
-                       $list .= '<img src="' . $CFG->pixpath . '/t/down.gif" class="iconsmall" ' . 'alt="' . $strmovedown . '" title="' . $strmovedown . '" /></a>' . "\n";
-               } else {
-                       $list .= '<img src="' . $CFG->wwwroot . '/pix/spacer.gif" class="iconsmall" alt="" /> ' . "\n";
-               }
-
-               // Print move icon
-               if ($element_type != 'topcat') {
-                       $list .= '<a href="category.php?' . "source=$sortorder&amp;action=move&amp;type=$element_type$gtree->commonvars\">\n";
-                       $list .= '<img src="' . $CFG->pixpath . '/t/move.gif" class="iconsmall" alt="' . $strmove . '" title="' . $strmove . '" /></a>' . "\n";
-               } else {
-                       $list .= '<img src="' . $CFG->wwwroot . '/pix/spacer.gif" class="iconsmall" alt="" /> ' . "\n";
-               }
-
-               // Print edit icon
-               $list .= '<a href="category.php?' . "target=$sortorder&amp;action=edit$gtree->commonvars\">\n";
-               $list .= '<img src="' . $CFG->pixpath . '/t/edit.gif" class="iconsmall" alt="' .
-               $stredit . '" title="' . $stredit . '" /></a>' . "\n";
-
-               // Print delete icon
-               $list .= '<a href="category.php?' . "target=$sortorder&amp;action=delete$gtree->commonvars\">\n";
-               $list .= '<img src="' . $CFG->pixpath . '/t/delete.gif" class="iconsmall" alt="' .
-               $strdelete . '" title="' . $strdelete . '" /></a>' . "\n";
-
-               // Print hide/show icon
-               $list .= '<a href="category.php?' . "target=$sortorder&amp;action=$hide_show$gtree->commonvars\">\n";
-               $list .= '<img src="' . $CFG->pixpath . '/t/' . $hide_show . '.gif" class="iconsmall" alt="' .
-               ${ 'str' . $hide_show } . '" title="' . ${ 'str' . $hide_show } . '" /></a>' . "\n";
-               // Print lock/unlock icon
-               $list .= '<a href="category.php?' . "target=$sortorder&amp;action=$lock_unlock$gtree->commonvars\">\n";
-               $list .= '<img src="' . $CFG->pixpath . '/t/' . $lock_unlock . '.gif" class="iconsmall" alt="' .
-               ${ 'str' . $lock_unlock } . '" title="' . ${ 'str' . $lock_unlock } . '" /></a>' . "\n";
-
-               $list .= '</div> <!-- end icons div -->';
-
-               if (!empty ($element['children'])) {
-                       $list .= get_edit_tree($gtree, $level +1, $element['children'], $source_sortorder, $action, $source_type);
-               }
-
-               $list .= '</li>' . "\n";
-
-               $first = false;
-               $count++;
-               if ($count == count($elements)) {
-                       $last = true;
-               }
-
-               $last_sortorder = $sortorder;
-       }
-
-       // Add an insertion box if source_sortorder is given and a few other constraints are satisfied
-       if ($source_sortorder && !empty ($action)) {
-               $moving_item_near_subcat = $element_type == 'subcat' && $source_type == 'item' && $level > 1;
-               $moving_cat_to_lower_level = ($level == 2 && $source_type == 'topcat') || ($level > 2 && $source_type == 'subcat');
-               $moving_subcat_near_item_in_cat = $element_type == 'item' && $source_type == 'subcat' && $level > 1;
-               $moving_element_near_itself = $sortorder == $source_sortorder;
-
-               if (!$moving_item_near_subcat && !$moving_cat_to_lower_level && !$moving_subcat_near_item_in_cat && !$moving_element_near_itself) {
-                       $list .= '<li class="insertion">' . "\n";
-                       $list .= '<a href="category.php?' . "source=$source_sortorder&amp;$action=$last_sortorder$gtree->commonvars\">\n";
-                       $list .= '<img class="movetarget" src="' . $CFG->wwwroot . '/pix/movehere.gif" alt="' . $strmovehere . '" title="' . $strmovehere . '" />' . "\n";
-                       $list .= "</a>\n</li>";
-               }
-       }
-
-       $list .= '</ul>' . "\n$closing_form_tags";
-
-       return $list;
-}
+require_once $CFG->libdir.'/gradelib.php';
+
+$courseid = required_param('id', PARAM_INT);
+$action   = optional_param('action', 0, PARAM_ALPHA);
+$eid      = optional_param('eid', 0, PARAM_ALPHANUM);
 
-$param = new stdClass();
-
-$param->courseid = optional_param('id', 0, PARAM_INT);
-$param->moveup = optional_param('moveup', 0, PARAM_INT);
-$param->movedown = optional_param('movedown', 0, PARAM_INT);
-$param->source = optional_param('source', 0, PARAM_INT);
-$param->action = optional_param('action', 0, PARAM_ALPHA);
-$param->move = optional_param('move', 0, PARAM_INT);
-$param->type = optional_param('type', 0, PARAM_ALPHA);
-$param->target = optional_param('target', 0, PARAM_INT);
-$param->confirm = optional_param('confirm', 0, PARAM_INT);
-$param->items = optional_param('items', 0, PARAM_INT);
-$param->categories = optional_param('categories', 0, PARAM_INT);
-$param->element_type = optional_param('element_type', 0, PARAM_ALPHA);
-$param->category_name = optional_param('category_name', 0, PARAM_ALPHA);
-$courseid = $param->courseid;
 
 /// Make sure they can even access this course
 
@@ -252,175 +38,215 @@ if (!$course = get_record('course', 'id', $courseid)) {
        print_error('nocourseid');
 }
 
-require_login($course->id);
+require_login($course);
 
 $context = get_context_instance(CONTEXT_COURSE, $course->id);
+//require_capability() here!!
 
-$strgrades = get_string('grades');
-$strgraderreport = get_string('graderreport', 'grades');
-$strcategoriesedit = get_string('categoriesedit', 'grades');
-
-$crumbs[] = array (
-       'name' => $strgrades,
-       'link' => $CFG->wwwroot . '/grade/index.php?id=' . $courseid,
-       'type' => 'misc'
-);
-$crumbs[] = array (
-       'name' => $strgraderreport,
-       'link' => $CFG->wwwroot . '/grade/report.php?id=' . $courseid . '&amp;report=grader',
-       'type' => 'misc'
-);
-$crumbs[] = array (
-       'name' => $strcategoriesedit,
-       'link' => '',
-       'type' => 'misc'
-);
-
-$navigation = build_navigation($crumbs);
+// default return url
+$returnurl = 'category.php?id='.$course->id;
 
-print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+// get the grading tree object
+$gtree = new grade_tree($courseid, false);
 
-$gtree = new grade_tree($param->courseid, false);
-$select_source = false;
+if (empty($eid)) {
+    $element = null;
+    $object  = null;
 
-if (!empty ($param->action) && !empty ($param->source) && confirm_sesskey()) {
-       $element = $gtree->locate_element($param->source);
-       $element_name = $element['object']->get_name();
+} else {
+    if (!$element = $gtree->locate_element($eid)) {
+        error('Incorrect element id!', $returnurl);
+    }
+    $object  = $element['object'];
+}
 
-       $strselectdestination = get_string('selectdestination', 'grades', $element_name);
-       $strmovingelement = get_string('movingelement', 'grades', $element_name);
-       $strcancel = get_string('cancel');
 
-       print_heading($strselectdestination);
+$strgrades         = get_string('grades');
+$strgraderreport   = get_string('graderreport', 'grades');
+$strcategoriesedit = get_string('categoriesedit', 'grades');
 
-       echo $strmovingelement . ' (<a href="category.php?cancelmove=true' . $gtree->commonvars . '">' . $strcancel . '</a>)' . "\n";
+$nav = array(array('name'=>$strgrades,'link'=>$CFG->wwwroot.'/grade/index.php?id='.$courseid, 'type'=>'misc'),
+             array('name'=>$strgraderreport, 'link'=>$CFG->wwwroot.'/grade/report.php?id='.$courseid.'&amp;report=grader', 'type'=>'misc'),
+             array('name'=>$strcategoriesedit, 'link'=>'', 'type'=>'misc'));
+
+$navigation = build_navigation($nav);
+$moving = false;
+
+switch ($action) {
+    case 'edit':
+        if ($eid and confirm_sesskey()) {
+            if ($element['type'] == 'category') {
+                redirect('edit_category.php?courseid='.$course->id.'&amp;id='.$object->id);
+            } else {
+                redirect('edit_item.php?courseid='.$course->id.'&amp;id='.$object->id);
+            }
+        }
+        break;
+
+    case 'delete':
+        //TODO: implement deleting in grade items and categories
+        break;
+
+    case 'move':
+        if ($eid and confirm_sesskey()) {
+            $moveafter = required_param('moveafter', PARAM_ALPHANUM);
+            if(!$after_el = $gtree->locate_element($moveafter)) {
+                error('Incorect element id in moveafter', $returnurl);
+            }
+            $after = $after_el['object'];
+            $parent = $after->get_parent_category();
+            $sortorder = $after->get_sortorder();
+
+            $object->set_parent($parent->id);
+            $object->move_after_sortorder($sortorder);
+
+            redirect($returnurl);
+        }
+        break;
+
+    case 'moveselect':
+        if ($eid and confirm_sesskey()) {
+            $moving = $eid;
+        }
+        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;
 }
-elseif (!empty ($param->source) && confirm_sesskey()) {
-       if (!empty ($param->moveup)) {
-               $gtree->move_element($param->source, $param->moveup);
-       }
-       elseif (!empty ($param->movedown)) {
-               $gtree->move_element($param->source, $param->movedown, 'after');
-       }
-       elseif (!empty ($param->move)) {
-               $gtree->move_element($param->source, $param->move, 'after');
-       }
 
-}
-elseif (!empty ($param->target) && !empty ($param->action) && confirm_sesskey()) {
-       $element = $gtree->locate_element($param->target);
-       switch ($param->action) {
-               case 'edit' :
-                       break;
-               case 'delete' :
-                       if ($param->confirm == 1) { // Perform the deletion
-                               $gtree->remove_element($param->target);
-                               // Print result message
-
-                       } else { // Print confirmation dialog
-                               $strdeletecheckfull = get_string('deletecheck', '', $element['object']->get_name());
-                               $linkyes = "category.php?target=$param->target&amp;action=delete&amp;confirm=1$gtree->commonvars";
-                               $linkno = "category.php?$gtree->commonvars";
-                               notice_yesno($strdeletecheckfull, $linkyes, $linkno);
-                       }
-                       break;
-
-               case 'hide' :
-                       // TODO Implement calendar for selection of a date to hide element until
-                       if (!$element['object']->set_hidden(1)) {
-                               debugging("Could not update the element's hidden state!");
-                       } else {
-                               $gtree = new grade_tree($param->courseid, false);
-                       }
-                       break;
-               case 'show' :
-                       if (!$element['object']->set_hidden(0)) {
-                               debugging("Could not update the element's hidden state!");
-                       } else {
-                $gtree = new grade_tree($param->courseid, false);
-                       }
-                       break;
-               case 'lock' :
-                       // TODO Implement calendar for selection of a date to lock element after
-                       if (!$element['object']->set_locked(1)) {
-                               debugging("Could not update the element's locked state!");
-                       } else {
-                $gtree = new grade_tree($param->courseid, false);
-                       }
-                       break;
-               case 'unlock' :
-                       if (!$element['object']->set_locked(0)) {
-                               debugging("Could not update the element's locked state!");
-                       } else {
-                $gtree = new grade_tree($param->courseid, false);
-                       }
-                       break;
-               default :
-                       break;
-       }
-       unset ($param->target);
-}
-elseif (!empty ($param->element_type) && !empty ($param->action) && $param->action == 'create' && confirm_sesskey()) {
-       if (empty ($param->category_name)) {
-               notice(get_string('createcategoryerror', 'grades') . ': ' . get_string('nocategoryname', 'grades'));
-       }
-       elseif ($param->element_type == 'items') {
-
-               if (!empty ($param->items)) {
-                       $category = new grade_category();
-                       $category->fullname = $param->category_name;
-                       $category->courseid = $gtree->courseid;
-                       $category->insert();
-
-                       $items = array ();
-
-                       foreach ($param->items as $sortorder => $useless_var) {
-                               $element = $gtree->locate_element($sortorder);
-                               $items[$element['object']->id] = $element['object'];
-                       }
-
-                       if ($category->set_as_parent($items) && $category->update()) {
-                               $gtree = new grade_tree($param->courseid, false);
-                       } else { // creation of category didn't work, print a message
-                               debugging("Could not create a parent category over the items you selected..");
-                       }
-
-               } else { // No items selected. Can't create a category over them...
-                       notice(get_string('createcategoryerror', 'grades') . ': ' . get_string('noselecteditems', 'grades'));
-               }
-       }
-       elseif ($param->element_type == 'categories') {
-               if (!empty ($param->categories)) {
-                       $category = new grade_category();
-                       $category->fullname = $param->category_name;
-                       $category->courseid = $gtree->courseid;
-                       $category->insert();
-
-                       $categories = array ();
-                       foreach ($param->categories as $sortorder => $useless_var) {
-                               $element = $gtree->locate_element($sortorder);
-                               $categories[$element['object']->id] = $element['object'];
-                       }
-
-                       if ($category->set_as_parent($categories) && $category->update()) {
-                               $gtree = new grade_tree($param->courseid, false);
-                       } else { // creation of category didn't work, print a message
-                               debugging("Could not create a parent category over the categories you selected..");
-                       }
-
-               } else { // No categories selected. Can't create a category over them...
-                       notice(get_string('createcategoryerror', 'grades') . ': ' . get_string('noselectedcategories', 'grades'));
-               }
-
-       } else { // The element_type wasn't set properly, throw up an error
-
-       }
+print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+
+echo '<ul class="grade_tree">';
+print_grade_tree($gtree->top_element, $moving);
+echo '</ul>';
+
+if ($moving) {
+    print_single_button('category.php', array('id'=>$course->id), get_string('cancel'), 'get');
+} else {
+    print_single_button('edit_category.php', array('courseid'=>$course->id), get_string('addcategory', 'grades'), 'get');
+    print_single_button('edit_item.php', array('courseid'=>$course->id), get_string('additem', 'grades'), 'get');
 }
 
-print_heading(get_string('categoriesedit', 'grades'));
-// Add tabs
-$currenttab = 'editcategory';
-include ('tabs.php');
-echo get_edit_tree($gtree, 1, null, $param->source, $param->action, $param->type);
 print_footer($course);
+die;
+
+
+
+
+function print_grade_tree($element, $moving) {
+    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="category.php?id='.$COURSE->id.'&amp;action=edit&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'.$stredit.'" title="'.$stredit.'"/></a>';
+
+    if ($element['type'] == 'item' or ($element['type'] == 'category' and $element['depth'] > 1)) {
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=delete&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/delete.gif" class="iconsmall" alt="'.$strdelete.'" title="'.$strdelete.'"/></a>';
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=moveselect&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/move.gif" class="iconsmall" alt="'.$strmove.'" title="'.$strmove.'"/></a>';
+    }
+
+    if ($object->is_locked()) {
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=unlock&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/unlock.gif" class="iconsmall" alt="'.$strunlock.'" title="'.$strunlock.'"/></a>';
+    } else {
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=lock&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/lock.gif" class="iconsmall" alt="'.$strlock.'" title="'.$strlock.'"/></a>';
+    }
+
+    if ($object->is_hidden()) {
+        $name = '<span class="dimmed_text">'.$object->get_name().'</span>';
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=show&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.$strshow.'" title="'.$strshow.'"/></a>';
+    } else {
+        $name = $object->get_name();
+        $actions .= '<a href="category.php?id='.$COURSE->id.'&amp;action=hide&amp;eid='.$eid.'&amp;sesskey='.sesskey().'"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.$strhide.'" title="'.$strhide.'"/></a>';
+    }
+
+/// prepare icon
+    $icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>';
+    switch ($element['type']) {
+        case 'item':
+            if ($object->itemtype == 'mod') {
+                $icon = '<img src="'.$CFG->modpixpath.'/'.$object->itemmodule.'/icon.gif" class="icon" alt="'.get_string('modulename', $object->itemmodule).'"/>';
+            } else if ($object->itemtype == 'manual') {
+                //TODO: add manual grading icon
+                $icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'.get_string('manualgrade', 'grades').'"/>'; // TODO: localize
+            }
+            break;
+        case 'courseitem':
+        case 'categoryitem':
+            $icon = '<img src="'.$CFG->pixpath.'/i/category_grade.gif" class="icon" alt="'.get_string('categorygrade').'"/>'; // TODO: localize
+            break;
+        case 'category':
+            $icon = '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category').'"/>';
+            break;
+    }
+
+/// prepare move target if needed
+    $moveto = '';
+    if ($moving) {
+        $actions = ''; // no action icons when moving
+        $moveto = '<li><a href="category.php?id='.$COURSE->id.'&amp;action=move&amp;eid='.$moving.'&amp;moveafter='.$eid.'&amp;sesskey='.sesskey().'"><img class="movetarget" src="'.$CFG->wwwroot.'/pix/movehere.gif" alt="'.$strmovehere.'" title="'.$strmovehere.'" /></a></li>';
+    }
+
+/// print the list items now
+    if ($moving == $eid) {
+        // do not diplay children
+        echo '<li class="'.$element['type'].'">'.$icon.$name.'('.get_string('move').')</li>';
+
+    } else if ($element['type'] != 'category') {
+        echo '<li class="'.$element['type'].'">'.$icon.$name.$actions.'</li>'.$moveto;
+
+    } else {
+        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);
+        }
+        echo '</ul></li>';
+        if ($element['depth'] > 1) {
+            echo $moveto; // can not move after the top category
+        }
+    }
+}
+
+
 ?>
diff --git a/grade/report/grader/edit_category.php b/grade/report/grader/edit_category.php
new file mode 100644 (file)
index 0000000..9be5a3a
--- /dev/null
@@ -0,0 +1,64 @@
+<?php  //$Id$
+
+require_once '../../../config.php';
+require_once $CFG->libdir.'/gradelib.php';
+require_once 'edit_category_form.php';
+
+$courseid = required_param('courseid', PARAM_INT);
+$id       = optional_param('id', 0, PARAM_INT);
+
+if (!$course = get_record('course', 'id', $courseid)) {
+    print_error('nocourseid');
+}
+
+require_login($course);
+
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+//require_capability() here!!
+
+// default return url
+$returnurl = 'category.php?id='.$course->id;
+
+
+$mform = new edit_category_form();
+if ($category = get_record('grade_categories', 'id', $id, 'courseid', $course->id)) {
+    $mform->set_data($category);
+} else {
+    $mform->set_data(array('courseid'=>$course->id));
+}
+
+if ($mform->is_cancelled()) {
+    redirect($returnurl);
+
+} else if ($data = $mform->get_data()) {
+    $grade_category = new grade_category(array('id'=>$id, 'courseid'=>$course->id));
+    grade_category::set_properties($grade_category, $data);
+
+    if (empty($grade_category->id)) {
+        $grade_category->insert();
+
+    } else {
+        $grade_category->update();
+    }
+
+    redirect($returnurl);
+}
+
+
+$strgrades         = get_string('grades');
+$strgraderreport   = get_string('graderreport', 'grades');
+$strcategoriesedit = get_string('categoriesedit', 'grades');
+
+$nav = array(array('name'=>$strgrades,'link'=>$CFG->wwwroot.'/grade/index.php?id='.$courseid, 'type'=>'misc'),
+             array('name'=>$strgraderreport, 'link'=>$CFG->wwwroot.'/grade/report.php?id='.$courseid.'&amp;report=grader', 'type'=>'misc'),
+             array('name'=>$strcategoriesedit, 'link'=>'', 'type'=>'misc'));
+
+$navigation = build_navigation($nav);
+
+
+print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
+
+$mform->display();
+
+print_footer($course);
+die;
\ No newline at end of file
diff --git a/grade/report/grader/edit_category_form.php b/grade/report/grader/edit_category_form.php
new file mode 100644 (file)
index 0000000..6e0c5b8
--- /dev/null
@@ -0,0 +1,26 @@
+<?php //$Id$
+
+require_once $CFG->libdir.'/formslib.php';
+
+class edit_category_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        // visible elements
+        $mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
+
+        //TODO: add other elements
+
+        // hidden params
+        $mform->addElement('hidden', 'id', 0);
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'courseid', 0);
+        $mform->setType('courseid', PARAM_INT);
+
+//-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons();
+    }
+}
+?>
\ No newline at end of file
diff --git a/grade/report/grader/edit_item.php b/grade/report/grader/edit_item.php
new file mode 100644 (file)
index 0000000..7a081dc
--- /dev/null
@@ -0,0 +1,64 @@
+<?php  //$Id$
+
+require_once '../../../config.php';
+require_once $CFG->libdir.'/gradelib.php';
+require_once 'edit_item_form.php';
+
+$courseid = required_param('courseid', PARAM_INT);
+$id       = optional_param('id', 0, PARAM_INT);
+
+if (!$course = get_record('course', 'id', $courseid)) {
+    print_error('nocourseid');
+}
+
+require_login($course);
+
+$context = get_context_instance(CONTEXT_COURSE, $course->id);
+//require_capability() here!!
+
+// default return url
+$returnurl = 'category.php?id='.$course->id;
+
+
+$mform = new edit_item_form();
+if ($item = get_record('grade_items', 'id', $id, 'courseid', $course->id)) {
+    $mform->set_data($item);
+} else {
+    $mform->set_data(array('courseid'=>$course->id, 'itemtype'=>'manual'));
+}
+
+if ($mform->is_cancelled()) {
+    redirect($returnurl);
+
+} else if ($data = $mform->get_data()) {
+    $grade_item = new grade_item(array('id'=>$id, 'courseid'=>$course->id));
+    grade_item::set_properties($grade_item, $data);
+
+    if (empty($grade_item->id)) {
+        $grade_item->insert();
+
+    } else {
+        $grade_item->update();
+    }
+
+    redirect($returnurl);
+}
+
+
+$strgrades       = get_string('grades');
+$strgraderreport = get_string('graderreport', 'grades');
+$stritemsedit    = get_string('itemsedit', 'grades');
+
+$nav = array(array('name'=>$strgrades,'link'=>$CFG->wwwroot.'/grade/index.php?id='.$courseid, 'type'=>'misc'),
+             array('name'=>$strgraderreport, 'link'=>$CFG->wwwroot.'/grade/report.php?id='.$courseid.'&amp;report=grader', 'type'=>'misc'),
+             array('name'=>$stritemsedit, 'link'=>'', 'type'=>'misc'));
+
+$navigation = build_navigation($nav);
+
+
+print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $stritemsedit, $navigation, '', '', true, '', navmenu($course));
+
+$mform->display();
+
+print_footer($course);
+die;
\ No newline at end of file
diff --git a/grade/report/grader/edit_item_form.php b/grade/report/grader/edit_item_form.php
new file mode 100644 (file)
index 0000000..365169a
--- /dev/null
@@ -0,0 +1,29 @@
+<?php //$Id$
+
+require_once $CFG->libdir.'/formslib.php';
+
+class edit_item_form extends moodleform {
+    function definition() {
+        $mform =& $this->_form;
+
+        // visible elements
+        $mform->addElement('text', 'itemname', get_string('itemname', 'grades'));
+
+        //TODO: add other elements
+
+        // hidden params
+        $mform->addElement('hidden', 'id', 0);
+        $mform->setType('id', PARAM_INT);
+
+        $mform->addElement('hidden', 'courseid', 0);
+        $mform->setType('courseid', PARAM_INT);
+
+        $mform->addElement('hidden', 'itemtype', 0);
+        $mform->setType('itemtype', PARAM_ALPHA);
+
+//-------------------------------------------------------------------------------
+        // buttons
+        $this->add_action_buttons();
+    }
+}
+?>
\ No newline at end of file
index 7e3caf564f45e2fb4dadbf1e35bf7b85c2db14ec..427d08640a2d941aa7ab35b4e6e54b29b7cdf083 100644 (file)
@@ -100,27 +100,21 @@ if ($sortitemid) {
 // Perform actions on categories, items and grades
 if (!empty($target) && !empty($action) && confirm_sesskey()) {
 
-    // If targetting a grade, create a pseudo-element
-    if (preg_match('/^grade([0-9]*)/', $target, $matches)) {
-        $grade_grades_id = $matches[1];
-        $element = new stdClass();
-        $grade_grades = new grade_grades(array('id' => $grade_grades_id));
-        $element->element = array('object' => $grade_grades);
-    } else {
-        $element = $gtree->locate_element($target);
-    }
+    $element = $gtree->locate_element($target);
 
     switch ($action) {
         case 'edit':
             break;
         case 'delete':
             if ($confirm == 1) { // Perform the deletion
-                $element['object']->delete($target);
+                //TODO: add proper delete support for grade items and categories
+                //$element['object']->delete();
                 // Print result message
 
             } else { // Print confirmation dialog
+                $eid = $element['eid'];
                 $strdeletecheckfull = get_string('deletecheck', '', $element['object']->get_name());
-                $linkyes = "category.php?target=$target&amp;action=delete&amp;confirm=1$gtree->commonvars";
+                $linkyes = "category.php?target=$eid&amp;action=delete&amp;confirm=1$gtree->commonvars";
                 $linkno = "category.php?$gtree->commonvars";
                 notice_yesno($strdeletecheckfull, $linkyes, $linkno);
             }
@@ -281,7 +275,7 @@ $headerhtml = '';
 
 $numrows = count($gtree->levels);
 foreach ($gtree->levels as $key=>$row) {
-    if ($key ==0) {
+    if ($key == 0) {
         // do not diplay course grade category
         // continue;
     }
@@ -295,6 +289,10 @@ foreach ($gtree->levels as $key=>$row) {
     }
 
     foreach ($row as $element) {
+        $eid    = $element['eid'];
+        $object = $element['object'];
+        $type   = $element['type'];
+
         if (!empty($element['colspan'])) {
             $colspan = 'colspan="'.$element['colspan'].'"';
         } else {
@@ -316,7 +314,7 @@ foreach ($gtree->levels as $key=>$row) {
 
             // Print icons
             if ($USER->gradeediting) {
-                $headerhtml .= grade_get_icons($element['object'], $gtree) . '</td>';
+                $headerhtml .= grade_get_icons($element, $gtree) . '</td>';
             }
 
         } else {
@@ -339,7 +337,7 @@ foreach ($gtree->levels as $key=>$row) {
                       . $element['object']->id .'">'. $element['object']->get_name()
                       . '</a>' . $arrow;
 
-            $headerhtml .= grade_get_icons($element['object'], $gtree) . '</th>';
+            $headerhtml .= grade_get_icons($element, $gtree) . '</th>';
 
             $items[$element['object']->sortorder] =& $element['object'];
         }
@@ -410,11 +408,6 @@ foreach ($users as $userid => $user) {
             }
         }
 
-        // Do not show any icons if no grade (no record in DB to match)
-        if (!empty($grade_grades->id)) {
-            $studentshtml .= grade_get_icons($grade_grades, $gtree);
-        }
-
         $studentshtml .=  '</td>' . "\n";
     }
     $studentshtml .= '</tr>';
index 7c7c020419efe4fdfb0cd599b264c3af4d8bcf4f..e142e8dd0621ac4dbcf08c905c13f3cc33ce80eb 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20070628" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20070630" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this entry" PREVIOUS="timemodified"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="usermodified"/>
-        <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="primary"/>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="gradeid"/>
+        <KEY NAME="gradeid" TYPE="foreign" FIELDS="gradeid" REFTABLE="grade_grades" REFFIELDS="id" PREVIOUS="primary" NEXT="usermodified"/>
+        <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="gradeid"/>
       </KEYS>
     </TABLE>
     <TABLE NAME="grade_outcomes" COMMENT="This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2)" PREVIOUS="grade_grades_text" NEXT="grade_history">
index a952ada961f02a09853f662f7ad0c862520bda9d..0255c1b90e5981a0a35c3f8f4f3488d663696692 100644 (file)
@@ -952,7 +952,7 @@ function xmldb_main_upgrade($oldversion=0) {
     }
 
 /// clenaup and recreate tables for course grade
-    if ($result && $oldversion < 2007062800) {
+    if ($result && $oldversion < 2007063000) {
         /// Remove obsoleted unitt tests tables - they will be recreated automatically
         $tables = array('grade_categories',
                         'scale',
@@ -1106,6 +1106,7 @@ function xmldb_main_upgrade($oldversion=0) {
 
     /// Adding keys to table grade_grades_text
         $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->addKeyInfo('gradeid', XMLDB_KEY_FOREIGN, array('gradeid'), 'grade_grades', array('id'));
         $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
 
     /// Launch create table for grade_grades_text
@@ -1160,6 +1161,17 @@ function xmldb_main_upgrade($oldversion=0) {
 
     }
 
+    // add foreign key that was forgotten in last commit
+    if ($result && $oldversion < 2007063001) {
+
+    /// Define key gradeid (foreign) to be added to grade_grades_text
+        $table = new XMLDBTable('grade_grades_text');
+        $key = new XMLDBKey('gradeid');
+        $key->setAttributes(XMLDB_KEY_FOREIGN, array('gradeid'), 'grade_grades', array('id'));
+
+    /// Launch add key gradeid
+        add_key($table, $key);
+    }
     return $result;
 }
 
index a0d09d8fa3e5a0b8db5d2f80e65e6f675af53935..f4a770a7a602b839bd7c6a83be8aa8d16ca5d73e 100644 (file)
@@ -189,19 +189,26 @@ class grade_category extends grade_object {
      * @return boolean Success or failure.
      */
     function delete() {
-        $result = parent::delete();
+        if ($this->is_course_category()) {
+            debuggin('Can not delete top course category!');
+            return false;
+        }
 
-        if ($result) {
-            $this->load_parent_category();
-            if (!empty($this->parent_category)) {
-                $result = $result && $this->parent_category->force_regrading();
-            }
+        $grade_item = $this->load_grade_item();
+        $parent = $this->load_parent_category();
 
-            // Update children's categoryid/parent field
-            global $db;
-            $set_field_result = set_field('grade_items', 'categoryid', null, 'categoryid', $this->id);
-            $set_field_result = set_field('grade_categories', 'parent', null, 'parent', $this->id);
-        }
+        // Update children's categoryid/parent field first
+        $set_field_result = set_field('grade_items', 'categoryid', $parent->id, 'categoryid', $this->id);
+        $set_field_result = set_field('grade_categories', 'parent', $parent->id, 'parent', $this->id);
+
+        // first delete the attached grade item
+        $grade_item->delete();
+
+        // delete category itself
+        $result = parent::delete();
+
+        // force regrading of parent
+        $parent->force_regrading();
 
         return $result;
     }
@@ -529,28 +536,6 @@ class grade_category extends grade_object {
         return count_records('grade_categories', 'parent', $this->id) + count_records('grade_items', 'categoryid', $this->id);
     }
 
-    /**
-     * Checks whether an existing child exists for this category. If the new child is of a
-     * different type, the method will return false (not allowed). Otherwise it will return true.
-     * @param object $child This must be a complete object, not a stdClass
-     * @return boolean Success or failure
-     */
-    function can_add_child($child) {
-        if ($this->is_course_category()) {
-            return true;
-
-        } else if ($this->has_children()) {
-            if (get_class($child) != $this->get_childrentype()) {
-                return false;
-            } else {
-                return true;
-            }
-
-        } else {
-            return true;
-        }
-    }
-
     /**
      * Returns tree with all grade_items and categories as elements
      * @static
@@ -637,7 +622,7 @@ class grade_category extends grade_object {
             // prevent problems with duplicate sortorders in db
             $sortorder = $item->sortorder;
             while(array_key_exists($sortorder, $cats[$categoryid]->children)) {
-                echo "$sortorder exists in item loop<br>";
+                //debugging("$sortorder exists in item loop");
                 $sortorder++;
             }
 
@@ -652,7 +637,7 @@ class grade_category extends grade_object {
                 // prevent problems with duplicate sortorders in db
                 $sortorder = $cat->sortorder;
                 while(array_key_exists($sortorder, $cats[$cat->parent]->children)) {
-                    echo "$sortorder exists in cat loop<br>";
+                    //debugging("$sortorder exists in cat loop");
                     $sortorder++;
                 }
 
@@ -710,28 +695,6 @@ class grade_category extends grade_object {
         return $children_array;
     }
 
-    /**
-     * Check the type of the first child of this category, to see whether it is a
-     * grade_category or a grade_item, and returns that type as a string (get_class).
-     * @return string
-     */
-    function get_childrentype() {
-        if (empty($this->children)) {
-            $count_item_children = count_records('grade_items', 'categoryid', $this->id);
-            $count_cat_children = count_records('grade_categories', 'parent', $this->id);
-
-            if ($count_item_children > 0) {
-                return 'grade_item';
-            } elseif ($count_cat_children > 0) {
-                return 'grade_category';
-            } else {
-                return null;
-            }
-        }
-        reset($this->children);
-        return get_class(current($this->children));
-    }
-
     /**
      * Uses get_grade_item to load or create a grade_item, then saves it as $this->grade_item.
      * @return object Grade_item
@@ -805,40 +768,6 @@ class grade_category extends grade_object {
         }
     }
 
-    /**
-     * Sets this category as the parent for the given children.
-     * A number of constraints are necessary:
-     *    - The children must all be of the same type and at the same level (top level is exception)
-     *    - The children all belong to the same course
-     * @param array $children An array of fully instantiated grade_category OR grade_item objects
-     *
-     * @return boolean Success or Failure
-     */
-    function set_as_parent($children) {
-        global $CFG;
-
-        if (empty($children) || !is_array($children)) {
-            debugging("Passed an empty or non-array variable to grade_category::set_as_parent()");
-            return false;
-        }
-
-        $result = true;
-
-        foreach ($children as $child) {
-            // check sanity of course id
-            if ($child->courseid != $this->courseid) {
-                debugging("Attempted to set a category over children which do not belong to the same course.");
-                continue;
-            }
-            // change parrent if possible
-            if (!$child->set_parent_id($this->id)) {
-                $result = false;
-            }
-        }
-
-        return $result;
-    }
-
     /**
      * Returns the most descriptive field for this object. This is a standard method used
      * when we do not know the exact type of an object.
@@ -873,13 +802,24 @@ class grade_category extends grade_object {
 
     /**
      * Sets this category's parent id. A generic method shared by objects that have a parent id of some kind.
-     * @param id $parentid
+     * @param int parentid
+     * @return boolean success
      */
-    function set_parent_id($parentid) {
-        if (!$parent_category = grade_category::fetch(array('id'=>$parentid))) {
-            return false;
+    function set_parent($parentid) {
+        if ($this->parent == $parentid) {
+            return true;
+        }
+
+        if ($parentid == $this->id) {
+            error('Can not assign self as parent!');
+        }
+
+        if (empty($this->parent) and $this->is_course_category()) {
+            error('Course category can not have parent!');
         }
-        if (!$parent_category->can_add_child($this)) {
+
+        // find parent and check course id
+        if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
             return false;
         }
 
@@ -927,8 +867,13 @@ class grade_category extends grade_object {
         $this->grade_item->set_sortorder($sortorder);
     }
 
+    function move_after_sortorder($sortorder) {
+        $this->load_grade_item();
+        $this->grade_item->move_after_sortorder($sortorder);
+    }
+
     /**
-     * Return true if this is the top most categroy that represents the total course grade.
+     * Return true if this is the top most category that represents the total course grade.
      * @return boolean
      */
     function is_course_category() {
@@ -995,6 +940,16 @@ class grade_category extends grade_object {
     function set_hidden($hidden) {
         $this->load_grade_item();
         $this->grade_item->set_hidden($hidden);
+        if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
+            foreach($children as $child) {
+                $child->set_hidden($hidden);
+            }
+        }
+        if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
+            foreach($children as $child) {
+                $child->set_hidden($hidden);
+            }
+        }
     }
 
 }
index 6a1f7adedf06617b5cdcd565fe4d85da13bb85f4..471e99b9bd8852e864b06829475e756ced7fd54d 100644 (file)
@@ -40,7 +40,7 @@ class grade_item extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'formula', 'calculation_normalized', 'scale', 'category', 'parent_category', 'outcome');
+    var $nonfields = array('table', 'nonfields', 'formula', 'calculation_normalized', 'scale', 'item_category', 'parent_category', 'outcome');
 
     /**
      * The course this grade_item belongs to.
@@ -56,9 +56,9 @@ class grade_item extends grade_object {
 
     /**
      * The grade_category object referenced $this->iteminstance (itemtype must be == 'category' or == 'course' in that case).
-     * @var object $category
+     * @var object $item_category
      */
-    var $category;
+    var $item_category;
 
     /**
      * The grade_category object referenced by $this->categoryid.
@@ -318,7 +318,12 @@ class grade_item extends grade_object {
      * @return boolean Success or failure.
      */
     function delete() {
-        if ($category = $this->get_parent_category()) {
+        if ($this->is_course_item()) {
+            debuggin('Can not delete course or category item!');
+            return false;
+        }
+
+        if (!$this->is_category_item() and $category = $this->get_parent_category()) {
             $category->force_regrading();
         }
 
@@ -560,7 +565,7 @@ class grade_item extends grade_object {
 
         } else if ($this->is_category_item() or $this->is_course_item()) {
             // aggregate category grade item
-            $category = $this->get_category();
+            $category = $this->get_item_category();
             if (!$category->generate_grades()) {
                 return ("Could not calculate raw category grades id:".$this->id); // TODO: improve and localize
             }
@@ -719,11 +724,6 @@ class grade_item extends grade_object {
         if ($this->is_course_item()) {
             // no parent
 
-        } else if ($this->is_category_item()) {
-            $category = $this->load_category();
-            $parent = $category->load_parent_category();
-            $parent->force_regrading();
-
         } else {
             $parent = $this->load_parent_category();
             $parent->force_regrading();
@@ -771,64 +771,54 @@ class grade_item extends grade_object {
     }
 
     /**
-    * Returns the grade_category object this grade_item belongs to (referenced by categoryid).
+    * Returns the grade_category object this grade_item belongs to (referenced by categoryid)
+    * or category attached to category item.
     *
     * @return mixed grade_category object if applicable, false if course item
     */
     function get_parent_category() {
-
-        if ($this->is_course_item()) {
-            return false;
-
-        } else if ($this->is_category_item()) {
-
-            $category = $this->get_category();
-            return $category->get_parent_category();
+        if ($this->is_category_item() or $this->is_course_item()) {
+            return $this->get_item_category();
 
         } else {
-            $category = grade_category::fetch(array('id'=>$this->categoryid));
-            return $category;
+            return grade_category::fetch(array('id'=>$this->categoryid));
         }
     }
 
     /**
-    * Returns the grade_category object of associated category for category and course items
-    * (referenced by iteminstance).
+     * Calls upon the get_parent_category method to retrieve the grade_category object
+     * from the DB and assigns it to $this->parent_category. It also returns the object.
+     * @return object Grade_category
+     */
+    function load_parent_category() {
+        if (empty($this->parent_category->id)) {
+            $this->parent_category = $this->get_parent_category();
+        }
+        return $this->parent_category;
+    }
+
+    /**
+    * Returns the grade_category for category item
     *
     * @return mixed grade_category object if applicable, false otherwise
     */
-    function get_category() {
+    function get_item_category() {
         if (!$this->is_course_item() and !$this->is_category_item()) {
             return false;
         }
-
-        $category = grade_category::fetch(array('id'=>$this->iteminstance));
-        $category->grade_item =& $this;
-        return $category;
+        return grade_category::fetch(array('id'=>$this->iteminstance));
     }
 
     /**
-     * Calls upon the get_category method to retrieve the grade_category object
-     * from the DB and assigns it to $this->category. It also returns the object.
+     * Calls upon the get_item_category method to retrieve the grade_category object
+     * from the DB and assigns it to $this->item_category. It also returns the object.
      * @return object Grade_category
      */
-    function load_category() {
+    function load_item_category() {
         if (empty($this->category->id)) {
-            $this->category = $this->get_category();
+            $this->item_category = $this->get_item_category();
         }
-        return $this->category;
-    }
-
-    /**
-     * Calls upon the get_category method to retrieve the grade_category object
-     * from the DB and assigns it to $this->category. It also returns the object.
-     * @return object Grade_category
-     */
-    function load_parent_category() {
-        if (empty($this->parent_category->id)) {
-            $this->parent_category = $this->get_parent_category();
-        }
-        return $this->parent_category;
+        return $this->item_category;
     }
 
     function is_category_item() {
@@ -978,29 +968,37 @@ class grade_item extends grade_object {
      * @return void
      */
     function set_sortorder($sortorder) {
-        if ($this->sortorder == $sortorder) {
-            return;
-        }
-
         $this->sortorder = $sortorder;
         $this->update();
     }
 
+    function move_after_sortorder($sortorder) {
+        global $CFG;
+
+        //make some room first
+        $sql = "UPDATE {$CFG->prefix}grade_items
+                   SET sortorder = sortorder + 1
+                 WHERE sortorder > $sortorder AND courseid = {$this->courseid}";
+        execute_sql($sql);
+
+        $this->set_sortorder($sortorder + 1);
+    }
+
     /**
      * Returns the most descriptive field for this object. This is a standard method used
      * when we do not know the exact type of an object.
      * @return string name
      */
     function get_name() {
-        if ($this->is_course_item()) {
-            return get_string('total'); // TODO: localize
+        if (!empty($this->itemname)) {
+            return $this->itemname;
 
-        } else if ($this->is_category_item()) {
-            $category = $this->get_category();
-            return 'Category<br />grade'; // TODO: localize
+        } else if ($this->is_course_item()) {
+            return get_string('total');
 
         } else {
-            return $this->itemname;
+            return get_string('grade');
+
         }
     }
 
@@ -1019,7 +1017,17 @@ class grade_item extends grade_object {
      * @return int $parentid
      */
     function get_parent_id() {
-        return $this->categoryid;
+        if ($this->is_course_item()) {
+            return false;
+
+        } else if ($this->is_category_item()) {
+
+            return $category->id;
+
+        } else {
+            return $this->categoryid;
+;
+        }
     }
 
     /**
@@ -1027,13 +1035,20 @@ class grade_item extends grade_object {
      * @param int $parentid
      * @return boolean success;
      */
-    function set_parent_id($parentid) {
-        if (!$parent_category = grade_category::fetch(array('id'=>$parentid))) {
-            return false;
+    function set_parent($parentid) {
+        if ($this->is_course_item() or $this->is_category_item()) {
+            error('Can not set parent for category or course item!');
         }
-        if (!$parent_category->can_add_child($this)) {
+
+        if ($this->categoryid == $parentid) {
+            return true;
+        }
+
+        // find parent and check course id
+        if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
             return false;
         }
+
         $this->force_regrading(); // mark old parent as needing regrading
 
         // set new parent
@@ -1062,7 +1077,7 @@ class grade_item extends grade_object {
                 return array();
             }
 
-        } else if ($grade_category = $this->load_category()) {
+        } else if ($grade_category = $this->load_item_category()) {
             $sql = "SELECT gi.id
                       FROM {$CFG->prefix}grade_items gi
                      WHERE gi.categoryid ={$grade_category->id}
index 9c52a9c41d5fdccb927aca80ea3b57f5fa4ca968..7f915d91ca597ef79b4a19c53a2971896accc69c 100644 (file)
@@ -35,9 +35,9 @@ class grade_tree {
 
     /**
      * The basic representation of the tree as a hierarchical, 3-tiered array.
-     * @var array $tree_array
+     * @var object $top_element
      */
-    var $tree_array = array();
+    var $top_element;
 
     /**
      * Whether or not this grade_tree should load and store all the grades in addition to the categories and items.
@@ -74,16 +74,16 @@ class grade_tree {
         $this->levels = array();
 
         // get course grade tree
-        $this->tree_array =& grade_category::fetch_course_tree($courseid, $include_grades, true);
+        $this->top_element =& grade_category::fetch_course_tree($courseid, $include_grades, true);
 
         if ($fillers) {
             // inject fake categories == fillers
-            grade_tree::inject_fillers($this->tree_array, 0);
+            grade_tree::inject_fillers($this->top_element, 0);
             // add colspans to categories and fillers
-            grade_tree::inject_colspans($this->tree_array);
+            grade_tree::inject_colspans($this->top_element);
         }
 
-        grade_tree::fill_levels($this->levels, $this->tree_array, 0);
+        grade_tree::fill_levels($this->levels, $this->top_element, 0);
     }
 
 
@@ -143,7 +143,7 @@ class grade_tree {
             }
             for ($i=0; $i < $maxdepth-$chd; $i++) {
                 $oldchild =& $element['children'][$chid];
-                $element['children'][$chid] = array('object'=>'filler', 'type'=>'filler', 'depth'=>$element['object']->depth,'children'=>array($oldchild));
+                $element['children'][$chid] = array('object'=>'filler', 'type'=>'filler', 'eid'=>'', 'depth'=>$element['object']->depth,'children'=>array($oldchild));
             }
         }
 
@@ -166,19 +166,18 @@ class grade_tree {
     }
 
     /**
-     * Parses the array in search of a given sort order (the elements are indexed by
-     * sortorder), and returns a stdClass object with vital information about the
-     * element it has found.
-     * @param int $sortorder
+     * 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($sortorder) {
+    function locate_element($eid) {
         foreach ($this->levels as $row) {
             foreach ($row as $element) {
-                if (empty($element['object']->sortorder)) {
+                if ($element['type'] == 'filler') {
                     continue;
                 }
-                if ($element['object']->sortorder == $sortorder) {
+                if ($element['eid'] == $eid) {
                     return $element;
                 }
             }
@@ -209,166 +208,4 @@ class grade_tree {
 
         return 'item';
     }
-
-    /**
-     * Removes the given element (a stdClass object or a sortorder), remove_elements
-     * it from the tree. This does not renumber the tree. If a sortorder (int) is given, this
-     * method will first retrieve the referenced element from the tree, then re-run the method with that object.
-     * @var object $element An stdClass object typically returned by $this->locate(), or a sortorder (int)
-     * @return boolean
-     */
-    function remove_element($element) {
-        //TODO: fix me
-        return false;
-/*
-        if (empty($this->first_sortorder)) {
-            $this->reset_first_sortorder();
-        }
-
-        if (isset($element->index)) {
-            // Decompose the element's index and build string for eval(unset) statement to follow
-            $indices = explode('/', $element->index);
-            $element_to_unset = '$this->tree_array[' . $indices[0] . ']';
-
-            if (isset($indices[1])) {
-                $element_to_unset .= "['children'][" . $indices[1] . ']';
-            }
-
-            if (isset($indices[2])) {
-                $element_to_unset .= "['children'][" . $indices[2] . ']';
-            }
-
-            eval("unset($element_to_unset);");
-
-            if (empty($element->element['object'])) {
-                debugging("Could not delete this element from the DB due to missing information.");
-                return false;
-            }
-
-            $this->need_delete[$element->element['object']->id] = $element->element['object'];
-
-            return true;
-        } else {
-            $element = $this->locate_element($element);
-            if (!empty($element)) {
-                return $this->remove_element($element);
-            } else {
-                debugging("The element you provided grade_tree::remove_element() is not valid.");
-                return false;
-            }
-        }
-
-        debugging("Unable to remove an element from the grade_tree.");
-        return false;*/
-    }
-
-    /**
-     * Inserts an element in the tree. This can be either an array as returned by the grade_category methods, or
-     * an element object returned by grade_tree.
-     * @param mixed $element array or object. If object, the sub-tree is contained in $object->element
-     * @param int $destination_sortorder Where to insert the element
-     * @param string $position Either 'before' the destination_sortorder or 'after'
-     * @param boolean
-     */
-    function insert_element($element, $destination_sortorder, $position='before') {
-        //TODO: fix me
-        return false;
-/*        if (empty($this->first_sortorder)) {
-            $this->reset_first_sortorder();
-        }
-
-        if ($position == 'before') {
-            $offset = -1;
-        } elseif ($position == 'after') {
-            $offset = 0;
-        } else {
-            debugging('move_element(..... $position) can only be "before" or "after", you gave ' . $position);
-            return false;
-        }
-
-        if (is_array($element)) {
-            $new_element = new stdClass();
-            $new_element->element = $element;
-        } elseif (is_object($element)) {
-            $new_element = $element;
-        }
-
-        $new_element_class = get_class($new_element->element['object']);
-        $has_final_grades = !empty($new_element->element['final_grades']);
-
-        // If the object is a grade_item, but the final_grades index isn't yet loaded, make the switch now. Same for grade_category and children
-        if ($new_element_class == 'grade_item' && !$has_final_grades && $this->include_grades) {
-            $new_element->element['final_grades'] = $new_element->element['object']->get_final();
-
-        } elseif ($new_element_class == 'grade_category' && empty($new_element->element['children']) && $new_element->element['object']->has_children()) {
-            $new_element->element['children'] = $new_element->element['object']->get_children(1);
-            unset($new_element->element['object']->children);
-        }
-
-        $destination_array = array($destination_sortorder => $new_element->element);
-
-        // Get the position of the destination element
-        $destination_element = $this->locate_element($destination_sortorder);
-        $position = $destination_element->position;
-
-        // Decompose the element's index and build string for eval(array_splice) statement to follow
-        $indices = explode('/', $destination_element->index);
-
-        if (empty($indices)) {
-            debugging("The destination element did not have a valid index (as assigned by grade_tree::locate_element).");
-            return false;
-        }
-
-        $element_to_splice = '$this->tree_array';
-
-        if (isset($indices[1])) {
-            $element_to_splice .= '[' . $indices[0] . "]['children']";
-        }
-
-        if (isset($indices[2])) {
-            $element_to_splice .= '[' . $indices[1] . "]['children']";
-        }
-
-        eval("array_splice($element_to_splice, \$position + \$offset, 0, \$destination_array);");
-
-        if (!is_object($new_element)) {
-            debugging("Could not insert this element into the DB due to missing information.");
-            return false;
-        }
-
-        $this->need_insert[$new_element->element['object']->id] = $new_element->element['object'];
-
-        return true;*/
-    }
-
-    /**
-     * Moves an existing element in the tree to another position OF EQUAL LEVEL. This
-     * constraint is essential and very important.
-     * @param int $source_sortorder The sortorder of the element to move
-     * @param int $destination_sortorder The sortorder where the element will go
-     * @param string $position Either 'before' the destination_sortorder or 'after' it
-     * @return boolean
-     */
-    function move_element($source_sortorder, $destination_sortorder, $position='before') {
-        //TODO: fix me
-        return false;
-/*        if (empty($this->first_sortorder)) {
-            $this->reset_first_sortorder();
-        }
-
-        // Locate the position of the source element in the tree
-        $source = $this->locate_element($source_sortorder);
-
-        // Remove this element from the tree
-        $this->remove_element($source);
-
-        $destination = $this->locate_element($destination_sortorder);
-
-        // Insert the element before the destination sortorder
-        $this->insert_element($source, $destination_sortorder, $position);
-
-        return true;*/
-    }
-
-
 }
index f68d650e51e439a549a9e01338d489924e713d14..ecfc962b584828a6c3dff5f5a7d107f3f23668a4 100644 (file)
@@ -667,7 +667,7 @@ function grade_oldgradebook_upgrade($courseid) {
             $newitem = new grade_item(array('courseid'=>$olditem->courseid, 'itemtype'=>'mod', 'itemmodule'=>$olditem->modname, 'iteminstance'=>$olditem->cminstance, 'itemnumber'=>0));
             if (!empty($olditem->category)) {
                 // we do this low level stuff to get some speedup during upgrade
-                $newitem->set_parent_id($categories[$olditem->category]->id);
+                $newitem->set_parent($categories[$olditem->category]->id);
             }
             $newitem->gradetype = GRADE_TYPE_NONE;
             $newitem->multfactor = $olditem->scale_grade;
@@ -689,7 +689,7 @@ function grade_oldgradebook_upgrade($courseid) {
  * @param object $tree (A complete grade_tree object)
  * @return string HTML
  */
-function grade_get_icons($object, $tree) {
+function grade_get_icons($element, $tree) {
     global $CFG;
     global $USER;
 
@@ -713,12 +713,19 @@ function grade_get_icons($object, $tree) {
 
     $html = '<div class="grade_icons">';
 
+    $eid    = $element['eid'];
+    $object = $element['object'];
+    $type   = $element['type'];
+
     // Icons shown when edit mode is on
     if ($USER->gradeediting) {
         // Edit icon (except for grade_grades)
-        if (get_class($object) != 'grade_grades') {
-            $html .= '<a href="report/grader/category.php?target=' . $object->get_sortorder()
-                  . "&amp;action=edit$tree->commonvars\">\n";
+        if ($type == 'category') {
+            $html .= '<a href="report/grader/edit_category.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">';
+            $html .= '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
+                  .$stredit.'" title="'.$stredit.'" /></a>'. "\n";
+        } else {
+            $html .= '<a href="report/grader/edit_item.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">';
             $html .= '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
                   .$stredit.'" title="'.$stredit.'" /></a>'. "\n";
         }
@@ -730,30 +737,24 @@ function grade_get_icons($object, $tree) {
         }
 
         // Setup object identifier and show feedback icon if applicable
-        if (get_class($object) != 'grade_grades') {
-            $identifier = $object->get_sortorder();
-        } else {
-            $identifier = 'grade' . $object->id;
-
-            if ($USER->gradefeedback) {
-                // Display Edit/Add feedback icon
-                if (empty($object->feedback)) {
-                    $html .= '<a href="report.php?report=grader&amp;target=' . $object->id
-                          . "&amp;action=addfeedback$tree->commonvars\">\n";
-                    $html .= '<img src="'.$CFG->pixpath.'/t/feedback_add.gif" class="iconsmall" alt="'.$straddfeedback.'" '
-                          . 'title="'.$straddfeedback.'" /></a>'. "\n";
-                } else {
-                    $html .= '<a href="report.php?report=grader&amp;target=' . $object->id
-                          . "&amp;action=editfeedback$tree->commonvars\">\n";
-                    $html .= '<img src="'.$CFG->pixpath.'/t/feedback.gif" class="iconsmall" alt="'.$streditfeedback.'" '
-                          . 'title="'.$streditfeedback.'" onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
-                      . $strfeedback.'\');" onmouseout="return nd();" /></a>'. "\n";
-                }
+        if ($type != 'category' and $USER->gradefeedback) {
+            // Display Edit/Add feedback icon
+            if (empty($object->feedback)) {
+                $html .= '<a href="report.php?report=grader&amp;target='.$eid
+                      . "&amp;action=addfeedback$tree->commonvars\">\n";
+                $html .= '<img src="'.$CFG->pixpath.'/t/feedback_add.gif" class="iconsmall" alt="'.$straddfeedback.'" '
+                      . 'title="'.$straddfeedback.'" /></a>'. "\n";
+            } else {
+                $html .= '<a href="report.php?report=grader&amp;target='.$eid
+                      . "&amp;action=editfeedback$tree->commonvars\">\n";
+                $html .= '<img src="'.$CFG->pixpath.'/t/feedback.gif" class="iconsmall" alt="'.$streditfeedback.'" '
+                      . 'title="'.$streditfeedback.'" onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
+                  . $strfeedback.'\');" onmouseout="return nd();" /></a>'. "\n";
             }
         }
 
         // Display Hide/Show icon
-        $html .= '<a href="report.php?report=grader&amp;target=' . $identifier
+        $html .= '<a href="report.php?report=grader&amp;target='.$eid
               . "&amp;action=$hide_show$tree->commonvars\">\n";
         $html .= '<img src="'.$CFG->pixpath.'/t/'.$hide_show.'.gif" class="iconsmall" alt="'
               .${'str' . $hide_show}.'" title="'.${'str' . $hide_show}.'" /></a>'. "\n";
@@ -765,7 +766,7 @@ function grade_get_icons($object, $tree) {
         }
 
         // Print lock/unlock icon
-        $html .= '<a href="report.php?report=grader&amp;target=' . $identifier
+        $html .= '<a href="report.php?report=grader&amp;target='.$eid
               . "&amp;action=$lock_unlock$tree->commonvars\">\n";
         $html .= '<img src="'.$CFG->pixpath.'/t/'.$lock_unlock.'.gif" class="iconsmall" alt="'
               .${'str' . $lock_unlock}.'" title="'.${'str' . $lock_unlock}.'" /></a>'. "\n";
@@ -780,7 +781,7 @@ function grade_get_icons($object, $tree) {
                 $expand_contract = 'switch_plus';
             }
 
-            $html .= '<a href="report.php?report=grader&amp;target=' . $identifier
+            $html .= '<a href="report.php?report=grader&amp;target=' . $eid
                   . "&amp;action=$expand_contract$tree->commonvars\">\n";
             $html .= '<img src="'.$CFG->pixpath.'/t/'.$expand_contract.'.gif" class="iconsmall" alt="'
                   .${'str' . $expand_contract}.'" title="'.${'str' . $expand_contract}.'" /></a>'. "\n";
@@ -789,7 +790,7 @@ function grade_get_icons($object, $tree) {
         if ($USER->gradefeedback) {
             // Display Edit/Add feedback icon
             if (!empty($object->feedback)) {
-                $html .= '<a href="report.php?report=grader&amp;target=' . $object->id
+                $html .= '<a href="report.php?report=grader&amp;target=' . $eid
                       . "&amp;action=viewfeedback$tree->commonvars\">\n";
                 $html .= '<img onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
                       . $strfeedback.'\');" onmouseout="return nd();" '
index ab1662a9994573dc506d0e984b7707b43a8aa6a2..7d2c4ec79be2e1d287a6849a9dd678062c41172d 100755 (executable)
@@ -207,57 +207,6 @@ class grade_category_test extends grade_test {
         return $grade->rawgrade;
     }
 
-    function test_grade_category_set_as_parent() {
-        //TODO: rewrite this test - we need proper items stored in database!
-
-/*        global $CFG;
-        $debuglevel = $CFG->debug;
-
-        // There are 3 constraints which, if violated, should return false and trigger a debugging message. Test each of them
-        $grade_category = new grade_category();
-        $grade_category->fullname    = 'new topcategory';
-        $grade_category->courseid    = $this->courseid;
-        $grade_category->insert();
-
-        // 1. mixed types of children
-        $child1 = new grade_item();
-        $child1->sortorder = 1;
-        $child2 = new grade_category();
-        $child2->grade_item = new grade_item();
-        $child2->grade_item->sortorder = 2;
-        $CFG->debug = 2;
-        $this->assertFalse($grade_category->set_as_parent(array($child1, $child2)));
-        $CFG->debug = $debuglevel;
-
-        // 2. Child is a top category
-        $child1 = new grade_category($this->grade_categories[0]);
-        $CFG->debug = 2;
-        $this->assertFalse($grade_category->set_as_parent(array($child1)));
-        $CFG->debug = $debuglevel;
-
-        // 3. Children belong to different courses
-        $child1 = new grade_item($this->grade_items[0]);
-        $child2 = new grade_item($this->grade_items[1]);
-        $child2->courseid = 543;
-        $CFG->debug = 2;
-        $this->assertFalse($grade_category->set_as_parent(array($child1, $child2)));
-        $CFG->debug = $debuglevel;
-
-        // Now test setting parent correctly
-        $child1 = new grade_item();
-        $child2 = new grade_item();
-        $child1->itemname = 'new grade_item';
-        $child2->itemname = 'new grade_item';
-        $child1->itemtype = 'something';
-        $child2->itemtype = 'something';
-        $child1->sortorder = 1;
-        $child2->sortorder = 2;
-        $child1->courseid = $grade_category->courseid;
-        $child2->courseid = $grade_category->courseid;
-        $child1->insert();
-        $child2->insert();
-        $this->assertTrue($grade_category->set_as_parent(array($child1, $child2)));*/
-    }
 /*
     function test_grade_category_apply_limit_rules() {
         $category = new grade_category();
index bb102d70ef566834d38891be8a547e501467a9da..1e425927b39dcc2871c4995b1845bc7e25b8d6e6 100644 (file)
@@ -39,337 +39,12 @@ require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class grade_tree_test extends grade_test {
 
-    function test_grade_tree_move_element() {
-return;
-        /* 0.
-         * Starting layout:
-         *__________________
-         *|_________1_______|     ____________
-         *|_____2_____|__5__|_____|_____8____|
-         *|__3__|__4__|__6__|__7__|__9__|_10_|
-         */
-        $tree = new grade_tree($this->courseid);
-        /* 1.
-         * Desired result:
-         *_____________
-         *|_____1_____|     _________________
-         *|__2__|__4__|_____|________7_______|
-         *|__3__|__5__|__6__|__8__|__9__|_10_|
-         */
-        $tree->move_element(4, 10);
-        $tree->renumber();
-
-        // Check need_? fields
-        $this->assertFalse(empty($tree->need_update));
-        $this->assertFalse(empty($tree->need_insert));
-        $this->assertFalse(empty($tree->need_delete));
-        $this->assertEqual(6, count($tree->need_update));
-        $this->assertEqual(1, count($tree->need_delete));
-        $this->assertEqual(1, count($tree->need_insert));
-
-        // Check sortorders
-        $this->assertEqual(1, $tree->tree_array[1]['object']->sortorder);
-        $this->assertEqual(2, $tree->tree_array[1]['children'][2]['object']->sortorder);
-        $this->assertEqual(3, $tree->tree_array[1]['children'][2]['children'][3]['object']->sortorder);
-        $this->assertEqual(4, $tree->tree_array[1]['children'][4]['object']->sortorder);
-        $this->assertEqual(5, $tree->tree_array[1]['children'][4]['children'][5]['object']->sortorder);
-        $this->assertEqual(6, $tree->tree_array[6]['object']->sortorder);
-        $this->assertEqual(7, $tree->tree_array[7]['object']->sortorder);
-        $this->assertEqual(8, $tree->tree_array[7]['children'][8]['object']->sortorder);
-        $this->assertEqual(9, $tree->tree_array[7]['children'][9]['object']->sortorder);
-        $this->assertEqual(10, $tree->tree_array[7]['children'][10]['object']->sortorder);
-
-        $this->assertFalse(empty($tree->tree_array[1]['children'][4]['children'][5]));
-        $this->assertEqual('unittestgradeitem3', $tree->tree_array[1]['children'][4]['children'][5]['object']->itemname);
-        $tree->need_update = array();
-
-        /* 2.
-         * Desired result:
-         *___________________
-         *|________1________|_________________
-         *|_____2_____|__5__|________7_______|
-         *|__3__|__4__|__6__|__8__|__9__|_10_|
-         */
-        $tree->move_element(6, 3, 'after');
-        $tree->renumber();
-        $this->assertEqual(3, count($tree->need_update));
-        $tree->need_update = array();
-
-        // Check sortorders
-        $this->assertEqual(1, $tree->tree_array[1]['object']->sortorder);
-        $this->assertEqual(2, $tree->tree_array[1]['children'][2]['object']->sortorder);
-        $this->assertEqual(3, $tree->tree_array[1]['children'][2]['children'][3]['object']->sortorder);
-        $this->assertEqual(4, $tree->tree_array[1]['children'][2]['children'][4]['object']->sortorder);
-        $this->assertEqual(5, $tree->tree_array[1]['children'][5]['object']->sortorder);
-        $this->assertEqual(6, $tree->tree_array[1]['children'][5]['children'][6]['object']->sortorder);
-        $this->assertEqual(7, $tree->tree_array[7]['object']->sortorder);
-        $this->assertEqual(8, $tree->tree_array[7]['children'][8]['object']->sortorder);
-        $this->assertEqual(9, $tree->tree_array[7]['children'][9]['object']->sortorder);
-        $this->assertEqual(10, $tree->tree_array[7]['children'][10]['object']->sortorder);
-
-        // Try moving a subcategory
-        /* 3.
-         * Desired result:
-         *___________________
-         *|________1________|_________________
-         *|__2__|_____4_____|________7_______|
-         *|__3__|__5__|__6__|__8__|__9__|_10_|
-         */
-        $tree->move_element(2, 5, 'after');
-        $tree->renumber();
-        $this->assertEqual(5, count($tree->need_update));
-        $tree->need_update = array();
-
-        // Check sortorders
-        $this->assertEqual(1, $tree->tree_array[1]['object']->sortorder);
-        $this->assertEqual(2, $tree->tree_array[1]['children'][2]['object']->sortorder);
-        $this->assertEqual(3, $tree->tree_array[1]['children'][2]['children'][3]['object']->sortorder);
-        $this->assertEqual(4, $tree->tree_array[1]['children'][4]['object']->sortorder);
-        $this->assertEqual(5, $tree->tree_array[1]['children'][4]['children'][5]['object']->sortorder);
-        $this->assertEqual(6, $tree->tree_array[1]['children'][4]['children'][6]['object']->sortorder);
-        $this->assertEqual(7, $tree->tree_array[7]['object']->sortorder);
-        $this->assertEqual(8, $tree->tree_array[7]['children'][8]['object']->sortorder);
-        $this->assertEqual(9, $tree->tree_array[7]['children'][9]['object']->sortorder);
-        $this->assertEqual(10, $tree->tree_array[7]['children'][10]['object']->sortorder);
-
-        /* 4.
-         * Desired result:
-         *_________________________
-         *|___________1___________|____________
-         *|__2__|________4________|_____8_____|
-         *|__3__|__5__|__6__|__7__|__9__|_10__|
-        */
-        $tree->move_element(8, 6);
-        $tree->renumber();
-        $this->assertEqual(3, count($tree->need_update));
-        $tree->need_update = array();
-
-        // Check sortorders
-        $this->assertEqual(1, $tree->tree_array[1]['object']->sortorder);
-        $this->assertEqual(2, $tree->tree_array[1]['children'][2]['object']->sortorder);
-        $this->assertEqual(3, $tree->tree_array[1]['children'][2]['children'][3]['object']->sortorder);
-        $this->assertEqual(4, $tree->tree_array[1]['children'][4]['object']->sortorder);
-        $this->assertEqual(5, $tree->tree_array[1]['children'][4]['children'][5]['object']->sortorder);
-        $this->assertEqual(6, $tree->tree_array[1]['children'][4]['children'][6]['object']->sortorder);
-        $this->assertEqual(7, $tree->tree_array[1]['children'][4]['children'][7]['object']->sortorder);
-        $this->assertEqual(8, $tree->tree_array[8]['object']->sortorder);
-        $this->assertEqual(9, $tree->tree_array[8]['children'][9]['object']->sortorder);
-        $this->assertEqual(10, $tree->tree_array[8]['children'][10]['object']->sortorder);
-
-        // Try moving a top category
-        /* 5.
-         * Desired result:
-         *      ___________________
-         *      |_________2_______|___________
-         *______|_____3_____|__6__|_____8____|
-         *|__1__|__4__|__5__|__7__|__9__|_10_|
-         */
-        $tree = new grade_tree($this->courseid);
-        $tree->move_element(1, 8);
-        $tree->renumber();
-        $this->assertEqual(7, count($tree->need_update));
-
-        // Check sortorders
-        $this->assertEqual(1, $tree->tree_array[1]['object']->sortorder);
-        $this->assertEqual(2, $tree->tree_array[2]['object']->sortorder);
-        $this->assertEqual(3, $tree->tree_array[2]['children'][3]['object']->sortorder);
-        $this->assertEqual(4, $tree->tree_array[2]['children'][3]['children'][4]['object']->sortorder);
-        $this->assertEqual(5, $tree->tree_array[2]['children'][3]['children'][5]['object']->sortorder);
-        $this->assertEqual(6, $tree->tree_array[2]['children'][6]['object']->sortorder);
-        $this->assertEqual(7, $tree->tree_array[2]['children'][6]['children'][7]['object']->sortorder);
-        $this->assertEqual(8, $tree->tree_array[8]['object']->sortorder);
-        $this->assertEqual(9, $tree->tree_array[8]['children'][9]['object']->sortorder);
-        $this->assertEqual(10, $tree->tree_array[8]['children'][10]['object']->sortorder);
-    }
-/*
-    function test_grade_tree_get_neighbour_sortorder() {
-        $tree = new grade_tree($this->courseid);
-
-        $element = $tree->locate_element(4);
-        $this->assertEqual(3, $tree->get_neighbour_sortorder($element, 'previous'));
-        $this->assertNull($tree->get_neighbour_sortorder($element, 'next'));
-
-        $element = $tree->locate_element(3);
-        $this->assertEqual(4, $tree->get_neighbour_sortorder($element, 'next'));
-        $this->assertNull($tree->get_neighbour_sortorder($element, 'previous'));
-
-        $element = $tree->locate_element(1);
-        $this->assertNull($tree->get_neighbour_sortorder($element, 'previous'));
-        $this->assertEqual(7, $tree->get_neighbour_sortorder($element, 'next'));
-
-        $element = $tree->locate_element(7);
-        $this->assertEqual(1, $tree->get_neighbour_sortorder($element, 'previous'));
-        $this->assertEqual(8, $tree->get_neighbour_sortorder($element, 'next'));
-
-        $element = $tree->locate_element(8);
-        $this->assertEqual(7, $tree->get_neighbour_sortorder($element, 'previous'));
-        $this->assertNull($tree->get_neighbour_sortorder($element, 'next'));
-
-    }
-
-    // TODO write more thorough and useful tests here. The renumber method assigns previous_sortorder and next_sortorder variables
-    function test_grade_tree_renumber() {
-        $tree = new grade_tree($this->courseid);
-        $this->assertFalse(empty($tree->tree_array[1]['object']->next_sortorder));
-
-        $this->assertTrue(empty($tree->need_update));
-    }
-
     function test_grade_tree_locate_element() {
-        $tree = new grade_tree($this->courseid);
-        $element = $tree->locate_element(5);
-        $this->assertEqual('1/5', $element->index);
-        $this->assertNotNull($element->element);
-        $this->assertEqual('unittestcategory3', $element->element['object']->fullname);
-        $this->assertEqual('unittestgradeitem3', $element->element['children'][6]['object']->itemname);
-
-        // Locate a grade_item
-        $element = $tree->locate_element(9);
-        $this->assertEqual('8/9', $element->index);
-        $this->assertNotNull($element->element);
-        $this->assertEqual('singleparentitem1', $element->element['object']->itemname);
-    }
-
-    function test_grade_tree_insert_grade_subcategory() {
-        $tree = new grade_tree($this->courseid);
-        $grade_category = new grade_category($this->grade_categories[3]);
-        $element = array('object' => $grade_category);
-
-        $tree->insert_element($element, 5);
-        $this->assertFalse(empty($tree->tree_array[1]['children'][1]['object']->fullname));
-        $this->assertEqual($this->grade_categories[3]->fullname, $tree->tree_array[1]['children'][1]['object']->fullname);
-        $this->assertFalse(empty($tree->tree_array[1]['children'][1]['children'][9]));
-        $this->assertEqual($this->grade_items[7]->itemname, $tree->tree_array[1]['children'][1]['children'][9]['object']->itemname);
-    }
-
-    function test_grade_tree_insert_grade_topcategory() {
-        $tree = new grade_tree($this->courseid);
-        $grade_category = new grade_category($this->grade_categories[0]);
-        $element = array('object' => $grade_category);
-
-        $tree->insert_element($element, 8);
-
-        $this->assertFalse(empty($tree->tree_array[2]['object']->fullname));
-        $this->assertEqual($this->grade_categories[0]->fullname, $tree->tree_array[2]['object']->fullname);
-        $this->assertFalse(empty($tree->tree_array[2]['children'][2]['object']->fullname));
-        $this->assertEqual($this->grade_categories[1]->fullname, $tree->tree_array[2]['children'][2]['object']->fullname);
-    }
-
-    function test_grade_tree_insert_grade_item() {
-        $tree = new grade_tree($this->courseid, true);
-        $grade_item = new grade_item($this->grade_items[2]);
-        $element = array('object' => $grade_item);
-        $tree->insert_element($element, 4);
-        $this->assertFalse(empty($tree->tree_array[1]['children'][2]['children'][1]['object']->itemname));
-        $this->assertEqual($this->grade_items[2]->itemname, $tree->tree_array[1]['children'][2]['children'][1]['object']->itemname);
-        $this->assertFalse(empty($tree->tree_array[1]['children'][2]['children'][1]['final_grades'][1]));
-        $this->assertEqual($this->grade_grades[6]->finalgrade, $tree->tree_array[1]['children'][2]['children'][1]['final_grades'][1]->finalgrade);
-
-        // Check the need_insert array
-        $this->assertEqual(1, count($tree->need_insert));
+        //TODO: add test
     }
 
     function test_grade_tree_constructor() {
         $tree = new grade_tree($this->courseid);
 
     }
-
-    function test_grade_tree_get_tree() {
-        $tree = new grade_tree($this->courseid, true);
-        $this->assertEqual(47, count($tree->tree_array, COUNT_RECURSIVE));
-    }
-
-    function test_grade_tree_remove_element() {
-        $tree = new grade_tree($this->courseid);
-
-        // Removing the orphan grade_item
-        $tree->remove_element(7);
-        $this->assertTrue(empty($tree->tree_array[7]));
-        $this->assertFalse(empty($tree->tree_array[1]));
-        $this->assertFalse(empty($tree->tree_array[8]));
-        $tree->renumber();
-        $this->assertFalse(empty($tree->tree_array[7]));
-        $this->assertFalse(empty($tree->tree_array[1]));
-        $this->assertTrue(empty($tree->tree_array[8]));
-
-        // Removing a grade_item with only 1 parent
-        $tree->remove_element(8);
-        $this->assertTrue(empty($tree->tree_array[7]['children'][8]));
-        $this->assertFalse(empty($tree->tree_array[7]['children'][9]));
-        $tree->renumber();
-        $this->assertFalse(empty($tree->tree_array[7]['children'][8]));
-        $this->assertTrue(empty($tree->tree_array[7]['children'][9]));
-
-        // Now remove this sub-category (the one without a topcat)
-        $tree->remove_element(7);
-        $this->assertTrue(empty($tree->tree_array[7]));
-
-        // At this point we're left with a topcat, 2 subcats and 3 items, so try removing an item first
-        $tree->remove_element(4);
-        $this->assertTrue(empty($tree->tree_array[1]['children'][2]['children'][4]));
-        $this->assertFalse(empty($tree->tree_array[1]['children'][5]));
-        $tree->renumber();
-        $this->assertFalse(empty($tree->tree_array[1]['children'][4]));
-
-        // Now remove a subcat sandwiched between a topcat and its items
-        $tree->remove_element(4);
-        $this->assertTrue(empty($tree->tree_array[1]['children'][4]));
-        $tree->renumber();
-        $this->assertTrue(empty($tree->tree_array[1]['children'][4]));
-
-        $this->assertEqual(9, count($tree->tree_array, COUNT_RECURSIVE));
-
-        // Check the need_delete array
-        $this->assertEqual(5, count($tree->need_delete));
-    }
-
-    function test_grade_tree_get_filler() {
-        $tree = new grade_tree($this->courseid);
-        $filler = $tree->get_filler($tree->tree_array[7]['object']);
-        $this->assertEqual('filler', $filler['object']);
-        $this->assertEqual('filler', $filler['children'][0]['object']);
-        $this->assertEqual($this->grade_items[6]->itemname, $filler['children'][0]['children'][0]['object']->itemname);
-    }
-
-    function test_grade_tree_build_tree_filled() {
-        $tree = new grade_tree($this->courseid);
-
-        $element = $tree->tree_array[7];
-        $tree->remove_element(7);
-        $tree->renumber();
-
-        $tree->insert_element($element, 4);
-        $tree->renumber();
-    }
-
-    function test_grade_tree_update_db() {
-        $tree = new grade_tree($this->courseid);
-        $tree->remove_element(7);
-        $tree->renumber();
-        $tree->update_db();
-        $item = grade_item::fetch(array('id'=>$this->grade_items[6]->id));
-        $this->assertTrue(empty($item->id));
-
-        $tree->move_element(4, 9);
-        $tree->renumber();
-        $tree->update_db();
-        $item = grade_item::fetch(array('id'=>$this->grade_items[1]->id));
-        $this->assertFalse(empty($item->id));
-        $this->assertEqual(8, $item->sortorder);
-
-        $grade_item = new grade_item($this->grade_items[2]);
-        $element = array('object' => $grade_item);
-        $tree->insert_element($element, 9);
-
-    }
-
-    function test_grade_tree_load_without_finals() {
-        $tree = new grade_tree($this->courseid);
-        $this->assertEqual(29, count($tree->tree_array, COUNT_RECURSIVE));
-    }
-
-    function test_grade_tree_display_edit_tree() {
-        $tree = new grade_tree($this->courseid);
-    }
-*/
 }
diff --git a/pix/i/category_grade.gif b/pix/i/category_grade.gif
new file mode 100755 (executable)
index 0000000..3c64470
Binary files /dev/null and b/pix/i/category_grade.gif differ
index 5c50ee30ee3957c32bff96779df97357a9a0ec00..713c9faceca776a46dacb6ab7a158ff62cf8a375 100644 (file)
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-   $version = 2007062800;  // YYYYMMDD = date
+   $version = 2007063001;  // YYYYMMDD = date
                            //       XY = increments within a single day
 
    $release = '1.9 dev';    // Human-friendly version name