From e280531436d080082aad9ef56de1598c06303065 Mon Sep 17 00:00:00 2001 From: Yuliya Bozhko Date: Tue, 16 Apr 2013 10:47:40 +1200 Subject: [PATCH] MDL-39063 badges: Improve external backpack usability and workflow --- admin/settings/badges.php | 9 +- badges/action.php | 2 +- badges/backpack_form.php | 96 +++++++++++----- badges/edit_form.php | 15 ++- badges/index.php | 8 +- badges/lib/backpacklib.php | 15 +-- badges/mybackpack.php | 146 +++++++++-------------- badges/preferences.php | 65 +++++++++++ badges/preferences_form.php | 47 ++++++++ badges/renderer.php | 223 ++++++++++++++++++------------------ lang/en/badges.php | 38 ++++-- lib/badgeslib.php | 45 ++++++-- lib/db/install.xml | 14 ++- lib/db/upgrade.php | 42 +++++++ lib/navigationlib.php | 9 ++ theme/base/style/core.css | 3 +- version.php | 2 +- 17 files changed, 506 insertions(+), 273 deletions(-) create mode 100644 badges/preferences.php create mode 100644 badges/preferences_form.php diff --git a/admin/settings/badges.php b/admin/settings/badges.php index 7e6f41e1096..a1cbca36531 100644 --- a/admin/settings/badges.php +++ b/admin/settings/badges.php @@ -70,7 +70,14 @@ if (!empty($CFG->enablebadges) && ($hassiteconfig || has_any_capability(array( 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') + array( + 'moodle/badges:viewawarded', + 'moodle/badges:createbadge', + 'moodle/badges:awardbadge', + 'moodle/badges:configuremessages', + 'moodle/badges:configuredetails', + 'moodle/badges:deletebadge' + ) ) ); diff --git a/badges/action.php b/badges/action.php index 33181a57d1e..ae38fa7f445 100644 --- a/badges/action.php +++ b/badges/action.php @@ -125,7 +125,7 @@ if ($activate) { } else { $awards = $badge->review_all_criteria(); $returnurl->param('awards', $awards); - } + } redirect($returnurl); } diff --git a/badges/backpack_form.php b/badges/backpack_form.php index dbe42e88ff6..dce06305ec1 100644 --- a/badges/backpack_form.php +++ b/badges/backpack_form.php @@ -42,14 +42,17 @@ class edit_backpack_form extends moodleform { global $USER; $mform = $this->_form; - $mform->addElement('header', 'backpackheader', get_string('backpackdetails', 'badges')); + $mform->addElement('header', 'backpackheader', get_string('backpackconnection', 'badges')); + $mform->addHelpButton('backpackheader', 'backpackconnection', 'badges'); $mform->addElement('static', 'url', get_string('url'), 'http://backpack.openbadges.org'); + $status = html_writer::tag('span', get_string('notconnected', 'badges'), array('class' => 'notconnected')); + $mform->addElement('static', 'status', get_string('status'), $status); $mform->addElement('text', 'email', get_string('email'), array('size' => '50')); $mform->setDefault('email', $USER->email); - $mform->setType('email', PARAM_EMAIL); + $mform->setType('email', PARAM_RAW); $mform->addRule('email', get_string('required'), 'required', null , 'client'); - $mform->addRule('email', get_string('maximumchars', '', 255), 'maxlength', 255, 'client'); + $mform->addHelpButton('email', 'backpackemail', 'badges'); $mform->addElement('hidden', 'userid', $USER->id); $mform->setType('userid', PARAM_INT); @@ -57,15 +60,38 @@ class edit_backpack_form extends moodleform { $mform->addElement('hidden', 'backpackurl', 'http://backpack.openbadges.org'); $mform->setType('backpackurl', PARAM_URL); - $this->add_action_buttons(); + $this->add_action_buttons(true, get_string('connect', 'badges')); + } + + /** + * Validates form data + */ + public function validation($data, $files) { + global $DB; + $errors = parent::validation($data, $files); + + if (!validate_email($data['email'])) { + $errors['email'] = get_string('invalidemail'); + } else { + $check = new stdClass(); + $check->backpackurl = $data['backpackurl']; + $check->email = $data['email']; + + $bp = new OpenBadgesBackpackHandler($check); + $request = $bp->curl_request('user'); + if (isset($request->status) && $request->status == 'missing') { + $errors['email'] = get_string('error:nosuchuser', 'badges'); + } + } + return $errors; } } /** - * Form to select backpack group options. + * Form to select backpack collections. * */ -class edit_backpack_group_form extends moodleform { +class edit_collections_form extends moodleform { /** * Defines the form @@ -73,38 +99,48 @@ class edit_backpack_group_form extends moodleform { public function definition() { global $USER; $mform = $this->_form; - $data = $this->_customdata['data']; - $groups = $this->_customdata['groups']; - $uid = $this->_customdata['backpackuid']; + $email = $this->_customdata['email']; + $bid = $this->_customdata['backpackid']; + $selected = $this->_customdata['selected']; - $selet = array(); - foreach ($groups as $group) { - $select[$group->groupId] = $group->name; + if (isset($this->_customdata['groups'])) { + $groups = $this->_customdata['groups']; + $nogroups = null; + } else { + $groups = null; + $nogroups = $this->_customdata['nogroups']; } - $mform->addElement('header', 'groupheader', get_string('backpackdetails', 'badges')); + $mform->addElement('header', 'backpackheader', get_string('backpackconnection', 'badges')); + $mform->addHelpButton('backpackheader', 'backpackconnection', 'badges'); $mform->addElement('static', 'url', get_string('url'), 'http://backpack.openbadges.org'); - $mform->addElement('text', 'email', get_string('email'), array('size' => '50')); - $mform->setType('email', PARAM_EMAIL); - $mform->setDefault('email', $data->email); - $mform->freeze(array('email')); + $status = html_writer::tag('span', get_string('connected', 'badges'), array('class' => 'connected')); + $mform->addElement('static', 'status', get_string('status'), $status); + $mform->addElement('static', 'email', get_string('email'), $email); + $mform->addHelpButton('email', 'backpackemail', 'badges'); + $mform->addElement('submit', 'disconnect', get_string('disconnect', 'badges')); - $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('header', 'collectionheader', get_string('backpackimport', 'badges')); + $mform->addHelpButton('collectionheader', 'backpackimport', 'badges'); + + if (!empty($groups)) { + $mform->addElement('static', 'selectgroup', '', get_string('selectgroup_start', 'badges')); + foreach ($groups as $group) { + $name = $group->name . ' (' . $group->badges . ')'; + $mform->addElement('advcheckbox', 'group[' . $group->groupId . ']', null, $name, array('group' => 1), array(false, $group->groupId)); + if (in_array($group->groupId, $selected)) { + $mform->setDefault('group[' . $group->groupId . ']', $group->groupId); + } + } + $mform->addElement('static', 'selectgroup', '', get_string('selectgroup_end', 'badges')); + } else { + $mform->addElement('static', 'selectgroup', '', $nogroups); } - $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); + $mform->addElement('hidden', 'backpackid', $bid); + $mform->setType('backpackid', PARAM_INT); $this->add_action_buttons(); } -} \ No newline at end of file +} diff --git a/badges/edit_form.php b/badges/edit_form.php index 768cc9519dd..7ebe2f4e8bb 100644 --- a/badges/edit_form.php +++ b/badges/edit_form.php @@ -83,8 +83,7 @@ class edit_details_form extends moodleform { if (isset($CFG->badges_defaultissuercontact)) { $mform->setDefault('issuercontact', $CFG->badges_defaultissuercontact); } - $mform->setType('issuercontact', PARAM_EMAIL); - $mform->addRule('issuercontact', get_string('invalidemail', 'moodle'), 'email', null, 'client', true); + $mform->setType('issuercontact', PARAM_RAW); $mform->addHelpButton('issuercontact', 'contact', 'badges'); $mform->addElement('header', 'issuancedetails', get_string('issuancedetails', 'badges')); @@ -163,6 +162,10 @@ class edit_details_form extends moodleform { global $DB; $errors = parent::validation($data, $files); + if (!empty($data['issuercontact']) && !validate_email($data['issuercontact'])) { + $errors['issuercontact'] = get_string('invalidemail'); + } + if ($data['expiry'] == 2 && $data['expireperiod'] <= 0) { $errors['expirydategr'] = get_string('error:invalidexpireperiod', 'badges'); } @@ -173,11 +176,11 @@ class edit_details_form extends moodleform { // Check for duplicate badge names. if ($data['action'] == 'new') { - $duplicate = $DB->record_exists_select('badge', 'name = :name', - array('name' => $data['name'])); + $duplicate = $DB->record_exists_select('badge', 'name = :name AND status != :deleted', + array('name' => $data['name'], 'deleted' => BADGE_STATUS_ARCHIVED)); } else { - $duplicate = $DB->record_exists_select('badge', 'name = :name AND id != :badgeid', - array('name' => $data['name'], 'badgeid' => $data['id'])); + $duplicate = $DB->record_exists_select('badge', 'name = :name AND id != :badgeid AND status != :deleted', + array('name' => $data['name'], 'badgeid' => $data['id'], 'deleted' => BADGE_STATUS_ARCHIVED)); } if ($duplicate) { diff --git a/badges/index.php b/badges/index.php index 64d6fe88fc8..56176fbff6f 100644 --- a/badges/index.php +++ b/badges/index.php @@ -87,7 +87,13 @@ if ($type == BADGE_TYPE_SITE) { ); } -if (!has_capability('moodle/badges:awardbadge', $PAGE->context)) { +if (!has_any_capability(array( + 'moodle/badges:viewawarded', + 'moodle/badges:createbadge', + 'moodle/badges:awardbadge', + 'moodle/badges:configuremessages', + 'moodle/badges:configuredetails', + 'moodle/badges:deletebadge'), $PAGE->context)) { redirect($CFG->wwwroot); } diff --git a/badges/lib/backpacklib.php b/badges/lib/backpacklib.php index f38a0668b9f..3cc9f88e659 100644 --- a/badges/lib/backpacklib.php +++ b/badges/lib/backpacklib.php @@ -36,28 +36,26 @@ 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) { + public function curl_request($action, $collection = null) { $curl = new curl(); switch($action) { case 'user': - $url = $this->backpack."/displayer/convert/email"; + $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'; + $url = $this->backpack . '/displayer/' . $this->backpackuid . '/group/' . $collection . '.json'; break; } @@ -86,11 +84,10 @@ class OpenBadgesBackpackHandler { 'message' => get_string('error:nosuchuser', 'badges') ); return $response; - break; } } - public function get_groups() { + public function get_collections() { $json = $this->curl_request('user', $this->email); if (isset($json->status)) { if ($json->status != 'okay') { @@ -102,13 +99,13 @@ class OpenBadgesBackpackHandler { } } - public function get_badges() { + public function get_badges($collection) { $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'); + return $this->curl_request('badges', $collection); } } } diff --git a/badges/mybackpack.php b/badges/mybackpack.php index c5bee6558b5..813550c078e 100644 --- a/badges/mybackpack.php +++ b/badges/mybackpack.php @@ -38,7 +38,7 @@ if (empty($CFG->enablebadges)) { $context = context_user::instance($USER->id); require_capability('moodle/badges:manageownbadges', $context); -$clear = optional_param('clear', false, PARAM_BOOL); +$disconnect = optional_param('disconnect', false, PARAM_BOOL); if (empty($CFG->badges_allowexternalbackpack)) { redirect($CFG->wwwroot); @@ -52,113 +52,77 @@ $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 ($disconnect && $backpack) { + require_sesskey(); + $DB->delete_records('badge_external', array('backpackid' => $backpack->id)); + $DB->delete_records('badge_backpack', array('userid' => $USER->id)); + redirect(new moodle_url('/badges/mybackpack.php')); +} + if ($backpack) { + // If backpack is connected, need to select collections. $bp = new OpenBadgesBackpackHandler($backpack); - $request = $bp->get_groups(); - + $request = $bp->get_collections(); if (empty($request->groups)) { - unset($SESSION->badgesparams); - redirect(new moodle_url('/badges/mybadges.php'), get_string('error:nogroups', 'badges'), 20); + $params['nogroups'] = get_string('error:nogroups', 'badges'); + } else { + $params['groups'] = $request->groups; } + $params['email'] = $backpack->email; + $params['selected'] = $DB->get_fieldset_select('badge_external', 'collectionid', 'backpackid = :bid', array('bid' => $backpack->id)); + $params['backpackid'] = $backpack->id; + $form = new edit_collections_form(new moodle_url('/badges/mybackpack.php'), $params); - $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()) { + if ($form->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); + } else if ($data = $form->get_data()) { + $groups = array_filter($data->group); + + // Remove all unselected collections if there are any. + $sqlparams = array('backpack' => $backpack->id); + $select = 'backpackid = :backpack '; + if (!empty($groups)) { + list($grouptest, $groupparams) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED, 'col', false); + $select .= ' AND collectionid ' . $grouptest; + $sqlparams = array_merge($sqlparams, $groupparams); + } + $DB->delete_records_select('badge_external', $select, $sqlparams); + + // Insert selected collections if they are not in database yet. + foreach ($groups as $group) { + $obj = new stdClass(); + $obj->backpackid = $data->backpackid; + $obj->collectionid = (int) $group; + if (!$DB->record_exists('badge_external', array('backpackid' => $obj->backpackid, 'collectionid' => $obj->collectionid))) { + $DB->insert_record('badge_external', $obj); + } } redirect(new moodle_url('/badges/mybadges.php')); } - - echo $OUTPUT->header(); - $groupform->display(); - echo $OUTPUT->footer(); - die(); } else { + // If backpack is not connected, need to connect first. $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(); + } else if ($data = $form->get_data()) { + $bp = new OpenBadgesBackpackHandler($data); - // 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); - } + $obj = new stdClass(); + $obj->userid = $data->userid; + $obj->email = $data->email; + $obj->backpackurl = $data->backpackurl; + $obj->backpackuid = $bp->curl_request('user')->userId; + $obj->autosync = 0; + $obj->password = ''; + $DB->insert_record('badge_backpack', $obj); - $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(); + redirect(new moodle_url('/badges/mybackpack.php')); } - - echo $OUTPUT->header(); - $form->display(); - echo $OUTPUT->footer(); } + +echo $OUTPUT->header(); +$form->display(); +echo $OUTPUT->footer(); diff --git a/badges/preferences.php b/badges/preferences.php new file mode 100644 index 00000000000..edb771883a0 --- /dev/null +++ b/badges/preferences.php @@ -0,0 +1,65 @@ +. + +/** + * Badges user preferences page. + * + * @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 + */ + +require_once(dirname(dirname(__FILE__)) . '/config.php'); +require_once('preferences_form.php'); + +$url = new moodle_url('/badges/preferences.php'); + +require_login(); +$PAGE->set_context(context_system::instance()); +$PAGE->set_url($url); +$PAGE->set_pagelayout('standard'); + +if (empty($CFG->enablebadges)) { + print_error('badgesdisabled', 'badges'); +} + +$mform = new badges_preferences_form(); +$mform->set_data(array('badgeprivacysetting' => get_user_preferences('badgeprivacysetting'))); + +if (!$mform->is_cancelled() && $data = $mform->get_data()) { + $setting = $data->badgeprivacysetting; + set_user_preference('badgeprivacysetting', $setting); +} + +if ($mform->is_cancelled()) { + redirect($CFG->wwwroot . '/badges/mybadges.php'); +} + +$strpreferences = get_string('preferences'); +$strbadges = get_string('badges'); + +$title = "$strbadges: $strpreferences"; +$PAGE->set_title($title); +$PAGE->set_heading($title); + +echo $OUTPUT->header(); +echo $OUTPUT->heading("$strbadges: $strpreferences", 2); + +$mform->display(); + +echo $OUTPUT->footer(); diff --git a/badges/preferences_form.php b/badges/preferences_form.php new file mode 100644 index 00000000000..7bfe8f83b2b --- /dev/null +++ b/badges/preferences_form.php @@ -0,0 +1,47 @@ +. + +/** + * Form class for editing badges preferences. + * + * @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 + */ + +if (!defined('MOODLE_INTERNAL')) { + die('Direct access to this script is forbidden.'); +} + +require_once($CFG->libdir . '/formslib.php'); + +class badges_preferences_form extends moodleform { + public function definition() { + global $USER, $CFG; + + $mform =& $this->_form; + + $mform->addElement('header', 'badgeprivacy', get_string('badgeprivacysetting', 'badges')); + $mform->addElement('advcheckbox', 'badgeprivacysetting', '', get_string('badgeprivacysetting_str', 'badges')); + $mform->setType('badgeprivacysetting', PARAM_INT); + $mform->setDefault('badgeprivacysetting', 1); + $mform->addHelpButton('badgeprivacy', 'badgeprivacysetting', 'badges'); + + $this->add_action_buttons(); + } +} diff --git a/badges/renderer.php b/badges/renderer.php index be5e26ae684..10fc496142c 100644 --- a/badges/renderer.php +++ b/badges/renderer.php @@ -60,7 +60,9 @@ class core_badges_renderer extends plugin_renderer_base { $download = $status = $push = ''; if (($userid == $USER->id) && !$profile) { $url = new moodle_url('mybadges.php', array('download' => $badge->id, 'hash' => $badge->uniquehash, 'sesskey' => sesskey())); - if (!empty($CFG->badges_allowexternalbackpack) && (empty($badge->dateexpire) || $badge->dateexpire > time())) { + $notexpiredbadge = (empty($badge->dateexpire) || $badge->dateexpire > time()); + $backpackexists = badges_user_has_backpack($USER->id); + if (!empty($CFG->badges_allowexternalbackpack) && $notexpiredbadge && $backpackexists) { $assertion = new moodle_url('/badges/assertion.php', array('b' => $badge->uniquehash)); $action = new component_action('click', 'addtobackpack', array('assertion' => $assertion->out(false))); $push = $this->output->action_icon(new moodle_url('#'), new pix_icon('t/backpack', get_string('addtobackpack', 'badges')), $action); @@ -279,100 +281,94 @@ class core_badges_renderer extends plugin_renderer_base { $today_date = date('Y-m-d'); $today = strtotime($today_date); - if ($ibadge->visible - || ($USER->id == $ibadge->recipient) - || has_capability('moodle/badges:viewawarded', context_system::instance())) { - $table = new html_table(); + $table = new html_table(); - $imagetable = new html_table(); - $imagetable->attributes = array('class' => 'clearfix badgeissuedimage'); - $imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $issued['badge']['image']))); - if ($USER->id == $ibadge->recipient && !empty($CFG->enablebadges)) { - $imagetable->data[] = array($this->output->single_button( - new moodle_url('/badges/badge.php', array('hash' => $ibadge->hash, 'bake' => true)), - get_string('download'), - 'POST')); - $expiration = isset($issued['expires']) ? strtotime($issued['expires']) : $today + 1; - if (!empty($CFG->badges_allowexternalbackpack) && ($expiration > $today)) { - $assertion = new moodle_url('/badges/assertion.php', array('b' => $ibadge->hash)); - $attributes = array( - 'type' => 'button', - 'value' => get_string('addtobackpack', 'badges'), - 'onclick' => 'OpenBadges.issue(["' . $assertion->out(false) . '"], function(errors, successes) { })'); - $tobackpack = html_writer::tag('input', '', $attributes); - $imagetable->data[] = array($tobackpack); - } + $imagetable = new html_table(); + $imagetable->attributes = array('class' => 'clearfix badgeissuedimage'); + $imagetable->data[] = array(html_writer::empty_tag('img', array('src' => $issued['badge']['image']))); + if ($USER->id == $ibadge->recipient && !empty($CFG->enablebadges)) { + $imagetable->data[] = array($this->output->single_button( + new moodle_url('/badges/badge.php', array('hash' => $ibadge->hash, 'bake' => true)), + get_string('download'), + 'POST')); + $expiration = isset($issued['expires']) ? strtotime($issued['expires']) : $today + 1; + if (!empty($CFG->badges_allowexternalbackpack) && ($expiration > $today) && badges_user_has_backpack($USER->id)) { + $assertion = new moodle_url('/badges/assertion.php', array('b' => $ibadge->hash)); + $attributes = array( + 'type' => 'button', + 'value' => get_string('addtobackpack', 'badges'), + 'onclick' => 'OpenBadges.issue(["' . $assertion->out(false) . '"], function(errors, successes) { })'); + $tobackpack = html_writer::tag('input', '', $attributes); + $imagetable->data[] = array($tobackpack); } - $datatable = new html_table(); - $datatable->attributes = array('class' => 'badgeissuedinfo'); - $datatable->colclasses = array('bfield', 'bvalue'); - $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), ''); - $datatable->data[] = array(get_string('issuername', 'badges'), $badge->issuername); - if (isset($badge->issuercontact) && !empty($badge->issuercontact)) { - $datatable->data[] = array(get_string('contact', 'badges'), - html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact))); - } - $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), ''); - $datatable->data[] = array(get_string('name'), $badge->name); - $datatable->data[] = array(get_string('description', 'badges'), $badge->description); - - if ($badge->type == BADGE_TYPE_COURSE && isset($badge->courseid)) { - $coursename = $DB->get_field('course', 'fullname', array('id' => $badge->courseid)); - $datatable->data[] = array(get_string('course'), $coursename); - } - - $datatable->data[] = array(get_string('bcriteria', 'badges'), self::print_badge_criteria($badge)); - $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), ''); - $datatable->data[] = array(get_string('dateawarded', 'badges'), $issued['issued_on']); - if (isset($issued['expires'])) { - $expiration = strtotime($issued['expires']); - if ($expiration < $today) { - $cell = new html_table_cell($issued['expires'] . get_string('warnexpired', 'badges')); - $cell->attributes = array('class' => 'notifyproblem warning'); - $datatable->data[] = array(get_string('expirydate', 'badges'), $cell); - - $image = html_writer::start_tag('div', array('class' => 'badge')); - $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image'])); - $image .= $this->output->pix_icon('i/expired', - get_string('expireddate', 'badges', $issued['expires']), - 'moodle', - array('class' => 'expireimage')); - $image .= html_writer::end_tag('div'); - $imagetable->data[0] = array($image); - } else { - $datatable->data[] = array(get_string('expirydate', 'badges'), $issued['expires']); - } - } - - // Print evidence. - $agg = $badge->get_aggregation_methods(); - $evidence = $badge->get_criteria_completions($ibadge->recipient); - $eids = array_map(create_function('$o', 'return $o->critid;'), $evidence); - unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]); - - $items = array(); - foreach ($badge->criteria as $type => $c) { - if (in_array($c->id, $eids)) { - if (count($c->params) == 1) { - $items[] = get_string('criteria_descr_single_' . $type , 'badges') . $c->get_details(); - } else { - $items[] = get_string('criteria_descr_' . $type , 'badges', - strtoupper($agg[$badge->get_aggregation_method($type)])) . $c->get_details(); - } - } - } - - $datatable->data[] = array(get_string('evidence', 'badges'), - get_string('completioninfo', 'badges') . - html_writer::alist($items, array(), 'ul')); - $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox'); - $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable)); - $htmlbadge = html_writer::table($table); - - return $htmlbadge; - } else { - return get_string('hiddenbadge', 'badges'); } + $datatable = new html_table(); + $datatable->attributes = array('class' => 'badgeissuedinfo'); + $datatable->colclasses = array('bfield', 'bvalue'); + $datatable->data[] = array($this->output->heading(get_string('issuerdetails', 'badges'), 3), ''); + $datatable->data[] = array(get_string('issuername', 'badges'), $badge->issuername); + if (isset($badge->issuercontact) && !empty($badge->issuercontact)) { + $datatable->data[] = array(get_string('contact', 'badges'), + html_writer::tag('a', $badge->issuercontact, array('href' => 'mailto:' . $badge->issuercontact))); + } + $datatable->data[] = array($this->output->heading(get_string('badgedetails', 'badges'), 3), ''); + $datatable->data[] = array(get_string('name'), $badge->name); + $datatable->data[] = array(get_string('description', 'badges'), $badge->description); + + if ($badge->type == BADGE_TYPE_COURSE && isset($badge->courseid)) { + $coursename = $DB->get_field('course', 'fullname', array('id' => $badge->courseid)); + $datatable->data[] = array(get_string('course'), $coursename); + } + + $datatable->data[] = array(get_string('bcriteria', 'badges'), self::print_badge_criteria($badge)); + $datatable->data[] = array($this->output->heading(get_string('issuancedetails', 'badges'), 3), ''); + $datatable->data[] = array(get_string('dateawarded', 'badges'), $issued['issued_on']); + if (isset($issued['expires'])) { + $expiration = strtotime($issued['expires']); + if ($expiration < $today) { + $cell = new html_table_cell($issued['expires'] . get_string('warnexpired', 'badges')); + $cell->attributes = array('class' => 'notifyproblem warning'); + $datatable->data[] = array(get_string('expirydate', 'badges'), $cell); + + $image = html_writer::start_tag('div', array('class' => 'badge')); + $image .= html_writer::empty_tag('img', array('src' => $issued['badge']['image'])); + $image .= $this->output->pix_icon('i/expired', + get_string('expireddate', 'badges', $issued['expires']), + 'moodle', + array('class' => 'expireimage')); + $image .= html_writer::end_tag('div'); + $imagetable->data[0] = array($image); + } else { + $datatable->data[] = array(get_string('expirydate', 'badges'), $issued['expires']); + } + } + + // Print evidence. + $agg = $badge->get_aggregation_methods(); + $evidence = $badge->get_criteria_completions($ibadge->recipient); + $eids = array_map(create_function('$o', 'return $o->critid;'), $evidence); + unset($badge->criteria[BADGE_CRITERIA_TYPE_OVERALL]); + + $items = array(); + foreach ($badge->criteria as $type => $c) { + if (in_array($c->id, $eids)) { + if (count($c->params) == 1) { + $items[] = get_string('criteria_descr_single_' . $type , 'badges') . $c->get_details(); + } else { + $items[] = get_string('criteria_descr_' . $type , 'badges', + strtoupper($agg[$badge->get_aggregation_method($type)])) . $c->get_details(); + } + } + } + + $datatable->data[] = array(get_string('evidence', 'badges'), + get_string('completioninfo', 'badges') . + html_writer::alist($items, array(), 'ul')); + $table->attributes = array('class' => 'generalbox boxaligncenter issuedbadgebox'); + $table->data[] = array(html_writer::table($imagetable), html_writer::table($datatable)); + $htmlbadge = html_writer::table($table); + + return $htmlbadge; } // Outputs external badge. @@ -443,9 +439,17 @@ class core_badges_renderer extends plugin_renderer_base { // Outputs table of user badges. protected function render_badge_user_collection(badge_user_collection $badges) { global $CFG, $USER, $SITE; + $backpack = $badges->backpack; + $mybackpack = new moodle_url('/badges/mybackpack.php'); + $paging = new paging_bar($badges->totalcount, $badges->page, $badges->perpage, $this->page->url, 'page'); $htmlpagingbar = $this->render($paging); + // Set backpack connection string. + $backpackconnect = ''; + if (!empty($CFG->badges_allowexternalbackpack) && is_null($backpack)) { + $backpackconnect = $this->output->box(get_string('localconnectto', 'badges', $mybackpack->out()), 'noticebox'); + } // Search box. $searchform = $this->output->box($this->helper_search_form($badges->search), 'boxwidthwide boxaligncenter'); @@ -465,39 +469,32 @@ class core_badges_renderer extends plugin_renderer_base { $downloadbutton = html_writer::table($table); $htmllist = $this->print_badges_list($badges->badges, $USER->id); - $localhtml .= $downloadbutton . $searchform . $htmlpagingbar . $htmllist . $htmlpagingbar; + $localhtml .= $backpackconnect . $downloadbutton . $searchform . $htmlpagingbar . $htmllist . $htmlpagingbar; } else { $localhtml .= $searchform . $this->output->notification(get_string('nobadges', 'badges')); } $localhtml .= html_writer::end_tag('fieldset'); // External badges. - $backpack = $badges->backpack; $externalhtml = ""; if (!empty($CFG->badges_allowexternalbackpack)) { $externalhtml .= html_writer::start_tag('fieldset', array('class' => 'generalbox')); $externalhtml .= html_writer::tag('legend', $this->output->heading_with_help(get_string('externalbadges', 'badges'), 'externalbadges', 'badges')); if (!is_null($backpack)) { - if ($backpack->totalbadges > 0) { - $externalhtml .= get_string('backpackbadges', 'badges', $backpack); + if ($backpack->totalcollections == 0) { + $externalhtml .= get_string('nobackpackcollections', 'badges', $backpack); } else { - $externalhtml .= get_string('nobackpackbadges', 'badges', $backpack); + if ($backpack->totalbadges == 0) { + $externalhtml .= get_string('nobackpackbadges', 'badges', $backpack); + } else { + $externalhtml .= get_string('backpackbadges', 'badges', $backpack); + $externalhtml .= '

' . $this->print_badges_list($backpack->badges, $USER->id, true, true); + } } - $label = get_string('editsettings', 'badges'); - $externalhtml .= $this->output->single_button( - new moodle_url('mybackpack.php', array('clear' => true)), - get_string('clearsettings', 'badges'), - 'POST', - array('class' => 'backpackform')); } else { - $externalhtml .= get_string('nobackpack', 'badges'); - $label = get_string('setup', 'badges'); + $externalhtml .= get_string('externalconnectto', 'badges', $mybackpack->out()); } - $externalhtml .= $this->output->single_button('mybackpack.php', $label, 'POST', array('class' => 'backpackform')); - if (isset($backpack->totalbadges) && $backpack->totalbadges !== 0) { - $externalhtml .= '

' . $this->print_badges_list($backpack->badges, $USER->id, true, true); - } $externalhtml .= html_writer::end_tag('fieldset'); } @@ -994,7 +991,7 @@ class badge_management extends badge_collection implements renderable { */ class badge_user_collection extends badge_collection implements renderable { /** @var array backpack settings */ - public $backpack; + public $backpack = null; /** @var string search */ public $search = ''; @@ -1006,7 +1003,11 @@ class badge_user_collection extends badge_collection implements renderable { * @param int $userid Badges owner */ public function __construct($badges, $userid) { + global $CFG; parent::__construct($badges); - $this->backpack = get_backpack_settings($userid); + + if (!empty($CFG->badges_allowexternalbackpack)) { + $this->backpack = get_backpack_settings($userid); + } } } diff --git a/lang/en/badges.php b/lang/en/badges.php index d8ea4214622..9d26764589a 100644 --- a/lang/en/badges.php +++ b/lang/en/badges.php @@ -79,14 +79,29 @@ If your site is not yet live you can create and issue test badges, as long as th ##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->backpackurl}.
'; +$string['backpackbadges'] = 'You have {$a->totalbadges} badge(s) displayed from {$a->totalcollections} collection(s). Change backpack settings.'; +$string['backpackconnection'] = 'Backpack connection'; +$string['backpackconnection_help'] = 'This page allows you to set up connection to an external backpack provider. Connecting to a backpack lets you display external badges within this site and push badges earned here to your backpack. + +Currently, only Mozilla OpenBadges Backpack is supported. You need to sign up for a backpack service before trying to set up backpack connection on this page.'; $string['backpackdetails'] = 'Backpack settings'; +$string['backpackemail'] = 'Email address'; +$string['backpackemail_help'] = 'Email address associated with your backpack'; +$string['backpackimport'] = 'Badge import settings'; +$string['backpackimport_help'] = 'After backpack connection is successfully established, badges from your backpack can be displayed on your "My Badges" page and your profile page. + +In this area, you can select collections of badges from your backpack that you would like to display in your profile.'; $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['badgeprivacysetting'] = 'Badge privacy settings'; +$string['badgeprivacysetting_help'] = 'Badges you earn can be displayed on your account profile page. This setting allows you to automatically set visibility of the newly earned badges. + +You can still control individual badge privacy settings on your My badges page.'; +$string['badgeprivacysetting_str'] = 'Automatically show badges I earn on my profile page'; $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.'; @@ -111,6 +126,8 @@ $string['completionnotenabled'] = 'Course completion is not enabled for this cou $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['connect'] = 'Connect'; +$string['connected'] = 'Connected'; $string['contact'] = 'Contact'; $string['contact_help'] = 'An email address associated with the badge issuer.'; $string['copyof'] = 'Copy of {$a}'; @@ -177,6 +194,7 @@ $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['disconnect'] = 'Disconnect'; $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'; @@ -192,8 +210,7 @@ $string['error:invalidexpireperiod'] = 'Expiry period cannot be negative or equa $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'] = '

There are no public collections of badges available in your backpack.

-

To display external badges, you will need to visit your backpack and make at least one collection of badges public.

-

If you already have backpack service connection established and your previously selected badge collection has been removed, clear these settings and try again.

'; +

Only public collections are shown, visit your backpack to create some public collections.

'; $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.'; @@ -215,13 +232,10 @@ $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['externalconnectto'] = 'To display external badges you need to connect to a backpack.'; $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 Mozilla OpenBadges Backpack 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['externalbadges_help'] = 'This area displays badges from your external backpack.'; $string['fixed'] = 'Fixed date'; $string['hidden'] = 'Hidden'; $string['hiddenbadge'] = 'Unfortunately, badge owner has not made this information available.'; @@ -231,6 +245,7 @@ $string['issuerdetails'] = 'Issuer details'; $string['issuername'] = 'Issuer name'; $string['issuername_help'] = 'Name of the issuing agent or authority.'; $string['issuerurl'] = 'Issuer URL'; +$string['localconnectto'] = 'To share these badges outside this web site you need to connect to a backpack.'; $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. @@ -257,13 +272,15 @@ $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.
'; -$string['nobackpackbadges'] = 'There are no badges displayed from your backpack at {$a->backpackurl}.
'; +$string['nobackpackbadges'] = 'There are no badges in the collections you have selected. Add more collections.'; +$string['nobackpackcollections'] = 'No badge collections have been selected. Add collections.'; $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.
If you would like to see users who have already earned this badge, you can visit {$a} page. '; +$string['notconnected'] = 'Not connected'; $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. @@ -295,7 +312,8 @@ $string['reviewconfirm'] = '

This action will perform a check if any of the us

Would you like to proceed?

'; $string['save'] = 'Save'; $string['searchname'] = 'Search by name'; -$string['selectgroup'] = 'Select badge collection'; +$string['selectgroup_end'] = 'Only public collections are shown, visit your backpack to create more public collections.'; +$string['selectgroup_start'] = 'Select collections from your backpack to display on this site:'; $string['selecting'] = 'With selected badges...'; $string['setup'] = 'Set up connection'; $string['sitebadges'] = 'Site badges'; diff --git a/lib/badgeslib.php b/lib/badgeslib.php index e5e4c3e0435..3c82be7d72d 100644 --- a/lib/badgeslib.php +++ b/lib/badgeslib.php @@ -387,8 +387,9 @@ class badge { $issued->dateexpire = null; } - // Issued badges always being issued as private. - $issued->visible = 0; + // Take into account user badges privacy settings. + // If none set, badges default visibility is set to public. + $issued->visible = get_user_preferences('badgeprivacysetting', 1, $userid); $result = $DB->insert_record('badge_issued', $issued, true); @@ -1150,7 +1151,7 @@ function badges_bake($hash, $badgeid, $userid = 0, $pathhash = false) { } /** - * Returns backpack service settings. + * Returns external backpack settings and badges from this backpack. * * @param int $userid Backpack user ID. * @return null|object Returns null is there is no backpack or object with backpack settings. @@ -1159,14 +1160,30 @@ function get_backpack_settings($userid) { global $DB; require_once(dirname(dirname(__FILE__)) . '/badges/lib/backpacklib.php'); - $record = $DB->get_record('badge_backpack', array('userid' => $userid), '*', IGNORE_MISSING); + $record = $DB->get_record('badge_backpack', array('userid' => $userid)); if ($record) { $backpack = new OpenBadgesBackpackHandler($record); $out = new stdClass(); $out->backpackurl = $backpack->get_url(); - $badges = $backpack->get_badges(); - $out->badges = isset($badges->badges) ? $badges->badges : array(); - $out->totalbadges = count($out->badges); + + if ($collections = $DB->get_records('badge_external', array('backpackid' => $record->id))) { + $out->totalcollections = count($collections); + $out->totalbadges = 0; + $out->badges = array(); + foreach ($collections as $collection) { + $badges = $backpack->get_badges($collection->collectionid); + if (isset($badges->badges)) { + $out->badges = array_merge($out->badges, $badges->badges); + $out->totalbadges += count($out->badges); + } else { + $out->badges = array_merge($out->badges, array()); + } + } + } else { + $out->totalbadges = 0; + $out->totalcollections = 0; + } + return $out; } @@ -1258,9 +1275,8 @@ function badges_check_backpack_accessibility() { $options = array( 'FRESH_CONNECT' => true, 'RETURNTRANSFER' => true, - 'FORBID_REUSE' => true, 'HEADER' => 0, - 'CONNECTTIMEOUT_MS' => 1000, + 'CONNECTTIMEOUT_MS' => 2000, ); $location = 'http://backpack.openbadges.org/baker'; $out = $curl->get($location, array('assertion' => $fakeassertion->out(false)), $options); @@ -1278,3 +1294,14 @@ function badges_check_backpack_accessibility() { return false; } + +/** + * Checks if user has external backpack connected. + * + * @param int $userid ID of a user. + * @return bool True|False whether backpack connection exists. + */ +function badges_user_has_backpack($userid) { + global $DB; + return $DB->record_exists('badge_backpack', array('userid' => $userid)); +} diff --git a/lib/db/install.xml b/lib/db/install.xml index ce95ce07454..3ee66b58cf2 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1,5 +1,5 @@ - @@ -3052,7 +3052,6 @@ - @@ -3061,5 +3060,16 @@ + + + + + + + + + + +
diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index ddefdd1f69a..0a4ce16032f 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -2000,5 +2000,47 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2013041200.00); } + if ($oldversion < 2013041500.00) { + // Create a new 'badge_external' table first. + // Define table 'badge_external' to be created. + $table = new xmldb_table('badge_external'); + + // Adding fields to table 'badge_external'. + $table->add_field('id', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null); + $table->add_field('backpackid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'id'); + $table->add_field('collectionid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, 'backpackid'); + + // Adding keys to table 'badge_external'. + $table->add_key('primary', XMLDB_KEY_PRIMARY, array('id')); + $table->add_key('fk_backpackid', XMLDB_KEY_FOREIGN, array('backpackid'), 'badge_backpack', array('id')); + + // Conditionally launch create table for 'badge_external'. + if (!$dbman->table_exists($table)) { + $dbman->create_table($table); + } + + // Perform user data migration. + $usercollections = $DB->get_records('badge_backpack'); + foreach ($usercollections as $usercollection) { + $collection = new stdClass(); + $collection->backpackid = $usercollection->id; + $collection->collectionid = $usercollection->backpackgid; + $DB->insert_record('badge_external', $collection); + } + + // Finally, drop the column. + // Define field backpackgid to be dropped from 'badge_backpack'. + $table = new xmldb_table('badge_backpack'); + $field = new xmldb_field('backpackgid'); + + // Conditionally launch drop field backpackgid. + if ($dbman->field_exists($table, $field)) { + $dbman->drop_field($table, $field); + } + + // Main savepoint reached. + upgrade_main_savepoint(true, 2013041500.00); + } + return true; } diff --git a/lib/navigationlib.php b/lib/navigationlib.php index 0e9e157d25d..adbe4f960a7 100644 --- a/lib/navigationlib.php +++ b/lib/navigationlib.php @@ -4049,6 +4049,15 @@ class settings_navigation extends navigation_node { } } + // Badges. + if ($currentuser && !empty($CFG->enablebadges)) { + $badges = $usersetting->add(get_string('badges'), null, navigation_node::TYPE_CONTAINER, null, 'badges'); + $badges->add(get_string('preferences'), new moodle_url('/badges/preferences.php'), navigation_node::TYPE_SETTING); + if (!empty($CFG->badges_allowexternalbackpack)) { + $badges->add(get_string('backpackdetails', 'badges'), new moodle_url('/badges/mybackpack.php'), navigation_node::TYPE_SETTING); + } + } + // Add reports node. $reporttab = $usersetting->add(get_string('activityreports')); $reports = get_plugin_list_with_function('report', 'extend_navigation_user', 'lib.php'); diff --git a/theme/base/style/core.css b/theme/base/style/core.css index b173532d859..14a5a2a19c2 100644 --- a/theme/base/style/core.css +++ b/theme/base/style/core.css @@ -1353,8 +1353,9 @@ 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; } +.connected { color: #006600; } +.notconnected { color: #660000; } #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; } diff --git a/version.php b/version.php index 5588236cdbb..d6cf9a7977c 100644 --- a/version.php +++ b/version.php @@ -29,7 +29,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2013041200.00; // YYYYMMDD = weekly release date of this DEV branch +$version = 2013041500.00; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes