コード例 #1
0
ファイル: grade_category.php プロジェクト: covex-nn/moodle
 /**
  * Internal function for grade category grade aggregation
  *
  * @param int    $userid The User ID
  * @param array  $items Grade items
  * @param array  $grade_values Array of grade values
  * @param object $oldgrade Old grade
  * @param array  $excluded Excluded
  */
 private function aggregate_grades($userid, $items, $grade_values, $oldgrade, $excluded)
 {
     global $CFG;
     if (empty($userid)) {
         //ignore first call
         return;
     }
     if ($oldgrade) {
         $oldfinalgrade = $oldgrade->finalgrade;
         $grade = new grade_grade($oldgrade, false);
         $grade->grade_item =& $this->grade_item;
     } else {
         // insert final grade - it will be needed later anyway
         $grade = new grade_grade(array('itemid' => $this->grade_item->id, 'userid' => $userid), false);
         $grade->grade_item =& $this->grade_item;
         $grade->insert('system');
         $oldfinalgrade = null;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return;
     }
     // can not use own final category grade in calculation
     unset($grade_values[$this->grade_item->id]);
     // sum is a special aggregation types - it adjusts the min max, does not use relative values
     if ($this->aggregation == GRADE_AGGREGATE_SUM) {
         $this->sum_grades($grade, $oldfinalgrade, $items, $grade_values, $excluded);
         return;
     }
     // if no grades calculation possible or grading not allowed clear final grade
     if (empty($grade_values) or empty($items) or $this->grade_item->gradetype != GRADE_TYPE_VALUE and $this->grade_item->gradetype != GRADE_TYPE_SCALE) {
         $grade->finalgrade = null;
         if (!is_null($oldfinalgrade)) {
             $grade->update('aggregation');
         }
         return;
     }
     // normalize the grades first - all will have value 0...1
     // ungraded items are not used in aggregation
     foreach ($grade_values as $itemid => $v) {
         if (is_null($v)) {
             // null means no grade
             unset($grade_values[$itemid]);
             continue;
         } else {
             if (in_array($itemid, $excluded)) {
                 unset($grade_values[$itemid]);
                 continue;
             }
         }
         $grade_values[$itemid] = grade_grade::standardise_score($v, $items[$itemid]->grademin, $items[$itemid]->grademax, 0, 1);
     }
     // use min grade if grade missing for these types
     if (!$this->aggregateonlygraded) {
         foreach ($items as $itemid => $value) {
             if (!isset($grade_values[$itemid]) and !in_array($itemid, $excluded)) {
                 $grade_values[$itemid] = 0;
             }
         }
     }
     // limit and sort
     $this->apply_limit_rules($grade_values, $items);
     asort($grade_values, SORT_NUMERIC);
     // let's see we have still enough grades to do any statistics
     if (count($grade_values) == 0) {
         // not enough attempts yet
         $grade->finalgrade = null;
         if (!is_null($oldfinalgrade)) {
             $grade->update('aggregation');
         }
         return;
     }
     // do the maths
     $agg_grade = $this->aggregate_values($grade_values, $items);
     // recalculate the grade back to requested range
     $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
     $grade->finalgrade = $this->grade_item->bounded_grade($finalgrade);
     // update in db if changed
     if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
         $grade->update('aggregation');
     }
     return;
 }
コード例 #2
0
function import_xml_grades($text, $course, &$error)
{
    global $USER;
    $importcode = get_new_importcode();
    $status = true;
    $content = xmlize($text);
    if (!empty($content['results']['#']['result'])) {
        $results = $content['results']['#']['result'];
        foreach ($results as $i => $result) {
            $gradeidnumber = $result['#']['assignment'][0]['#'];
            if (!($grade_items = grade_item::fetch_all(array('idnumber' => $gradeidnumber, 'courseid' => $course->id)))) {
                // gradeitem does not exist
                // no data in temp table so far, abort
                $status = false;
                $error = get_string('errincorrectgradeidnumber', 'gradeimport_xml', $gradeidnumber);
                break;
            } else {
                if (count($grade_items) != 1) {
                    $status = false;
                    $error = get_string('errduplicategradeidnumber', 'gradeimport_xml', $gradeidnumber);
                    break;
                } else {
                    $grade_item = reset($grade_items);
                }
            }
            // grade item locked, abort
            if ($grade_item->is_locked()) {
                $status = false;
                $error = get_string('gradeitemlocked', 'grades');
                break;
            }
            // check if user exist and convert idnumber to user id
            $useridnumber = $result['#']['student'][0]['#'];
            if (!($user = get_record('user', 'idnumber', addslashes($useridnumber)))) {
                // no user found, abort
                $status = false;
                $error = get_string('errincorrectuseridnumber', 'gradeimport_xml', $useridnumber);
                break;
            }
            // check if grade_grade is locked and if so, abort
            if ($grade_grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $user->id))) {
                $grade_grade->grade_item =& $grade_item;
                if ($grade_grade->is_locked()) {
                    // individual grade locked, abort
                    $status = false;
                    $error = get_string('gradegradeslocked', 'grades');
                    break;
                }
            }
            $newgrade = new object();
            $newgrade->itemid = $grade_item->id;
            $newgrade->userid = $user->id;
            $newgrade->importcode = $importcode;
            $newgrade->importer = $USER->id;
            // check grade value exists and is a numeric grade
            if (isset($result['#']['score'][0]['#'])) {
                if (is_numeric($result['#']['score'][0]['#'])) {
                    $newgrade->finalgrade = $result['#']['score'][0]['#'];
                } else {
                    $status = false;
                    $error = get_string('badgrade', 'grades');
                    break;
                }
            } else {
                $newgrade->finalgrade = NULL;
            }
            // check grade feedback exists
            if (isset($result['#']['feedback'][0]['#'])) {
                $newgrade->feedback = $result['#']['feedback'][0]['#'];
            } else {
                $newgrade->feedback = NULL;
            }
            // insert this grade into a temp table
            if (!insert_record('grade_import_values', addslashes_recursive($newgrade))) {
                $status = false;
                // could not insert into temp table
                $error = get_string('importfailed', 'grades');
                break;
            }
        }
    } else {
        // no results section found in xml,
        // assuming bad format, abort import
        $status = false;
        $error = get_string('errbadxmlformat', 'gradeimport_xml');
    }
    if ($status) {
        return $importcode;
    } else {
        import_cleanup($importcode);
        return false;
    }
}
コード例 #3
0
ファイル: querylib.php プロジェクト: vuchannguyen/web
/**
 * Returns the aggregated or calculated course grade for the given user(s).
 * @public
 * @param int $userid
 * @param int $courseid optional id of course or array of ids, empty means all uses courses (returns array if not present)
 * @return mixed grade info or grades array including item info, false if error
 */
