### Eclipse Workspace Patch 1.0
#P core
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 20 Dec 2007 14:05:28 -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);
@@ -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}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 20 Dec 2007 14:05:28 -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 '
";
+ $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 .= "
+ ";
+ // 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: course/lib.php
===================================================================
RCS file: /cvsroot/moodle/moodle/course/lib.php,v
retrieving revision 1.541
diff -u -r1.541 lib.php
--- course/lib.php 27 Nov 2007 01:56:21 -0000 1.541
+++ course/lib.php 20 Dec 2007 14:05:24 -0000
@@ -13,11 +13,11 @@
define('COURSE_MAX_SUMMARIES_PER_PAGE', 10); // courses
define('COURSE_MAX_COURSES_PER_DROPDOWN',1000); // max courses in log dropdown before switching to optional
define('COURSE_MAX_USERS_PER_DROPDOWN',1000); // max users in log dropdown before switching to optional
-define('FRONTPAGENEWS', 0);
-define('FRONTPAGECOURSELIST', 1);
-define('FRONTPAGECATEGORYNAMES', 2);
-define('FRONTPAGETOPICONLY', 3);
-define('FRONTPAGECATEGORYCOMBO', 4);
+define('FRONTPAGENEWS', '0');
+define('FRONTPAGECOURSELIST', '1');
+define('FRONTPAGECATEGORYNAMES', '2');
+define('FRONTPAGETOPICONLY', '3');
+define('FRONTPAGECATEGORYCOMBO', '4');
define('FRONTPAGECOURSELIMIT', 200); // maximum number of courses displayed on the frontpage
define('EXCELROWS', 65535);
define('FIRSTUSEDEXCELROW', 3);
@@ -260,6 +260,9 @@
case 'upload':
return $url;
break;
+ case 'coursetags':
+ return '/'.$url;
+ break;
case 'library':
case '':
return '/';
@@ -280,11 +283,11 @@
// and so the next 86400 seconds worth of logs are printed.
/// Setup for group handling.
-
- // TODO: I don't understand group/context/etc. enough to be able to do
+
+ // TODO: I don't understand group/context/etc. enough to be able to do
// something interesting with it here
// What is the context of a remote course?
-
+
/// If the group mode is separate, and this user does not have editing privileges,
/// then only the user's group can be viewed.
//if ($course->groupmode == SEPARATEGROUPS and !has_capability('moodle/course:managegroups', get_context_instance(CONTEXT_COURSE, $course->id))) {
@@ -301,14 +304,14 @@
$qry = "
SELECT
l.*,
- u.firstname,
- u.lastname,
+ u.firstname,
+ u.lastname,
u.picture
FROM
{$CFG->prefix}mnet_log l
- LEFT JOIN
+ LEFT JOIN
{$CFG->prefix}user u
- ON
+ ON
l.userid = u.id
WHERE
";
@@ -327,7 +330,7 @@
if ('site_errors' === $modid) {
$where .= " AND\n ( l.action='error' OR l.action='infected' )";
} else if ($modid) {
- //TODO: This assumes that modids are the same across sites... probably
+ //TODO: This assumes that modids are the same across sites... probably
//not true
$where .= " AND\n l.cmid = '$modid'";
}
@@ -404,7 +407,7 @@
}
}
-
+
/// Getting all members of a group.
if ($groupid and !$user) {
if ($gusers = groups_get_members($groupid)) {
@@ -489,7 +492,7 @@
if (empty($logs['logs'])) {
$logs['logs'] = array();
}
-
+
$row = 1;
foreach ($logs['logs'] as $log) {
@@ -550,16 +553,16 @@
function print_mnet_log($hostid, $course, $user=0, $date=0, $order="l.time ASC", $page=0, $perpage=100,
$url="", $modname="", $modid=0, $modaction="", $groupid=0) {
-
+
global $CFG;
-
+
if (!$logs = build_mnet_logs_array($hostid, $course, $user, $date, $order, $page*$perpage, $perpage,
$modname, $modid, $modaction, $groupid)) {
notify("No logs found!");
print_footer($course);
exit;
}
-
+
if ($course->id == SITEID) {
$courses[0] = '';
if ($ccc = get_courses('all', 'c.id ASC', 'c.id,c.shortname,c.visible')) {
@@ -568,7 +571,7 @@
}
}
}
-
+
$totalcount = $logs['totalcount'];
$count=0;
$ldcache = array();
@@ -602,7 +605,7 @@
$row = 1;
foreach ($logs['logs'] as $log) {
-
+
$log->info = $log->coursename;
$row = ($row + 1) % 2;
@@ -621,7 +624,7 @@
}
}
- //Filter log->info
+ //Filter log->info
$log->info = format_string($log->info);
$log->url = strip_tags(urldecode($log->url)); // Some XSS protection
@@ -1344,7 +1347,7 @@
/// Casting $course->modinfo to string prevents one notice when the field is null
$modinfo = unserialize((string)$course->modinfo);
-
+
$groupings = groups_get_all_groupings($course->id);
//Acccessibility: replace table with list
, but don't output empty list.
@@ -1498,7 +1501,7 @@
static $resources = false;
static $activities = false;
- if ($resources === false) {
+ if ($resources === false) {
$resources = array();
$activities = array();
@@ -1507,7 +1510,7 @@
continue;
}
- require_once("$CFG->dirroot/mod/$modname/lib.php");
+ include_once("$CFG->dirroot/mod/$modname/lib.php");
$gettypesfunc = $modname.'_get_types';
if (function_exists($gettypesfunc)) {
$types = $gettypesfunc();
@@ -1580,6 +1583,32 @@
}
+function get_child_categories($parent) {
+/// Returns an array of the children categories for the given category
+/// ID by caching all of the categories in a static hash
+
+ static $allcategories = null;
+
+ // only fill in this variable the first time
+ if (null == $allcategories) {
+ $allcategories = array();
+
+ $categories = get_categories();
+ foreach ($categories as $category) {
+ if (empty($allcategories[$category->parent])) {
+ $allcategories[$category->parent] = array();
+ }
+ $allcategories[$category->parent][] = $category;
+ }
+ }
+
+ if (empty($allcategories[$parent])) {
+ return array();
+ } else {
+ return $allcategories[$parent];
+ }
+}
+
function make_categories_list(&$list, &$parents, $category=NULL, $path="") {
/// Given an empty array, this function recursively travels the
@@ -1605,7 +1634,7 @@
$category->id = 0;
}
- if ($categories = get_categories($category->id)) { // Print all the children recursively
+ if ($categories = get_child_categories($category->id)) { // Print all the children recursively
foreach ($categories as $cat) {
if (!empty($category->id)) {
if (isset($parents[$category->id])) {
@@ -1643,7 +1672,7 @@
$category->id = "0";
}
- if ($categories = get_categories($category->id)) { // Print all the children recursively
+ if ($categories = get_child_categories($category->id)) { // Print all the children recursively
$countcats = count($categories);
$count = 0;
$first = true;
@@ -1782,21 +1811,21 @@
global $CFG;
if (!is_object($category) && $category==0) {
- $categories = get_categories(0); // Parent = 0 ie top-level categories only
+ $categories = get_child_categories(0); // Parent = 0 ie top-level categories only
if (is_array($categories) && count($categories) == 1) {
$category = array_shift($categories);
- $courses = get_courses_wmanagers($category->id,
- 'c.sortorder ASC',
+ $courses = get_courses_wmanagers($category->id,
+ 'c.sortorder ASC',
array('password','summary','currency'));
} else {
- $courses = get_courses_wmanagers('all',
- 'c.sortorder ASC',
+ $courses = get_courses_wmanagers('all',
+ 'c.sortorder ASC',
array('password','summary','currency'));
}
unset($categories);
} else {
- $courses = get_courses_wmanagers($category->id,
- 'c.sortorder ASC',
+ $courses = get_courses_wmanagers($category->id,
+ 'c.sortorder ASC',
array('password','summary','currency'));
}
@@ -1842,12 +1871,12 @@
echo '
';
@@ -2743,10 +2772,10 @@
context_moved($context, $newparent);
- // The most effective thing would be to find the common parent,
+ // The most effective thing would be to find the common parent,
// until then, do it sitewide...
fix_course_sortorder();
-
+
return true;
}
@@ -2792,7 +2821,7 @@
}
-/*
+/*
* Create a course and either return a $course object or false
*
* @param object $data - all the data needed for an entry in the 'course' table
@@ -2842,13 +2871,13 @@
add_to_log(SITEID, 'course', 'new', 'view.php?id='.$course->id, $data->fullname.' (ID '.$course->id.')');
return $course;
- }
+ }
return false; // error
}
-/*
+/*
* Update a course and return true or false
*
* @param object $data - all the data needed for an entry in the 'course' table
@@ -2898,37 +2927,37 @@
// put custom role names into db
$context = get_context_instance(CONTEXT_COURSE, $course->id);
-
+
foreach ($data as $dname => $dvalue) {
-
+
// is this the right param?
$dvalue = clean_param($dvalue, PARAM_NOTAGS);
if (!strstr($dname, 'role_')) {
continue;
- }
-
+ }
+
$dt = explode('_', $dname);
$roleid = $dt[1];
// make up our mind whether we want to delete, update or insert
-
+
if (empty($dvalue)) {
-
+
delete_records('role_names', 'contextid', $context->id, 'roleid', $roleid);
-
+
} else if ($t = get_record('role_names', 'contextid', $context->id, 'roleid', $roleid)) {
-
+
$t->text = $dvalue;
- update_record('role_names', $t);
-
+ update_record('role_names', $t);
+
} else {
-
+
$t->contextid = $context->id;
$t->roleid = $roleid;
$t->text = $dvalue;
- insert_record('role_names', $t);
+ insert_record('role_names', $t);
}
-
+
}
return true;
Index: lib/db/upgrade.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v
retrieving revision 1.168
diff -u -r1.168 upgrade.php
--- lib/db/upgrade.php 8 Dec 2007 18:44:12 -0000 1.168
+++ lib/db/upgrade.php 20 Dec 2007 14:05:28 -0000
@@ -2054,6 +2054,9 @@
/// Launch create table for context_temp
$result = $result && create_table($table);
+ /// make sure category depths, parents and paths are ok, categories from 1.5 may not be properly initialized (MDL-12585)
+ upgrade_fix_category_depths();
+
/// Recalculate depths, paths and so on
if (!empty($CFG->rolesactive)) {
cleanup_contexts();
@@ -2309,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
@@ -2354,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'));
@@ -2516,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);
@@ -2539,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;
}
@@ -2575,30 +2578,30 @@
$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);
} else {
// 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")) {
@@ -2626,13 +2629,59 @@
/// Main savepoint reached
upgrade_main_savepoint($result, 2007101502);
- }
+ }
if ($result && $oldversion < 2007101503) {
// Update courses that used weekscss to weeks
$result = $result && set_field('course', 'format', 'weeks', 'format', 'weekscss');
}
+ if ($result && $oldversion < 2007101505) {
+
+ /// Changing precision of field dst_time on table timezone to (6)
+ $table = new XMLDBTable('timezone');
+ $field = new XMLDBField('dst_time');
+ $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'dst_skipweeks');
+
+ /// Launch change of precision for field dst_time
+ $result = $result && change_field_precision($table, $field);
+
+ /// Changing precision of field std_time on table timezone to (6)
+ $table = new XMLDBTable('timezone');
+ $field = new XMLDBField('std_time');
+ $field->setAttributes(XMLDB_TYPE_CHAR, '6', null, XMLDB_NOTNULL, null, null, null, '00:00', 'std_skipweeks');
+
+ /// Launch change of precision for field std_time
+ $result = $result && change_field_precision($table, $field);
+
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2007101505);
+ }
+
+ if ($result && $oldversion < 2007101506) {
+
+ // 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);
+ //$index->setAttributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid', 'tiuserid'));
+ $result = $result && add_index($table, $index);
+
+ /// Main savepoint reached
+ upgrade_main_savepoint($result, 2007101506);
+ }
+
return $result;
}
Index: lib/db/install.xml
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v
retrieving revision 1.136
diff -u -r1.136 install.xml
--- lib/db/install.xml 8 Nov 2007 02:01:34 -0000 1.136
+++ lib/db/install.xml 20 Dec 2007 14:05:27 -0000
@@ -1,5 +1,5 @@
-
@@ -419,12 +419,12 @@
-
+
-
+
@@ -1516,8 +1516,9 @@
-
-
+
+
+
@@ -1525,7 +1526,7 @@
-
+
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 20 Dec 2007 14:05:24 -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: version.php
===================================================================
RCS file: /cvsroot/moodle/moodle/version.php,v
retrieving revision 1.571
diff -u -r1.571 version.php
--- version.php 21 Nov 2007 07:53:42 -0000 1.571
+++ version.php 20 Dec 2007 14:05:23 -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 = 2007101504; // YYYYMMDD = date
+ $version = 2007101506; // 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.977
diff -u -r1.977 moodlelib.php
--- lib/moodlelib.php 17 Dec 2007 23:44:25 -0000 1.977
+++ lib/moodlelib.php 20 Dec 2007 14:05:26 -0000
@@ -234,6 +234,7 @@
* PAGE_COURSE_VIEW is a definition of a page type. For more information on the page class see moodle/lib/pagelib.php.
*/
define('PAGE_COURSE_VIEW', 'course-view');
+define('PAGE_MOD_VIEW', 'mod-view');
/// Debug levels ///
/** no warnings at all */
@@ -611,11 +612,17 @@
global $CFG;
if (empty($plugin)) {
- $CFG->$name = $value; // So it's defined for this invocation at least
+ if (!array_key_exists($name, $CFG->config_php_settings)) {
+ // So it's defined for this invocation at least
+ if (is_null($value)) {
+ unset($CFG->$name);
+ } else {
+ $CFG->$name = (string)$value; // settings from db are always strings
+ }
+ }
if (get_field('config', 'name', 'name', $name)) {
if ($value===null) {
- unset($CFG->$name);
return delete_records('config', 'name', $name);
} else {
return set_field('config', 'value', addslashes($value), 'name', $name);
@@ -697,14 +704,9 @@
foreach ($configs as $config) {
if (!isset($localcfg[$config->name])) {
$localcfg[$config->name] = $config->value;
- } else {
- if ($localcfg[$config->name] != $config->value ) {
- // complain if the DB has a different
- // value than config.php does
- error_log("\$CFG->{$config->name} in config.php ({$localcfg[$config->name]}) overrides database setting ({$config->value})");
}
+ // do not complain anymore if config.php overrides settings from db
}
- }
$localcfg = (object)$localcfg;
return $localcfg;
@@ -1874,12 +1876,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'));
}
@@ -1891,7 +1893,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
@@ -1900,14 +1902,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)) {
@@ -1922,7 +1924,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");
@@ -1970,7 +1972,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
@@ -3030,7 +3032,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.
*
@@ -3042,7 +3044,7 @@
*/
function complete_user_login($user) {
global $CFG, $USER;
-
+
$USER = $user; // should not be needed, but cover for legacy code
update_user_login_times();
@@ -3541,6 +3543,11 @@
/// 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);
+ notify("$strdeleted course tags");
+
return $result;
}
@@ -4343,7 +4350,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;
@@ -4357,20 +4364,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) {
@@ -4378,7 +4385,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) {
@@ -4388,7 +4395,7 @@
}
}
}
- }
+ }
}
} else {
notify("$rootdir does not exist!");
@@ -6357,7 +6364,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) {
@@ -6369,7 +6376,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);
@@ -6425,7 +6432,7 @@
$truncate .= $line_matchings[2];
$total_length += $content_length;
}
-
+
// if the maximum length is reached, get off the loop
if($total_length >= $ideal) {
break;
@@ -6446,7 +6453,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.
';
+echo $outstr;
+
+print_footer();
+?>
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/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: 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/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: 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,443 @@
+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');
+ // 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) {
+ $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 because rsslib needs updating to accept dc/cc input before this can work.
+ */
+/*
+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
+ *
+ * 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: 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.
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 = '