Skip to content

Commit

Permalink
MDL-55491 badges: Add cohort as badge criteria
Browse files Browse the repository at this point in the history
  • Loading branch information
sbourget authored and sarjona committed Apr 9, 2018
1 parent abc07b5 commit 75653a3
Show file tree
Hide file tree
Showing 6 changed files with 569 additions and 43 deletions.
40 changes: 12 additions & 28 deletions badges/classes/observer.php
Original file line number Diff line number Diff line change
Expand Up @@ -170,18 +170,17 @@ public static function profile_criteria_review(\core\event\user_updated $event)
}

/**
* Triggered when an event happens that updates cohort membership. Seeing as there
* are more than one event that can trigger this, we're accepting a generic event object
* as param.
* Triggered when the 'cohort_member_added' event happens.
*
* @param \core\event\base $event generated event
* @param \core\event\cohort_member_added $event generated when a user is added to a cohort
*/
public static function cohort_criteria_review(\core\event\base $event) {
public static function cohort_criteria_review(\core\event\cohort_member_added $event) {
global $DB, $CFG;

if (!empty($CFG->enablebadges)) {
require_once($CFG->dirroot.'/lib/badgeslib.php');
$cohortid = $event->objectid;
$userid = $event->relateduserid;

// Get relevant badges.
$badgesql = "SELECT badgeid
Expand All @@ -194,36 +193,21 @@ public static function cohort_criteria_review(\core\event\base $event) {
return;
}

// Get the users that should be issued badges.
$usersql = "SELECT userid
FROM {cohort_members} cm
WHERE cohortid = ?
AND userid NOT IN (
SELECT userid
FROM {badge_issued} bi
WHERE badgeid IN (
{$badgesql}
)
)";
$users = $DB->get_records_sql($usersql, array($cohortid, BADGE_CRITERIA_TYPE_COHORT, "cohort_{$cohortid}"));

foreach ($badges as $b) {
$badge = new badge($b->badgeid);
if (!$badge->is_active()) {
continue;
}
foreach ($users as $u) {
if ($badge->is_issued($u->userid)) {
continue;
}
if ($badge->is_issued($userid)) {
continue;
}

if ($badge->criteria[BADGE_CRITERIA_TYPE_COHORT]->review($u->userid)) {
$badge->criteria[BADGE_CRITERIA_TYPE_COHORT]->mark_complete($u->userid);
if ($badge->criteria[BADGE_CRITERIA_TYPE_COHORT]->review($userid)) {
$badge->criteria[BADGE_CRITERIA_TYPE_COHORT]->mark_complete($userid);

if ($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($u->userid)) {
$badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($u->userid);
$badge->issue($u->userid);
}
if ($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->review($userid)) {
$badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->mark_complete($userid);
$badge->issue($userid);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion badges/criteria/award_criteria.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@
* Cohort criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_COHORT', 98);
define('BADGE_CRITERIA_TYPE_COHORT', 8);

/*
* Criteria type constant to class name mapping
Expand Down
64 changes: 56 additions & 8 deletions badges/criteria/award_criteria_cohort.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,26 @@
/**
* Badge award criteria -- award on cohort membership
*
* @package core
* @subpackage badges
* @copyright 2016 onwards Catalyst IT {@link https://www.catalyst.net.nz/}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @author Eugene Venter <[email protected]>
*/
class award_criteria_cohort extends award_criteria {

/* @var int Criteria [BADGE_CRITERIA_TYPE_COHORT] */
/* @var int $criteriatype Criteria [BADGE_CRITERIA_TYPE_COHORT] */
public $criteriatype = BADGE_CRITERIA_TYPE_COHORT;

/* @var string $required_param Required form param */
public $required_param = 'cohort';

/* @var array $optional_params Optional form params */
public $optional_params = array();

/**
* Get criteria details for displaying to users
*
* @param string $short Print short version of criteria
* @return string
*/
public function get_details($short = '') {
Expand All @@ -69,6 +77,7 @@ public function get_details($short = '') {
/**
* Add appropriate new criteria options to the form
*
* @param object $mform moodle form
*/
public function get_options(&$mform) {
global $DB;
Expand All @@ -77,7 +86,7 @@ public function get_options(&$mform) {
$mform->addElement('header', 'first_header', $this->get_title());
$mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges');

// Get cohorts
// Get cohorts.
$cohorts = $DB->get_records_menu('cohort', array(), 'name ASC', 'id, name');
if (!empty($cohorts)) {
$select = array();
Expand Down Expand Up @@ -122,10 +131,11 @@ public function get_options(&$mform) {
/**
* Save criteria records
*
* @param $params criteria params
* @param array $params Values from the form or any other array.
*/
public function save($params = array()) {
$cohorts = $params['cohort_cohorts'];

unset($params['cohort_cohorts']);
foreach ($cohorts as $cohortid) {
$params["cohort_{$cohortid}"] = $cohortid;
Expand All @@ -137,7 +147,11 @@ public function save($params = array()) {
/**
* Review this criteria and decide if it has been completed
*
* @return bool Whether criteria is complete
* @param int $userid User whose criteria completion needs to be reviewed.
* @param bool $filtered An additional parameter indicating that user list
* has been reduced and some expensive checks can be skipped.
*
* @return bool Whether criteria is complete.
*/
public function review($userid, $filtered = false) {
global $DB;
Expand Down Expand Up @@ -197,9 +211,43 @@ public function validate() {
return array(true, '');
}

/**
* Returns array with sql code and parameters returning all ids
* of users who meet this particular criterion.
*
* @return array list($join, $where, $params)
*/
public function get_completed_criteria_sql() {
// TODO;

return array($join, $where, $params);
$join = '';
$where = '';
$params = array();

if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
// User is a member of ANY of the specified cohorts.
$join = " LEFT JOIN {cohort_members} cm ON cm.userid = u.id";
$where = "AND (";
$i = 0;
foreach ($this->params as $param) {
if ($i == 0) {
$where .= ' cm.cohortid = :cohortid'.$i;
} else {
$where .= ' OR cm.cohortid = :cohortid'.$i;
}
$params['cohortid'.$i] = $param['cohort'];
$i++;
}
$where .= ") ";
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";
$i = 0;
foreach ($this->params as $param) {
$i++;
$where = ' AND cm.cohortid = :cohortid'.$i;
$params['cohortid'.$i] = $param['cohort'];
}
return array($join, $where, $params);
}
}
}
32 changes: 32 additions & 0 deletions badges/tests/badgeslib_test.php
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,38 @@ public function test_badges_observer_profile_criteria_review() {
$this->assertTrue($badge->is_issued($this->user->id));
}

/**
* Test badges observer when cohort_member_added event is fired.
*/
public function test_badges_observer_cohort_criteria_review() {
global $CFG;

require_once("$CFG->dirroot/cohort/lib.php");

$cohort = $this->getDataGenerator()->create_cohort();

$this->preventResetByRollback(); // Messaging is not compatible with transactions.
$badge = new badge($this->badgeid);
$this->assertFalse($badge->is_issued($this->user->id));

// Set up the badge criteria.
$criteriaoverall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
$criteriaoverall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY));
$criteriaoverall1 = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_COHORT, 'badgeid' => $badge->id));
$criteriaoverall1->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ANY, 'cohort_cohorts' => array('0' => $cohort->id)));

// Make the badge active.
$badge->set_status(BADGE_STATUS_ACTIVE);

// Add the user to the cohort.
cohort_add_member($cohort->id, $this->user->id);

// Verify that the badge was awarded.
$this->assertDebuggingCalled();
$this->assertTrue($badge->is_issued($this->user->id));

}

/**
* Test badges assertion generated when a badge is issued.
*/
Expand Down
Loading

0 comments on commit 75653a3

Please sign in to comment.