/** * Reviews criteria and awards badges * * First find all badges that can be earned, then reviews each badge. * (Not sure how efficient this is timewise). */ function badge_review_cron() { global $DB, $CFG; $total = 0; $courseparams = array(); if (empty($CFG->badges_allowcoursebadges)) { $coursesql = ''; } else { $coursesql = ' OR EXISTS (SELECT id FROM {course} WHERE visible = :visible AND startdate < :current) '; $courseparams = array('visible' => true, 'current' => time()); } $sql = 'SELECT id FROM {badge} WHERE (status = :active OR status = :activelocked) AND (type = :site ' . $coursesql . ')'; $badgeparams = array('active' => BADGE_STATUS_ACTIVE, 'activelocked' => BADGE_STATUS_ACTIVE_LOCKED, 'site' => BADGE_TYPE_SITE); $params = array_merge($badgeparams, $courseparams); $badges = $DB->get_fieldset_sql($sql, $params); mtrace('Started reviewing available badges.'); foreach ($badges as $bid) { $badge = new badge($bid); if ($badge->has_criteria()) { if (debugging()) { mtrace('Processing badge "' . $badge->name . '"...'); } $issued = $badge->review_all_criteria(); if (debugging()) { mtrace('...badge was issued to ' . $issued . ' users.'); } $total += $issued; } } mtrace('Badges were issued ' . $total . ' time(s).'); }
$PAGE->url->param('activate', 1); $status = $badge->status == BADGE_STATUS_INACTIVE ? BADGE_STATUS_ACTIVE : BADGE_STATUS_ACTIVE_LOCKED; if ($confirm == 1) { require_sesskey(); $badge->set_status($status); $returnurl->param('msg', 'activatesuccess'); if ($badge->type == BADGE_TYPE_SITE) { // Review on cron if there are more than 1000 users who can earn a site-level badge. $sql = 'SELECT COUNT(u.id) as num FROM {user} u LEFT JOIN {badge_issued} bi ON u.id = bi.userid AND bi.badgeid = :badgeid WHERE bi.badgeid IS NULL AND u.id != :guestid AND u.deleted = 0'; $toearn = $DB->get_record_sql($sql, array('badgeid' => $badge->id, 'guestid' => $CFG->siteguest)); if ($toearn->num < 1000) { $awards = $badge->review_all_criteria(); $returnurl->param('awards', $awards); } else { $returnurl->param('awards', 'cron'); } } else { $awards = $badge->review_all_criteria(); $returnurl->param('awards', $awards); } redirect($returnurl); } $strheading = get_string('reviewbadge', 'badges'); $PAGE->navbar->add($strheading); $PAGE->set_title($strheading); $PAGE->set_heading($badge->name); echo $OUTPUT->header();
/** * Test badges observer when user_updated event is fired. */ public function test_badges_observer_profile_criteria_review() { global $CFG, $DB; require_once $CFG->dirroot . '/user/profile/lib.php'; // Add a custom field of textarea type. $customprofileid = $DB->insert_record('user_info_field', array('shortname' => 'newfield', 'name' => 'Description of new field', 'categoryid' => 1, 'datatype' => 'textarea')); $this->preventResetByRollback(); // Messaging is not compatible with transactions. $badge = new badge($this->coursebadge); $criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id)); $criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY)); $criteria_overall1 = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id)); $criteria_overall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address', 'field_aim' => 'aim', 'field_' . $customprofileid => $customprofileid)); // Assert the badge will not be issued to the user as is. $badge = new badge($this->coursebadge); $badge->review_all_criteria(); $this->assertFalse($badge->is_issued($this->user->id)); // Set the required fields and make sure the badge got issued. $this->user->address = 'Test address'; $this->user->aim = '999999999'; $sink = $this->redirectEmails(); profile_save_data((object) array('id' => $this->user->id, 'profile_field_newfield' => 'X')); user_update_user($this->user, false); $this->assertCount(1, $sink->get_messages()); $sink->close(); // Check if badge is awarded. $this->assertDebuggingCalled('Error baking badge image!'); $this->assertTrue($badge->is_issued($this->user->id)); }