MDL-11992: adding course tagging patch, by John Beedell. This feature is not

active by default at this time. Related help files are not included in this
commit, as they are being revised (see issue 15385) and will be sent in soon.
This commit is contained in:
scyrma 2008-06-30 09:04:07 +00:00
parent 0f59046fa2
commit 38fb819028
18 changed files with 1740 additions and 70 deletions

View File

@ -2,8 +2,12 @@
class block_tags extends block_base {
function init() {
$this->version = 2007101509;
$this->version = 2008063001;
$this->title = get_string('blocktagstitle', 'tag');
// the cron function goes through all users, so only do daily
// (this creates rss feeds for personal course tags)
// removed until rsslib supports dc/cc
// $this->cron = 60*60*24;
}
function instance_allow_multiple() {
@ -11,7 +15,7 @@ class block_tags extends block_base {
}
function has_config() {
return false;
return true;
}
function applicable_formats() {
@ -61,7 +65,253 @@ class block_tags extends block_base {
require_once($CFG->dirroot.'/tag/lib.php');
$this->content->text = tag_print_cloud($this->config->numberoftags, true);
if (empty($CFG->block_tags_showcoursetags) or !$CFG->block_tags_showcoursetags) {
$this->content->text = tag_print_cloud($this->config->numberoftags, true);
// start of show course tags section
} else {
require_once($CFG->dirroot.'/tag/coursetagslib.php');
// Permissions and page awareness
$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
$isguest = has_capability('moodle/legacy:guest', $sitecontext, $USER->id, false);
$loggedin = isloggedin() && !$isguest;
$coursepage = $canedit = false;
$coursepage = (isset($COURSE->id) && $COURSE->id != SITEID);
$mymoodlepage = strpos($_SERVER['PHP_SELF'], 'my') > 0 ? true : false;
$sitepage = (isset($COURSE->id) && $COURSE->id == SITEID && !$mymoodlepage);
$coursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id);
if ($coursepage) {
$canedit = has_capability('moodle/tag:create', $sitecontext);
}
// Check rss feed - temporarily removed until Dublin Core tags added
// provides a feed of users course tags for each unit they have tagged
//$rssfeed = '';
//if (file_exists($CFG->dataroot.'/'.SITEID.'/usertagsrss/'.$USER->id.'/user_unit_tags_rss.xml')) {
// $rssfeed = '/file.php/'.SITEID.'/usertagsrss/'.$USER->id.'/user_unit_tags_rss.xml';
//}
// Language strings
$tagslang = 'block_tags';
// DB hits to get groups of marked up tags (if available)
//TODO check whether time limited personal tags are required
$numoftags = $this->config->numberoftags;
$sort = 'name';
$alltags = $officialtags = $coursetags = $commtags = $mytags = $coursetagdivs = $courseflag = '';
if ($sitepage or $coursepage) {
$alltags = coursetag_print_cloud(coursetag_get_all_tags($sort, $this->config->numberoftags), true);
$officialtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), true);
$commtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', $numoftags, $sort), true);
if ($loggedin) {
$mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', $numoftags, $sort), true);
}
}
if ($coursepage) {
$coursetags = coursetag_print_cloud(coursetag_get_tags($COURSE->id, 0, '', $numoftags, $sort), true);
if (!$coursetags) $coursetags = get_string('notagsyet', $tagslang);
$courseflag = '&courseid='.$COURSE->id;
}
if ($mymoodlepage) {
$mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', $numoftags, $sort), true);
$officialtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), true);
$commtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', $numoftags, $sort), true);
}
// Prepare the divs and javascript that displays the groups of tags (and which is displayed first)
$moretags = $CFG->wwwroot.'/tag/coursetags_more.php';
$moretagstitle = get_string('moretags', $tagslang);
$moretagsstring = get_string('more', $tagslang);
$displayblock = 'style="display:block"';
$displaynone = 'style="display:none"'; //only one div created below will be displayed at a time
if ($alltags) {
if ($sitepage) {
$display = $displayblock;
} else {
$display = $displaynone;
}
$alltagscontent = '
<div id="f_alltags" '.$display.'>'.
get_string("alltags", $tagslang).
'<div class="coursetag_list">'.$alltags.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags.'?show=all'.$courseflag.'" title="'.$moretagstitle.'">'.$moretagsstring.'</a>
</div>
</div>';
$coursetagdivs .= '"f_alltags", ';
}
if ($mytags) {
if ($mymoodlepage) {
$display = $displayblock;
} else {
$display = $displaynone;
}
$mytagscontent = '
<div id="f_mytags" '.$display.'>';
/*if ($rssfeed) { // - temporarily removed
$mytagscontent .= link_to_popup_window(
$rssfeed, $name='popup',
'<img src="'.$CFG->wwwroot.'/pix/rss.gif" alt="User Unit Tags RSS" /> My Unit Tags RSS',
$height=600, $width=800,
$title='My Unit Tags RSS', $options='menubar=1,scrollbars,resizable', $return=true).'<br />';
}*/
$mytagscontent .=
get_string('mytags', $tagslang).
'<div class="coursetag_list">'.$mytags.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags.'?show=my'.$courseflag.'" title="'.$moretagstitle.'">'.$moretagsstring.'</a>
</div>
</div>';
$coursetagdivs .= '"f_mytags", ';
}
if ($officialtags) {
if ($mytags or $alltags) {
$display = $displaynone;
} else {
$display = $displayblock;
}
$officialtagscontent = '
<div id="f_officialtags" '.$display.'>'.
get_string('officialtags', $tagslang).
'<div class="coursetag_list">'.$officialtags.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags.'?show=official'.$courseflag.'" title="'.$moretagstitle.'">'.$moretagsstring.'</a>
</div>
</div>';
$coursetagdivs .= '"f_officialtags", ';
}
if ($coursetags) {
if ($coursepage) {
$display = $displayblock;
} else {
$display = $displaynone;
}
$coursetagscontent = '
<div id="f_coursetags" '.$display.'>'.
get_string('coursetags', $tagslang).
'<div class="coursetag_list">'.$coursetags.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags.'?show=course'.$courseflag.'" title="'.$moretagstitle.'">'.$moretagsstring.'</a>
</div>
</div>';
$coursetagdivs .= '"f_coursetags", ';
}
if ($commtags) {
$commtagscontent = '
<div id="f_commtags" '.$displaynone.'>'.
get_string('communitytags', $tagslang).
'<div class="coursetag_list">'.$commtags.'</div>
<div class="coursetag_morelink">
<a href="'.$moretags.'?show=community'.$courseflag.'" title="'.$moretagstitle.'">'.$moretagsstring.'</a>
</div>
</div>';
$coursetagdivs .= '"f_commtags", ';
}
// Tidy up the end of a javascript array and add javascript
$coursetagdivs = rtrim($coursetagdivs, ', ');
$this->content->text .= coursetag_get_jscript($coursetagdivs);
// Add the divs (containing the tags) to the block's content
if ($alltags) { $this->content->text .= $alltagscontent; }
if ($mytags) { $this->content->text .= $mytagscontent; }
if ($officialtags) { $this->content->text .= $officialtagscontent; }
if ($coursetags) { $this->content->text .= $coursetagscontent; }
if ($commtags) { $this->content->text .= $commtagscontent; }
// add the input form section (allowing a user to tag the current course) and navigation, or loggin message
if ($loggedin) {
// only show the input form on course pages for those allowed (or not barred)
if ($coursepage && $canedit) {
//$this->content->footer .= coursetag_get_jscript();
$tagthisunit = get_string('tagthisunit', $tagslang);
$buttonadd = get_string('add', $tagslang);
$arrowtitle = get_string('arrowtitle', $tagslang);
$coursetaghelpbutton = helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE);
$this->content->footer .= <<<EOT
<hr />
<form action="{$CFG->wwwroot}/tag/coursetags_add.php" method="post" id="coursetag"
onsubmit="return ctags_checkinput(this.coursetag_new_tag.value)">
<div style="display: none;">
<input type="hidden" name="entryid" value="$COURSE->id" />
<input type="hidden" name="userid" value="$USER->id" />
</div>
<div><label for="coursetag_new_tag">$tagthisunit</label></div>
<div class="coursetag_form_wrapper">
<div class="coursetag_form_positioner">
<div class="coursetag_form_input1">
<input type="text" name="coursetag_sug_keyword" class="coursetag_form_input1a" disabled="disabled" />
</div>
<div class="coursetag_form_input2">
<input type="text" name="coursetag_new_tag" id="coursetag_new_tag" class="coursetag_form_input2a"
onfocus="ctags_getKeywords()" onkeyup="ctags_getKeywords()" maxlength="50" />
</div>
<div class="coursetag_form_input3" id="coursetag_sug_btn">
<a title="$arrowtitle">
<img src="$CFG->pixpath/t/arrow_left.gif" width="10" height="10" alt="enter" onclick="ctags_setKeywords()" />
</a>
</div>
</div>
<div style="display: inline;">
<button type="submit">$buttonadd</button>
$coursetaghelpbutton
</div>
</div>
</form>
EOT;
// add the edit link
$this->content->footer .= '
<div>
<a href="'.$CFG->wwwroot.'/tag/coursetags_edit.php?courseid='.$COURSE->id.'"
title="'.get_string('edittags', $tagslang).'">'.get_string('edittags', $tagslang).'</a>
</div>';
}
// Navigation elements at the bottom of the block
// show the alternative displays options if available
if ($mytags or $officialtags or $commtags or $coursetags) {
$this->content->footer .= '<div id="coursetagslinks"></div>';
}
// This section sets the order of the links
$coursetagslinks = array();
if ($mytags) {
$coursetagslinks['my'] = array('title'=>get_string('mytags2', $tagslang),
'onclick'=>'f_mytags',
'text'=>get_string('mytags1', $tagslang));
}
// because alltags is always present, only show link if there is something else as well
if ($alltags and ($mytags or $officialtags or $commtags or $coursetags)) {
$coursetagslinks['all'] = array('title'=>get_string('alltags2', $tagslang),
'onclick'=>'f_alltags',
'text'=>get_string('alltags1', $tagslang));
}
if ($officialtags) {
$coursetagslinks['off'] = array('title'=>get_string('officialtags2', $tagslang),
'onclick'=>'f_officialtags',
'text'=>get_string('officialtags1', $tagslang));
}
//if ($commtags) {
// $coursetagslinks['com'] = array('title'=>get_string('communitytags2', $tagslang),
// 'onclick'=>'f_commtags',
// 'text'=>get_string('communitytags1', $tagslang));
//}
if ($coursetags) {
$coursetagslinks['crs'] = array('title'=>get_string('coursetags2', $tagslang),
'onclick'=>'f_coursetags',
'text'=>get_string('coursetags1', $tagslang));
}
$this->content->footer .= coursetag_get_jscript_links($coursetagslinks);
} else {
//if not logged in
$this->content->footer = '<hr />'.get_string('please', $tagslang).'
<a href="'.$CFG->wwwroot.'/login/index.php">'.get_string('login', $tagslang).'
</a> '.get_string('tagunits', $tagslang);
}
}
// end of show course tags section
return $this->content;
}
@ -81,6 +331,21 @@ class block_tags extends block_base {
notice(get_string('blockconfigbad'), str_replace('blockaction=', 'dummy=', qualified_me()));
}
}
}
/*
* function removed until rsslib supports dc/cc
*/
/*
function cron() {
if (SHOWCOURSETAGS) {
global $CFG;
require_once($CFG->dirroot.'/tag/coursetagslib.php');
return coursetag_rss_feeds();
} else {
return TRUE;
}
}
*/
}
?>

