From b1e63fc7e2eaacd5b8c30c0e6f2f11932b86e94a Mon Sep 17 00:00:00 2001 From: Silvia Pinheiro Date: Wed, 16 Jan 2019 15:20:47 +0000 Subject: [PATCH] MDL-62836 badges: Potential badge recipients by group This affects the case when a badge is setup with the criteria "manual issue by role". The non-editing teacher can see all participants of the course, when awarding a badge, even with SEPARATE GROUPS mode enabled. With this change, when the non-editing teacher chooses a group, and searches for a user, the results are filtered for that group. The same happens for "Existing badge recipients by group" when revoking a badge. --- badges/award.php | 22 +++++++++++++++-- badges/lib/awardlib.php | 54 ++++++++++++++++++++++++++++++++++++++--- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/badges/award.php b/badges/award.php index 18242b98b54c0..8f8669829f0e1 100644 --- a/badges/award.php +++ b/badges/award.php @@ -90,6 +90,19 @@ die(); } +// Get groupmode and currentgroup before going further. +$groupmode = groups_get_course_groupmode($COURSE); // Groups are being used. +$currentgroup = groups_get_course_group($COURSE, true); // Get active group. + +// Check groupmode (SEPARATEGROUPS), currentgroup and capability (or admin). +if ($groupmode == SEPARATEGROUPS && empty($currentgroup) && + !has_capability('moodle/site:accessallgroups', $context) && !is_siteadmin() ) { + echo $OUTPUT->header(); + echo $OUTPUT->heading(get_string("notingroup")); + echo $OUTPUT->footer(); + die(); +} + if (count($acceptedroles) > 1) { // If there is more than one role that can award a badge, prompt user to make a selection. // If it is an admin, include all accepted roles, otherwise only the ones that current user has in this context. @@ -151,8 +164,10 @@ 'badgeid' => $badge->id, 'context' => $context, 'issuerid' => $USER->id, - 'issuerrole' => $issuerrole->roleid - ); + 'issuerrole' => $issuerrole->roleid, + 'currentgroup' => $currentgroup, + 'url' => $url, + ); $existingselector = new badge_existing_users_selector('existingrecipients', $options); $recipientselector = new badge_potential_users_selector('potentialrecipients', $options); $recipientselector->set_existing_recipients($existingselector->find_users('')); @@ -193,6 +208,9 @@ echo $OUTPUT->header(); echo $OUTPUT->heading($strrecipients); +// Print group selector/dropdown menu (find out current groups mode). +groups_print_course_menu($COURSE, $url); + if (count($acceptedroles) > 1) { echo $OUTPUT->box($roleselect); } diff --git a/badges/lib/awardlib.php b/badges/lib/awardlib.php index 4425540cf4906..f085c56cd01e4 100644 --- a/badges/lib/awardlib.php +++ b/badges/lib/awardlib.php @@ -52,6 +52,18 @@ abstract class badge_award_selector_base extends user_selector_base { */ protected $issuerid = null; + /** + * The return address. Accepts either a string or a moodle_url. + * @var string $url + */ + public $url; + + /** + * The current group being displayed. + * @var int $currentgroup + */ + public $currentgroup; + /** * Constructor method * @param string $name @@ -77,6 +89,15 @@ public function __construct($name, array $options) { if (isset($options['issuerrole'])) { $this->issuerrole = $options['issuerrole']; } + if (isset($options['url'])) { + $this->url = $options['url']; + } + if (isset($options['currentgroup'])) { + $this->currentgroup = $options['currentgroup']; + } else { + // Returns group active in course, changes the group by default if 'group' page param present. + $this->currentgroup = groups_get_course_group($COURSE, true); + } } /** @@ -92,8 +113,27 @@ protected function get_options() { $options['badgeid'] = $this->badgeid; $options['issuerid'] = $this->issuerid; $options['issuerrole'] = $this->issuerrole; + // These will be used to filter potential badge recipients when searching. + $options['currentgroup'] = $this->currentgroup; return $options; } + + /** + * Restricts the selection of users to display, according to the groups they belong. + * + * @return array + */ + protected function get_groups_sql() { + $groupsql = ''; + $groupwheresql = ''; + $groupwheresqlparams = array(); + if ($this->currentgroup) { + $groupsql = ' JOIN {groups_members} gm ON gm.userid = u.id '; + $groupwheresql = ' AND gm.groupid = :gr_grpid '; + $groupwheresqlparams = array('gr_grpid' => $this->currentgroup); + } + return array($groupsql, $groupwheresql, $groupwheresqlparams); + } } /** @@ -141,8 +181,10 @@ public function find_users($search) { $wherecondition = ' WHERE ' . implode(' AND ', $whereconditions); } + list($groupsql, $groupwheresql, $groupwheresqlparams) = $this->get_groups_sql(); + list($esql, $eparams) = get_enrolled_sql($this->context, 'moodle/badges:earnbadge', 0, true); - $params = array_merge($params, $eparams); + $params = array_merge($params, $eparams, $groupwheresqlparams); $fields = 'SELECT ' . $this->required_fields_sql('u'); $countfields = 'SELECT COUNT(u.id)'; @@ -153,7 +195,9 @@ public function find_users($search) { $sql = " FROM {user} u JOIN ($esql) je ON je.id = u.id LEFT JOIN {badge_manual_award} bm ON (bm.recipientid = u.id AND bm.badgeid = :badgeid AND bm.issuerrole = :issuerrole) - $wherecondition AND bm.id IS NULL"; + $groupsql + $wherecondition AND bm.id IS NULL + $groupwheresql"; list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); $order = ' ORDER BY ' . $sort; @@ -204,12 +248,16 @@ public function find_users($search) { $fields = $this->required_fields_sql('u'); list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); - $params = array_merge($params, $eparams, $sortparams); + list($groupsql, $groupwheresql, $groupwheresqlparams) = $this->get_groups_sql(); + + $params = array_merge($params, $eparams, $sortparams, $groupwheresqlparams); $recipients = $DB->get_records_sql("SELECT $fields FROM {user} u JOIN ($esql) je ON je.id = u.id JOIN {badge_manual_award} s ON s.recipientid = u.id + $groupsql WHERE $wherecondition AND s.badgeid = :badgeid AND s.issuerrole = :issuerrole + $groupwheresql ORDER BY $sort", $params); return array(get_string('existingrecipients', 'badges') => $recipients);