MDL-39063 badges: Improve external backpack usability and workflow
authorYuliya Bozhko <yuliya.bozhko@totaralms.com>
Mon, 15 Apr 2013 22:47:40 +0000 (10:47 +1200)
committerYuliya Bozhko <yuliya.bozhko@totaralms.com>
Mon, 15 Apr 2013 22:47:40 +0000 (10:47 +1200)
17 files changed:
admin/settings/badges.php
badges/action.php
badges/backpack_form.php
badges/edit_form.php
badges/index.php
badges/lib/backpacklib.php
badges/mybackpack.php
badges/preferences.php [new file with mode: 0644]
badges/preferences_form.php [new file with mode: 0644]
badges/renderer.php
lang/en/badges.php
lib/badgeslib.php
lib/db/install.xml
lib/db/upgrade.php
lib/navigationlib.php
theme/base/style/core.css
version.php

index 7e6f41e..a1cbca3 100644 (file)
@@ -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'
+            )
         )
     );
 
index 33181a5..ae38fa7 100644 (file)
@@ -125,7 +125,7 @@ if ($activate) {
         } else {
             $awards = $badge->review_all_criteria();
             $returnurl->param('awards', $awards);
-         }
+        }
         redirect($returnurl);
     }
 
index dbe42e8..dce0630 100644 (file)
@@ -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'];
-
-        $selet = array();
-        foreach ($groups as $group) {
-            $select[$group->groupId] = $group->name;
+        $email = $this->_customdata['email'];
+        $bid = $this->_customdata['backpackid'];
+        $selected = $this->_customdata['selected'];
+
+        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'));
-
-        $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);
+        $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('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
+}
index 768cc95..7ebe2f4 100644 (file)
@@ -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) {
index 64d6fe8..56176fb 100644 (file)
@@ -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);
 }
 
index f38a066..3cc9f88 100644 (file)
@@ -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);
             }
         }
     }
index c5bee65..813550c 100644 (file)
@@ -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'));
+$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
 
-if ($clear) {
-     $DB->delete_records('badge_backpack', array('userid' => $USER->id));
-     redirect(new moodle_url('/badges/mybadges.php'));
+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'));
 }
 
-$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
-
 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();
-
-            // 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);
+    } else if ($data = $form->get_data()) {
+        $bp = new OpenBadgesBackpackHandler($data);
 
-        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'));
-        }
+        $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);
 
-        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 (file)
index 0000000..edb7718
--- /dev/null
@@ -0,0 +1,65 @@
+<?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/>.
+
+/**
+ * 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 <yuliya.bozhko@totaralms.com>
+ */
+
+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 (file)
index 0000000..7bfe8f8
--- /dev/null
@@ -0,0 +1,47 @@
+<?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 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 <yuliya.bozhko@totaralms.com>
+ */
+
+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();
+    }
+}
index be5e26a..10fc496 100644 (file)
@@ -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);
-                }
-            }
-            $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)));
+        $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->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);
+        }
+        $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);
-            }
+        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']);
-                }
+        $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();
-                    }
+        // 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);
+        $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');
-        }
+        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 .= '<br/><br/>' . $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 .= '<br/><br/>' . $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);
+        }
     }
 }
index d8ea421..9d26764 100644 (file)
@@ -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 href="{$a->backpackurl}">{$a->backpackurl}</a>.<br/>';
+$string['backpackbadges'] = 'You have {$a->totalbadges} badge(s) displayed from {$a->totalcollections} collection(s). <a href="mybackpack.php">Change backpack settings</a>.';
+$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 <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.';
 $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 <a href="mybadges.php">My badges</a> 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'] = '<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>';
+<p>Only public collections are shown, <a href="http://backpack.openbadges.org">visit your backpack</a> to create some public collections.</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.';
@@ -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 <a href="{$a}">connect to a backpack</a>.';
 $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['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 <a href="{$a}">connect to a backpack</a>.';
 $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.<br/>';
-$string['nobackpackbadges'] = 'There are no badges displayed from your backpack at <a href="{$a->backpackurl}">{$a->backpackurl}</a>.<br/>';
+$string['nobackpackbadges'] = 'There are no badges in the collections you have selected. <a href="mybackpack.php">Add more collections</a>.';
+$string['nobackpackcollections'] = 'No badge collections have been selected. <a href="mybackpack.php">Add collections</a>.';
 $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['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'] = '<p>This action will perform a check if any of the us
 <p>Would you like to proceed?</p>';
 $string['save'] = 'Save';
 $string['searchname'] = 'Search by name';
-$string['selectgroup'] = 'Select badge collection';
+$string['selectgroup_end'] = 'Only public collections are shown, <a href="http://backpack.openbadges.org">visit your backpack</a> 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';
index e5e4c3e..3c82be7 100644 (file)
@@ -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));
+}
index ce95ce0..3ee66b5 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20130405" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20130412" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <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>
         <KEY NAME="fk_userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id"/>
       </KEYS>
     </TABLE>
+    <TABLE NAME="badge_external" COMMENT="Setting for external badges display">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
+        <FIELD NAME="backpackid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of a backpack"/>
+        <FIELD NAME="collectionid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Badge collection id in the backpack"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id"/>
+        <KEY NAME="fk_backpackid" TYPE="foreign" FIELDS="backpackid" REFTABLE="badge_backpack" REFFIELDS="id"/>
+      </KEYS>
+    </TABLE>
   </TABLES>
 </XMLDB>
index ddefdd1..0a4ce16 100644 (file)
@@ -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;
 }
index 0e9e157..adbe4f9 100644 (file)
@@ -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');
index b173532..14a5a2a 100644 (file)
@@ -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; }
index 5588236..d6cf9a7 100644 (file)
@@ -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