62
blocks/tags/coursetags.js Normal file
View File

@ -0,0 +1,62 @@
/**
* coursetags.js
* @author j.beedell@open.ac.uk July07
*
* getKeywords modified from an original script (Auto Complete Textfield)
* from The JavaScript Source http://javascript.internet.com
* originally created by: Timothy Groves http://www.brandspankingnew.net/
*/
function ctags_show_div(mydiv) {
for(x in coursetagdivs) {
if(mydiv == coursetagdivs[x]) {
document.getElementById(coursetagdivs[x]).style.display="block";
} else {
document.getElementById(coursetagdivs[x]).style.display="none";
}
}
return false;
}
var sug = "";
var sug_disp = "";
function ctags_getKeywords() {
/*
// This 'workaround' removing the xhtml strict form autocomplete="off" needs to
// be added to the body onload() script to work - but decided not to include
// (having the browser list might help with screen readers more than this script)
// document.forms['coursetag'].setAttribute("autocomplete", "off");
*/
var input = document.forms['coursetag'].coursetag_new_tag.value;
var len = input.length;
sug_disp = ""; sug = "";
if (input.length) {
for (ele in coursetag_tags)
{
if (coursetag_tags[ele].substr(0,len).toLowerCase() == input.toLowerCase())
{
sug_disp = input + coursetag_tags[ele].substr(len);
sug = coursetag_tags[ele];
break;
}
}
}
document.forms['coursetag'].coursetag_sug_keyword.value = sug_disp;
if (!sug.length || input == sug_disp)
document.getElementById('coursetag_sug_btn').style.display = "none";
else
document.getElementById('coursetag_sug_btn').style.display = "block";
}
function ctags_setKeywords() {
document.forms['coursetag'].coursetag_new_tag.value = sug;
ctags_hideSug();
}
function ctags_hideSug() {
document.forms['coursetag'].coursetag_sug_keyword.value = "";
document.getElementById('coursetag_sug_btn').style.display = "none";
}

6
blocks/tags/settings.php Normal file
View File

@ -0,0 +1,6 @@
<?php
$settings->add(new admin_setting_configcheckbox('block_tags_showcoursetags', get_string('showcoursetags', 'block_tags'),
get_string('showcoursetagsdef', 'block_tags'), 0));
?>

116
blocks/tags/styles.php Normal file
View File

@ -0,0 +1,116 @@
/*
* CSS for course tags
* @author j.beedell@open.ac.uk July07
*
* Styles for block_tags.php
*/
.coursetag_form_wrapper {
margin: auto;
width: 13em;
}
.coursetag_form_positioner {
position: relative;
margin: 5px 0 0 0;
height: 25px;
}
.coursetag_form_input1 {
position: absolute;
top: 0;
left: 0;
z-index: 1;
}
.coursetag_form_input2 {
position: absolute;
top: 0;
left: 0;
z-index: 2;
}
.coursetag_form_input3 {
position: absolute;
top: 3px;
left: 12.8em;
display: none;
}
.coursetag_form_input1a {
background-color: white;
border: 1px solid #999;
width: 12em;
padding: 2px;
}
.coursetag_form_input2a {
background: transparent;
color: #669954;
border: 1px solid #999;
width: 12em;
padding: 2px;
}
.coursetag_morelink {
float: right;
font-size: 0.8em;
margin: -5px 5px 5px 0;
}
.coursetag_list {
padding-top: 4px;
}
/* Styles for edit_tags.php */
.coursetag_edit_centered {
position: relative;
width: 600px;
margin: 20px auto;
}
.coursetag_edit_row {
margin: 5px 0 5px 0;
height: 30px;
}
.coursetag_edit_left {
position: relative;
float: left;
padding: 3px 5px;
}
.coursetag_edit_right {
position: relative;
float: left;
padding: 3px 0px;
}
.coursetag_edit_input3 {
position: relative;
left: 10.5em;
display: none;
}
/* Styles for more_tags.php */
.coursetag_more_title {
margin: 30px 30px -25px 30px;
}
.coursetag_more_tags {
margin: 30px;
}
.coursetag_more_large {
font-size: 120%
}
.coursetag_more_small {
font-size: 80%
}
.coursetag_more_link {
font-size: 80%;
}

View File