function grade_get_course_grade($userid, $courseid_or_ids = null)
{
    if (!is_array($courseid_or_ids)) {
        if (empty($courseid_or_ids)) {
            if (!($courses = enrol_get_users_courses($userid))) {
                return false;
            }
            $courseids = array_keys($courses);
            return grade_get_course_grade($userid, $courseids);
        }
        if (!is_numeric($courseid_or_ids)) {
            return false;
        }
        if (!($grades = grade_get_course_grade($userid, array($courseid_or_ids)))) {
            return false;
        } else {
            // only one grade - not array
            $grade = reset($grades);
            return $grade;
        }
    }
    foreach ($courseid_or_ids as $courseid) {
        $grade_item = grade_item::fetch_course_item($courseid);
        $course_items[$grade_item->courseid] = $grade_item;
    }
    $grades = array();
    foreach ($course_items as $grade_item) {
        if ($grade_item->needsupdate) {
            grade_regrade_final_grades($courseid);
        }
        $item = new stdClass();
        $item->scaleid = $grade_item->scaleid;
        $item->name = $grade_item->get_name();
        $item->grademin = $grade_item->grademin;
        $item->grademax = $grade_item->grademax;
        $item->gradepass = $grade_item->gradepass;
        $item->locked = $grade_item->is_locked();
        $item->hidden = $grade_item->is_hidden();
        switch ($grade_item->gradetype) {
            case GRADE_TYPE_NONE:
                continue;
            case GRADE_TYPE_VALUE:
                $item->scaleid = 0;
                break;
            case GRADE_TYPE_TEXT:
                $item->scaleid = 0;
                $item->grademin = 0;
                $item->grademax = 0;
                $item->gradepass = 0;
                break;
        }
        $grade_grade = new grade_grade(array('userid' => $userid, 'itemid' => $grade_item->id));
        $grade_grade->grade_item =& $grade_item;
        $grade = new stdClass();
        $grade->grade = $grade_grade->finalgrade;
        $grade->locked = $grade_grade->is_locked();
        $grade->hidden = $grade_grade->is_hidden();
        $grade->overridden = $grade_grade->overridden;
        $grade->feedback = $grade_grade->feedback;
        $grade->feedbackformat = $grade_grade->feedbackformat;
        $grade->usermodified = $grade_grade->usermodified;
        $grade->dategraded = $grade_grade->get_dategraded();
        $grade->item = $item;
        // create text representation of grade
        if ($grade_item->needsupdate) {
            $grade->grade = false;
            $grade->str_grade = get_string('error');
            $grade->str_long_grade = $grade->str_grade;
        } else {
            if (is_null($grade->grade)) {
                $grade->str_grade = '-';
                $grade->str_long_grade = $grade->str_grade;
            } else {
                $grade->str_grade = grade_format_gradevalue($grade->grade, $grade_item);
                if ($grade_item->gradetype == GRADE_TYPE_SCALE or $grade_item->get_displaytype() != GRADE_DISPLAY_TYPE_REAL) {
                    $grade->str_long_grade = $grade->str_grade;
                } else {
                    $a = new stdClass();
                    $a->grade = $grade->str_grade;
                    $a->max = grade_format_gradevalue($grade_item->grademax, $grade_item);
                    $grade->str_long_grade = get_string('gradelong', 'grades', $a);
                }
            }
        }
        // create html representation of feedback
        if (is_null($grade->feedback)) {
            $grade->str_feedback = '';
        } else {
            $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat);
        }
        $grades[$grade_item->courseid] = $grade;
    }
    return $grades;
}
コード例 #4
0
ファイル: index.php プロジェクト: covex-nn/moodle
     echo $OUTPUT->notification('user mapping error, could not find user!');
     break;
 }
 if ($separatemode and !groups_is_member($currentgroup, $studentid)) {
     // not allowed to import into this group, abort
     $status = false;
     import_cleanup($importcode);
     echo $OUTPUT->notification('user not member of current group, can not update!');
     break;
 }
 // insert results of this students into buffer
 if ($status and !empty($newgrades)) {
     foreach ($newgrades as $newgrade) {
         // check if grade_grade is locked and if so, abort
         if (!empty($newgrade->itemid) and $grade_grade = new grade_grade(array('itemid' => $newgrade->itemid, 'userid' => $studentid))) {
             if ($grade_grade->is_locked()) {
                 // individual grade locked
                 $status = false;
                 import_cleanup($importcode);
                 echo $OUTPUT->notification(get_string('gradelocked', 'grades'));
                 break 2;
             }
         }
         $newgrade->importcode = $importcode;
         $newgrade->userid = $studentid;
         $newgrade->importer = $USER->id;
         $DB->insert_record('grade_import_values', $newgrade);
     }
 }
 // updating/inserting all comments here
 if ($status and !empty($newfeedbacks)) {
コード例 #5
0
ファイル: grade_form.php プロジェクト: JP-Git/moodle
 function definition_after_data()
 {
     global $CFG, $COURSE, $DB;
     $context = context_course::instance($COURSE->id);
     $mform =& $this->_form;
     $grade_item = $this->_customdata['grade_item'];
     // fill in user name if user still exists
     $userid = $mform->getElementValue('userid');
     if ($user = $DB->get_record('user', array('id' => $userid))) {
         $username = '******' . $CFG->wwwroot . '/user/view.php?id=' . $userid . '">' . fullname($user) . '</a>';
         $user_el =& $mform->getElement('user');
         $user_el->setValue($username);
     }
     // add activity name + link
     if ($grade_item->itemtype == 'mod') {
         $cm = get_coursemodule_from_instance($grade_item->itemmodule, $grade_item->iteminstance, $grade_item->courseid);
         $itemname = '<a href="' . $CFG->wwwroot . '/mod/' . $grade_item->itemmodule . '/view.php?id=' . $cm->id . '">' . $grade_item->get_name() . '</a>';
     } else {
         $itemname = $grade_item->get_name();
     }
     $itemname_el =& $mform->getElement('itemname');
     $itemname_el->setValue($itemname);
     // access control - disable not allowed elements
     if (!has_capability('moodle/grade:manage', $context)) {
         $mform->hardFreeze('excluded');
     }
     if (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:hide', $context)) {
         $mform->hardFreeze('hidden');
         $mform->hardFreeze('hiddenuntil');
     }
     $old_grade_grade = new grade_grade(array('itemid' => $grade_item->id, 'userid' => $userid));
     if (!$grade_item->is_overridable_item()) {
         $mform->removeElement('overridden');
     }
     if ($grade_item->is_hidden()) {
         $mform->hardFreeze('hidden');
     }
     if ($old_grade_grade->is_locked()) {
         if ($grade_item->is_locked()) {
             $mform->hardFreeze('locked');
             $mform->hardFreeze('locktime');
         }
         $mform->hardFreeze('overridden');
         $mform->hardFreeze('finalgrade');
         $mform->hardFreeze('feedback');
     } else {
         if (empty($old_grade_grade->id)) {
             $old_grade_grade->locked = $grade_item->locked;
             $old_grade_grade->locktime = $grade_item->locktime;
         }
         if (($old_grade_grade->locked or $old_grade_grade->locktime) and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:unlock', $context))) {
             $mform->hardFreeze('locked');
             $mform->hardFreeze('locktime');
         } else {
             if (!$old_grade_grade->locked and !$old_grade_grade->locktime and (!has_capability('moodle/grade:manage', $context) and !has_capability('moodle/grade:lock', $context))) {
                 $mform->hardFreeze('locked');
                 $mform->hardFreeze('locktime');
             }
         }
     }
 }
コード例 #6
0
ファイル: grade_item.php プロジェクト: r007/PMoodle
 /**
  * internal function - does the final grade calculation
  */
 function use_formula($userid, $params, $useditems, $oldgrade)
 {
     if (empty($userid)) {
         return true;
     }
     // add missing final grade values
     // not graded (null) is counted as 0 - the spreadsheet way
     foreach ($useditems as $gi) {
         if (!array_key_exists('gi' . $gi, $params)) {
             $params['gi' . $gi] = 0;
         } else {
             $params['gi' . $gi] = (double) $params['gi' . $gi];
         }
     }
     // can not use own final grade during calculation
     unset($params['gi' . $this->id]);
     // insert final grade - will be needed later anyway
     if ($oldgrade) {
         $oldfinalgrade = $oldgrade->finalgrade;
         $grade = new grade_grade($oldgrade, false);
         // fetching from db is not needed
         $grade->grade_item =& $this;
     } else {
         $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid), false);
         $grade->grade_item =& $this;
         $grade->insert('system');
         $oldfinalgrade = null;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return true;
     }
     // do the calculation
     $this->formula->set_params($params);
     $result = $this->formula->evaluate();
     if ($result === false) {
         $grade->finalgrade = null;
     } else {
         // normalize
         $result = bounded_number($this->grademin, $result, $this->grademax);
         if ($this->gradetype == GRADE_TYPE_SCALE) {
             $result = round($result + 1.0E-5);
             // round scales upwards
         }
         $grade->finalgrade = $result;
     }
     // update in db if changed
     if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
         $grade->update('compute');
     }
     if ($result !== false) {
         //lock grade if needed
     }
     if ($result === false) {
         return false;
     } else {
         return true;
     }
 }
