Permalink
Browse files

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
  • Loading branch information...
ybozhko authored and damyon committed Apr 2, 2013
1 parent ec6089f commit 278065528aed2e6d712292b09ecdedf3d5b26bfe
Showing with 8,760 additions and 3 deletions.
  1. +23 −0 admin/registration/forms.php
  2. +14 −0 admin/registration/lib.php
  3. +2 −0 admin/registration/register.php
  4. +83 −0 admin/settings/badges.php
  5. +2 −0 admin/settings/subsystems.php
  6. +1 −0 admin/settings/top.php
  7. +159 −0 badges/action.php
  8. +43 −0 badges/ajax.php
  9. +40 −0 badges/assertion.php
  10. +143 −0 badges/award.php
  11. +29 −0 badges/backpack.js
  12. +109 −0 badges/backpack_form.php
  13. +68 −0 badges/badge.php
  14. +103 −0 badges/criteria.php
  15. +390 −0 badges/criteria/award_criteria.php
  16. +232 −0 badges/criteria/award_criteria_activity.php
  17. +178 −0 badges/criteria/award_criteria_course.php
  18. +250 −0 badges/criteria/award_criteria_courseset.php
  19. +184 −0 badges/criteria/award_criteria_manual.php
  20. +145 −0 badges/criteria/award_criteria_overall.php
  21. +190 −0 badges/criteria/award_criteria_profile.php
  22. +86 −0 badges/criteria_action.php
  23. +89 −0 badges/criteria_form.php
  24. +105 −0 badges/criteria_settings.php
  25. +162 −0 badges/cron.php
  26. +146 −0 badges/edit.php
  27. +241 −0 badges/edit_form.php
  28. +45 −0 badges/external.php
  29. +186 −0 badges/index.php
  30. +242 −0 badges/lib/awardlib.php
  31. +119 −0 badges/lib/backpacklib.php
  32. +155 −0 badges/lib/bakerlib.php
  33. +164 −0 badges/mybackpack.php
  34. +116 −0 badges/mybadges.php
  35. +106 −0 badges/newbadge.php
  36. +74 −0 badges/overview.php
  37. +107 −0 badges/recipients.php
  38. +1,013 −0 badges/renderer.php
  39. +188 −0 badges/tests/badgeslib_test.php
  40. +46 −0 badges/tests/behat/add_badge.feature
  41. +58 −0 badges/tests/behat/award_badge.feature
  42. BIN badges/tests/behat/badge.png
  43. +106 −0 badges/view.php
  44. +100 −0 blocks/badges/block_badges.php
  45. +46 −0 blocks/badges/db/access.php
  46. +38 −0 blocks/badges/edit_form.php
  47. +30 −0 blocks/badges/lang/en/block_badges.php
  48. +30 −0 blocks/badges/version.php
  49. +337 −0 lang/en/badges.php
  50. +2 −0 lang/en/hub.php
  51. +1 −0 lang/en/moodle.php
  52. +12 −0 lang/en/role.php
  53. +1,279 −0 lib/badgeslib.php
  54. +2 −0 lib/completionlib.php
  55. +5 −0 lib/cronlib.php
  56. +143 −0 lib/db/access.php
  57. +18 −1 lib/db/events.php
  58. +139 −0 lib/db/install.xml
  59. +188 −0 lib/db/upgrade.php
  60. +25 −0 lib/filelib.php
  61. +1 −0 lib/moodlelib.php
  62. +49 −0 lib/navigationlib.php
  63. +3 −0 phpunit.xml.dist
  64. BIN pix/i/badge.png
  65. +25 −0 pix/i/badge.svg
  66. BIN pix/i/expired.png
  67. +11 −0 pix/i/expired.svg
  68. BIN pix/t/award.png
  69. +111 −0 pix/t/award.svg
  70. BIN pix/t/backpack.png
  71. +98 −0 pix/t/backpack.svg
  72. +60 −0 pix/t/download.svg
  73. +58 −0 theme/base/style/core.css
  74. +6 −1 user/profile.php
  75. +1 −1 version.php
@@ -243,6 +243,8 @@ public function definition() {
$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 @@ public function definition() {
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 @@ public function definition() {
" " . 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 @@ public function definition() {
$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);
View
@@ -247,6 +247,20 @@ public function get_site_info($huburl) {
$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) {
@@ -84,6 +84,8 @@
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');
}
View
@@ -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 <yuliya.bozhko@totaralms.com>
+*/
+
+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')
+ )
+ );
+}
@@ -41,4 +41,6 @@
$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));
}
View
@@ -30,6 +30,7 @@
$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')));
View
@@ -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 <yuliya.bozhko@totaralms.com>
+ */
+
+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);
+}
View
@@ -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 <yuliya.bozhko@totaralms.com>
+ */
+
+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();
Oops, something went wrong.

0 comments on commit 2780655

Please sign in to comment.