@ -40,6 +40,9 @@ function make_log_url($module, $url) {
case 'upload':
return $url;
break;
case 'coursetags':
return '/'.$url;
break;
case 'library':
case '':
return '/';

View File

@ -0,0 +1,66 @@
<?php
/* block_tags.php
* @author j.beedell@open.ac.uk July07
*/
$string['add'] = 'Add';
$string['alltags'] = 'All tags:';
$string['alltags1'] = 'all tags';
$string['alltags2'] = 'Show all tags (user profile, blogs and course tags)';
$string['arrowtitle'] = 'Click here to enter the suggested text (grey letters).';
$string['communitytags'] = 'Community tags:';
$string['communitytags1'] = 'community tags';
$string['communitytags2'] = 'Show all user created course tags';
$string['coursetags'] = 'Course tags:';
$string['coursetags1'] = 'course tags';
$string['coursetags2'] = 'Show tags for this course';
$string['edit'] = 'edit...';
$string['editdeletemytag'] = 'Delete tag from this course:';
$string['editmytags'] = 'My tags - shortcuts to all your tagged courses.';
$string['editmytagsfor'] = 'Edit my tags for $a';
$string['editnopersonaltags'] = 'No personal tags have been created yet.';
$string['edittagthisunit'] = 'Add tag to this course:';
$string['editthiscoursetags'] = 'My tags for this course are $a';
$string['edittags'] = 'Edit my tags...';
$string['edittitle'] = 'My tags';
$string['entries'] = 'entries';
$string['entry'] = 'entry';
$string['jserror1'] = 'Tags must have more that one and less than 50 characters. Please adjust your tag.';
$string['jserror2'] = 'Tags cannot contain these special characters - backslash, less than or greater than. Please adjust your tag.';
$string['login'] = 'log in';
$string['more'] = 'more...';
$string['moreorder'] = 'Order: ';
$string['moreorderalpha'] = 'Alphabetical';
$string['moreorderdate'] = 'Date created';
$string['moreorderpop'] = 'Popularity';
$string['moreshow'] = 'Show: ';
$string['moreshowalltags'] = 'All tags';
$string['moreshowcommtags'] = 'Community tags';
$string['moreshowofficialtags'] = 'Official tags';
$string['moreshowmytags'] = 'My tags';
$string['moretags'] = 'Show and filter more tags';
$string['moreshowcoursetags'] = 'Tags for \'$a\'';
$string['moretitle'] = 'More tags';
$string['morewelcome'] = "Welcome to the 'More tags' tag cloud.
Tags are user created links to things. Tags allow you to categorise and link things
like your favourite courses, your blogs or your profile with your own words.
Different groups of tags may be displayed with the links on the 'Show:' line,
and may be reordered with the links on the 'Order:' line. More help is here:";
$string['mycoursetag1'] = 'Show my course tags';
$string['mycoursetag2'] = 'my course tags';
$string['mycoursetags'] = 'My course tags:';
$string['mytags'] = 'My tags:';
$string['mytags1'] = 'my tags';
$string['mytags2'] = 'Show my personal tags';
$string['notagsyet'] = 'No tags yet';
$string['officialtags'] = 'Official course tags:';
$string['officialtags1'] = 'official tags';
$string['officialtags2'] = 'Show official course tags';
$string['please'] = 'Please';
$string['select'] = 'Select...';
$string['showcoursetags'] = 'Show course tags';
$string['showcoursetagsdef'] = 'Display the course tagging features in the tags block, allowing students to tag courses.';
$string['tags'] = 'tags';
$string['tagthisunit'] = 'Tag this course:';
$string['tagunits'] = 'to tag your favourite courses';
?>

View File

@ -10,12 +10,16 @@ $string['changetype'] = 'Change tag type';
$string['description'] = 'Description';
$string['delete'] = 'Delete';
$string['deleted'] = 'Deleted';
$string['deletedcoursetags'] = 'Deleted - course tags';
$string['edittag'] = 'Edit this tag';
$string['errordeleting'] = 'Error deleting tag with id $a, please report to your system administrator.';
$string['errortagfrontpage'] = 'Tagging the site main page is not allowed';
$string['errorupdatingrecord'] = 'Error updating tag record';
$string['flag'] = 'Flag';
$string['flagasinappropriate'] = 'Flag as inappropriate';
$string['helprelatedtags'] = 'Comma separated related tags';
$string['id'] = 'id';
$string['relatedblogs'] = 'Recent blog entries with this tag';
$string['relatedblogs'] = 'Most recent blog entries tagged with \"$a\"';
$string['managetags'] = 'Manage tags';
$string['name'] = 'Tag name';
$string['namesalreadybeeingused'] = 'Tag names already being used';
@ -30,8 +34,10 @@ $string['removetagfrommyinterests'] = 'Remove \"$a\" from my interests';
$string['responsiblewillbenotified'] = 'The person responsible will be notified';
$string['resetflag'] = 'Reset flag';
$string['reset'] = 'Reset';
$string['rsstitle'] = 'Course Tags RSS Feed for user: $a';
$string['rssdesc'] = 'This RSS feed was automatically generated by Moodle and contains user generated tags for courses.';
$string['search'] = 'Search';
$string['seeallblogs'] = 'See all blogs with this tag';
$string['seeallblogs'] = 'See all blog entries tagged with \"$a\"...';
$string['searchresultsfor'] = 'Search results for \"$a\"';
$string['searchtags'] = 'Search tags';
$string['select'] = 'Select';
@ -40,9 +46,9 @@ $string['tag'] = 'Tag';
$string['tagtype'] = 'Tag type';
$string['tagtype_official'] = 'Official';
$string['tagtype_default'] = 'Default';
$string['tagindex_coursetitle'] = 'Courses tagged with \"$a\"';
$string['tags'] = 'Tags';
$string['tagsaredisabled'] = 'Tags are disabled';
$string['thingstaggedwith'] = '$a->count things tagged with \"$a->name\"';
$string['thistaghasnodesc'] = 'This tag currently has no description.';
$string['timemodified'] = 'Modified';
$string['typechanged'] = 'Tag type changed';

View File

@ -1503,8 +1503,9 @@
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="tagid"/>
<FIELD NAME="tagid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="id" NEXT="itemtype"/>
<FIELD NAME="itemtype" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="tagid" NEXT="itemid"/>
<FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="itemtype" NEXT="ordering"/>
<FIELD NAME="ordering" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Maintains the order of the tag instances of an item" PREVIOUS="itemid" NEXT="timemodified"/>
<FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="itemtype" NEXT="tiuserid"/>
<FIELD NAME="tiuserid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="itemid" NEXT="ordering"/>
<FIELD NAME="ordering" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Maintains the order of the tag instances of an item" PREVIOUS="tiuserid" NEXT="timemodified"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="timemodified" PREVIOUS="ordering"/>
</FIELDS>
<KEYS>
@ -1512,7 +1513,7 @@
<KEY NAME="tagid" TYPE="foreign" FIELDS="tagid" REFTABLE="tag" REFFIELDS="id" PREVIOUS="primary"/>
</KEYS>
<INDEXES>
<INDEX NAME="itemtype-itemid-tagid" UNIQUE="true" FIELDS="itemtype, itemid, tagid"/>
<INDEX NAME="itemtype-itemid-tagid-tiuserid" UNIQUE="true" FIELDS="itemtype, itemid, tagid, tiuserid"/>
</INDEXES>
</TABLE>
<TABLE NAME="groups" COMMENT="Each record represents a group." PREVIOUS="tag_instance" NEXT="groupings">

View File

@ -134,6 +134,28 @@ function xmldb_main_upgrade($oldversion=0) {
upgrade_main_savepoint($result, 2008051203);
}
if ($result && $oldversion < 2008063001) {
// table to be modified
$table = new xmldb_table('tag_instance');
// add field
$field = new xmldb_field('tiuserid');
if (!$dbman->field_exists($table, $field)) {
$field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'itemid');
$dbman->add_field($table, $field);
}
// modify index
$index = new xmldb_index('itemtype-itemid-tagid');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid'));
$dbman->drop_index($table, $index);
$index = new xmldb_index('itemtype-itemid-tagid-tiuserid');
$index->set_attributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid', 'tiuserid'));
$dbman->add_index($table, $index);
/// Main savepoint reached
upgrade_main_savepoint($result, 2008063001);
}
/*
* TODO:
* drop adodb_logsql table and create a new general sql log table

View File

@ -154,8 +154,8 @@ define('PARAM_FILE', 0x0010);
define('PARAM_TAG', 0x0011);
/**
* PARAM_TAGLIST - list of tags separated by commas (interests, blogs, etc.)
*/
* PARAM_TAGLIST - list of tags separated by commas (interests, blogs, etc.)
*/
define('PARAM_TAGLIST', 0x0012);
/**
@ -2817,7 +2817,7 @@ function update_user_record($username, $authplugin) {
}
/**
* will truncate userinfo as it comes from auth_get_userinfo (from external auth)
* will truncate userinfo as it comes from auth_get_userinfo (from external auth)
* which may have large fields
*/
function truncate_userinfo($info) {
@ -3543,6 +3543,10 @@ function remove_course_contents($courseid, $showfeedback=true) {
remove_course_grades($courseid, $showfeedback);
remove_grade_letters($context, $showfeedback);
/// Delete course tags
require_once($CFG->dirroot.'/tag/coursetagslib.php');
coursetag_delete_course_tags($course->id, $showfeedback);
return $result;
}

34
tag/coursetags_add.php Normal file
View File

@ -0,0 +1,34 @@
<?php
/**
* coursetags_add.php
* @author j.beedell@open.ac.uk June07
*/
require_once('../config.php');
$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT);
$courseid = optional_param('entryid', 0, PARAM_INT);
$userid = optional_param('userid', 0, PARAM_INT);
$keyword = trim(strip_tags($keyword)); //better cleanup of user input is done later
if ($keyword) {
require_once($CFG->dirroot.'/tag/coursetagslib.php');
if ($courseid > 0 and $userid > 0) {
$myurl = 'tag/search.php';
$keywords = explode(',', $keyword);
coursetag_store_keywords($keywords, $courseid, $userid, 'default', $myurl);
}
}
// send back to originating page, where the new tag will be visible in the block
if ($courseid > 0) {
$myurl = $CFG->wwwroot.'/course/view.php?id='.$courseid;
} else {
$myurl = $CFG->wwwroot.'/';
}
redirect($myurl);
?>

