MDL-35073 badges: Open badges integration

The badges feature allows to integrate Mozilla "Open Badges" to issue, assign,
manage and display digital badges in Moodle. This feature supports:
-- badge creation and issuing based on criteria
-- badge baking and verification service
-- direct pushing of internal badges to external backpack
-- interanl and external badge display in Moodle
-- Moodle block to display latest badges
This commit is contained in:
Yuliya Bozhko
2013-04-02 15:49:02 +08:00
committed by Damyon Wiese
parent ec6089f07b
commit 278065528a
75 changed files with 8760 additions and 3 deletions
+23
View File
@@ -243,6 +243,8 @@ class site_registration_form extends moodleform {
$postsnumber = get_config('hub', 'site_postsnumber_' . $cleanhuburl);
$questionsnumber = get_config('hub', 'site_questionsnumber_' . $cleanhuburl);
$resourcesnumber = get_config('hub', 'site_resourcesnumber_' . $cleanhuburl);
$badges = get_config('hub', 'site_badges_' . $cleanhuburl);
$issuedbadges = get_config('hub', 'site_issuedbadges_' . $cleanhuburl);
$mediancoursesize = get_config('hub', 'site_mediancoursesize_' . $cleanhuburl);
//hidden parameters
@@ -372,6 +374,9 @@ class site_registration_form extends moodleform {
require_once($CFG->dirroot . "/course/lib.php");
$participantnumberaverage = number_format(average_number_of_participants(), 2);
$modulenumberaverage = number_format(average_number_of_courses_modules(), 2);
require_once($CFG->libdir . '/badgeslib.php');
$badges = $DB->count_records_select('badge', 'status <> ' . BADGE_STATUS_ARCHIVED);
$issuedbadges = $DB->count_records('badge_issued');
if (HUB_MOODLEORGHUBURL != $huburl) {
$mform->addElement('checkbox', 'courses', get_string('sendfollowinginfo', 'hub'),
@@ -399,6 +404,14 @@ class site_registration_form extends moodleform {
" " . get_string('resourcesnumber', 'hub', $resourcecount));
$mform->setDefault('resources', true);
$mform->addElement('checkbox', 'badges', '',
" " . get_string('badgesnumber', 'hub', $badges));
$mform->setDefault('badges', true);
$mform->addElement('checkbox', 'issuedbadges', '',
" " . get_string('issuedbadgesnumber', 'hub', $issuedbadges));
$mform->setDefault('issuedbadges', true);
$mform->addElement('checkbox', 'participantnumberaverage', '',
" " . get_string('participantnumberaverage', 'hub', $participantnumberaverage));
$mform->setDefault('participantnumberaverage', true);
@@ -438,6 +451,16 @@ class site_registration_form extends moodleform {
$mform->addElement('hidden', 'resources', true);
$mform->setType('resources', PARAM_FLOAT);
$mform->addElement('static', 'badgeslabel', '',
" " . get_string('badgesnumber', 'hub', $badges));
$mform->addElement('hidden', 'badges', true);
$mform->setType('badges', PARAM_INT);
$mform->addElement('static', 'issuedbadgeslabel', '',
" " . get_string('issuedbadgesnumber', 'hub', $issuedbadges));
$mform->addElement('hidden', 'issuedbadges', true);
$mform->setType('issuedbadges', PARAM_INT);
$mform->addElement('static', 'participantnumberaveragelabel', '',
" " . get_string('participantnumberaverage', 'hub', $participantnumberaverage));
$mform->addElement('hidden', 'participantnumberaverage', true);
+14
View File
@@ -247,6 +247,20 @@ class registration_manager {
$resourcecount = $DB->count_records('resource');
}
$siteinfo['resources'] = $resourcecount;
// Badge statistics.
require_once($CFG->libdir . '/badgeslib.php');
if (get_config('hub', 'site_badges_' . $cleanhuburl) == -1) {
$badges = -1;
} else {
$badges = $DB->count_records_select('badge', 'status <> ' . BADGE_STATUS_ARCHIVED);
}
$siteinfo['badges'] = $badges;
if (get_config('hub', 'site_issuedbadges_' . $cleanhuburl) == -1) {
$issuedbadges = -1;
} else {
$issuedbadges = $DB->count_records('badge_issued');
}
$siteinfo['issuedbadges'] = $issuedbadges;
//TODO
require_once($CFG->dirroot . "/course/lib.php");
if (get_config('hub', 'site_participantnumberaverage_' . $cleanhuburl) == -1) {
+2
View File
@@ -84,6 +84,8 @@ if (!empty($fromform) and confirm_sesskey()) {
set_config('site_postsnumber_' . $cleanhuburl, $fromform->posts, 'hub');
set_config('site_questionsnumber_' . $cleanhuburl, $fromform->questions, 'hub');
set_config('site_resourcesnumber_' . $cleanhuburl, $fromform->resources, 'hub');
set_config('site_badges_' . $cleanhuburl, $fromform->badges, 'hub');
set_config('site_issuedbadges_' . $cleanhuburl, $fromform->issuedbadges, 'hub');
set_config('site_modulenumberaverage_' . $cleanhuburl, $fromform->modulenumberaverage, 'hub');
set_config('site_participantnumberaverage_' . $cleanhuburl, $fromform->participantnumberaverage, 'hub');
}
+83
View File
@@ -0,0 +1,83 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file defines settingpages and externalpages under the "badges" section
*
* @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 <[email protected]>
*/
global $SITE;
require_once($CFG->libdir . '/badgeslib.php');
if (!empty($CFG->enablebadges) && ($hassiteconfig || has_any_capability(array(
'moodle/badges:viewawarded',
'moodle/badges:createbadge',
'moodle/badges:manageglobalsettings',
'moodle/badges:awardbadge',
'moodle/badges:configuremessages',
'moodle/badges:configuredetails',
'moodle/badges:deletebadge'), $systemcontext))) {
$globalsettings = new admin_settingpage('badgesettings', new lang_string('badgesettings', 'badges'),
array('moodle/badges:manageglobalsettings'));
$globalsettings->add(new admin_setting_configtext('badges_defaultissuername',
new lang_string('defaultissuername', 'badges'),
new lang_string('defaultissuername_desc', 'badges'),
$SITE->fullname ? $SITE->fullname : $SITE->shortname, PARAM_TEXT));
$globalsettings->add(new admin_setting_configtext('badges_defaultissuercontact',
new lang_string('defaultissuercontact', 'badges'),
new lang_string('defaultissuercontact_desc', 'badges'),
get_config('moodle','supportemail'), PARAM_EMAIL));
$globalsettings->add(new admin_setting_configtext('badges_badgesalt',
new lang_string('badgesalt', 'badges'),
new lang_string('badgesalt_desc', 'badges'),
'badges' . $SITE->timecreated, PARAM_ALPHANUM));
$globalsettings->add(new admin_setting_configcheckbox('badges_allowexternalbackpack',
new lang_string('allowexternalbackpack', 'badges'),
new lang_string('allowexternalbackpack_desc', 'badges'), 1));
$globalsettings->add(new admin_setting_configcheckbox('badges_allowcoursebadges',
new lang_string('allowcoursebadges', 'badges'),
new lang_string('allowcoursebadges_desc', 'badges'), 1));
$ADMIN->add('badges', $globalsettings);
$ADMIN->add('badges',
new admin_externalpage('managebadges',
new lang_string('managebadges', 'badges'),
new moodle_url($CFG->wwwroot . '/badges/index.php', array('type' => BADGE_TYPE_SITE)),
array('moodle/badges:viewawarded')
)
);
$ADMIN->add('badges',
new admin_externalpage('newbadge',
new lang_string('newbadge', 'badges'),
new moodle_url($CFG->wwwroot . '/badges/newbadge.php', array('type' => BADGE_TYPE_SITE)),
array('moodle/badges:createbadge')
)
);
}
+2
View File
@@ -41,4 +41,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page
$checkbox->set_affects_modinfo(true);
$optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
$optionalsubsystems->add(new admin_setting_configcheckbox('enablebadges', new lang_string('enablebadges', 'badges'), new lang_string('configenablebadges', 'badges'), 1));
}
+1
View File
@@ -30,6 +30,7 @@ if ($hassiteconfig) {
$ADMIN->add('root', new admin_category('users', new lang_string('users','admin')));
$ADMIN->add('root', new admin_category('courses', new lang_string('courses','admin')));
$ADMIN->add('root', new admin_category('grades', new lang_string('grades')));
$ADMIN->add('root', new admin_category('badges', new lang_string('badges'), (isset($CFG->enablebadges) && $CFG->enablebadges == 0)));
$ADMIN->add('root', new admin_category('location', new lang_string('location','admin')));
$ADMIN->add('root', new admin_category('language', new lang_string('language')));
$ADMIN->add('root', new admin_category('modules', new lang_string('plugins', 'admin')));
+159
View File
@@ -0,0 +1,159 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Page to handle actions associated with badges management.
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = required_param('id', PARAM_INT);
$copy = optional_param('copy', 0, PARAM_BOOL);
$delete = optional_param('delete', 0, PARAM_BOOL);
$activate = optional_param('activate', 0, PARAM_BOOL);
$deactivate = optional_param('lock', 0, PARAM_BOOL);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
$return = optional_param('return', 0, PARAM_LOCALURL);
require_login();
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$PAGE->set_context($context);
$PAGE->set_url('/badges/action.php', array('id' => $badge->id));
$PAGE->set_pagelayout('standard');
navigation_node::override_active_url($navurl);
if ($return !== 0) {
$returnurl = new moodle_url($return);
} else {
$returnurl = new moodle_url('/badges/overview.php', array('id' => $badge->id));
}
$returnurl->remove_params('awards');
if ($delete) {
require_capability('moodle/badges:deletebadge', $context);
$PAGE->url->param('delete', 1);
if ($confirm) {
require_sesskey();
$badge->delete();
redirect(new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid)));
}
$strheading = get_string('delbadge', 'badges');
$PAGE->navbar->add($strheading);
$PAGE->set_title($strheading);
$PAGE->set_heading($badge->name);
echo $OUTPUT->header();
echo $OUTPUT->heading($strheading);
$urlparams = array(
'id' => $badge->id,
'delete' => 1,
'confirm' => 1,
'sesskey' => sesskey()
);
$continue = new moodle_url('/badges/action.php', $urlparams);
$cancel = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
$message = get_string('delconfirm', 'badges', $badge->name);
echo $OUTPUT->confirm($message, $continue, $cancel);
echo $OUTPUT->footer();
die;
}
if ($copy) {
require_capability('moodle/badges:createbadge', $context);
$cloneid = $badge->make_clone();
redirect(new moodle_url('/badges/edit.php', array('id' => $cloneid, 'action' => 'details')));
}
if ($activate) {
require_capability('moodle/badges:configurecriteria', $context);
$PAGE->url->param('activate', 1);
$status = ($badge->status == BADGE_STATUS_INACTIVE) ? BADGE_STATUS_ACTIVE : BADGE_STATUS_ACTIVE_LOCKED;
if ($confirm == 1) {
require_sesskey();
$badge->set_status($status);
if ($badge->type == BADGE_TYPE_SITE) {
// Review on cron if there are more than 1000 users who can earn a site-level badge.
$sql = 'SELECT COUNT(u.id) as num
FROM {user} u
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_record_sql($sql, array('badgeid' => $badge->id, 'guestid' => $CFG->siteguest));
if ($toearn->num < 1000) {
$awards = $badge->review_all_criteria();
$returnurl->param('awards', $awards);
} else {
$returnurl->param('awards', 'cron');
}
} else {
$awards = $badge->review_all_criteria();
$returnurl->param('awards', $awards);
}
redirect($returnurl);
}
$strheading = get_string('reviewbadge', 'badges');
$PAGE->navbar->add($strheading);
$PAGE->set_title($strheading);
$PAGE->set_heading($badge->name);
echo $OUTPUT->header();
echo $OUTPUT->heading($strheading);
$params = array('id' => $badge->id, 'activate' => 1, 'sesskey' => sesskey(), 'confirm' => 1, 'return' => $return);
$url = new moodle_url('/badges/action.php', $params);
if (!$badge->has_criteria()) {
echo $OUTPUT->notification(get_string('error:cannotact', 'badges') . get_string('nocriteria', 'badges'));
echo $OUTPUT->continue_button($returnurl);
} else {
$message = get_string('reviewconfirm', 'badges', $badge->name);
echo $OUTPUT->confirm($message, $url, $returnurl);
}
echo $OUTPUT->footer();
die;
}
if ($deactivate) {
require_sesskey();
require_capability('moodle/badges:configurecriteria', $context);
$status = ($badge->status == BADGE_STATUS_ACTIVE) ? BADGE_STATUS_INACTIVE : BADGE_STATUS_INACTIVE_LOCKED;
$badge->set_status($status);
redirect($returnurl);
}
+43
View File
@@ -0,0 +1,43 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Sends request to check web site availability.
*
* @package core
* @subpackage badges
* @copyright 2013 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 <[email protected]>
*/
define('AJAX_SCRIPT', true);
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_login();
$PAGE->set_url('/badges/ajax.php');
$PAGE->set_context(context_system::instance());
$result = badges_check_backpack_accessibility();
$outcome = new stdClass();
$outcome->code = $result;
$outcome->response = get_string('error:backpacknotavailable', 'badges') . $OUTPUT->help_icon('backpackavailability', 'badges');
echo json_encode($outcome);
die();
+40
View File
@@ -0,0 +1,40 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Serve assertion JSON by unique hash of issued badge
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$hash = required_param('b', PARAM_ALPHANUM);
$badge = badges_get_issued_badge_info($hash);
header('Content-type: application/json; charset=utf-8');
echo json_encode($badge);
+143
View File
@@ -0,0 +1,143 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Handle 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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->dirroot . '/badges/lib/awardlib.php');
$badgeid = required_param('id', PARAM_INT);
$role = optional_param('role', 0, PARAM_INT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$badge = new badge($badgeid);
$context = $badge->get_context();
$isadmin = is_siteadmin($USER);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
require_capability('moodle/badges:awardbadge', $context);
$url = new moodle_url('/badges/award.php', array('id' => $badgeid));
$PAGE->set_url($url);
$PAGE->set_context($context);
// Set up navigation and breadcrumbs.
$strrecipients = get_string('recipients', 'badges');
navigation_node::override_active_url($navurl);
$PAGE->navbar->add($badge->name, new moodle_url('overview.php', array('id' => $badge->id)))->add($strrecipients);
$PAGE->set_title($strrecipients);
$PAGE->set_heading($badge->name);
$PAGE->set_pagelayout('standard');
if (!$badge->is_active()) {
echo $OUTPUT->header();
echo $OUTPUT->notification(get_string('donotaward', 'badges'));
echo $OUTPUT->footer();
die();
}
$output = $PAGE->get_renderer('core', 'badges');
// Roles that can award this badge.
$accepted_roles = array_keys($badge->criteria[BADGE_CRITERIA_TYPE_MANUAL]->params);
// If site admin, select a role to award a badge.
if ($isadmin) {
list($usertest, $userparams) = $DB->get_in_or_equal($accepted_roles, SQL_PARAMS_NAMED, 'existing', true);
$options = $DB->get_records_sql('SELECT * FROM {role} WHERE id ' . $usertest, $userparams);
foreach ($options as $p) {
$select[$p->id] = role_get_name($p);
}
if (!$role) {
echo $OUTPUT->header();
echo $OUTPUT->box(get_string('adminaward', 'badges') . $OUTPUT->single_select(new moodle_url($PAGE->url), 'role', $select));
echo $OUTPUT->footer();
die();
} else {
$issuerrole = new stdClass();
$issuerrole->roleid = $role;
$roleselect = get_string('adminaward', 'badges') . $OUTPUT->single_select(new moodle_url($PAGE->url), 'role', $select, $role);
}
} else {
// Current user's role.
$issuerrole = array_shift(get_user_roles($context, $USER->id));
if (!isset($issuerrole->roleid) || !in_array($issuerrole->roleid, $accepted_roles)) {
echo $OUTPUT->header();
$rlink = html_writer::link(new moodle_url('recipients.php', array('id' => $badge->id)), get_string('recipients', 'badges'));
echo $OUTPUT->notification(get_string('notacceptedrole', 'badges', $rlink));
echo $OUTPUT->footer();
die();
}
}
$options = array(
'badgeid' => $badge->id,
'context' => $context,
'issuerid' => $USER->id,
'issuerrole' => $issuerrole->roleid
);
$existingselector = new badge_existing_users_selector('existingrecipients', $options);
$recipientselector = new badge_potential_users_selector('potentialrecipients', $options);
$recipientselector->set_existing_recipients($existingselector->find_users(''));
if (optional_param('award', false, PARAM_BOOL) && data_submitted() && has_capability('moodle/badges:awardbadge', $context)) {
require_sesskey();
$users = $recipientselector->get_selected_users();
foreach ($users as $user) {
if (process_manual_award($user->id, $USER->id, $issuerrole->roleid, $badgeid)) {
// If badge was successfully awarded, review manual badge criteria.
$data = new stdClass();
$data->crit = $badge->criteria[BADGE_CRITERIA_TYPE_MANUAL];
$data->userid = $user->id;
badges_award_handle_manual_criteria_review($data);
} else {
echo $OUTPUT->error_text(get_string('error:cannotawardbadge', 'badges'));
}
}
$recipientselector->invalidate_selected_users();
$existingselector->invalidate_selected_users();
$recipientselector->set_existing_recipients($existingselector->find_users(''));
}
echo $OUTPUT->header();
echo $OUTPUT->heading($strrecipients);
if ($isadmin) {
echo $OUTPUT->box($roleselect);
}
echo $output->recipients_selection_form($existingselector, $recipientselector);
echo $OUTPUT->footer();
+29
View File
@@ -0,0 +1,29 @@
/**
* Push badges to backpack.
*/
function addtobackpack(event, args) {
OpenBadges.issue([args.assertion], function(errors, successes) { });
}
/**
* Check if website is externally accessible from the backpack.
*/
function check_site_access() {
var add = Y.one('#check_connection');
var callback = {
success: function(o) {
var data = Y.JSON.parse(o.responseText);
if (data.code == 'http-unreachable') {
add.setHTML(data.response);
add.removeClass('hide');
}
},
failure: function(o) { }
};
YUI().use('yui2-connection', function (Y) {
Y.YUI2.util.Connect.asyncRequest('GET', 'ajax.php', callback, null);
});
return false;
}
+109
View File
@@ -0,0 +1,109 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form class for mybackpack.php
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->libdir . '/badgeslib.php');
/**
* Form to edit backpack initial details.
*
*/
class edit_backpack_form extends moodleform {
/**
* Defines the form
*/
public function definition() {
global $USER;
$mform = $this->_form;
$mform->addElement('header', 'backpackheader', get_string('backpackdetails', 'badges'));
$mform->addElement('static', 'url', get_string('url'), 'http://backpack.openbadges.org');
$mform->addElement('text', 'email', get_string('email'), array('size' => '50'));
$mform->setDefault('email', $USER->email);
$mform->setType('email', PARAM_EMAIL);
$mform->addRule('email', get_string('required'), 'required', null , 'client');
$mform->addRule('email', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->addElement('hidden', 'userid', $USER->id);
$mform->setType('userid', PARAM_INT);
$mform->addElement('hidden', 'backpackurl', 'http://backpack.openbadges.org');
$mform->setType('backpackurl', PARAM_URL);
$this->add_action_buttons();
}
}
/**
* Form to select backpack group options.
*
*/
class edit_backpack_group_form extends moodleform {
/**
* Defines the form
*/
public function definition() {
global $USER;
$mform = $this->_form;
$data = $this->_customdata['data'];
$groups = $this->_customdata['groups'];
$uid = $this->_customdata['backpackuid'];
$selet = array();
foreach ($groups as $group) {
$select[$group->groupId] = $group->name;
}
$mform->addElement('header', 'groupheader', get_string('backpackdetails', 'badges'));
$mform->addElement('static', 'url', get_string('url'), 'http://backpack.openbadges.org');
$mform->addElement('text', 'email', get_string('email'), array('size' => '50'));
$mform->setDefault('email', $data->email);
$mform->freeze(array('email'));
$mform->addElement('select', 'backpackgid', get_string('selectgroup', 'badges'), $select);
$mform->addRule('backpackgid', get_string('required'), 'required', null , 'client');
if (isset($data->backpackgid)) {
$mform->setDefault('backpackgid', $data->backpackgid);
}
$mform->addElement('hidden', 'userid', $data->userid);
$mform->setType('userid', PARAM_INT);
$mform->addElement('hidden', 'backpackurl', 'http://backpack.openbadges.org');
$mform->setType('backpackurl', PARAM_URL);
$mform->addElement('hidden', 'backpackuid', $uid);
$mform->setType('backpackuid', PARAM_INT);
$this->add_action_buttons();
}
}
+68
View File
@@ -0,0 +1,68 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Display details of an issued badge with criteria and evidence
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$id = required_param('hash', PARAM_ALPHANUM);
$bake = optional_param('bake', 0, PARAM_BOOL);
$PAGE->set_context(context_system::instance());
$output = $PAGE->get_renderer('core', 'badges');
$badge = new issued_badge($id);
if ($bake && ($badge->recipient == $USER->id)) {
$name = str_replace(' ', '_', $badge->issued['badge']['name']) . '.png';
ob_start();
$file = badges_bake($id, $badge->badgeid);
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="'. $name .'"');
readfile($file);
ob_flush();
}
$PAGE->set_url('/badges/badge.php', array('hash' => $id));
$PAGE->set_pagelayout('base');
$PAGE->set_title(get_string('issuedbadge', 'badges'));
if (isloggedin()) {
$PAGE->set_heading($badge->issued['badge']['name']);
$PAGE->navbar->add($badge->issued['badge']['name']);
$url = new moodle_url('/badges/mybadges.php');
navigation_node::override_active_url($url);
}
// TODO: Better way of pushing badges to Mozilla backpack?
if ($CFG->badges_allowexternalbackpack) {
$PAGE->requires->js(new moodle_url('http://backpack.openbadges.org/issuer.js'), true);
}
echo $OUTPUT->header();
echo $output->render($badge);
echo $OUTPUT->footer();
+103
View File
@@ -0,0 +1,103 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Editing badge details, criteria, messages
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = required_param('id', PARAM_INT);
$update = optional_param('update', 0, PARAM_INT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$currenturl = new moodle_url('/badges/criteria.php', array('id' => $badge->id));
$PAGE->set_context($context);
$PAGE->set_url($currenturl);
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
// Set up navigation and breadcrumbs.
navigation_node::override_active_url($navurl);
$PAGE->navbar->add($badge->name);
$output = $PAGE->get_renderer('core', 'badges');
$msg = optional_param('msg', '', PARAM_TEXT);
$emsg = optional_param('emsg', '', PARAM_TEXT);
if ((($update == BADGE_CRITERIA_AGGREGATION_ALL) || ($update == BADGE_CRITERIA_AGGREGATION_ANY))) {
require_sesskey();
require_capability('moodle/badges:configurecriteria', $context);
$obj = new stdClass();
$obj->id = $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->id;
$obj->method = $update;
if ($DB->update_record('badge_criteria', $obj)) {
$msg = get_string('changessaved');
} else {
$emsg = get_string('error:save', 'badges');
}
}
echo $OUTPUT->header();
echo $OUTPUT->heading(print_badge_image($badge, $context, 'small') . ' ' . $badge->name);
if ($emsg !== '') {
echo $OUTPUT->notification($emsg);
} else if ($msg !== '') {
echo $OUTPUT->notification($msg, 'notifysuccess');
}
echo $output->print_badge_status_box($badge);
$output->print_badge_tabs($badgeid, $context, 'criteria');
if (!$badge->is_locked() && !$badge->is_active()) {
echo $output->print_criteria_actions($badge);
}
if ($badge->has_criteria()) {
ksort($badge->criteria);
foreach ($badge->criteria as $crit) {
$crit->config_form_criteria($badge);
}
} else {
echo $OUTPUT->box(get_string('addcriteriatext', 'badges'));
}
echo $OUTPUT->footer();
+390
View File
@@ -0,0 +1,390 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Badge award criteria
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
/*
* Role completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_OVERALL', 0);
/*
* Activity completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_ACTIVITY', 1);
/*
* Duration completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_MANUAL', 2);
/*
* Grade completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_SOCIAL', 3);
/*
* Course completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_COURSE', 4);
/*
* Courseset completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_COURSESET', 5);
/*
* Course completion criteria type
* Criteria type constant, primarily for storing criteria type in the database.
*/
define('BADGE_CRITERIA_TYPE_PROFILE', 6);
/*
* Criteria type constant to class name mapping
*/
global $BADGE_CRITERIA_TYPES;
$BADGE_CRITERIA_TYPES = array(
BADGE_CRITERIA_TYPE_OVERALL => 'overall',
BADGE_CRITERIA_TYPE_ACTIVITY => 'activity',
BADGE_CRITERIA_TYPE_MANUAL => 'manual',
BADGE_CRITERIA_TYPE_SOCIAL => 'social',
BADGE_CRITERIA_TYPE_COURSE => 'course',
BADGE_CRITERIA_TYPE_COURSESET => 'courseset',
BADGE_CRITERIA_TYPE_PROFILE => 'profile'
);
/**
* Award criteria abstract definition
*
*/
abstract class award_criteria {
public $id;
public $method;
public $badgeid;
public $params = array();
/**
* The base constructor
*
* @param array $params
*/
public function __construct($params) {
$this->id = isset($params['id']) ? $params['id'] : 0;
$this->method = isset($params['method']) ? $params['method'] : BADGE_CRITERIA_AGGREGATION_ANY;
$this->badgeid = $params['badgeid'];
if (isset($params['id'])) {
$this->params = $this->get_params($params['id']);
}
}
/**
* Factory method for creating criteria class object
*
* @param array $params associative arrays varname => value
* @return award_criteria
*/
public static function build($params) {
global $CFG, $BADGE_CRITERIA_TYPES;
if (!isset($params['criteriatype']) || !isset($BADGE_CRITERIA_TYPES[$params['criteriatype']])) {
print_error('error:invalidcriteriatype', 'badges');
}
$class = 'award_criteria_' . $BADGE_CRITERIA_TYPES[$params['criteriatype']];
require_once($CFG->dirroot . '/badges/criteria/' . $class . '.php');
return new $class($params);
}
/**
* Return criteria title
*
* @return string
*/
public function get_title() {
return get_string('criteria_' . $this->criteriatype, 'badges');
}
/**
* Get criteria details for displaying to users
*
* @param string $short Print short version of criteria
* @return string
*/
abstract public function get_details($short = '');
/**
* Add appropriate criteria options to the form
*
*/
abstract public function get_options(&$mform);
/**
* Add appropriate parameter elements to the criteria form
*
*/
public function config_options(&$mform, $param) {
global $OUTPUT;
$prefix = $this->required_param . '_';
if ($param['error']) {
$parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '',
$OUTPUT->error_text($param['name']), null, array(0, $param['id']));
$mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false);
} else {
$parameter[] =& $mform->createElement('advcheckbox', $prefix . $param['id'], '', $param['name'], null, array(0, $param['id']));
$parameter[] =& $mform->createElement('static', 'break_start_' . $param['id'], null, '<div style="margin-left: 3em;">');
if (in_array('grade', $this->optional_params)) {
$parameter[] =& $mform->createElement('static', 'mgrade_' . $param['id'], null, get_string('mingrade', 'badges'));
$parameter[] =& $mform->createElement('text', 'grade_' . $param['id'], '', array('size' => '5'));
}
if (in_array('bydate', $this->optional_params)) {
$parameter[] =& $mform->createElement('static', 'complby_' . $param['id'], null, get_string('bydate', 'badges'));
$parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['id'], "", array('optional' => true));
}
$parameter[] =& $mform->createElement('static', 'break_end_' . $param['id'], null, '</div>');
$mform->addGroup($parameter, 'param_' . $prefix . $param['id'], '', array(' '), false);
if (in_array('grade', $this->optional_params)) {
$mform->addGroupRule('param_' . $prefix . $param['id'], array(
'grade_' . $param['id'] => array(array(get_string('err_numeric', 'form'), 'numeric', '', 'client'))));
}
$mform->disabledIf('bydate_' . $param['id'] . '[day]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
$mform->disabledIf('bydate_' . $param['id'] . '[month]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
$mform->disabledIf('bydate_' . $param['id'] . '[year]', 'bydate_' . $param['id'] . '[enabled]', 'notchecked');
$mform->disabledIf('param_' . $prefix . $param['id'], $prefix . $param['id'], 'notchecked');
}
// Set default values.
$mform->setDefault($prefix . $param['id'], $param['checked']);
if (isset($param['bydate'])) {
$mform->setDefault('bydate_' . $param['id'], $param['bydate']);
}
if (isset($param['grade'])) {
$mform->setDefault('grade_' . $param['id'], $param['grade']);
}
}
/**
* Add appropriate criteria elements
*
* @param stdClass $data details of various criteria
*/
public function config_form_criteria($data) {
global $OUTPUT;
$agg = $data->get_aggregation_methods();
$editurl = new moodle_url('/badges/criteria_settings.php',
array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id));
$deleteurl = new moodle_url('/badges/criteria_action.php',
array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype));
$editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action'));
$deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action'));
echo $OUTPUT->box_start();
if (!$data->is_locked() && !$data->is_active()) {
echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header'));
}
echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
if (!empty($this->params)) {
if (count($this->params) > 1) {
echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges',
strtoupper($agg[$data->get_aggregation_method($this->criteriatype)])), array('clearfix'));
} else {
echo $OUTPUT->box(get_string('criteria_descr_single_' . $this->criteriatype , 'badges'), array('clearfix'));
}
echo $OUTPUT->box($this->get_details(), array('clearfix'));
}
echo $OUTPUT->box_end();
}
/**
* Review this criteria and decide if the user has completed
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
abstract public function review($userid);
/**
* Mark this criteria as complete for a user
*
* @param int $userid User whose criteria is completed.
*/
public function mark_complete($userid) {
global $DB;
$obj = array();
$obj['critid'] = $this->id;
$obj['userid'] = $userid;
$obj['datemet'] = time();
if (!$DB->record_exists('badge_criteria_met', array('critid' => $this->id, 'userid' => $userid))) {
$DB->insert_record('badge_criteria_met', $obj);
}
}
/**
* Return criteria parameters
*
* @param int $critid Criterion ID
* @return array
*/
public function get_params($cid) {
global $DB;
$params = array();
$records = $DB->get_records('badge_criteria_param', array('critid' => $cid));
foreach ($records as $rec) {
$arr = explode('_', $rec->name);
$params[$arr[1]][$arr[0]] = $rec->value;
}
return $params;
}
/**
* Delete this criterion
*
*/
public function delete() {
global $DB;
// Remove any records if it has already been met.
$DB->delete_records('badge_criteria_met', array('critid' => $this->id));
// Remove all parameters records.
$DB->delete_records('badge_criteria_param', array('critid' => $this->id));
// Finally remove criterion itself.
$DB->delete_records('badge_criteria', array('id' => $this->id));
}
/**
* Saves intial criteria records with required parameters set up.
*/
public function save($params = array()) {
global $DB;
$fordb = new stdClass();
$fordb->criteriatype = $this->criteriatype;
$fordb->method = isset($params->agg) ? $params->agg : $params['agg'];
$fordb->badgeid = $this->badgeid;
$t = $DB->start_delegated_transaction();
// Unset unnecessary parameters supplied with form.
if (isset($params->agg)) {
unset($params->agg);
} else {
unset($params['agg']);
}
unset($params->submitbutton);
$params = array_filter((array)$params);
if ($this->id !== 0) {
$cid = $this->id;
// Update criteria before doing anything with parameters.
$fordb->id = $cid;
$DB->update_record('badge_criteria', $fordb, true);
$existing = $DB->get_fieldset_select('badge_criteria_param', 'name', 'critid = ?', array($cid));
$todelete = array_diff($existing, array_keys($params));
if (!empty($todelete)) {
// A workaround to add some disabled elements that are still being submitted from the form.
foreach ($todelete as $del) {
$name = explode('_', $del);
if ($name[0] == $this->required_param) {
foreach ($this->optional_params as $opt) {
$todelete[] = $opt . '_' . $name[1];
}
}
}
$todelete = array_unique($todelete);
list($sql, $sqlparams) = $DB->get_in_or_equal($todelete, SQL_PARAMS_NAMED, 'd', true);
$sqlparams = array_merge(array('critid' => $cid), $sqlparams);
$DB->delete_records_select('badge_criteria_param', 'critid = :critid AND name ' . $sql, $sqlparams);
}
foreach ($params as $key => $value) {
if (in_array($key, $existing)) {
$updp = $DB->get_record('badge_criteria_param', array('name' => $key, 'critid' => $cid));
$updp->value = $value;
$DB->update_record('badge_criteria_param', $updp, true);
} else {
$newp = new stdClass();
$newp->critid = $cid;
$newp->name = $key;
$newp->value = $value;
$DB->insert_record('badge_criteria_param', $newp);
}
}
} else {
$cid = $DB->insert_record('badge_criteria', $fordb, true);
if ($cid) {
foreach ($params as $key => $value) {
$newp = new stdClass();
$newp->critid = $cid;
$newp->name = $key;
$newp->value = $value;
$DB->insert_record('badge_criteria_param', $newp, false, true);
}
}
}
$t->allow_commit();
}
/**
* Saves intial criteria records with required parameters set up.
*/
public function make_clone($newbadgeid) {
global $DB;
$fordb = new stdClass();
$fordb->criteriatype = $this->criteriatype;
$fordb->method = $this->method;
$fordb->badgeid = $newbadgeid;
if (($newcrit = $DB->insert_record('badge_criteria', $fordb, true)) && isset($this->params)) {
foreach ($this->params as $k => $param) {
foreach ($param as $key => $value) {
$paramdb = new stdClass();
$paramdb->critid = $newcrit;
$paramdb->name = $key . '_' . $k;
$paramdb->value = $value;
$DB->insert_record('badge_criteria_param', $paramdb);
}
}
}
}
}
+232
View File
@@ -0,0 +1,232 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the activity badge award criteria type class
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/completionlib.php');
/**
* Badge award criteria -- award on activity completion
*
*/
class award_criteria_activity extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_ACTIVITY] */
public $criteriatype = BADGE_CRITERIA_TYPE_ACTIVITY;
private $courseid;
public $required_param = 'module';
public $optional_params = array('bydate');
public function __construct($record) {
parent::__construct($record);
$this->courseid = self::get_course();
}
/**
* Gets the module instance from the database and returns it.
* If no module instance exists this function returns false.
*
* @return stdClass|bool
*/
private function get_mod_instance($cmid) {
global $DB;
$rec = $DB->get_record_sql("SELECT md.name
FROM {course_modules} cm,
{modules} md
WHERE cm.id = ? AND
md.id = cm.module", array($cmid));
if ($rec) {
return get_coursemodule_from_id($rec->name, $cmid);
} else {
return null;
}
}
/**
* Get criteria description for displaying to users
*
* @return string
*/
public function get_details($short = '') {
global $DB, $OUTPUT;
$output = array();
foreach ($this->params as $p) {
$mod = self::get_mod_instance($p['module']);
if (!$mod) {
$str = $OUTPUT->error_text(get_string('error:nosuchmod', 'badges'));
} else {
$str = html_writer::tag('b', '"' . ucfirst($mod->modname) . ' - ' . $mod->name . '"');
if (isset($p['bydate'])) {
$str .= get_string('criteria_descr_bydate', 'badges', userdate($p['bydate'], get_string('strftimedate', 'core_langconfig')));
}
}
$output[] = $str;
}
if ($short) {
return implode(', ', $output);
} else {
return html_writer::alist($output, array(), 'ul');
}
}
/**
* Return course ID for activities
*
* @return int
*/
private function get_course() {
global $DB;
$courseid = $DB->get_field('badge', 'courseid', array('id' => $this->badgeid));
return $courseid;
}
/**
* Add appropriate new criteria options to the form
*
*/
public function get_options(&$mform) {
global $DB;
$none = true;
$existing = array();
$missing = array();
$course = $DB->get_record('course', array('id' => $this->courseid));
$info = new completion_info($course);
$mods = $info->get_activities();
$mids = array_map(create_function('$o', 'return $o->id;'), $mods);
if ($this->id !== 0) {
$existing = array_keys($this->params);
$missing = array_diff($existing, $mids);
}
if (!empty($missing)) {
$mform->addElement('header', 'category_errors', get_string('criterror', 'badges'));
$mform->addHelpButton('category_errors', 'criterror', 'badges');
foreach ($missing as $m) {
$this->config_options($mform, array('id' => $m, 'checked' => true,
'name' => get_string('error:nosuchmod', 'badges'), 'error' => true));
$none = false;
}
}
if (!empty($mods)) {
$mform->addElement('header', 'first_header', $this->get_title());
foreach ($mods as $mod) {
$checked = false;
if (in_array($mod->id, $existing)) {
$checked = true;
}
$param = array('id' => $mod->id,
'checked' => $checked,
'name' => ucfirst($mod->modname) . ' - ' . $mod->name,
'error' => false
);
if ($this->id !== 0 && isset($this->params[$mod->id]['bydate'])) {
$param['bydate'] = $this->params[$mod->id]['bydate'];
}
if ($this->id !== 0 && isset($this->params[$mod->id]['grade'])) {
$param['grade'] = $this->params[$mod->id]['grade'];
}
$this->config_options($mform, $param);
$none = false;
}
}
// Add aggregation.
if (!$none) {
$mform->addElement('header', 'aggregation', get_string('method', 'badges'));
$agg = array();
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodactivity', 'badges'), 1);
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodactivity', 'badges'), 2);
$mform->addGroup($agg, 'methodgr', '', array('<br/>'), false);
if ($this->id !== 0) {
$mform->setDefault('agg', $this->method);
} else {
$mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
}
}
return array($none, get_string('error:noactivities', 'badges'));
}
/**
* Review this criteria and decide if it has been completed
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
$completionstates = array(COMPLETION_COMPLETE, COMPLETION_COMPLETE_PASS);
$course = $DB->get_record('course', array('id' => $this->courseid));
if ($course->startdate > time()) {
return false;
}
$info = new completion_info($course);
$overall = false;
foreach ($this->params as $param) {
$cm = new stdClass();
$cm->id = $param['module'];
$data = $info->get_data($cm, false, $userid);
$check_date = true;
if (isset($param['bydate'])) {
$date = $data->timemodified;
$check_date = ($date <= $param['bydate']);
}
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if (in_array($data->completionstate, $completionstates) && $check_date) {
$overall = true;
continue;
} else {
return false;
}
} else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
if (in_array($data->completionstate, $completionstates) && $check_date) {
return true;
} else {
$overall = false;
continue;
}
}
}
return $overall;
}
}
+178
View File
@@ -0,0 +1,178 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the course completion badge award criteria type class
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/completionlib.php');
require_once($CFG->dirroot . '/grade/querylib.php');
require_once($CFG->libdir . '/gradelib.php');
/**
* Badge award criteria -- award on course completion
*
*/
class award_criteria_course extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_COURSE] */
public $criteriatype = BADGE_CRITERIA_TYPE_COURSE;
public $required_param = 'course';
public $optional_params = array('grade', 'bydate');
/**
* Add appropriate form elements to the criteria form
*
* @param moodleform $mform Moodle forms object
* @param stdClass $data details of various modules
*/
public function config_form_criteria($data) {
global $OUTPUT;
$editurl = new moodle_url('/badges/criteria_settings.php', array('badgeid' => $this->badgeid, 'edit' => true, 'type' => $this->criteriatype, 'crit' => $this->id));
$deleteurl = new moodle_url('/badges/criteria_action.php', array('badgeid' => $this->badgeid, 'delete' => true, 'type' => $this->criteriatype));
$editaction = $OUTPUT->action_icon($editurl, new pix_icon('t/edit', get_string('edit')), null, array('class' => 'criteria-action'));
$deleteaction = $OUTPUT->action_icon($deleteurl, new pix_icon('t/delete', get_string('delete')), null, array('class' => 'criteria-action'));
echo $OUTPUT->box_start();
if (!$data->is_locked() && !$data->is_active()) {
echo $OUTPUT->box($deleteaction . $editaction, array('criteria-header'));
}
echo $OUTPUT->heading($this->get_title() . $OUTPUT->help_icon('criteria_' . $this->criteriatype, 'badges'), 3, 'main help');
if (!empty($this->params)) {
echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges') . $this->get_details(), array('clearfix'));
}
echo $OUTPUT->box_end();
}
/**
* Get criteria details for displaying to users
*
* @return string
*/
public function get_details($short = '') {
global $DB;
$param = reset($this->params);
$course = $DB->get_record('course', array('id' => $param['course']));
$str = '"' . $course->fullname . '"';
if (isset($param['bydate'])) {
$str .= get_string('criteria_descr_bydate', 'badges', userdate($param['bydate'], get_string('strftimedate', 'core_langconfig')));
}
if (isset($param['grade'])) {
$str .= get_string('criteria_descr_grade', 'badges', $param['grade']);
}
return $str;
}
/**
* Add appropriate new criteria options to the form
*
*/
public function get_options(&$mform) {
global $PAGE, $DB;
$param = array_shift($this->params);
$course = $DB->get_record('course', array('id' => $PAGE->course->id));
if (!($course->enablecompletion == COMPLETION_ENABLED)) {
$none = true;
$message = get_string('completionnotenabled', 'badges');
} else {
$mform->addElement('header', 'criteria_course', $this->get_title());
$mform->addHelpButton('criteria_course', 'criteria_' . $this->criteriatype, 'badges');
$parameter = array();
$parameter[] =& $mform->createElement('static', 'mgrade_', null, get_string('mingrade', 'badges'));
$parameter[] =& $mform->createElement('text', 'grade_' . $param['course'], '', array('size' => '5'));
$parameter[] =& $mform->createElement('static', 'complby_' . $param['course'], null, get_string('bydate', 'badges'));
$parameter[] =& $mform->createElement('date_selector', 'bydate_' . $param['course'], '', array('optional' => true));
$mform->addGroup($parameter, 'param_' . $param['course'], '', array(' '), false);
$mform->disabledIf('bydate_' . $param['course'] . '[day]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
$mform->disabledIf('bydate_' . $param['course'] . '[month]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
$mform->disabledIf('bydate_' . $param['course'] . '[year]', 'bydate_' . $param['course'] . '[enabled]', 'notchecked');
// Set existing values.
if (isset($param['bydate'])) {
$mform->setDefault('bydate_' . $param['course'], $param['bydate']);
}
if (isset($param['grade'])) {
$mform->setDefault('grade_' . $param['course'], $param['grade']);
}
// Add hidden elements.
$mform->addElement('hidden', 'course_' . $course->id, $course->id);
$mform->setType('course_' . $course->id, PARAM_INT);
$mform->addElement('hidden', 'agg', BADGE_CRITERIA_AGGREGATION_ALL);
$mform->setType('agg', PARAM_INT);
$none = false;
$message = '';
}
return array($none, $message);
}
/**
* Review this criteria and decide if it has been completed
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
foreach ($this->params as $param) {
$course = $DB->get_record('course', array('id' => $param['course']));
if ($course->startdate > time()) {
return false;
}
$info = new completion_info($course);
$check_grade = true;
$check_date = true;
if (isset($param['grade'])) {
$grade = grade_get_course_grade($userid, $course->id);
$check_grade = ($grade->grade >= $param['grade']);
}
if (isset($param['bydate'])) {
$cparams = array(
'userid' => $userid,
'course' => $course->id,
);
$completion = new completion_completion($cparams);
$date = $completion->timecompleted;
$check_date = ($date <= $param['bydate']);
}
if ($info->is_course_complete($userid) && $check_grade && $check_date) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,250 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the courseset completion badge award criteria type class
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once('award_criteria_course.php');
require_once($CFG->libdir . '/completionlib.php');
require_once($CFG->dirroot . '/grade/querylib.php');
require_once($CFG->libdir . '/gradelib.php');
/**
* Badge award criteria -- award on courseset completion
*
*/
class award_criteria_courseset extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_COURSESET] */
public $criteriatype = BADGE_CRITERIA_TYPE_COURSESET;
public $required_param = 'course';
public $optional_params = array('grade', 'bydate');
/**
* Get criteria details for displaying to users
*
* @return string
*/
public function get_details($short = '') {
global $DB, $OUTPUT;
$output = array();
foreach ($this->params as $p) {
$coursename = $DB->get_field('course', 'fullname', array('id' => $p['course']));
if (!$coursename) {
$str = $OUTPUT->error_text(get_string('error:nosuchcourse', 'badges'));
} else {
$str = html_writer::tag('b', '"' . $coursename . '"');
if (isset($p['bydate'])) {
$str .= get_string('criteria_descr_bydate', 'badges', userdate($p['bydate'], get_string('strftimedate', 'core_langconfig')));
}
if (isset($p['grade'])) {
$str .= get_string('criteria_descr_grade', 'badges', $p['grade']);
}
}
$output[] = $str;
}
if ($short) {
return implode(', ', $output);
} else {
return html_writer::alist($output, array(), 'ul');
}
}
public function get_courses(&$mform) {
global $DB, $CFG, $PAGE;
require_once($CFG->dirroot . '/course/lib.php');
$buttonarray = array();
// Get courses with enabled completion.
$courses = $DB->get_records('course', array('enablecompletion' => COMPLETION_ENABLED));
if (!empty($courses)) {
$list = array();
$parents = array();
make_categories_list($list, $parents);
$select = array();
$selected = array();
foreach ($courses as $c) {
$select[$c->id] = $list[$c->category] . ' / ' . format_string($c->fullname, true, array('context' => context_course::instance($c->id)));
}
if ($this->id !== 0) {
$selected = array_keys($this->params);
}
$settings = array('multiple' => 'multiple', 'size' => 20, 'style' => 'width:300px');
$mform->addElement('select', 'courses', get_string('addcourse', 'badges'), $select, $settings);
$mform->addRule('courses', get_string('requiredcourse', 'badges'), 'required');
$mform->addHelpButton('courses', 'addcourse', 'badges');
$buttonarray[] =& $mform->createElement('submit', 'submitcourse', get_string('addcourse', 'badges'));
$buttonarray[] =& $mform->createElement('submit', 'back', get_string('cancel'));
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
$mform->addElement('hidden', 'addcourse', 'addcourse');
$mform->setType('addcourse', PARAM_TEXT);
if ($this->id !== 0) {
$mform->setDefault('courses', $selected);
}
$mform->setType('agg', PARAM_INT);
} else {
$mform->addElement('static', 'nocourses', '', get_string('error:nocourses', 'badges'));
$buttonarray[] =& $mform->createElement('submit', 'back', get_string('continue'));
$mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
}
}
public function add_courses($params = array()) {
global $DB;
$t = $DB->start_delegated_transaction();
if ($this->id !== 0) {
$critid = $this->id;
} else {
$fordb = new stdClass();
$fordb->criteriatype = $this->criteriatype;
$fordb->method = BADGE_CRITERIA_AGGREGATION_ALL;
$fordb->badgeid = $this->badgeid;
$critid = $DB->insert_record('badge_criteria', $fordb, true, true);
}
if ($critid) {
foreach ($params as $p) {
$newp = new stdClass();
$newp->critid = $critid;
$newp->name = 'course_' . $p;
$newp->value = $p;
if (!$DB->record_exists('badge_criteria_param', array('critid' => $critid, 'name' => $newp->name))) {
$DB->insert_record('badge_criteria_param', $newp, false, true);
}
}
}
$t->allow_commit();
return $critid;
}
/**
* Add appropriate new criteria options to the form
*
*/
public function get_options(&$mform) {
global $DB;
$none = true;
$mform->addElement('header', 'first_header', $this->get_title());
$mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges');
if ($courses = $DB->get_records('course', array('enablecompletion' => COMPLETION_ENABLED))) {
$mform->addElement('submit', 'addcourse', get_string('addcourse', 'badges'), array('class' => 'addcourse'));
}
// In courseset, print out only the ones that were already selected.
foreach ($this->params as $p) {
if ($course = $DB->get_record('course', array('id' => $p['course']))) {
$param = array(
'id' => $course->id,
'checked' => true,
'name' => ucfirst($course->fullname),
'error' => false
);
if (isset($p['bydate'])) {
$param['bydate'] = $p['bydate'];
}
if (isset($p['grade'])) {
$param['grade'] = $p['grade'];
}
$this->config_options($mform, $param);
$none = false;
} else {
$this->config_options($mform, array('id' => $p['course'], 'checked' => true,
'name' => get_string('error:nosuchcourse', 'badges'), 'error' => true));
}
}
// Add aggregation.
if (!$none) {
$mform->addElement('header', 'aggregation', get_string('method', 'badges'));
$agg = array();
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodcourseset', 'badges'), 1);
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodcourseset', 'badges'), 2);
$mform->addGroup($agg, 'methodgr', '', array('<br/>'), false);
if ($this->id !== 0) {
$mform->setDefault('agg', $this->method);
} else {
$mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
}
}
return array($none, get_string('noparamstoadd', 'badges'));
}
/**
* Review this criteria and decide if it has been completed
*
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
foreach ($this->params as $param) {
$course = $DB->get_record('course', array('id' => $param['course']));
$info = new completion_info($course);
$check_grade = true;
$check_date = true;
if (isset($param['grade'])) {
$grade = grade_get_course_grade($userid, $course->id);
$check_grade = ($grade->grade >= $param['grade']);
}
if (isset($param['bydate'])) {
$cparams = array(
'userid' => $userid,
'course' => $course->id,
);
$completion = new completion_completion($cparams);
$date = $completion->timecompleted;
$check_date = ($date <= $param['bydate']);
}
$overall = false;
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if ($info->is_course_complete($userid) && $check_grade && $check_date) {
$overall = true;
continue;
} else {
return false;
}
} else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
if ($info->is_course_complete($userid) && $check_grade && $check_date) {
return true;
} else {
$overall = false;
continue;
}
}
}
return $overall;
}
}
+184
View File
@@ -0,0 +1,184 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the manual badge award criteria type class
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
/**
* Manual badge award criteria
*
*/
class award_criteria_manual extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_MANUAL] */
public $criteriatype = BADGE_CRITERIA_TYPE_MANUAL;
public $required_param = 'role';
public $optional_params = array();
/**
* Gets role name.
* If no such role exists this function returns null.
*
* @return string|null
*/
private function get_role_name($rid) {
global $DB, $PAGE;
$rec = $DB->get_record('role', array('id' => $rid));
if ($rec) {
return role_get_name($rec, $PAGE->context, ROLENAME_ALIAS);
} else {
return null;
}
}
/**
* Add appropriate new criteria options to the form
*
*/
public function get_options(&$mform) {
global $PAGE;
$options = '';
$none = true;
$roles = get_roles_with_capability('moodle/badges:awardbadge', CAP_ALLOW, $PAGE->context);
$roleids = array_map(create_function('$o', 'return $o->id;'), $roles);
$existing = array();
$missing = array();
if ($this->id !== 0) {
$existing = array_keys($this->params);
$missing = array_diff($existing, $roleids);
}
if (!empty($missing)) {
$mform->addElement('header', 'category_errors', get_string('criterror', 'badges'));
$mform->addHelpButton('category_errors', 'criterror', 'badges');
foreach ($missing as $m) {
$this->config_options($mform, array('id' => $m, 'checked' => true, 'name' => get_string('error:nosuchrole', 'badges'), 'error' => true));
$none = false;
}
}
if (!empty($roleids)) {
$mform->addElement('header', 'first_header', $this->get_title());
$mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges');
foreach ($roleids as $rid) {
$checked = false;
if (in_array($rid, $existing)) {
$checked = true;
}
$this->config_options($mform, array('id' => $rid, 'checked' => $checked, 'name' => self::get_role_name($rid), 'error' => false));
$none = false;
}
}
// Add aggregation.
if (!$none) {
$mform->addElement('header', 'aggregation', get_string('method', 'badges'));
$agg = array();
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodmanual', 'badges'), 1);
$agg[] =& $mform->createElement('static', 'none_break', null, '<br/>');
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodmanual', 'badges'), 2);
$mform->addGroup($agg, 'methodgr', '', array(' '), false);
if ($this->id !== 0) {
$mform->setDefault('agg', $this->method);
} else {
$mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
}
}
return array($none, get_string('noparamstoadd', 'badges'));
}
/**
* Get criteria details for displaying to users
*
* @return string
*/
public function get_details($short = '') {
global $OUTPUT;
$output = array();
foreach ($this->params as $p) {
$str = self::get_role_name($p['role']);
if (!$str) {
$output[] = $OUTPUT->error_text(get_string('error:nosuchrole', 'badges'));
} else {
$output[] = $str;
}
}
if ($short) {
return implode(', ', $output);
} else {
return html_writer::alist($output, array(), 'ul');
}
}
/**
* Review this criteria and decide if it has been completed
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
$overall = false;
foreach ($this->params as $param) {
$crit = $DB->get_record('badge_manual_award', array('issuerrole' => $param['role'], 'recipientid' => $userid, 'badgeid' => $this->badgeid));
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if (!$crit) {
return false;
} else {
$overall = true;
continue;
}
} else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
if (!$crit) {
$overall = false;
continue;
} else {
return true;
}
}
}
return $overall;
}
/**
* Delete this criterion
*
*/
public function delete() {
global $DB;
// Remove any records of manual award.
$DB->delete_records('badge_manual_award', array('badgeid' => $this->badgeid));
parent::delete();
}
}
+145
View File
@@ -0,0 +1,145 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the overall badge award criteria type
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
/**
* Overall badge award criteria
*
*/
class award_criteria_overall extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_OVERALL] */
public $criteriatype = BADGE_CRITERIA_TYPE_OVERALL;
/**
* Add appropriate form elements to the criteria form
*
* @param stdClass $data details of overall criterion
*/
public function config_form_criteria($data) {
global $OUTPUT;
$prefix = 'criteria-' . $this->id;
if (count($data->criteria) > 2) {
echo $OUTPUT->box_start();
echo $OUTPUT->heading($this->get_title(), 2);
$agg = $data->get_aggregation_methods();
if (!$data->is_locked() && !$data->is_active()) {
$url = new moodle_url('criteria.php', array('id' => $data->id, 'sesskey' => sesskey()));
$table = new html_table();
$table->attributes = array('class' => 'clearfix');
$table->colclasses = array('', 'activatebadge');
$table->data[] = array(
$OUTPUT->single_select($url, 'update', $agg, $data->get_aggregation_method($this->criteriatype), null),
get_string('overallcrit', 'badges')
);
echo html_writer::table($table);
} else {
echo $OUTPUT->box(get_string('criteria_descr_' . $this->criteriatype, 'badges',
strtoupper($agg[$data->get_aggregation_method()])), 'clearfix');
}
echo $OUTPUT->box_end();
}
}
/**
* Add appropriate parameter elements to the criteria form
*
*/
public function config_options(&$mform, $param) {
}
/**
* Get criteria details for displaying to users
*
* @return string
*/
public function get_details($short = '') {
}
/**
* Review this criteria and decide if it has been completed
* Overall criteria review should be called only from other criteria handlers.
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
$sql = "SELECT bc.*, bcm.critid, bcm.userid, bcm.datemet
FROM {badge_criteria} bc
LEFT JOIN {badge_criteria_met} bcm
ON bc.id = bcm.critid AND bcm.userid = :userid
WHERE bc.badgeid = :badgeid
AND bc.criteriatype != :criteriatype ";
$params = array(
'userid' => $userid,
'badgeid' => $this->badgeid,
'criteriatype' => BADGE_CRITERIA_TYPE_OVERALL
);
$criteria = $DB->get_records_sql($sql, $params);
$overall = false;
foreach ($criteria as $crit) {
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if ($crit->datemet === null) {
return false;
} else {
$overall = true;
continue;
}
} else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
if ($crit->datemet === null) {
$overall = false;
continue;
} else {
return true;
}
}
}
return $overall;
}
/**
* Add appropriate criteria elements to the form
*
*/
public function get_options(&$mform) {
}
/**
* Return criteria parameters
*
* @param int $critid Criterion ID
* @return array
*/
public function get_params($cid) {
}
}
+190
View File
@@ -0,0 +1,190 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* This file contains the profile completion badge award criteria type class
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . "/user/lib.php");
/**
* Profile completion badge award criteria
*
*/
class award_criteria_profile extends award_criteria {
/* @var int Criteria [BADGE_CRITERIA_TYPE_PROFILE] */
public $criteriatype = BADGE_CRITERIA_TYPE_PROFILE;
public $required_param = 'field';
public $optional_params = array();
/**
* Add appropriate new criteria options to the form
*
*/
public function get_options(&$mform) {
global $DB;
$none = true;
$existing = array();
$missing = array();
// Note: cannot use user_get_default_fields() here because it is not possible to decide which fields user can modify.
$dfields = array('firstname', 'lastname', 'email', 'address', 'phone1', 'phone2', 'icq', 'skype', 'yahoo',
'aim', 'msn', 'department', 'institution', 'description', 'city', 'url', 'country');
$sql = "SELECT uf.id as fieldid, uf.name as name, ic.id as categoryid, ic.name as categoryname, uf.datatype
FROM {user_info_field} uf
JOIN {user_info_category} ic
ON uf.categoryid = ic.id AND uf.visible <> 0
ORDER BY ic.sortorder ASC, uf.sortorder ASC";
// Get custom fields.
$cfields = $DB->get_records_sql($sql);
$cfids = array_map(create_function('$o', 'return $o->fieldid;'), $cfields);
if ($this->id !== 0) {
$existing = array_keys($this->params);
$missing = array_diff($existing, array_merge($dfields, $cfids));
}
if (!empty($missing)) {
$mform->addElement('header', 'category_errors', get_string('criterror', 'badges'));
$mform->addHelpButton('category_errors', 'criterror', 'badges');
foreach ($missing as $m) {
$this->config_options($mform, array('id' => $m, 'checked' => true, 'name' => get_string('error:nosuchfield', 'badges'), 'error' => true));
$none = false;
}
}
if (!empty($dfields)) {
$mform->addElement('header', 'first_header', $this->get_title());
$mform->addHelpButton('first_header', 'criteria_' . $this->criteriatype, 'badges');
foreach ($dfields as $field) {
$checked = false;
if (in_array($field, $existing)) {
$checked = true;
}
$this->config_options($mform, array('id' => $field, 'checked' => $checked, 'name' => get_user_field_name($field), 'error' => false));
$none = false;
}
}
if (!empty($cfields)) {
foreach ($cfields as $field) {
if (!isset($currentcat) || $currentcat != $field->categoryid) {
$currentcat = $field->categoryid;
$mform->addElement('header', 'category_' . $currentcat, format_string($field->categoryname));
}
$checked = false;
if (in_array($field->fieldid, $existing)) {
$checked = true;
}
$this->config_options($mform, array('id' => $field->fieldid, 'checked' => $checked, 'name' => $field->name, 'error' => false));
$none = false;
}
}
// Add aggregation.
if (!$none) {
$mform->addElement('header', 'aggregation', get_string('method', 'badges'));
$agg = array();
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('allmethodprofile', 'badges'), 1);
$agg[] =& $mform->createElement('static', 'none_break', null, '<br/>');
$agg[] =& $mform->createElement('radio', 'agg', '', get_string('anymethodprofile', 'badges'), 2);
$mform->addGroup($agg, 'methodgr', '', array(' '), false);
if ($this->id !== 0) {
$mform->setDefault('agg', $this->method);
} else {
$mform->setDefault('agg', BADGE_CRITERIA_AGGREGATION_ANY);
}
}
return array($none, get_string('noparamstoadd', 'badges'));
}
/**
* Get criteria details for displaying to users
*
* @return string
*/
public function get_details($short = '') {
global $DB, $OUTPUT;
$output = array();
foreach ($this->params as $p) {
if (is_numeric($p['field'])) {
$str = $DB->get_field('user_info_field', 'name', array('id' => $p['field']));
} else {
$str = get_user_field_name($p['field']);
}
if (!$str) {
$output[] = $OUTPUT->error_text(get_string('error:nosuchfield', 'badges'));
} else {
$output[] = $str;
}
}
if ($short) {
return implode(', ', $output);
} else {
return html_writer::alist($output, array(), 'ul');
}
}
/**
* Review this criteria and decide if it has been completed
*
* @param int $userid User whose criteria completion needs to be reviewed.
* @return bool Whether criteria is complete
*/
public function review($userid) {
global $DB;
$overall = false;
foreach ($this->params as $param) {
if (is_numeric($param['field'])) {
$crit = $DB->get_field('user_info_data', 'data', array('userid' => $userid, 'fieldid' => $param['field']));
} else {
$crit = $DB->get_field('user', $param['field'], array('id' => $userid));
}
if ($this->method == BADGE_CRITERIA_AGGREGATION_ALL) {
if (!$crit) {
return false;
} else {
$overall = true;
continue;
}
} else if ($this->method == BADGE_CRITERIA_AGGREGATION_ANY) {
if (!$crit) {
$overall = false;
continue;
} else {
return true;
}
}
}
return $overall;
}
}
+86
View File
@@ -0,0 +1,86 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Processing actions with badge criteria.
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = optional_param('badgeid', 0, PARAM_INT); // Badge ID.
$crit = optional_param('crit', 0, PARAM_INT);
$type = optional_param('type', 0, PARAM_INT); // Criteria type.
$delete = optional_param('delete', 0, PARAM_BOOL);
$confirm = optional_param('confirm', 0, PARAM_BOOL);
require_login();
$return = new moodle_url('/badges/criteria.php', array('id' => $badgeid));
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
// Make sure that no actions available for locked or active badges.
if ($badge->is_active() || $badge->is_locked()) {
redirect($return);
}
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$PAGE->set_context($context);
$PAGE->set_url('/badges/criteria_action.php');
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
navigation_node::override_active_url($navurl);
if ($delete && has_capability('moodle/badges:configurecriteria', $context)) {
if (!$confirm) {
$optionsyes = array('confirm' => 1, 'sesskey' => sesskey(), 'badgeid' => $badgeid, 'delete' => true, 'type' => $type);
$strdeletecheckfull = get_string('delcritconfirm', 'badges');
echo $OUTPUT->header();
$formcontinue = new single_button(new moodle_url('/badges/criteria_action.php', $optionsyes), get_string('yes'));
$formcancel = new single_button($return, get_string('no'), 'get');
echo $OUTPUT->confirm($strdeletecheckfull, $formcontinue, $formcancel);
echo $OUTPUT->footer();
die();
}
require_sesskey();
if (count($badge->criteria) == 2) {
// Remove overall criterion as well.
$badge->criteria[$type]->delete();
$badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->delete();
} else {
$badge->criteria[$type]->delete();
}
redirect($return);
}
redirect($return);
+89
View File
@@ -0,0 +1,89 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form classes for editing badges criteria
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->libdir . '/badgeslib.php');
/**
* Form to edit badge criteria.
*
*/
class edit_criteria_form extends moodleform {
public function definition() {
global $DB;
$mform = $this->_form;
$criteria = $this->_customdata['criteria'];
$addcourse = $this->_customdata['addcourse'];
// Get course selector first if it's a new courseset criteria.
if (($criteria->id == 0 || $addcourse) && $criteria->criteriatype == BADGE_CRITERIA_TYPE_COURSESET) {
$criteria->get_courses($mform);
} else {
list($none, $message) = $criteria->get_options($mform);
if ($none) {
$mform->addElement('html', html_writer::tag('div', $message));
$mform->addElement('submit', 'cancel', get_string('continue'));
} else {
$mform->closeHeaderBefore('buttonar');
$this->add_action_buttons(true, get_string('save', 'badges'));
}
}
}
/**
* Validates form data
*/
public function validation($data, $files) {
global $OUTPUT;
$errors = parent::validation($data, $files);
$addcourse = $this->_customdata['addcourse'];
if (!$addcourse) {
$required = $this->_customdata['criteria']->required_param;
$pattern1 = '/^' . $required . '_(\d+)$/';
$pattern2 = '/^' . $required . '_(\w+)$/';
$ok = false;
foreach ($data as $key => $value) {
if ((preg_match($pattern1, $key) || preg_match($pattern2, $key)) && !($value === 0 || $value == '0')) {
$ok = true;
}
}
$warning = $this->_form->createElement('html',
$OUTPUT->notification(get_string('error:parameter', 'badges'), 'notifyproblem'), 'submissionerror');
if (!$ok) {
$errors['formerrors'] = 'Error';
$this->_form->insertElementBefore($warning, 'first_header');
}
}
return $errors;
}
}
+105
View File
@@ -0,0 +1,105 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Page for editing badges criteria settings.
*
* @package core
* @subpackage badges
* @copyright 2013 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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->dirroot . '/badges/criteria_form.php');
$badgeid = optional_param('badgeid', 0, PARAM_INT); // Badge ID.
$type = optional_param('type', 0, PARAM_INT); // Criteria type.
$edit = optional_param('edit', 0, PARAM_INT); // Edit criteria ID.
$crit = optional_param('crit', 0, PARAM_INT); // Criteria ID for managing params.
$param = optional_param('param', '', PARAM_TEXT); // Param name for managing params.
$goback = optional_param('cancel', '', PARAM_TEXT);
$addcourse = optional_param('addcourse', '', PARAM_TEXT);
$submitcourse = optional_param('submitcourse', '', PARAM_TEXT);
require_login();
$return = new moodle_url('/badges/criteria.php', array('id' => $badgeid));
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
require_capability('moodle/badges:configurecriteria', $context);
if (!empty($goback)) {
redirect($return);
}
// Make sure that no actions available for locked or active badges.
if ($badge->is_active() || $badge->is_locked()) {
redirect($return);
}
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$PAGE->set_context($context);
$PAGE->set_url('/badges/criteria_settings.php');
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
navigation_node::override_active_url($navurl);
$PAGE->navbar->add($badge->name, new moodle_url('overview.php', array('id' => $badge->id)))->add(get_string('criteria_' . $type, 'badges'));
$cparams = array('criteriatype' => $type, 'badgeid' => $badge->id);
if ($edit) {
$criteria = $badge->criteria[$type];
} else {
$criteria = award_criteria::build($cparams);
}
$mform = new edit_criteria_form($FULLME, array('criteria' => $criteria, 'addcourse' => $addcourse));
if (!empty($addcourse)) {
if ($data = $mform->get_data()) {
// If no criteria yet, add overall aggregation.
if (count($badge->criteria) == 0) {
$criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
$criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
}
$id = $criteria->add_courses($data->courses);
redirect(new moodle_url('/badges/criteria_settings.php',
array('badgeid' => $badgeid, 'edit' => true, 'type' => BADGE_CRITERIA_TYPE_COURSESET, 'crit' => $id)));
}
} else if ($data = $mform->get_data()) {
// If no criteria yet, add overall aggregation.
if (count($badge->criteria) == 0) {
$criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
$criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
}
$criteria->save($data);
$return->param('msg', get_string('changessaved'));
redirect($return);
}
echo $OUTPUT->header();
$mform->display();
echo $OUTPUT->footer();
+162
View File
@@ -0,0 +1,162 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Cron job for reviewing and aggregating badge award criteria
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/badgeslib.php');
function badge_cron() {
global $CFG;
if ($CFG->enablebadges) {
badge_review_cron();
badge_message_cron();
}
}
/**
* Reviews criteria and awards badges
*
* First find all badges that can be earned, then reviews each badge.
* (Not sure how efficient this is timewise).
*/
function badge_review_cron() {
global $DB, $CFG;
$total = 0;
$courseparams = array();
if (empty($CFG->badges_allowcoursebadges)) {
$coursesql = '';
} else {
$coursesql = ' OR EXISTS (SELECT id FROM {course} WHERE visible = :visible AND startdate < :current) ';
$courseparams = array('visible' => true, 'current' => time());
}
$sql = 'SELECT id
FROM {badge}
WHERE (status = :active OR status = :activelocked)
AND (type = :site ' . $coursesql . ')';
$badgeparams = array(
'active' => BADGE_STATUS_ACTIVE,
'activelocked' => BADGE_STATUS_ACTIVE_LOCKED,
'site' => BADGE_TYPE_SITE
);
$params = array_merge($badgeparams, $courseparams);
$badges = $DB->get_fieldset_sql($sql, $params);
mtrace('Started reviewing available badges.');
foreach ($badges as $bid) {
$badge = new badge($bid);
if ($badge->has_criteria()) {
if (debugging()) {
mtrace('Processing badge "' . $badge->name . '"...');
}
$issued = $badge->review_all_criteria();
if (debugging()) {
mtrace('...badge was issued to ' . $issued . ' users.');
}
$total += $issued;
}
}
mtrace('Badges were issued ' . $total . ' time(s).');
}
/**
* Sends out scheduled messages to badge creators
*
*/
function badge_message_cron() {
global $DB;
mtrace('Sending scheduled badge notifications.');
$scheduled = $DB->get_records_select('badge', 'notification > ? AND (status != ?) AND nextcron < ?',
array(BADGE_MESSAGE_ALWAYS, BADGE_STATUS_ARCHIVED, time()),
'notification ASC', 'id, name, notification, usercreated as creator, timecreated');
foreach ($scheduled as $sch) {
// Send messages.
badge_assemble_notification($sch);
// Update next cron value.
$nextcron = badges_calculate_message_schedule($sch->notification);
$DB->set_field('badge', 'nextcron', $nextcron, array('id' => $sch->id));
}
}
/**
* Creates single message for all notification and sends it out
*
* @param object $badge A badge which is notified about.
*/
function badge_assemble_notification(stdClass $badge) {
global $CFG, $DB;
$admin = get_admin();
$userfrom = new stdClass();
$userfrom->id = $admin->id;
$userfrom->email = !empty($CFG->badges_defaultissuercontact) ? $CFG->badges_defaultissuercontact : $admin->email;
$userfrom->firstname = !empty($CFG->badges_defaultissuername) ? $CFG->badges_defaultissuername : $admin->firstname;
$userfrom->lastname = !empty($CFG->badges_defaultissuername) ? '' : $admin->lastname;
$userfrom->maildisplay = true;
if ($msgs = $DB->get_records_select('badge_issued', 'issuernotified IS NULL AND badgeid = ?', array($badge->id))) {
// Get badge creator.
$creator = $DB->get_record('user', array('id' => $badge->creator), '*', MUST_EXIST);
$creatorsubject = get_string('creatorsubject', 'badges', $badge->name);
$creatormessage = '';
// Put all messages in one digest.
foreach ($msgs as $msg) {
$issuedlink = html_writer::link(new moodle_url('/badges/badge.php', array('hash' => $msg->uniquehash)), $badge->name);
$recipient = $DB->get_record('user', array('id' => $msg->userid), '*', MUST_EXIST);
$a = new stdClass();
$a->user = fullname($recipient);
$a->link = $issuedlink;
$creatormessage .= get_string('creatorbody', 'badges', $a);
$DB->set_field('badge_issued', 'issuernotified', time(), array('badgeid' => $msg->badgeid, 'userid' => $msg->userid));
}
// Create a message object.
$eventdata = new stdClass();
$eventdata->component = 'moodle';
$eventdata->name = 'instantmessage';
$eventdata->userfrom = $userfrom;
$eventdata->userto = $creator;
$eventdata->notification = 1;
$eventdata->subject = $creatorsubject;
$eventdata->fullmessage = $creatormessage;
$eventdata->fullmessageformat = FORMAT_PLAIN;
$eventdata->fullmessagehtml = format_text($creatormessage, FORMAT_HTML);
$eventdata->smallmessage = '';
message_send($eventdata);
}
}
+146
View File
@@ -0,0 +1,146 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Editing badge details, criteria, messages
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->dirroot . '/badges/edit_form.php');
$badgeid = required_param('id', PARAM_INT);
$action = optional_param('action', 'details', PARAM_TEXT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
require_capability('moodle/badges:configuredetails', $context);
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$currenturl = new moodle_url('/badges/edit.php', array('id' => $badge->id, 'action' => $action));
$PAGE->set_context($context);
$PAGE->set_url($currenturl);
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
// Set up navigation and breadcrumbs.
navigation_node::override_active_url($navurl);
$PAGE->navbar->add($badge->name);
$output = $PAGE->get_renderer('core', 'badges');
$statusmsg = '';
$errormsg = '';
$badge->message = clean_text($badge->message, FORMAT_HTML);
$editoroptions = array(
'subdirs' => 0,
'maxbytes' => 0,
'maxfiles' => 0,
'changeformat' => 0,
'context' => $context,
'noclean' => false,
'trusttext' => false
);
$badge = file_prepare_standard_editor($badge, 'message', $editoroptions, $context);
$form_class = 'edit_' . $action . '_form';
$form = new $form_class($currenturl, array('badge' => $badge, 'action' => $action, 'editoroptions' => $editoroptions));
if ($form->is_cancelled()) {
redirect(new moodle_url('/badges/overview.php', array('id' => $badgeid)));
} else if ($form->is_submitted() && $form->is_validated() && ($data = $form->get_data())) {
if ($action == 'details') {
$badge->name = $data->name;
$badge->description = $data->description;
$badge->usermodified = $USER->id;
$badge->issuername = $data->issuername;
$badge->issuerurl = $data->issuerurl;
$badge->issuercontact = $data->issuercontact;
$badge->expiredate = ($data->expiry == 1) ? $data->expiredate : null;
$badge->expireperiod = ($data->expiry == 2) ? $data->expireperiod : null;
// Need to unset message_editor options to avoid errors on form edit.
unset($badge->messageformat);
unset($badge->message_editor);
if ($badge->save()) {
badges_process_badge_image($badge, $form->save_temp_file('image'));
$form->set_data($badge);
$statusmsg = get_string('changessaved');
} else {
$errormsg = get_string('error:save', 'badges');
}
} else if ($action == 'message') {
// Calculate next message cron if form data is different from original badge data.
if ($data->notification != $badge->notification) {
if ($data->notification > BADGE_MESSAGE_ALWAYS) {
$badge->nextcron = badges_calculate_message_schedule($data->notification);
} else {
$badge->nextcron = null;
}
}
$badge->message = clean_text($data->message_editor['text'], FORMAT_HTML);
$badge->messagesubject = $data->messagesubject;
$badge->notification = $data->notification;
$badge->attachment = $data->attachment;
unset($badge->messageformat);
unset($badge->message_editor);
if ($badge->save()) {
$statusmsg = get_string('changessaved');
} else {
$errormsg = get_string('error:save', 'badges');
}
}
}
echo $OUTPUT->header();
echo $OUTPUT->heading(print_badge_image($badge, $context, 'small') . ' ' . $badge->name);
if ($errormsg !== '') {
echo $OUTPUT->notification($errormsg);
} else if ($statusmsg !== '') {
echo $OUTPUT->notification($statusmsg, 'notifysuccess');
}
echo $output->print_badge_status_box($badge);
$output->print_badge_tabs($badgeid, $context, $action);
$form->display();
echo $OUTPUT->footer();
+241
View File
@@ -0,0 +1,241 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form classes for editing badges
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . '/formslib.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->libdir . '/filelib.php');
/**
* Form to edit badge details.
*
*/
class edit_details_form extends moodleform {
/**
* Defines the form
*/
public function definition() {
global $CFG;
$mform = $this->_form;
$badge = (isset($this->_customdata['badge'])) ? $this->_customdata['badge'] : false;
$action = $this->_customdata['action'];
$mform->addElement('header', 'badgedetails', get_string('badgedetails', 'badges'));
$mform->addElement('text', 'name', get_string('name'), array('size' => '70'));
// Using PARAM_FILE to avoid problems later when downloading badge files.
$mform->setType('name', PARAM_FILE);
$mform->addRule('name', null, 'required');
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$mform->addElement('textarea', 'description', get_string('description', 'badges'), 'wrap="virtual" rows="8" cols="70"');
$mform->setType('description', PARAM_CLEANHTML);
$mform->addRule('description', null, 'required');
$str = $action == 'new' ? get_string('badgeimage', 'badges') : get_string('newimage', 'badges');
$imageoptions = array('maxbytes' => 262144, 'accepted_types' => array('web_image'));
$mform->addElement('filepicker', 'image', $str, null, $imageoptions);
if ($action == 'new') {
$mform->addRule('image', null, 'required');
} else {
$currentimage = $mform->createElement('static', 'currentimage', get_string('currentimage', 'badges'));
$mform->insertElementBefore($currentimage, 'image');
}
$mform->addHelpButton('image', 'badgeimage', 'badges');
$mform->addElement('header', 'issuerdetails', get_string('issuerdetails', 'badges'));
$mform->addElement('text', 'issuername', get_string('name'), array('size' => '70'));
$mform->setType('issuername', PARAM_NOTAGS);
$mform->addRule('issuername', null, 'required');
$mform->setDefault('issuername', $CFG->badges_defaultissuername);
$mform->addHelpButton('issuername', 'issuername', 'badges');
$mform->addElement('text', 'issuercontact', get_string('contact', 'badges'), array('size' => '70'));
$mform->setDefault('issuercontact', $CFG->badges_defaultissuercontact);
$mform->setType('issuercontact', PARAM_EMAIL);
$mform->addRule('issuercontact', get_string('invalidemail', 'moodle'), 'email', null, 'client', true);
$mform->addHelpButton('issuercontact', 'contact', 'badges');
$mform->addElement('header', 'issuancedetails', get_string('issuancedetails', 'badges'));
$issuancedetails = array();
$issuancedetails[] =& $mform->createElement('radio', 'expiry', '', get_string('never', 'badges'), 0);
$issuancedetails[] =& $mform->createElement('static', 'none_break', null, '<br/>');
$issuancedetails[] =& $mform->createElement('radio', 'expiry', '', get_string('fixed', 'badges'), 1);
$issuancedetails[] =& $mform->createElement('date_selector', 'expiredate', '');
$issuancedetails[] =& $mform->createElement('static', 'expirydate_break', null, '<br/>');
$issuancedetails[] =& $mform->createElement('radio', 'expiry', '', get_string('relative', 'badges'), 2);
$issuancedetails[] =& $mform->createElement('duration', 'expireperiod', '', array('defaultunit' => 86400, 'optional' => false));
$issuancedetails[] =& $mform->createElement('static', 'expiryperiods_break', null, get_string('after', 'badges'));
$mform->addGroup($issuancedetails, 'expirydategr', get_string('expirydate', 'badges'), array(' '), false);
$mform->addHelpButton('expirydategr', 'expirydate', 'badges');
$mform->setDefault('expiry', 0);
$mform->setDefault('expiredate', strtotime('+1 year'));
$mform->disabledIf('expiredate[day]', 'expiry', 'neq', 1);
$mform->disabledIf('expiredate[month]', 'expiry', 'neq', 1);
$mform->disabledIf('expiredate[year]', 'expiry', 'neq', 1);
$mform->disabledIf('expireperiod[number]', 'expiry', 'neq', 2);
$mform->disabledIf('expireperiod[timeunit]', 'expiry', 'neq', 2);
// Set issuer URL.
// Have to parse URL because badge issuer origin cannot be a subfolder in wwwroot.
$url = parse_url($CFG->wwwroot);
$mform->addElement('hidden', 'issuerurl', $url['scheme'] . '://' . $url['host']);
$mform->setType('issuerurl', PARAM_URL);
$mform->addElement('hidden', 'action', $action);
$mform->setType('action', PARAM_TEXT);
if ($action == 'new') {
$this->add_action_buttons(true, get_string('createbutton', 'badges'));
} else {
// Add hidden fields.
$mform->addElement('hidden', 'id', $badge->id);
$mform->setType('id', PARAM_INT);
$this->add_action_buttons();
$this->set_data($badge);
// Freeze all elements if badge is active or locked.
if ($badge->is_active() || $badge->is_locked()) {
$mform->hardFreezeAllVisibleExcept(array());
}
}
}
/**
* Load in existing data as form defaults
*
* @param stdClass|array $default_values object or array of default values
*/
public function set_data($badge) {
$default_values = array();
parent::set_data($badge);
if (!empty($badge->expiredate)) {
$default_values['expiry'] = 1;
$default_values['expiredate'] = $badge->expiredate;
} else if (!empty($badge->expireperiod)) {
$default_values['expiry'] = 2;
$default_values['expireperiod'] = $badge->expireperiod;
}
$default_values['currentimage'] = print_badge_image($badge, $badge->get_context(), 'large');
parent::set_data($default_values);
}
/**
* Validates form data
*/
public function validation($data, $files) {
global $DB;
$errors = parent::validation($data, $files);
if ($data['expiry'] == 2 && $data['expireperiod'] <= 0) {
$errors['expirydategr'] = get_string('error:invalidexpireperiod', 'badges');
}
if ($data['expiry'] == 1 && $data['expiredate'] <= time()) {
$errors['expirydategr'] = get_string('error:invalidexpiredate', 'badges');
}
// Check for duplicate badge names.
if ($data['action'] == 'new') {
$duplicate = $DB->record_exists_select('badge', 'name = :name',
array('name' => $data['name']));
} else {
$duplicate = $DB->record_exists_select('badge', 'name = :name AND id != :badgeid',
array('name' => $data['name'], 'badgeid' => $data['id']));
}
if ($duplicate) {
$errors['name'] = get_string('error:duplicatename', 'badges');
}
return $errors;
}
}
/**
* Form to edit badge message.
*
*/
class edit_message_form extends moodleform {
public function definition() {
global $CFG, $OUTPUT;
$mform = $this->_form;
$badge = $this->_customdata['badge'];
$action = $this->_customdata['action'];
$editoroptions = $this->_customdata['editoroptions'];
// Add hidden fields.
$mform->addElement('hidden', 'id', $badge->id);
$mform->setType('id', PARAM_INT);
$mform->addElement('hidden', 'action', $action);
$mform->setType('action', PARAM_TEXT);
$mform->addElement('header', 'badgemessage', get_string('configuremessage', 'badges'));
$mform->addHelpButton('badgemessage', 'variablesubstitution', 'badges');
$mform->addElement('text', 'messagesubject', get_string('subject', 'badges'), array('size' => '70'));
$mform->setType('messagesubject', PARAM_TEXT);
$mform->addRule('messagesubject', null, 'required');
$mform->addRule('messagesubject', get_string('maximumchars', '', 255), 'maxlength', 255);
$mform->addElement('editor', 'message_editor', get_string('message', 'badges'), null, $editoroptions);
$mform->setType('message_editor', PARAM_RAW);
$mform->addRule('message_editor', null, 'required');
$mform->addElement('advcheckbox', 'attachment', get_string('attachment', 'badges'), '', null, array(0, 1));
$mform->addHelpButton('attachment', 'attachment', 'badges');
$options = array(
BADGE_MESSAGE_NEVER => get_string('never'),
BADGE_MESSAGE_ALWAYS => get_string('notifyevery', 'badges'),
BADGE_MESSAGE_DAILY => get_string('notifydaily', 'badges'),
BADGE_MESSAGE_WEEKLY => get_string('notifyweekly', 'badges'),
BADGE_MESSAGE_MONTHLY => get_string('notifymonthly', 'badges'),
);
$mform->addElement('select', 'notification', get_string('notification', 'badges'), $options);
$mform->addHelpButton('notification', 'notification', 'badges');
$this->add_action_buttons();
$this->set_data($badge);
}
public function validation($data, $files) {
$errors = parent::validation($data, $files);
return $errors;
}
}
+45
View File
@@ -0,0 +1,45 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Display details of an issued badge with criteria and evidence
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$json = required_param('badge', PARAM_RAW);
$PAGE->set_context(context_system::instance());
$output = $PAGE->get_renderer('core', 'badges');
$badge = new external_badge(unserialize($json));
$PAGE->set_url('/badges/external.php');
$PAGE->set_pagelayout('base');
$PAGE->set_title(get_string('issuedbadge', 'badges'));
echo $OUTPUT->header();
echo $output->render($badge);
echo $OUTPUT->footer();
+186
View File
@@ -0,0 +1,186 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Page for badges management
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$type = required_param('type', PARAM_INT);
$courseid = optional_param('id', 0, PARAM_INT);
$page = optional_param('page', 0, PARAM_INT);
$activate = optional_param('activate', 0, PARAM_INT);
$deactivate = optional_param('lock', 0, PARAM_INT);
$sortby = optional_param('sort', 'name', PARAM_ALPHA);
$sorthow = optional_param('dir', 'ASC', PARAM_ALPHA);
$confirm = optional_param('confirm', false, PARAM_BOOL);
$delete = optional_param('delete', 0, PARAM_INT);
$msg = optional_param('msg', '', PARAM_TEXT);
if (!in_array($sortby, array('name', 'status'))) {
$sortby = 'name';
}
if ($sorthow != 'ASC' and $sorthow != 'DESC') {
$sorthow = 'ASC';
}
if ($page < 0) {
$page = 0;
}
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$err = '';
$urlparams = array('sort' => $sortby, 'dir' => $sorthow, 'page' => $page);
if ($course = $DB->get_record('course', array('id' => $courseid))) {
$urlparams['type'] = $type;
$urlparams['id'] = $course->id;
} else {
$urlparams['type'] = $type;
}
$hdr = get_string('managebadges', 'badges');
$returnurl = new moodle_url('/badges/index.php', $urlparams);
$PAGE->set_url($returnurl);
if ($type == BADGE_TYPE_SITE) {
$title = get_string('sitebadges', 'badges');
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('admin');
$PAGE->set_heading($title . ': ' . $hdr);
navigation_node::override_active_url(new moodle_url('/badges/index.php', array('type' => BADGE_TYPE_SITE)));
} else {
require_login($course);
$title = get_string('coursebadges', 'badges');
$PAGE->set_context(context_course::instance($course->id));
$PAGE->set_pagelayout('course');
$PAGE->set_heading($course->fullname . ': ' . $hdr);
navigation_node::override_active_url(
new moodle_url('/badges/index.php', array('type' => BADGE_TYPE_COURSE, 'id' => $course->id))
);
}
if (!has_capability('moodle/badges:awardbadge', $PAGE->context)) {
redirect($CFG->wwwroot);
}
$PAGE->set_title($hdr);
$PAGE->requires->js('/badges/backpack.js');
$PAGE->requires->js_init_call('check_site_access', null, false);
$output = $PAGE->get_renderer('core', 'badges');
if ($delete && has_capability('moodle/badges:deletebadge', $PAGE->context)) {
$badge = new badge($delete);
if (!$confirm) {
echo $output->header();
echo $output->confirm(
get_string('delconfirm', 'badges', $badge->name),
new moodle_url($PAGE->url, array('delete' => $badge->id, 'confirm' => 1)),
$returnurl
);
echo $output->footer();
die();
} else {
require_sesskey();
$badge->delete();
redirect($returnurl);
}
}
if ($activate && has_capability('moodle/badges:configuredetails', $PAGE->context)) {
$badge = new badge($activate);
if (!$badge->has_criteria()) {
$err = get_string('error:cannotact', 'badges') . get_string('nocriteria', 'badges');
} else {
if ($badge->is_locked()) {
$badge->set_status(BADGE_STATUS_ACTIVE_LOCKED);
$msg = get_string('activatesuccess', 'badges');
} else {
$badge->set_status(BADGE_STATUS_ACTIVE);
$msg = get_string('activatesuccess', 'badges');
}
$returnurl->param('msg', $msg);
redirect($returnurl);
}
} else if ($deactivate && has_capability('moodle/badges:configuredetails', $PAGE->context)) {
$badge = new badge($deactivate);
if ($badge->is_locked()) {
$badge->set_status(BADGE_STATUS_INACTIVE_LOCKED);
$msg = get_string('deactivatesuccess', 'badges');
} else {
$badge->set_status(BADGE_STATUS_INACTIVE);
$msg = get_string('deactivatesuccess', 'badges');
}
$returnurl->param('msg', $msg);
redirect($returnurl);
}
echo $OUTPUT->header();
if ($type == BADGE_TYPE_SITE) {
echo $OUTPUT->heading_with_help($PAGE->heading, 'sitebadges', 'badges');
} else {
echo $OUTPUT->heading($PAGE->heading);
}
echo $OUTPUT->box('', 'notifyproblem hide', 'check_connection');
$totalcount = count(badges_get_badges($type, $courseid, '', '' , '', ''));
$records = badges_get_badges($type, $courseid, $sortby, $sorthow, $page, BADGE_PERPAGE);
if ($totalcount) {
echo $output->heading(get_string('badgestoearn', 'badges', $totalcount), 4);
if ($course && $course->startdate > time()) {
echo $OUTPUT->box(get_string('error:notifycoursedate', 'badges'), 'generalbox notifyproblem');
}
if ($err !== '') {
echo $OUTPUT->notification($err, 'notifyproblem');
}
if ($msg !== '') {
echo $OUTPUT->notification($msg, 'notifysuccess');
}
$badges = new badge_management($records);
$badges->sort = $sortby;
$badges->dir = $sorthow;
$badges->page = $page;
$badges->perpage = BADGE_PERPAGE;
$badges->totalcount = $totalcount;
echo $output->render($badges);
} else {
echo $output->notification(get_string('nobadges', 'badges'));
echo $OUTPUT->single_button(new moodle_url('newbadge.php', array('type' => $type, 'id' => $courseid)),
get_string('newbadge', 'badges'));
}
echo $OUTPUT->footer();
+242
View File
@@ -0,0 +1,242 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* 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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once(dirname(dirname(dirname(__FILE__))) . '/config.php');
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;
}
+119
View File
@@ -0,0 +1,119 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* External backpack library.
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/filelib.php');
// Adopted from https://github.com/jbkc85/openbadges-class-php.
// Author Jason Cameron <[email protected]>.
class OpenBadgesBackpackHandler {
private $backpack;
private $email;
private $backpackuid = 0;
private $backpackgid = 0;
public function __construct($record) {
$this->backpack = $record->backpackurl;
$this->email = $record->email;
$this->backpackuid = isset($record->backpackuid) ? $record->backpackuid : 0;
$this->backpackgid = isset($record->backpackgid) ? $record->backpackgid : 0;
}
public function curl_request($action) {
$curl = new curl();
switch($action) {
case 'user':
$url = $this->backpack."/displayer/convert/email";
$param = array('email' => $this->email);
break;
case 'groups':
$url = $this->backpack . '/displayer/' . $this->backpackuid . '/groups.json';
break;
case 'badges':
$url = $this->backpack . '/displayer/' . $this->backpackuid . '/group/'. $this->backpackgid . '.json';
break;
}
$options = array(
'FRESH_CONNECT' => true,
'RETURNTRANSFER' => true,
'FORBID_REUSE' => true,
'HEADER' => 0,
'CONNECTTIMEOUT_MS' => 3000,
);
if ($action == 'user') {
$out = $curl->post($url, $param, $options);
} else {
$out = $curl->get($url, array(), $options);
}
return json_decode($out);
}
private function check_status($status) {
switch($status) {
case "missing":
$response = array(
'status' => $status,
'message' => get_string('error:nosuchuser', 'badges')
);
return $response;
break;
}
}
public function get_groups() {
$json = $this->curl_request('user', $this->email);
if (isset($json->status)) {
if ($json->status != 'okay') {
return $this->check_status($json->status);
} else {
$this->backpackuid = $json->userId;
return $this->curl_request('groups');
}
}
}
public function get_badges() {
$json = $this->curl_request('user', $this->email);
if (isset($json->status)) {
if ($json->status != 'okay') {
return $this->check_status($json->status);
} else {
return $this->curl_request('badges');
}
}
}
public function get_url() {
return $this->backpack;
}
}
+155
View File
@@ -0,0 +1,155 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Baking badges library.
*
* @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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
/**
* Information on PNG file chunks can be found at http://www.w3.org/TR/PNG/#11Chunks
* Some other info on PNG that I used http://garethrees.org/2007/11/14/pngcrush/
*
* Example of use:
* $png = new PNG_MetaDataHandler('file.png');
*
* if ($png->check_chunks("tEXt", "openbadge")) {
* $newcontents = $png->add_chunks("tEXt", "openbadge", 'http://some.public.url/to.your.assertion.file');
* }
*
* file_put_contents('file.png', $newcontents);
*/
class PNG_MetaDataHandler
{
/** @var string File content as a string */
private $_contents;
/** @var int Length of the image file */
private $_size;
/** @var array Variable for storing parsed chunks */
private $_chunks;
/**
* Prepares file for handling metadata.
* Verifies that this file is a valid PNG file.
* Unpacks file chunks and reads them into an array.
*
* @param string $contents File content as a string
*/
public function __construct($contents) {
$this->_contents = $contents;
$png_signature = pack("C8", 137, 80, 78, 71, 13, 10, 26, 10);
// Read 8 bytes of PNG header and verify.
$header = substr($this->_contents, 0, 8);
if ($header != $png_signature) {
debugging('This is not a valid PNG image');
}
$this->_size = strlen($this->_contents);
$this->_chunks = array();
// Skip 8 bytes of IHDR image header.
$position = 8;
do {
$chunk = @unpack('Nsize/a4type', substr($this->_contents, $position, 8));
$this->_chunks[$chunk['type']][] = substr($this->_contents, $position + 8, $chunk['size']);
// Skip 12 bytes chunk overhead.
$position += $chunk['size'] + 12;
} while ($position < $this->_size);
}
/**
* Checks if a key already exists in the chunk of said type.
* We need to avoid writing same keyword into file chunks.
*
* @param string $type Chunk type, like iTXt, tEXt, etc.
* @param string $check Keyword that needs to be checked.
*
* @return boolean (true|false) True if file is safe to write this keyword, false otherwise.
*/
public function check_chunks($type, $check) {
if (array_key_exists($type, $this->_chunks)) {
foreach (array_keys($this->_chunks[$type]) as $typekey) {
list($key, $data) = explode("\0", $this->_chunks[$type][$typekey]);
if (strcmp($key, $check) == 0) {
debugging('Key "' . $check . '" already exists in "' . $type . '" chunk.');
return false;
}
}
}
return true;
}
/**
* Adds a chunk with keyword and data to the file content.
* Chunk is added to the end of the file, before IEND image trailer.
*
* @param string $type Chunk type, like iTXt, tEXt, etc.
* @param string $key Keyword that needs to be added.
* @param string $value Currently an assertion URL that is added to an image metadata.
*
* @return string $result File content with a new chunk as a string. Can be used in file_put_contents() to write to a file.
*/
public function add_chunks($type, $key, $value) {
if (strlen($key) > 79) {
debugging('Key is too big');
}
if ($type == 'iTXt') {
// iTXt International textual data.
// Keyword: 1-79 bytes (character string)
// Null separator: 1 byte
// Compression flag: 1 byte
// Compression method: 1 byte
// Language tag: 0 or more bytes (character string)
// Null separator: 1 byte
// Translated keyword: 0 or more bytes
// Null separator: 1 byte
// Text: 0 or more bytes
$data = $key . "\000'json'\0''\0\"{'method': 'hosted', 'assertionUrl': '" . $value . "'}\"";
} else {
// tEXt Textual data.
// Keyword: 1-79 bytes (character string)
// Null separator: 1 byte
// Text: n bytes (character string)
$data = $key . "\0" . $value;
}
$crc = pack("N", crc32($type . $data));
$len = pack("N", strlen($data));
// Chunk format: length + type + data + CRC.
// CRC is a CRC-32 computed over the chunk type and chunk data.
$newchunk = $len . $type . $data . $crc;
$result = substr($this->_contents, 0, $this->_size - 12)
. $newchunk
. substr($this->_contents, $this->_size - 12, 12);
return $result;
}
}
+164
View File
@@ -0,0 +1,164 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* User backpack settings page.
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->dirroot . '/badges/backpack_form.php');
require_once($CFG->dirroot . '/badges/lib/backpacklib.php');
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$context = context_user::instance($USER->id);
require_capability('moodle/badges:manageownbadges', $context);
$clear = optional_param('clear', false, PARAM_BOOL);
if (!$CFG->badges_allowexternalbackpack) {
redirect($CFG->wwwroot);
}
$PAGE->set_url(new moodle_url('/badges/mybackpack.php'));
$PAGE->set_context($context);
$title = get_string('mybackpack', 'badges');
$PAGE->set_title($title);
$PAGE->set_heading($title);
$PAGE->set_pagelayout('mydashboard');
navigation_node::override_active_url(new moodle_url('/badges/mybadges.php'));
$PAGE->navbar->add(get_string('mybackpack', 'badges'));
if ($clear) {
$DB->delete_records('badge_backpack', array('userid' => $USER->id));
redirect(new moodle_url('/badges/mybadges.php'));
}
$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
if ($backpack) {
$bp = new OpenBadgesBackpackHandler($backpack);
$request = $bp->get_groups();
if (empty($request->groups)) {
unset($SESSION->badgesparams);
redirect(new moodle_url('/badges/mybadges.php'), get_string('error:nogroups', 'badges'), 20);
}
$params = array(
'data' => $backpack,
'backpackuid' => $request->userId,
'groups' => $request->groups
);
$groupform = new edit_backpack_group_form(new moodle_url('/badges/mybackpack.php'), $params);
if ($groupform->is_cancelled()) {
redirect(new moodle_url('/badges/mybadges.php'));
} else if ($groupdata = $groupform->get_data()) {
$obj = new stdClass();
$obj->userid = $groupdata->userid;
$obj->email = $groupdata->email;
$obj->backpackurl = $groupdata->backpackurl;
$obj->backpackuid = $groupdata->backpackuid;
$obj->backpackgid = $groupdata->backpackgid;
$obj->autosync = 0;
$obj->password = '';
if ($rec = $DB->get_record('badge_backpack', array('userid' => $groupdata->userid))) {
$obj->id = $rec->id;
$DB->update_record('badge_backpack', $obj);
} else {
$DB->insert_record('badge_backpack', $obj);
}
redirect(new moodle_url('/badges/mybadges.php'));
}
echo $OUTPUT->header();
$groupform->display();
echo $OUTPUT->footer();
die();
} else {
$form = new edit_backpack_form();
if ($form->is_cancelled()) {
redirect(new moodle_url('/badges/mybadges.php'));
} else if (($data = $form->get_data()) || !empty($SESSION->badgesparams)) {
if (empty($SESSION->badgesparams)) {
$bp = new OpenBadgesBackpackHandler($data);
$request = $bp->get_groups();
// If there is an error, start over.
if (is_array($request) && $request['status'] == 'missing') {
unset($SESSION->badgesparams);
redirect(new moodle_url('/badges/mybackpack.php'), $request['message'], 10);
} else if (empty($request->groups)) {
unset($SESSION->badgesparams);
redirect(new moodle_url('/badges/mybadges.php'), get_string('error:nogroups', 'badges'), 20);
}
$params = array(
'data' => $data,
'backpackuid' => $request->userId,
'groups' => $request->groups
);
$SESSION->badgesparams = $params;
}
$groupform = new edit_backpack_group_form(new moodle_url('/badges/mybackpack.php', array('addgroups' => true)), $SESSION->badgesparams);
if ($groupform->is_cancelled()) {
unset($SESSION->badgesparams);
redirect(new moodle_url('/badges/mybadges.php'));
} else if ($groupdata = $groupform->get_data()) {
$obj = new stdClass();
$obj->userid = $groupdata->userid;
$obj->email = $groupdata->email;
$obj->backpackurl = $groupdata->backpackurl;
$obj->backpackuid = $groupdata->backpackuid;
$obj->backpackgid = $groupdata->backpackgid;
$obj->autosync = 0;
$obj->password = '';
if ($rec = $DB->get_record('badge_backpack', array('userid' => $groupdata->userid))) {
$obj->id = $rec->id;
$DB->update_record('badge_backpack', $obj);
} else {
$DB->insert_record('badge_backpack', $obj);
}
unset($SESSION->badgesparams);
redirect(new moodle_url('/badges/mybadges.php'));
}
echo $OUTPUT->header();
$groupform->display();
echo $OUTPUT->footer();
die();
}
echo $OUTPUT->header();
$form->display();
echo $OUTPUT->footer();
}
+116
View File
@@ -0,0 +1,116 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Displays user badges for badges management in own profile
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$page = optional_param('page', 0, PARAM_INT);
$search = optional_param('search', '', PARAM_CLEAN);
$clearsearch = optional_param('clearsearch', '', PARAM_TEXT);
$download = optional_param('download', 0, PARAM_INT);
$hash = optional_param('hash', '', PARAM_ALPHANUM);
$downloadall = optional_param('downloadall', false, PARAM_BOOL);
$hide = optional_param('hide', 0, PARAM_INT);
$show = optional_param('show', 0, PARAM_INT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
if (isguestuser()) {
die();
}
if ($page < 0) {
$page = 0;
}
if ($clearsearch) {
$search = '';
}
if ($hide) {
require_sesskey();
$DB->set_field('badge_issued', 'visible', 0, array('id' => $hide));
} else if ($show) {
require_sesskey();
$DB->set_field('badge_issued', 'visible', 1, array('id' => $show));
} else if ($download && $hash) {
require_sesskey();
$badge = new badge($download);
$name = str_replace(' ', '_', $badge->name) . '.png';
ob_start();
$file = badges_bake($hash, $download);
header('Content-Type: image/png');
header('Content-Disposition: attachment; filename="'. $name .'"');
readfile($file);
ob_flush();
} else if ($downloadall) {
require_sesskey();
ob_start();
badges_download($USER->id);
ob_flush();
}
$context = context_user::instance($USER->id);
require_capability('moodle/badges:manageownbadges', $context);
$url = new moodle_url('/badges/mybadges.php');
$PAGE->set_url($url);
$PAGE->set_context($context);
$title = get_string('mybadges', 'badges');
$PAGE->set_title($title);
$PAGE->set_heading($title);
$PAGE->set_pagelayout('mydashboard');
// TODO: Better way of pushing badges to Mozilla backpack?
if ($CFG->badges_allowexternalbackpack) {
$PAGE->requires->js(new moodle_url('http://backpack.openbadges.org/issuer.js'), true);
$PAGE->requires->js('/badges/backpack.js', true);
}
$output = $PAGE->get_renderer('core', 'badges');
$badges = badges_get_user_badges($USER->id);
echo $OUTPUT->header();
$totalcount = count($badges);
$records = badges_get_user_badges($USER->id, null, $page, BADGE_PERPAGE, $search);
$userbadges = new badge_user_collection($records, $USER->id);
$userbadges->sort = 'dateissued';
$userbadges->dir = 'DESC';
$userbadges->page = $page;
$userbadges->perpage = BADGE_PERPAGE;
$userbadges->totalcount = $totalcount;
$userbadges->search = $search;
echo $output->render($userbadges);
echo $OUTPUT->footer();
+106
View File
@@ -0,0 +1,106 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* First step page for creating a new badge
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
require_once($CFG->dirroot . '/badges/edit_form.php');
$type = required_param('type', PARAM_INT);
$courseid = optional_param('id', 0, PARAM_INT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$title = get_string('create', 'badges');
if (($type == BADGE_TYPE_COURSE) && ($course = $DB->get_record('course', array('id' => $courseid)))) {
require_login($course);
$PAGE->set_context(context_course::instance($course->id));
$PAGE->set_pagelayout('course');
$PAGE->set_url('/badges/newbadge.php', array('type' => $type, 'id' => $course->id));
$PAGE->set_heading($course->fullname . ": " . $title);
$PAGE->set_title($course->fullname . ": " . $title);
} else {
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('admin');
$PAGE->set_url('/badges/newbadge.php', array('type' => $type));
$PAGE->set_heading($title);
$PAGE->set_title($title);
}
require_capability('moodle/badges:createbadge', $PAGE->context);
$PAGE->requires->js('/badges/backpack.js');
$PAGE->requires->js_init_call('check_site_access', null, false);
$fordb = new stdClass();
$fordb->id = null;
$form = new edit_details_form($PAGE->url, array('action' => 'new'));
if ($form->is_cancelled()) {
redirect(new moodle_url('/badges/index.php', array('type' => $type, 'id' => $courseid)));
} else if ($data = $form->get_data()) {
// Creating new badge here.
$now = time();
$fordb->name = $data->name;
$fordb->description = $data->description;
$fordb->timecreated = $now;
$fordb->timemodified = $now;
$fordb->usercreated = $USER->id;
$fordb->usermodified = $USER->id;
$fordb->image = 0;
$fordb->issuername = $data->issuername;
$fordb->issuerurl = $data->issuerurl;
$fordb->issuercontact = $data->issuercontact;
$fordb->expiredate = ($data->expiry == 1) ? $data->expiredate : null;
$fordb->expireperiod = ($data->expiry == 2) ? $data->expireperiod : null;
$fordb->type = $type;
$fordb->courseid = ($type == BADGE_TYPE_COURSE) ? $courseid : null;
$fordb->messagesubject = get_string('messagesubject', 'badges');
$fordb->message = get_string('messagebody', 'badges',
html_writer::link($CFG->wwwroot . '/badges/mybadges.php', get_string('mybadges', 'badges')));
$fordb->attachment = 1;
$fordb->notification = BADGE_MESSAGE_NEVER;
$fordb->status = BADGE_STATUS_INACTIVE;
$newid = $DB->insert_record('badge', $fordb, true);
$newbadge = new badge($newid);
badges_process_badge_image($newbadge, $form->save_temp_file('image'));
redirect(new moodle_url('/badges/criteria.php', array('id' => $newid)));
}
echo $OUTPUT->header();
echo $OUTPUT->box('', 'notifyproblem hide', 'check_connection');
$form->display();
echo $OUTPUT->footer();
+74
View File
@@ -0,0 +1,74 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Badge overview page
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = required_param('id', PARAM_INT);
$awards = optional_param('awards', '', PARAM_ALPHANUM);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$currenturl = new moodle_url('/badges/overview.php', array('id' => $badge->id));
$PAGE->set_context($context);
$PAGE->set_url($currenturl);
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
// Set up navigation and breadcrumbs.
navigation_node::override_active_url($navurl);
$PAGE->navbar->add($badge->name);
echo $OUTPUT->header();
echo $OUTPUT->heading(print_badge_image($badge, $context, 'small') . ' ' . $badge->name);
if ($awards == 'cron') {
echo $OUTPUT->notification(get_string('awardoncron', 'badges'), 'notifysuccess');
} else if ($awards != 0) {
echo $OUTPUT->notification(get_string('numawardstat', 'badges', $awards), 'notifysuccess');
}
$output = $PAGE->get_renderer('core', 'badges');
echo $output->print_badge_status_box($badge);
$output->print_badge_tabs($badgeid, $context, 'overview');
echo $output->print_badge_overview($badge, $context);
echo $OUTPUT->footer();
+107
View File
@@ -0,0 +1,107 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Badge awards information
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = required_param('id', PARAM_INT);
$sortby = optional_param('sort', 'dateissued', PARAM_ALPHA);
$sorthow = optional_param('dir', 'DESC', PARAM_ALPHA);
$page = optional_param('page', 0, PARAM_INT);
$updatepref = optional_param('updatepref', false, PARAM_BOOL);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
if (!in_array($sortby, array('firstname', 'lastname', 'dateissued'))) {
$sortby = 'dateissued';
}
if ($sorthow != 'ASC' and $sorthow != 'DESC') {
$sorthow = 'DESC';
}
if ($page < 0) {
$page = 0;
}
$badge = new badge($badgeid);
$context = $badge->get_context();
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type));
if ($badge->type == BADGE_TYPE_COURSE) {
require_login($badge->courseid);
$navurl = new moodle_url('/badges/index.php', array('type' => $badge->type, 'id' => $badge->courseid));
}
$PAGE->set_context($context);
$PAGE->set_url('/badges/recipients.php', array('id' => $badgeid, 'sort' => $sortby, 'dir' => $sorthow));
$PAGE->set_pagelayout('standard');
$PAGE->set_heading($badge->name);
$PAGE->set_title($badge->name);
$PAGE->navbar->add($badge->name);
navigation_node::override_active_url($navurl);
$output = $PAGE->get_renderer('core', 'badges');
echo $output->header();
echo $OUTPUT->heading(print_badge_image($badge, $context, 'small') . ' ' . $badge->name);
echo $output->print_badge_status_box($badge);
$output->print_badge_tabs($badgeid, $context, 'awards');
// Add button for badge manual award.
if ($badge->has_manual_award_criteria() && has_capability('moodle/badges:awardbadge', $context) && $badge->is_active()) {
$url = new moodle_url('/badges/award.php', array('id' => $badge->id));
echo $OUTPUT->box($OUTPUT->single_button($url, get_string('award', 'badges')), 'clearfix mdl-align');
}
$sql = "SELECT b.userid, b.dateissued, b.uniquehash, u.firstname, u.lastname
FROM {badge_issued} b INNER JOIN {user} u
ON b.userid = u.id
WHERE b.badgeid = :badgeid
ORDER BY $sortby $sorthow";
$totalcount = $DB->count_records('badge_issued', array('badgeid' => $badge->id));
if ($badge->has_awards()) {
$users = $DB->get_records_sql($sql, array('badgeid' => $badge->id), $page * BADGE_PERPAGE, BADGE_PERPAGE);
$recipients = new badge_recipients($users);
$recipients->sort = $sortby;
$recipients->dir = $sorthow;
$recipients->page = $page;
$recipients->perpage = BADGE_PERPAGE;
$recipients->totalcount = $totalcount;
echo $output->render($recipients);
} else {
echo $output->notification(get_string('noawards', 'badges'));
}
echo $output->footer();
+1013
View File
File diff suppressed because it is too large Load Diff
+188
View File
@@ -0,0 +1,188 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for badges
*
* @package core
* @subpackage badges
* @copyright 2013 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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . '/badgeslib.php');
class badges_testcase extends advanced_testcase {
protected $badgeid;
protected function setUp() {
global $DB;
$this->resetAfterTest(true);
$user = $this->getDataGenerator()->create_user();
$fordb = new stdClass();
$fordb->id = null;
$fordb->name = "Test badge";
$fordb->description = "Testing badges";
$fordb->timecreated = time();
$fordb->timemodified = time();
$fordb->usercreated = $user->id;
$fordb->usermodified = $user->id;
$fordb->image = 0;
$fordb->issuername = "Test issuer";
$fordb->issuerurl = "http://issuer-url.domain.co.nz";
$fordb->expiredate = null;
$fordb->expireperiod = null;
$fordb->type = BADGE_TYPE_SITE;
$fordb->courseid = null;
$fordb->messagesubject = "Test message subject";
$fordb->message = "Test message body";
$fordb->attachment = 1;
$fordb->notification = 0;
$fordb->status = BADGE_STATUS_INACTIVE;
$this->badgeid = $DB->insert_record('badge', $fordb, true);
}
public function test_create_badge() {
$badge = new badge($this->badgeid);
$this->assertInstanceOf('badge', $badge);
$this->assertEquals($this->badgeid, $badge->id);
}
public function test_clone_badge() {
$badge = new badge($this->badgeid);
$newid = $badge->make_clone();
$cloned_badge = new badge($newid);
$this->assertEquals($badge->image, $cloned_badge->image);
$this->assertEquals($badge->description, $cloned_badge->description);
$this->assertEquals($badge->issuercontact, $cloned_badge->issuercontact);
$this->assertEquals($badge->issuername, $cloned_badge->issuername);
$this->assertEquals($badge->issuerurl, $cloned_badge->issuerurl);
$this->assertEquals($badge->expiredate, $cloned_badge->expiredate);
$this->assertEquals($badge->expireperiod, $cloned_badge->expireperiod);
$this->assertEquals($badge->type, $cloned_badge->type);
$this->assertEquals($badge->courseid, $cloned_badge->courseid);
$this->assertEquals($badge->message, $cloned_badge->message);
$this->assertEquals($badge->messagesubject, $cloned_badge->messagesubject);
$this->assertEquals($badge->attachment, $cloned_badge->attachment);
$this->assertEquals($badge->notification, $cloned_badge->notification);
}
public function test_badge_status() {
$badge = new badge($this->badgeid);
$old_status = $badge->status;
$badge->set_status(BADGE_STATUS_ACTIVE);
$this->assertAttributeNotEquals($old_status, 'status', $badge);
$this->assertAttributeEquals(BADGE_STATUS_ACTIVE, 'status', $badge);
}
public function test_delete_badge() {
$badge = new badge($this->badgeid);
$badge->delete();
// We don't actually delete badges. We archive them.
$this->assertAttributeEquals(BADGE_STATUS_ARCHIVED, 'status', $badge);
}
public function test_create_badge_criteria() {
$badge = new badge($this->badgeid);
$criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id));
$criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
$this->assertCount(1, $badge->get_criteria());
$criteria_profile = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id));
$params = array('agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address');
$criteria_profile->save($params);
$this->assertCount(2, $badge->get_criteria());
}
public function test_delete_badge_criteria() {
$criteria_overall = award_criteria::build(array('criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $this->badgeid));
$criteria_overall->save(array('agg' => BADGE_CRITERIA_AGGREGATION_ALL));
$badge = new badge($this->badgeid);
$this->assertInstanceOf('award_criteria_overall', $badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]);
$badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]->delete();
$this->assertEmpty($badge->get_criteria());
}
public function test_badge_awards() {
$badge = new badge($this->badgeid);
$user1 = $this->getDataGenerator()->create_user();
$badge->issue($user1->id, true);
$this->assertTrue($badge->is_issued($user1->id));
$user2 = $this->getDataGenerator()->create_user();
$badge->issue($user2->id, true);
$this->assertTrue($badge->is_issued($user2->id));
$this->assertCount(2, $badge->get_awards());
}
public function data_for_message_from_template() {
return array(
array(
'This is a message with no variables',
array(), // no params
'This is a message with no variables'
),
array(
'This is a message with %amissing% variables',
array(), // no params
'This is a message with %amissing% variables'
),
array(
'This is a message with %one% variable',
array('one' => 'a single'),
'This is a message with a single variable'
),
array(
'This is a message with %one% %two% %three% variables',
array('one' => 'more', 'two' => 'than', 'three' => 'one'),
'This is a message with more than one variables'
),
array(
'This is a message with %three% %two% %one%',
array('one' => 'variables', 'two' => 'ordered', 'three' => 'randomly'),
'This is a message with randomly ordered variables'
),
array(
'This is a message with %repeated% %one% %repeated% of variables',
array('one' => 'and', 'repeated' => 'lots'),
'This is a message with lots and lots of variables'
),
);
}
/**
* @dataProvider data_for_message_from_template
*/
public function test_badge_message_from_template($message, $params, $result) {
$this->assertEquals(badge_message_from_template($message, $params), $result);
}
}
+46
View File
@@ -0,0 +1,46 @@
@badges
Feature: Add badges to the system
In order to give badges to users for their achievements
As an admin
I need to manage badges in the system
Background:
Given I am on homepage
And I log in as "admin"
@javascript
Scenario: Setting badges settings
Given I expand "Site administration" node
And I expand "Badges" node
And I follow "Badges settings"
And I fill in "Default badge issuer name" with "Test Badge Site"
And I fill in "Default badge issuer contact details" with "testuser@test-badge-site.com"
And I press "Save changes"
When I follow "Add a new badge"
Then the "issuercontact" field should match "testuser@test-badge-site.com" value
And the "issuername" field should match "Test Badge Site" value
@javascript
Scenario: Accessing the badges
Given I expand "Site pages" node
And I follow "Site badges"
Then I should see "There are no badges available."
@javascript
Scenario: Add a badge
Given I expand "Site administration" node
And I expand "Badges" node
And I follow "Add a new badge"
And I fill the moodle form with:
| Name | Test Badge |
| Description | Test badge description |
| issuername | Test Badge Site |
| issuercontact | testuser@test-badge-site.com |
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
When I press "Create badge"
Then I should see "Edit details"
And I should see "Test Badge"
And I should not see "Create badge"
And I follow "Manage badges"
And I should see "Number of badges available: 1"
And I should not see "There are no badges available."
+58
View File
@@ -0,0 +1,58 @@
@award_badges
Feature: Award badges
In order to award badges to users for their achievements
As an admin
I need to add criteria to badges in the system
Background:
Given I am on homepage
And I log in as "admin"
@javascript
Scenario: Add criteria
Given I expand "Site administration" node
And I expand "Badges" node
And I follow "Add a new badge"
And I fill the moodle form with:
| Name | Test Badge |
| Description | Test badge description |
| issuername | Test Badge Site |
| issuercontact | testuser@test-badge-site.com |
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
And I press "Create badge"
And I select "Profile completion" from "type"
And I wait "5" seconds
And I check "First name"
And I check "Email address"
When I press "Save"
Then I should see "Profile completion"
And I should see "First name"
And I should see "Email address"
And I should not see "Criteria for this badge have not been set up yet."
@javascript
Scenario: Earn badge
Given I expand "Site administration" node
And I expand "Badges" node
And I follow "Add a new badge"
And I fill the moodle form with:
| Name | Profile Badge |
| Description | Test badge description |
| issuername | Test Badge Site |
| issuercontact | testuser@test-badge-site.com |
And I upload "badges/tests/behat/badge.png" file to "Image" filepicker
And I press "Create badge"
And I select "Profile completion" from "type"
And I wait "5" seconds
And I check "Phone"
And I press "Save"
And I press "Enable access"
And I press "Continue"
And I expand "My profile settings" node
And I follow "Edit profile"
And I expand all fieldsets
And I fill in "Phone" with "123456789"
And I press "Update profile"
When I follow "My badges"
Then I should see "Profile Badge"
And I should not see "There are no badges available."
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

