MDL-85621 core_badges: Replace manual JSON with exporters
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
issueNumber: MDL-85621
|
||||
notes:
|
||||
core_badges:
|
||||
- message: >-
|
||||
The class core_badges_assertion has been deprecated and replaced by
|
||||
\core_badges\achievement_credential.
|
||||
The method badges_get_default_issuer() has also been deprecated because
|
||||
it is no longer needed.
|
||||
The file badges/endorsement.php has been removed because it stopped being used
|
||||
when MDL-84323 was integrated.
|
||||
type: deprecated
|
||||
@@ -25,6 +25,8 @@
|
||||
require_once(__DIR__ . '/../config.php');
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
|
||||
use core_badges\local\backpack\helper;
|
||||
|
||||
require_login();
|
||||
|
||||
$userbackpack = badges_get_user_backpack();
|
||||
@@ -32,13 +34,13 @@ if (badges_open_badges_backpack_api($userbackpack->id) != OPEN_BADGES_V2) {
|
||||
throw new coding_exception('No backpacks support Open Badges V2.');
|
||||
}
|
||||
|
||||
$id = required_param('hash', PARAM_ALPHANUM);
|
||||
$assertionhash = required_param('hash', PARAM_ALPHANUM);
|
||||
|
||||
$PAGE->set_url('/badges/backpack-add.php', array('hash' => $id));
|
||||
$PAGE->set_url('/badges/backpack-add.php', ['hash' => $assertionhash]);
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$output = $PAGE->get_renderer('core', 'badges');
|
||||
|
||||
$issuedbadge = new \core_badges\output\issued_badge($id);
|
||||
$issuedbadge = new \core_badges\output\issued_badge($assertionhash);
|
||||
if (!empty($issuedbadge->recipient->id)) {
|
||||
// The flow for issuing a badge is:
|
||||
// * Create issuer
|
||||
@@ -55,9 +57,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$badge = new badge($badgeid);
|
||||
$backpack = $DB->get_record('badge_backpack', array('userid' => $USER->id));
|
||||
$userbackpack = badges_get_site_backpack($backpack->externalbackpackid, $USER->id);
|
||||
$assertion = new core_badges_assertion($id, OPEN_BADGES_V2);
|
||||
$assertiondata = $assertion->get_badge_assertion(false, false);
|
||||
$assertionid = $assertion->get_assertion_hash();
|
||||
$assertiondata = helper::export_achievement_credential(OPEN_BADGES_V2, $assertionhash, false, false);
|
||||
$assertionentityid = $assertiondata['id'];
|
||||
$badgeadded = false;
|
||||
$issuerexists = false;
|
||||
@@ -69,7 +69,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
// A numeric response indicates a valid successful authentication. Else an error object will be returned.
|
||||
if (is_numeric($response)) {
|
||||
// Create issuer.
|
||||
$issuer = $assertion->get_issuer();
|
||||
$issuer = helper::export_issuer(OPEN_BADGES_V2, $badgeid);
|
||||
if (!($issuerentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_ISSUER, $issuer['email']))) {
|
||||
$response = $api->put_issuer($issuer);
|
||||
if ($response) {
|
||||
@@ -85,8 +85,11 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
}
|
||||
if ($issuerexists) {
|
||||
// Create badge.
|
||||
$badge = $assertion->get_badge_class(false);
|
||||
$badgeid = $assertion->get_badge_id();
|
||||
$badge = helper::export_credential(
|
||||
OPEN_BADGES_V2,
|
||||
$badgeid,
|
||||
false,
|
||||
);
|
||||
if (!($badgeentityid = badges_external_get_mapping($sitebackpack->id, OPEN_BADGES_V2_TYPE_BADGE, $badgeid))) {
|
||||
$response = $api->put_badgeclass($issuerentityid, $badge);
|
||||
if ($response) {
|
||||
@@ -104,7 +107,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$assertionentityid = badges_external_get_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid
|
||||
$assertionhash
|
||||
);
|
||||
|
||||
if ($assertionentityid && strpos($sitebackpack->backpackapiurl, 'badgr')) {
|
||||
@@ -128,7 +131,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
badges_external_create_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
$assertionhash,
|
||||
$response->id,
|
||||
);
|
||||
}
|
||||
@@ -137,7 +140,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
$internalid = badges_external_get_mapping(
|
||||
$sitebackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
$assertionhash,
|
||||
'externalid'
|
||||
);
|
||||
$response = $api->update_assertion($internalid, $assertiondata);
|
||||
@@ -152,7 +155,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
// - This is only needed when the backpacks are from different regions.
|
||||
if (
|
||||
$assertionentityid
|
||||
&& (!$issuerexists || !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionid))
|
||||
&& (!$issuerexists || !badges_external_get_mapping($userbackpack->id, OPEN_BADGES_V2_TYPE_ASSERTION, $assertionhash))
|
||||
) {
|
||||
$userapi = new \core_badges\backpack_api($userbackpack, $backpack);
|
||||
$userapi->authenticate();
|
||||
@@ -163,7 +166,7 @@ if (!empty($issuedbadge->recipient->id)) {
|
||||
badges_external_create_mapping(
|
||||
$userbackpack->id,
|
||||
OPEN_BADGES_V2_TYPE_ASSERTION,
|
||||
$assertionid,
|
||||
$assertionhash,
|
||||
$assertionentityid,
|
||||
);
|
||||
}
|
||||
|
||||
+146
-142
@@ -16,6 +16,12 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
require_once($CFG->dirroot . '/badges/renderer.php');
|
||||
|
||||
use core_badges\local\backpack\helper;
|
||||
use core_badges\local\backpack\ob_factory;
|
||||
|
||||
/**
|
||||
* Open Badges Assertions specification 2.0
|
||||
* {@link https://www.imsglobal.org/sites/default/files/Badges/OBv2p0Final/index.html#Assertion}
|
||||
@@ -24,18 +30,19 @@ defined('MOODLE_INTERNAL') || die();
|
||||
* - Badge Assertion (information regarding a specific badge that was awarded to a badge earner)
|
||||
* - Badge Class (general information about a badge and what it is intended to represent)
|
||||
* - Issuer Class (general information of an issuing organisation)
|
||||
*/
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
require_once($CFG->dirroot . '/badges/renderer.php');
|
||||
|
||||
/**
|
||||
* Class that represents badge assertion.
|
||||
*
|
||||
* @package core_badges
|
||||
* @copyright 2012 onwards Totara Learning Solutions Ltd {@link http://www.totaralms.com/}
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @author Yuliya Bozhko <[email protected]>
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\achievement_credential',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
class core_badges_assertion {
|
||||
/** @var object Issued badge information from database */
|
||||
private $_data;
|
||||
@@ -51,10 +58,19 @@ class core_badges_assertion {
|
||||
*
|
||||
* @param string $hash Badge unique hash from badge_issued table.
|
||||
* @param int $obversion to control version JSON-LD.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\achievement_credential::instance()',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function __construct($hash, $obversion = OPEN_BADGES_V2) {
|
||||
global $DB;
|
||||
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$this->_data = $DB->get_record_sql('
|
||||
SELECT
|
||||
bi.dateissued,
|
||||
@@ -86,8 +102,17 @@ class core_badges_assertion {
|
||||
* Get the local id for this badge.
|
||||
*
|
||||
* @return int
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\achievement_credential::get_badge_id()',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_badge_id() {
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$badgeid = 0;
|
||||
if ($this->_data) {
|
||||
$badgeid = $this->_data->id;
|
||||
@@ -99,8 +124,17 @@ class core_badges_assertion {
|
||||
* Get the local id for this badge assertion.
|
||||
*
|
||||
* @return string
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\achievement_credential::get_hash()',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_assertion_hash() {
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$hash = '';
|
||||
if ($this->_data) {
|
||||
$hash = $this->_data->uniquehash;
|
||||
@@ -114,55 +148,23 @@ class core_badges_assertion {
|
||||
* @param boolean $issued Include the nested badge issued information.
|
||||
* @param boolean $usesalt Hash the identity and include the salt information for the hash.
|
||||
* @return array Badge assertion.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\helper::export_achievement_credential',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_badge_assertion($issued = true, $usesalt = true) {
|
||||
global $CFG;
|
||||
$assertion = array();
|
||||
if ($this->_data) {
|
||||
$hash = $this->_data->uniquehash;
|
||||
$email = empty($this->_data->backpackemail) ? $this->_data->email : $this->_data->backpackemail;
|
||||
$assertionurl = new moodle_url('/badges/assertion.php', array('b' => $hash, 'obversion' => $this->_obversion));
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
if ($this->_obversion >= OPEN_BADGES_V2) {
|
||||
$classurl = new moodle_url('/badges/badge_json.php', array('id' => $this->get_badge_id()));
|
||||
} else {
|
||||
$classurl = new moodle_url('/badges/assertion.php', array('b' => $hash, 'action' => 1));
|
||||
}
|
||||
|
||||
// Required.
|
||||
$assertion['uid'] = $hash;
|
||||
$assertion['recipient'] = array();
|
||||
if ($usesalt) {
|
||||
$assertion['recipient']['identity'] = 'sha256$' . hash('sha256', $email . $CFG->badges_badgesalt);
|
||||
} else {
|
||||
$assertion['recipient']['identity'] = $email;
|
||||
}
|
||||
$assertion['recipient']['type'] = 'email'; // Currently the only supported type.
|
||||
$assertion['recipient']['hashed'] = true; // We are always hashing recipient.
|
||||
if ($usesalt) {
|
||||
$assertion['recipient']['salt'] = $CFG->badges_badgesalt;
|
||||
}
|
||||
if ($issued) {
|
||||
$assertion['badge'] = $classurl->out(false);
|
||||
}
|
||||
$assertion['verify'] = array();
|
||||
$assertion['verify']['type'] = 'hosted'; // 'Signed' is not implemented yet.
|
||||
$assertion['verify']['url'] = $assertionurl->out(false);
|
||||
$assertion['issuedOn'] = $this->_data->dateissued;
|
||||
if ($issued) {
|
||||
$assertion['evidence'] = $this->_url->out(false); // Currently issued badge URL.
|
||||
}
|
||||
// Optional.
|
||||
if (!empty($this->_data->dateexpire)) {
|
||||
$assertion['expires'] = $this->_data->dateexpire;
|
||||
}
|
||||
$tags = $this->get_tags();
|
||||
if (is_array($tags) && count($tags) > 0) {
|
||||
$assertion['tags'] = $tags;
|
||||
}
|
||||
$this->embed_data_badge_version2($assertion, OPEN_BADGES_V2_TYPE_ASSERTION);
|
||||
}
|
||||
return $assertion;
|
||||
return helper::export_achievement_credential(
|
||||
helper::convert_apiversion($this->_obversion),
|
||||
$this->get_assertion_hash(),
|
||||
$issued,
|
||||
$usesalt,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,63 +172,43 @@ class core_badges_assertion {
|
||||
*
|
||||
* @param boolean $issued Include the nested badge issuer information.
|
||||
* @return array Badge Class information.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\helper::export_credential',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_badge_class($issued = true) {
|
||||
$class = [];
|
||||
if ($this->_data) {
|
||||
if (empty($this->_data->courseid)) {
|
||||
$context = context_system::instance();
|
||||
} else {
|
||||
$context = context_course::instance($this->_data->courseid);
|
||||
}
|
||||
// Required.
|
||||
$class['name'] = $this->_data->name;
|
||||
$class['description'] = $this->_data->description;
|
||||
$storage = get_file_storage();
|
||||
$imagefile = $storage->get_file($context->id, 'badges', 'badgeimage', $this->_data->id, '/', 'f3.png');
|
||||
if ($imagefile) {
|
||||
$imagedata = base64_encode($imagefile->get_content());
|
||||
} else {
|
||||
if (defined('PHPUNIT_TEST') && PHPUNIT_TEST) {
|
||||
// Unit tests the file might not exist yet.
|
||||
$imagedata = '';
|
||||
} else {
|
||||
throw new coding_exception('Image file does not exist.');
|
||||
}
|
||||
}
|
||||
$class['image'] = 'data:image/png;base64,' . $imagedata;
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$params = ['id' => $this->get_badge_id()];
|
||||
$badgeurl = new moodle_url('/badges/badgeclass.php', $params);
|
||||
$class['criteria'] = $badgeurl->out(false); // Currently badge URL.
|
||||
if ($issued) {
|
||||
$params = ['id' => $this->get_badge_id()];
|
||||
$issuerurl = new moodle_url('/badges/issuer_json.php', $params);
|
||||
$class['issuer'] = $issuerurl->out(false);
|
||||
}
|
||||
$tags = $this->get_tags();
|
||||
if (is_array($tags) && count($tags) > 0) {
|
||||
$class['tags'] = $tags;
|
||||
}
|
||||
$this->embed_data_badge_version2($class, OPEN_BADGES_V2_TYPE_BADGE);
|
||||
if (!$issued) {
|
||||
unset($class['issuer']);
|
||||
}
|
||||
}
|
||||
return $class;
|
||||
return helper::export_credential(
|
||||
helper::convert_apiversion($this->_obversion),
|
||||
$this->get_badge_id(),
|
||||
$issued,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get badge issuer information.
|
||||
*
|
||||
* @return array Issuer information.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\helper::export_issuer',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_issuer() {
|
||||
$badge = new badge($this->get_badge_id());
|
||||
$issuer = $badge->get_badge_issuer();
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$this->embed_data_badge_version2($issuer, OPEN_BADGES_V2_TYPE_ISSUER);
|
||||
return $issuer;
|
||||
return helper::export_issuer(
|
||||
helper::convert_apiversion($this->_obversion),
|
||||
$this->get_badge_id(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,32 +216,40 @@ class core_badges_assertion {
|
||||
*
|
||||
* @param badge $badge Badge object.
|
||||
* @return array|bool List related badges.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\ob\badge_exporter_interface::export_related_badges',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_related_badges(badge $badge) {
|
||||
global $DB;
|
||||
$arraybadges = array();
|
||||
$relatedbadges = $badge->get_related_badges(true);
|
||||
if ($relatedbadges) {
|
||||
foreach ($relatedbadges as $rb) {
|
||||
$url = new moodle_url('/badges/badge_json.php', array('id' => $rb->id));
|
||||
$arraybadges[] = array(
|
||||
'id' => $url->out(false),
|
||||
'version' => $rb->version,
|
||||
'@language' => $rb->language
|
||||
);
|
||||
}
|
||||
}
|
||||
return $arraybadges;
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$badgeexporter = ob_factory::create_badge_exporter_from_id(
|
||||
$badge->id,
|
||||
helper::convert_apiversion($this->_obversion),
|
||||
);
|
||||
return $badgeexporter->export_related_badges();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get endorsement of the badge.
|
||||
*
|
||||
* @return false|stdClass Endorsement information.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_endorsement() {
|
||||
global $DB;
|
||||
$endorsement = array();
|
||||
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$record = $DB->get_record_select('badge_endorsement', 'badgeid = ?', array($this->_data->id));
|
||||
return $record;
|
||||
}
|
||||
@@ -268,46 +258,44 @@ class core_badges_assertion {
|
||||
* Get criteria of badge class.
|
||||
*
|
||||
* @return array|string Criteria information.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\ob\badge_exporter_interface::export_criteria',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_criteria_badge_class() {
|
||||
$badge = new badge($this->_data->id);
|
||||
$narrative = $badge->markdown_badge_criteria();
|
||||
$params = ['id' => $this->get_badge_id()];
|
||||
$badgeurl = new moodle_url('/badges/badgeclass.php', $params);
|
||||
if (!empty($narrative)) {
|
||||
$criteria = [];
|
||||
$criteria['id'] = $badgeurl->out(false);
|
||||
$criteria['narrative'] = $narrative;
|
||||
return $criteria;
|
||||
} else {
|
||||
return $badgeurl->out(false);
|
||||
}
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$badgeexporter = ob_factory::create_badge_exporter_from_id(
|
||||
$this->get_badge_id(),
|
||||
helper::convert_apiversion(OPEN_BADGES_V2),
|
||||
);
|
||||
return $badgeexporter->export_criteria();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get alignment of the badge.
|
||||
*
|
||||
* @return array information.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
replacement: '\core_badges\local\backpack\ob\badge_exporter_interface::export_alignments',
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_alignments() {
|
||||
global $DB;
|
||||
$badgeid = $this->_data->id;
|
||||
$alignments = array();
|
||||
$items = $DB->get_records_select('badge_alignment', 'badgeid = ?', array($badgeid));
|
||||
foreach ($items as $item) {
|
||||
$alignment = array('targetName' => $item->targetname, 'targetUrl' => $item->targeturl);
|
||||
if ($item->targetdescription) {
|
||||
$alignment['targetDescription'] = $item->targetdescription;
|
||||
}
|
||||
if ($item->targetframework) {
|
||||
$alignment['targetFramework'] = $item->targetframework;
|
||||
}
|
||||
if ($item->targetcode) {
|
||||
$alignment['targetCode'] = $item->targetcode;
|
||||
}
|
||||
$alignments[] = $alignment;
|
||||
}
|
||||
return $alignments;
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
$badgeexporter = ob_factory::create_badge_exporter_from_id(
|
||||
$this->get_badge_id(),
|
||||
helper::convert_apiversion(OPEN_BADGES_V2),
|
||||
);
|
||||
return $badgeexporter->export_alignments();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -315,8 +303,16 @@ class core_badges_assertion {
|
||||
*
|
||||
* @param array $json for assertion, badges, issuer.
|
||||
* @param string $type Content type.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
protected function embed_data_badge_version2(&$json, $type = OPEN_BADGES_V2_TYPE_ASSERTION) {
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
// Specification Version 2.0.
|
||||
if ($this->_obversion >= OPEN_BADGES_V2) {
|
||||
$badge = new badge($this->_data->id);
|
||||
@@ -390,8 +386,16 @@ class core_badges_assertion {
|
||||
* Get tags of the badge.
|
||||
*
|
||||
* @return array tags.
|
||||
* @deprecated since Moodle 5.1.
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
since: '5.1',
|
||||
mdl: 'MDL-85621',
|
||||
)]
|
||||
public function get_tags(): array {
|
||||
\core\deprecation::emit_deprecation_if_present([self::class, __FUNCTION__]);
|
||||
|
||||
return array_values(\core_tag_tag::get_item_tags_array('core_badges', 'badge', $this->get_badge_id()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
|
||||
namespace core_badges;
|
||||
|
||||
use core_badges\local\backpack\helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/filelib.php');
|
||||
@@ -265,8 +267,10 @@ class backpack_api2p1 {
|
||||
|
||||
$this->tokendata = $this->get_stored_token($this->externalbackpack->id);
|
||||
|
||||
$assertion = new \core_badges_assertion($hash, OPEN_BADGES_V2);
|
||||
$data['assertion'] = $assertion->get_badge_assertion();
|
||||
$data['assertion'] = helper::export_achievement_credential(
|
||||
OPEN_BADGES_V2,
|
||||
$hash,
|
||||
);
|
||||
$response = $this->curl_request('post.assertions', $data);
|
||||
if ($response && isset($response->status->statusCode) && $response->status->statusCode == 200) {
|
||||
$msg['status'] = \core\output\notification::NOTIFY_SUCCESS;
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
|
||||
namespace core_badges;
|
||||
|
||||
use core_badges\local\backpack\helper;
|
||||
use core_badges\local\backpack\ob_factory;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->dirroot.'/lib/badgeslib.php');
|
||||
@@ -24,7 +27,6 @@ use context_system;
|
||||
use context_course;
|
||||
use context_user;
|
||||
use moodle_exception;
|
||||
use moodle_url;
|
||||
use core_text;
|
||||
use award_criteria;
|
||||
use core_php_time_limit;
|
||||
@@ -937,14 +939,11 @@ class badge {
|
||||
* @return array Issuer informations of the badge.
|
||||
*/
|
||||
public function get_badge_issuer(?int $obversion = null) {
|
||||
return [
|
||||
'name' => $this->issuername,
|
||||
'url' => $this->issuerurl,
|
||||
'email' => $this->issuercontact,
|
||||
'@context' => OPEN_BADGES_V2_CONTEXT,
|
||||
'id' => (new moodle_url('/badges/issuer_json.php', ['id' => $this->id]))->out(false),
|
||||
'type' => OPEN_BADGES_V2_TYPE_ISSUER,
|
||||
];
|
||||
$issuerexporter = ob_factory::create_issuer_exporter_from_id(
|
||||
$this->id,
|
||||
helper::convert_apiversion($obversion),
|
||||
);
|
||||
return $issuerexporter->export();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
namespace core_badges\output;
|
||||
|
||||
use core_badges\local\backpack\helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
@@ -72,12 +74,12 @@ class issued_badge implements renderable {
|
||||
global $DB;
|
||||
|
||||
$this->hash = $hash;
|
||||
$assertion = new \core_badges_assertion($hash, badges_open_badges_backpack_api());
|
||||
$this->issued = $assertion->get_badge_assertion();
|
||||
// Get achievement credential data using OBv2.0 specification.
|
||||
// In the future, we may want to support other OB versions.
|
||||
$this->issued = helper::export_achievement_credential(OPEN_BADGES_V2, $hash);
|
||||
if (array_key_exists('issuedOn', $this->issued) && !is_numeric($this->issued['issuedOn'])) {
|
||||
$this->issued['issuedOn'] = strtotime($this->issued['issuedOn']);
|
||||
}
|
||||
$this->badgeclass = $assertion->get_badge_class();
|
||||
|
||||
$rec = $DB->get_record_sql('SELECT userid, visible, badgeid
|
||||
FROM {badge_issued}
|
||||
@@ -92,6 +94,13 @@ class issued_badge implements renderable {
|
||||
$this->recipient = $user;
|
||||
$this->visible = $rec->visible;
|
||||
$this->badgeid = $rec->badgeid;
|
||||
|
||||
// Get the badge class using OBv2.0 specification.
|
||||
// In the future, we may want to support other OB versions.
|
||||
$this->badgeclass = helper::export_credential(
|
||||
OPEN_BADGES_V2,
|
||||
$this->badgeid,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://moodle.org/
|
||||
//
|
||||
// Moodle is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// Moodle is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
/**
|
||||
* Serve endorsement JSON for assertion.
|
||||
*
|
||||
* @package core
|
||||
* @subpackage badges
|
||||
* @copyright 2018 Tung Thai
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
* @author Tung Thai <[email protected]>
|
||||
*/
|
||||
define('AJAX_SCRIPT', true);
|
||||
define('NO_MOODLE_COOKIES', true); // No need for a session here.
|
||||
require_once(__DIR__ . '/../config.php');
|
||||
require_once($CFG->libdir . '/badgeslib.php');
|
||||
|
||||
if (empty($CFG->enablebadges)) {
|
||||
throw new \moodle_exception('badgesdisabled', 'badges');
|
||||
}
|
||||
|
||||
global $DB;
|
||||
$id = required_param('id', PARAM_INT);
|
||||
$action = optional_param('action', null, PARAM_BOOL); // Generates endorsement issuer class if true.
|
||||
$badge = new badge($id);
|
||||
|
||||
$json = array();
|
||||
$endorsement = $badge->get_endorsement();
|
||||
$endorsementurl = new moodle_url('/badges/endorsement_json.php', array('id' => $id));
|
||||
|
||||
if ($endorsement) {
|
||||
$issuer = array();
|
||||
$issuerurl = new moodle_url('/badges/endorsement_json.php', array('id' => $id, 'action' => 1));
|
||||
$issuer['id'] = $issuerurl->out(false);
|
||||
$issuer['name'] = $endorsement->issuername;
|
||||
$issuer['email'] = $endorsement->issueremail;
|
||||
$issuer['url'] = $endorsement->issuerurl;
|
||||
if ($action) {
|
||||
$json = $issuer;
|
||||
} else {
|
||||
$json['@context'] = OPEN_BADGES_V2_CONTEXT;
|
||||
$json['type'] = OPEN_BADGES_V2_TYPE_ENDORSEMENT;
|
||||
$json['id'] = $endorsementurl->out(false);
|
||||
$json['issuer'] = $issuer;
|
||||
if (!empty($endorsement->claimcomment)) {
|
||||
$json['claim']['id'] = $endorsement->claimid;
|
||||
$json['claim']['endorsementComment'] = $endorsement->claimcomment;
|
||||
} else {
|
||||
$json['claim'] = $endorsement->claimid;
|
||||
}
|
||||
$json['issuedOn'] = date('c', $endorsement->dateissued);
|
||||
$json['verification'] = array('type' => 'hosted');
|
||||
}
|
||||
}
|
||||
|
||||
echo $OUTPUT->header();
|
||||
echo json_encode($json);
|
||||
@@ -15,6 +15,7 @@
|
||||
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use core_badges\helper;
|
||||
use core_badges\local\backpack\ob_factory;
|
||||
use core_badges\tests\badges_testcase;
|
||||
use core\task\manager;
|
||||
|
||||
@@ -759,51 +760,6 @@ final class badgeslib_test extends badges_testcase {
|
||||
$this->assertSame(0, $badge->review_all_criteria()); // Verify award_criteria_cohort->get_completed_criteria_sql().
|
||||
}
|
||||
|
||||
/**
|
||||
* Test badges assertion generated when a badge is issued.
|
||||
*/
|
||||
public function test_badges_assertion(): void {
|
||||
$this->preventResetByRollback(); // Messaging is not compatible with transactions.
|
||||
$badge = new badge($this->coursebadge);
|
||||
$this->assertFalse($badge->is_issued($this->user->id));
|
||||
|
||||
$criteriaoverall = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_OVERALL, 'badgeid' => $badge->id]);
|
||||
$criteriaoverall->save(['agg' => BADGE_CRITERIA_AGGREGATION_ANY]);
|
||||
$criteriaoverall1 = award_criteria::build(['criteriatype' => BADGE_CRITERIA_TYPE_PROFILE, 'badgeid' => $badge->id]);
|
||||
$criteriaoverall1->save(['agg' => BADGE_CRITERIA_AGGREGATION_ALL, 'field_address' => 'address']);
|
||||
|
||||
$this->user->address = 'Test address';
|
||||
$sink = $this->redirectEmails();
|
||||
user_update_user($this->user, false);
|
||||
$this->assertCount(1, $sink->get_messages());
|
||||
$sink->close();
|
||||
// Check if badge is awarded.
|
||||
$this->assertDebuggingCalled('Error baking badge image!');
|
||||
$awards = $badge->get_awards();
|
||||
$this->assertCount(1, $awards);
|
||||
|
||||
// Test Openbadge specification version 2.0.
|
||||
// Get assertion version 2.
|
||||
$award = reset($awards);
|
||||
$assertion2 = new core_badges_assertion($award->uniquehash, OPEN_BADGES_V2);
|
||||
$testassertion2 = $this->assertion2;
|
||||
|
||||
// Make sure JSON strings have the same structure.
|
||||
$this->assertStringMatchesFormat($testassertion2->badge, json_encode($assertion2->get_badge_assertion()));
|
||||
$this->assertStringMatchesFormat($testassertion2->class, json_encode($assertion2->get_badge_class()));
|
||||
$this->assertStringMatchesFormat($testassertion2->issuer, json_encode($assertion2->get_issuer()));
|
||||
|
||||
// Test Openbadge specification version 2.1. It has the same format as OBv2.0.
|
||||
// Get assertion version 2.1.
|
||||
$award = reset($awards);
|
||||
$assertion2 = new core_badges_assertion($award->uniquehash, OPEN_BADGES_V2P1);
|
||||
|
||||
// Make sure JSON strings have the same structure.
|
||||
$this->assertStringMatchesFormat($testassertion2->badge, json_encode($assertion2->get_badge_assertion()));
|
||||
$this->assertStringMatchesFormat($testassertion2->class, json_encode($assertion2->get_badge_class()));
|
||||
$this->assertStringMatchesFormat($testassertion2->issuer, json_encode($assertion2->get_issuer()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the core_badges_myprofile_navigation() function.
|
||||
*/
|
||||
|
||||
@@ -34,10 +34,6 @@ abstract class badges_testcase extends \advanced_testcase {
|
||||
protected $user;
|
||||
protected $module;
|
||||
protected $coursebadge;
|
||||
protected $assertion;
|
||||
|
||||
/** @var $assertion2 to define json format for Open badge version 2 */
|
||||
protected $assertion2;
|
||||
|
||||
#[\Override]
|
||||
public static function setUpBeforeClass(): void {
|
||||
@@ -150,32 +146,5 @@ abstract class badges_testcase extends \advanced_testcase {
|
||||
|
||||
// Insert tags.
|
||||
core_tag_tag::set_item_tags('core_badges', 'badge', $badge->id, $badge->get_context(), ['tag1', 'tag2']);
|
||||
|
||||
$this->assertion = new stdClass();
|
||||
$this->assertion->badge = '{"uid":"%s","recipient":{"identity":"%s","type":"email","hashed":true,"salt":"%s"},' .
|
||||
'"badge":"%s","verify":{"type":"hosted","url":"%s"},"issuedOn":"%d","evidence":"%s","tags":%s}';
|
||||
$this->assertion->class = '{"name":"%s","description":"%s","image":"%s","criteria":"%s","issuer":"%s","tags":%s}';
|
||||
$this->assertion->issuer = '{"name":"%s","url":"%s","email":"%s"}';
|
||||
// Format JSON-LD for Openbadge specification version 2.0.
|
||||
$this->assertion2 = new stdClass();
|
||||
$this->assertion2->badge = '{"recipient":{"identity":"%s","type":"email","hashed":true,"salt":"%s"},' .
|
||||
'"badge":{"name":"%s","description":"%s","image":"%s",' .
|
||||
'"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' .
|
||||
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' .
|
||||
'"tags":%s,"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' .
|
||||
'"@language":"en","related":[{"id":"%s","version":"%s","@language":"%s"}],' .
|
||||
'"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' .
|
||||
'"targetCode":"%s"}]},"verify":{"type":"hosted","url":"%s"},"issuedOn":"%s","evidence":"%s","tags":%s,' .
|
||||
'"@context":"https:\/\/w3id.org\/openbadges\/v2","type":"Assertion","id":"%s"}';
|
||||
|
||||
$this->assertion2->class = '{"name":"%s","description":"%s","image":"%s",' .
|
||||
'"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' .
|
||||
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' .
|
||||
'"tags":%s,"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' .
|
||||
'"@language":"%s","related":[{"id":"%s","version":"%s","@language":"%s"}],' .
|
||||
'"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' .
|
||||
'"targetCode":"%s"}]}';
|
||||
$this->assertion2->issuer = '{"name":"%s","url":"%s","email":"%s",' .
|
||||
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"}';
|
||||
}
|
||||
}
|
||||
|
||||
+16
-29
@@ -132,6 +132,8 @@ define('BACKPACK_MOVE_DOWN', 1);
|
||||
class_alias('\core_badges\badge', 'badge');
|
||||
|
||||
use core_badges\png_metadata_handler;
|
||||
use core_badges\local\backpack\helper;
|
||||
use core_badges\local\backpack\ob_factory;
|
||||
|
||||
/**
|
||||
* Sends notifications to users about awarded badges.
|
||||
@@ -708,7 +710,7 @@ function print_badge_image(badge $badge, stdClass $context, $size = 'small') {
|
||||
* @return string|moodle_url|null Returns either new file path hash or new file URL
|
||||
*/
|
||||
function badges_bake($hash, $badgeid, $userid = 0, $pathhash = false) {
|
||||
global $CFG, $USER;
|
||||
global $USER;
|
||||
|
||||
$badge = new badge($badgeid);
|
||||
$badge_context = $badge->get_context();
|
||||
@@ -721,10 +723,19 @@ function badges_bake($hash, $badgeid, $userid = 0, $pathhash = false) {
|
||||
$contents = $file->get_content();
|
||||
|
||||
$filehandler = new png_metadata_handler($contents);
|
||||
// For now, the site backpack OB version will be used as default.
|
||||
$obversion = badges_open_badges_backpack_api();
|
||||
$assertion = new core_badges_assertion($hash, $obversion);
|
||||
$assertionjson = json_encode($assertion->get_badge_assertion());
|
||||
// For now, the user backpack OB version will be used as default (or site if the user doesn't have).
|
||||
// Make OB version configurable in the future, to let users choose which use.
|
||||
$backpack = badges_get_user_backpack($userid);
|
||||
if ($backpack) {
|
||||
$obversion = $backpack->apiversion;
|
||||
} else {
|
||||
$obversion = badges_open_badges_backpack_api();
|
||||
}
|
||||
$assertionexporter = ob_factory::create_assertion_exporter_from_hash(
|
||||
$hash,
|
||||
helper::convert_apiversion($obversion),
|
||||
);
|
||||
$assertionjson = $assertionexporter->get_json();
|
||||
if ($filehandler->check_chunks("iTXt", "openbadges")) {
|
||||
// Add assertion URL iTXt chunk.
|
||||
$newcontents = $filehandler->add_chunks("iTXt", "openbadges", $assertionjson);
|
||||
@@ -1211,30 +1222,6 @@ function badges_get_badge_api_versions() {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default issuer for a badge from this site.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function badges_get_default_issuer() {
|
||||
global $CFG, $SITE;
|
||||
|
||||
$sitebackpack = badges_get_site_primary_backpack();
|
||||
$issuer = array();
|
||||
$issuerurl = new moodle_url('/');
|
||||
$issuer['name'] = $CFG->badges_defaultissuername;
|
||||
if (empty($issuer['name'])) {
|
||||
$issuer['name'] = $SITE->fullname ? $SITE->fullname : $SITE->shortname;
|
||||
}
|
||||
$issuer['url'] = $issuerurl->out(false);
|
||||
$issuer['email'] = $sitebackpack->backpackemail ?: $CFG->badges_defaultissuercontact;
|
||||
$issuer['@context'] = OPEN_BADGES_V2_CONTEXT;
|
||||
$issuerid = new moodle_url('/badges/issuer_json.php');
|
||||
$issuer['id'] = $issuerid->out(false);
|
||||
$issuer['type'] = OPEN_BADGES_V2_TYPE_ISSUER;
|
||||
return $issuer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disconnect from the user backpack by deleting the user preferences.
|
||||
*
|
||||
|
||||
@@ -899,3 +899,37 @@ function file_encode_url($urlbase, $path, $forcedownload = false, $https = false
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default issuer for a badge from this site.
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @deprecated Since Moodle 5.2
|
||||
* @todo MDL-85730 Final deprecation in Moodle 6.0.
|
||||
*/
|
||||
#[\core\attribute\deprecated(
|
||||
since: '5.2',
|
||||
mdl: 'MDL-85621',
|
||||
reason: 'It is no longer used.'
|
||||
)]
|
||||
function badges_get_default_issuer() {
|
||||
\core\deprecation::emit_deprecation(__FUNCTION__);
|
||||
|
||||
global $CFG, $SITE;
|
||||
|
||||
$sitebackpack = badges_get_site_primary_backpack();
|
||||
$issuer = [];
|
||||
$issuerurl = new moodle_url('/');
|
||||
$issuer['name'] = $CFG->badges_defaultissuername;
|
||||
if (empty($issuer['name'])) {
|
||||
$issuer['name'] = $SITE->fullname ? $SITE->fullname : $SITE->shortname;
|
||||
}
|
||||
$issuer['url'] = $issuerurl->out(false);
|
||||
$issuer['email'] = $sitebackpack->backpackemail ?: $CFG->badges_defaultissuercontact;
|
||||
$issuer['@context'] = OPEN_BADGES_V2_CONTEXT;
|
||||
$issuerid = new moodle_url('/badges/issuer_json.php');
|
||||
$issuer['id'] = $issuerid->out(false);
|
||||
$issuer['type'] = OPEN_BADGES_V2_TYPE_ISSUER;
|
||||
return $issuer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user