コード例 #7
0
ファイル: grade_category.php プロジェクト: jtibbetts/moodle
 /**
  * Internal function for grade category grade aggregation
  *
  * @param int    $userid The User ID
  * @param array  $items Grade items
  * @param array  $grade_values Array of grade values
  * @param object $oldgrade Old grade
  * @param array  $excluded Excluded
  * @param array  $grademinoverrides User specific grademin values if different to the grade_item grademin (key is itemid)
  * @param array  $grademaxoverrides User specific grademax values if different to the grade_item grademax (key is itemid)
  */
 private function aggregate_grades($userid, $items, $grade_values, $oldgrade, $excluded, $grademinoverrides, $grademaxoverrides)
 {
     global $CFG, $DB;
     // Remember these so we can set flags on them to describe how they were used in the aggregation.
     $novalue = array();
     $dropped = array();
     $extracredit = array();
     $usedweights = array();
     if (empty($userid)) {
         //ignore first call
         return;
     }
     if ($oldgrade) {
         $oldfinalgrade = $oldgrade->finalgrade;
         $grade = new grade_grade($oldgrade, false);
         $grade->grade_item =& $this->grade_item;
     } else {
         // insert final grade - it will be needed later anyway
         $grade = new grade_grade(array('itemid' => $this->grade_item->id, 'userid' => $userid), false);
         $grade->grade_item =& $this->grade_item;
         $grade->insert('system');
         $oldfinalgrade = null;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return;
     }
     // can not use own final category grade in calculation
     unset($grade_values[$this->grade_item->id]);
     // Make sure a grade_grade exists for every grade_item.
     // We need to do this so we can set the aggregationstatus
     // with a set_field call instead of checking if each one exists and creating/updating.
     if (!empty($items)) {
         list($ggsql, $params) = $DB->get_in_or_equal(array_keys($items), SQL_PARAMS_NAMED, 'g');
         $params['userid'] = $userid;
         $sql = "SELECT itemid\n                      FROM {grade_grades}\n                     WHERE itemid {$ggsql} AND userid = :userid";
         $existingitems = $DB->get_records_sql($sql, $params);
         $notexisting = array_diff(array_keys($items), array_keys($existingitems));
         foreach ($notexisting as $itemid) {
             $gradeitem = $items[$itemid];
             $gradegrade = new grade_grade(array('itemid' => $itemid, 'userid' => $userid, 'rawgrademin' => $gradeitem->grademin, 'rawgrademax' => $gradeitem->grademax), false);
             $gradegrade->grade_item = $gradeitem;
             $gradegrade->insert('system');
         }
     }
     // if no grades calculation possible or grading not allowed clear final grade
     if (empty($grade_values) or empty($items) or $this->grade_item->gradetype != GRADE_TYPE_VALUE and $this->grade_item->gradetype != GRADE_TYPE_SCALE) {
         $grade->finalgrade = null;
         if (!is_null($oldfinalgrade)) {
             $success = $grade->update('aggregation');
             // If successful trigger a user_graded event.
             if ($success) {
                 \core\event\user_graded::create_from_grade($grade)->trigger();
             }
         }
         $dropped = $grade_values;
         $this->set_usedinaggregation($userid, $usedweights, $novalue, $dropped, $extracredit);
         return;
     }
     // Normalize the grades first - all will have value 0...1
     // ungraded items are not used in aggregation.
     foreach ($grade_values as $itemid => $v) {
         if (is_null($v)) {
             // If null, it means no grade.
             if ($this->aggregateonlygraded) {
                 unset($grade_values[$itemid]);
                 // Mark this item as "excluded empty" because it has no grade.
                 $novalue[$itemid] = 0;
                 continue;
             }
         }
         if (in_array($itemid, $excluded)) {
             unset($grade_values[$itemid]);
             $dropped[$itemid] = 0;
             continue;
         }
         // Check for user specific grade min/max overrides.
         $usergrademin = $items[$itemid]->grademin;
         $usergrademax = $items[$itemid]->grademax;
         if (isset($grademinoverrides[$itemid])) {
             $usergrademin = $grademinoverrides[$itemid];
         }
         if (isset($grademaxoverrides[$itemid])) {
             $usergrademax = $grademaxoverrides[$itemid];
         }
         if ($this->aggregation == GRADE_AGGREGATE_SUM) {
             // Assume that the grademin is 0 when standardising the score, to preserve negative grades.
             $grade_values[$itemid] = grade_grade::standardise_score($v, 0, $usergrademax, 0, 1);
         } else {
             $grade_values[$itemid] = grade_grade::standardise_score($v, $usergrademin, $usergrademax, 0, 1);
         }
     }
     // For items with no value, and not excluded - either set their grade to 0 or exclude them.
     foreach ($items as $itemid => $value) {
         if (!isset($grade_values[$itemid]) and !in_array($itemid, $excluded)) {
             if (!$this->aggregateonlygraded) {
                 $grade_values[$itemid] = 0;
             } else {
                 // We are specifically marking these items as "excluded empty".
                 $novalue[$itemid] = 0;
             }
         }
     }
     // limit and sort
     $allvalues = $grade_values;
     if ($this->can_apply_limit_rules()) {
         $this->apply_limit_rules($grade_values, $items);
     }
     $moredropped = array_diff($allvalues, $grade_values);
     foreach ($moredropped as $drop => $unused) {
         $dropped[$drop] = 0;
     }
     foreach ($grade_values as $itemid => $val) {
         if (self::is_extracredit_used() && $items[$itemid]->aggregationcoef > 0) {
             $extracredit[$itemid] = 0;
         }
     }
     asort($grade_values, SORT_NUMERIC);
     // let's see we have still enough grades to do any statistics
     if (count($grade_values) == 0) {
         // not enough attempts yet
         $grade->finalgrade = null;
         if (!is_null($oldfinalgrade)) {
             $success = $grade->update('aggregation');
             // If successful trigger a user_graded event.
             if ($success) {
                 \core\event\user_graded::create_from_grade($grade)->trigger();
             }
         }
         $this->set_usedinaggregation($userid, $usedweights, $novalue, $dropped, $extracredit);
         return;
     }
     // do the maths
     $result = $this->aggregate_values_and_adjust_bounds($grade_values, $items, $usedweights, $grademinoverrides, $grademaxoverrides);
     $agg_grade = $result['grade'];
     // Set the actual grademin and max to bind the grade properly.
     $this->grade_item->grademin = $result['grademin'];
     $this->grade_item->grademax = $result['grademax'];
     if ($this->aggregation == GRADE_AGGREGATE_SUM) {
         // The natural aggregation always displays the range as coming from 0 for categories.
         // However, when we bind the grade we allow for negative values.
         $result['grademin'] = 0;
     }
     // Recalculate the grade back to requested range.
     $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $result['grademin'], $result['grademax']);
     $grade->finalgrade = $this->grade_item->bounded_grade($finalgrade);
     $oldrawgrademin = $grade->rawgrademin;
     $oldrawgrademax = $grade->rawgrademax;
     $grade->rawgrademin = $result['grademin'];
     $grade->rawgrademax = $result['grademax'];
     // Update in db if changed.
     if (grade_floats_different($grade->finalgrade, $oldfinalgrade) || grade_floats_different($grade->rawgrademax, $oldrawgrademax) || grade_floats_different($grade->rawgrademin, $oldrawgrademin)) {
         $success = $grade->update('aggregation');
         // If successful trigger a user_graded event.
         if ($success) {
             \core\event\user_graded::create_from_grade($grade)->trigger();
         }
     }
     $this->set_usedinaggregation($userid, $usedweights, $novalue, $dropped, $extracredit);
     return;
 }
