Merge branch 'MDL-42965_master' of https://github.com/totara/openbadges
authorSam Hemelryk <sam@moodle.com>
Mon, 16 Dec 2013 00:47:57 +0000 (13:47 +1300)
committerSam Hemelryk <sam@moodle.com>
Mon, 16 Dec 2013 00:47:57 +0000 (13:47 +1300)
1  2 
lib/badgeslib.php

@@@ -426,54 -426,66 +426,66 @@@ class badge 
          $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++;
              }
          }