177
tag/coursetags_edit.php Normal file
View File

@ -0,0 +1,177 @@
<?php
/**
* coursetags_edit.php
* displays personal tags for a course with some editing facilites
* @author j.beedell@open.ac.uk June07
*/
require_once('../config.php');
require_once($CFG->dirroot.'/tag/coursetagslib.php');
require_once($CFG->dirroot.'/tag/lib.php');
$courseid = optional_param('courseid', 0, PARAM_INT);
$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT);
$deltag = optional_param('del_tag', 0, PARAM_INT);
if ($courseid != SITEID) {
if (! ($course = $DB->get_record('course', array('id' => $courseid), '*')) ) {
print_error('invalidcourse');
}
} else {
print_error('errortagfrontpage', 'tag');
}
// Permissions
$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
require_login($course->id);
$canedit = has_capability('moodle/tag:create', $sitecontext);
// Language strings
$tagslang = 'block_tags';
// Store data
if ($data = data_submitted()) {
if (confirm_sesskey() and $courseid > 0 and $USER->id > 0 and $canedit) {
// store personal tag
if (trim(strip_tags($keyword))) {
$myurl = 'tag/search.php';
$keywords = explode(',', $keyword);
try {
coursetag_store_keywords($keywords, $courseid, $USER->id, 'default', $myurl);
}
catch (Exception $e) {
notice($e->getmessage());
}
}
// delete personal tag
if ($deltag > 0) {
coursetag_delete_keyword($deltag, $USER->id, $courseid);
}
}
}
// The title and breadcrumb
$title = get_string('edittitle', $tagslang);
$coursefullname = format_string($course->fullname);
$courseshortname = format_string($course->shortname);
//$navigation[] = array('name' => $coursefullname, 'link' => $CFG->wwwroot.'/course/view.php?id='.$courseid, 'type' => 'misc');
$navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc');
$nav = build_navigation($navigation);
print_header_simple($title, '', $nav, '', '', false);
// Print personal tags for all courses
$title = get_string('edittitle', $tagslang);
print_heading($title, 'center');
$mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default'), true);
$outstr = '
<div class="coursetag_edit_centered">
<div>
'.get_string('editmytags', $tagslang).'
</div>
<div>';
if ($mytags) {
$outstr .= $mytags;
} else {
$outstr .= get_string('editnopersonaltags', $tagslang);
}
$outstr .= '
</div>
</div>';
echo $outstr;
// Personal tag editing
if ($canedit) {
$title = get_string('editmytagsfor', $tagslang, '"'.$coursefullname.' ('.$courseshortname.')"');
print_heading($title);
// Deletion here is open to the users own tags for this course only
$selectoptions = '<option value="0">'.get_string('select', $tagslang).'</option>';
$coursetabs = '';
if ($options = coursetag_get_records($courseid, $USER->id)) {
$coursetabs = '"';
foreach ($options as $option) {
$selectoptions .= '<option value="'.$option->id.'">'.$option->rawname.'</option>';
$coursetabs .= $option->rawname . ', ';
}
$coursetabs = rtrim($coursetabs, ', ');
$coursetabs .= '"';
}
if ($coursetabs) {
$outstr = '
<div class="coursetag_edit_centered">
'.get_string('editthiscoursetags', $tagslang, $coursetabs).'
</div>';
} else {
$outstr = '
<div class="coursetag_edit_centered">
'.get_string('editnopersonaltags', $tagslang).'
</div>';
}
// Print the add and delete form
$script = coursetag_get_jscript();
$addtagshelp = helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE);
$edittagthisunit = get_string('edittagthisunit', $tagslang);
$arrowtitle = get_string('arrowtitle', $tagslang);
$outstr .= <<<EOT
$script
<form action="$CFG->wwwroot/tag/coursetags_edit.php" method="post" id="coursetag">
<div style="display: none;">
<input type="hidden" name="courseid" value="$course->id" />
<input type="hidden" name="sesskey" value="$USER->sesskey" />
</div>
<div class="coursetag_edit_centered">
<div class="coursetag_edit_row">
<div class="coursetag_edit_left">
$addtagshelp$edittagthisunit
</div>
<div class="coursetag_edit_right">
<div class="coursetag_form_input1">
<input type="text" name="coursetag_sug_keyword" class="coursetag_form_input1a" disabled="disabled" />
</div>
<div class="coursetag_form_input2">
<input type="text" name="coursetag_new_tag" id="coursetag_new_tag" class="coursetag_form_input2a"
onfocus="ctags_getKeywords()" onkeyup="ctags_getKeywords()" maxlength="50" />
</div>
<div class="coursetag_edit_input3" id="coursetag_sug_btn">
<a title="$arrowtitle">
<img src="$CFG->pixpath/t/arrow_left.gif" width="10" height="10" alt="enter" onclick="ctags_setKeywords()" />
</a>
</div>
</div>
</div>
EOT;
if ($coursetabs) {
$deletetagshelp = helpbutton('deletetags', 'deleting tags', $tagslang, TRUE, FALSE, '', TRUE);
$editdeletemytag = get_string('editdeletemytag', $tagslang);
$outstr .= <<<EOT1
<div class="coursetag_edit_row">
<div class="coursetag_edit_left">
$deletetagshelp$editdeletemytag
</div>
<div class="coursetag_edit_right">
<select name="del_tag">
$selectoptions
</select>
</div>
</div>
EOT1;
}
$submitstr = get_string('submit');
$outstr .= <<<EOT2
<div class="clearer"></div>
<div class="coursetag_edit_row">
<button type="submit">$submitstr</button>
</div>
</div>
</form>
EOT2;
echo $outstr;
}
print_footer();
?>

187
tag/coursetags_more.php Normal file
View File