コード例 #8
0
ファイル: grade_item.php プロジェクト: mongo0se/moodle
 /**
  * Internal function that does the final grade calculation
  *
  * @param int $userid The user ID
  * @param array $params An array of grade items of the form {'gi'.$itemid]} => $finalgrade
  * @param array $useditems An array of grade item IDs that this grade item depends on plus its own ID
  * @param grade_grade $oldgrade A grade_grade instance containing the old values from the database
  * @return bool False if an error occurred
  */
 public function use_formula($userid, $params, $useditems, $oldgrade)
 {
     if (empty($userid)) {
         return true;
     }
     // add missing final grade values
     // not graded (null) is counted as 0 - the spreadsheet way
     $allinputsnull = true;
     foreach ($useditems as $gi) {
         if (!array_key_exists('gi' . $gi, $params) || is_null($params['gi' . $gi])) {
             $params['gi' . $gi] = 0;
         } else {
             $params['gi' . $gi] = (double) $params['gi' . $gi];
             if ($gi != $this->id) {
                 $allinputsnull = false;
             }
         }
     }
     // can not use own final grade during calculation
     unset($params['gi' . $this->id]);
     // Check to see if the gradebook is frozen. This allows grades to not be altered at all until a user verifies that they
     // wish to update the grades.
     $gradebookcalculationsfreeze = get_config('core', 'gradebook_calculations_freeze_' . $this->courseid);
     $rawminandmaxchanged = false;
     // insert final grade - will be needed later anyway
     if ($oldgrade) {
         // Only run through this code if the gradebook isn't frozen.
         if ($gradebookcalculationsfreeze && (int) $gradebookcalculationsfreeze <= 20150627) {
             // Do nothing.
         } else {
             // The grade_grade for a calculated item should have the raw grade maximum and minimum set to the
             // grade_item grade maximum and minimum respectively.
             if ($oldgrade->rawgrademax != $this->grademax || $oldgrade->rawgrademin != $this->grademin) {
                 $rawminandmaxchanged = true;
                 $oldgrade->rawgrademax = $this->grademax;
                 $oldgrade->rawgrademin = $this->grademin;
             }
         }
         $oldfinalgrade = $oldgrade->finalgrade;
         $grade = new grade_grade($oldgrade, false);
         // fetching from db is not needed
         $grade->grade_item =& $this;
     } else {
         $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid), false);
         $grade->grade_item =& $this;
         $rawminandmaxchanged = false;
         if ($gradebookcalculationsfreeze && (int) $gradebookcalculationsfreeze <= 20150627) {
             // Do nothing.
         } else {
             // The grade_grade for a calculated item should have the raw grade maximum and minimum set to the
             // grade_item grade maximum and minimum respectively.
             $rawminandmaxchanged = true;
             $grade->rawgrademax = $this->grademax;
             $grade->rawgrademin = $this->grademin;
         }
         $grade->insert('system');
         $oldfinalgrade = null;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return true;
     }
     if ($allinputsnull) {
         $grade->finalgrade = null;
         $result = true;
     } else {
         // do the calculation
         $this->formula->set_params($params);
         $result = $this->formula->evaluate();
         if ($result === false) {
             $grade->finalgrade = null;
         } else {
             // normalize
             $grade->finalgrade = $this->bounded_grade($result);
         }
     }
     // Only run through this code if the gradebook isn't frozen.
     if ($gradebookcalculationsfreeze && (int) $gradebookcalculationsfreeze <= 20150627) {
         // Update in db if changed.
         if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
             $grade->timemodified = time();
             $success = $grade->update('compute');
             // If successful trigger a user_graded event.
             if ($success) {
                 \core\event\user_graded::create_from_grade($grade)->trigger();
             }
         }
     } else {
         // Update in db if changed.
         if (grade_floats_different($grade->finalgrade, $oldfinalgrade) || $rawminandmaxchanged) {
             $grade->timemodified = time();
             $success = $grade->update('compute');
             // If successful trigger a user_graded event.
             if ($success) {
                 \core\event\user_graded::create_from_grade($grade)->trigger();
             }
         }
     }
     if ($result !== false) {
         //lock grade if needed
     }
     if ($result === false) {
         return false;
     } else {
         return true;
     }
 }
