$awards = 0;
// Raise timelimit as this could take a while for big web sites.
- set_time_limit(0);
+ core_php_time_limit::raise();
raise_memory_limit(MEMORY_HUGE);
- // For site level badges, get all active site users who can earn this badge and haven't got it yet.
- if ($this->type == BADGE_TYPE_SITE) {
- $sql = 'SELECT DISTINCT u.id, bi.badgeid
+ foreach ($this->criteria as $crit) {
+ // Overall criterion is decided when other criteria are reviewed.
+ if ($crit->criteriatype == BADGE_CRITERIA_TYPE_OVERALL) {
+ continue;
+ }
+
+ list($extrajoin, $extrawhere, $extraparams) = $crit->get_completed_criteria_sql();
+ // For site level badges, get all active site users who can earn this badge and haven't got it yet.
+ if ($this->type == BADGE_TYPE_SITE) {
+ $sql = "SELECT DISTINCT u.id, bi.badgeid
FROM {user} u
+ {$extrajoin}
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_fieldset_sql($sql, array('badgeid' => $this->id, 'guestid' => $CFG->siteguest));
- } else {
- // For course level badges, get users who can earn this badge in the course.
- // These are all enrolled users with capability moodle/badges:earnbadge.
- $earned = $DB->get_fieldset_select('badge_issued', 'userid AS id', 'badgeid = :badgeid', array('badgeid' => $this->id));
- $users = get_enrolled_users($this->get_context(), 'moodle/badges:earnbadge', 0, 'u.id');
- $toearn = array_diff(array_keys($users), $earned);
- }
+ WHERE bi.badgeid IS NULL AND u.id != :guestid AND u.deleted = 0 " . $extrawhere;
+ $params = array_merge(array('badgeid' => $this->id, 'guestid' => $CFG->siteguest), $extraparams);
+ $toearn = $DB->get_fieldset_sql($sql, $params);
+ } else {
+ // For course level badges, get all users who already earned the badge in this course.
+ // Then find the ones who are enrolled in the course and don't have a badge yet.
+ $earned = $DB->get_fieldset_select('badge_issued', 'userid AS id', 'badgeid = :badgeid', array('badgeid' => $this->id));
+ $wheresql = '';
+ $earnedparams = array();
+ if (!empty($earned)) {
+ list($earnedsql, $earnedparams) = $DB->get_in_or_equal($earned, SQL_PARAMS_NAMED, 'u', false);
+ $wheresql = ' WHERE u.id ' . $earnedsql;
+ }
+ list($enrolledsql, $enrolledparams) = get_enrolled_sql($this->get_context(), 'moodle/badges:earnbadge', 0, true);
+ $sql = "SELECT u.id
+ FROM {user} u
+ {$extrajoin}
+ JOIN ({$enrolledsql}) je ON je.id = u.id " . $wheresql . $extrawhere;
+ $params = array_merge($enrolledparams, $earnedparams, $extraparams);
+ $toearn = $DB->get_fieldset_sql($sql, $params);
+ }
- foreach ($toearn as $uid) {
- $toreview = false;
- foreach ($this->criteria as $crit) {
- if ($crit->criteriatype != BADGE_CRITERIA_TYPE_OVERALL) {
- if ($crit->review($uid)) {
- $crit->mark_complete($uid);
- if ($this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->method == BADGE_CRITERIA_AGGREGATION_ANY) {
- $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($uid);
- $this->issue($uid);
- $awards++;
- break;
- } else {
- $toreview = true;
- continue;
- }
+ foreach ($toearn as $uid) {
+ $reviewoverall = false;
+ if ($crit->review($uid, true)) {
+ $crit->mark_complete($uid);
+ if ($this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->method == BADGE_CRITERIA_AGGREGATION_ANY) {
+ $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($uid);
+ $this->issue($uid);
+ $awards++;
} else {
- if ($this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->method == BADGE_CRITERIA_AGGREGATION_ANY) {
- continue;
- } else {
- break;
- }
+ $reviewoverall = true;
}
+ } else {
+ // Will be reviewed some other time.
+ $reviewoverall = false;
+ }
+ // Review overall if it is required.
+ if ($reviewoverall && $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($uid)) {
+ $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($uid);
+ $this->issue($uid);
+ $awards++;
}
- }
- // Review overall if it is required.
- if ($toreview && $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($uid)) {
- $this->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($uid);
- $this->issue($uid);
- $awards++;
}
}