@ -0,0 +1,187 @@
<?php
/**
* coursetags_more.php
* a full display of tags allowing some filtering and reordering
* @author j.beedell@open.ac.uk June07
*/
require_once('../config.php');
require_once($CFG->dirroot.'/tag/coursetagslib.php');
require_once($CFG->dirroot.'/tag/lib.php');
$sort = optional_param('sort', 'alpha', PARAM_TEXT); //alpha, date or popularity
$show = optional_param('show', 'all', PARAM_TEXT); //all, my, official, community or course
$courseid = optional_param('courseid', 0, PARAM_INT);
// Some things require logging in
if ($CFG->forcelogin or $show == 'my') {
require_login();
}
// Permissions
$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
$isguest = has_capability('moodle/legacy:guest', $sitecontext, $USER->id, false);
$loggedin = isloggedin() && !$isguest;
// Course check
if ($courseid) {
if (!($course = $DB->get_record('course', array('id'=>$courseid)))) {
$courseid = 0;
}
if ($courseid == SITEID) $courseid = 0;
}
// Language strings
$tagslang = 'block_tags';
$title = get_string('moretitle', $tagslang);
$link1 = get_string('moreshow', $tagslang);
$link2 = get_string('moreorder', $tagslang);
$showalltags = get_string('moreshowalltags', $tagslang);
$showofficialtags = get_string('moreshowofficialtags', $tagslang);
$showmytags = get_string('moreshowmytags', $tagslang);
$showcommtags = get_string('moreshowcommtags', $tagslang);
$orderalpha = get_string('moreorderalpha', $tagslang);
$orderdate = get_string('moreorderdate', $tagslang);
$orderpop = get_string('moreorderpop', $tagslang);
$welcome = get_string('morewelcome', $tagslang);
// The title and breadcrumb
if ($courseid) {
$navigation[] = array('name' => format_string($course->shortname), 'link' => $CFG->wwwroot.'/course/view.php?id='.$courseid, 'type' => 'misc');
$navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc');
} else {
$navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc');
}
$nav = build_navigation($navigation);
print_header_simple($title, '', $nav, '', '', false);
print_heading($title, 'centre');
// Prepare data for tags
$courselink = '';
if ($courseid) { $courselink = '&amp;courseid='.$courseid; }
$myurl = $CFG->wwwroot.'/tag/coursetags_more.php';
$myurl2 = $CFG->wwwroot.'/tag/coursetags_more.php?show='.$show;
// Course tags
if ($show == 'course' and $courseid) {
if ($sort == 'popularity') {
$tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'popularity'), true, 200, 90);
} else if ($sort == 'date') {
$tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'timemodified'), true, 200, 90);
} else {
$tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'name'), true, 200, 90);
}
// My tags
} else if ($show == 'my' and $loggedin) {
if ($sort == 'popularity') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'popularity'), true, 200, 90);
} else if ($sort == 'date') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'timemodified'), true, 200, 90);
} else {
$tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'name'), true, 200, 90);
}
// Official course tags
} else if ($show == 'official') {
if ($sort == 'popularity') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'popularity'), true, 200, 90);
} else if ($sort == 'date') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'timemodified'), true, 200, 90);
} else {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'name'), true, 200, 90);
}
// Community (official and personal together) also called user tags
} else if ($show == 'community') {
if ($sort == 'popularity') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'popularity'), true, 200, 90);
} else if ($sort == 'date') {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'timemodified'), true, 200, 90);
} else {
$tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'name'), true, 200, 90);
}
// All tags for courses and blogs and any thing else tagged - the fallback default ($show == all)
} else {
$subtitle = $showalltags;
if ($sort == 'popularity') {
$tags = coursetag_print_cloud(coursetag_get_all_tags('popularity'), true, 200, 90);
} else if ($sort == 'date') {
$tags = coursetag_print_cloud(coursetag_get_all_tags('timemodified'), true, 200, 90);
} else {
$tags = coursetag_print_cloud(coursetag_get_all_tags('name'), true, 200, 90);
}
}
// Prepare the links for the show and order lines
if ($show == 'all') {
$link1 .= '<b>'.$showalltags.'</b>';
} else {
$link1 .= '<a href="'.$myurl.'?show=all'.$courselink.'">'.$showalltags.'</a>';
}
//if ($show == 'official') { //add back in if you start to use official course tags
// $link1 .= ' | <b>'.$showofficialtags.'</b>';
//} else {
// $link1 .= ' | <a href="'.$myurl.'?show=official'.$courselink.'">'.$showofficialtags.'</a>';
//}
if ($show == 'community') {
$link1 .= ' | <b>'.$showcommtags.'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=community'.$courselink.'">'.$showcommtags.'</a>';
}
if ($loggedin) {
if ($show == 'my') {
$link1 .= ' | <b>'.$showmytags.'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=my'.$courselink.'">'.$showmytags.'</a>';
}
}
if ($courseid) {
if ($show == 'course') {
$link1 .= ' | <b>'.get_string('moreshowcoursetags', $tagslang, $course->fullname).'</b>';
} else {
$link1 .= ' | <a href="'.$myurl.'?show=course'.$courselink.'">'.get_string('moreshowcoursetags', $tagslang, $course->fullname).'</a>';
}
}
if ($sort == 'alpha') {
$link2 .= '<b>'.$orderalpha.'</b> | ';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=alpha'.$courselink.'">'.$orderalpha.'</a> | ';
}
if ($sort == 'popularity') {
$link2 .= '<b>'.$orderpop.'</b> | ';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=popularity'.$courselink.'">'.$orderpop.'</a> | ';
}
if ($sort == 'date') {
$link2 .= '<b>'.$orderdate.'</b>';
} else {
$link2 .= '<a href="'.$myurl2.'&amp;sort=date'.$courselink.'">'.$orderdate.'</a>';
}
// Prepare output
$fclass = '';
// make the tags larger when there are not so many
if (strlen($tags) < 10000) { $fclass = 'coursetag_more_large'; }
$outstr = '
<div class="coursetag_more_title">
<div style="padding-bottom:5px">'.$welcome.
helpbutton('usingtags', 'using tags', $tagslang, TRUE, FALSE, '', TRUE).'
</div>
<div class="coursetag_more_link">'.$link1.'</div>
<div class="coursetag_more_link">'.$link2.'</div>
</div>
<div class="coursetag_more_tags '.$fclass.'">'.
$tags.'
</div>';
echo $outstr;
print_footer();
?>

698
tag/coursetagslib.php Normal file
View File