コード例 #9
0
 /**
  * Internal function that does the final grade calculation
  *
  * @param int $userid The user ID
  * @param array $params An array of grade items of the form {'gi'.$itemid]} => $finalgrade
  * @param array $useditems An array of grade item IDs that this grade item depends on plus its own ID
  * @param grade_grade $oldgrade A grade_grade instance containing the old values from the database
  * @return bool False if an error occurred
  */
 public function use_formula($userid, $params, $useditems, $oldgrade)
 {
     if (empty($userid)) {
         return true;
     }
     // add missing final grade values
     // not graded (null) is counted as 0 - the spreadsheet way
     $allinputsnull = true;
     foreach ($useditems as $gi) {
         if (!array_key_exists('gi' . $gi, $params) || is_null($params['gi' . $gi])) {
             $params['gi' . $gi] = 0;
         } else {
             $params['gi' . $gi] = (double) $params['gi' . $gi];
             if ($gi != $this->id) {
                 $allinputsnull = false;
             }
         }
     }
     // can not use own final grade during calculation
     unset($params['gi' . $this->id]);
     // insert final grade - will be needed later anyway
     if ($oldgrade) {
         $oldfinalgrade = $oldgrade->finalgrade;
         $grade = new grade_grade($oldgrade, false);
         // fetching from db is not needed
         $grade->grade_item =& $this;
     } else {
         $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid), false);
         $grade->grade_item =& $this;
         $grade->insert('system');
         $oldfinalgrade = null;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return true;
     }
     if ($allinputsnull) {
         $grade->finalgrade = null;
         $result = true;
     } else {
         // do the calculation
         $this->formula->set_params($params);
         $result = $this->formula->evaluate();
         if ($result === false) {
             $grade->finalgrade = null;
         } else {
             // normalize
             $grade->finalgrade = $this->bounded_grade($result);
         }
     }
     // update in db if changed
     if (grade_floats_different($grade->finalgrade, $oldfinalgrade)) {
         $grade->timemodified = time();
         $grade->update('compute');
     }
     if ($result !== false) {
         //lock grade if needed
     }
     if ($result === false) {
         return false;
     } else {
         return true;
     }
 }
