Index: version.php =================================================================== RCS file: /cvsroot/moodle/moodle/version.php,v retrieving revision 1.685 diff -u -F ^f -w -b -B -a -u -r1.685 version.php --- version.php 18 Jun 2008 01:36:39 -0000 1.685 +++ version.php 19 Jun 2008 10:04:42 -0000 @@ -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 = 2008061901; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20080618)'; // Human-friendly version name Index: blocks/tags/block_tags.php =================================================================== RCS file: /cvsroot/moodle/moodle/blocks/tags/block_tags.php,v retrieving revision 1.8 diff -u -F ^f -w -b -B -a -u -r1.8 block_tags.php --- blocks/tags/block_tags.php 3 Mar 2008 11:43:34 -0000 1.8 +++ blocks/tags/block_tags.php 19 Jun 2008 10:04:43 -0000 @@ -4,6 +4,10 @@ function init() { $this->version = 2007101509; $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 @@ } function has_config() { - return false; + return true; } function applicable_formats() { @@ -61,8 +65,256 @@ require_once($CFG->dirroot.'/tag/lib.php'); + 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; + $isadmin = has_capability('moodle/site:doanything', $sitecontext); + $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 = ' +
'. + get_string("alltags", $tagslang). + '
'.$alltags.'
+ +
'; + $coursetagdivs .= '"f_alltags", '; + } + if ($mytags) { + if ($mymoodlepage) { + $display = $displayblock; + } else { + $display = $displaynone; + } + $mytagscontent = ' +
'; + /*if ($rssfeed) { // - temporarily removed + $mytagscontent .= link_to_popup_window( + $rssfeed, $name='popup', + 'User Unit Tags RSS My Unit Tags RSS', + $height=600, $width=800, + $title='My Unit Tags RSS', $options='menubar=1,scrollbars,resizable', $return=true).'
'; + }*/ + $mytagscontent .= + get_string('mytags', $tagslang). + '
'.$mytags.'
+ +
'; + $coursetagdivs .= '"f_mytags", '; + } + if ($officialtags) { + if ($mytags or $alltags) { + $display = $displaynone; + } else { + $display = $displayblock; + } + $officialtagscontent = ' +
'. + get_string('officialtags', $tagslang). + '
'.$officialtags.'
+ +
'; + $coursetagdivs .= '"f_officialtags", '; + } + if ($coursetags) { + if ($coursepage) { + $display = $displayblock; + } else { + $display = $displaynone; + } + $coursetagscontent = ' +
'. + get_string('coursetags', $tagslang). + '
'.$coursetags.'
+ +
'; + $coursetagdivs .= '"f_coursetags", '; + } + if ($commtags) { + $commtagscontent = ' +
'. + get_string('communitytags', $tagslang). + '
'.$commtags.'
+ +
'; + $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 .= << +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+ + enter + +
+
+
+ + $coursetaghelpbutton +
+
+
+EOT; + // add the edit link + $this->content->footer .= ' +
+ '.get_string('edittags', $tagslang).' +
'; + } + + // 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 .= '
'; + } + if ($mytags) { + $this->content->footer .= ' + + '.get_string('mytags2', $tagslang).' |'; + } + if ($alltags and ($mytags or $officialtags or $commtags or $coursetags)) { + $this->content->footer .= ' + + '.get_string('alltags1', $tagslang).' |'; + } + if ($officialtags) { + $this->content->footer .= ' + + '.get_string('officialtags1', $tagslang).' |'; + } + if ($commtags) { + $this->content->footer .= ' + + '.get_string('communitytags1', $tagslang).' |'; + } + if ($coursetags) { + $this->content->footer .= ' + + '.get_string('coursetags1', $tagslang).' |'; + } + $this->content->footer = rtrim($this->content->footer, '|'); + } else { + //if not logged in + $this->content->footer = '
'.get_string('please', $tagslang).' + '.get_string('login', $tagslang).' + '.get_string('tagunits', $tagslang); + } + } + // end of show course tags section + return $this->content; } @@ -81,6 +333,21 @@ 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; } + } + */ +} ?> Index: blocks/tags/coursetags.js =================================================================== RCS file: blocks/tags/coursetags.js diff -N blocks/tags/coursetags.js --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/coursetags.js 19 Jun 2008 10:04:43 -0000 @@ -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"; +} Index: blocks/tags/settings.php =================================================================== RCS file: blocks/tags/settings.php diff -N blocks/tags/settings.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/settings.php 19 Jun 2008 10:04:43 -0000 @@ -0,0 +1,6 @@ +add(new admin_setting_configcheckbox('block_tags_showcoursetags', get_string('showcoursetags', 'block_tags'), + get_string('showcoursetagsdef', 'block_tags'), 0)); + +?> Index: blocks/tags/styles.php =================================================================== RCS file: blocks/tags/styles.php diff -N blocks/tags/styles.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/styles.php 19 Jun 2008 10:04:43 -0000 @@ -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%; +} Index: course/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/course/lib.php,v retrieving revision 1.604 diff -u -F ^f -w -b -B -a -u -r1.604 lib.php --- course/lib.php 16 Jun 2008 14:25:53 -0000 1.604 +++ course/lib.php 19 Jun 2008 10:04:44 -0000 @@ -40,6 +40,9 @@ function make_log_url($module, $url) { case 'upload': return $url; break; + case 'coursetags': + return '/'.$url; + break; case 'library': case '': return '/'; Index: lang/en_utf8/block_tags.php =================================================================== RCS file: lang/en_utf8/block_tags.php diff -N lang/en_utf8/block_tags.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lang/en_utf8/block_tags.php 19 Jun 2008 10:04:44 -0000 @@ -0,0 +1,66 @@ + Index: lang/en_utf8/tag.php =================================================================== RCS file: /cvsroot/moodle/moodle/lang/en_utf8/tag.php,v retrieving revision 1.15 diff -u -F ^f -w -b -B -a -u -r1.15 tag.php --- lang/en_utf8/tag.php 29 Feb 2008 09:35:04 -0000 1.15 +++ lang/en_utf8/tag.php 19 Jun 2008 10:04:45 -0000 @@ -10,7 +10,11 @@ $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'; @@ -30,6 +34,8 @@ $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['searchresultsfor'] = 'Search results for \"$a\"'; @@ -40,9 +46,11 @@ $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['thingtaggedwith'] = '$a->count thing tagged with \"$a->name\"'; $string['thistaghasnodesc'] = 'This tag currently has no description.'; $string['timemodified'] = 'Modified'; $string['typechanged'] = 'Tag type changed'; Index: lang/en_utf8/help/block_tags/addtags.html =================================================================== RCS file: lang/en_utf8/help/block_tags/addtags.html diff -N lang/en_utf8/help/block_tags/addtags.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lang/en_utf8/help/block_tags/addtags.html 19 Jun 2008 10:04:45 -0000 @@ -0,0 +1,27 @@ +