@ -0,0 +1,698 @@
<?php
/**
* coursetagslib.php
* @author j.beedell@open.ac.uk July07
*/
require_once $CFG->dirroot.'/tag/lib.php';
/**
* Returns an ordered array of tags associated with visible courses
* (boosted replacement of get_all_tags() allowing association with user and tagtype).
*
* @uses $CFG
* @param int $courseid, a 0 will return all distinct tags for visible courses
* @param int $userid optional the user id, a default of 0 will return all users tags for the course
* @param string $tagtype optional 'official' or 'default', empty returns both tag types
* @param int $numtags optional number of tags to display, default of 80 is set in the block, 0 returns all
* @param string $sort optional selected sorting, default is alpha sort (name) also timemodified or popularity
* @return array
*/
function coursetag_get_tags($courseid, $userid=0, $tagtype='', $numtags=0, $sort='name') {
global $CFG, $DB;
// get visible course ids
$courselist = array();
if ($courseid === 0) {
if ($courses = $DB->get_records_select('course', 'visible=1 AND category>0', null, '', 'id')) {
foreach ($courses as $key => $value) {
$courselist[] = $key;
}
}
}
// get tags from the db ordered by highest count first
$params = array();
$sql = "SELECT id as tkey, name, id, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance}
WHERE itemtype = 'course' ";
if ($courseid > 0) {
$sql .= " AND itemid = :courseid ";
$params['courseid'] = $courseid;
} else {
if (!empty($courselist)) {
list($usql, $uparams) = $DB->get_in_or_equal($courselist, SQL_PARAMS_NAMED);
$sql .= "AND itemid $usql ";
$params = $params + $uparams;
}
}
if ($userid > 0) {
$sql .= " AND tiuserid = :userid ";
$params['userid'] = $userid;
}
$sql .= " GROUP BY tagid) f
WHERE t.id = f.tagid ";
if ($tagtype != '') {
$sql .= "AND tagtype = :tagtype ";
$params['tagtype'] = $tagtype;
}
$sql .= "ORDER BY count DESC, name ASC";
// limit the number of tags for output
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql, $params);
} else {
$tags = $DB->get_records_sql($sql, $params, 0, $numtags);
}
// prepare the return
$return = array();
if ($tags) {
// sort the tag display order
if ($sort != 'popularity') {
$CFG->tagsort = $sort;
usort($tags, "coursetag_sort");
}
// avoid print_tag_cloud()'s ksort upsetting ordering by setting the key here
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Returns an ordered array of tags
* (replaces popular_tags_count() allowing sorting).
*
* @uses $CFG
* @param string $sort optional selected sorting, default is alpha sort (name) also timemodified or popularity
* @param int $numtags optional number of tags to display, default of 20 is set in the block, 0 returns all
* @return array
*/
function coursetag_get_all_tags($sort='name', $numtags=0) {
global $CFG, $DB;
// note that this selects all tags except for courses that are not visible
$sql = "SELECT id, name, id, tagtype, rawname, f.timemodified, flag, count
FROM {tag} t,
(SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count
FROM {tag_instance} WHERE tagid NOT IN
(SELECT tagid FROM {tag_instance} ti, {course} c
WHERE c.visible = 0
AND ti.itemtype = 'course'
AND ti.itemid = c.id)
GROUP BY tagid) f
WHERE t.id = f.tagid
ORDER BY count DESC, name ASC";
if ($numtags == 0) {
$tags = $DB->get_records_sql($sql);
} else {
$tags = $DB->get_records_sql($sql, null, 0, $numtags);
}
$return = array();
if ($tags) {
if ($sort != 'popularity') {
$CFG->tagsort = $sort;
usort($tags, "coursetag_sort");
}
foreach ($tags as $value) {
$return[] = $value;
}
}
return $return;
}
/**
* Callback function for coursetag_get_tags() and coursetag_get_all_tags() only
* @uses $CFG
*/
function coursetag_sort($a, $b) {
// originally from block_blog_tags
global $CFG;
// set up the variable $tagsort as either 'name' or 'timemodified' only, 'popularity' does not need sorting
if (empty($CFG->tagsort)) {
$tagsort = 'name';
} else {
$tagsort = $CFG->tagsort;
}
if (is_numeric($a->$tagsort)) {
return ($a->$tagsort == $b->$tagsort) ? 0 : ($a->$tagsort > $b->$tagsort) ? 1 : -1;
} elseif (is_string($a->$tagsort)) {
return strcmp($a->$tagsort, $b->$tagsort);
} else {
return 0;
}
}
/**
* Prints a tag cloud
*
* @param array $tagcloud array of tag objects (fields: id, name, rawname, count and flag)
* @param int $max_size maximum text size, in percentage
* @param int $min_size minimum text size, in percentage
* @param $return if true return html string
*/
function coursetag_print_cloud($tagcloud, $return=false, $max_size=180, $min_size=80) {
global $CFG;
if (empty($tagcloud)) {
return;
}
ksort($tagcloud);
$count = array();
foreach ($tagcloud as $key => $value) {
if(!empty($value->count)) {
$count[$key] = log10($value->count);
} else {
$count[$key] = 0;
}
}
$max = max($count);
$min = min($count);
$spread = $max - $min;
if (0 == $spread) { // we don't want to divide by zero
$spread = 1;
}
$step = ($max_size - $min_size)/($spread);
$systemcontext = get_context_instance(CONTEXT_SYSTEM);
$can_manage_tags = has_capability('moodle/tag:manage', $systemcontext);
//prints the tag cloud
$output = '<ul class="tag-cloud inline-list">';
foreach ($tagcloud as $key => $tag) {
$size = $min_size + ((log10($tag->count) - $min) * $step);
$size = ceil($size);
$style = 'style="font-size: '.$size.'%"';
if ($tag->count > 1) {
$title = 'title="'.s(get_string('thingstaggedwith','tag', $tag)).'"';
} else {
$title = 'title="'.s(get_string('thingtaggedwith','tag', $tag)).'"';
}
$href = 'href="'.$CFG->wwwroot.'/tag/index.php?id='.$tag->id.'"';
//highlight tags that have been flagged as inappropriate for those who can manage them
$tagname = tag_display_name($tag);
if ($tag->flag > 0 && $can_manage_tags) {
$tagname = '<span class="flagged-tag">' . tag_display_name($tag) . '</span>';
}
$tag_link = '<li><a '.$href.' '.$title.' '. $style .'>'.$tagname.'</a></li> ';
$output .= $tag_link;
}
$output .= '</ul>'."\n";
if ($return) {
return $output;
} else {
echo $output;
}
}
/**
* Returns javascript for use in tags block and supporting pages
* @param string $coursetagdivs comma separated divs ids
* @uses $CFG
*/
function coursetag_get_jscript($coursetagdivs = '') {
global $CFG, $DB;
$tabscript = '';
if ($coursetagdivs) {
$tabscript = 'var coursetagdivs = new Array('.$coursetagdivs.');';
}
$coursetags = $DB->get_records('tag', null, 'name ASC', 'name, id');
$a = 0;
$coursetagscript = '';
if (!empty($coursetags)) {
foreach ($coursetags as $key => $value) {
$coursetagscript .= "coursetag_tags[$a] = \"".addslashes_js($key)."\"; ";
$a++;
}
}
$jserror1 = get_string('jserror1', 'block_tags');
$jserror2 = get_string('jserror2', 'block_tags');
$inputscript = <<<EOT
function ctags_checkinput(val) {
var len = val.length;
if (len < 2 || len > 50) {
alert("$jserror1");
return false;
//can't check this - unterminated string error } else if (val.indexOf("\\") > 0) {
} else if (val.indexOf("<") > 0) {
alert("$jserror2");
return false;
} else if (val.indexOf(">") > 0) {
alert("$jserror2");
return false;
} else {
return true;
}
}
EOT;
$str = '
<script type="text/javascript">
//<![CDATA[
'.$tabscript.'
var coursetag_tags = new Array();
'.$coursetagscript.'
'.$inputscript.'
//]]>
</script>
<script src="'.$CFG->wwwroot.'/blocks/tags/coursetags.js" type="text/javascript"></script>';
return $str;
}
/**
* Returns javascript to create the links in the tag block footer.
*/
function coursetag_get_jscript_links($coursetagslinks) {
$links = '';
if (!empty($coursetagslinks)) {
$links .= '<hr />';
foreach ($coursetagslinks as $a) {
$links .= '<a href="" title="'.$a['title'].'"
onclick="return ctags_show_div(\''.$a['onclick'].'\')">'.$a['text'].'</a> |';
}
$links = addslashes_js(rtrim($links, '|'));
}
$str = '
<script type="text/javascript">
//<![CDATA[
var element = document.getElementById("coursetagslinks");
element.innerHTML = "'.$links.'";
//]]>
</script>';
return $str;
}
/**
* Returns all tags created by a user for a course
*
* @uses $CFG
* @param int $courseid
* @param int $userid
*/
function coursetag_get_records($courseid, $userid) {
global $CFG, $DB;
$sql = "SELECT t.id, name, rawname
FROM {tag} t, {tag_instance} ti
WHERE t.id = ti.tagid
AND ti.tiuserid = :userid
AND ti.itemid = :courseid
ORDER BY name ASC";
return $DB->get_records_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid));
}
/**
* 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)) {
//tag_set_add('course', $courseid, $tags, $userid);
//if ($tagtype == 'official') {
// $tags_ids = tag_get_id($tags);
//}
foreach($tags as $tag) {
$tag = trim($tag);
if (strlen($tag) > 0) {
tag_set_add('course', $courseid, $tag, $userid);
if ($myurl) {
$url = $myurl.'?query='.urlencode($tag);
}
if ($tagtype == 'default' and $myurl != '') {
// log the tagging request - note only for user added tags
add_to_log($courseid, 'coursetags', 'add', $url, 'Course tagged');
}
if ($tagtype == 'official') {
tag_type_set(tag_get_id($tag), $tagtype);
}
}
}
}
}
/**
* Deletes a personal tag for a user for a course.
*
* @uses $CFG
* @param int $tagid
* @param int $userid
* @param int $courseid
*/
function coursetag_delete_keyword($tagid, $userid, $courseid) {
global $CFG, $DB;
$sql = "SELECT COUNT(*)
FROM {tag_instance}
WHERE tagid = $tagid
AND tiuserid = $userid
AND itemtype = 'course'
AND itemid = $courseid";
if ($DB->count_records_sql($sql) == 1) {
$sql = "tagid = $tagid
AND tiuserid = $userid
AND itemtype = 'course'
AND itemid = $courseid";
$DB->delete_records_select('tag_instance', $sql);
// if there are no other instances of the tag then consider deleting the tag as well
if (!$DB->record_exists('tag_instance', array('tagid' => $tagid))) {
// if the tag is a personal tag then delete it - don't do official tags
if ($DB->record_exists('tag', array('id' => $tagid, 'tagtype' => 'default'))) {
$DB->delete_records('tag', array('id' => $tagid, 'tagtype' => 'default'));
}
}
} else {
print_error("errordeleting", 'tag', '', $tagid);
}
}
/**
* Get courses tagged with a tag
*
* @param int $tagid
* @return array of course objects
*/
function coursetag_get_tagged_courses($tagid) {
global $DB;
$courses = array();
if ($crs = $DB->get_records_select('tag_instance', "tagid=:tagid AND itemtype='course'", array('tagid'=>$tagid))) {
foreach ($crs as $c) {
//this capability check was introduced to stop display of courses that a student could not
//view, but arguably it is best that when clicking on a tag, the tagged course summary should
//be seen and then if the student clicks on that they will be given the opportunity to join
//note courses not visible should not have their tagid sent to this function
//if (has_capability('moodle/course:view', get_context_instance(CONTEXT_COURSE, $c->itemid))) {
$course = $DB->get_record('course', array('id'=>$c->itemid));
$courses[$c->itemid] = $course;
//}
}
}
return $courses;
}
/**
* Course tagging function used only during the deletion of a
* course (called by lib/moodlelib.php) to clean up associated tags
*
* @param $courseid
* @param $showfeedback
*/
function coursetag_delete_course_tags($courseid, $showfeedback=false) {
global $DB;
if ($tags = $DB->get_records_select('tag_instance', "itemtype='course' AND itemid=:courseid", array('courseid'=>$courseid))) {
foreach ($tags as $tag) {
//delete the course tag instance record
$DB->delete_records('tag_instance', array('tagid'=>$tag->tagid, 'itemtype'=>'course', 'itemid'=> $courseid));
// delete tag if there are no other tag_instance entries now
if (!($DB->record_exists('tag_instance', array('tagid'=>$tag->tagid)))) {
$DB->delete_records('tag', array('id'=>$tag->tagid));
}
}
}
if ($showfeedback) {
notify(get_string('deletedcoursetags', 'tag'));
}
}
/**
* Function called by cron to create/update users rss feeds
*
* @uses $CFG
* @return true
*
* Function removed.
* rsslib.php needs updating to accept Dublin Core tags (dc/cc) input before this can work.
*/
/*
function coursetag_rss_feeds() {
global $CFG, $DB;
require_once($CFG->dirroot.'/lib/dmllib.php');
require_once($CFG->dirroot.'/lib/rsslib.php');
$status = true;
mtrace(' Preparing to update all user unit tags RSS feeds');
if (empty($CFG->enablerssfeeds)) {
mtrace(' RSS DISABLED (admin variables - enablerssfeeds)');
} else {
// Load all the categories for use later on
$categories = $DB->get_records('course_categories');
// get list of users who have tagged a unit
$sql = "
SELECT DISTINCT u.id as userid, u.username, u.firstname, u.lastname, u.email
FROM {user} u, {course} c, {tag_instance} cti, {tag} t
WHERE c.id = cti.itemid
AND u.id = cti.tiuserid
AND t.id = cti.tagid
AND t.tagtype = 'personal'
AND u.confirmed = 1
AND u.deleted = 0
ORDER BY userid";
if ($users = $DB->get_records_sql($sql)) {
$items = array(); //contains rss data items for each user
foreach ($users as $user) {
// loop through each user, getting the data (tags for courses)
$sql = "
SELECT cti.id, c.id as courseid, c.fullname, c.shortname, c.category, t.rawname, cti.timemodified
FROM {course} c, {tag_instance} cti, {tag} t
WHERE c.id = cti.itemid
AND cti.tiuserid = :userid{$user->userid}
AND cti.tagid = t.id
AND t.tagtype = 'personal'
ORDER BY courseid";
if ($usertags = $DB->get_records_sql($sql, array('userid' => $user->userid))) {
$latest_date = 0; //latest date any tag was created by a user
$c = 0; //course identifier
foreach ($usertags as $usertag) {
if ($usertag->courseid != $c) {
$c = $usertag->courseid;
$items[$c] = new stdClass();
$items[$c]->title = $usertag->fullname . '(' . $usertag->shortname . ')';
$items[$c]->link = $CFG->wwwroot . '/course/view.php?name=' . $usertag->shortname;
$items[$c]->description = ''; //needs to be blank
$items[$c]->category = $categories[$usertag->category]->name;
$items[$c]->subject[] = $usertag->rawname;
$items[$c]->pubdate = $usertag->timemodified;
$items[$c]->tag = true;
} else {
$items[$c]->subject[] .= $usertag->rawname;
}
// Check and set the latest modified date.
$latest_date = $usertag->timemodified > $latest_date ? $usertag->timemodified : $latest_date;
}
// Setup some vars for use while creating the file
$path = $CFG->dataroot.'/1/usertagsrss/'.$user->userid;
$file_name = 'user_unit_tags_rss.xml';
$title = get_string('rsstitle', 'tag', ucwords(strtolower($user->firstname.' '.$user->lastname)));
$desc = get_string('rssdesc', 'tag');
// check that the path exists
if (!file_exists($path)) {
mtrace(' Creating folder '.$path);
check_dir_exists($path, TRUE, TRUE);
}
// create or update the feed for the user
// this functionality can be copied into seperate lib as in next two lines
//require_once($CFG->dirroot.'/local/ocilib.php');
//oci_create_rss_feed( $path, $file_name, $latest_date, $items, $title, $desc, $dc=true, $cc=false);
// Set path to RSS file
$full_path = "$save_path/$file_name";
mtrace(" Preparing to update RSS feed for $file_name");
// First let's make sure there is work to do by checking the time the file was last modified,
// if a course was update after the file was mofified
if (file_exists($full_path)) {
if ($lastmodified = filemtime($full_path)) {
mtrace(" XML File $file_name Created on ".date( "D, j M Y G:i:s T", $lastmodified ));
mtrace(' Lastest course modification on '.date( "D, j M Y G:i:s T", $latest_date ));
if ($latest_date > $lastmodified) {
mtrace(" XML File $file_name needs updating");
$changes = true;
} else {
mtrace(" XML File $file_name doesn't need updating");
$changes = false;
}
}
} else {
mtrace(" XML File $file_name needs updating");
$changes = true;
}
if ($changes) {
// Now we know something has changed, write the new file
if (!empty($items)) {
// First set rss feeds common headers
$header = rss_standard_header(strip_tags(format_string($title,true)),
$CFG->wwwroot,
$desc,
true, true);
// Now all the rss items
if (!empty($header)) {
$articles = rss_add_items($items,$dc,$cc);
}
// Now all rss feeds common footers
if (!empty($header) && !empty($articles)) {
$footer = rss_standard_footer();
}
// Now, if everything is ok, concatenate it
if (!empty($header) && !empty($articles) && !empty($footer)) {
$result = $header.$articles.$footer;
} else {
$result = false;
}
} else {
$result = false;
}
// Save the XML contents to file
if (!empty($result)) {
$rss_file = fopen($full_path, "w");
if ($rss_file) {
$status = fwrite ($rss_file, $result);
fclose($rss_file);
} else {
$status = false;
}
}
// Output result
if (empty($result)) {
// There was nothing to put into the XML file. Delete it!
if( is_file($full_path) ) {
mtrace(" There were no items for XML File $file_name. Deleting XML File");
unlink($full_path);
mtrace(" $full_path -> (deleted)");
} else {
mtrace(" There were no items for the XML File $file_name and no file to delete. Ignore.");
}
} else {
if (!empty($status)) {
mtrace(" $full_path -> OK");
} else {
mtrace(" $full_path -> FAILED");
}
}
}
//end of oci_create_rss_feed()
}
}
}
}
return $status;
}
*/
/**
* Get official keywords for the <meta name="keywords"> in header.html
* use: echo '<meta name="keywords" content="'.coursetag_get_official_keywords($COURSE->id).'"/>';
* @uses $CFG
* @param int $courseid
* @return string
*
* Function removed but fully working
* This function is potentially useful to anyone wanting to improve search results for course pages.
* The idea is to add official tags (not personal tags to prevent their deletion) to all
* courses (facility not added yet) which will be automatically added to the page header to boost
* search engine specificity/ratings.
*/
/*
function coursetag_get_official_keywords($courseid, $asarray=false) {
global $CFG;
$returnstr = '';
$sql = "SELECT t.id, name, rawname
FROM {tag} t, {tag_instance} ti
WHERE ti.itemid = :courseid
AND ti.itemtype = 'course'
AND t.tagtype = 'official'
AND ti.tagid = t.id
ORDER BY name ASC";
if ($tags = $DB->get_records_sql($sql, array('courseid' => $courseid))) {
if ($asarray) {
return $tags;
}
foreach ($tags as $tag) {
if( empty($CFG->keeptagnamecase) ) {
$textlib = textlib_get_instance();
$name = $textlib->strtotitle($tag->name);
} else {
$name = $tag->rawname;
}
$returnstr .= $name.', ';
}
$returnstr = rtrim($returnstr, ', ');
}
return $returnstr;
}
*/
?>