+106
View File
@@ -0,0 +1,106 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Displays available badges to a user
*
* @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 <[email protected]>
*/
require_once(dirname(dirname(__FILE__)) . '/config.php');
require_once($CFG->libdir . '/badgeslib.php');
$type = required_param('type', PARAM_INT);
$courseid = optional_param('id', 0, PARAM_INT);
$sortby = optional_param('sort', 'name', PARAM_ALPHA);
$sorthow = optional_param('dir', 'DESC', PARAM_ALPHA);
$page = optional_param('page', 0, PARAM_INT);
require_login();
if (empty($CFG->enablebadges)) {
print_error('badgesdisabled', 'badges');
}
if (!in_array($sortby, array('name', 'dateissued'))) {
$sortby = 'name';
}
if ($sorthow != 'ASC' && $sorthow != 'DESC') {
$sorthow = 'ACS';
}
if ($page < 0) {
$page = 0;
}
if ($course = $DB->get_record('course', array('id' => $courseid))) {
$PAGE->set_url('/badges/view.php', array('type' => $type, 'id' => $course->id, 'sort' => $sortby, 'dir' => $sorthow));
} else {
$PAGE->set_url('/badges/view.php', array('type' => $type, 'sort' => $sortby, 'dir' => $sorthow));
}
if ($type == BADGE_TYPE_SITE) {
$title = get_string('sitebadges', 'badges');
$PAGE->set_context(context_system::instance());
$PAGE->set_pagelayout('admin');
$PAGE->set_heading($title);
} else {
require_login($course);
$title = $course->fullname . ': ' . get_string('coursebadges', 'badges');
$PAGE->set_context(context_course::instance($course->id));
$PAGE->set_pagelayout('course');
$PAGE->set_heading($title);
// Fix course navigation.
$PAGE->navbar->ignore_active();
$PAGE->navbar->add($course->shortname, new moodle_url('/course/view.php', array('id' => $course->id)));
$PAGE->navbar->add(get_string('coursebadges', 'badges'));
}
$PAGE->set_title($title);
$output = $PAGE->get_renderer('core', 'badges');
echo $output->header();
echo $OUTPUT->heading($title);
$totalcount = count(badges_get_badges($type, $courseid, '', '', '', '', $USER->id));
$records = badges_get_badges($type, $courseid, $sortby, $sorthow, $page, BADGE_PERPAGE, $USER->id);
if ($totalcount) {
echo $output->heading(get_string('badgestoearn', 'badges', $totalcount), 4);
if ($course && $course->startdate > time()) {
echo $OUTPUT->box(get_string('error:notifycoursedate', 'badges'), 'generalbox notifyproblem');
}
$badges = new badge_collection($records);
$badges->sort = $sortby;
$badges->dir = $sorthow;
$badges->page = $page;
$badges->perpage = BADGE_PERPAGE;
$badges->totalcount = $totalcount;
echo $output->render($badges);
} else {
echo $output->notification(get_string('nobadges', 'badges'));
}
echo $output->footer();
+100
View File
@@ -0,0 +1,100 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Block for displaying earned local badges to users
*
* @package block_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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->libdir . "/badgeslib.php");
/**
* Displays recent badges
*/
class block_badges extends block_base {
public function init() {
$this->title = get_string('pluginname', 'block_badges');
}
public function instance_allow_multiple() {
return true;
}
public function has_config() {
return false;
}
public function instance_allow_config() {
return true;
}
public function applicable_formats() {
return array(
'admin' => false,
'site-index' => true,
'course-view' => false,
'mod' => false,
'my' => true
);
}
public function specialization() {
if (empty($this->config->title)) {
$this->title = get_string('pluginname', 'block_badges');
} else {
$this->title = $this->config->title;
}
}
public function get_content() {
global $USER, $PAGE, $CFG;
if ($this->content !== null) {
return $this->content;
}
if (empty($this->config)) {
$this->config = new stdClass();
}
// Number of badges to display.
if (empty($this->config->numberofbadges)) {
$this->config->numberofbadges = 10;
}
// Create empty content.
$this->content = new stdClass();
$this->content->text = '';
if (empty($CFG->enablebadges)) {
$this->content->text .= get_string('badgesdisabled', 'badges');
} else if ($badges = badges_get_user_badges($USER->id, null, 0, $this->config->numberofbadges)) {
$output = $PAGE->get_renderer('core', 'badges');
$this->content->text = $output->print_badges_list($badges, $USER->id, true);
} else {
$this->content->text .= get_string('nothingtodisplay', 'block_badges');
}
return $this->content;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* My latest badges block capabilities.
*
* @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 <[email protected]>
*/
$capabilities = array(
'block/badges:addinstance' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW,
),
'clonepermissionsfrom' => 'moodle/site:manageblocks'
),
'block/badges:myaddinstance' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW,
),
'clonepermissionsfrom' => 'moodle/my:manageblocks'
),
);
+38
View File
@@ -0,0 +1,38 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Form for editing badges block instances.
*
* @package block_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 <[email protected]>
*/
class block_badges_edit_form extends block_edit_form {
protected function specific_definition($mform) {
$mform->addElement('header', 'configheader', get_string('blocksettings', 'block'));
$numberofbadges = array('0' => get_string('all'));
for ($i = 1; $i <= 20; $i++) {
$numberofbadges[$i] = $i;
}
$mform->addElement('select', 'config_numberofbadges', get_string('numbadgestodisplay', 'block_badges'), $numberofbadges);
$mform->setDefault('config_numberofbadges', 10);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Language file for block "badges"
*
* @package block_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 <[email protected]>
*/
$string['pluginname'] = 'My latest badges';
$string['numbadgestodisplay'] = 'Number of latest badges to display';
$string['nothingtodisplay'] = 'You have no badges to display';
$string['badges:addinstance'] = 'Add a new My latest badges block';
$string['badges:myaddinstance'] = 'Add a new My latest badges block to the My Moodle page';
+30
View File
@@ -0,0 +1,30 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Version details
*
* @package block_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 <[email protected]>
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2012110600; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2012061700; // Requires this Moodle version.
$plugin->component = 'block_badges';
+337
View File
@@ -0,0 +1,337 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Language file for 'badges' component
*
* @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 <[email protected]>
*/
$string['actions'] = 'Actions';
$string['activate'] = 'Enable access';
$string['activatesuccess'] = 'Access to the badges was successfully enabled.';
$string['addbadgecriteria'] = 'Add badge criteria';
$string['addcriteria'] = 'Add criteria';
$string['addcriteriatext'] = 'To start adding criteria, please select one of the options from the drop down menu.';
$string['addcourse'] = 'Add courses';
$string['addcourse_help'] = 'Select all courses that should be added to this badge requirement. Hold CTRL key to select multiple items.';
$string['addtobackpack'] = 'Add to backpack';
$string['adminaward'] = 'As a site administrator, you can select a role to award this badge.';
$string['adminonly'] = 'This page is restricted to Site Administrators only';
$string['after'] = 'after the date of issue.';
$string['aggregationmethod'] = 'Aggregation method';
$string['all'] = 'All';
$string['allmethod'] = 'All of the selected conditions are met';
$string['allmethodactivity'] = 'All of the selected activities are complete';
$string['allmethodcourseset'] = 'All of the selected courses are complete';
$string['allmethodmanual'] = 'All of the selected roles award the badge';
$string['allmethodprofile'] = 'All of the selected profile fields have been completed';
$string['allowcoursebadges'] = 'Enable course badges';
$string['allowcoursebadges_desc'] = 'Allow badges to be created and awarded in course context.';
$string['allowexternalbackpack'] = 'Enable connection to external backpacks';
$string['allowexternalbackpack_desc'] = 'Allow users to set up connections and display badges from their external backpack providers.
Note: It is recommended to leave this option disabled if the web site cannot be accesed from the internet (e.g. because of the firewall).';
$string['any'] = 'Any';
$string['anymethod'] = 'Any of the selected conditions is met';
$string['anymethodactivity'] = 'Any of the selected activities is complete';
$string['anymethodcourseset'] = 'Any of the selected courses is complete';
$string['anymethodmanual'] = 'Any of the selected roles awards the badge';
$string['anymethodprofile'] = 'Any of the selected profile fields has been completed';
$string['attachment'] = 'Attach badge to message';
$string['attachment_help'] = 'If checked, an issued badge will be attached to the recepient\'s email for download';
$string['award'] = 'Award badge';
$string['awardedtoyou'] = 'Issued to me';
$string['awardoncron'] = 'Access to the badges was successfully enabled. Too many users can instantly earn this badge. To ensure site performance, this action will take some time to process.';
$string['awards'] = 'Recipients';
$string['backpackavailability'] = 'External badge verification';
$string['backpackavailability_help'] = 'For badge recipients to be able to prove they earned their badges from you, an external backpack service should be able to access your site and verify badges issued from it.
Your site does not currently appear to be accessible, which means that badges you have already issued or will issue in the future cannot be verified.
##Why am I seeing this message?
It may be that your firewall prevents access from users outside your network, your site is password protected, or you are running the site on a computer that is not available from the internet (such as a local development machine).
##Is this a problem?
You should fix this issue on any production site where you are planning to issue badges, otherwise the recipients will not be able to prove they earned their badges from you.
If your site is not yet live you can create and issue test badges, as long as the site is accessible before you go live.
##What if I can\'t make my whole site publically accessible?
The only URL required for verification is [your-site-url]/badges/assertion.php so if you are able to modify your firewall to allow external access to that file, badge verification will still work.';
$string['backpackbadges'] = 'You have {$a->totalbadges} badge(s) displayed from your backpack at <a href="{$a->backpackurl}">{$a->backpackurl}</a>.<br/>';
$string['backpackdetails'] = 'Backpack settings';
$string['badgedetails'] = 'Badge details';
$string['badgeimage'] = 'Image';
$string['badgeimage_help'] = 'This is an image that will be used when this badge is issued.
To add a new image, browse and select an image (in JPG or PNG format) then click "Save changes". The image will be cropped to a square and resized to match badge image requirements. ';
$string['badgesalt'] = 'Salt for hashing the recepient\'s email address';
$string['badgesalt_desc'] = 'Using a hash allows backpack services to confirm the badge earner without having to expose their email address. This setting should only use numbers and letters.';
$string['badgesdisabled'] = 'Badges are not enabled on this site.';
$string['badgesearned'] = 'Number of badges earned: {$a}';
$string['badgesettings'] = 'Badges settings';
$string['badgestatus_0'] = 'Not available to users';
$string['badgestatus_1'] = 'Available to users';
$string['badgestatus_2'] = 'Not available to users';
$string['badgestatus_3'] = 'Available to users';
$string['badgestatus_4'] = 'Archived';
$string['badgestoearn'] = 'Number of badges available: {$a}';
$string['badgesview'] = 'Course badges';
$string['badgeurl'] = 'Issued badge link';
$string['bawards'] = 'Recipients ({$a})';
$string['bcriteria'] = 'Criteria';
$string['bdetails'] = 'Edit details';
$string['bmessage'] = 'Message';
$string['boverview'] = 'Overview';
$string['bydate'] = ' complete by';
$string['clearsettings'] = 'Clear settings';
$string['completionnotenabled'] = 'Course completion is not enabled for this course, so it cannot be included in badge criteria.<br/>You can enable course completion in the course settings.';
$string['completioninfo'] = 'This badge was issued for completing: ';
$string['configenablebadges'] = 'When enabled, this feature lets you create badges and award them to site users.';
$string['configuremessage'] = 'Badge message';
$string['contact'] = 'Contact';
$string['contact_help'] = 'An email address associated with the badge issuer.';
$string['copyof'] = 'Copy of {$a}';
$string['coursecompletion'] = 'Learners must complete this course. ';
$string['coursebadges'] = 'Badges';
$string['create'] = 'New badge';
$string['createbutton'] = 'Create badge';
$string['creatorbody'] = '<p>{$a->user} has completed all badge requirements and has been awarded the badge. View issued badge at {$a->link} </p>';
$string['creatorsubject'] = '\'{$a}\' has been awarded!';
$string['criteriasummary'] = 'Criteria summary';
$string['criteria_descr'] = 'Learners are awarded this badge when they complete the following requirement: ';
$string['criteria_descr_bydate'] = ' by <em>{$a}</em> ';
$string['criteria_descr_grade'] = ' with minimum grade of <em>{$a}</em> ';
$string['criteria_descr_short0'] = 'Complete <strong>{$a}</strong> of: ';
$string['criteria_descr_short1'] = 'Complete <strong>{$a}</strong> of: ';
$string['criteria_descr_short2'] = 'Awarded by <strong>{$a}</strong> of: ';
$string['criteria_descr_short4'] = 'Complete the course ';
$string['criteria_descr_short5'] = 'Complete <strong>{$a}</strong> of: ';
$string['criteria_descr_short6'] = 'Complete <strong>{$a}</strong> of: ';
$string['criteria_descr_single_short1'] = 'Complete: ';
$string['criteria_descr_single_short2'] = 'Awarded by: ';
$string['criteria_descr_single_short4'] = 'Complete the course ';
$string['criteria_descr_single_short5'] = 'Complete: ';
$string['criteria_descr_single_short6'] = 'Complete: ';
$string['criteria_descr_single_1'] = 'The following activity has to be completed:';
$string['criteria_descr_single_2'] = 'This badge has to be awarded by a user with the following role:';
$string['criteria_descr_single_4'] = 'Learners must complete the course ';
$string['criteria_descr_single_5'] = 'The following course has to be completed:';
$string['criteria_descr_single_6'] = 'The following user profile field has to be completed:';
$string['criteria_descr_0'] = 'Learners are awarded this badge when they complete <strong>{$a}</strong> of the listed requirements.';
$string['criteria_descr_1'] = '<strong>{$a}</strong> of the following activities are completed:';
$string['criteria_descr_2'] = 'This badge has to be awarded by the users with <strong>{$a}</strong> of the following roles:';
$string['criteria_descr_4'] = 'Learners must complete the course ';
$string['criteria_descr_5'] = '<strong>{$a}</strong> of the following courses have to be completed:';
$string['criteria_descr_6'] = '<strong>{$a}</strong> of the following user profile fields have to be completed:';
$string['criteria_0'] = 'This badge is awarded when...';
$string['criteria_1'] = 'Activity completion';
$string['criteria_1_help'] = 'Allows a badge to be awarded to users based on the completion of a set of activities within a course.';
$string['criteria_2'] = 'Manual issue by role';
$string['criteria_2_help'] = 'Allows a badge to be awarded manually by users who have a particular role within the site or course.';
$string['criteria_3'] = 'Social participation';
$string['criteria_3_help'] = 'Social';
$string['criteria_4'] = 'Course completion';
$string['criteria_4_help'] = 'Allows a badge to be awarded to users who have completed the course. This criterion can have additional parameters such as minimum grade and date of course completion.';
$string['criteria_5'] = 'Completing a set of courses';
$string['criteria_5_help'] = 'Allows a badge to be awarded to users who have completed a set of courses. Each course can have additional parameters such as minimum grade and date of course completion. ';
$string['criteria_6'] = 'Profile completion';
$string['criteria_6_help'] = 'Allows a badge to be awarded to users for completing certain fields in their profile. You can select from default and custom profile fields that are available to users. ';
$string['criterror'] = 'Current parameters issues';
$string['criterror_help'] = 'This fieldset shows all parameters that were initially added to this badge requirement but are no longer available. It is recommended that you uncheck such parameters to make sure that learners can earn this badge in the future.';
$string['currentimage'] = 'Current image';
$string['currentstatus'] = 'Current status: ';
$string['dateawarded'] = 'Date issued';
$string['dateearned'] = 'Date: {$a}';
$string['day'] = 'Day(s)';
$string['deactivate'] = 'Disable access';
$string['deactivatesuccess'] = 'Access to the badges was successfully disabled.';
$string['defaultissuercontact'] = 'Default badge issuer contact details';
$string['defaultissuercontact_desc'] = 'An email address associated with the badge issuer.';
$string['defaultissuername'] = 'Default badge issuer name';
$string['defaultissuername_desc'] = 'Name of the issuing agent or authority.';
$string['delbadge'] = 'Delete badge';
$string['delconfirm'] = 'Are you sure that you want to delete badge \'{$a}\'?';
$string['delcritconfirm'] = 'Are you sure that you want to delete this criterion?';
$string['delparamconfirm'] = 'Are you sure that you want to delete this parameter?';
$string['description'] = 'Description';
$string['donotaward'] = 'Currently, this badge is not active, so it cannot be awarded to users. If you would like to award this badge, please set its status to active.';
$string['editsettings'] = 'Edit settings';
$string['enablebadges'] = 'Enable badges';
$string['error:backpacknotavailable'] = 'Your site is not accessible from the Internet, so any badges issued from this site cannot be verified by external backpack services';
$string['error:cannotact'] = 'Cannot activate the badge. ';
$string['error:cannotawardbadge'] = 'Cannot award badge to a user.';
$string['error:clone'] = 'Cannot clone the badge.';
$string['error:duplicatename'] = 'Badge with such name already exists in the system.';
$string['error:invalidbadgeurl'] = 'Invalid badge issuer URL format.';
$string['error:invalidcriteriatype'] = 'Invalid criteria type.';
$string['error:invalidexpiredate'] = 'Expiry date has to be in the future.';
$string['error:invalidexpireperiod'] = 'Expiry period cannot be negative or equal 0.';
$string['error:noactivities'] = 'There are no activities with completion criteria enabled in this course.';
$string['error:nocourses'] = 'Course completion is not enabled for any of the courses in this site, so none can be displayed. You can enable course completion in the course settings.';
$string['error:nogroups'] = '<p>There are no public collections of badges available in your backpack. </p>
<p>To display external badges, you will need to visit your backpack and make at least one collection of badges public. </p>
<p>If you already have backpack service connection established and your previously selected badge collection has been removed, clear these settings and try again.</p>';
$string['error:nopermissiontoview'] = 'You have no permissions to view badge recipients';
$string['error:nosuchbadge'] = 'Badge with id {$a} does not exist.';
$string['error:nosuchcourse'] = 'Warning: This course is no longer available.';
$string['error:nosuchfield'] = 'Warning: This user profile field is no longer available.';
$string['error:nosuchmod'] = 'Warning: This activity is no longer available.';
$string['error:nosuchrole'] = 'Warning: This role is no longer available.';
$string['error:nosuchuser'] = 'User with this email address does not have an account with the current backpack provider';
$string['error:notifycoursedate'] = 'Warning: Badges associated with course and activity completions will not be issued until the course start date.';
$string['error:parameter'] = 'Warning: At least one parameter should be selected to ensure correct badge issuing workflow.';
$string['error:save'] = 'Cannot save the badge.';
$string['evidence'] = 'Evidence';
$string['existingrecipients'] = 'Existing badge recipients';
$string['expired'] = 'Expired';
$string['expiredate'] = 'This badge expires on {$a}.';
$string['expireddate'] = 'This badge expired on {$a}.';
$string['expireperiod'] = 'This badge expires {$a} day(s) after being issued.';
$string['expireperiodh'] = 'This badge expires {$a} hour(s) after being issued.';
$string['expireperiodm'] = 'This badge expires {$a} minute(s) after being issued.';
$string['expireperiods'] = 'This badge expires {$a} second(s) after being issued.';
$string['expirydate'] = 'Expiry date';
$string['expirydate_help'] = 'Optionally, badges can expire on a specific date, or the date can be calculated based on the date when the badge was issued to a user. ';
$string['externalbadges'] = 'My badges from other web sites';
$string['externalbadgesp'] = 'Badges from other web sites:';
$string['externalbadges_help'] = 'This area allows to set up connection to an external backpack provider.
Currently, only <a href="http://backpack.openbadges.org">Mozilla OpenBadges Backpack</a> is supported. You need to sign up for a backpack service before trying to set up backpack connection on this page.
After such connection is successfully established, a number of badges from your backpack will be displayed on this page. A list of badges from a backpack along with their details and description can be found on a user profile page.';
$string['fixed'] = 'Fixed date';
$string['hidden'] = 'Hidden';
$string['hiddenbadge'] = 'Unfortunately, badge owner has not made this information available.';
$string['issuedbadge'] = 'Issued badge information';
$string['issuancedetails'] = 'Badge expiry';
$string['issuerdetails'] = 'Issuer details';
$string['issuername'] = 'Issuer name';
$string['issuername_help'] = 'Name of the issuing agent or authority.';
$string['issuerurl'] = 'Issuer URL';
$string['localbadges'] = 'My badges from {$a} web site';
$string['localbadgesh'] = 'My badges from this web site';
$string['localbadgesh_help'] = 'All badges earned within this web site by completing courses, course activities, and other requirements.
You can manage your badges here by making them public or private for your profile page.
You can download all of your badges or each badge separately and save them on your computer. Downloaded badges can be added to your external backpack service.';
$string['localbadgesp'] = 'Badges from {$a}:';
$string['makeprivate'] = 'Make private';
$string['makepublic'] = 'Make public';
$string['managebadges'] = 'Manage badges';
$string['message'] = 'Message body';
$string['messagebody'] = '<p>You have been awarded a badge "%badgename%"!</p>
<p>More information about this badge can be found at %badgelink%.</p>
<p>If there is no badge attached to this email, you can manage and download it from {$a} page.</p>';
$string['messagesubject'] = 'Congratulations! You just earned a badge!';
$string['method'] = 'This criterion is complete when...';
$string['mingrade'] = 'Minimum grade required';
$string['month'] = 'Month(s)';
$string['mybadges'] = 'My badges';
$string['mybackpack'] = 'My backpack settings';
$string['never'] = 'Never';
$string['newbadge'] = 'Add a new badge';
$string['newimage'] = 'New image';
$string['noawards'] = 'This badge has not been earned yet.';
$string['nobackpack'] = 'There is no backpack service connected to this account.<br/>';
$string['nobackpackbadges'] = 'There are no badges displayed from your backpack at <a href="{$a->backpackurl}">{$a->backpackurl}</a>.<br/>';
$string['nobadges'] = 'There are no badges available.';
$string['nocriteria'] = 'Criteria for this badge have not been set up yet.';
$string['noexpiry'] = 'This badge does not have an expiry date.';
$string['noparamstoadd'] = 'There are no additional parameters available to add to this badge requirement.';
$string['notacceptedrole'] = 'Your current role assignment is not among the roles that can manually issue this badge.<br/>
If you would like to see users who have already earned this badge, you can visit {$a} page. ';
$string['nothingtoadd'] = 'There are no available criteria to add.';
$string['notification'] = 'Notify badge creator';
$string['notification_help'] = 'This setting manages notifications sent to a badge creator to let them know that the badge has been issued.
The following options are available:
* **NEVER** Do not send notifications.
* **EVERY TIME** Send a notification every time this badge is awarded.
* **DAILY** Send notifications once a day.
* **WEEKLY** Send notifications once a week.
* **MONTHLY** Send notifications once a month.';
$string['notifydaily'] = 'Daily';
$string['notifyevery'] = 'Every time';
$string['notifymonthly'] = 'Monthly';
$string['notifyweekly'] = 'Weekly';
$string['numawards'] = 'This badge has been issued to <a href="{$a->link}">{$a->count}</a> user(s).';
$string['numawardstat'] = 'This badge has been issued {$a} user(s).';
$string['overallcrit'] = 'of the selected criteria are complete.';
$string['potentialrecipients'] = 'Potential badge recipients';
$string['recipients'] = 'Badge recipients';
$string['relative'] = 'Relative date';
$string['requiredcourse'] = 'At least one course should be added to the courseset criterion.';
$string['reviewbadge'] = 'Review badge criteria';
$string['reviewconfirm'] = '<p>This action will perform a check if any of the users have already completed all the requirements for \'{$a}\' badge?</p>
<p>Would you like to proceed?</p>';
$string['save'] = 'Save';
$string['searchname'] = 'Search by name';
$string['selectgroup'] = 'Select badge collection';
$string['selecting'] = 'With selected badges...';
$string['setup'] = 'Set up connection';
$string['sitebadges'] = 'Site badges';
$string['sitebadges_help'] = 'Site badges can only be awarded to users for site related activities. These include completing a set of courses or parts of user profiles. Site badges can also be issued manually by one user to another.
Badges for course related activities must be created at a course level. Course badges can be found under Course Administration > Badges';
$string['statusmessage_0'] = 'This badge is currently not available to users. Enable access if you want users to earn this badge. ';
$string['statusmessage_1'] = 'This badge is currently available to users. Disable access to make any changes. ';
$string['statusmessage_2'] = 'This badge is currently not available to users, and its criteria are locked. Enable access if you want users to earn this badge. ';
$string['statusmessage_3'] = 'This badge is currently available to users, and its criteria are locked. ';
$string['statusmessage_4'] = 'This badge is currently archived';
$string['status'] = 'Badge status';
$string['status_help'] = 'Status of a badge determines its behaviour in the system:
* **AVAILABLE** Means that this badge can be earned by users. While a badge is available to users, its criteria cannot be modified.
* **NOT AVAILABLE** Means that this badge is not available to users and cannot be earned or manually issued. If such badge has never been issued before, its criteria can be changed.
Once a badge has been issued to at least one user, it automatically becomes **LOCKED**. Locked badges can still be earned by users, but their criteria can no longer be changed. If you need to modify details or criteria of a locked badge, you can duplicate this badge and make all the required changes.
*Why do we lock badges?*
We want to make sure that all users complete the same requirements to earn a badge. Currently, it is not possible to revoke badges. If we allowed badges requirements to be modified all the time, we would most likely end up with users having the same badge for meeting completely different requirements.';
$string['subject'] = 'Message subject';
$string['variablesubstitution'] = 'Variable substitution in messages.';
$string['variablesubstitution_help'] = 'In a badge message, certain variables can be inserted into the subject and/or body of a message so that they will be replaced with real values when the message is sent. The variables should be inserted into the the text exactly as they are shown below. The following variables can be used:
%badgename%
: This will be replaced by the badge\'s full name.
%username%
: This will be replaced by the recipient\'s full name.
%badgelink%
: This will be replaced by the public URL with information about the issued badge.';
$string['viewbadge'] = 'View issued badge';
$string['visible'] = 'Visible';
$string['warnexpired'] = ' (This badge has expired!)';
$string['year'] = 'Year(s)';
+2
View File
@@ -41,6 +41,7 @@ $string['audienceeducators'] = 'Educators';
$string['audiencestudents'] = 'Students';
$string['audienceadmins'] = 'Moodle administrators';
$string['badurlformat'] = 'Bad URL format';
$string['badgesnumber'] = 'Number of badges ({$a})';
$string['community'] = 'Community';
$string['communityremoved'] = 'That course link has been removed from your list';
$string['confirmregistration'] = 'Confirm registration';
@@ -109,6 +110,7 @@ $string['hub'] = 'Hub';
$string['imageurl'] = 'Image URL';
$string['imageurl_help'] = 'This image will be displayed on the hub. This image must be available from the hub at any moment. The image should have a maximum size of {$a->width} X {$a->height}';
$string['information'] = 'Information';
$string['issuedbadgesnumber'] = 'Number of issued badges ({$a})';
$string['language'] = 'Language';
$string['language_help'] = 'The main language of this course.';
$string['lasttimechecked'] = 'Last time checked';
+1
View File
@@ -193,6 +193,7 @@ $string['backuptakealook'] = 'Please take a look at your backup logs in:
{$a}';
$string['backupuserfileshelp'] = 'Choose whether user files (eg profile images) should be included in automated backups';
$string['backupversion'] = 'Backup version';
$string['badges'] = 'Badges';
$string['block'] = 'Block';
$string['blockconfiga'] = 'Configuring a {$a} block';
$string['blockconfigbad'] = 'This block has not been implemented correctly and thus cannot provide a configuration interface.';
+12
View File
@@ -69,6 +69,18 @@ $string['backup:downloadfile'] = 'Download files from backup areas';
$string['backup:backuptargethub'] = 'Backup for hub';
$string['backup:backuptargetimport'] = 'Backup for import';
$string['backup:userinfo'] = 'Backup user data';
$string['badges:awardbadge'] = 'Award badge to a user';
$string['badges:createbadge'] = 'Create/duplicate badges';
$string['badges:configuredetails'] = 'Set up/edit badge details';
$string['badges:configurecriteria'] = 'Set up/edit criteria of earning a badge';
$string['badges:configuremessages'] = 'Configure badge messages';
$string['badges:deletebadge'] = 'Delete badges';
$string['badges:earnbadge'] = 'Earn badge';
$string['badges:manageglobalsettings'] = 'Manage badges global settings';
$string['badges:manageownbadges'] = 'View and manage own earned badges';
$string['badges:viewawarded'] = 'View users who earned a specific badge without being able to award a badge';
$string['badges:viewbadges'] = 'View available badges without earning them';
$string['badges:viewotherbadges'] = 'View public badges in other users\' profiles';
$string['block:edit'] = 'Edit a block\'s settings';
$string['block:view'] = 'View block';
$string['blog:associatecourse'] = 'Associate blog entries with courses';
+1279
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -1036,6 +1036,8 @@ class completion_info {
}
$transaction->allow_commit();
events_trigger('activity_completion_changed', $data);
if ($data->userid == $USER->id) {
$SESSION->completioncache[$cm->course][$cm->id] = $data;
// reset modinfo for user (no need to call rebuild_course_cache())
+5
View File
@@ -482,6 +482,11 @@ function cron_run() {
}
}
// Run badges review cron.
mtrace("Starting badges cron...");
require_once($CFG->dirroot . '/badges/cron.php');
badge_cron();
mtrace('done.');
// cleanup file trash - not very important
$fs = get_file_storage();
+143
View File
@@ -1878,5 +1878,148 @@ $capabilities = array(
'manager' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
)
),
// Badges.
'moodle/badges:manageglobalsettings' => array(
'riskbitmask' => RISK_DATALOSS | RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// View available badges without earning them.
'moodle/badges:viewbadges' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'user' => CAP_ALLOW,
'student' => CAP_ALLOW
)
),
// Manage badges on own private badges page.
'moodle/badges:manageownbadges' => array(
'riskbitmap' => RISK_SPAM | RISK_PERSONAL,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW
)
),
// View public badges in other users' profiles.
'moodle/badges:viewotherbadges' => array(
'riskbitmap' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_USER,
'archetypes' => array(
'user' => CAP_ALLOW
)
),
// Earn badge.
'moodle/badges:earnbadge' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'user' => CAP_ALLOW,
'student' => CAP_ALLOW,
)
),
// Create/duplicate badges.
'moodle/badges:createbadge' => array(
'riskbitmask' => RISK_CONFIG | RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// Delete badges.
'moodle/badges:deletebadge' => array(
'riskbitmask' => RISK_CONFIG | RISK_DATALOSS,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// Set up/edit badge details.
'moodle/badges:configuredetails' => array(
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// Set up/edit criteria of earning a badge.
'moodle/badges:configurecriteria' => array(
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// Configure badge messages.
'moodle/badges:configuremessages' => array(
'riskbitmask' => RISK_CONFIG,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// Award badge to a user.
'moodle/badges:awardbadge' => array(
'riskbitmask' => RISK_SPAM,
'captype' => 'write',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'coursecreator' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
'student' => CAP_PREVENT
)
),
// View users who earned a specific badge without being able to award a badge.
'moodle/badges:viewawarded' => array(
'riskbitmask' => RISK_PERSONAL,
'captype' => 'read',
'contextlevel' => CONTEXT_SYSTEM,
'archetypes' => array(
'manager' => CAP_ALLOW,
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
)
)
);
+18 -1
View File
@@ -50,7 +50,24 @@ $handlers = array(
'schedule' => 'cron',
'internal' => 0,
),
'course_completed' => array (
'handlerfile' => '/lib/badgeslib.php',
'handlerfunction' => 'badges_award_handle_course_criteria_review',
'schedule' => 'instant',
'internal' => 1,
),
'activity_completion_changed' => array (
'handlerfile' => '/lib/badgeslib.php',
'handlerfunction' => 'badges_award_handle_activity_criteria_review',
'schedule' => 'instant',
'internal' => 1,
),
'user_updated' => array (
'handlerfile' => '/lib/badgeslib.php',
'handlerfunction' => 'badges_award_handle_profile_criteria_review',
'schedule' => 'instant',
'internal' => 1,
),
/* no more here please, core should not consume any events!!!!!!! */
);
+139
View File
@@ -2932,5 +2932,144 @@
<INDEX NAME="usercourseaction" UNIQUE="false" FIELDS="userid, course, action"/>
</INDEXES>
</TABLE>
<TABLE NAME="badge" COMMENT="Defines badge">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="description" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="image" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="usercreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="issuername" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="issuerurl" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="issuercontact" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="expiredate" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="expireperiod" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="type" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="1 = site, 2 = course"/>
<FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="message" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="messagesubject" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="attachment" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Attach baked badge for download"/>
<FIELD NAME="notification" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="Message when badge is awarded"/>
<FIELD NAME="status" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Badge status: 0 = inactive, 1 = active, 2 = active+locked, 3 = inactive+locked, 4 = archived"/>
<FIELD NAME="nextcron" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id"/>
<KEY NAME="fk_usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="fk_usercreated" TYPE="foreign" FIELDS="usercreated" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="type" UNIQUE="false" FIELDS="type"/>
</INDEXES>
</TABLE>
<TABLE NAME="badge_criteria" COMMENT="Defines criteria for issuing badges">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true"/>
<FIELD NAME="badgeid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="criteriatype" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false" COMMENT="The criteria type we are aggregating"/>
<FIELD NAME="method" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="1 = all, 2 = any"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_badgeid" TYPE="foreign" FIELDS="badgeid" REFTABLE="badge" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="badgeid" UNIQUE="false" FIELDS="badgeid"/>
<INDEX NAME="criteriatype" UNIQUE="false" FIELDS="criteriatype"/>
<INDEX NAME="badgecriteriatype" UNIQUE="true" FIELDS="badgeid, criteriatype"/>
</INDEXES>
</TABLE>
<TABLE NAME="badge_criteria_param" COMMENT="Defines parameters for badges criteria">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true"/>
<FIELD NAME="critid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="value" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_critid" TYPE="foreign" FIELDS="critid" REFTABLE="badge_criteria" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="critid" UNIQUE="false" FIELDS="critid"/>
</INDEXES>
</TABLE>
<TABLE NAME="badge_issued" COMMENT="Defines issued badges">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="badgeid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="uniquehash" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="dateissued" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="dateexpire" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="visible" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="issuernotified" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_badgeid" TYPE="foreign" FIELDS="badgeid" REFTABLE="badge" REFFIELDS="id"/>
<KEY NAME="fk_userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="badgeid" UNIQUE="false" FIELDS="badgeid"/>
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
<INDEX NAME="badgeuser" UNIQUE="true" FIELDS="badgeid, userid"/>
</INDEXES>
</TABLE>
<TABLE NAME="badge_criteria_met" COMMENT="Defines criteria that were met for an issued badge">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="issuedid" TYPE="int" LENGTH="10" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="critid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="datemet" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_critid" TYPE="foreign" FIELDS="critid" REFTABLE="badge_criteria" REFFIELDS="id"/>
<KEY NAME="fk_userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="fk_issuedid" TYPE="foreign" FIELDS="issuedid" REFTABLE="badge_issued" REFFIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="badge_manual_award" COMMENT="Track manual award criteria for badges">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="badgeid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="recipientid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="issuerid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="issuerrole" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="datemet" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_badgeid" TYPE="foreign" FIELDS="id" REFTABLE="badge" REFFIELDS="id"/>
<KEY NAME="fk_recipientid" TYPE="foreign" FIELDS="recipientid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="fk_issuerid" TYPE="foreign" FIELDS="issuerid" REFTABLE="user" REFFIELDS="id"/>
<KEY NAME="fk_issuerrole" TYPE="foreign" FIELDS="issuerrole" REFTABLE="role" REFFIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="badge_backpack" COMMENT="Defines settings for connecting external backpack">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="email" TYPE="char" LENGTH="100" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="backpackurl" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="backpackuid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="backpackgid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="autosync" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="password" TYPE="char" LENGTH="50" NOTNULL="false" SEQUENCE="false"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
<KEY NAME="fk_userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="userid" UNIQUE="false" FIELDS="userid"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
+188
View File
@@ -1786,5 +1786,193 @@ function xmldb_main_upgrade($oldversion) {
upgrade_main_savepoint(true, 2013032600.04);
}
if ($oldversion < 2013040200.00) {
// Add openbadges tables.
// Define table 'badge' to be created.
$table = new xmldb_table('badge');
// Adding fields to table 'badge'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'id');
$table->add_field('description', XMLDB_TYPE_TEXT, null, null, null, null, null, 'name');
$table->add_field('image', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'description');
$table->add_field('timecreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'image');
$table->add_field('timemodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'timecreated');
$table->add_field('usercreated', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'timemodified');
$table->add_field('usermodified', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'usercreated');
$table->add_field('issuername', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'usermodified');
$table->add_field('issuerurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'issuername');
$table->add_field('issuercontact', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'issuerurl');
$table->add_field('expiredate', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'issuercontact');
$table->add_field('expireperiod', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'expiredate');
$table->add_field('type', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'expireperiod');
$table->add_field('courseid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'type');
$table->add_field('message', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'courseid');
$table->add_field('messagesubject', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'message');
$table->add_field('attachment', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'messagesubject');
$table->add_field('notification', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'attachment');
$table->add_field('status', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'notification');
$table->add_field('nextcron', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'status');
// Adding keys to table 'badge'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
$table->add_key('fk_usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
$table->add_key('fk_usercreated', XMLDB_KEY_FOREIGN, array('usercreated'), 'user', array('id'));
// Adding indexes to table 'badge'.
$table->add_index('type', XMLDB_INDEX_NOTUNIQUE, array('type'));
// Conditionally launch create table for 'badge'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_criteria' to be created.
$table = new xmldb_table('badge_criteria');
// Adding fields to table 'badge_criteria'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
$table->add_field('criteriatype', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'badgeid');
$table->add_field('method', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '1', 'criteriatype');
// Adding keys to table 'badge_criteria'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
// Adding indexes to table 'badge_criteria'.
$table->add_index('badgeid', XMLDB_INDEX_NOTUNIQUE, array('badgeid'));
$table->add_index('criteriatype', XMLDB_INDEX_NOTUNIQUE, array('criteriatype'));
$table->add_index('badgecriteriatype', XMLDB_INDEX_UNIQUE, array('badgeid', 'criteriatype'));
// Conditionally launch create table for 'badge_criteria'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_criteria_param' to be created.
$table = new xmldb_table('badge_criteria_param');
// Adding fields to table 'badge_criteria_param'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
$table->add_field('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'critid');
$table->add_field('value', XMLDB_TYPE_CHAR, '255', null, null, null, null, 'name');
// Adding keys to table 'badge_criteria_param'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));
// Adding indexes to table 'badge_criteria_param'.
$table->add_index('critid', XMLDB_INDEX_NOTUNIQUE, array('critid'));
// Conditionally launch create table for 'badge_criteria_param'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_issued' to be created.
$table = new xmldb_table('badge_issued');
// Adding fields to table 'badge_issued'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'badgeid');
$table->add_field('uniquehash', XMLDB_TYPE_TEXT, null, null, XMLDB_NOTNULL, null, null, 'userid');
$table->add_field('dateissued', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'uniquehash');
$table->add_field('dateexpire', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'dateissued');
$table->add_field('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'dateexpire');
$table->add_field('issuernotified', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'visible');
// Adding keys to table 'badge_issued'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('badgeid'), 'badge', array('id'));
$table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
// Adding indexes to table 'badge_issued'.
$table->add_index('badgeid', XMLDB_INDEX_NOTUNIQUE, array('badgeid'));
$table->add_index('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
$table->add_index('badgeuser', XMLDB_INDEX_UNIQUE, array('badgeid', 'userid'));
// Conditionally launch create table for 'badge_issued'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_criteria_met' to be created.
$table = new xmldb_table('badge_criteria_met');
// Adding fields to table 'badge_criteria_met'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('issuedid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, 'id');
$table->add_field('critid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuedid');
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'critid');
$table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'userid');
// Adding keys to table 'badge_criteria_met'
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_critid', XMLDB_KEY_FOREIGN, array('critid'), 'badge_criteria', array('id'));
$table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
$table->add_key('fk_issuedid', XMLDB_KEY_FOREIGN, array('issuedid'), 'badge_issued', array('id'));
// Conditionally launch create table for 'badge_criteria_met'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_manual_award' to be created.
$table = new xmldb_table('badge_manual_award');
// Adding fields to table 'badge_manual_award'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('badgeid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id');
$table->add_field('recipientid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'badgeid');
$table->add_field('issuerid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'recipientid');
$table->add_field('issuerrole', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerid');
$table->add_field('datemet', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'issuerrole');
// Adding keys to table 'badge_manual_award'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_badgeid', XMLDB_KEY_FOREIGN, array('id'), 'badge', array('id'));
$table->add_key('fk_recipientid', XMLDB_KEY_FOREIGN, array('recipientid'), 'user', array('id'));
$table->add_key('fk_issuerid', XMLDB_KEY_FOREIGN, array('issuerid'), 'user', array('id'));
$table->add_key('fk_issuerrole', XMLDB_KEY_FOREIGN, array('issuerrole'), 'role', array('id'));
// Conditionally launch create table for 'badge_manual_award'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Define table 'badge_backpack' to be created.
$table = new xmldb_table('badge_backpack');
// Adding fields to table 'badge_backpack'.
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null);
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, '0', 'id');
$table->add_field('email', XMLDB_TYPE_CHAR, '100', null, XMLDB_NOTNULL, null, null, 'userid');
$table->add_field('backpackurl', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, 'email');
$table->add_field('backpackuid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackurl');
$table->add_field('backpackgid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackuid');
$table->add_field('autosync', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, '0', 'backpackgid');
$table->add_field('password', XMLDB_TYPE_CHAR, '50', null, null, null, null, 'autosync');
// Adding keys to table 'badge_backpack'.
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('fk_userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
// Adding indexes to table 'badge_backpack'.
$table->add_index('userid', XMLDB_INDEX_NOTUNIQUE, array('userid'));
// Conditionally launch create table for 'badge_backpack'.
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
// Main savepoint reached.
upgrade_main_savepoint(true, 2013040200.00);
}
return true;
}
+25
View File
@@ -3758,7 +3758,32 @@ function file_pluginfile($relativepath, $forcedownload, $preview = null) {
} else {
send_file_not_found();
}
// ========================================================================================================================
} else if ($component === 'badges') {
require_once($CFG->libdir . '/badgeslib.php');
$badgeid = (int)array_shift($args);
$badge = new badge($badgeid);
$filename = array_pop($args);
if ($filearea === 'badgeimage') {
if ($filename !== 'f1' && $filename !== 'f2') {
send_file_not_found();
}
if (!$file = $fs->get_file($context->id, 'badges', 'badgeimage', $badge->id, '/', $filename.'.png')) {
send_file_not_found();
}
session_get_instance()->write_close();
send_stored_file($file, 60*60, 0, $forcedownload, array('preview' => $preview));
} else if ($filearea === 'userbadge' and $context->contextlevel == CONTEXT_USER) {
if (!$file = $fs->get_file($context->id, 'badges', 'userbadge', $badge->id, '/', $filename.'.png')) {
send_file_not_found();
}
session_get_instance()->write_close();
send_stored_file($file, 60*60, 0, true, array('preview' => $preview));
}
// ========================================================================================================================
} else if ($component === 'calendar') {
if ($filearea === 'event_description' and $context->contextlevel == CONTEXT_SYSTEM) {
+1
View File
@@ -8109,6 +8109,7 @@ function get_core_subsystems() {
'admin' => $CFG->admin,
'auth' => 'auth',
'backup' => 'backup/util/ui',
'badges' => 'badges',
'block' => 'blocks',
'blog' => 'blog',
'bulkusers' => NULL,
+49
View File
@@ -2182,6 +2182,12 @@ class global_navigation extends navigation_node {
$usernode->add(get_string('myfiles'), $url, self::TYPE_SETTING);
}
if ($CFG->enablebadges && $iscurrentuser &&
has_capability('moodle/badges:manageownbadges', context_user::instance($USER->id))) {
$url = new moodle_url('/badges/mybadges.php');
$usernode->add(get_string('mybadges', 'badges'), $url, self::TYPE_SETTING);
}
// Add a node to view the users notes if permitted
if (!empty($CFG->enablenotes) && has_any_capability(array('moodle/notes:manage', 'moodle/notes:view'), $coursecontext)) {
$url = new moodle_url('/notes/index.php',array('user'=>$user->id));
@@ -2432,6 +2438,39 @@ class global_navigation extends navigation_node {
$participants = $coursenode->add(get_string('participants'), null, self::TYPE_CONTAINER, get_string('participants'), 'participants');
}
// View course reports
if (has_capability('moodle/site:viewreports', $this->page->context)) { // basic capability for listing of reports
$reportnav = $coursenode->add(get_string('reports'), null, self::TYPE_CONTAINER, null, null, new pix_icon('i/stats', ''));
$coursereports = get_plugin_list('coursereport'); // deprecated
foreach ($coursereports as $report=>$dir) {
$libfile = $CFG->dirroot.'/course/report/'.$report.'/lib.php';
if (file_exists($libfile)) {
require_once($libfile);
$reportfunction = $report.'_report_extend_navigation';
if (function_exists($report.'_report_extend_navigation')) {
$reportfunction($reportnav, $course, $this->page->context);
}
}
}
$reports = get_plugin_list_with_function('report', 'extend_navigation_course', 'lib.php');
foreach ($reports as $reportfunction) {
$reportfunction($reportnav, $course, $this->page->context);
}
}
// Badges.
if ($CFG->enablebadges && has_capability('moodle/badges:viewbadges', $this->page->context)) {
$url = new moodle_url($CFG->wwwroot . '/badges/view.php',
array('type' => 2, 'id' => $course->id));
$coursenode->add(get_string('coursebadges', 'badges'), null,
navigation_node::TYPE_CONTAINER, null, 'coursebadges');
$coursenode->get('coursebadges')->add(get_string('badgesview', 'badges'), $url,
navigation_node::TYPE_SETTING, null, 'badgesview',
new pix_icon('i/badge', get_string('badgesview', 'badges')));
}
return true;
}
/**
@@ -2471,6 +2510,12 @@ class global_navigation extends navigation_node {
$coursenode->add(get_string('blogssite','blog'), $blogsurls->out());
}
//Badges
if ($CFG->enablebadges && has_capability('moodle/badges:viewbadges', $this->page->context)) {
$url = new moodle_url($CFG->wwwroot . '/badges/view.php', array('type' => 1));
$coursenode->add(get_string('sitebadges', 'badges'), $url, navigation_node::TYPE_CUSTOM);
}
// Notes
if (!empty($CFG->enablenotes) && (has_capability('moodle/notes:manage', $this->page->context) || has_capability('moodle/notes:view', $this->page->context))) {
$coursenode->add(get_string('notes','notes'), new moodle_url('/notes/index.php', array('filtertype'=>'course', 'filterselect'=>$filterselect)));
@@ -3498,6 +3543,10 @@ class settings_navigation extends navigation_node {
$coursenode->add(get_string('outcomes', 'grades'), $url, self::TYPE_SETTING, null, 'outcomes', new pix_icon('i/outcomes', ''));
}
//Add badges navigation
require_once($CFG->libdir .'/badgeslib.php');
badges_add_course_navigation($coursenode, $course);
// Backup this course
if (has_capability('moodle/backup:backupcourse', $coursecontext)) {
$url = new moodle_url('/backup/backup.php', array('id'=>$course->id));
+3
View File
@@ -56,6 +56,9 @@
<directory suffix="_test.php">backup/converter/moodle1/tests</directory>
<directory suffix="_test.php">backup/util</directory>
</testsuite>
<testsuite name="core_badges">
<directory suffix="_test.php">badges/tests</directory>
</testsuite>
<testsuite name="core_blog">
<directory suffix="_test.php">blog/tests</directory>
</testsuite>
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 807 B

+25
View File
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="SHAPE_circle_Layer_1" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 155.534 155.537" enable-background="new 0 0 155.534 155.537" xml:space="preserve" preserveAspectRatio="xMinYMid meet">
<linearGradient id="SHAPE_circle_SVGID_1_" gradientUnits="userSpaceOnUse" x1="0" y1="77.7681" x2="155.5342" y2="77.7681">
<stop offset="0" style="stop-color:#F8F07D"></stop>
<stop offset="0.0343" style="stop-color:#F8E977"></stop>
<stop offset="0.1909" style="stop-color:#F9D461"></stop>
<stop offset="0.3574" style="stop-color:#F9C450"></stop>
<stop offset="0.5362" style="stop-color:#FBB945"></stop>
<stop offset="0.7361" style="stop-color:#FBB23E"></stop>
<stop offset="1" style="stop-color:#FBB03C"></stop>
</linearGradient>
<circle fill="url(#SHAPE_circle_SVGID_1_)" cx="77.767" cy="77.768" r="77.767"></circle>
<circle fill="#9A6733" cx="77.88" cy="77.432" r="69.672"></circle>
<linearGradient id="SHAPE_circle_SVGID_2_" gradientUnits="userSpaceOnUse" x1="17.208" y1="77.9321" x2="139.5518" y2="77.9321">
<stop offset="0" style="stop-color:#F8F07D"></stop>
<stop offset="1" style="stop-color:#FBB03C"></stop>
</linearGradient>
<path fill="url(#SHAPE_circle_SVGID_2_)" d="M139.552,77.932c0,33.785-27.384,61.174-61.171,61.174c-33.786,0-61.173-27.389-61.173-61.174 s27.387-61.174,61.173-61.174C112.168,16.758,139.552,44.147,139.552,77.932z"></path>
<g transform="translate(78, 78) scale(0.75) translate(-34.5, -48)">
<path fill="#9A6733" d="M56.198,37.566c3.636-0.474,12.589-2.879,13.035-15.094c0,0-0.795-23.747-12.795-10.088V0h-44v11.593 C0.438-0.342,0,22.473,0,22.473c0.427,11.685,8.412,14.394,12.297,15.02c0.165,8.311,6.051,15.355,14.345,18.088 c1.116,3.145,1.763,7.627,0.524,13.581c-2.024,1.245-3.328,3.115-3.328,5.207c0,1.896,1.054,3.609,2.758,4.841 C26.032,82.719,23.536,92.883,13.403,96H54.93c0,0-14.283-8.367-15.314-16.848c1.658-1.228,2.683-2.918,2.683-4.784 c0-2.153-1.368-4.069-3.496-5.313c-0.413-2.786-0.961-8.015-0.222-12.635C48.503,54.633,55.993,46.902,56.198,37.566z M64.914,23.412c0,0-0.066,9.868-8.637,8.724l0.132-5.941c0.135-0.731,0.029-1.474,0.029-2.239v-0.189v-5.429 C58.438,16.009,64.442,9.861,64.914,23.412z M4.319,23.412c0.425-12.195,5.12-8.435,8.12-5.863v6.218v0.094V24h-0.454l0.226,8.203 C4.206,32.847,4.319,23.412,4.319,23.412z"></path>
</g></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

+11
View File
@@ -0,0 +1,11 @@
<svg width="150" height="150" xmlns="http://www.w3.org/2000/svg">
<!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
<g>
<title>Layer 1</title>
<g id="svg_5">
<rect stroke="#ffffff" transform="rotate(-45 75.0089 73.625)" id="svg_4" height="42" width="151" y="52.625" x="-0.491117" fill-opacity="0" stroke-linecap="null" stroke-linejoin="null" stroke-dasharray="null" stroke-width="8" fill="#000000"/>
<rect fill="#000000" stroke-width="5" x="-0.29617" y="52.95618" width="150" height="41.49538" id="svg_1" fill-opacity="0" stroke="#bf3b08" transform="rotate(-45 74.7038 73.7039)"/>
<text stroke="#ffffff" fill="#bf3b08" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="72.605337" y="79.726979" id="svg_2" font-size="20" font-family="Sans-serif" text-anchor="middle" xml:space="preserve" font-weight="bold" font-style="normal" transform="rotate(-45 74.9404 73.9979) matrix(1.00967 0 0 1 1.94841 0.788716)">E X P I R E D</text>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 998 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 417 B

+111
View File
@@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="SHAPE_circle_Layer_1"
x="0px"
y="0px"
width="12"
height="12"
viewBox="0 0 116.6505 116.65275"
enable-background="new 0 0 155.534 155.537"
xml:space="preserve"
preserveAspectRatio="xMinYMid meet"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="badge.svg"><metadata
id="metadata37"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs35" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="933"
inkscape:window-height="777"
id="namedview33"
showgrid="false"
inkscape:zoom="29.5"
inkscape:cx="5.5704236"
inkscape:cy="8.9143982"
inkscape:window-x="876"
inkscape:window-y="120"
inkscape:window-maximized="0"
inkscape:current-layer="SHAPE_circle_Layer_1" />
<linearGradient
id="SHAPE_circle_SVGID_1_"
gradientUnits="userSpaceOnUse"
x1="0"
y1="77.768097"
x2="155.53419"
y2="77.768097">
<stop
offset="0"
style="stop-color:#F8F07D"
id="stop4" />
<stop
offset="0.0343"
style="stop-color:#F8E977"
id="stop6" />
<stop
offset="0.1909"
style="stop-color:#F9D461"
id="stop8" />
<stop
offset="0.3574"
style="stop-color:#F9C450"
id="stop10" />
<stop
offset="0.5362"
style="stop-color:#FBB945"
id="stop12" />
<stop
offset="0.7361"
style="stop-color:#FBB23E"
id="stop14" />
<stop
offset="1"
style="stop-color:#FBB03C"
id="stop16" />
</linearGradient>
<linearGradient
id="SHAPE_circle_SVGID_2_"
gradientUnits="userSpaceOnUse"
x1="17.208"
y1="77.932098"
x2="139.5518"
y2="77.932098">
<stop
offset="0"
style="stop-color:#F8F07D"
id="stop23" />
<stop
offset="1"
style="stop-color:#FBB03C"
id="stop25" />
</linearGradient>
<g
transform="matrix(1.4734726,0,0,1.2099656,7.6387822,0.47952991)"
id="g29"
style="fill:#999999;fill-opacity:1">
<path
d="m 56.198,37.566 c 3.636,-0.474 12.589,-2.879 13.035,-15.094 0,0 -0.795,-23.747 -12.795,-10.088 V 0 h -44 V 11.593 C 0.438,-0.342 0,22.473 0,22.473 c 0.427,11.685 8.412,14.394 12.297,15.02 0.165,8.311 6.051,15.355 14.345,18.088 1.116,3.145 1.763,7.627 0.524,13.581 -2.024,1.245 -3.328,3.115 -3.328,5.207 0,1.896 1.054,3.609 2.758,4.841 C 26.032,82.719 23.536,92.883 13.403,96 H 54.93 c 0,0 -14.283,-8.367 -15.314,-16.848 1.658,-1.228 2.683,-2.918 2.683,-4.784 0,-2.153 -1.368,-4.069 -3.496,-5.313 C 38.39,66.269 37.842,61.04 38.581,56.42 48.503,54.633 55.993,46.902 56.198,37.566 z m 8.716,-14.154 c 0,0 -0.066,9.868 -8.637,8.724 l 0.132,-5.941 c 0.135,-0.731 0.029,-1.474 0.029,-2.239 v -0.189 -5.429 c 2,-2.329 8.004,-8.477 8.476,5.074 z m -60.595,0 c 0.425,-12.195 5.12,-8.435 8.12,-5.863 V 23.767 23.861 24 h -0.454 l 0.226,8.203 C 4.206,32.847 4.319,23.412 4.319,23.412 z"
id="path31"
inkscape:connector-curvature="0"
style="fill:#999999;fill-opacity:1" />
</g></svg>

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

+98
View File
@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="12"
height="12"
id="svg3063"
version="1.1"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="backpack.svg">
<defs
id="defs3065" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="11.2"
inkscape:cx="1.429084"
inkscape:cy="4.5052503"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="830"
inkscape:window-height="592"
inkscape:window-x="280"
inkscape:window-y="204"
inkscape:window-maximized="0" />
<metadata
id="metadata3068">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1040.3622)">
<path
d="m 10.543488,1048.9648 c 0.394394,-2.5165 0.718883,-3.667 1.05778,-5.1365 0.82931,-3.5958 -2.2531987,-2.8176 -2.9030487,-2.8336 l 0.447857,0.938 c 1.4007247,0.401 1.8058647,1.2639 0.823647,4.8576"
id="path3476"
style="fill:none;stroke:#999999;stroke-width:0.62900001;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
d="m 1.8580936,1044.3127 c -1.00476496,0.094 -1.87411891,4.6548 -0.75118,5.8508 1.348319,1.436 5.249987,1.9192 6.101278,1.6285 1.891616,-0.6461 2.7947904,-1.1697 2.8491554,-2.2359 0.081,-1.5869 -0.4443624,-7.5316 -1.7011894,-7.9244"
id="path3468"
style="fill:none;stroke:#999999;stroke-width:1.215;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
d="m 3.4779306,1049.0721 -1.120545,-0.4837 c -0.110732,-0.4931 -0.10429,-0.5847 0.147902,-0.6592 l 1.183311,0.2782 c -0.229472,0.098 -0.293891,0.2349 -0.210668,0.8647 z"
id="path3478"
style="fill:none;stroke:#999999;stroke-width:0.45217568;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
d="m 3.4644806,1048.139 -1.035364,-0.2526 c -0.142854,-0.3159 -0.119045,-0.5515 0.138893,-0.6934 l 1.116149,0.2397 c -0.09058,0.094 -0.289451,0.1236 -0.219678,0.7063 z"
id="path3480"
style="fill:none;stroke:#999999;stroke-width:0.45217568;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
d="m 3.6034606,1047.4412 -1.093646,-0.244 c -0.142897,-0.3158 -0.128011,-0.5557 0.12997,-0.6977 l 1.254999,0.2569 c -0.08605,0.068 -0.710744,0.1364 -0.291323,0.6848 z"
id="path3482"
style="fill:none;stroke:#999999;stroke-width:0.45217568;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
d="m 8.8008246,1041.8475 c -1.967048,-1.0297 -1.805695,1.8144 -3.806781,3.9135 -2.09976,2.2025 -3.010551,-0.6299 -3.068049,-0.7991 -0.88794,-2.6104 1.187184,-3.4884 2.580118,-3.8783 1.353455,-0.3789 3.817183,-0.3632 4.294712,0.7639 z"
id="path3470"
style="fill:none;stroke:#999999;stroke-width:1.163;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
id="path190"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 12.071228,1048.5083 c 0,2.1186 -1.635668,3.8363 -3.653042,3.8363 -2.01742,0 -3.6530436,-1.7177 -3.6530436,-3.8363 0,-2.1187 1.6356236,-3.8364 3.6530436,-3.8364 2.017374,0 3.653042,1.7177 3.653042,3.8364" />
<path
style="fill:#999999;overflow:visible"
d="m 2.5691904,1052.2788 z m 9.1231616,-4.1669 -2.7059844,-3.0004 c -0.309334,-0.3333 -0.773131,-0.3333 -1.082465,0 l -2.706035,3.0837 c -0.309232,0.3333 -0.231925,0.75 0.231923,0.75 l 1.778289,0 0,2.5003 c 0,0.4167 0.386591,0.8333 0.85054,0.8333 l 0.773081,0 c 0.386642,0 0.695875,-0.4166 0.695875,-0.8333 l 0,-2.5003 1.9328524,0 c 0.386591,0 0.541207,-0.5001 0.231924,-0.8333 z"
id="path6-1-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccscsssscsc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

+60
View File
@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
width="12px"
height="12px"
viewBox="0 0 12 12"
style="overflow:visible;enable-background:new 0 0 12 12;"
xml:space="preserve"
preserveAspectRatio="xMinYMid meet"
id="svg2"
inkscape:version="0.48.3.1 r9886"
sodipodi:docname="portfolioadd.svg"><metadata
id="metadata10"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="932"
inkscape:window-height="719"
id="namedview8"
showgrid="false"
inkscape:zoom="3.4766083"
inkscape:cx="-39.823493"
inkscape:cy="4.7957596"
inkscape:window-x="922"
inkscape:window-y="168"
inkscape:window-maximized="0"
inkscape:current-layer="svg2" />
<defs
id="defs4">
</defs>
<path
style="fill:#999999"
d="M 5.3,12 0,12 0,2.6 0,2.6 2.6,0 2.6,0 10,0 10,3.8 9,2.8 9,1 4,1 4,4 1,4 l 0,7 4,0 c 0,0.4 0.1,0.7 0.3,1 z"
id="path6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccccccccccc" />
<path
style="fill:#999999;overflow:visible"
d="m -0.05724243,3.0499999 z m 11.80000043,5 L 8.2427575,11.65 c -0.4,0.4 -1,0.4 -1.4,0 l -3.5,-3.7000001 c -0.4,-0.4 -0.3,-0.9 0.3,-0.9 l 2.3,0 0,-3 c 0,-0.5 0.5,-1 1.1,-1 l 1,0 c 0.5,0 0.9,0.5 0.9,1 l 0,3 2.5000005,0 c 0.5,0 0.7,0.6 0.3,1 z"
id="path6-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccscsssscsc" /></svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

+58
View File
@@ -1280,3 +1280,61 @@ body.jsenabled .formlistingradio {
body.jsenabled .formlisting {
display: block;
}
/**
* Badges styles
*/
#page-badges-view .collection { width: 90%; margin: 1em auto; }
#page-badges-index .collection { width: 85%; margin: 1em auto; }
table.collection th { font-size: inherit !important; border-width: 1px; border-style: solid; border-color: #CCCCCC; vertical-align: middle; padding-left: 5px; padding-right: 5px; vertical-align: top; text-align: center !important; }
table.collection td { border-width: 1px; border-style: solid; border-color: #CCCCCC; vertical-align: middle; padding-left: 5px; padding-right: 5px; vertical-align: top; }
table.collection .r1 { background-color: #FFFFFF; }
table.collection .r0 { background-color: #F6F6F6; }
table.collection ul { margin: 0.5em 0.5em 0.5em 2em; }
#page-badges-view table.collection .badgeimage,
#page-badges-index table.collection .status { width: 15%; text-align: center; vertical-align: middle; }
#page-badges-view table.collection .awards,
#page-badges-index table.collection .awards { width: 10%; text-align: center; vertical-align: middle; }
#page-badges-view table.collection .description { width: 25%; text-align: left; }
table.collection .name { text-align: left; vertical-align: middle; }
#page-badges-view table.collection .criteria { width: 35%; text-align: left; vertical-align: top; }
#page-badges-index table.collection .criteria { width: 40%; text-align: left; vertical-align: top; }
#page-badges-index table.collection .actions { width: 11em; text-align: center; vertical-align: middle; }
a.criteria-action { padding: 0px 3px; float: right; }
table.issuedbadgebox { width: 750px; background-color: white; }
table.badgeissuedimage { width: 150px; text-align: center; }
table.badgeissuedinfo { width: 600px; }
table.badgeissuedinfo .bvalue { text-align: left; vertical-align: middle; }
table.badgeissuedinfo .bfield { width: 125px; text-align: left; font-style: italic; }
ul.badges { margin: 0; list-style: none; }
.badges li { position: relative; display: inline-block; padding-bottom: 2em; text-align: center; vertical-align: top; width: 150px; }
.badges li .badge-name { display: block; padding: 5px; }
.badges li > img { position: absolute; }
.badges li .badge-image { width: 90px; height: 90px; left: 10px; top: 0px; z-index: 1; }
.badges li .badge-actions { position: relative; }
div.badge { position: relative; display: block; }
div.badge .expireimage { width: 100px; height: 100px; left: 20px; top: 0px; }
.expireimage { width: 90px; height: 90px; left: 30px; top: 0px; position: absolute; z-index:10; filter: alpha(opacity = 85); -moz-opacity: 0.85; -khtml-opacity: 0.85; opacity: 0.85;}
.backpackform { width: 100px !important; float: left; }
.badge-profile { vertical-align: top; }
#page-badges-award .recipienttable { background-color: #EEEEEE; border: 1px solid #BBBBBB; width: 100%; vertical-align: top; }
#page-badges-award .recipienttable tr td { vertical-align: top; }
#page-badges-award .recipienttable tr td.actions { width: 16%; padding-top: 3em; }
#page-badges-award .recipienttable tr td.actions .actionbutton { margin: 0.3em 0; padding: 0.5em 0; width: 100%; }
#page-badges-award .recipienttable tr td.existing,
#page-badges-award .recipienttable tr td.potential { width: 42%; }
.statustable { margin-bottom: 0px; }
.statusbox { border-color: #BBBBBB; }
.statusbox.active { background-color: #D9F991; }
.statusbox.inactive { background-color: #FFEBA8; }
.activatebadge { margin: 0px; text-align: left; vertical-align: middle; }
.addcourse { float: right; }
+6 -1
View File
@@ -404,6 +404,11 @@ if (!isset($hiddenfields['suspended'])) {
}
}
require_once($CFG->libdir . '/badgeslib.php');
if (!empty($CFG->enablebadges)) {
profile_display_badges($user->id);
}
echo html_writer::end_tag('dl');
echo "</div></div>"; // Closing desriptionbox and userprofilebox.
echo '<div id="region-content" class="block-region"><div class="region-content">';
@@ -425,4 +430,4 @@ if ($CFG->debugdisplay && debugging('', DEBUG_DEVELOPER) && $currentuser) { //
}
echo '</div>'; // userprofile class
echo $OUTPUT->footer();
echo $OUTPUT->footer();
+1 -1
View File
@@ -29,7 +29,7 @@
defined('MOODLE_INTERNAL') || die();
$version = 2013032800.00; // YYYYMMDD = weekly release date of this DEV branch
$version = 2013040200.00; // YYYYMMDD = weekly release date of this DEV branch
// RR = release increments - 00 in DEV branches
// .XX = incremental changes