. /** * Classes to manage manual badge award. * * @package core * @subpackage badges * @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/} * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later * @author Yuliya Bozhko */ defined('MOODLE_INTERNAL') || die(); require_once($CFG->libdir . '/badgeslib.php'); require_once($CFG->dirroot . '/user/selector/lib.php'); abstract class badge_award_selector_base extends user_selector_base { /** * The id of the badge this selector is being used for * @var int */ protected $badgeid = null; /** * The context of the badge this selector is being used for * @var object */ protected $context = null; /** * The id of the role of badge issuer in current context * @var int */ protected $issuerrole = null; /** * The id of badge issuer * @var int */ protected $issuerid = null; /** * Constructor method * @param string $name * @param array $options */ public function __construct($name, array $options) { $options['accesscontext'] = $options['context']; parent::__construct($name, $options); if (isset($options['context'])) { if ($options['context'] instanceof context_system) { // If it is a site badge, we need to get context of frontpage. $this->context = context_course::instance(SITEID); } else { $this->context = $options['context']; } } if (isset($options['badgeid'])) { $this->badgeid = $options['badgeid']; } if (isset($options['issuerid'])) { $this->issuerid = $options['issuerid']; } if (isset($options['issuerrole'])) { $this->issuerrole = $options['issuerrole']; } } /** * Returns an array of options to seralise and store for searches * * @return array */ protected function get_options() { global $CFG; $options = parent::get_options(); $options['file'] = 'badges/lib/awardlib.php'; $options['context'] = $this->context; $options['badgeid'] = $this->badgeid; $options['issuerid'] = $this->issuerid; $options['issuerrole'] = $this->issuerrole; return $options; } } /** * A user selector control for potential users to award badge */ class badge_potential_users_selector extends badge_award_selector_base { const MAX_USERS_PER_PAGE = 100; /** * Existing recipients */ protected $existingrecipients = array(); /** * Finds all potential badge recipients * * Potential badge recipients are all enroled users * who haven't got a badge from current issuer role. * * @param string $search * @return array */ public function find_users($search) { global $DB; $whereconditions = array(); list($wherecondition, $params) = $this->search_sql($search, 'u'); if ($wherecondition) { $whereconditions[] = $wherecondition; } $existingids = array(); foreach ($this->existingrecipients as $group) { foreach ($group as $user) { $existingids[] = $user->id; } } if ($existingids) { list($usertest, $userparams) = $DB->get_in_or_equal($existingids, SQL_PARAMS_NAMED, 'ex', false); $whereconditions[] = 'u.id ' . $usertest; $params = array_merge($params, $userparams); } if ($whereconditions) { $wherecondition = ' WHERE ' . implode(' AND ', $whereconditions); } list($esql, $eparams) = get_enrolled_sql($this->context, 'moodle/badges:earnbadge', 0, true); $params = array_merge($params, $eparams); $fields = 'SELECT ' . $this->required_fields_sql('u'); $countfields = 'SELECT COUNT(u.id)'; $params['badgeid'] = $this->badgeid; $params['issuerrole'] = $this->issuerrole; $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"; list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); $order = ' ORDER BY ' . $sort; if (!$this->is_validating()) { $potentialmemberscount = $DB->count_records_sql($countfields . $sql, $params); if ($potentialmemberscount > self::MAX_USERS_PER_PAGE) { return $this->too_many_results($search, $potentialmemberscount); } } $availableusers = $DB->get_records_sql($fields . $sql . $order, array_merge($params, $sortparams)); if (empty($availableusers)) { return array(); } return array(get_string('potentialrecipients', 'badges') => $availableusers); } /** * Sets the existing recipients * @param array $users */ public function set_existing_recipients(array $users) { $this->existingrecipients = $users; } } /** * A user selector control for existing users to award badge */ class badge_existing_users_selector extends badge_award_selector_base { /** * Finds all users who already have been awarded a badge by current role * * @param string $search * @return array */ public function find_users($search) { global $DB; list($wherecondition, $params) = $this->search_sql($search, 'u'); $params['badgeid'] = $this->badgeid; $params['issuerrole'] = $this->issuerrole; list($esql, $eparams) = get_enrolled_sql($this->context, 'moodle/badges:earnbadge', 0, true); $fields = $this->required_fields_sql('u'); list($sort, $sortparams) = users_order_by_sql('u', $search, $this->accesscontext); $params = array_merge($params, $eparams, $sortparams); $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 WHERE $wherecondition AND s.badgeid = :badgeid AND s.issuerrole = :issuerrole ORDER BY $sort", $params); return array(get_string('existingrecipients', 'badges') => $recipients); } } function process_manual_award($recipientid, $issuerid, $issuerrole, $badgeid) { global $DB; $params = array( 'badgeid' => $badgeid, 'issuerid' => $issuerid, 'issuerrole' => $issuerrole, 'recipientid' => $recipientid ); if (!$DB->record_exists('badge_manual_award', $params)) { $award = new stdClass(); $award->badgeid = $badgeid; $award->issuerid = $issuerid; $award->issuerrole = $issuerrole; $award->recipientid = $recipientid; $award->datemet = time(); if ($DB->insert_record('badge_manual_award', $award)) { return true; } } return false; } /** * Manually revoke awarded badges. * * @param int $recipientid * @param int $issuerid * @param int $issuerrole * @param int $badgeid * @return bool */ function process_manual_revoke($recipientid, $issuerid, $issuerrole, $badgeid) { global $DB; $params = array( 'badgeid' => $badgeid, 'issuerid' => $issuerid, 'issuerrole' => $issuerrole, 'recipientid' => $recipientid ); if ($DB->record_exists('badge_manual_award', $params)) { if ($DB->delete_records('badge_manual_award', array('badgeid' => $badgeid, 'issuerid' => $issuerid, 'recipientid' => $recipientid)) && $DB->delete_records('badge_issued', array('badgeid' => $badgeid, 'userid' => $recipientid))) { // Trigger event, badge revoked. $badge = new \badge($badgeid); $eventparams = array( 'objectid' => $badgeid, 'relateduserid' => $recipientid, 'context' => $badge->get_context() ); $event = \core\event\badge_revoked::create($eventparams); $event->trigger(); return true; } } else { throw new moodle_exception('error:badgenotfound', 'badges'); } return false; }