Adding a tag for a course

+ +

Logged on users may 'tag' courses.

+ +

A tag is a shortcut or way of navigating to your favourite things.

+ +

Not only can you tag courses, but you may also tag your blogs, or even your own profile.

+ +

Clicking on a tag will take you to a page listing all the things associated with that tag. +If the tag is a popular one you will be able to see what other things other users have associated +with that tag.

+ +

You may add as many tags as you like. While it is recommended to only add one tag at a time, +more tags could be entered on one occasion by seperating the tags with a comma. +As you are adding a tag you may notice a word appearing in the background where you are typing. +If this word is what you want as your tag then you can click on the little +arrow next to the entry box to save typing the that word (and don't forget to click submit to save).

+ +

Tags must be more than one character and may be up to 50 characters long. +Please note that while extended characters are allowed (e.g. French acute +accented characters or Chinese characters), special characters will be +stripped (e.g. "',\,_,<,-,~,?"). +Also note that tags cannot be pure integers or float number (e.g. 1 or 1.11) +but number and letter combinations are fine (e.g. 1a). +Finally, commas cannot be used in tag names, as these are separators between tags entered.

+ +

Don't forget to click the 'Submit' button below to save your new tag.

Index: lang/en_utf8/help/block_tags/deletetags.html =================================================================== RCS file: lang/en_utf8/help/block_tags/deletetags.html diff -N lang/en_utf8/help/block_tags/deletetags.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lang/en_utf8/help/block_tags/deletetags.html 19 Jun 2008 10:04:45 -0000 @@ -0,0 +1,9 @@ +

Deleting a tag for a course

+ +

You will only be able to delete a tag entry that you have previously created. +This allows you to tidy up those mis-spelled, or out-dated tags. Please note that +deletion will only delete the tag if no other user has tagged something else with it, +otherwise deletion will just delete your association of that tag for the course.

+ +

Deleting is done by highlighting the tag you wish to delete under 'Select...', +then clicking the 'Submit' button below.

Index: lang/en_utf8/help/block_tags/usingtags.html =================================================================== RCS file: lang/en_utf8/help/block_tags/usingtags.html diff -N lang/en_utf8/help/block_tags/usingtags.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ lang/en_utf8/help/block_tags/usingtags.html 19 Jun 2008 10:04:45 -0000 @@ -0,0 +1,21 @@ +

Using course tagging

+ +

A note about the tag count. Hovering the mouse over a tag will reveal a tag count message +like '2 things tagged with ...'. +This count (number) will vary depending on where the tag is being displayed at the time.

+ +

The 'More tags' page (and the tags block) can display several different selections of tags +- for instance 'all tags' or 'my tags'. +The count displayed for a tag under 'all tags' may be different to the count for the same tag +displayed under the 'my tags' or one of the other selections. +This is because when 'all tags' is showing, all tags for courses, blogs and user profiles +are displayed and counted. +Where as when 'my tags' is showing, only your own tags for courses you have tagged +are displayed and counted. +So the count could be quite different for one tag under different sections.

+ +

Of course the size of the tag is also a clue to the count. The bigger the font size for the tag the +more popular the tag is.

+ +

In fact it is easy to re-order the tags displayed by popularity, using the link provided. +And the tags may be re-ordered alphabetically or in date of creation order as well. Try it.

Index: lib/moodlelib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/moodlelib.php,v retrieving revision 1.1060 diff -u -F ^f -w -b -B -a -u -r1.1060 moodlelib.php --- lib/moodlelib.php 18 Jun 2008 05:58:06 -0000 1.1060 +++ lib/moodlelib.php 19 Jun 2008 10:04:48 -0000 @@ -3624,6 +3623,10 @@ function remove_course_contents($coursei 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; } Index: lib/db/install.xml =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v retrieving revision 1.151 diff -u -F ^f -w -b -B -a -u -r1.151 install.xml --- lib/db/install.xml 12 Jun 2008 02:09:26 -0000 1.151 +++ lib/db/install.xml 19 Jun 2008 10:04:50 -0000 @@ -1503,8 +1503,9 @@ - - + + + @@ -1512,7 +1513,7 @@ - + Index: lib/db/upgrade.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v retrieving revision 1.206 diff -u -F ^f -w -b -B -a -u -r1.206 upgrade.php --- lib/db/upgrade.php 16 Jun 2008 00:16:00 -0000 1.206 +++ lib/db/upgrade.php 19 Jun 2008 10:04:51 -0000 @@ -135,6 +135,29 @@ function xmldb_main_upgrade($oldversion= upgrade_main_savepoint($result, 2008051203); } + if ($result && $oldversion < 2008061901) { + // 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'); + $result = $result && $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->drop_index($table, $index); //should not be required, but better safe than sorry + $result = $result && $dbman->add_index($table, $index); + + /// Main savepoint reached + upgrade_main_savepoint($result, 2008061901); + } + + /* * TODO: * drop adodb_logsql table and create a new general sql log table Index: pix/t/arrow_left.gif =================================================================== RCS file: pix/t/arrow_left.gif diff -N pix/t/arrow_left.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ pix/t/arrow_left.gif 19 Jun 2008 10:04:53 -0000 @@ -0,0 +1,5 @@ +GIF89a + +fffݵ!, + +M$/KB'#UFp; \ No newline at end of file Index: tag/coursetags_add.php =================================================================== RCS file: tag/coursetags_add.php diff -N tag/coursetags_add.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tag/coursetags_add.php 19 Jun 2008 10:04:54 -0000 @@ -0,0 +1,34 @@ +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); + +?> Index: tag/coursetags_edit.php =================================================================== RCS file: tag/coursetags_edit.php diff -N tag/coursetags_edit.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tag/coursetags_edit.php 19 Jun 2008 10:04:54 -0000 @@ -0,0 +1,177 @@ +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 = ' +
+
+ '.get_string('editmytags', $tagslang).' +
+
'; + + if ($mytags) { + $outstr .= $mytags; + } else { + $outstr .= get_string('editnopersonaltags', $tagslang); + } + + $outstr .= ' +
+
'; + 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 = ''; + $coursetabs = ''; + if ($options = coursetag_get_records($courseid, $USER->id)) { + $coursetabs = '"'; + foreach ($options as $option) { + $selectoptions .= ''; + $coursetabs .= $option->rawname . ', '; + } + $coursetabs = rtrim($coursetabs, ', '); + $coursetabs .= '"'; + } + if ($coursetabs) { + $outstr = ' +
+ '.get_string('editthiscoursetags', $tagslang, $coursetabs).' +
'; + } else { + $outstr = ' +
+ '.get_string('editnopersonaltags', $tagslang).' +
'; + } + + // 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 .= << +
+ + +
+
+
+
+ $addtagshelp$edittagthisunit +
+
+
+ +
+
+ +
+
+ + enter + +
+
+
+EOT; + if ($coursetabs) { + $deletetagshelp = helpbutton('deletetags', 'deleting tags', $tagslang, TRUE, FALSE, '', TRUE); + $editdeletemytag = get_string('editdeletemytag', $tagslang); + $outstr .= << +
+ $deletetagshelp$editdeletemytag +
+
+ +
+
+EOT1; + } + $submitstr = get_string('submit'); + $outstr .= << +
+ +
+ + +EOT2; + echo $outstr; + } + +print_footer(); +?> Index: tag/coursetags_more.php =================================================================== RCS file: tag/coursetags_more.php diff -N tag/coursetags_more.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tag/coursetags_more.php 19 Jun 2008 10:04:54 -0000 @@ -0,0 +1,187 @@ +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 = '&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 .= ''.$showalltags.''; +} else { + $link1 .= ''.$showalltags.''; +} +//if ($show == 'official') { //add back in if you start to use official course tags +// $link1 .= ' | '.$showofficialtags.''; +//} else { +// $link1 .= ' | '.$showofficialtags.''; +//} +if ($show == 'community') { + $link1 .= ' | '.$showcommtags.''; +} else { + $link1 .= ' | '.$showcommtags.''; +} +if ($loggedin) { + if ($show == 'my') { + $link1 .= ' | '.$showmytags.''; + } else { + $link1 .= ' | '.$showmytags.''; + } +} +if ($courseid) { + if ($show == 'course') { + $link1 .= ' | '.get_string('moreshowcoursetags', $tagslang, $course->fullname).''; + } else { + $link1 .= ' | '.get_string('moreshowcoursetags', $tagslang, $course->fullname).''; + } +} +if ($sort == 'alpha') { + $link2 .= ''.$orderalpha.' | '; +} else { + $link2 .= ''.$orderalpha.' | '; +} +if ($sort == 'popularity') { + $link2 .= ''.$orderpop.' | '; +} else { + $link2 .= ''.$orderpop.' | '; +} +if ($sort == 'date') { + $link2 .= ''.$orderdate.''; +} else { + $link2 .= ''.$orderdate.''; +} + +// Prepare output +$fclass = ''; +// make the tags larger when there are not so many +if (strlen($tags) < 10000) { $fclass = 'coursetag_more_large'; } +$outstr = ' +
+
'.$welcome. + helpbutton('usingtags', 'using tags', $tagslang, TRUE, FALSE, '', TRUE).' +
+ + +
+
'. + $tags.' +
'; +echo $outstr; + +print_footer(); +?> Index: tag/coursetagslib.php =================================================================== RCS file: tag/coursetagslib.php diff -N tag/coursetagslib.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ tag/coursetagslib.php 19 Jun 2008 10:04:54 -0000 @@ -0,0 +1,672 @@ +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 = '
    '; + 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 = '' . tag_display_name($tag) . ''; + } + + $tag_link = '
  • '.$tagname.'
  • '; + + $output .= $tag_link; + + } + $output .= '
'."\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 = << 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 = ' + + '; + + 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 in header.html + * use: echo ''; + * @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; +} +*/ + +?> Index: tag/edit.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/edit.php,v retrieving revision 1.25 diff -u -F ^f -w -b -B -a -u -r1.25 edit.php --- tag/edit.php 9 Jun 2008 16:53:39 -0000 1.25 +++ tag/edit.php 19 Jun 2008 10:04:54 -0000 @@ -90,7 +90,7 @@ 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'); } } Index: tag/index.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/index.php,v retrieving revision 1.28 diff -u -F ^f -w -b -B -a -u -r1.28 index.php --- tag/index.php 19 Jun 2008 10:02:10 -0000 1.28 +++ tag/index.php 19 Jun 2008 10:04:54 -0000 @@ -134,9 +134,26 @@ } } +// Display courses tagged with the tag +require_once($CFG->dirroot.'/tag/coursetagslib.php'); +if ($courses = coursetag_get_tagged_courses($tag->id)) { -echo ''; + $totalcount = count( $courses ); + $coursestitle = get_string('tagindex_coursetitle', 'tag', '"'.$tagname.'": '.$totalcount); + + 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 + + print_heading($coursestitle, '', 3); + + foreach ($courses as $course) { + print_course($course); + print_spacer(5,5); + } + print_box_end(); +} + +echo ''; //----------------- right column ----------------- Index: tag/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/lib.php,v retrieving revision 1.83 diff -u -F ^f -w -b -B -a -u -r1.83 lib.php --- tag/lib.php 19 Jun 2008 10:02:11 -0000 1.83 +++ tag/lib.php 19 Jun 2008 10:04:55 -0000 @@ -63,9 +63,10 @@ * @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_i $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_i * '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, $return * @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, $rec $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, $recor $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); } }