This commit is contained in:
Jun Pataleta 2023-06-15 11:31:22 +08:00
commit 620371e7d3
17 changed files with 205 additions and 28 deletions

View File

@ -939,6 +939,9 @@ class backup_badges_structure_step extends backup_structure_step {
$manual_award = new backup_nested_element('manual_award', array('id'), array('badgeid', $manual_award = new backup_nested_element('manual_award', array('id'), array('badgeid',
'recipientid', 'issuerid', 'issuerrole', 'datemet')); 'recipientid', 'issuerid', 'issuerrole', 'datemet'));
$tags = new backup_nested_element('tags');
$tag = new backup_nested_element('tag', ['id'], ['name', 'rawname']);
// Build the tree. // Build the tree.
$badges->add_child($badge); $badges->add_child($badge);
@ -953,6 +956,8 @@ class backup_badges_structure_step extends backup_structure_step {
$relatedbadges->add_child($relatedbadge); $relatedbadges->add_child($relatedbadge);
$badge->add_child($manual_awards); $badge->add_child($manual_awards);
$manual_awards->add_child($manual_award); $manual_awards->add_child($manual_award);
$badge->add_child($tags);
$tags->add_child($tag);
// Define sources. // Define sources.
@ -980,6 +985,12 @@ class backup_badges_structure_step extends backup_structure_step {
$manual_award->set_source_table('badge_manual_award', array('badgeid' => backup::VAR_PARENTID)); $manual_award->set_source_table('badge_manual_award', array('badgeid' => backup::VAR_PARENTID));
$tag->set_source_sql('SELECT t.id, t.name, t.rawname
FROM {tag} t
JOIN {tag_instance} ti ON ti.tagid = t.id
WHERE ti.itemtype = ?
AND ti.itemid = ?', [backup_helper::is_sqlparam('badge'), backup::VAR_PARENTID]);
// Define id annotations. // Define id annotations.
$badge->annotate_ids('user', 'usercreated'); $badge->annotate_ids('user', 'usercreated');

View File

@ -2621,6 +2621,7 @@ class restore_badges_structure_step extends restore_structure_step {
$paths[] = new restore_path_element('alignment', '/badges/badge/alignments/alignment'); $paths[] = new restore_path_element('alignment', '/badges/badge/alignments/alignment');
$paths[] = new restore_path_element('relatedbadge', '/badges/badge/relatedbadges/relatedbadge'); $paths[] = new restore_path_element('relatedbadge', '/badges/badge/relatedbadges/relatedbadge');
$paths[] = new restore_path_element('manual_award', '/badges/badge/manual_awards/manual_award'); $paths[] = new restore_path_element('manual_award', '/badges/badge/manual_awards/manual_award');
$paths[] = new restore_path_element('tag', '/badges/badge/tags/tag');
return $paths; return $paths;
} }
@ -2830,6 +2831,22 @@ class restore_badges_structure_step extends restore_structure_step {
} }
} }
/**
* Process tag.
*
* @param array $data The data.
* @throws base_step_exception
*/
public function process_tag(array $data): void {
$data = (object)$data;
$badgeid = $this->get_new_parentid('badge');
if (!empty($data->rawname)) {
core_tag_tag::add_item_tag('core_badges', 'badge', $badgeid,
context_course::instance($this->get_courseid()), $data->rawname);
}
}
protected function after_execute() { protected function after_execute() {
global $DB; global $DB;
// Add related files. // Add related files.

View File

@ -80,6 +80,10 @@ if ($badge->status != BADGE_STATUS_INACTIVE) {
if (!empty($badge->language)) { if (!empty($badge->language)) {
$json['@language'] = $badge->language; $json['@language'] = $badge->language;
} }
$badgetags = $badge->get_badge_tags();
if ($badgetags) {
$json['tags'] = $badgetags;
}
$relatedbadges = $badge->get_related_badges(true); $relatedbadges = $badge->get_related_badges(true);
if (!empty($relatedbadges)) { if (!empty($relatedbadges)) {

View File

@ -161,6 +161,10 @@ class core_badges_assertion {
if (!empty($this->_data->dateexpire)) { if (!empty($this->_data->dateexpire)) {
$assertion['expires'] = $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); $this->embed_data_badge_version2($assertion, OPEN_BADGES_V2_TYPE_ASSERTION);
} }
return $assertion; return $assertion;
@ -205,6 +209,10 @@ class core_badges_assertion {
$issuerurl = new moodle_url('/badges/issuer_json.php', $params); $issuerurl = new moodle_url('/badges/issuer_json.php', $params);
$class['issuer'] = $issuerurl->out(false); $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); $this->embed_data_badge_version2($class, OPEN_BADGES_V2_TYPE_BADGE);
if (!$issued) { if (!$issued) {
unset($class['issuer']); unset($class['issuer']);
@ -404,4 +412,13 @@ class core_badges_assertion {
} }
} }
} }
/**
* Get tags of the badge.
*
* @return array tags.
*/
public function get_tags(): array {
return array_values(\core_tag_tag::get_item_tags_array('core_badges', 'badge', $this->get_badge_id()));
}
} }

