From c776e1dd402b9e5a58efa359aef0b8c491cbe21d Mon Sep 17 00:00:00 2001 From: dpalou Date: Wed, 7 Nov 2018 16:45:28 +0100 Subject: [PATCH 1/3] MDL-63729 badges: Create an exporter for badge info --- badges/classes/external.php | 50 +--- .../classes/external/user_badge_exporter.php | 230 ++++++++++++++++++ 2 files changed, 242 insertions(+), 38 deletions(-) create mode 100644 badges/classes/external/user_badge_exporter.php diff --git a/badges/classes/external.php b/badges/classes/external.php index e5b2de0a2b9..c7a02934125 100644 --- a/badges/classes/external.php +++ b/badges/classes/external.php @@ -29,6 +29,8 @@ defined('MOODLE_INTERNAL') || die; require_once($CFG->libdir . '/externallib.php'); require_once($CFG->libdir . '/badgeslib.php'); +use core_badges\external\user_badge_exporter; + /** * Badges external functions * @@ -73,7 +75,7 @@ class core_badges_external extends external_api { * @throws moodle_exception */ public static function get_user_badges($userid = 0, $courseid = 0, $page = 0, $perpage = 0, $search = '', $onlypublic = false) { - global $CFG, $USER; + global $CFG, $USER, $PAGE; $warnings = array(); @@ -122,17 +124,13 @@ class core_badges_external extends external_api { foreach ($userbadges as $badge) { $context = ($badge->type == BADGE_TYPE_SITE) ? context_system::instance() : context_course::instance($badge->courseid); - $badge->badgeurl = moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', - 'f1')->out(false); - // Return all the information if we are requesting our own badges. - // Or, if we have permissions for configuring badges in the badge context. - if ($USER->id == $user->id or has_capability('moodle/badges:configuredetails', $context)) { - $result['badges'][] = (array) $badge; - } else { - $result['badges'][] = array( + + // If the user is viewing another user's badge and doesn't have the right capability return only part of the data. + if ($USER->id != $user->id and !has_capability('moodle/badges:configuredetails', $context)) { + $badge = (object) array( + 'id' => $badge->id, 'name' => $badge->name, 'description' => $badge->description, - 'badgeurl' => $badge->badgeurl, 'issuername' => $badge->issuername, 'issuerurl' => $badge->issuerurl, 'issuercontact' => $badge->issuercontact, @@ -141,6 +139,9 @@ class core_badges_external extends external_api { 'dateexpire' => $badge->dateexpire, ); } + + $exporter = new user_badge_exporter($badge, array('context' => $context)); + $result['badges'][] = $exporter->export($PAGE->get_renderer('core')); } return $result; @@ -156,34 +157,7 @@ class core_badges_external extends external_api { return new external_single_structure( array( 'badges' => new external_multiple_structure( - new external_single_structure( - array( - 'id' => new external_value(PARAM_INT, 'Badge id.', VALUE_OPTIONAL), - 'name' => new external_value(PARAM_TEXT, 'Badge name.'), - 'description' => new external_value(PARAM_NOTAGS, 'Badge description.'), - 'badgeurl' => new external_value(PARAM_URL, 'Badge URL.'), - 'timecreated' => new external_value(PARAM_INT, 'Time created.', VALUE_OPTIONAL), - 'timemodified' => new external_value(PARAM_INT, 'Time modified.', VALUE_OPTIONAL), - 'usercreated' => new external_value(PARAM_INT, 'User created.', VALUE_OPTIONAL), - 'usermodified' => new external_value(PARAM_INT, 'User modified.', VALUE_OPTIONAL), - 'issuername' => new external_value(PARAM_NOTAGS, 'Issuer name.'), - 'issuerurl' => new external_value(PARAM_URL, 'Issuer URL.'), - 'issuercontact' => new external_value(PARAM_RAW, 'Issuer contact.'), - 'expiredate' => new external_value(PARAM_INT, 'Expire date.', VALUE_OPTIONAL), - 'expireperiod' => new external_value(PARAM_INT, 'Expire period.', VALUE_OPTIONAL), - 'type' => new external_value(PARAM_INT, 'Type.', VALUE_OPTIONAL), - 'courseid' => new external_value(PARAM_INT, 'Course id.', VALUE_OPTIONAL), - 'message' => new external_value(PARAM_RAW, 'Message.', VALUE_OPTIONAL), - 'messagesubject' => new external_value(PARAM_TEXT, 'Message subject.', VALUE_OPTIONAL), - 'attachment' => new external_value(PARAM_INT, 'Attachment.', VALUE_OPTIONAL), - 'status' => new external_value(PARAM_INT, 'Status.', VALUE_OPTIONAL), - 'issuedid' => new external_value(PARAM_INT, 'Issued id.', VALUE_OPTIONAL), - 'uniquehash' => new external_value(PARAM_ALPHANUM, 'Unique hash.'), - 'dateissued' => new external_value(PARAM_INT, 'Date issued.'), - 'dateexpire' => new external_value(PARAM_INT, 'Date expire.'), - 'visible' => new external_value(PARAM_INT, 'Visible.', VALUE_OPTIONAL), - ) - ) + user_badge_exporter::get_read_structure() ), 'warnings' => new external_warnings(), ) diff --git a/badges/classes/external/user_badge_exporter.php b/badges/classes/external/user_badge_exporter.php new file mode 100644 index 00000000000..f9832c1b121 --- /dev/null +++ b/badges/classes/external/user_badge_exporter.php @@ -0,0 +1,230 @@ +. + +/** + * Contains user badge class for displaying a badge issued to a user. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_badges\external; + +defined('MOODLE_INTERNAL') || die(); + +use core\external\exporter; +use renderer_base; +use moodle_url; + +/** + * Class for displaying a badge issued to a user. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class user_badge_exporter extends exporter { + + /** + * Return the list of properties. + * + * @return array + */ + protected static function define_properties() { + return [ + 'id' => [ + 'type' => PARAM_INT, + 'description' => 'Badge id', + 'optional' => true, + ], + 'name' => [ + 'type' => PARAM_TEXT, + 'description' => 'Badge name', + ], + 'description' => [ + 'type' => PARAM_NOTAGS, + 'description' => 'Badge description', + 'null' => NULL_ALLOWED, + ], + 'timecreated' => [ + 'type' => PARAM_INT, + 'description' => 'Time created', + 'optional' => true, + 'default' => 0, + ], + 'timemodified' => [ + 'type' => PARAM_INT, + 'description' => 'Time modified', + 'optional' => true, + 'default' => 0, + ], + 'usercreated' => [ + 'type' => PARAM_INT, + 'description' => 'User created', + 'optional' => true, + ], + 'usermodified' => [ + 'type' => PARAM_INT, + 'description' => 'User modified', + 'optional' => true, + ], + 'issuername' => [ + 'type' => PARAM_NOTAGS, + 'description' => 'Issuer name', + ], + 'issuerurl' => [ + 'type' => PARAM_URL, + 'description' => 'Issuer URL', + ], + 'issuercontact' => [ + 'type' => PARAM_RAW, + 'description' => 'Issuer contact', + 'null' => NULL_ALLOWED, + ], + 'expiredate' => [ + 'type' => PARAM_INT, + 'description' => 'Expire date', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'expireperiod' => [ + 'type' => PARAM_INT, + 'description' => 'Expire period', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'type' => [ + 'type' => PARAM_INT, + 'description' => 'Type', + 'optional' => true, + 'default' => 1, + ], + 'courseid' => [ + 'type' => PARAM_INT, + 'description' => 'Course id', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'message' => [ + 'type' => PARAM_RAW, + 'description' => 'Message', + 'optional' => true, + ], + 'messagesubject' => [ + 'type' => PARAM_TEXT, + 'description' => 'Message subject', + 'optional' => true, + ], + 'attachment' => [ + 'type' => PARAM_INT, + 'description' => 'Attachment', + 'optional' => true, + 'default' => 1, + ], + 'notification' => [ + 'type' => PARAM_INT, + 'description' => 'Whether to notify when badge is awarded', + 'optional' => true, + 'default' => 1, + ], + 'nextcron' => [ + 'type' => PARAM_INT, + 'description' => 'Next cron', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'status' => [ + 'type' => PARAM_INT, + 'description' => 'Status', + 'optional' => true, + 'default' => 0, + ], + 'issuedid' => [ + 'type' => PARAM_INT, + 'description' => 'Issued id', + 'optional' => true, + ], + 'uniquehash' => [ + 'type' => PARAM_ALPHANUM, + 'description' => 'Unique hash', + ], + 'dateissued' => [ + 'type' => PARAM_INT, + 'description' => 'Date issued', + 'default' => 0, + ], + 'dateexpire' => [ + 'type' => PARAM_INT, + 'description' => 'Date expire', + 'null' => NULL_ALLOWED, + ], + 'visible' => [ + 'type' => PARAM_INT, + 'description' => 'Visible', + 'optional' => true, + 'default' => 0, + ], + 'email' => [ + 'type' => PARAM_TEXT, + 'description' => 'User email', + 'optional' => true, + ], + ]; + } + + /** + * Returns a list of objects that are related. + * + * @return array + */ + protected static function define_related() { + return array( + 'context' => 'context' + ); + } + + /** + * Return the list of additional properties. + * + * @return array + */ + protected static function define_other_properties() { + return [ + 'badgeurl' => [ + 'type' => PARAM_URL, + 'description' => 'Badge URL', + ], + ]; + } + + /** + * Get the additional values to inject while exporting. + * + * @param renderer_base $output The renderer. + * @return array Keys are the property names, values are their values. + */ + protected function get_other_values(renderer_base $output) { + $context = $this->related['context']; + + $values = array( + 'badgeurl' => moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $this->data->id, '/', + 'f1')->out(false), + ); + + return $values; + } +} From 18d27ac2eb467ff1bceed31eb335b034ff17092c Mon Sep 17 00:00:00 2001 From: dpalou Date: Thu, 8 Nov 2018 09:24:48 +0100 Subject: [PATCH 2/3] MDL-63729 badges: Return new fields in badge table in WS --- badges/classes/external.php | 6 ++++ .../classes/external/user_badge_exporter.php | 36 +++++++++++++++++++ badges/tests/external_test.php | 21 +++++++++-- 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/badges/classes/external.php b/badges/classes/external.php index c7a02934125..19a764d2610 100644 --- a/badges/classes/external.php +++ b/badges/classes/external.php @@ -137,6 +137,12 @@ class core_badges_external extends external_api { 'uniquehash' => $badge->uniquehash, 'dateissued' => $badge->dateissued, 'dateexpire' => $badge->dateexpire, + 'version' => $badge->version, + 'language' => $badge->language, + 'imageauthorname' => $badge->imageauthorname, + 'imageauthoremail' => $badge->imageauthoremail, + 'imageauthorurl' => $badge->imageauthorurl, + 'imagecaption' => $badge->imagecaption, ); } diff --git a/badges/classes/external/user_badge_exporter.php b/badges/classes/external/user_badge_exporter.php index f9832c1b121..0e284fb4a5d 100644 --- a/badges/classes/external/user_badge_exporter.php +++ b/badges/classes/external/user_badge_exporter.php @@ -183,6 +183,42 @@ class user_badge_exporter extends exporter { 'description' => 'User email', 'optional' => true, ], + 'version' => [ + 'type' => PARAM_TEXT, + 'description' => 'Version', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'language' => [ + 'type' => PARAM_NOTAGS, + 'description' => 'Language', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'imageauthorname' => [ + 'type' => PARAM_TEXT, + 'description' => 'Name of the image author', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'imageauthoremail' => [ + 'type' => PARAM_TEXT, + 'description' => 'Email of the image author', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'imageauthorurl' => [ + 'type' => PARAM_URL, + 'description' => 'URL of the image author', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'imagecaption' => [ + 'type' => PARAM_TEXT, + 'description' => 'Caption of the image', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], ]; } diff --git a/badges/tests/external_test.php b/badges/tests/external_test.php index 77db1a40c6e..1176b9fa6c9 100644 --- a/badges/tests/external_test.php +++ b/badges/tests/external_test.php @@ -85,6 +85,12 @@ class core_badges_external_testcase extends externallib_advanced_testcase { $badge->attachment = 1; $badge->notification = 0; $badge->status = BADGE_STATUS_ACTIVE; + $badge->version = '1'; + $badge->language = 'en'; + $badge->imageauthorname = 'Image author'; + $badge->imageauthoremail = 'imageauthor@example.com'; + $badge->imageauthorurl = 'http://image-author-url.domain.co.nz'; + $badge->imagecaption = 'Caption'; $badgeid = $DB->insert_record('badge', $badge, true); $badge = new badge($badgeid); @@ -116,15 +122,26 @@ class core_badges_external_testcase extends externallib_advanced_testcase { $this->setUser($this->student); + $badges = (array) badges_get_user_badges($this->student->id); + $expectedbadges = array(); + + foreach ($badges as $badge) { + $context = ($badge->type == BADGE_TYPE_SITE) ? context_system::instance() : context_course::instance($badge->courseid); + $badge->badgeurl = moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', + 'f1')->out(false); + + $expectedbadges[] = (array) $badge; + } + $result = core_badges_external::get_user_badges(); $result = external_api::clean_returnvalue(core_badges_external::get_user_badges_returns(), $result); - $this->assertCount(2, $result['badges']); + $this->assertEquals($expectedbadges, $result['badges']); // Pagination and filtering. $result = core_badges_external::get_user_badges(0, $this->course->id, 0, 1, '', true); $result = external_api::clean_returnvalue(core_badges_external::get_user_badges_returns(), $result); $this->assertCount(1, $result['badges']); - $this->assertEquals($this->course->id, $result['badges'][0]['courseid']); + $this->assertEquals($expectedbadges[1], $result['badges'][0]); } /** From 5bb1889f43ea188908d2e020948700f1ba6c5ca1 Mon Sep 17 00:00:00 2001 From: dpalou Date: Fri, 9 Nov 2018 08:53:13 +0100 Subject: [PATCH 3/3] MDL-63729 badges: Return new DB tables data in WS --- badges/classes/external.php | 38 +++++++- .../classes/external/competency_exporter.php | 94 ++++++++++++++++++ .../classes/external/endorsement_exporter.php | 95 +++++++++++++++++++ .../external/related_info_exporter.php | 85 +++++++++++++++++ .../classes/external/user_badge_exporter.php | 49 +++++++++- badges/tests/external_test.php | 80 +++++++++++++++- badges/upgrade.txt | 4 + 7 files changed, 438 insertions(+), 7 deletions(-) create mode 100644 badges/classes/external/competency_exporter.php create mode 100644 badges/classes/external/endorsement_exporter.php create mode 100644 badges/classes/external/related_info_exporter.php diff --git a/badges/classes/external.php b/badges/classes/external.php index 19a764d2610..15437d09c2f 100644 --- a/badges/classes/external.php +++ b/badges/classes/external.php @@ -124,9 +124,10 @@ class core_badges_external extends external_api { foreach ($userbadges as $badge) { $context = ($badge->type == BADGE_TYPE_SITE) ? context_system::instance() : context_course::instance($badge->courseid); + $canconfiguredetails = has_capability('moodle/badges:configuredetails', $context); // If the user is viewing another user's badge and doesn't have the right capability return only part of the data. - if ($USER->id != $user->id and !has_capability('moodle/badges:configuredetails', $context)) { + if ($USER->id != $user->id and !$canconfiguredetails) { $badge = (object) array( 'id' => $badge->id, 'name' => $badge->name, @@ -146,7 +147,40 @@ class core_badges_external extends external_api { ); } - $exporter = new user_badge_exporter($badge, array('context' => $context)); + // Create a badge instance to be able to get the endorsement and other info. + $badgeinstance = new badge($badge->id); + $endorsement = $badgeinstance->get_endorsement(); + $competencies = $badgeinstance->get_alignment(); + $relatedbadges = $badgeinstance->get_related_badges(); + + if (!$canconfiguredetails) { + // Return only the properties visible by the user. + + if (!empty($competencies)) { + foreach ($competencies as $competency) { + unset($competency->targetdescription); + unset($competency->targetframework); + unset($competency->targetcode); + } + } + + if (!empty($relatedbadges)) { + foreach ($relatedbadges as $relatedbadge) { + unset($relatedbadge->version); + unset($relatedbadge->language); + unset($relatedbadge->type); + } + } + } + + $related = array( + 'context' => $context, + 'endorsement' => $endorsement ? $endorsement : null, + 'competencies' => $competencies, + 'relatedbadges' => $relatedbadges, + ); + + $exporter = new user_badge_exporter($badge, $related); $result['badges'][] = $exporter->export($PAGE->get_renderer('core')); } diff --git a/badges/classes/external/competency_exporter.php b/badges/classes/external/competency_exporter.php new file mode 100644 index 00000000000..3eca46a2027 --- /dev/null +++ b/badges/classes/external/competency_exporter.php @@ -0,0 +1,94 @@ +. + +/** + * Contains competency class for displaying a badge competency. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_badges\external; + +defined('MOODLE_INTERNAL') || die(); + +use core\external\exporter; + +/** + * Class for displaying a badge competency. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class competency_exporter extends exporter { + + /** + * Return the list of properties. + * + * @return array + */ + protected static function define_properties() { + return [ + 'id' => [ + 'type' => PARAM_INT, + 'description' => 'Competency id', + ], + 'badgeid' => [ + 'type' => PARAM_INT, + 'description' => 'Badge id', + ], + 'targetname' => [ + 'type' => PARAM_TEXT, + 'description' => 'Target name', + ], + 'targeturl' => [ + 'type' => PARAM_URL, + 'description' => 'Target URL', + ], + 'targetdescription' => [ + 'type' => PARAM_TEXT, + 'description' => 'Target description', + 'null' => NULL_ALLOWED, + 'optional' => true, + ], + 'targetframework' => [ + 'type' => PARAM_TEXT, + 'description' => 'Target framework', + 'null' => NULL_ALLOWED, + 'optional' => true, + ], + 'targetcode' => [ + 'type' => PARAM_TEXT, + 'description' => 'Target code', + 'null' => NULL_ALLOWED, + 'optional' => true, + ] + ]; + } + + /** + * Returns a list of objects that are related. + * + * @return array + */ + protected static function define_related() { + return array( + 'context' => 'context', + ); + } +} diff --git a/badges/classes/external/endorsement_exporter.php b/badges/classes/external/endorsement_exporter.php new file mode 100644 index 00000000000..80e4ddeb670 --- /dev/null +++ b/badges/classes/external/endorsement_exporter.php @@ -0,0 +1,95 @@ +. + +/** + * Contains endorsement class for displaying a badge endorsement. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_badges\external; + +defined('MOODLE_INTERNAL') || die(); + +use core\external\exporter; + +/** + * Class for displaying a badge endorsement. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class endorsement_exporter extends exporter { + + /** + * Return the list of properties. + * + * @return array + */ + protected static function define_properties() { + return [ + 'id' => [ + 'type' => PARAM_INT, + 'description' => 'Endorsement id', + ], + 'badgeid' => [ + 'type' => PARAM_INT, + 'description' => 'Badge id', + ], + 'issuername' => [ + 'type' => PARAM_TEXT, + 'description' => 'Endorsement issuer name', + ], + 'issuerurl' => [ + 'type' => PARAM_URL, + 'description' => 'Endorsement issuer URL', + ], + 'issueremail' => [ + 'type' => PARAM_RAW, + 'description' => 'Endorsement issuer email', + ], + 'claimid' => [ + 'type' => PARAM_URL, + 'description' => 'Claim URL', + 'null' => NULL_ALLOWED, + ], + 'claimcomment' => [ + 'type' => PARAM_NOTAGS, + 'description' => 'Claim comment', + 'null' => NULL_ALLOWED, + ], + 'dateissued' => [ + 'type' => PARAM_INT, + 'description' => 'Date issued', + 'default' => 0, + ] + ]; + } + + /** + * Returns a list of objects that are related. + * + * @return array + */ + protected static function define_related() { + return array( + 'context' => 'context', + ); + } +} diff --git a/badges/classes/external/related_info_exporter.php b/badges/classes/external/related_info_exporter.php new file mode 100644 index 00000000000..83bee1e7c56 --- /dev/null +++ b/badges/classes/external/related_info_exporter.php @@ -0,0 +1,85 @@ +. + +/** + * Contains related class for displaying information of a related badge. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace core_badges\external; + +defined('MOODLE_INTERNAL') || die(); + +use core\external\exporter; + +/** + * Class for displaying information of a related badge. + * + * @package core_badges + * @copyright 2018 Dani Palou + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +class related_info_exporter extends exporter { + + /** + * Return the list of properties. + * + * @return array + */ + protected static function define_properties() { + return [ + 'id' => [ + 'type' => PARAM_INT, + 'description' => 'Badge id', + ], + 'name' => [ + 'type' => PARAM_TEXT, + 'description' => 'Badge name', + ], + 'version' => [ + 'type' => PARAM_TEXT, + 'description' => 'Version', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'language' => [ + 'type' => PARAM_NOTAGS, + 'description' => 'Language', + 'optional' => true, + 'null' => NULL_ALLOWED, + ], + 'type' => [ + 'type' => PARAM_INT, + 'description' => 'Type', + 'optional' => true, + ], + ]; + } + + /** + * Returns a list of objects that are related. + * + * @return array + */ + protected static function define_related() { + return array( + 'context' => 'context', + ); + } +} diff --git a/badges/classes/external/user_badge_exporter.php b/badges/classes/external/user_badge_exporter.php index 0e284fb4a5d..0cc7269da3e 100644 --- a/badges/classes/external/user_badge_exporter.php +++ b/badges/classes/external/user_badge_exporter.php @@ -29,6 +29,9 @@ defined('MOODLE_INTERNAL') || die(); use core\external\exporter; use renderer_base; use moodle_url; +use core_badges\external\endorsement_exporter; +use core_badges\external\competency_exporter; +use core_badges\external\related_info_exporter; /** * Class for displaying a badge issued to a user. @@ -229,7 +232,10 @@ class user_badge_exporter extends exporter { */ protected static function define_related() { return array( - 'context' => 'context' + 'context' => 'context', + 'endorsement' => 'stdClass?', + 'competencies' => 'stdClass[]', + 'relatedbadges' => 'stdClass[]', ); } @@ -244,6 +250,21 @@ class user_badge_exporter extends exporter { 'type' => PARAM_URL, 'description' => 'Badge URL', ], + 'endorsement' => [ + 'type' => endorsement_exporter::read_properties_definition(), + 'description' => 'Badge endorsement', + 'optional' => true, + ], + 'competencies' => [ + 'type' => competency_exporter::read_properties_definition(), + 'description' => 'Badge competencies (alignment)', + 'multiple' => true, + ], + 'relatedbadges' => [ + 'type' => related_info_exporter::read_properties_definition(), + 'description' => 'Related badges', + 'multiple' => true, + ] ]; } @@ -255,12 +276,36 @@ class user_badge_exporter extends exporter { */ protected function get_other_values(renderer_base $output) { $context = $this->related['context']; + $endorsement = $this->related['endorsement']; + $competencies = $this->related['competencies']; + $relatedbadges = $this->related['relatedbadges']; $values = array( 'badgeurl' => moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $this->data->id, '/', - 'f1')->out(false), + 'f1')->out(false), + 'competencies' => array(), + 'relatedbadges' => array(), ); + if ($endorsement) { + $endorsementexporter = new endorsement_exporter($endorsement, array('context' => $context)); + $values['endorsement'] = $endorsementexporter->export($output); + } + + if (!empty($competencies)) { + foreach ($competencies as $competency) { + $competencyexporter = new competency_exporter($competency, array('context' => $context)); + $values['competencies'][] = $competencyexporter->export($output); + } + } + + if (!empty($relatedbadges)) { + foreach ($relatedbadges as $badge) { + $relatedexporter = new related_info_exporter($badge, array('context' => $context)); + $values['relatedbadges'][] = $relatedexporter->export($output); + } + } + return $values; } } diff --git a/badges/tests/external_test.php b/badges/tests/external_test.php index 1176b9fa6c9..6cf9ad53584 100644 --- a/badges/tests/external_test.php +++ b/badges/tests/external_test.php @@ -99,6 +99,34 @@ class core_badges_external_testcase extends externallib_advanced_testcase { // Hack the database to adjust the time each badge was issued. $DB->set_field('badge_issued', 'dateissued', $now - 11, array('userid' => $this->student->id, 'badgeid' => $badgeid)); + // Add an endorsement for the badge. + $endorsement = new stdClass(); + $endorsement->badgeid = $badgeid; + $endorsement->issuername = 'Issuer name'; + $endorsement->issuerurl = 'http://endorsement-issuer-url.domain.co.nz'; + $endorsement->issueremail = 'endorsementissuer@example.com'; + $endorsement->claimid = 'http://claim-url.domain.co.nz'; + $endorsement->claimcomment = 'Claim comment'; + $endorsement->dateissued = $now; + $badge->save_endorsement($endorsement); + + // Add 2 competencies. + $competency = new stdClass(); + $competency->badgeid = $badgeid; + $competency->targetname = 'Competency 1'; + $competency->targeturl = 'http://c1-target-url.domain.co.nz'; + $competency->targetdescription = 'C1 target description'; + $competency->targetframework = 'C1 framework'; + $competency->targetcode = 'C1 code'; + $badge->save_alignment($competency); + + $competency->targetname = 'Competency 2'; + $competency->targeturl = 'http://c2-target-url.domain.co.nz'; + $competency->targetdescription = 'C2 target description'; + $competency->targetframework = 'C2 framework'; + $competency->targetcode = 'C2 code'; + $badge->save_alignment($competency); + // Now a course badge. $badge->id = null; $badge->name = "Test badge course"; @@ -106,12 +134,15 @@ class core_badges_external_testcase extends externallib_advanced_testcase { $badge->type = BADGE_TYPE_COURSE; $badge->courseid = $this->course->id; - $badgeid = $DB->insert_record('badge', $badge, true); - $badge = new badge($badgeid); + $coursebadgeid = $DB->insert_record('badge', $badge, true); + $badge = new badge($coursebadgeid); $badge->issue($this->student->id, true); // Hack the database to adjust the time each badge was issued. - $DB->set_field('badge_issued', 'dateissued', $now - 11, array('userid' => $this->student->id, 'badgeid' => $badgeid)); + $DB->set_field('badge_issued', 'dateissued', $now - 11, array('userid' => $this->student->id, 'badgeid' => $coursebadgeid)); + + // Make the site badge a related badge. + $badge->add_related_badges(array($badgeid)); } /** @@ -130,6 +161,40 @@ class core_badges_external_testcase extends externallib_advanced_testcase { $badge->badgeurl = moodle_url::make_webservice_pluginfile_url($context->id, 'badges', 'badgeimage', $badge->id, '/', 'f1')->out(false); + // Get the endorsement, competencies and related badges. + $badgeinstance = new badge($badge->id); + $endorsement = $badgeinstance->get_endorsement(); + $competencies = $badgeinstance->get_alignment(); + $relatedbadges = $badgeinstance->get_related_badges(); + $badge->competencies = array(); + $badge->relatedbadges = array(); + + if ($endorsement) { + $badge->endorsement = (array) $endorsement; + } + + if (!empty($competencies)) { + foreach ($competencies as $competency) { + // Students cannot see some fields of the competencies. + unset($competency->targetdescription); + unset($competency->targetframework); + unset($competency->targetcode); + + $badge->competencies[] = (array) $competency; + } + } + + if (!empty($relatedbadges)) { + foreach ($relatedbadges as $relatedbadge) { + // Students cannot see some fields of the related badges. + unset($relatedbadge->version); + unset($relatedbadge->language); + unset($relatedbadge->type); + + $badge->relatedbadges[] = (array) $relatedbadge; + } + } + $expectedbadges[] = (array) $badge; } @@ -160,6 +225,15 @@ class core_badges_external_testcase extends externallib_advanced_testcase { foreach ($result['badges'] as $badge) { if (isset($badge['type']) and $badge['type'] == BADGE_TYPE_COURSE) { $this->assertTrue(isset($badge['message'])); + + // Check that we have permissions to see all the data in competencies and related badges. + foreach ($badge['competencies'] as $competency) { + $this->assertTrue(isset($competency['targetdescription'])); + } + + foreach ($badge['relatedbadges'] as $relatedbadge) { + $this->assertTrue(isset($relatedbadge['type'])); + } } else { $this->assertFalse(isset($badge['message'])); } diff --git a/badges/upgrade.txt b/badges/upgrade.txt index 8dd1f87f7c8..8b2039407c3 100644 --- a/badges/upgrade.txt +++ b/badges/upgrade.txt @@ -1,6 +1,10 @@ This files describes API changes in /badges/*, information provided here is intended especially for developers. +=== 3.6 === + +* The WebService core_badges_get_user_badges now returns more information for each badge: notification, nextcron, email, version, language, imageauthorname, imageauthoremail, imageauthorurl, imagecaption, endorsement, competencies and relatedbadges. + === 2.7 === * get_completed_criteria_sql() - This method was added to award_criteria class and must be overriden