public function cleanup() { // cleanup any clickers before the test $user_id = iclicker_service::require_user(); $results = iclicker_service::get_registrations_by_user($user_id); if ($results) { echo "cleanup registrations for user: {$user_id} " . PHP_EOL; foreach ($results as $reg) { if ($reg->clicker_id == $this->clicker_id) { iclicker_service::remove_registration($reg->id); echo "cleanup: {$reg->id} " . PHP_EOL; } } } // cleanup the test grades $def_grade_cats = grade_category::fetch_all(array('courseid' => $this->courseid, 'fullname' => iclicker_service::GRADE_CATEGORY_NAME)); $stuff_grade_cats = grade_category::fetch_all(array('courseid' => $this->courseid, 'fullname' => 'stuff')); $grade_cats = $def_grade_cats; if (is_array($def_grade_cats) && is_array($stuff_grade_cats)) { $grade_cats = array_merge($def_grade_cats, $stuff_grade_cats); } else { if (is_array($stuff_grade_cats)) { $grade_cats = $stuff_grade_cats; } } if ($grade_cats) { foreach ($grade_cats as $cat) { $grade_items = grade_item::fetch_all(array('courseid' => $this->courseid, 'categoryid' => $cat->id)); if ($grade_items) { foreach ($grade_items as $item) { $grades = grade_grade::fetch_all(array('itemid' => $item->id)); if ($grades) { foreach ($grades as $grade) { $grade->delete("cleanup"); } } $item->delete("cleanup"); } } $cat->delete("cleanup"); } } }
/** * Purge course data when user unenrolls from a course * * @param int $courseid The ID of the course the user has unenrolled from * @param int $userid The ID of the user unenrolling */ function grade_user_unenrol($courseid, $userid) { if ($items = grade_item::fetch_all(array('courseid' => $courseid))) { foreach ($items as $item) { if ($grades = grade_grade::fetch_all(array('userid' => $userid, 'itemid' => $item->id))) { foreach ($grades as $grade) { $grade->delete('userdelete'); } } } } }
/** * Set the hidden status of grade_item and all grades, 0 mean visible, 1 always hidden, number means date to hide until. * @param int $hidden new hidden status * @param boolean $cascade apply to child objects too * @return void */ function set_hidden($hidden, $cascade = false) { $this->hidden = $hidden; $this->update(); if ($cascade) { if ($grades = grade_grade::fetch_all(array('itemid' => $this->id))) { foreach ($grades as $grade) { $grade->grade_item =& $this; $grade->set_hidden($hidden, $cascade); } } } }
/** * Marks user deleted in internal user database and notifies the auth plugin. * Also unenrols user from all roles and does other cleanup. * @param object $user Userobject before delete (without system magic quotes) * @return boolean success */ function delete_user($user) { global $CFG; require_once $CFG->libdir . '/grouplib.php'; require_once $CFG->libdir . '/gradelib.php'; require_once $CFG->dirroot . '/message/lib.php'; begin_sql(); // delete all grades - backup is kept in grade_grades_history table if ($grades = grade_grade::fetch_all(array('userid' => $user->id))) { foreach ($grades as $grade) { $grade->delete('userdelete'); } } //move unread messages from this user to read message_move_userfrom_unread2read($user->id); // remove from all groups delete_records('groups_members', 'userid', $user->id); // unenrol from all roles in all contexts role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup! // now do a final accesslib cleanup - removes all role assingments in user context and context itself delete_context(CONTEXT_USER, $user->id); require_once $CFG->dirroot . '/tag/lib.php'; tag_set('user', $user->id, array()); // workaround for bulk deletes of users with the same email address $delname = addslashes("{$user->email}." . time()); while (record_exists('user', 'username', $delname)) { // no need to use mnethostid here $delname++; } // mark internal user record as "deleted" $updateuser = new object(); $updateuser->id = $user->id; $updateuser->deleted = 1; $updateuser->username = $delname; // Remember it just in case $updateuser->email = md5($user->username); // Store hash of username, useful importing/restoring users $updateuser->idnumber = ''; // Clear this field to free it up $updateuser->timemodified = time(); if (update_record('user', $updateuser)) { commit_sql(); // notify auth plugin - do not block the delete even when plugin fails $authplugin = get_auth_plugin($user->auth); $authplugin->user_delete($user); events_trigger('user_deleted', $user); return true; } else { rollback_sql(); return false; } }
function sub_test_grade_grade_fetch_all() { $grade_grade = new grade_grade(); $this->assertTrue(method_exists($grade_grade, 'fetch_all')); $grades = grade_grade::fetch_all(array()); $this->assertEqual(count($this->grade_grades), count($grades)); }
/** * Set the hidden status of grade_item and all grades, 0 mean visible, 1 always hidden, number means date to hide until. * @param int $hidden new hidden status * @param boolean $cascade apply to child objects too * @return void */ function set_hidden($hidden, $cascade = false) { $this->hidden = $hidden; $this->update(); if ($cascade) { if ($grades = grade_grade::fetch_all(array('itemid' => $this->id))) { foreach ($grades as $grade) { $grade->grade_item =& $this; $grade->set_hidden($hidden, $cascade); } } } //if marking item visible make sure category is visible MDL-21367 if (!$hidden) { $category_array = grade_category::fetch_all(array('id' => $this->categoryid)); if ($category_array && array_key_exists($this->categoryid, $category_array)) { $category = $category_array[$this->categoryid]; //call set_hidden on the category regardless of whether it is hidden as its parent might be hidden //if($category->is_hidden()) { $category->set_hidden($hidden, false); //} } } }
/** * Marks user deleted in internal user database and notifies the auth plugin. * Also unenrols user from all roles and does other cleanup. * @param object $user Userobject before delete (without system magic quotes) * @return boolean success */ function delete_user($user) { global $CFG; require_once $CFG->libdir . '/grouplib.php'; require_once $CFG->libdir . '/gradelib.php'; begin_sql(); // delete all grades - backup is kept in grade_grades_history table if ($grades = grade_grade::fetch_all(array('userid' => $user->id))) { foreach ($grades as $grade) { $grade->delete('userdelete'); } } // remove from all groups delete_records('groups_members', 'userid', $user->id); // unenrol from all roles in all contexts role_unassign(0, $user->id); // this might be slow but it is really needed - modules might do some extra cleanup! // now do a final accesslib cleanup - removes all role assingments in user context and context itself delete_context(CONTEXT_USER, $user->id); // mark internal user record as "deleted" $updateuser = new object(); $updateuser->id = $user->id; $updateuser->deleted = 1; $updateuser->username = addslashes("{$user->email}." . time()); // Remember it just in case $updateuser->email = ''; // Clear this field to free it up $updateuser->idnumber = ''; // Clear this field to free it up $updateuser->timemodified = time(); if (update_record('user', $updateuser)) { commit_sql(); // notify auth plugin - do not block the delete even when plugin fails $authplugin = get_auth_plugin($user->auth); $authplugin->user_delete($user); return true; } else { rollback_sql(); return false; } }
public function locked($lock) { global $COURSE, $USER; static $grades; if ($lock['type'] == 'grade' and isset($lock['id']) and isset($lock['grade'])) { if (!isset($grades)) { $grades = grade_grade::fetch_all(array('userid' => $USER->id)); } if (!empty($grades)) { $lockgrades = explode(':', $lock['grade']); foreach ($grades as $grade) { if ($grade->itemid == $lock['id']) { if (count($lockgrades) == 2) { if ($grade->finalgrade >= $lockgrades[0] and $grade->finalgrade <= $lockgrades[1]) { // Passed criteria for ranged lock - don't lock return false; } } else { if ($grade->finalgrade >= $lockgrades[0]) { // Passed criteria for lock - don't lock return false; } } } } } // Very important - may not have a grade record yet. // No grade record == locked return true; } // Lock is probably bad/outdated - don't lock return false; }
private static function save_grade_item($grade_item) { if (!$grade_item) { throw new InvalidArgumentException("grade_item must be set"); } if (!$grade_item->courseid) { throw new InvalidArgumentException("grade_item->courseid must be set"); } if (!$grade_item->categoryid) { throw new InvalidArgumentException("grade_item->categoryid must be set"); } if (!$grade_item->name) { throw new InvalidArgumentException("grade_item->name must be set"); } if (!isset($grade_item->item_number)) { $grade_item->item_number = 0; } // check for an existing item and update or create $grade_item_tosave = grade_item::fetch(array('courseid' => $grade_item->courseid, 'itemmodule' => self::GRADE_ITEM_MODULE, 'itemname' => $grade_item->name)); if (!$grade_item_tosave) { // create new one $grade_item_tosave = new grade_item(); $grade_item_tosave->itemmodule = self::GRADE_ITEM_MODULE; $grade_item_tosave->courseid = $grade_item->courseid; $grade_item_tosave->categoryid = $grade_item->categoryid; $grade_item_tosave->iteminfo = $grade_item->typename; //$grade_item_tosave->iteminfo = $grade_item->name.' '.$grade_item->type.' '.self::GRADE_CATEGORY_NAME; $grade_item_tosave->itemnumber = $grade_item->item_number; //$grade_item_tosave->idnumber = $grade_item->name; $grade_item_tosave->itemname = $grade_item->name; $grade_item_tosave->itemtype = self::GRADE_ITEM_TYPE; //$grade_item_tosave->itemmodule = self::GRADE_ITEM_MODULE; if (isset($grade_item->points_possible) && $grade_item->points_possible > 0) { $grade_item_tosave->grademax = $grade_item->points_possible; } $grade_item_tosave->insert(self::GRADE_LOCATION_STR); } else { // update if (isset($grade_item->points_possible) && $grade_item->points_possible > 0) { $grade_item_tosave->grademax = $grade_item->points_possible; } $grade_item_tosave->categoryid = $grade_item->categoryid; $grade_item_tosave->iteminfo = $grade_item->typename; $grade_item_tosave->update(self::GRADE_LOCATION_STR); } $grade_item_id = $grade_item_tosave->id; $grade_item_pp = $grade_item_tosave->grademax; // now save the related scores if (isset($grade_item->scores) && !empty($grade_item->scores)) { // get the existing scores $current_scores = array(); $existing_grades = grade_grade::fetch_all(array('itemid' => $grade_item_id)); if ($existing_grades) { foreach ($existing_grades as $grade) { $current_scores[$grade->userid] = $grade; } } // run through the scores in the gradeitem and try to save them $errors_count = 0; $processed_scores = array(); foreach ($grade_item->scores as $score) { $user = self::get_users($score->user_id); if (!$user) { $score->error = self::USER_DOES_NOT_EXIST_ERROR; $processed_scores[] = $score; $errors_count++; continue; } $user_id = $user->id; // null/blank scores are not allowed if (!isset($score->score)) { $score->error = 'NO_SCORE_ERROR'; $processed_scores[] = $score; $errors_count++; continue; } if (!is_numeric($score->score)) { $score->error = 'SCORE_INVALID'; $processed_scores[] = $score; $errors_count++; continue; } $score->score = floatval($score->score); // Student Score should not be greater than the total points possible if ($score->score > $grade_item_pp) { $score->error = self::POINTS_POSSIBLE_UPDATE_ERRORS; $processed_scores[] = $score; $errors_count++; continue; } try { $grade_tosave = null; if (isset($current_scores[$user_id])) { // existing score $grade_tosave = $current_scores[$user_id]; // check against existing score if ($score->score < $grade_tosave->rawgrade) { $score->error = self::SCORE_UPDATE_ERRORS; $processed_scores[] = $score; $errors_count++; continue; } $grade_tosave->finalgrade = $score->score; $grade_tosave->rawgrade = $score->score; $grade_tosave->timemodified = time(); /** @noinspection PhpUndefinedMethodInspection */ $grade_tosave->update(self::GRADE_LOCATION_STR); } else { // new score $grade_tosave = new grade_grade(); $grade_tosave->itemid = $grade_item_id; $grade_tosave->userid = $user_id; $grade_tosave->finalgrade = $score->score; $grade_tosave->rawgrade = $score->score; $grade_tosave->rawgrademax = $grade_item_pp; $now = time(); $grade_tosave->timecreated = $now; $grade_tosave->timemodified = $now; $grade_tosave->insert(self::GRADE_LOCATION_STR); } /** @noinspection PhpUndefinedFieldInspection */ $grade_tosave->user_id = $score->user_id; $processed_scores[] = $grade_tosave; } catch (Exception $e) { // General errors, caused while performing updates (Tag: generalerrors) $score->error = self::GENERAL_ERRORS; $processed_scores[] = $score; $errors_count++; } } /** @noinspection PhpUndefinedFieldInspection */ $grade_item_tosave->scores = $processed_scores; // put the errors in the item if ($errors_count > 0) { $errors = array(); foreach ($processed_scores as $score) { if (isset($score->error)) { $errors[$score->user_id] = $score->error; } } /** @noinspection PhpUndefinedFieldInspection */ $grade_item_tosave->errors = $errors; } $grade_item_tosave->force_regrading(); } return $grade_item_tosave; }
/** * Returns grade item info and grades. * * @param string $source * @param string $courseid * @param string $itemtype * @param string $itemmodule * @param string $iteminstance * @param string $itemnumber * @param string $grades * @param string $itemdetails * @return mixed * @throws invalid_parameter_exception * @throws moodle_exception */ public static function get_grade($source = 'mhaairs', $courseid = '', $itemtype = self::ITEM_DEFAULT_TYPE, $itemmodule = self::ITEM_DEFAULT_MODULE, $iteminstance = '0', $itemnumber = '0', $grades = null, $itemdetails = null) { global $USER; $result = array(); // Gradebook sync must be enabled by admin in the block's site configuration. if (!($syncgrades = get_config('core', 'block_mhaairs_sync_gradebook'))) { return $result; } // Parameters validation. $params = self::validate_parameters(self::update_grade_parameters(), array('source' => $source, 'courseid' => $courseid, 'itemtype' => $itemtype, 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'itemnumber' => $itemnumber, 'grades' => $grades, 'itemdetails' => $itemdetails)); // Extract the validated parameters to their respective variables. foreach ($params as $var => $value) { ${$var} = $value; } // Context validation. // OPTIONAL but in most web service it should be present. $context = context_user::instance($USER->id); self::validate_context($context); // Capability checking. // OPTIONAL but in most web service it should be present. require_capability('moodle/user:viewdetails', $context, null, true, 'cannotviewprofile'); // Validate item details. $itemdetails = json_decode(urldecode($itemdetails), true); $itemdetails = self::validate_item_details($itemdetails); // Get the item details identity type variable. $identitytype = self::get_details_itentity_type($itemdetails); // Validate grades. $grades = json_decode(urldecode($grades), true); $grades = self::validate_grades($grades); // HACK Make sure grades has identity type; take from item details if must. if ($grades and !isset($grades['identity_type'])) { $grades['identity_type'] = null; if ($identitytype) { $grades['identity_type'] = $identitytype; } } // Get the course. $course = self::get_course($courseid, $identitytype); if ($course === false) { // No valid course specified. return GRADE_UPDATE_FAILED; } $courseid = $course->id; // Get the grade item. $gitem = self::get_grade_item($source, $courseid, self::ITEM_DEFAULT_TYPE, self::ITEM_DEFAULT_MODULE, $iteminstance, $itemnumber); if (!$gitem) { return $result; } // Prepare result. $result = array('item' => array('courseid' => $courseid, 'categoryid' => $gitem->categoryid, 'itemname' => $gitem->itemname, 'itemtype' => $gitem->itemtype, 'idnumber' => $gitem->idnumber, 'gradetype' => $gitem->gradetype, 'grademax' => $gitem->grademax), 'grades' => array()); if ($grades) { if (!empty($grades['userid'])) { $gradegrades = grade_grade::fetch_users_grades($gitem, array($grades['userid']), false); } else { $gradegrades = grade_grade::fetch_all(array('itemid' => $gitem->id)); } if ($gradegrades) { foreach ($gradegrades as $grade) { $result['grades'][] = array('userid' => $grade->userid, 'grade' => $grade->finalgrade); } } } return $result; }
function test_gradebook() { global $DB; $this->resetAfterTest(true); // reset all changes automatically after this test $location_str = 'manual'; // try to get category $grade_category = grade_category::fetch(array('courseid' => $this->courseid, 'fullname' => $this->cat_name)); // NOTE: grade category will not be null but it will be empty $this->assertFalse($grade_category); // create a category $params = new stdClass(); $params->courseid = $this->courseid; $params->fullname = $this->cat_name; $grade_category = new grade_category($params, false); $this->assertTrue(method_exists($grade_category, 'insert')); $grade_category->insert($location_str); // now we will really get the category that we just made $grade_category_fetched = grade_category::fetch(array('courseid' => $this->courseid, 'fullname' => $this->cat_name)); $this->assertTrue($grade_category_fetched !== false); $this->assertEquals($grade_category->id, $grade_category_fetched->id); $this->assertEquals($grade_category->courseid, $grade_category_fetched->courseid); $this->assertEquals($grade_category->path, $grade_category_fetched->path); $this->assertEquals($grade_category->fullname, $grade_category_fetched->fullname); $this->assertEquals($grade_category->parent, $grade_category_fetched->parent); // try to get grade item $grade_item = grade_item::fetch(array('courseid' => $this->courseid, 'categoryid' => $grade_category->id, 'itemname' => $this->item_name)); // NOTE: grade category will not be null but it will be empty $this->assertFalse($grade_item); // create a grade item $grade_item = new grade_item(); $this->assertTrue(method_exists($grade_item, 'insert')); $grade_item->courseid = $this->courseid; $grade_item->categoryid = $grade_category->id; $grade_item->idnumber = $this->item_name; // lookup $grade_item->itemname = $this->item_name; // display $grade_item->itemtype = 'blocks'; $grade_item->itemmodule = 'iclicker'; $grade_item->iteminfo = 'blocks/iclicker for unit testing'; // grademax=100, grademin=0 $grade_item->grademax = 100.0; $grade_item->insert($location_str); // now we will really get the new item $grade_item_fetched = grade_item::fetch(array('courseid' => $this->courseid, 'categoryid' => $grade_category->id, 'itemname' => $this->item_name)); $this->assertTrue($grade_item_fetched !== false); $this->assertEquals($grade_item->id, $grade_item_fetched->id); $this->assertEquals($grade_item->courseid, $grade_item_fetched->courseid); $this->assertEquals($grade_item->categoryid, $grade_item_fetched->categoryid); $this->assertEquals($grade_item->itemname, $grade_item_fetched->itemname); // get empty grades list $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id)); $this->assertFalse($all_grades); // add grade $grade_grade = new grade_grade(); $this->assertTrue(method_exists($grade_grade, 'insert')); $grade_grade->itemid = $grade_item->id; $grade_grade->userid = $this->studentid1; $grade_grade->rawgrade = $this->grade_score; $grade_grade->insert($location_str); // get new grade $grade_grade_fetched = grade_grade::fetch(array('itemid' => $grade_item->id, 'userid' => $this->studentid1)); $this->assertTrue($grade_grade_fetched !== false); $this->assertEquals($grade_grade->id, $grade_grade_fetched->id); $this->assertEquals($grade_grade->itemid, $grade_grade_fetched->itemid); $this->assertEquals($grade_grade->userid, $grade_grade_fetched->userid); $this->assertEquals($grade_grade->rawgrade, $grade_grade_fetched->rawgrade); // update the grade $grade_grade->rawgrade = 50; $result = $grade_grade->update($location_str); $this->assertTrue($result); $grade_grade_fetched = grade_grade::fetch(array('id' => $grade_grade->id)); $this->assertTrue($grade_grade_fetched !== false); $this->assertEquals($grade_grade->id, $grade_grade_fetched->id); $this->assertEquals($grade_grade->rawgrade, $grade_grade_fetched->rawgrade); $this->assertEquals(50, $grade_grade_fetched->rawgrade); // get grades $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id)); $this->assertTrue($all_grades !== false); $this->assertEquals(1, sizeof($all_grades)); // add more grades $grade_grade2 = new grade_grade(); $grade_grade2->itemid = $grade_item->id; $grade_grade2->userid = $this->studentid2; $grade_grade2->rawgrade = $this->grade_score; $grade_grade2->insert($location_str); // get grades $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id)); $this->assertTrue($all_grades !== false); $this->assertEquals(2, sizeof($all_grades)); // make sure this can run $result = $grade_item->regrade_final_grades(); $this->assertTrue($result); // remove grades $this->assertTrue(method_exists($grade_grade, 'delete')); $result = $grade_grade->delete($location_str); $this->assertTrue($result); $result = $grade_grade2->delete($location_str); $this->assertTrue($result); // check no grades left $all_grades = grade_grade::fetch_all(array('itemid' => $grade_item->id)); $this->assertFalse($all_grades); // remove grade item $this->assertTrue(method_exists($grade_item, 'delete')); $result = $grade_item->delete($location_str); $this->assertTrue($result); // remove grade category $this->assertTrue(method_exists($grade_category, 'delete')); $result = $grade_category->delete($location_str); $this->assertTrue($result); $this->resetAfterTest(); }