/** * Test the tag_set function. * This function was deprecated in 3.1 */ public function test_tag_set_get() { global $DB; // Create a course to tag. $course = $this->getDataGenerator()->create_course(); // Create the tag and tag instance. tag_set('course', $course->id, array('A random tag'), 'core', context_course::instance($course->id)->id); $this->assertDebuggingCalled(); // Get the tag instance that should have been created. $taginstance = $DB->get_record('tag_instance', array('itemtype' => 'course', 'itemid' => $course->id), '*', MUST_EXIST); $this->assertEquals('core', $taginstance->component); $this->assertEquals(context_course::instance($course->id)->id, $taginstance->contextid); $tagbyname = tag_get('name', 'A random tag'); $this->assertDebuggingCalled(); $this->assertEquals('A random tag', $tagbyname->rawname); $this->assertEmpty(tag_get('name', 'Non existing tag')); $this->assertDebuggingCalled(); $tagbyid = tag_get('id', $tagbyname->id); $this->assertDebuggingCalled(); $this->assertEquals('A random tag', $tagbyid->rawname); $tagid = $tagbyname->id; $this->assertEmpty(tag_get('id', $tagid + 1)); $this->assertDebuggingCalled(); tag_set('tag', $tagid, array('Some related tag')); $this->assertDebuggingCalled(); $relatedtags = tag_get_related_tags($tagid); $this->assertDebuggingCalled(); $this->assertCount(1, $relatedtags); $this->assertEquals('Some related tag', $relatedtags[0]->rawname); $tagids = tag_get_id(array('A random tag', 'Some related tag')); $this->assertDebuggingCalled(); $this->assertCount(2, $tagids); $this->assertEquals($tagid, $tagids['a random tag']); $this->assertEquals($relatedtags[0]->id, $tagids['some related tag']); }
/** * Stores a tag for a course for a user * * @uses $CFG * @param array $tags simple array of keywords to be stored * @param integer $courseid * @param integer $userid * @param string $tagtype official or default only * @param string $myurl optional for logging creation of course tags */ function coursetag_store_keywords($tags, $courseid, $userid=0, $tagtype='official', $myurl='') { global $CFG; if (is_array($tags) and !empty($tags)) { foreach($tags as $tag) { $tag = trim($tag); if (strlen($tag) > 0) { //tag_set_add('course', $courseid, $tag, $userid); //deletes official tags //add tag if does not exist if (!$tagid = tag_get_id($tag)) { $tag_id_array = tag_add(array($tag), $tagtype); $tagid = $tag_id_array[moodle_strtolower($tag)]; } //ordering $ordering = 0; if ($current_ids = tag_get_tags_ids('course', $courseid)) { end($current_ids); $ordering = key($current_ids) + 1; } //set type tag_type_set($tagid, $tagtype); //tag_instance entry tag_assign('course', $courseid, $tagid, $ordering, $userid); //logging - note only for user added tags if ($tagtype == 'default' and $myurl != '') { $url = $myurl.'?query='.urlencode($tag); add_to_log($courseid, 'coursetags', 'add', $url, 'Course tagged'); } } } } }
/** * Determine if a record is tagged with a specific tag * * @param string $record_type the record type to look for * @param int $record_id the record id to look for * @param string $tag a tag name * @return bool true if it is tagged, false otherwise */ function tag_record_tagged_with($record_type, $record_id, $tag) { if ($tagid = tag_get_id($tag)) { return count_records('tag_instance', 'itemtype', $record_type, 'itemid', $record_id, 'tagid', $tagid); } else { return 0; // tag doesn't exist } }
if ($tag->tagtype != 'default' && (!isset($tagnew->tagtype) || $tagnew->tagtype != '1')) { tag_type_set($tag->id, 'default'); } elseif ($tag->tagtype != 'official' && $tagnew->tagtype == '1') { tag_type_set($tag->id, 'official'); } } if (!has_capability('moodle/tag:manage', $systemcontext)) { unset($tagnew->name); unset($tagnew->rawname); } else { // They might be trying to change the rawname, make sure it's a change that doesn't affect name $norm = tag_normalize($tagnew->rawname, TAG_CASE_LOWER); $tagnew->name = array_shift($norm); if ($tag->name != $tagnew->name) { // The name has changed, let's make sure it's not another existing tag if (tag_get_id($tagnew->name)) { // Something exists already, so flag an error $errorstring = s($tagnew->rawname) . ': ' . get_string('namesalreadybeeingused', 'tag'); } } } if (empty($errorstring)) { // All is OK, let's save it $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); tag_description_set($tag_id, $tagnew->description, $tagnew->descriptionformat); $tagnew->timemodified = time(); if (has_capability('moodle/tag:manage', $systemcontext)) { // rename tag if (!tag_rename($tag->id, $tagnew->rawname)) { print_error('errorupdatingrecord', 'tag'); }
} } //notice to inform what tags had their names effectively updated if ($tags_names_changed) { $notice = implode($tags_names_changed, ', '); $notice .= ' -- ' . get_string('updated', 'tag'); } break; case 'addofficialtag': if (!data_submitted() or !confirm_sesskey()) { break; } $new_otags = explode(',', optional_param('otagsadd', '', PARAM_TAG)); $notice = ''; foreach ($new_otags as $new_otag) { if ($new_otag_id = tag_get_id($new_otag)) { // tag exists, change the type tag_type_set($new_otag_id, 'official'); } else { require_capability('moodle/tag:create', get_context_instance(CONTEXT_SYSTEM)); tag_add($new_otag, 'official'); } $notice .= get_string('addedotag', 'tag', $new_otag) . ' '; } break; } if ($err_notice) { echo $OUTPUT->notification($err_notice, 'red'); } if ($notice) { echo $OUTPUT->notification($notice, 'green');
/** * Determine if a record is tagged with a specific tag * * @param string $record_type the record type to look for * @param int $record_id the record id to look for * @param string $tag a tag name * @return bool true if it is tagged, false otherwise */ function tag_record_tagged_with($record_type, $record_id, $tag) { global $DB; if ($tagid = tag_get_id($tag)) { return $DB->count_records('tag_instance', array('itemtype' => $record_type, 'itemid' => $record_id, 'tagid' => $tagid)); } else { return 0; // tag doesn't exist } }
} elseif (($tag->tagtype != 'official') && ($tagnew->tagtype == '1')) { tag_type_set($tag->id, 'official'); } } if (!has_capability('moodle/tag:manage', $systemcontext) && !has_capability('moodle/tag:edit', $systemcontext)) { unset($tagnew->name); unset($tagnew->rawname); } else { // They might be trying to change the rawname, make sure it's a change that doesn't affect name $norm = tag_normalize($tagnew->rawname, TAG_CASE_LOWER); $tagnew->name = array_shift($norm); if ($tag->name != $tagnew->name) { // The name has changed, let's make sure it's not another existing tag if (tag_get_id($tagnew->name)) { // Something exists already, so flag an error $errorstring = s($tagnew->rawname).': '.get_string('namesalreadybeeingused', 'tag'); } } } if (empty($errorstring)) { // All is OK, let's save it $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); tag_description_set($tag_id, $tagnew->description, $tagnew->descriptionformat); $tagnew->timemodified = time(); if (has_capability('moodle/tag:manage', $systemcontext)) { // rename tag
if ($tag->tagtype != 'default' && (!isset($tagnew->tagtype) || $tagnew->tagtype != '1')) { tag_type_set($tag->id, 'default'); } elseif ($tag->tagtype != 'official' && $tagnew->tagtype == '1') { tag_type_set($tag->id, 'official'); } } if (!has_capability('moodle/tag:manage', $systemcontext)) { unset($tagnew->name); unset($tagnew->rawname); } else { // They might be trying to change the rawname, make sure it's a change that doesn't affect name $norm = tag_normalize($tagnew->rawname, TAG_CASE_LOWER); $tagnew->name = array_shift($norm); if ($tag->rawname !== $tagnew->rawname) { // The name has changed, let's make sure it's not another existing tag if (($id = tag_get_id($tagnew->name)) && $id != $tag->id) { // Something exists already, so flag an error. $errorstring = s($tagnew->rawname) . ': ' . get_string('namesalreadybeeingused', 'tag'); } } } if (empty($errorstring)) { // All is OK, let's save it $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); if ($tag->description != $tagnew->description) { tag_description_set($tag_id, $tagnew->description, $tagnew->descriptionformat); } $tagnew->timemodified = time(); if (has_capability('moodle/tag:manage', $systemcontext)) { // Check if we need to rename the tag. if (isset($tagnew->name) && $tag->rawname != $tagnew->rawname) {
/** * Stores a tag for a course for a user * * @package core_tag * @category tag * @param array $tags simple array of keywords to be stored * @param int $courseid the id of the course we wish to store a tag for * @param int $userid the id of the user we wish to store a tag for * @param string $tagtype official or default only * @param string $myurl (optional) for logging creation of course tags */ function coursetag_store_keywords($tags, $courseid, $userid = 0, $tagtype = 'official', $myurl = '') { global $CFG; if (is_array($tags) and !empty($tags)) { foreach ($tags as $tag) { $tag = trim($tag); if (strlen($tag) > 0) { //tag_set_add('course', $courseid, $tag, $userid); //deletes official tags //add tag if does not exist if (!($tagid = tag_get_id($tag))) { $tag_id_array = tag_add(array($tag), $tagtype); $tagid = $tag_id_array[core_text::strtolower($tag)]; } //ordering $ordering = 0; if ($current_ids = tag_get_tags_ids('course', $courseid)) { end($current_ids); $ordering = key($current_ids) + 1; } //set type tag_type_set($tagid, $tagtype); //tag_instance entry tag_assign('course', $courseid, $tagid, $ordering, $userid, 'core', context_course::instance($courseid)->id); } } } }
print_error('sesskey'); } switch ($action) { case 'addinterest': if (empty($tag) && $id) { // for backward-compatibility (people saving bookmarks, mostly..) $tag = tag_get_name($id); } tag_set_add('user', $USER->id, $tag); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag)); break; case 'removeinterest': if (empty($tag) && $id) { // for backward-compatibility (people saving bookmarks, mostly..) $tag = tag_get_name($id); } tag_set_delete('user', $USER->id, $tag); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag)); break; case 'flaginappropriate': require_capability('moodle/tag:flag', context_system::instance()); $tagid = tag_get_id($tag); // Add flaging action to logs add_to_log(SITEID, 'tag', 'flag', 'index.php?id=' . $tagid, $tagid, '', $USER->id); tag_set_flag($tagid); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag), get_string('responsiblewillbenotified', 'tag')); break; default: print_error('unknowaction'); break; }
if (isguestuser()) { print_error('noguest'); } if (!confirm_sesskey()) { print_error('sesskey'); } switch ($action) { case 'addinterest': if (empty($tag) && $id) { // for backward-compatibility (people saving bookmarks, mostly..) $tag = tag_get_name($id); } tag_set_add('user', $USER->id, $tag); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag)); break; case 'removeinterest': if (empty($tag) && $id) { // for backward-compatibility (people saving bookmarks, mostly..) $tag = tag_get_name($id); } tag_set_delete('user', $USER->id, $tag); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag)); break; case 'flaginappropriate': tag_set_flag(tag_get_id($tag)); redirect($CFG->wwwroot . '/tag/index.php?tag=' . rawurlencode($tag), get_string('responsiblewillbenotified', 'tag')); break; default: print_error('unknowaction'); break; }
/** * Sets 'Set' tags for groups for the forum. * Necessary to use this rather than core tag lib as that does not deal with context * and as group item ids can be the same that is an issue * Also can only have 1 unique group/tag/user record * @param int $forumid forum table id * @param int $groupid groups table id * @param array $tags array of tag rawnames e.g. Fish, frog */ public static function set_group_tags($forumid, $groupid, $tags) { global $DB, $CFG, $USER; require_once $CFG->dirroot . '/tag/lib.php'; $forum = self::get_from_id($forumid, self::CLONE_DIRECT); $context = $forum->get_context(true); $transaction = $DB->start_delegated_transaction(); // Get existing tags used. $settags = array(); $taginstances = $DB->get_records_sql("\n SELECT DISTINCT t.*, ti.id as instanceid\n FROM {tag} t\n INNER JOIN {tag_instance} ti\n ON t.id = ti.tagid\n WHERE ti.component = ? AND ti.itemtype = ? AND ti.contextid = ? AND ti.itemid = ?", array('mod_forumng', 'groups', $context->id, $groupid)); // Delete instances any not in new tags (note tag records not deleted as cleaned in cron). $tistodelete = array(); foreach ($taginstances as $tinstance) { if (!in_array($tinstance->rawname, $tags)) { $tistodelete[] = $tinstance->instanceid; } else { // Store existing tag instance used. $settags[$tinstance->instanceid] = $tinstance->rawname; } } if ($tistodelete) { list($delsql, $delparams) = $DB->get_in_or_equal($tistodelete); $DB->delete_records_select('tag_instance', "id {$delsql}", $delparams); } // Add/get new tag records. $existingtags = tag_get_id($tags, TAG_RETURN_ARRAY); // Normalize tags passed so can match to existing tags array. $normaltags = tag_normalize($tags); // Add tag instances (where needed). $ordering = 0; foreach ($normaltags as $rawname => $name) { if (in_array($rawname, $settags)) { // Pre-existing instance, skip. $ordering++; continue; } $tagid = 0; if (!array_key_exists($name, $existingtags) || empty($existingtags[$name])) { // Need to add tag. $newtag = tag_add($rawname); $tagid = array_pop($newtag); } else { $tagid = $existingtags[$name]; } // Create instance (like tag_assign()). $tag_instance_object = new stdClass(); $tag_instance_object->tagid = $tagid; $tag_instance_object->component = 'mod_forumng'; $tag_instance_object->itemid = $groupid; $tag_instance_object->itemtype = 'groups'; $tag_instance_object->contextid = $context->id; $tag_instance_object->ordering = $ordering; $tag_instance_object->timecreated = time(); $tag_instance_object->timemodified = $tag_instance_object->timecreated; $tag_instance_object->tiuserid = self::get_group_taginstance_userid($groupid, $tagid); $DB->insert_record('tag_instance', $tag_instance_object); $ordering++; } $DB->commit_delegated_transaction($transaction); }
/** * Stores a tag for a course for a user * * @deprecated since 3.0 * @package core_tag * @category tag * @param array $tags simple array of keywords to be stored * @param int $courseid the id of the course we wish to store a tag for * @param int $userid the id of the user we wish to store a tag for * @param string $tagtype official or default only * @param string $myurl (optional) for logging creation of course tags */ function coursetag_store_keywords($tags, $courseid, $userid = 0, $tagtype = 'official', $myurl = '') { debugging('Function coursetag_store_keywords() is deprecated. Userid is no longer used for tagging courses.', DEBUG_DEVELOPER); global $CFG; require_once $CFG->dirroot . '/tag/lib.php'; if (is_array($tags) and !empty($tags)) { foreach ($tags as $tag) { $tag = trim($tag); if (strlen($tag) > 0) { //tag_set_add('course', $courseid, $tag, $userid); //deletes official tags //add tag if does not exist if (!($tagid = tag_get_id($tag))) { $tag_id_array = tag_add(array($tag), $tagtype); $tagid = $tag_id_array[core_text::strtolower($tag)]; } //ordering $ordering = 0; if ($current_ids = tag_get_tags_ids('course', $courseid)) { end($current_ids); $ordering = key($current_ids) + 1; } //set type tag_type_set($tagid, $tagtype); //tag_instance entry tag_assign('course', $courseid, $tagid, $ordering, $userid, 'core', context_course::instance($courseid)->id); } } } }
} elseif (($tag->tagtype != 'official') && ($tagnew->tagtype == '1')) { tag_type_set($tag->id, 'official'); } } if (!has_capability('moodle/tag:manage', $systemcontext)) { unset($tagnew->name); unset($tagnew->rawname); } else { // They might be trying to change the rawname, make sure it's a change that doesn't affect name $norm = tag_normalize($tagnew->rawname, TAG_CASE_LOWER); $tagnew->name = array_shift($norm); if ($tag->rawname !== $tagnew->rawname) { // The name has changed, let's make sure it's not another existing tag if (($id = tag_get_id($tagnew->name)) && $id != $tag->id) { // Something exists already, so flag an error. $errorstring = s($tagnew->rawname).': '.get_string('namesalreadybeeingused', 'tag'); } } } if (empty($errorstring)) { // All is OK, let's save it $tagnew = file_postupdate_standard_editor($tagnew, 'description', $editoroptions, $systemcontext, 'tag', 'description', $tag->id); if ($tag->description != $tagnew->description) { tag_description_set($tag_id, $tagnew->description, $tagnew->descriptionformat); } $tagnew->timemodified = time();
/** * Test for function tag_compute_correlations() that is part of tag cron */ public function test_correlations() { global $DB; $user = $this->getDataGenerator()->create_user(); $this->setUser($user); $user1 = $this->getDataGenerator()->create_user(); $user2 = $this->getDataGenerator()->create_user(); $user3 = $this->getDataGenerator()->create_user(); $user4 = $this->getDataGenerator()->create_user(); $user5 = $this->getDataGenerator()->create_user(); $user6 = $this->getDataGenerator()->create_user(); // Several records have both 'cat' and 'cats' tags attached to them. // This will make those tags automatically correlated. // Same with 'dog', 'dogs' and 'puppy. tag_set('user', $user1->id, array('cat', 'cats'), 'core', context_user::instance($user1->id)->id); tag_set('user', $user2->id, array('cat', 'cats', 'kitten'), 'core', context_user::instance($user2->id)->id); tag_set('user', $user3->id, array('cat', 'cats'), 'core', context_user::instance($user3->id)->id); tag_set('user', $user4->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user4->id)->id); tag_set('user', $user5->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user5->id)->id); tag_set('user', $user6->id, array('dog', 'dogs', 'puppy'), 'core', context_user::instance($user6->id)->id); $tags = tag_get_id(array('cat', 'cats', 'dog', 'dogs', 'kitten', 'puppy')); // Add manual relation between tags 'cat' and 'kitten'. tag_set('tag', $tags['cat'], array('kitten'), 'core', context_system::instance()->id); tag_compute_correlations(); $this->assertEquals($tags['cats'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cat']))); $this->assertEquals($tags['cat'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['cats']))); $this->assertEquals($tags['dogs'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dog']))); $this->assertEquals($tags['dog'] . ',' . $tags['puppy'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['dogs']))); $this->assertEquals($tags['dog'] . ',' . $tags['dogs'], $DB->get_field_select('tag_correlation', 'correlatedtags', 'tagid = ?', array($tags['puppy']))); // Make sure tag_get_correlated() returns 'cats' as the only correlated tag to the 'cat'. $correlatedtags = array_values(tag_get_correlated($tags['cat'])); $this->assertCount(3, $correlatedtags); // This will return all existing instances but they all point to the same tag. $this->assertEquals('cats', $correlatedtags[0]->rawname); $this->assertEquals('cats', $correlatedtags[1]->rawname); $this->assertEquals('cats', $correlatedtags[2]->rawname); $correlatedtags = array_values(tag_get_related_tags($tags['cat'], TAG_RELATED_CORRELATED)); $this->assertCount(1, $correlatedtags); // Duplicates are filtered out here. $this->assertEquals('cats', $correlatedtags[0]->rawname); // Make sure tag_get_correlated() returns 'dogs' and 'puppy' as the correlated tags to the 'dog'. $correlatedtags = array_values(tag_get_correlated($tags['dog'])); $this->assertCount(6, $correlatedtags); // 2 tags times 3 instances. $correlatedtags = array_values(tag_get_related_tags($tags['dog'], TAG_RELATED_CORRELATED)); $this->assertCount(2, $correlatedtags); $this->assertEquals('dogs', $correlatedtags[0]->rawname); $this->assertEquals('puppy', $correlatedtags[1]->rawname); // Function tag_get_related_tags() with default argument will return both related and correlated tags. $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // If we then manually set 'cat' and 'cats' as related, tag_get_related_tags() will filter out duplicates. tag_set('tag', $tags['cat'], array('kitten', 'cats'), 'core', context_system::instance()->id); $relatedtags = array_values(tag_get_related_tags($tags['cat'])); $this->assertCount(2, $relatedtags); $this->assertEquals('kitten', $relatedtags[0]->rawname); $this->assertEquals('cats', $relatedtags[1]->rawname); // Make sure tag_get_correlated() and tag_get_tags() return the same set of fields. $relatedtags = tag_get_tags('tag', $tags['cat']); $relatedtag = reset($relatedtags); $correlatedtags = tag_get_correlated($tags['cat']); $correlatedtag = reset($correlatedtags); $this->assertEquals(array_keys((array) $relatedtag), array_keys((array) $correlatedtag)); }
if (tag_type_set($tagid, $tagtype)) { redirect(new moodle_url($PAGE->url, array('notice' => 'typechanged'))); } } redirect($PAGE->url); break; case 'addofficialtag': require_sesskey(); $otagsadd = optional_param('otagsadd', '', PARAM_RAW); $newtags = preg_split('/\\s*,\\s*/', trim($otagsadd), -1, PREG_SPLIT_NO_EMPTY); $newtags = array_filter(tag_normalize($newtags, TAG_CASE_ORIGINAL)); if (!$newtags) { redirect($PAGE->url); } foreach ($newtags as $newotag) { if ($newotagid = tag_get_id($newotag)) { // Tag exists, change the type. tag_type_set($newotagid, 'official'); } else { tag_add($newotag, 'official'); } } redirect(new moodle_url($PAGE->url, array('notice' => 'added'))); break; } echo $OUTPUT->header(); if ($notice && get_string_manager()->string_exists($notice, 'tag')) { echo $OUTPUT->notification(get_string($notice, 'tag'), 'notifysuccess'); } // Small form to add an official tag. print '<form class="tag-addtags-form" method="post" action="' . $CFG->wwwroot . '/tag/manage.php">';