View File

@ -302,6 +302,7 @@ class badge {
$fordb->usermodified = $USER->id; $fordb->usermodified = $USER->id;
$fordb->timecreated = time(); $fordb->timecreated = time();
$fordb->timemodified = time(); $fordb->timemodified = time();
$tags = $this->get_badge_tags();
unset($fordb->id); unset($fordb->id);
if ($fordb->notification > 1) { if ($fordb->notification > 1) {
@ -313,6 +314,8 @@ class badge {
if ($new = $DB->insert_record('badge', $fordb, true)) { if ($new = $DB->insert_record('badge', $fordb, true)) {
$newbadge = new badge($new); $newbadge = new badge($new);
// Copy badge tags.
\core_tag_tag::set_item_tags('core_badges', 'badge', $newbadge->id, $this->get_context(), $tags);
// Copy badge image. // Copy badge image.
$fs = get_file_storage(); $fs = get_file_storage();
@ -745,6 +748,9 @@ class badge {
$DB->delete_records_select('badge_related', $relatedsql, $relatedparams); $DB->delete_records_select('badge_related', $relatedsql, $relatedparams);
$DB->delete_records('badge_alignment', array('badgeid' => $this->id)); $DB->delete_records('badge_alignment', array('badgeid' => $this->id));
// Delete all tags.
\core_tag_tag::remove_all_item_tags('core_badges', 'badge', $this->id);
// Finally, remove badge itself. // Finally, remove badge itself.
$DB->delete_records('badge', array('id' => $this->id)); $DB->delete_records('badge', array('id' => $this->id));
@ -976,4 +982,13 @@ class badge {
return $issuer; return $issuer;
} }
/**
* Get tags of badge.
*
* @return array Badge tags.
*/
public function get_badge_tags(): array {
return array_values(\core_tag_tag::get_item_tags_array('core_badges', 'badge', $this->id));
}
} }

View File

@ -92,7 +92,7 @@ class badge extends moodleform {
$mform->addElement('text', 'imagecaption', get_string('imagecaption', 'badges'), array('size' => '70')); $mform->addElement('text', 'imagecaption', get_string('imagecaption', 'badges'), array('size' => '70'));
$mform->setType('imagecaption', PARAM_TEXT); $mform->setType('imagecaption', PARAM_TEXT);
$mform->addHelpButton('imagecaption', 'imagecaption', 'badges'); $mform->addHelpButton('imagecaption', 'imagecaption', 'badges');
$mform->addElement('tags', 'tags', get_string('tags', 'badges'), ['itemtype' => 'badge', 'component' => 'core_badges']);
if (badges_open_badges_backpack_api() == OPEN_BADGES_V1) { if (badges_open_badges_backpack_api() == OPEN_BADGES_V1) {
$mform->addElement('header', 'issuerdetails', get_string('issuerdetails', 'badges')); $mform->addElement('header', 'issuerdetails', get_string('issuerdetails', 'badges'));
@ -173,22 +173,23 @@ class badge extends moodleform {
/** /**
* Load in existing data as form defaults * Load in existing data as form defaults
* *
* @param stdClass|array $default_values object or array of default values * @param stdClass|array $badge object or array of default values
*/ */
public function set_data($badge) { public function set_data($badge) {
$default_values = array(); $defaultvalues = [];
parent::set_data($badge); parent::set_data($badge);
if (!empty($badge->expiredate)) { if (!empty($badge->expiredate)) {
$default_values['expiry'] = 1; $defaultvalues['expiry'] = 1;
$default_values['expiredate'] = $badge->expiredate; $defaultvalues['expiredate'] = $badge->expiredate;
} else if (!empty($badge->expireperiod)) { } else if (!empty($badge->expireperiod)) {
$default_values['expiry'] = 2; $defaultvalues['expiry'] = 2;
$default_values['expireperiod'] = $badge->expireperiod; $defaultvalues['expireperiod'] = $badge->expireperiod;
} }
$default_values['currentimage'] = print_badge_image($badge, $badge->get_context(), 'large'); $defaultvalues['tags'] = \core_tag_tag::get_item_tags_array('core_badges', 'badge', $badge->id);
$defaultvalues['currentimage'] = print_badge_image($badge, $badge->get_context(), 'large');
parent::set_data($default_values); parent::set_data($defaultvalues);
} }
/** /**

View File

@ -170,6 +170,11 @@ class badgeclass implements renderable {
} }
} }
// Field: Tags.
$tags = \core_tag_tag::get_item_tags('core_badges', 'badge', $this->badgeid);
$taglist = new \core_tag\output\taglist($tags);
$data->badgetag = $taglist->export_for_template($output);
return $data; return $data;
} }
} }

View File

@ -242,6 +242,11 @@ class issued_badge implements renderable {
} }
} }
// Field: Tags.
$tags = \core_tag_tag::get_item_tags('core_badges', 'badge', $this->badgeid);
$taglist = new \core_tag\output\taglist($tags);
$data->badgetag = $taglist->export_for_template($output);
return $data; return $data;
} }
} }

View File

@ -117,6 +117,8 @@ if ($form->is_cancelled()) {
unset($badge->message_editor); unset($badge->message_editor);
if ($badge->save()) { if ($badge->save()) {
core_tag_tag::set_item_tags('core_badges', 'badge', $badge->id, $context, $data->tags);
$badge->tags = core_tag_tag::get_item_tags_array('core_badges', 'badge', $badge->id);
badges_process_badge_image($badge, $form->save_temp_file('image')); badges_process_badge_image($badge, $form->save_temp_file('image'));
$form->set_data($badge); $form->set_data($badge);
$statusmsg = get_string('changessaved'); $statusmsg = get_string('changessaved');

View File

@ -73,3 +73,44 @@ function core_badges_myprofile_navigation(\core_user\output\myprofile\tree $tree
} }
} }
} }
/**
* Returns badges tagged with a specified tag.
*
* @param object $tag
* @param bool $exclusivemode if set to true it means that no other entities tagged with this tag
* are displayed on the page and the per-page limit may be bigger
* @param null|int $fromctx context id where the link was displayed, may be used by callbacks
* to display items in the same context first
* @param null|int $ctx context id where to search for records
* @param bool $rec search in subcontexts as well
* @param int $page 0-based number of page being displayed
* @return \core_tag\output\tagindex
*/
function badge_get_tagged_badges(object $tag, bool $exclusivemode = false, null|int $fromctx = 0, null|int $ctx = 0,
bool $rec = true, int $page = 0): object {
global $OUTPUT;
$badgecount = $tag->count_tagged_items('core_badges', 'badge');
$perpage = $exclusivemode ? 20 : 5;
$content = '';
$totalpages = ceil($badgecount / $perpage);
if ($badgecount) {
$badges = $tag->get_tagged_items('core_badges', 'badge', $page * $perpage, $perpage);
$tagfeed = new core_tag\output\tagfeed();
foreach ($badges as $badge) {
$badgelink = new moodle_url('/badges/badgeclass.php', ['id' => $badge->id]);
$fullname = html_writer::link($badgelink, $badge->name);
$icon = html_writer::link($badgelink, html_writer::empty_tag('img',
['src' => $OUTPUT->image_url('i/badge')]));
$tagfeed->add($icon, $fullname, '<br>');
}
$items = $tagfeed->export_for_template($OUTPUT);
$content .= $OUTPUT->render_from_template('core_tag/tagfeed', $items);
}
return new core_tag\output\tagindex($tag, 'core_badges', 'badge', $content,
$exclusivemode, $fromctx, $ctx, $rec, $page, $totalpages);
}

View File

@ -116,6 +116,7 @@ if ($form->is_cancelled()) {
$event->trigger(); $event->trigger();
$newbadge = new badge($newid); $newbadge = new badge($newid);
core_tag_tag::set_item_tags('core_badges', 'badge', $newid, $PAGE->context, $data->tags);
badges_process_badge_image($newbadge, $form->save_temp_file('image')); badges_process_badge_image($newbadge, $form->save_temp_file('image'));
// If a user can configure badge criteria, they will be redirected to the criteria page. // If a user can configure badge criteria, they will be redirected to the criteria page.
if (has_capability('moodle/badges:configurecriteria', $PAGE->context)) { if (has_capability('moodle/badges:configurecriteria', $PAGE->context)) {

View File

@ -192,6 +192,8 @@ class core_badges_renderer extends plugin_renderer_base {
$dl[get_string('imageauthorurl', 'badges')] = $dl[get_string('imageauthorurl', 'badges')] =
html_writer::link($badge->imageauthorurl, $badge->imageauthorurl, array('target' => '_blank')); html_writer::link($badge->imageauthorurl, $badge->imageauthorurl, array('target' => '_blank'));
$dl[get_string('imagecaption', 'badges')] = $badge->imagecaption; $dl[get_string('imagecaption', 'badges')] = $badge->imagecaption;
$tags = \core_tag_tag::get_item_tags('core_badges', 'badge', $badge->id);
$dl[get_string('tags', 'badges')] = $this->output->tag_list($tags, '');
$display .= $this->definition_list($dl); $display .= $this->definition_list($dl);
// Issuer details. // Issuer details.

View File

@ -211,6 +211,11 @@
</div> </div>
{{/coursefullname}} {{/coursefullname}}
</div> </div>
{{#badgetag}}
<p class="pb-2">
{{> core_tag/taglist}}
</p>
{{/badgetag}}
<p class="pb-4">{{{badgedescription}}}</p> <p class="pb-4">{{{badgedescription}}}</p>

View File

@ -135,9 +135,13 @@ class badgeslib_test extends advanced_testcase {
$alignment->targetcode = 'CCSS.RST.11-12.3'; $alignment->targetcode = 'CCSS.RST.11-12.3';
$DB->insert_record('badge_alignment', $alignment, true); $DB->insert_record('badge_alignment', $alignment, true);
// Insert tags.
core_tag_tag::set_item_tags('core_badges', 'badge', $badge->id, $badge->get_context(), ['tag1', 'tag2']);
$this->assertion = new stdClass(); $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"}'; $this->assertion->badge = '{"uid":"%s","recipient":{"identity":"%s","type":"email","hashed":true,"salt":"%s"},' .
$this->assertion->class = '{"name":"%s","description":"%s","image":"%s","criteria":"%s","issuer":"%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"}'; $this->assertion->issuer = '{"name":"%s","url":"%s","email":"%s"}';
// Format JSON-LD for Openbadge specification version 2.0. // Format JSON-LD for Openbadge specification version 2.0.
$this->assertion2 = new stdClass(); $this->assertion2 = new stdClass();
@ -145,16 +149,16 @@ class badgeslib_test extends advanced_testcase {
'"badge":{"name":"%s","description":"%s","image":"%s",' . '"badge":{"name":"%s","description":"%s","image":"%s",' .
'"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' . '"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' .
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' . '"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' .
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' . '"tags":%s,"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' .
'"@language":"en","related":[{"id":"%s","version":"%s","@language":"%s"}],"endorsement":"%s",' . '"@language":"en","related":[{"id":"%s","version":"%s","@language":"%s"}],"endorsement":"%s",' .
'"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' . '"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' .
'"targetCode":"%s"}]},"verify":{"type":"hosted","url":"%s"},"issuedOn":"%s","evidence":"%s",' . '"targetCode":"%s"}]},"verify":{"type":"hosted","url":"%s"},"issuedOn":"%s","evidence":"%s","tags":%s,' .
'"@context":"https:\/\/w3id.org\/openbadges\/v2","type":"Assertion","id":"%s"}'; '"@context":"https:\/\/w3id.org\/openbadges\/v2","type":"Assertion","id":"%s"}';
$this->assertion2->class = '{"name":"%s","description":"%s","image":"%s",' . $this->assertion2->class = '{"name":"%s","description":"%s","image":"%s",' .
'"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' . '"criteria":{"id":"%s","narrative":"%s"},"issuer":{"name":"%s","url":"%s","email":"%s",' .
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' . '"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"Issuer"},' .
'"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' . '"tags":%s,"@context":"https:\/\/w3id.org\/openbadges\/v2","id":"%s","type":"BadgeClass","version":"%s",' .
'"@language":"%s","related":[{"id":"%s","version":"%s","@language":"%s"}],"endorsement":"%s",' . '"@language":"%s","related":[{"id":"%s","version":"%s","@language":"%s"}],"endorsement":"%s",' .
'"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' . '"alignments":[{"targetName":"%s","targetUrl":"%s","targetDescription":"%s","targetFramework":"%s",' .
'"targetCode":"%s"}]}'; '"targetCode":"%s"}]}';
@ -217,6 +221,8 @@ class badgeslib_test extends advanced_testcase {
global $DB; global $DB;
$badge = new badge($this->badgeid); $badge = new badge($this->badgeid);
// Insert tags for the badge.
core_tag_tag::set_item_tags('core_badges', 'badge', $badge->id, $badge->get_context(), ['tag1', 'tag2']);
$newid1 = $badge->make_clone(); $newid1 = $badge->make_clone();
$newid2 = $badge->make_clone(); $newid2 = $badge->make_clone();
@ -239,6 +245,9 @@ class badgeslib_test extends advanced_testcase {
// Badge 1 has 4 related records. 3 where it's the badgeid, 1 where it's the relatedbadgeid. // Badge 1 has 4 related records. 3 where it's the badgeid, 1 where it's the relatedbadgeid.
$this->assertEquals(4, $DB->count_records_select('badge_related', $relatedsql, $relatedparams)); $this->assertEquals(4, $DB->count_records_select('badge_related', $relatedsql, $relatedparams));
// Badge has 2 tag instance records.
$this->assertEquals(2, $DB->count_records('tag_instance', ['itemid' => $this->badgeid]));
// Delete the badge for real. // Delete the badge for real.
$badge->delete(false); $badge->delete(false);
@ -247,6 +256,9 @@ class badgeslib_test extends advanced_testcase {
// Confirm that the records about this badge about its relations have been removed as well. // Confirm that the records about this badge about its relations have been removed as well.
$this->assertFalse($DB->record_exists_select('badge_related', $relatedsql, $relatedparams)); $this->assertFalse($DB->record_exists_select('badge_related', $relatedsql, $relatedparams));
// Confirm that the tag instance of the badge has been removed.
$this->assertFalse($DB->record_exists('tag_instance', ['itemid' => $this->badgeid]));
} }
public function test_create_badge_criteria() { public function test_create_badge_criteria() {
@ -1638,4 +1650,24 @@ class badgeslib_test extends advanced_testcase {
$backpack = badges_get_site_backpack($backpackid); $backpack = badges_get_site_backpack($backpackid);
} }
} }
/**
* Testing function test_badge_get_tagged_badges - search tagged badges
*
* @covers ::badge_get_tagged_badges
*/
public function test_badge_get_tagged_badges() {
$this->resetAfterTest();
$this->setAdminUser();
// Setup test data.
$badge = new badge($this->coursebadge);
\core_tag_tag::set_item_tags('core_badges', 'badge', $this->badgeid, $badge->get_context(),
['Cats', 'Dogs']);
$tag = \core_tag_tag::get_by_name(0, 'Cats');
$res = badge_get_tagged_badges($tag, false, 0, 0, 1, 0);
$this->assertStringContainsString("Test badge with 'apostrophe' and other friends (<>&@#)", $res->content);
}
} }

View File

@ -33,6 +33,7 @@ Feature: Add badges to the system
| Description | Test badge description | | Description | Test badge description |
| Image author | http://author.example.com | | Image author | http://author.example.com |
| Image caption | Test caption image | | Image caption | Test caption image |
| Tags | Math, Physics |
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
When I press "Create badge" When I press "Create badge"
Then I should see "Edit details" Then I should see "Edit details"
@ -46,6 +47,9 @@ Feature: Add badges to the system
And I should see "Issuer details" And I should see "Issuer details"
And I should see "Test Badge Site" And I should see "Test Badge Site"
And I should see "testuser@example.com" And I should see "testuser@example.com"
And I should see "Tags"
And I should see "Math"
And I should see "Physics"
And I navigate to "Badges > Manage badges" in site administration And I navigate to "Badges > Manage badges" in site administration
And I should not see "There are currently no badges available for users to earn." And I should not see "There are currently no badges available for users to earn."
@ -181,17 +185,24 @@ Feature: Add badges to the system
| Description | Test badge description | | Description | Test badge description |
| Image author | http://author.example.com | | Image author | http://author.example.com |
| Image caption | Test caption image | | Image caption | Test caption image |
| Tags | Math, Physics |
And I upload "badges/tests/behat/badge.png" file to "Image" filemanager And I upload "badges/tests/behat/badge.png" file to "Image" filemanager
And I press "Create badge" And I press "Create badge"
When I select "Edit details" from the "jump" singleselect When I select "Edit details" from the "jump" singleselect
And I should see "Test badge with 'apostrophe' and other friends (&@#)" And I should see "Test badge with 'apostrophe' and other friends (&@#)"
And I should not see "Issuer details" And I should not see "Issuer details"
And I should see "Math"
And I should see "Physics"
And I set the following fields to these values: And I set the following fields to these values:
| Name | Test badge renamed | | Name | Test badge renamed |
| Version | secondversion | | Version | secondversion |
| Tags | Math, History |
And I press "Save changes" And I press "Save changes"
And I select "Overview" from the "jump" singleselect And I select "Overview" from the "jump" singleselect
Then I should not see "Test badge with 'apostrophe' and other friends (&@#)" Then I should not see "Test badge with 'apostrophe' and other friends (&@#)"
And I should not see "firstversion" And I should not see "firstversion"
And I should not see "Math, Physics"
And I should see "Test badge renamed" And I should see "Test badge renamed"
And I should see "secondversion" And I should see "secondversion"
And I should see "Math"
And I should see "History"

View File

@ -547,6 +547,7 @@ Once a badge has been issued to at least one user, it automatically becomes **LO
We want to make sure that all users complete the same requirements to earn a badge. Currently, it is not possible to revoke badges. If we allowed badges requirements to be modified all the time, we would most likely end up with users having the same badge for meeting completely different requirements.'; We want to make sure that all users complete the same requirements to earn a badge. Currently, it is not possible to revoke badges. If we allowed badges requirements to be modified all the time, we would most likely end up with users having the same badge for meeting completely different requirements.';
$string['subject'] = 'Message subject'; $string['subject'] = 'Message subject';
$string['tags'] = 'Tags';
$string['targetname'] = 'Name'; $string['targetname'] = 'Name';
$string['targetname_help'] = 'The external skill or standard which the badge is aligned with.'; $string['targetname_help'] = 'The external skill or standard which the badge is aligned with.';
$string['targeturl'] = 'URL'; $string['targeturl'] = 'URL';
@ -560,6 +561,7 @@ $string['targetcode_help'] = 'A unique string identifier for referencing the ext
$string['testbackpack'] = 'Test backpack \'{$a}\''; $string['testbackpack'] = 'Test backpack \'{$a}\'';
$string['testsettings'] = 'Test settings'; $string['testsettings'] = 'Test settings';
$string['type'] = 'Type'; $string['type'] = 'Type';
$string['tagarea_badge'] = 'Badges';
$string['userbadges'] = 'User badges'; $string['userbadges'] = 'User badges';
$string['variablesubstitution'] = 'Variable substitution in messages.'; $string['variablesubstitution'] = 'Variable substitution in messages.';
$string['variablesubstitution_help'] = 'In a badge message, certain variables can be inserted into the subject and/or body of a message so that they will be replaced with real values when the message is sent. The variables should be inserted into the text exactly as they are shown below. The following variables can be used: $string['variablesubstitution_help'] = 'In a badge message, certain variables can be inserted into the subject and/or body of a message so that they will be replaced with real values when the message is sent. The variables should be inserted into the text exactly as they are shown below. The following variables can be used:

View File

@ -52,39 +52,45 @@
defined('MOODLE_INTERNAL') || die(); defined('MOODLE_INTERNAL') || die();
$tagareas = array( $tagareas = [
array( [
'itemtype' => 'user', // Users. 'itemtype' => 'user', // Users.
'component' => 'core', 'component' => 'core',
'callback' => 'user_get_tagged_users', 'callback' => 'user_get_tagged_users',
'callbackfile' => '/user/lib.php', 'callbackfile' => '/user/lib.php',
'showstandard' => core_tag_tag::HIDE_STANDARD, 'showstandard' => core_tag_tag::HIDE_STANDARD,
), ],
array( [
'itemtype' => 'course', // Courses. 'itemtype' => 'course', // Courses.
'component' => 'core', 'component' => 'core',
'callback' => 'course_get_tagged_courses', 'callback' => 'course_get_tagged_courses',
'callbackfile' => '/course/lib.php', 'callbackfile' => '/course/lib.php',
), ],
array( [
'itemtype' => 'question', // Questions. 'itemtype' => 'question', // Questions.
'component' => 'core_question', 'component' => 'core_question',
'multiplecontexts' => true, 'multiplecontexts' => true,
), ],
array( [
'itemtype' => 'post', // Blog posts. 'itemtype' => 'post', // Blog posts.
'component' => 'core', 'component' => 'core',
'callback' => 'blog_get_tagged_posts', 'callback' => 'blog_get_tagged_posts',
'callbackfile' => '/blog/lib.php', 'callbackfile' => '/blog/lib.php',
), ],
array( [
'itemtype' => 'blog_external', // External blogs. 'itemtype' => 'blog_external', // External blogs.
'component' => 'core', 'component' => 'core',
), ],
array( [
'itemtype' => 'course_modules', // Course modules. 'itemtype' => 'course_modules', // Course modules.
'component' => 'core', 'component' => 'core',
'callback' => 'course_get_tagged_course_modules', 'callback' => 'course_get_tagged_course_modules',
'callbackfile' => '/course/lib.php', 'callbackfile' => '/course/lib.php',
), ],
); [
'itemtype' => 'badge', // Badges.
'component' => 'core_badges',
'callback' => 'badge_get_tagged_badges',
'callbackfile' => '/badges/lib.php',
],
];