コード例 #10
0
ファイル: load_data.php プロジェクト: evltuma/moodle
 /**
  * Checks and prepares grade data for inserting into the gradebook.
  *
  * @param array $header Column headers of the CSV file.
  * @param object $formdata Mapping information from the preview page.
  * @param object $csvimport csv import reader object for iterating over the imported CSV file.
  * @param int $courseid The course ID.
  * @param bool $separatemode If we have groups are they separate?
  * @param mixed $currentgroup current group information.
  * @param bool $verbosescales Form setting for grading with scales.
  * @return bool True if the status for importing is okay, false if there are errors.
  */
 public function prepare_import_grade_data($header, $formdata, $csvimport, $courseid, $separatemode, $currentgroup, $verbosescales)
 {
     global $DB, $USER;
     // The import code is used for inserting data into the grade tables.
     $this->importcode = $formdata->importcode;
     $this->status = true;
     $this->headers = $header;
     $this->studentid = null;
     $this->gradebookerrors = null;
     $forceimport = $formdata->forceimport;
     // Temporary array to keep track of what new headers are processed.
     $this->newgradeitems = array();
     $this->trim_headers();
     $timeexportkey = null;
     $map = array();
     // Loops mapping_0, mapping_1 .. mapping_n and construct $map array.
     foreach ($header as $i => $head) {
         if (isset($formdata->{'mapping_' . $i})) {
             $map[$i] = $formdata->{'mapping_' . $i};
         }
         if ($head == get_string('timeexported', 'gradeexport_txt')) {
             $timeexportkey = $i;
         }
     }
     // If mapping information is supplied.
     $map[clean_param($formdata->mapfrom, PARAM_RAW)] = clean_param($formdata->mapto, PARAM_RAW);
     // Check for mapto collisions.
     $maperrors = array();
     foreach ($map as $i => $j) {
         if ($j == 0) {
             // You can have multiple ignores.
             continue;
         } else {
             if (!isset($maperrors[$j])) {
                 $maperrors[$j] = true;
             } else {
                 // Collision.
                 print_error('cannotmapfield', '', '', $j);
             }
         }
     }
     $this->raise_limits();
     $csvimport->init();
     while ($line = $csvimport->next()) {
         if (count($line) <= 1) {
             // There is no data on this line, move on.
             continue;
         }
         // Array to hold all grades to be inserted.
         $this->newgrades = array();
         // Array to hold all feedback.
         $this->newfeedbacks = array();
         // Each line is a student record.
         foreach ($line as $key => $value) {
             $value = clean_param($value, PARAM_RAW);
             $value = trim($value);
             /*
              * the options are
              * 1) userid, useridnumber, usermail, username - used to identify user row
              * 2) new - new grade item
              * 3) id - id of the old grade item to map onto
              * 3) feedback_id - feedback for grade item id
              */
             // Explode the mapping for feedback into a label 'feedback' and the identifying number.
             $mappingbase = explode("_", $map[$key]);
             $mappingidentifier = $mappingbase[0];
             // Set the feedback identifier if it exists.
             if (isset($mappingbase[1])) {
                 $feedbackgradeid = (int) $mappingbase[1];
             } else {
                 $feedbackgradeid = '';
             }
             $this->map_user_data_with_value($mappingidentifier, $value, $header, $map, $key, $courseid, $feedbackgradeid, $verbosescales);
             if ($this->status === false) {
                 return $this->status;
             }
         }
         // No user mapping supplied at all, or user mapping failed.
         if (empty($this->studentid) || !is_numeric($this->studentid)) {
             // User not found, abort whole import.
             $this->cleanup_import(get_string('usermappingerrorusernotfound', 'grades'));
             break;
         }
         if ($separatemode and !groups_is_member($currentgroup, $this->studentid)) {
             // Not allowed to import into this group, abort.
             $this->cleanup_import(get_string('usermappingerrorcurrentgroup', 'grades'));
             break;
         }
         // Insert results of this students into buffer.
         if ($this->status and !empty($this->newgrades)) {
             foreach ($this->newgrades as $newgrade) {
                 // Check if grade_grade is locked and if so, abort.
                 if (!empty($newgrade->itemid) and $gradegrade = new grade_grade(array('itemid' => $newgrade->itemid, 'userid' => $this->studentid))) {
                     if ($gradegrade->is_locked()) {
                         // Individual grade locked.
                         $this->cleanup_import(get_string('gradelocked', 'grades'));
                         return $this->status;
                     }
                     // Check if the force import option is disabled and the last exported date column is present.
                     if (!$forceimport && !empty($timeexportkey)) {
                         $exportedtime = $line[$timeexportkey];
                         if (clean_param($exportedtime, PARAM_INT) != $exportedtime || $exportedtime > time() || $exportedtime < strtotime("-1 year", time())) {
                             // The date is invalid, or in the future, or more than a year old.
                             $this->cleanup_import(get_string('invalidgradeexporteddate', 'grades'));
                             return $this->status;
                         }
                         $timemodified = $gradegrade->get_dategraded();
                         if (!empty($timemodified) && $exportedtime < $timemodified) {
                             // The item was graded after we exported it, we return here not to override it.
                             $user = core_user::get_user($this->studentid);
                             $this->cleanup_import(get_string('gradealreadyupdated', 'grades', fullname($user)));
                             return $this->status;
                         }
                     }
                 }
                 $insertid = self::insert_grade_record($newgrade, $this->studentid);
                 // Check to see if the insert was successful.
                 if (empty($insertid)) {
                     return null;
                 }
             }
         }
         // Updating/inserting all comments here.
         if ($this->status and !empty($this->newfeedbacks)) {
             foreach ($this->newfeedbacks as $newfeedback) {
                 $sql = "SELECT *\n                              FROM {grade_import_values}\n                             WHERE importcode=? AND userid=? AND itemid=? AND importer=?";
                 if ($feedback = $DB->get_record_sql($sql, array($this->importcode, $this->studentid, $newfeedback->itemid, $USER->id))) {
                     $newfeedback->id = $feedback->id;
                     $DB->update_record('grade_import_values', $newfeedback);
                 } else {
                     // The grade item for this is not updated.
                     $newfeedback->importonlyfeedback = true;
                     $insertid = self::insert_grade_record($newfeedback, $this->studentid);
                     // Check to see if the insert was successful.
                     if (empty($insertid)) {
                         return null;
                     }
                 }
             }
         }
     }
     return $this->status;
 }
