MDL-9506 MDL-9137 MDL-9629

Added a number of small getters and setters to grade_item and grade_category, to hide the structural differences between the two, and provide a common interface for cases when we are not sure whether an $object is of one type or another.
The grade_tree::renumber() method now adds complete objects to the need_update array, because both grade_category and grade_item need to update their parent field when moved to a different parent. Amazingly, these important changes worked straight away (after 1 hour of coding without testing anything), and all the unit tests passed!
This commit is contained in:
nicolasconnault 2007-05-31 03:15:43 +00:00
parent bffe39c6d5
commit 0fc7f62445
4 changed files with 418 additions and 324 deletions

View File

@ -193,6 +193,16 @@ class grade_category extends grade_object {
function update() {
$qualifies = $this->qualifies_for_update();
// Update the grade_item's sortorder if needed
if (!empty($this->sortorder)) {
$this->load_grade_item();
if (!empty($this->grade_item)) {
$this->grade_item->sortorder = $this->sortorder;
$this->grade_item->update();
}
unset($this->sortorder);
}
$result = parent::update();
// Use $this->path to update all parent categories
@ -491,6 +501,57 @@ class grade_category extends grade_object {
return $aggregated_grades;
}
/**
* Given an array of stdClass children of a certain $object_type, returns a flat or nested
* array of these children, ready for appending to a tree built by get_children.
* @static
* @param array $children
* @param string $arraytype
* @param string $object_type
* @return array
*/
function children_to_array($children, $arraytype='nested', $object_type='grade_item') {
$children_array = array();
foreach ($children as $id => $child) {
$child = new $object_type($child, false);
if ($arraytype == 'nested') {
$children_array[$child->get_sortorder()] = array('object' => $child);
} else {
$children_array[$child->get_sortorder()] = $child;
}
}
return $children_array;
}
/**
* Returns true if this category has any child grade_category or grade_item.
* @return int number of direct children, or false if none found.
*/
function has_children() {
return count_records('grade_categories', 'parent', $this->id) + count_records('grade_items', 'categoryid', $this->id);
}
/**
* This method 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->has_children()) {
if (get_class($child) != $this->get_childrentype()) {
return false;
} else {
return true;
}
} else {
return true;
}
}
/**
* Looks at a path string (e.g. /2/45/56) and returns the depth level represented by this path (in this example, 3).
* If no string is given, it looks at the obect's path and assigns the resulting depth to its $depth variable.
@ -567,74 +628,6 @@ class grade_category extends grade_object {
return $children_array;
}
/**
* Returns the sortorder of the associated grade_item. This method is also available in
* grade_item, for cases where the object type is not know. It will act as a virtual
* variable for a grade_category.
* @return int Sort order
*/
function get_sortorder() {
if (empty($this->sortorder)) {
$this->load_grade_item();
if (!empty($this->grade_item)) {
return $this->grade_item->sortorder;
}
} else {
return $this->sortorder;
}
}
/**
* Given an array of stdClass children of a certain $object_type, returns a flat or nested
* array of these children, ready for appending to a tree built by get_children.
* @static
* @param array $children
* @param string $arraytype
* @param string $object_type
* @return array
*/
function children_to_array($children, $arraytype='nested', $object_type='grade_item') {
$children_array = array();
foreach ($children as $id => $child) {
$child = new $object_type($child, false);
if ($arraytype == 'nested') {
$children_array[$child->get_sortorder()] = array('object' => $child);
} else {
$children_array[$child->get_sortorder()] = $child;
}
}
return $children_array;
}
/**
* Returns true if this category has any child grade_category or grade_item.
* @return int number of direct children, or false if none found.
*/
function has_children() {
return count_records('grade_categories', 'parent', $this->id) + count_records('grade_items', 'categoryid', $this->id);
}
/**
* This method 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->has_children()) {
if (get_class($child) != $this->get_childrentype()) {
return false;
} else {
return true;
}
} else {
return true;
}
}
/**
* 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).
@ -834,5 +827,49 @@ class grade_category extends grade_object {
$this->load_grade_item();
return $this->grade_item->id;
}
/**
* Returns this category's parent id. A generic method shared by objects that have a parent id of some kind.
* @return id $parentid
*/
function get_parent_id() {
return $this->parent;
}
/**
* Sets this category's parent id. A generic method shared by objects that have a parent id of some kind.
* @param id $parentid
*/
function set_parent_id($parentid) {
$this->parent = $parentid;
}
/**
* Returns the sortorder of the associated grade_item. This method is also available in
* grade_item, for cases where the object type is not know. It will act as a virtual
* variable for a grade_category.
* @return int Sort order
*/
function get_sortorder() {
if (empty($this->sortorder)) {
$this->load_grade_item();
if (!empty($this->grade_item)) {
return $this->grade_item->sortorder;
}
} else {
return $this->sortorder;
}
}
/**
* Sets a temporary sortorder variable for this category. It is used in the update() method to update the grade_item.
* This method is also available in grade_item, for cases where the object type is not know.
* @param int $sortorder
* @return void
*/
function set_sortorder($sortorder) {
$this->sortorder = $sortorder;
}
}
?>

View File

@ -213,141 +213,6 @@ class grade_item extends grade_object {
$this->grade_object($params, $fetch);
}
/**
* Instantiates a grade_scale object whose data is retrieved from the DB,
* if this item's scaleid variable is set.
* @return object grade_scale
*/
function load_scale() {
if (!empty($this->scaleid)) {
$this->scale = grade_scale::fetch('id', $this->scaleid);
if (method_exists($this->scale, 'load_items')) {
$this->scale->load_items();
} else {
$this->scale = null;
}
}
return $this->scale;
}
/**
* Instantiates a grade_outcome object whose data is retrieved from the DB,
* if this item's outcomeid variable is set.
* @return object grade_outcome
*/
function load_outcome() {
if (!empty($this->outcomeid)) {
$this->outcome = grade_outcome::fetch('id', $this->outcomeid);
}
return $this->outcome;
}
/**
* Loads all the grade_grades_raw objects for this grade_item from the DB into grade_item::$grade_grades_raw array.
* @return array grade_grades_raw objects
*/
function load_raw() {
$grade_raw_array = get_records('grade_grades_raw', 'itemid', $this->id);
if (empty($grade_raw_array)) {
return null;
}
foreach ($grade_raw_array as $r) {
$this->grade_grades_raw[$r->userid] = new grade_grades_raw($r);
}
return $this->grade_grades_raw;
}
/**
* Loads all the grade_grades_final objects for this grade_item from the DB into grade_item::$grade_grades_final array.
* @param boolean $generatefakenullgrades If set to true, AND $CFG->usenullgrades is true, will replace missing grades with grades, gradevalue=grademin
* @return array grade_grades_final objects
*/
function load_final($generatefakenullgrades=false) {
global $CFG;
$grade_final_array = get_records('grade_grades_final', 'itemid', $this->id);
if (empty($grade_final_array)) {
$this->generate_final();
$grade_final_array = get_records('grade_grades_final', 'itemid', $this->id);
}
if (empty($grade_final_array)) {
debugging("No final grades recorded for this grade_item");
return false;
}
foreach ($grade_final_array as $f) {
$this->grade_grades_final[$f->userid] = new grade_grades_final($f);
}
$returnarray = fullclone($this->grade_grades_final);
// If we are generating fake null grades, we have to get a list of users
if ($generatefakenullgrades && $CFG->usenullgrades) {
$users = get_records_sql_menu('SELECT userid AS "user", userid FROM ' . $CFG->prefix . 'grade_grades_final GROUP BY userid ORDER BY userid');
if (!empty($users) && is_array($users)) {
foreach ($users as $userid) {
if (!isset($returnarray[$userid])) {
$fakefinal = new grade_grades_final();
$fakefinal->itemid = $this->id;
$fakefinal->userid = $userid;
$fakefinal->gradevalue = $this->grademin;
$returnarray[$userid] = $fakefinal;
}
}
}
}
return $returnarray;
}
/**
* Returns an array of values (NOT objects) standardised from the final grades of this grade_item. They are indexed by userid.
* @return array integers
*/
function get_standardised_final() {
$standardised_finals = array();
$final_grades = $this->load_final(true);
foreach ($final_grades as $userid => $final) {
$standardised_finals[$userid] = standardise_score($final->gradevalue, $this->grademin, $this->grademax, 0, 1);
}
return $standardised_finals;
}
/**
* Returns the grade_category object this grade_item belongs to (if any).
* This category object may be the parent (referenced by categoryid) or the associated category
* (referenced by iteminstance).
*
* @return mixed grade_category object if applicable, NULL otherwise
*/
function get_category() {
$category = null;
if (!empty($this->categoryid)) {
$category = grade_category::fetch('id', $this->categoryid);
} elseif (!empty($this->iteminstance) && $this->itemtype == 'category') {
$category = grade_category::fetch('id', $this->iteminstance);
}
return $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_category() {
$this->category = $this->get_category();
return $this->category;
}
/**
* In addition to update() as defined in grade_object, handle the grade_outcome and grade_scale objects.
*/
@ -514,26 +379,6 @@ class grade_item extends grade_object {
return $result;
}
/**
* Returns the raw values for this grade item (as imported by module or other source).
* @param int $userid Optional: to retrieve a single raw grade
* @return mixed An array of all raw_grades (stdClass objects) for this grade_item, or a single raw_grade.
*/
function get_raw($userid=NULL) {
if (empty($this->grade_grades_raw)) {
$this->load_raw();
}
$grade_raw_array = null;
if (!empty($userid)) {
$r = get_record('grade_grades_raw', 'itemid', $this->id, 'userid', $userid);
$grade_raw_array[$r->userid] = new grade_grades_raw($r);
} else {
$grade_raw_array = $this->grade_grades_raw;
}
return $grade_raw_array;
}
/**
* Takes an array of grade_grades_raw objects, indexed by userid, and saves each as a raw grade
* under this grade_item. This replaces any existing grades, after having logged each change in the history table.
@ -563,26 +408,6 @@ class grade_item extends grade_object {
}
}
/**
* Returns the final values for this grade item (as imported by module or other source).
* @param int $userid Optional: to retrieve a single final grade
* @return mixed An array of all final_grades (stdClass objects) for this grade_item, or a single final_grade.
*/
function get_final($userid=NULL) {
if (empty($this->grade_grades_final)) {
$this->load_final();
}
$grade_final_array = null;
if (!empty($userid)) {
$f = get_record('grade_grades_final', 'itemid', $this->id, 'userid', $userid);
$grade_final_array[$f->userid] = new grade_grades_final($f);
} else {
$grade_final_array = $this->grade_grades_final;
}
return $grade_final_array;
}
/**
* Once the raw_grades are imported or entered, this method uses the grade_item's calculation and rules to
* generate final grade entries in the DB.
@ -612,71 +437,6 @@ class grade_item extends grade_object {
return $success;
}
/**
* Returns this object's calculation.
* @param boolean $fetch Whether to fetch the value from the DB or not (false == just use the object's value)
* @return mixed $calculation A string if found, false otherwise.
*/
function get_calculation($fetch = false) {
if (!$fetch && get_class($this->calculation) == 'grade_calculation') {
return $this->calculation;
}
$grade_calculation = grade_calculation::fetch('itemid', $this->id);
if (empty($grade_calculation)) { // There is no calculation in DB
return false;
} elseif (empty($this->calculation) || !is_object($this->calculation)) { // The calculation isn't yet loaded
$this->calculation = $grade_calculation;
return $grade_calculation;
} elseif ($grade_calculation->calculation != $this->calculation->calculation) { // The object's calculation is not in sync with the DB (new value??)
$this->calculation = $grade_calculation;
return $grade_calculation;
} else { // The object's calculation is already in sync with the database
return $this->calculation;
}
}
/**
* Sets this item's calculation (creates it) if not yet set, or
* updates it if already set (in the DB). If no calculation is given,
* the method will attempt to retrieve one from the Database, based on
* the variables set in the current object.
* @param string $calculation
* @return boolean
*/
function set_calculation($calculation = null) {
if (empty($calculation)) { // We are setting this item object's calculation variable from the DB
$grade_calculation = $this->get_calculation(true);
if (empty($grade_calculation)) {
debugging("No calculation to set for this grade_item.");
return false;
} else {
$this->calculation = $grade_calculation;
}
} else { // We are updating or creating the calculation entry in the DB
$grade_calculation = $this->get_calculation();
if (empty($grade_calculation)) { // Creating
$grade_calculation = new grade_calculation();
$grade_calculation->calculation = $calculation;
$grade_calculation->itemid = $this->id;
if ($grade_calculation->insert()) {
$this->calculation = $grade_calculation;
return true;
} else {
debugging("Could not save the calculation in the database, for this grade_item.");
return false;
}
} else { // Updating
$grade_calculation->calculation = $calculation;
$grade_calculation = new grade_calculation($grade_calculation);
$this->calculation = $grade_calculation;
return $grade_calculation->update();
}
}
}
/**
* Returns the locked state of this grade_item (if the grade_item is locked OR no specific
* $userid is given) or the locked state of a specific grade within this item if a specific
@ -912,6 +672,246 @@ class grade_item extends grade_object {
return $result;
}
/**
* Instantiates a grade_scale object whose data is retrieved from the DB,
* if this item's scaleid variable is set.
* @return object grade_scale
*/
function load_scale() {
if (!empty($this->scaleid)) {
$this->scale = grade_scale::fetch('id', $this->scaleid);
if (method_exists($this->scale, 'load_items')) {
$this->scale->load_items();
} else {
$this->scale = null;
}
}
return $this->scale;
}
/**
* Instantiates a grade_outcome object whose data is retrieved from the DB,
* if this item's outcomeid variable is set.
* @return object grade_outcome
*/
function load_outcome() {
if (!empty($this->outcomeid)) {
$this->outcome = grade_outcome::fetch('id', $this->outcomeid);
}
return $this->outcome;
}
/**
* Loads all the grade_grades_raw objects for this grade_item from the DB into grade_item::$grade_grades_raw array.
* @return array grade_grades_raw objects
*/
function load_raw() {
$grade_raw_array = get_records('grade_grades_raw', 'itemid', $this->id);
if (empty($grade_raw_array)) {
return null;
}
foreach ($grade_raw_array as $r) {
$this->grade_grades_raw[$r->userid] = new grade_grades_raw($r);
}
return $this->grade_grades_raw;
}
/**
* Loads all the grade_grades_final objects for this grade_item from the DB into grade_item::$grade_grades_final array.
* @param boolean $generatefakenullgrades If set to true, AND $CFG->usenullgrades is true, will replace missing grades with grades, gradevalue=grademin
* @return array grade_grades_final objects
*/
function load_final($generatefakenullgrades=false) {
global $CFG;
$grade_final_array = get_records('grade_grades_final', 'itemid', $this->id);
if (empty($grade_final_array)) {
$this->generate_final();
$grade_final_array = get_records('grade_grades_final', 'itemid', $this->id);
}
if (empty($grade_final_array)) {
debugging("No final grades recorded for this grade_item");
return false;
}
foreach ($grade_final_array as $f) {
$this->grade_grades_final[$f->userid] = new grade_grades_final($f);
}
$returnarray = fullclone($this->grade_grades_final);
// If we are generating fake null grades, we have to get a list of users
if ($generatefakenullgrades && $CFG->usenullgrades) {
$users = get_records_sql_menu('SELECT userid AS "user", userid FROM ' . $CFG->prefix . 'grade_grades_final GROUP BY userid ORDER BY userid');
if (!empty($users) && is_array($users)) {
foreach ($users as $userid) {
if (!isset($returnarray[$userid])) {
$fakefinal = new grade_grades_final();
$fakefinal->itemid = $this->id;
$fakefinal->userid = $userid;
$fakefinal->gradevalue = $this->grademin;
$returnarray[$userid] = $fakefinal;
}
}
}
}
return $returnarray;
}
/**
* Returns an array of values (NOT objects) standardised from the final grades of this grade_item. They are indexed by userid.
* @return array integers
*/
function get_standardised_final() {
$standardised_finals = array();
$final_grades = $this->load_final(true);
foreach ($final_grades as $userid => $final) {
$standardised_finals[$userid] = standardise_score($final->gradevalue, $this->grademin, $this->grademax, 0, 1);
}
return $standardised_finals;
}
/**
* Returns the grade_category object this grade_item belongs to (if any).
* This category object may be the parent (referenced by categoryid) or the associated category
* (referenced by iteminstance).
*
* @return mixed grade_category object if applicable, NULL otherwise
*/
function get_category() {
$category = null;
if (!empty($this->categoryid)) {
$category = grade_category::fetch('id', $this->categoryid);
} elseif (!empty($this->iteminstance) && $this->itemtype == 'category') {
$category = grade_category::fetch('id', $this->iteminstance);
}
return $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_category() {
$this->category = $this->get_category();
return $this->category;
}
/**
* Returns this object's calculation.
* @param boolean $fetch Whether to fetch the value from the DB or not (false == just use the object's value)
* @return mixed $calculation A string if found, false otherwise.
*/
function get_calculation($fetch = false) {
if (!$fetch && get_class($this->calculation) == 'grade_calculation') {
return $this->calculation;
}
$grade_calculation = grade_calculation::fetch('itemid', $this->id);
if (empty($grade_calculation)) { // There is no calculation in DB
return false;
} elseif (empty($this->calculation) || !is_object($this->calculation)) { // The calculation isn't yet loaded
$this->calculation = $grade_calculation;
return $grade_calculation;
} elseif ($grade_calculation->calculation != $this->calculation->calculation) { // The object's calculation is not in sync with the DB (new value??)
$this->calculation = $grade_calculation;
return $grade_calculation;
} else { // The object's calculation is already in sync with the database
return $this->calculation;
}
}
/**
* Sets this item's calculation (creates it) if not yet set, or
* updates it if already set (in the DB). If no calculation is given,
* the method will attempt to retrieve one from the Database, based on
* the variables set in the current object.
* @param string $calculation
* @return boolean
*/
function set_calculation($calculation = null) {
if (empty($calculation)) { // We are setting this item object's calculation variable from the DB
$grade_calculation = $this->get_calculation(true);
if (empty($grade_calculation)) {
debugging("No calculation to set for this grade_item.");
return false;
} else {
$this->calculation = $grade_calculation;
}
} else { // We are updating or creating the calculation entry in the DB
$grade_calculation = $this->get_calculation();
if (empty($grade_calculation)) { // Creating
$grade_calculation = new grade_calculation();
$grade_calculation->calculation = $calculation;
$grade_calculation->itemid = $this->id;
if ($grade_calculation->insert()) {
$this->calculation = $grade_calculation;
return true;
} else {
debugging("Could not save the calculation in the database, for this grade_item.");
return false;
}
} else { // Updating
$grade_calculation->calculation = $calculation;
$grade_calculation = new grade_calculation($grade_calculation);
$this->calculation = $grade_calculation;
return $grade_calculation->update();
}
}
}
/**
* Returns the raw values for this grade item (as imported by module or other source).
* @param int $userid Optional: to retrieve a single raw grade
* @return mixed An array of all raw_grades (stdClass objects) for this grade_item, or a single raw_grade.
*/
function get_raw($userid=NULL) {
if (empty($this->grade_grades_raw)) {
$this->load_raw();
}
$grade_raw_array = null;
if (!empty($userid)) {
$r = get_record('grade_grades_raw', 'itemid', $this->id, 'userid', $userid);
$grade_raw_array[$r->userid] = new grade_grades_raw($r);
} else {
$grade_raw_array = $this->grade_grades_raw;
}
return $grade_raw_array;
}
/**
* Returns the final values for this grade item (as imported by module or other source).
* @param int $userid Optional: to retrieve a single final grade
* @return mixed An array of all final_grades (stdClass objects) for this grade_item, or a single final_grade.
*/
function get_final($userid=NULL) {
if (empty($this->grade_grades_final)) {
$this->load_final();
}
$grade_final_array = null;
if (!empty($userid)) {
$f = get_record('grade_grades_final', 'itemid', $this->id, 'userid', $userid);
$grade_final_array[$f->userid] = new grade_grades_final($f);
} else {
$grade_final_array = $this->grade_grades_final;
}
return $grade_final_array;
}
/**
* Returns the sortorder of this grade_item. This method is also available in
* grade_category, for cases where the object type is not know. It will act as a virtual
@ -922,6 +922,17 @@ class grade_item extends grade_object {
return $this->sortorder;
}
/**
* Sets the sortorder of this grade_item. This method is also available in
* grade_category, for cases where the object type is not know. It will act as a virtual
* variable for a grade_category.
* @param int $sortorder
* @return void
*/
function set_sortorder($sortorder) {
$this->sortorder = $sortorder;
}
/**
* 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.
@ -940,5 +951,21 @@ class grade_item extends grade_object {
function get_item_id() {
return $this->id;
}
/**
* Returns this item's category id. A generic method shared by objects that have a parent id of some kind.
* @return int $parentid
*/
function get_parent_id() {
return $this->categoryid;
}
/**
* Sets this item's categoryid. A generic method shared by objects that have a parent id of some kind.
* @param int $parentid
*/
function set_parent_id($parentid) {
$this->categoryid = $parentid;
}
}
?>

View File

@ -287,19 +287,18 @@ class grade_tree {
$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 (get_class($new_element->element['object']) == 'grade_item' && empty($new_element->element['final_grades']) && $this->include_grades) {
if ($new_element_class == 'grade_item' && !$has_final_grades && $this->include_grades) {
$new_element->element['final_grades'] = $new_element->element['object']->load_final();
unset($new_element->element['object']->grade_grades_final);
} elseif (get_class($new_element->element['object']) == 'grade_category' &&
empty($new_element->element['children']) &&
$new_element->element['object']->has_children()) {
} 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);
}
// TODO Problem when moving topcategories: sortorder gets reindexed when splicing the array
$destination_array = array($destination_sortorder => $new_element->element);
// Get the position of the destination element
@ -383,10 +382,11 @@ class grade_tree {
* down and across the tree.
* @param int $starting_sortorder Used by recursion to "seed" the first element in each sub-tree
* @param array $element A sub-tree given to each layer of recursion. If null, level 0 of recursion is assumed.
* @param int $parentid The id of the element within which this iteration of the method is running. Used to reassign element parentage.
* @return array A debugging array which shows the progression of variables throughout this method. This is very useful
* to identify problems and implement new functionality.
*/
function renumber($starting_sortorder=NULL, $elements=NULL) {
function renumber($starting_sortorder=NULL, $elements=NULL, $parentid=NULL) {
$sortorder = $starting_sortorder;
if (empty($elements) && empty($starting_sortorder)) {
@ -416,16 +416,15 @@ class grade_tree {
if (!empty($element['children'])) {
$newtree[$this->first_sortorder] = $element;
$newtree[$this->first_sortorder]['children'] = $this->renumber($this->first_sortorder, $element['children']);
$newtree[$this->first_sortorder]['children'] = $this->renumber($this->first_sortorder, $element['children'], $element['object']->id);
} else {
$newtree[$this->first_sortorder] = $element;
}
if ($new_sortorder != $old_sortorder) {
$this->need_update[$element['object']->get_item_id()] =
array('old_sortorder' => $old_sortorder,
'new_sortorder' => $new_sortorder,
'name' => $element['object']->get_name());
$element['object']->set_parent_id($parentid);
$element['object']->set_sortorder($new_sortorder);
$this->need_update[] = $element['object'];
}
}
@ -898,10 +897,10 @@ class grade_tree {
$this->need_delete = array();
$this->need_insert = array();
// The items' sortorder are updated
foreach ($this->need_update as $id => $element) {
if (!set_field('grade_items', 'sortorder', $element['new_sortorder'], 'id', $id)) {
debugging("Could not update the grade_item's sortorder in DB.");
// The objects are updated
foreach ($this->need_update as $object) {
if (!$object->update()) {
debugging("Could not update the object in DB.");
}
}

View File

@ -2007,6 +2007,37 @@ body#grade-index .grades .weighted {
margin:0px 20px 0px 20px;
}
#grade_edit_tree .insertion_box {
border: 1px #999999 solid;
background-color: #CCCCCC;
position: relative;
width: 40px;
height: 20px;
}
#grade_edit_tree li {
list-style: none;
}
#grade_edit_tree li.insertion {
cursor: pointer;
}
#grade_edit_tree .moveuparrow {
cursor: pointer;
}
#grade_edit_tree .movedownarrow {
cursor: pointer;
}
#grade_edit_tree form.movearrow div {
display: inline;
}
#grade_edit_tree form.movearrow {
display: inline;
}
/***
*** Login
***/