View File

@ -90,7 +90,7 @@ if ($tagnew = $tagform->get_data()) {
if (has_capability('moodle/tag:manage', $systemcontext)) {
// rename tag
if(!tag_rename($tag->id, $tagnew->rawname)) {
error('Error updating tag record');
print_error('errorupdatingrecord', 'tag');
}
}

View File

@ -14,7 +14,7 @@ if (empty($CFG->usetags)) {
}
$tagid = optional_param('id', 0, PARAM_INT); // tag id
$tagname = optional_param('tag', '', PARAM_TAG); // tag
$tagname = optional_param('tag', '', PARAM_TAG); // tag
$edit = optional_param('edit', -1, PARAM_BOOL);
$userpage = optional_param('userpage', 0, PARAM_INT); // which page to show
@ -78,8 +78,64 @@ print_heading($tagname, '', 2, 'headingblock header tag-heading');
tag_print_management_box($tag);
tag_print_description_box($tag);
$usercount = tag_record_count('user', $tag->id);
// Display courses tagged with the tag
require_once($CFG->dirroot.'/tag/coursetagslib.php');
if ($courses = coursetag_get_tagged_courses($tag->id)) {
$totalcount = count( $courses );
print_box_start('generalbox', 'tag-blogs'); //could use an id separate from tag-blogs, but would have to copy the css style to make it look the same
$heading = get_string('tagindex_coursetitle', 'tag', $tagname) .': '. $totalcount;
print_heading($heading, '', 3);
foreach ($courses as $course) {
print_course($course);
}
print_box_end();
}
// Print up to 10 previous blogs entries
// I was not able to use get_items_tagged_with() because it automatically
// tries to join on 'blog' table, since the itemtype is 'blog'. However blogs
// uses the post table so this would not really work. - Yu 29/8/07
if (has_capability('moodle/blog:view', $systemcontext)) { // You have to see blogs obviously
$count = 10;
if ($blogs = blog_fetch_entries('', $count, 0, 'site', '', $tag->id)) {
print_box_start('generalbox', 'tag-blogs');
$heading = get_string('relatedblogs', 'tag', $tagname);
print_heading($heading, '', 3);
echo '<ul id="tagblogentries">';
foreach ($blogs as $blog) {
if ($blog->publishstate == 'draft') {
$class = 'class="dimmed"';
} else {
$class = '';
}
echo '<li '.$class.'>';
echo '<a '.$class.' href="'.$CFG->wwwroot.'/blog/index.php?postid='.$blog->id.'">';
echo format_string($blog->subject);
echo '</a>';
echo ' - ';
echo '<a '.$class.' href="'.$CFG->wwwroot.'/user/view.php?id='.$blog->userid.'">';
echo fullname($blog);
echo '</a>';
echo ', '. userdate($blog->lastmodified);
echo '</li>';
}
echo '</ul>';
echo '<p class="moreblogs"><a href="'.$CFG->wwwroot.'/blog/index.php?filtertype=site&filterselect=0&tagid='.$tag->id.'">'.get_string('seeallblogs', 'tag', $tagname).'</a></p>';
print_box_end();
}
}
$usercount = tag_record_count('user', $tag->id);
if ($usercount > 0) {
//user table box
@ -95,49 +151,8 @@ if ($usercount > 0) {
print_box_end();
}
// Print last 10 blogs
// I was not able to use get_items_tagged_with() because it automatically
// tries to join on 'blog' table, since the itemtype is 'blog'. However blogs
// uses the post table so this would not really work. - Yu 29/8/07
if (has_capability('moodle/blog:view', $systemcontext)) { // You have to see blogs obviously
if ($blogs = blog_fetch_entries('', 10, 0, 'site', '', $tag->id)) {
print_box_start('generalbox', 'tag-blogs');
print_heading(get_string('relatedblogs', 'tag'), '', 3);
echo '<ul id="tagblogentries">';
foreach ($blogs as $blog) {
if ($blog->publishstate == 'draft') {
$class = 'class="dimmed"';
} else {
$class = '';
}
echo '<li '.$class.'>';
echo '<a '.$class.' href="'.$CFG->wwwroot.'/blog/index.php?postid='.$blog->id.'">';
echo format_string($blog->subject);
echo '</a>';
echo ' - ';
echo '<a '.$class.' href="'.$CFG->wwwroot.'/user/view.php?id='.$blog->userid.'">';
echo fullname($blog);
echo '</a>';
echo ', '. userdate($blog->lastmodified);
echo '</li>';
}
echo '</ul>';
echo '<p class="moreblogs"><a href="'.$CFG->wwwroot.'/blog/index.php?filtertype=site&filterselect=0&tagid='.$tag->id.'">'.get_string('seeallblogs', 'tag').'</a>...</p>';
print_box_end();
}
}
echo '</td>';
//----------------- right column -----------------
$blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210);
@ -151,9 +166,6 @@ if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing(
/// Finish the page
echo '</tr></table>';
$PAGE->print_footer();
?>

View File

@ -63,9 +63,10 @@ define('TAG_RELATED_CORRELATED', 2);
* @param int $record_id the id of the record to tag
* @param array $tags the array of tags to set on the record. If
* given an empty array, all tags will be removed.
* @param int $userid optional only required for course tagging
* @return void
*/
function tag_set($record_type, $record_id, $tags) {
function tag_set($record_type, $record_id, $tags, $userid = 0) {
static $in_recursion_semaphore = false; // this is to prevent loops when tagging a tag
if ( $record_type == 'tag' && !$in_recursion_semaphore) {
@ -108,7 +109,7 @@ function tag_set($record_type, $record_id, $tags) {
$tag_current_id = $new_tag[$clean_tag];
}
tag_assign($record_type, $record_id, $tag_current_id, $ordering);
tag_assign($record_type, $record_id, $tag_current_id, $ordering, $userid);
// if we are tagging a tag (adding a manually-assigned related tag), we
// need to create the opposite relationship as well.
@ -127,17 +128,18 @@ function tag_set($record_type, $record_id, $tags) {
* 'user' for users, etc.
* @param int $record_id the id of the record to tag
* @param string $tag the tag to add
* @param int $userid optional only required for course tagging
* @return void
*/
function tag_set_add($record_type, $record_id, $tag) {
function tag_set_add($record_type, $record_id, $tag, $userid = 0) {
$new_tags = array();
foreach( tag_get_tags($record_type, $record_id) as $current_tag ) {
foreach( tag_get_tags($record_type, $record_id, NULL, $userid) as $current_tag ) {
$new_tags[] = $current_tag->rawname;
}
$new_tags[] = $tag;
return tag_set($record_type, $record_id, $new_tags);
return tag_set($record_type, $record_id, $new_tags, $userid);
}
/**
@ -236,9 +238,10 @@ function tag_get($field, $value, $returnfields='id, name, rawname') {
* @param int $record_id the record id for which we want to get the tags
* @param string $type the tag type (either 'default' or 'official'). By default,
* all tags are returned.
* @param int $userid optional only required for course tagging
* @return array the array of tags
*/
function tag_get_tags($record_type, $record_id, $type=null) {
function tag_get_tags($record_type, $record_id, $type=null, $userid=0) {
global $CFG, $DB;
$params = array();
@ -250,9 +253,15 @@ function tag_get_tags($record_type, $record_id, $type=null) {
$sql_type = '';
}
$u = null;
if ($userid) {
$u = "AND ti.tiuserid = :userid ";
$params['userid'] = $userid;
}
$sql = "SELECT tg.id, tg.tagtype, tg.name, tg.rawname, tg.flag, ti.ordering
FROM {tag_instance} ti JOIN {tag} tg ON tg.id = ti.tagid
WHERE ti.itemtype = :recordtype AND ti.itemid = :recordid $sql_type
WHERE ti.itemtype = :recordtype AND ti.itemid = :recordid $u $sql_type
ORDER BY ti.ordering ASC";
$params['recordtype'] = $record_type;
$params['recordid'] = $record_id;
@ -662,12 +671,13 @@ function tag_add($tags, $type="default") {
* @param int $record_id the id of the record that will be tagged
* @param string $tagid the tag id to set on the record.
* @param int $ordering the order of the instance for this record
* @param int $userid optional only required for course tagging
* @return bool true on success, false otherwise
*/
function tag_assign($record_type, $record_id, $tagid, $ordering) {
function tag_assign($record_type, $record_id, $tagid, $ordering, $userid = 0) {
global $DB;
if ( $tag_instance_object = $DB->get_record('tag_instance', array('tagid'=>$tagid, 'itemtype'=>$record_type, 'itemid'=>$record_id), 'id')) {
if ( $tag_instance_object = $DB->get_record('tag_instance', array('tagid'=>$tagid, 'itemtype'=>$record_type, 'itemid'=>$record_id, 'tiuserid'=>$userid), 'id')) {
$tag_instance_object->ordering = $ordering;
$tag_instance_object->timemodified = time();
return $DB->update_record('tag_instance', $tag_instance_object);
@ -678,6 +688,7 @@ function tag_assign($record_type, $record_id, $tagid, $ordering) {
$tag_instance_object->itemtype = $record_type;
$tag_instance_object->ordering = $ordering;
$tag_instance_object->timemodified = time();
$tag_instance_object->tiuserid = $userid;
return $DB->insert_record('tag_instance', $tag_instance_object);
}
}

View File

@ -6,7 +6,7 @@
// This is compared against the values stored in the database to determine
// whether upgrades should be performed (see lib/db/*.php)
$version = 2008051203; // YYYYMMDD = date of the last version bump
$version = 2008063001; // YYYYMMDD = date of the last version bump
// XX = daily increments
$release = '2.0 dev (Build: 20080630)'; // Human-friendly version name