コード例 #11
0
 /**
  * Updates final grade value for given user, this is a only way to update final
  * grades from gradebook and import because it logs the change in history table
  * and deals with overridden flag. This flag is set to prevent later overriding
  * from raw grades submitted from modules.
  *
  * @param int $userid the graded user
  * @param mixed $finalgrade float value of final grade - false means do not change
  * @param string $howmodified modification source
  * @param string $note optional note
  * @param mixed $feedback teachers feedback as string - false means do not change
  * @param int $feedbackformat
  * @return boolean success
  */
 function update_final_grade($userid, $finalgrade = false, $source = NULL, $feedback = false, $feedbackformat = FORMAT_MOODLE, $usermodified = null)
 {
     global $USER, $CFG;
     $result = true;
     // no grading used or locked
     if ($this->gradetype == GRADE_TYPE_NONE or $this->is_locked()) {
         return false;
     }
     $grade = new grade_grade(array('itemid' => $this->id, 'userid' => $userid));
     $grade->grade_item =& $this;
     // prevent db fetching of this grade_item
     if (empty($usermodified)) {
         $grade->usermodified = $USER->id;
     } else {
         $grade->usermodified = $usermodified;
     }
     if ($grade->is_locked()) {
         // do not update locked grades at all
         return false;
     }
     $locktime = $grade->get_locktime();
     if ($locktime and $locktime < time()) {
         // do not update grades that should be already locked, force regrade instead
         $this->force_regrading();
         return false;
     }
     $oldgrade = new object();
     $oldgrade->finalgrade = $grade->finalgrade;
     $oldgrade->overridden = $grade->overridden;
     $oldgrade->feedback = $grade->feedback;
     $oldgrade->feedbackformat = $grade->feedbackformat;
     // changed grade?
     if ($finalgrade !== false) {
         if ($this->is_overridable_item()) {
             $grade->overridden = time();
         } else {
             $grade->overridden = 0;
         }
         $grade->finalgrade = $this->bounded_grade($finalgrade);
     }
     // do we have comment from teacher?
     if ($feedback !== false) {
         if ($this->is_overridable_item_feedback()) {
             // external items (modules, plugins) may have own feedback
             $grade->overridden = time();
         }
         $grade->feedback = $feedback;
         $grade->feedbackformat = $feedbackformat;
     }
     // HACK: Bob Puffer to allow accurate max score to be inserted into the grade_item record
     $grade->rawgrademax = $this->grademax;
     // END OF HACK
     if (empty($grade->id)) {
         $grade->timecreated = null;
         // hack alert - date submitted - no submission yet
         $grade->timemodified = time();
         // hack alert - date graded
         $result = (bool) $grade->insert($source);
     } else {
         if (grade_floats_different($grade->finalgrade, $oldgrade->finalgrade) or $grade->feedback !== $oldgrade->feedback or $grade->feedbackformat != $oldgrade->feedbackformat or $grade->overridden != $oldgrade->overridden) {
             $grade->timemodified = time();
             // hack alert - date graded
             $result = $grade->update($source);
         } else {
             // no grade change
             return $result;
         }
     }
     if (!$result) {
         // something went wrong - better force final grade recalculation
         $this->force_regrading();
     } else {
         if ($this->is_course_item() and !$this->needsupdate) {
             if (grade_regrade_final_grades($this->courseid, $userid, $this) !== true) {
                 $this->force_regrading();
             }
         } else {
             if (!$this->needsupdate) {
                 $course_item = grade_item_local::fetch_course_item($this->courseid);
                 if (!$course_item->needsupdate) {
                     if (grade_regrade_final_grades_local($this->courseid, $userid, $this) !== true) {
                         $this->force_regrading();
                     }
                 } else {
                     $this->force_regrading();
                 }
             }
         }
     }
     return $result;
 }
コード例 #12
0
 /**
  * internal function for category grades aggregation
  */
 function aggregate_grades($userid, $items, $grade_values, $oldgrade, $excluded)
 {
     global $CFG;
     if (empty($userid)) {
         //ignore first call
         return;
     }
     if ($oldgrade) {
         $grade = new grade_grade($oldgrade, false);
         $grade->grade_item =& $this->grade_item;
     } else {
         // insert final grade - it will be needed later anyway
         $grade = new grade_grade(array('itemid' => $this->grade_item->id, 'userid' => $userid), false);
         $grade->insert('system');
         $grade->grade_item =& $this->grade_item;
         $oldgrade = new object();
         $oldgrade->finalgrade = $grade->finalgrade;
         $oldgrade->rawgrade = $grade->rawgrade;
         $oldgrade->rawgrademin = $grade->rawgrademin;
         $oldgrade->rawgrademax = $grade->rawgrademax;
         $oldgrade->rawscaleid = $grade->rawscaleid;
     }
     // no need to recalculate locked or overridden grades
     if ($grade->is_locked() or $grade->is_overridden()) {
         return;
     }
     // can not use own final category grade in calculation
     unset($grade_values[$this->grade_item->id]);
     // if no grades calculation possible or grading not allowed clear both final and raw
     if (empty($grade_values) or empty($items) or $this->grade_item->gradetype != GRADE_TYPE_VALUE and $this->grade_item->gradetype != GRADE_TYPE_SCALE) {
         $grade->finalgrade = null;
         $grade->rawgrade = null;
         if ($grade->finalgrade !== $oldgrade->finalgrade or $grade->rawgrade !== $oldgrade->rawgrade) {
             $grade->update('system');
         }
         return;
     }
     /// normalize the grades first - all will have value 0...1
     // ungraded items are not used in aggregation
     foreach ($grade_values as $itemid => $v) {
         if (is_null($v)) {
             // null means no grade
             unset($grade_values[$itemid]);
             continue;
         } else {
             if (in_array($itemid, $excluded)) {
                 unset($grade_values[$itemid]);
                 continue;
             }
         }
         $grade_values[$itemid] = grade_grade::standardise_score($v, $items[$itemid]->grademin, $items[$itemid]->grademax, 0, 1);
     }
     // If global aggregateonlygraded is set, override category value
     if ($CFG->grade_aggregateonlygraded != -1) {
         $this->aggregateonlygraded = $CFG->grade_aggregateonlygraded;
     }
     // use min grade if grade missing for these types
     if (!$this->aggregateonlygraded) {
         foreach ($items as $itemid => $value) {
             if (!isset($grade_values[$itemid]) and !in_array($itemid, $excluded)) {
                 $grade_values[$itemid] = 0;
             }
         }
     }
     // limit and sort
     $this->apply_limit_rules($grade_values);
     asort($grade_values, SORT_NUMERIC);
     // let's see we have still enough grades to do any statistics
     if (count($grade_values) == 0) {
         // not enough attempts yet
         $grade->finalgrade = null;
         $grade->rawgrade = null;
         if ($grade->finalgrade !== $oldgrade->finalgrade or $grade->rawgrade !== $oldgrade->rawgrade) {
             $grade->update('system');
         }
         return;
     }
     /// start the aggregation
     switch ($this->aggregation) {
         case GRADE_AGGREGATE_MEDIAN:
             // Middle point value in the set: ignores frequencies
             $num = count($grade_values);
             $grades = array_values($grade_values);
             if ($num % 2 == 0) {
                 $agg_grade = ($grades[intval($num / 2) - 1] + $grades[intval($num / 2)]) / 2;
             } else {
                 $agg_grade = $grades[intval($num / 2 - 0.5)];
             }
             break;
         case GRADE_AGGREGATE_MIN:
             $agg_grade = reset($grade_values);
             break;
         case GRADE_AGGREGATE_MAX:
             $agg_grade = array_pop($grade_values);
             break;
         case GRADE_AGGREGATE_MODE:
             // the most common value, average used if multimode
             $freq = array_count_values($grade_values);
             arsort($freq);
             // sort by frequency keeping keys
             $top = reset($freq);
             // highest frequency count
             $modes = array_keys($freq, $top);
             // search for all modes (have the same highest count)
             rsort($modes, SORT_NUMERIC);
             // get highes mode
             $agg_grade = reset($modes);
             break;
         case GRADE_AGGREGATE_WEIGHTED_MEAN:
             // Weighted average of all existing final grades
             $weightsum = 0;
             $sum = 0;
             foreach ($grade_values as $itemid => $grade_value) {
                 if ($items[$itemid]->aggregationcoef <= 0) {
                     continue;
                 }
                 $weightsum += $items[$itemid]->aggregationcoef;
                 $sum += $items[$itemid]->aggregationcoef * $grade_value;
             }
             if ($weightsum == 0) {
                 $agg_grade = null;
             } else {
                 $agg_grade = $sum / $weightsum;
             }
             break;
         case GRADE_AGGREGATE_EXTRACREDIT_MEAN:
             // special average
             $num = 0;
             $sum = 0;
             foreach ($grade_values as $itemid => $grade_value) {
                 if ($items[$itemid]->aggregationcoef == 0) {
                     $num += 1;
                     $sum += $grade_value;
                 } else {
                     if ($items[$itemid]->aggregationcoef > 0) {
                         $sum += $items[$itemid]->aggregationcoef * $grade_value;
                     }
                 }
             }
             if ($num == 0) {
                 $agg_grade = $sum;
                 // only extra credits or wrong coefs
             } else {
                 $agg_grade = $sum / $num;
             }
             break;
         case GRADE_AGGREGATE_MEAN:
             // Arithmetic average of all grade items (if ungraded aggregated, NULL counted as minimum)
         // Arithmetic average of all grade items (if ungraded aggregated, NULL counted as minimum)
         default:
             $num = count($grade_values);
             $sum = array_sum($grade_values);
             $agg_grade = $sum / $num;
             break;
     }
     /// prepare update of new raw grade
     $grade->rawgrademin = $this->grade_item->grademin;
     $grade->rawgrademax = $this->grade_item->grademax;
     $grade->rawscaleid = $this->grade_item->scaleid;
     $grade->rawgrade = null;
     // categories do not use raw grades
     // recalculate the rawgrade back to requested range
     $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
     if (!is_null($finalgrade)) {
         $grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
     } else {
         $grade->finalgrade = $finalgrade;
     }
     // update in db if changed
     if ($grade->finalgrade !== $oldgrade->finalgrade or $grade->rawgrade !== $oldgrade->rawgrade or $grade->rawgrademin !== $oldgrade->rawgrademin or $grade->rawgrademax !== $oldgrade->rawgrademax or $grade->rawscaleid !== $oldgrade->rawscaleid) {
         $grade->update('system');
     }
     return;
 }
