### Eclipse Workspace Patch 1.0 #P core Index: blocks/tags/block_tags.php =================================================================== RCS file: /cvsroot/moodle/moodle/blocks/tags/block_tags.php,v retrieving revision 1.3 diff -u -r1.3 block_tags.php --- blocks/tags/block_tags.php 16 Sep 2007 21:43:08 -0000 1.3 +++ blocks/tags/block_tags.php 10 Jan 2008 08:37:39 -0000 @@ -1,9 +1,18 @@ version = 2007082800; + $this->version = 2007120600; $this->title = get_string('blocktagstitle', 'tag'); + // the cron function goes through all users so only do daily + // remove until rsslib supports dc/cc + // $this->cron = 60*60*24; } function instance_allow_multiple() { @@ -61,7 +70,247 @@ require_once($CFG->dirroot.'/tag/lib.php'); - $this->content->text = print_tag_cloud(popular_tags_count($this->config->numberoftags), false, 170, 70, true); + if (!SHOWCOURSETAGS) { + + $this->content->text = print_tag_cloud(popular_tags_count($this->config->numberoftags), false, 170, 70, true); + + } else { + + require_once($CFG->dirroot.'/blocks/tags/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 + //$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 = print_tag_cloud(coursetag_get_all_tags($sort, $this->config->numberoftags), false, 170, 70, true); + $officialtags = print_tag_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), false, 170, 70, true); + $commtags = print_tag_cloud(coursetag_get_tags(0, 0, 'personal', $numoftags, $sort), false, 170, 70, true); + if ($loggedin) { + $mytags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal', $numoftags, $sort), false, 170, 70, true); + } + } + if ($coursepage) { + $coursetags = print_tag_cloud(coursetag_get_tags($COURSE->id, 0, '', $numoftags, $sort), false, 170, 70, true); + if (!$coursetags) $coursetags = get_string('notagsyet', $tagslang); + $courseflag = '&courseid='.$COURSE->id; + } + if ($mymoodlepage) { + $mytags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal', $numoftags, $sort), false, 170, 70, true); + $officialtags = print_tag_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), false, 170, 70, true); + $commtags = print_tag_cloud(coursetag_get_tags(0, 0, 'personal', $numoftags, $sort), false, 170, 70, true); + } + + // Prepare the divs and javascript that displays the groups of tags (and which is displayed first) + $moretags = $CFG->wwwroot.'/blocks/tags/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 + $coursetagdivs = rtrim($coursetagdivs, ', '); + + // Add the divs (containing the tags) to the block's content + $this->content->text = "
+ + "; + 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(); + $this->content->footer .= "
+
+ + + ".get_string('tagthisunit', $tagslang)." +
+
+ +
+
+ +
+
+ + + +
+
+ "; + $this->content->footer .= helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE); + $this->content->footer .= "
"; + // 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, '|'); + $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 SHOWCOURSETAGS section return $this->content; } @@ -81,6 +330,22 @@ notice(get_string('blockconfigbad'), str_replace('blockaction=', 'dummy=', qualified_me())); } } -} + + /* + * function removed unit rsslib supports dc/cc + */ + /* + function cron() { + if (SHOWCOURSETAGS) { + global $CFG; + require_once($CFG->dirroot.'/blocks/tags/coursetagslib.php'); + return coursetag_rss_feeds(); + } else { + return TRUE; + } + } + */ + +} ?> Index: tag/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/lib.php,v retrieving revision 1.46 diff -u -r1.46 lib.php --- tag/lib.php 1 Nov 2007 12:32:59 -0000 1.46 +++ tag/lib.php 10 Jan 2008 08:37:44 -0000 @@ -364,9 +364,13 @@ * @param string $item_id id of the item to be tagged * @param string $tag_names_or_ids_csv comma separated tag names (can be unormalized) or ids of existing tags * @param string $tag_type type of the tags that are beeing added (optional, default value is "default") + * + * coursetag addition + * the addition of userid here allows a tag to be associated with both an item and a user + * @param int $userid userid of creator of this tag instance or 0 */ -function tag_an_item($item_type, $item_id, $tag_names_or_ids_csv, $tag_type="default") { +function tag_an_item($item_type, $item_id, $tag_names_or_ids_csv, $tag_type="default", $userid=0) { global $CFG; //convert any tag ids passed to their corresponding tag names @@ -400,6 +404,7 @@ $tag_instance = new StdClass; $tag_instance->itemtype = $item_type; $tag_instance->itemid = $item_id; + $tag_instance->tiuserid = $userid; //create tag instances @@ -408,7 +413,9 @@ $tag_instance->tagid = $tag_id; $tag_instance->ordering = $ordering[$tag_normalized_name]; $tag_instance->timemodified = time(); - $tag_instance_exists = get_record('tag_instance', 'tagid', $tag_id, 'itemtype', $item_type, 'itemid', $item_id); + //$tag_instance_exists = get_record('tag_instance', 'tagid', $tag_id, 'itemtype', $item_type, 'itemid', $item_id); + $query = "tagid = $tag_id AND itemtype = '$item_type' AND itemid = $item_id AND tiuserid = $userid"; + $tag_instance_exists = get_record_select('tag_instance', $query); if (!$tag_instance_exists) { insert_record('tag_instance',$tag_instance); @@ -842,9 +849,10 @@ // query that counts how many times any tag appears together in items // with the tag passed as argument ($tag_id) - $query = "SELECT tb.tagid , COUNT(*) nr + $query = "SELECT tb.tagid , COUNT(*) as nr FROM {$CFG->prefix}tag_instance ta - INNER JOIN {$CFG->prefix}tag_instance tb ON ta.itemid = tb.itemid + INNER JOIN {$CFG->prefix}tag_instance tb + ON ta.itemid = tb.itemid WHERE ta.tagid = {$tag_id} GROUP BY tb.tagid ORDER BY nr DESC"; @@ -900,18 +908,17 @@ // then this tag_instance is an orphan and it will be removed. foreach ($items_types as $type) { - $query = " - {$CFG->prefix}tag_instance.id - IN - ( SELECT sq1.id - FROM - (SELECT sq2.* + $query = "{$CFG->prefix}tag_instance.id + IN ( + SELECT sq1.id + FROM ( + SELECT sq2.* FROM {$CFG->prefix}tag_instance sq2 - LEFT JOIN {$CFG->prefix}{$type->itemtype} item + LEFT JOIN {$CFG->prefix}tag item ON sq2.itemid = item.id WHERE item.id IS NULL - AND sq2.itemtype = '{$type->itemtype}') - sq1 + AND sq2.itemtype = '{$type->itemtype}' + ) sq1 ) "; delete_records_select('tag_instance', $query); @@ -1129,10 +1136,12 @@ function tag_cron(){ + mtrace('Start of tag cron - tag instance table cleanup'); tag_instance_table_cleanup(); if ($tags = get_all_tags('*')) { + mtrace(' Preparing to update correlated tags cache'); foreach ($tags as $tag){ cache_correlated_tags($tag->id); } @@ -1510,7 +1519,13 @@ $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 Index: tag/index.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/index.php,v retrieving revision 1.16 diff -u -r1.16 index.php --- tag/index.php 31 Aug 2007 05:46:33 -0000 1.16 +++ tag/index.php 10 Jan 2008 08:37:44 -0000 @@ -94,7 +94,7 @@ // Print last 10 blogs -// I was not able to use get_items_tagged_with() because it automatically +// 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 ($blogs = blog_fetch_entries('', 10, 0, 'site', '', $tag->id)) { @@ -114,7 +114,7 @@ echo ''; echo format_string($blog->subject); echo ''; - echo ' - '; + echo ' - '; echo ''; echo fullname($blog); echo ''; @@ -129,6 +129,27 @@ } +// Display courses tagged with the tag +require_once($CFG->dirroot.'/blocks/tags/coursetagslib.php'); +if ($courses = coursetag_get_tagged_courses($tag->id)) { + + $totalcount = count( $courses ); + + print_box_start('generalbox', 'tag-blogs'); + + print_heading('Units tagged with "'.$tagname.'": '.$totalcount, '', 3); + + foreach ($courses as $course) { + //echo '
'; + print_course($course); + //echo '
'; + print_spacer(5,5); + } + + print_box_end(); +} + + echo ''; Index: tag/search.php =================================================================== RCS file: /cvsroot/moodle/moodle/tag/search.php,v retrieving revision 1.5 diff -u -r1.5 search.php --- tag/search.php 28 Aug 2007 06:14:38 -0000 1.5 +++ tag/search.php 10 Jan 2008 08:37:44 -0000 @@ -22,6 +22,8 @@ $systemcontext = get_context_instance(CONTEXT_SYSTEM); if ( has_capability('moodle/tag:manage',$systemcontext) ) { $manage_link = "wwwroot}/tag/manage.php\">" . get_string('managetags', 'tag') . "" ; +} else { + $manage_link = NULL; } print_header_simple(get_string('tags', 'tag'), '', $navigation, '', '', '', $manage_link); Index: course/lib.php =================================================================== RCS file: /cvsroot/moodle/moodle/course/lib.php,v retrieving revision 1.550 diff -u -r1.550 lib.php --- course/lib.php 9 Jan 2008 10:12:31 -0000 1.550 +++ course/lib.php 10 Jan 2008 08:37:40 -0000 @@ -259,6 +259,9 @@ case 'upload': return $url; break; + case 'coursetags': + return '/'.$url; + break; case 'library': case '': return '/'; Index: lang/en_utf8/tag.php =================================================================== RCS file: /cvsroot/moodle/moodle/lang/en_utf8/tag.php,v retrieving revision 1.12 diff -u -r1.12 tag.php --- lang/en_utf8/tag.php 16 Sep 2007 20:19:20 -0000 1.12 +++ lang/en_utf8/tag.php 10 Jan 2008 08:37:40 -0000 @@ -37,6 +37,7 @@ $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: lib/db/install.xml =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v retrieving revision 1.137 diff -u -r1.137 install.xml --- lib/db/install.xml 15 Dec 2007 00:49:05 -0000 1.137 +++ lib/db/install.xml 10 Jan 2008 08:37:43 -0000 @@ -1516,8 +1516,9 @@ - - + + + @@ -1525,7 +1526,7 @@ - + Index: lib/db/upgrade.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v retrieving revision 1.172 diff -u -r1.172 upgrade.php --- lib/db/upgrade.php 23 Dec 2007 20:01:14 -0000 1.172 +++ lib/db/upgrade.php 10 Jan 2008 08:37:44 -0000 @@ -2312,7 +2312,7 @@ $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id')); /* - * Note: mysql can not create indexes on text fields larger than 333 chars! + * Note: mysql can not create indexes on text fields larger than 333 chars! */ /// Adding indexes to table cache_flags @@ -2357,7 +2357,7 @@ if (index_exists($table, $index)) { $result = $result && drop_index($table, $index); } - + $table = new XMLDBTable('cache_flags'); $index = new XMLDBIndex('flagtype'); $index->setAttributes(XMLDB_INDEX_NOTUNIQUE, array('flagtype')); @@ -2519,7 +2519,7 @@ FROM {$CFG->prefix}user_lastaccess WHERE NOT EXISTS (SELECT 'x' FROM {$CFG->prefix}course c - WHERE c.id = {$CFG->prefix}user_lastaccess.courseid)"; + WHERE c.id = {$CFG->prefix}user_lastaccess.courseid)"; execute_sql($sql); upgrade_main_savepoint($result, 2007100902); @@ -2542,16 +2542,16 @@ upgrade_main_savepoint($result, 2007100903); } - + if ($result && $oldversion < 2007101500 && !file_exists($CFG->dataroot . '/user')) { // Get list of users by browsing moodledata/user $oldusersdir = $CFG->dataroot . '/users'; $folders = get_directory_list($oldusersdir, '', false, true, false); - + foreach ($folders as $userid) { $olddir = $oldusersdir . '/' . $userid; $files = get_directory_list($olddir); - + if (empty($files)) { continue; } @@ -2578,7 +2578,7 @@ $readmefilename = $oldusersdir . '/README.txt'; if ($handle = fopen($readmefilename, 'w+b')) { if (!fwrite($handle, get_string('olduserdirectory'))) { - // Could not write to the readme file. No cause for huge concern + // Could not write to the readme file. No cause for huge concern notify("Could not write to the README.txt file in $readmefilename."); } fclose($handle); @@ -2586,22 +2586,22 @@ // Could not create the readme file. No cause for huge concern notify("Could not create the README.txt file in $readmefilename."); } - } + } if ($result && $oldversion < 2007101502) { /// try to remove duplicate entries - + $SQL = "SELECT userid, itemid, COUNT(*) FROM {$CFG->prefix}grade_grades GROUP BY userid, itemid HAVING COUNT( * ) >1"; // duplicates found - + if ($rs = get_recordset_sql($SQL)) { if ($rs && $rs->RecordCount() > 0) { while ($dup = rs_fetch_next_record($rs)) { - if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades + if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades WHERE itemid = $dup->itemid AND userid = $dup->userid ORDER BY timemodified DESC")) { @@ -2629,7 +2629,7 @@ /// Main savepoint reached upgrade_main_savepoint($result, 2007101502); - } + } if ($result && $oldversion < 2007101503) { // Update courses that used weekscss to weeks @@ -2664,13 +2664,36 @@ $sql = "DELETE FROM {$CFG->prefix}context WHERE contextlevel=20"; - + execute_sql($sql); /// Main savepoint reached upgrade_main_savepoint($result, 2007101506); } + if ($result && $oldversion < 2007101507) { + + // table to be modified + $table = new XMLDBTable('tag_instance'); + // add field + $field = new XMLDBField('tiuserid'); + if (!field_exists($table, $field)) { + $field->setAttributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'itemid'); + $result = $result && add_field($table, $field); + } + // modify index + $index = new XMLDBIndex('itemtype-itemid-tagid'); + $index->setAttributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid')); + drop_index($table, $index); + $index = new XMLDBIndex('itemtype-itemid-tagid-tiuserid'); + $index->setAttributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid', 'tiuserid')); + drop_index($table, $index); //should not be required, but better safe than sorry + $result = $result && add_index($table, $index); + + /// Main savepoint reached + upgrade_main_savepoint($result, 2007101507); + } + return $result; } Index: version.php =================================================================== RCS file: /cvsroot/moodle/moodle/version.php,v retrieving revision 1.573 diff -u -r1.573 version.php --- version.php 23 Dec 2007 20:01:14 -0000 1.573 +++ version.php 10 Jan 2008 08:37:39 -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 = 2007101506; // YYYYMMDD = date + $version = 2007101507; // YYYYMMDD = date // XY = increments within a single day $release = '2.0 dev'; // Human-friendly version name Index: lib/moodlelib.php =================================================================== RCS file: /cvsroot/moodle/moodle/lib/moodlelib.php,v retrieving revision 1.985 diff -u -r1.985 moodlelib.php --- lib/moodlelib.php 1 Jan 2008 17:23:05 -0000 1.985 +++ lib/moodlelib.php 10 Jan 2008 08:37:42 -0000 @@ -1875,12 +1875,12 @@ // Fetch the course context, and prefetch its child contexts if (!isset($COURSE->context)) { if ( ! $COURSE->context = get_context_instance(CONTEXT_COURSE, $COURSE->id) ) { - print_error('nocontext'); + print_error('nocontext'); } } if ($COURSE->id == SITEID) { /// Eliminate hidden site activities straight away - if (!empty($cm) && !$cm->visible + if (!empty($cm) && !$cm->visible && !has_capability('moodle/course:viewhiddenactivities', $COURSE->context)) { redirect($CFG->wwwroot, get_string('activityiscurrentlyhidden')); } @@ -1892,7 +1892,7 @@ if (empty($USER->access['rsw'][$COURSE->context->path])) { // // Spaghetti logic construct - // + // // - able to view course? // - able to view category? // => if either is missing, course is hidden from this user @@ -1901,14 +1901,14 @@ // more costly checks last... // if (! (($COURSE->visible || has_capability('moodle/course:viewhiddencourses', $COURSE->context)) - && (course_parent_visible($COURSE)) || has_capability('moodle/course:viewhiddencourses', + && (course_parent_visible($COURSE)) || has_capability('moodle/course:viewhiddencourses', get_context_instance(CONTEXT_COURSECAT, $COURSE->category)))) { print_header_simple(); notice(get_string('coursehidden'), $CFG->wwwroot .'/'); } - } - + } + /// Non-guests who don't currently have access, check if they can be allowed in as a guest if ($USER->username != 'guest' and !has_capability('moodle/course:view', $COURSE->context)) { @@ -1923,7 +1923,7 @@ if (has_capability('moodle/legacy:guest', $COURSE->context, NULL, false)) { switch ($COURSE->guest) { /// Check course policy about guest access - case 1: /// Guests always allowed + case 1: /// Guests always allowed if (!has_capability('moodle/course:view', $COURSE->context)) { // Prohibited by capability print_header_simple(); notice(get_string('guestsnotallowed', '', format_string($COURSE->fullname)), "$CFG->wwwroot/login/index.php"); @@ -1971,7 +1971,7 @@ /// Make sure they can read this activity too, if specified - if (!empty($cm) and !$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $COURSE->context)) { + if (!empty($cm) and !$cm->visible and !has_capability('moodle/course:viewhiddenactivities', $COURSE->context)) { redirect($CFG->wwwroot.'/course/view.php?id='.$cm->course, get_string('activityiscurrentlyhidden')); } return; // User is allowed to see this course @@ -3031,7 +3031,7 @@ * Call to complete the user login process after authenticate_user_login() * has succeeded. It will setup the $USER variable and other required bits * and pieces. - * + * * NOTE: * - It will NOT log anything -- up to the caller to decide what to log. * @@ -3043,7 +3043,7 @@ */ function complete_user_login($user) { global $CFG, $USER; - + $USER = $user; // should not be needed, but cover for legacy code update_user_login_times(); @@ -3542,6 +3542,13 @@ /// Delete questions and question categories question_delete_course($course, $showfeedback); +/// Delete course tags + require_once($CFG->dirroot.'/blocks/tags/coursetagslib.php'); + coursetag_delete_course_tags($course->id); + if ($showfeedback) { + notify("$strdeleted course tags"); + } + return $result; } @@ -4294,7 +4301,7 @@ /// If you don't want a welcome message sent, then make the message string blank. if (!empty($message)) { $subject = get_string('welcometocourse', '', format_string($course->fullname)); - + if (! $teacher = get_teacher($course->id)) { $teacher = get_admin(); } @@ -4349,7 +4356,7 @@ // Generate a two-level path for the userid. First level groups them by slices of 1000 users, second level is userid $level1 = floor($userid / 1000) * 1000; - + $userdir = "user/$level1/$userid"; if ($test) { return $CFG->dataroot . '/' . $userdir; @@ -4363,20 +4370,20 @@ * * @param bool $only_non_empty Only return directories that contain files * @param bool $legacy Search for user directories in legacy location (dataroot/users/userid) instead of (dataroot/user/section/userid) - * @return array An associative array: userid=>array(basedir => $basedir, userfolder => $userfolder) + * @return array An associative array: userid=>array(basedir => $basedir, userfolder => $userfolder) */ function get_user_directories($only_non_empty=true, $legacy=false) { global $CFG; $rootdir = $CFG->dataroot."/user"; - + if ($legacy) { - $rootdir = $CFG->dataroot."/users"; + $rootdir = $CFG->dataroot."/users"; } $dirlist = array(); - //Check if directory exists - if (check_dir_exists($rootdir, true)) { + //Check if directory exists + if (check_dir_exists($rootdir, true)) { if ($legacy) { if ($userlist = get_directory_list($rootdir, '', true, true, false)) { foreach ($userlist as $userid) { @@ -4384,7 +4391,7 @@ } } else { notify("no directories found under $rootdir"); - } + } } else { if ($grouplist =get_directory_list($rootdir, '', true, true, false)) { // directories will be in the form 0, 1000, 2000 etc... foreach ($grouplist as $group) { @@ -4394,7 +4401,7 @@ } } } - } + } } } else { notify("$rootdir does not exist!"); @@ -6363,7 +6370,7 @@ * @param string $text - text to be shortened * @param int $ideal - ideal string length * @param boolean $exact if false, $text will not be cut mid-word - * @return string $truncate - shortened string + * @return string $truncate - shortened string */ function shorten_text($text, $ideal=30, $exact = false) { @@ -6375,7 +6382,7 @@ if (strlen(preg_replace('/<.*?>/', '', $text)) <= $ideal) { return $text; } - + // splits all html-tags to scanable lines preg_match_all('/(<.+?>)?([^<>]*)/s', $text, $lines, PREG_SET_ORDER); @@ -6431,7 +6438,7 @@ $truncate .= $line_matchings[2]; $total_length += $content_length; } - + // if the maximum length is reached, get off the loop if($total_length >= $ideal) { break; @@ -6452,7 +6459,7 @@ } } } - + if (isset($breakpos)) { // ...and cut the text in this position $truncate = substr($truncate, 0, $breakpos); 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 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,66 @@ + 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 1 Jan 1970 00:00:00 -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: blocks/tags/coursetags_more.php =================================================================== RCS file: blocks/tags/coursetags_more.php diff -N blocks/tags/coursetags_more.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/coursetags_more.php 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,192 @@ +dirroot.'/blocks/tags/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 = get_record('course', '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); +$tagsfor = get_string('moretagsfor', $tagslang); +$orderalpha = get_string('moreorderalpha', $tagslang); +$orderdate = get_string('moreorderdate', $tagslang); +$orderpop = get_string('moreorderpop', $tagslang); +$mytags = get_string('moremytags', $tagslang); +$officialtags = get_string('moreofficialtags', $tagslang); +$communitytags = get_string('morecommtags', $tagslang); +$alltags = get_string('morealltags', $tagslang); +$welcome = get_string('morewelcome', $tagslang); + +// The title and breadcrumb +if ($courseid) { + $navigation[] = array('name' => $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.'/blocks/tags/coursetags_more.php'; +$myurl2 = $CFG->wwwroot.'/blocks/tags/coursetags_more.php?show='.$show; + +// Course tags +if ($show == 'course' and $courseid) { + + if ($sort == 'popularity') { + $tags = print_tag_cloud(coursetag_get_tags($courseid, 0, '', 0, 'popularity'), false, 200, 90, true); + } else if ($sort == 'date') { + $tags = print_tag_cloud(coursetag_get_tags($courseid, 0, '', 0, 'timemodified'), false, 200, 90, true); + } else { + $tags = print_tag_cloud(coursetag_get_tags($courseid, 0, '', 0, 'name'), false, 200, 90, true); + } + +// My tags +} else if ($show == 'my' and $loggedin) { + + if ($sort == 'popularity') { + $tags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal', 0, 'popularity'), false, 200, 90, true); + } else if ($sort == 'date') { + $tags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal', 0, 'timemodified'), false, 200, 90, true); + } else { + $tags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal', 0, 'name'), false, 200, 90, true); + } + +// Official course tags +} else if ($show == 'official') { + + if ($sort == 'popularity') { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'official', 0, 'popularity'), false, 200, 90, true); + } else if ($sort == 'date') { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'official', 0, 'timemodified'), false, 200, 90, true); + } else { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'official', 0, 'name'), false, 200, 90, true); + } + +// Community (official and personal together) also called user tags +} else if ($show == 'community') { + + if ($sort == 'popularity') { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'personal', 0, 'popularity'), false, 200, 90, true); + } else if ($sort == 'date') { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'personal', 0, 'timemodified'), false, 200, 90, true); + } else { + $tags = print_tag_cloud(coursetag_get_tags(0, 0, 'personal', 0, 'name'), false, 200, 90, true); + } + +// All tags for courses and blogs and any thing else tagged - the fallback default ($show == all) +} else { + + $subtitle = $alltags; + if ($sort == 'popularity') { + $tags = print_tag_cloud(coursetag_get_all_tags('popularity'), false, 200, 90, true); + } else if ($sort == 'date') { + $tags = print_tag_cloud(coursetag_get_all_tags('timemodified'), false, 200, 90, true); + } else { + $tags = print_tag_cloud(coursetag_get_all_tags('name'), false, 200, 90, true); + } + +} + +// Prepare the links for the show and order lines +if ($show == 'all') { + $link1 .= ''.$showalltags.''; +} else { + $link1 .= ''.$showalltags.''; +} +if ($show == 'official') { + $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 .= ' | '.$tagsfor.' \''.$course->fullname.'\''; + } else { + $link1 .= ' | '.$tagsfor.' \''.$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: blocks/tags/arrow_left.gif =================================================================== RCS file: blocks/tags/arrow_left.gif diff -N blocks/tags/arrow_left.gif --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/arrow_left.gif 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,5 @@ +GIF89a + +¢fffÿ̰°°ÿÿÿÝÝݵµµ!ù, + +º¼M?Û$/‡KºB'Œ#„ÙãU¤Fp?; Index: blocks/tags/coursetags_add.php =================================================================== RCS file: blocks/tags/coursetags_add.php diff -N blocks/tags/coursetags_add.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/coursetags_add.php 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,37 @@ +dirroot.'/blocks/tags/coursetagslib.php'); + + if ($entryid > 0 and $userid > 0) { + $myurl = 'tag/search.php?query='.urlencode($keyword); + $keywords = (array)$keyword; + try { + coursetag_store_keywords($keywords, $entryid, $userid, 'personal', $myurl); + } + catch (Exception $e) { + error($e->getmessage()); + } + } +} + +// send back to originating page, where the new tag will be visible in the block +if ($entryid > 0) { + $myurl = $CFG->wwwroot.'/course/view.php?id='.$entryid; +} else { + $myurl = $CFG->wwwroot.'/'; +} +redirect($myurl); +?> 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 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,108 @@ +/* + * CSS for course tags + * @author j.beedell@open.ac.uk July07 + * + * Styles for block_tags.php + */ + +.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; + width: 10em; +} + +.coursetag_form_input3 { + position: absolute; + top: 3px; + left: 13em; + display: none; +} + +.coursetag_form_input1a { + background-color: transparent; + 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: -10px 5px 5px 0; +} + +/* 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: 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 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,79 @@ +/** + * 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; +} + +function ctags_checkinput(val) { + var len = val.length; + if (len < 2 || len > 50) { + alert("Tags must have more that one and less than 50 characters. Please adjust your tag."); + return false; + } else if (val.indexOf("'") > 0) { + alert("Regretably tags cannot contain apostrophies at the moment. Please adjust your tag."); + return false; + } else if (val.indexOf("_") > 0) { + alert("Tags cannot contain underscores. Please adjust your tag."); + return false; + } else if (val.indexOf("-") > 0) { + alert("Tags cannot contain hyphens. Please adjust your tag."); + return false; + } else if (isFinite(val)) { + alert("Tags cannot be an integer or float. Please adjust your tag."); + return false; + } else { + return true; + } +} + +var sug = ""; +var sug_disp = ""; + +function ctags_getKeywords() { + var input = document.forms['coursetag'].coursetag_new_tag.value; + var len = input.length; + sug_disp = ""; sug = ""; + + if (input.length) { + // get matching folks_tag from array + 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: 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 1 Jan 1970 00:00:00 -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: blocks/tags/coursetagslib.php =================================================================== RCS file: blocks/tags/coursetagslib.php diff -N blocks/tags/coursetagslib.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/coursetagslib.php 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,447 @@ +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 'personal', default returns both tag types + * @param int $numtags optional number of tags to display, default of 20 is set in the block, 0 returns all + * @param string $sort optional selected sorting, default is alpha sort (name) also timemodified or popularity + * @param int $timewithin optional limit to age of tags to be displayed, default returns all + * @return array + */ +function coursetag_get_tags($courseid, $userid=0, $tagtype='', $numtags=0, $sort='name', $timewithin=10) { + + global $CFG; + + // get visible course ids + if ($courseid === 0) { + $courselist = '('; + if ($courses = get_records_select('course', 'visible=1 AND category>0', '', 'id')) { + foreach ($courses as $key => $value) { + $courselist .= "$key, "; + } + $courselist = rtrim($courselist, ', '); + $courselist .= ')'; + } else { + $courselist = ''; + } + } + + // get tags from the db ordered by highest count first + $sql = "SELECT id as key, name, id, tagtype, rawname, f.timemodified, flag, count + FROM {$CFG->prefix}tag t, + (SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count + FROM {$CFG->prefix}tag_instance + WHERE itemtype = 'course' + AND timemodified > $timewithin "; + if ($courseid > 0) { + $sql .= "AND itemid = $courseid "; + } else { + if ($courselist) { + $sql .= "AND itemid IN $courselist "; + } + } + if ($userid > 0) $sql .= "AND tiuserid = $userid "; + $sql .= "GROUP BY tagid) f + WHERE t.id = f.tagid "; + if ($tagtype == 'official') $sql .= "AND tagtype = '$tagtype' "; + $sql .= "ORDER BY count DESC, name ASC"; + + // limit the number of tags for output + if ($numtags == 0) { + $tags = get_records_sql($sql); + } else { + $tags = get_records_sql($sql, 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; + + $sql = "SELECT id as key, name, id, tagtype, rawname, f.timemodified, flag, count + FROM {$CFG->prefix}tag t, + (SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count + FROM {$CFG->prefix}tag_instance + GROUP BY tagid) f + WHERE t.id = f.tagid + ORDER BY count DESC, name ASC"; + + if ($numtags == 0) { + $tags = get_records_sql($sql); + } else { + $tags = get_records_sql($sql, 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_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; + } +} + +/** + * Return a javascript block for use in tags block and supporting pages + * @uses $CFG + */ +function coursetag_get_jscript() { + + global $CFG; + + $coursetags = get_all_tags('*', $sort='name ASC', $fields='name, id'); + $a = 0; + $coursetagscript = ''; + if (!empty($coursetags)) { + foreach ($coursetags as $key => $value) { + $coursetagscript .= "coursetag_tags[$a] = \"$key\"; "; + $a++; + } + } + $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; + + $sql = "SELECT t.id, name, rawname + FROM {$CFG->prefix}tag t, {$CFG->prefix}tag_instance ti + WHERE t.id = ti.tagid + AND t.tagtype = 'personal' + AND ti.tiuserid = '$userid' + AND ti.itemid = '$courseid' + ORDER by name ASC"; + $return = get_records_sql($sql); + + return $return; + +} + +/** + * 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 defaults to admin user + * @param string $tagtype official (default) or personal only + * @param string $myurl optional for logging creation of course tags + */ +function coursetag_store_keywords($tags, $courseid, $userid=3, $tagtype='official', $myurl='') { + + global $CFG; + + if (is_array($tags) and !empty($tags)) { + foreach($tags as $tag) { + // don't store non-existant tags + if (strlen($tag) > 0) { + tag_an_item('course', $courseid, $tag, $tagtype, $userid); + if ($tagtype == 'personal' and $myurl != '') { + // log the tagging request + add_to_log($courseid, 'coursetags', 'add', $myurl, 'Personal tag \''.$tag.'\''); + } + } + } + } + +} + +/** + * 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; + + $sql = "SELECT COUNT(*) + FROM {$CFG->prefix}tag_instance + WHERE tagid = $tagid + AND tiuserid = $userid + AND itemtype = 'course' + AND itemid = $courseid"; + if (count_records_sql($sql) == 1) { + $sql = "tagid = $tagid + AND tiuserid = $userid + AND itemtype = 'course' + AND itemid = $courseid"; + delete_records_select('tag_instance', $sql); + // if there are no other instances of the tag then consider deleting the tag as well + if (!record_exists('tag_instance', 'tagid', $tagid)) { + // if the tag is a personal tag then delete it + if (record_exists('tag', 'id', $tagid, 'tagtype', 'personal')) { + delete_records('tag', 'id', $tagid, 'tagtype', 'personal'); + } + } + } else { + error("Error deleting tag with id $tagid, please report to your system administrator."); + } + +} + +/** + * Function used only during the deletion of a course (lib/moodlelib.php) + * + * @param $courseid + */ +function coursetag_delete_course_tags($courseid) { + if ($tags = get_records_select('tag_instance', "itemtype='course' AND itemid=".$courseid)) { + foreach ($tags as $tag) { + //delete the course tag instance record + delete_records('tag_instance', 'tagid', $tag->tagid, 'itemtype', 'course', 'itemid', $courseid); + // delete tag if there are no other tag_instance entries now + if (!(record_exists('tag_instance', 'tagid', $tag->tagid))) { + delete_records('tag', 'id', $tag->tagid); + } + } + } +} + +/** + * Get courses tagged with a tag + * + * @param $tagid + * @return array of course objects + */ +function coursetag_get_tagged_courses($tagid) { + + $courses = array(); + if ($crs = get_records_select('tag_instance', "tagid='$tagid' AND itemtype='course'", '', 'itemid')) { + foreach ($crs as $c) { + if (has_capability('moodle/course:view', get_context_instance(CONTEXT_COURSE, $c->itemid))) { + $course = get_record('course', 'id', $c->itemid); + $courses[$c->itemid] = $course; + } + } + } + return $courses; + +} + +/** + * Function called by cron to create/update users rss feeds + * + * @uses $CFG + * @return true + * + * Function removed. + * rsslib.php needs updating to accept dc/cc input before this can work (or modified). + */ +/* +function coursetag_rss_feeds() { + + global $CFG; + 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 = 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 {$CFG->prefix}user u, {$CFG->prefix}course c, {$CFG->prefix}tag_instance cti, {$CFG->prefix}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 = 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 {$CFG->prefix}course c, {$CFG->prefix}tag_instance cti, {$CFG->prefix}tag t + WHERE c.id = cti.itemid + AND cti.tiuserid = {$user->userid} + AND cti.tagid = t.id + AND t.tagtype = 'personal' + ORDER BY courseid"; + if ($usertags = get_records_sql($sql)) { + $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 = 'The OpenLearn Unit Tags RSS Feed for user: '.ucwords(strtolower($user->firstname.' '.$user->lastname)); + $desc = 'This RSS feed was automatically generated by OpenLearn folksonomies and contains user generated tags for units.'; + // 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 entirely once rsslib is adjusted + require_once($CFG->dirroot.'/local/ocilib.php'); + oci_create_rss_feed( $path, $file_name, $latest_date, $items, $title, $desc, true); + } + } + } + } + + return $status; +} + */ + +/** + * Get official keywords for the in header.html + * use: echo ''; + * @uses $CFG + * @param int $courseid + * @return string + * + * Function removed + * This function is potentially useful to anyone wanting to improve search results for course pages. + * The idea is to add official (not personal ones, so users cannot delete) tags to all + * courses (facility not added yet) which wil be automatically added to the page to boost + * search engine specificity/ratings. + */ +/* +function coursetag_get_official_keywords($courseid, $asarray=false) { + global $CFG; + $returnstr = ''; + $sql = "SELECT t.id, name, rawname + FROM {$CFG->prefix}tag t, {$CFG->prefix}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 = get_records_sql($sql)) { + 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: blocks/tags/coursetags_edit.php =================================================================== RCS file: blocks/tags/coursetags_edit.php diff -N blocks/tags/coursetags_edit.php --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ blocks/tags/coursetags_edit.php 1 Jan 1970 00:00:00 -0000 @@ -0,0 +1,165 @@ +dirroot.'/blocks/tags/coursetagslib.php'); +require_once($CFG->dirroot.'/tag/lib.php'); + +$courseid = optional_param('courseid', 1, PARAM_INT); +$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT); +$deltag = optional_param('del_tag', 0, PARAM_INT); + +if ($courseid > 0) { + if (! ($COURSE = get_record('course', 'id', $courseid)) ) { + error('Invalid course id'); + } +} else { + error('Invalid course id'); +} + +// Permissions +$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); +$isguest = has_capability('moodle/legacy:guest', $sitecontext, $USER->id, false); +$loggedin = isloggedin() && !$isguest; +$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($keyword)) { + //$keywords = folks_input_to_keywords($keyword); + $keywords = (array)$keyword; + try { + coursetag_store_keywords($keywords, $courseid, $USER->id, 'personal'); + } + catch (Exception $e) { + error($e->getmessage()); + } + } + // delete personal tag + if ($deltag > 0) { + coursetag_delete_keyword($deltag, $USER->id, $courseid); + } + } +} + +// The title and breadcrumb +$title = get_string('edittitle', $tagslang); +$nav = build_navigation(array(array('name' => $title, 'link' => null, 'type' => 'misc'))); +print_header_simple($title, '', $nav, '', '', false); + +// Tags for all - providing navigation to units +print_heading($title, 'centre'); + +// Personal tags section for logged in users +if ($loggedin) { + + $mytags = print_tag_cloud(coursetag_get_tags(0, $USER->id, 'personal'), false, 500, 100, true); + if ($mytags) { + $outstr = " +
+ ".get_string('editmytags', $tagslang)." +
+
+ $mytags +
"; + echo $outstr; + } + + // Personal tag editing - not for site front page + if ($canedit and $courseid > 1) { + $title = get_string('editedit', $tagslang).' "'.$COURSE->fullname.' ('.$COURSE->shortname.')"'; + print_heading($title); + + // Deletion here is open to the registered users own tags for this course only + $selectoptions = ""; + $coursetabs = ''; + if ($options = coursetag_get_records($COURSE->id, $USER->id)) { + $coursetabs = '"'; + foreach ($options as $value) { + $selectoptions .= "\n"; + $coursetabs .= $value->rawname . ', '; + } + $coursetabs = rtrim($coursetabs, ', '); + $coursetabs .= '"'; + } + + // Print course tags + $outstr = '
'; + if ($coursetabs) { + $outstr .= get_string('editmytagsfor', $tagslang)." \"{$COURSE->fullname}\" ". + get_string('editare', $tagslang)." $coursetabs."; + } else { + $outstr .= get_string('editnopersonaltags', $tagslang)." '{$COURSE->fullname}' ". + get_string('edityet', $tagslang); + } + $outstr .= '
'; + echo $outstr; + + // Getting deletions and additions to personal tags for a unit + $outstr = " + "; + $outstr .= coursetag_get_jscript(); + $outstr .= " + + + +
+
+
"; + $outstr .= helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE); + $outstr .= get_string('edittagthisunit', $tagslang).' '; + $outstr .= "
+
+
+ +
+
+ +
+
+ + + +
+
+
"; + if ($coursetabs) { + $outstr .= " +
+
"; + $outstr .= helpbutton('deletetags', 'deleting tags', $tagslang, TRUE, FALSE, '', TRUE); + $outstr .= get_string('editdeletemytag', $tagslang).' '; + $outstr .= "
+
+ +
+
"; + } + $outstr .= " +
+
+ +
+
+ "; + echo $outstr; + } + +} + +print_footer(); +?> 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 1 Jan 1970 00:00:00 -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.