From 5ef3241ae395d692f4754392848752d19bca511a Mon Sep 17 00:00:00 2001 From: Marty Gilbert Date: Fri, 19 Jun 2020 14:57:31 -0400 Subject: [PATCH] MDL-69102 badge: Fixes broken WHERE clause When buildilng the 'WHERE' clause, the SQL generated a query that selected any user who was a member of the **last** group, not all of the groups. I believe the query has to be re-worked so that it only returns users who are in ALL of the groups. This can be done by a GROUP BY and HAVING. --- badges/criteria/award_criteria_cohort.php | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/badges/criteria/award_criteria_cohort.php b/badges/criteria/award_criteria_cohort.php index 1e0bb80ad53..81290eb07a8 100644 --- a/badges/criteria/award_criteria_cohort.php +++ b/badges/criteria/award_criteria_cohort.php @@ -240,13 +240,23 @@ class award_criteria_cohort extends award_criteria { return array($join, $where, $params); } else { // User is a member of ALL of the specified cohorts. - $join = " LEFT JOIN {cohort_members} cm ON cm.userid = u.id"; + $join = ' LEFT JOIN {cohort_members} cm ON cm.userid = u.id'; + $where = ' AND ('; $i = 0; foreach ($this->params as $param) { - $i++; - $where = ' AND cm.cohortid = :cohortid'.$i; + if ($i == 0) { + $where .= 'cm.cohortid = :cohortid'.$i; + } else { + $where .= ' OR cm.cohortid = :cohortid'.$i; + } $params['cohortid'.$i] = $param['cohort']; + $i++; } + $where .= ') + GROUP BY u.id, bi.badgeid + HAVING COUNT(cm.cohortid) = :cohortcount'; + $params['cohortcount'] = $i; + return array($join, $where, $params); } }