コード例 #13
0
 /**
  * Harvest the grades from the data base and build the finalgrades array.
  * Filters out hidden, locked and null grades based on users settings.
  * Partly based on grader reports load_final_grades function.
  */
 public function harvest_data()
 {
     global $CFG, $DB;
     $params = array();
     if (isset($DB) && !is_null($DB)) {
         $params = array_merge(array($this->courseid), $this->userselect_params);
         /// please note that we must fetch all grade_grades fields if we want to contruct grade_grade object from it!
         $sql = "SELECT g.*\n                  FROM {grade_items} gi,\n                       {grade_grades} g\n                 WHERE g.itemid = gi.id AND gi.courseid = ? {$this->userselect}";
         $grades = $DB->get_records_sql($sql, $params);
     } else {
         /// please note that we must fetch all grade_grades fields if we want to contruct grade_grade object from it!
         $sql = "SELECT g.*\n                  FROM {$CFG->prefix}grade_items gi,\n                       {$CFG->prefix}grade_grades g\n                 WHERE g.itemid = gi.id AND gi.courseid = {$this->courseid} {$this->userselect}";
         $grades = get_records_sql($sql);
     }
     $userids = array_keys($this->users);
     if ($grades) {
         foreach ($grades as $graderec) {
             if (in_array($graderec->userid, $userids) && array_key_exists($graderec->itemid, $this->gtree->items)) {
                 // some items may not be present!!
                 $grade = new grade_grade($graderec, false);
                 $grade->grade_item =& $this->gtree->items[$graderec->itemid];
                 if (($grade->is_hidden() && $this->canviewhidden && ($this->get_pref('visual', 'usehidden') || is_null($this->get_pref('visual', 'usehidden'))) || !$grade->is_hidden()) && ($grade->is_locked() && ($this->get_pref('visual', 'uselocked') || is_null($this->get_pref('visual', 'uselocked'))) || !$grade->is_locked())) {
                     $this->grades[$graderec->itemid][$graderec->userid] = $grade;
                 }
             }
         }
     }
     if ($this->get_pref('visual', 'incompleasmin')) {
         /// prefil grades that do not exist yet
         foreach ($userids as $userid) {
             foreach ($this->gtree->items as $itemid => $unused) {
                 if (!isset($this->grades[$itemid][$userid])) {
                     $grade = new grade_grade();
                     $grade->itemid = $itemid;
                     $grade->userid = $userid;
                     $grade->grade_item =& $this->gtree->items[$itemid];
                     // db caching
                     $grade->finalgrade = $this->gtree->items[$itemid]->grademin;
                     if (($grade->is_hidden() && $this->canviewhidden && ($this->get_pref('visual', 'usehidden') || is_null($this->get_pref('visual', 'usehidden'))) || !$grade->is_hidden()) && ($grade->is_locked() && ($this->get_pref('visual', 'uselocked') || is_null($this->get_pref('visual', 'uselocked'))) || !$grade->is_locked())) {
                         $this->grades[$itemid][$userid] = $grade;
                     }
                 }
             }
         }
     }
 }