diff --git a/blocks/tags/block_tags.php b/blocks/tags/block_tags.php index 0b21493b171..4aff6fc9fea 100644 --- a/blocks/tags/block_tags.php +++ b/blocks/tags/block_tags.php @@ -2,8 +2,12 @@ class block_tags extends block_base { function init() { - $this->version = 2007101509; + $this->version = 2008063001; $this->title = get_string('blocktagstitle', 'tag'); + // the cron function goes through all users, so only do daily + // (this creates rss feeds for personal course tags) + // removed until rsslib supports dc/cc + // $this->cron = 60*60*24; } function instance_allow_multiple() { @@ -11,7 +15,7 @@ class block_tags extends block_base { } function has_config() { - return false; + return true; } function applicable_formats() { @@ -61,7 +65,253 @@ class block_tags extends block_base { require_once($CFG->dirroot.'/tag/lib.php'); - $this->content->text = tag_print_cloud($this->config->numberoftags, true); + if (empty($CFG->block_tags_showcoursetags) or !$CFG->block_tags_showcoursetags) { + + $this->content->text = tag_print_cloud($this->config->numberoftags, true); + + // start of show course tags section + } else { + + require_once($CFG->dirroot.'/tag/coursetagslib.php'); + + // Permissions and page awareness + $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); + $isguest = has_capability('moodle/legacy:guest', $sitecontext, $USER->id, false); + $loggedin = isloggedin() && !$isguest; + $coursepage = $canedit = false; + $coursepage = (isset($COURSE->id) && $COURSE->id != SITEID); + $mymoodlepage = strpos($_SERVER['PHP_SELF'], 'my') > 0 ? true : false; + $sitepage = (isset($COURSE->id) && $COURSE->id == SITEID && !$mymoodlepage); + $coursecontext = get_context_instance(CONTEXT_COURSE, $COURSE->id); + if ($coursepage) { + $canedit = has_capability('moodle/tag:create', $sitecontext); + } + + // Check rss feed - temporarily removed until Dublin Core tags added + // provides a feed of users course tags for each unit they have tagged + //$rssfeed = ''; + //if (file_exists($CFG->dataroot.'/'.SITEID.'/usertagsrss/'.$USER->id.'/user_unit_tags_rss.xml')) { + // $rssfeed = '/file.php/'.SITEID.'/usertagsrss/'.$USER->id.'/user_unit_tags_rss.xml'; + //} + + // Language strings + $tagslang = 'block_tags'; + + // DB hits to get groups of marked up tags (if available) + //TODO check whether time limited personal tags are required + $numoftags = $this->config->numberoftags; + $sort = 'name'; + $alltags = $officialtags = $coursetags = $commtags = $mytags = $coursetagdivs = $courseflag = ''; + if ($sitepage or $coursepage) { + $alltags = coursetag_print_cloud(coursetag_get_all_tags($sort, $this->config->numberoftags), true); + $officialtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), true); + $commtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', $numoftags, $sort), true); + if ($loggedin) { + $mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', $numoftags, $sort), true); + } + } + if ($coursepage) { + $coursetags = coursetag_print_cloud(coursetag_get_tags($COURSE->id, 0, '', $numoftags, $sort), true); + if (!$coursetags) $coursetags = get_string('notagsyet', $tagslang); + $courseflag = '&courseid='.$COURSE->id; + } + if ($mymoodlepage) { + $mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', $numoftags, $sort), true); + $officialtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', $numoftags, $sort), true); + $commtags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', $numoftags, $sort), true); + } + + // Prepare the divs and javascript that displays the groups of tags (and which is displayed first) + $moretags = $CFG->wwwroot.'/tag/coursetags_more.php'; + $moretagstitle = get_string('moretags', $tagslang); + $moretagsstring = get_string('more', $tagslang); + $displayblock = 'style="display:block"'; + $displaynone = 'style="display:none"'; //only one div created below will be displayed at a time + if ($alltags) { + if ($sitepage) { + $display = $displayblock; + } else { + $display = $displaynone; + } + $alltagscontent = ' +
'. + get_string("alltags", $tagslang). + '
'.$alltags.'
+ +
'; + $coursetagdivs .= '"f_alltags", '; + } + if ($mytags) { + if ($mymoodlepage) { + $display = $displayblock; + } else { + $display = $displaynone; + } + $mytagscontent = ' +
'; + /*if ($rssfeed) { // - temporarily removed + $mytagscontent .= link_to_popup_window( + $rssfeed, $name='popup', + 'User Unit Tags RSS My Unit Tags RSS', + $height=600, $width=800, + $title='My Unit Tags RSS', $options='menubar=1,scrollbars,resizable', $return=true).'
'; + }*/ + $mytagscontent .= + get_string('mytags', $tagslang). + '
'.$mytags.'
+ +
'; + $coursetagdivs .= '"f_mytags", '; + } + if ($officialtags) { + if ($mytags or $alltags) { + $display = $displaynone; + } else { + $display = $displayblock; + } + $officialtagscontent = ' +
'. + get_string('officialtags', $tagslang). + '
'.$officialtags.'
+ +
'; + $coursetagdivs .= '"f_officialtags", '; + } + if ($coursetags) { + if ($coursepage) { + $display = $displayblock; + } else { + $display = $displaynone; + } + $coursetagscontent = ' +
'. + get_string('coursetags', $tagslang). + '
'.$coursetags.'
+ +
'; + $coursetagdivs .= '"f_coursetags", '; + } + if ($commtags) { + $commtagscontent = ' +
'. + get_string('communitytags', $tagslang). + '
'.$commtags.'
+ +
'; + $coursetagdivs .= '"f_commtags", '; + } + // Tidy up the end of a javascript array and add javascript + $coursetagdivs = rtrim($coursetagdivs, ', '); + $this->content->text .= coursetag_get_jscript($coursetagdivs); + + // Add the divs (containing the tags) to the block's content + if ($alltags) { $this->content->text .= $alltagscontent; } + if ($mytags) { $this->content->text .= $mytagscontent; } + if ($officialtags) { $this->content->text .= $officialtagscontent; } + if ($coursetags) { $this->content->text .= $coursetagscontent; } + if ($commtags) { $this->content->text .= $commtagscontent; } + + // add the input form section (allowing a user to tag the current course) and navigation, or loggin message + if ($loggedin) { + // only show the input form on course pages for those allowed (or not barred) + if ($coursepage && $canedit) { + //$this->content->footer .= coursetag_get_jscript(); + $tagthisunit = get_string('tagthisunit', $tagslang); + $buttonadd = get_string('add', $tagslang); + $arrowtitle = get_string('arrowtitle', $tagslang); + $coursetaghelpbutton = helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE); + $this->content->footer .= << +
+
+ + +
+
+
+
+
+ +
+
+ +
+
+ + enter + +
+
+
+ + $coursetaghelpbutton +
+
+
+EOT; + // add the edit link + $this->content->footer .= ' +
+ '.get_string('edittags', $tagslang).' +
'; + } + + // Navigation elements at the bottom of the block + // show the alternative displays options if available + if ($mytags or $officialtags or $commtags or $coursetags) { + $this->content->footer .= ''; + } + // This section sets the order of the links + $coursetagslinks = array(); + if ($mytags) { + $coursetagslinks['my'] = array('title'=>get_string('mytags2', $tagslang), + 'onclick'=>'f_mytags', + 'text'=>get_string('mytags1', $tagslang)); + } + // because alltags is always present, only show link if there is something else as well + if ($alltags and ($mytags or $officialtags or $commtags or $coursetags)) { + $coursetagslinks['all'] = array('title'=>get_string('alltags2', $tagslang), + 'onclick'=>'f_alltags', + 'text'=>get_string('alltags1', $tagslang)); + } + if ($officialtags) { + $coursetagslinks['off'] = array('title'=>get_string('officialtags2', $tagslang), + 'onclick'=>'f_officialtags', + 'text'=>get_string('officialtags1', $tagslang)); + } + //if ($commtags) { + // $coursetagslinks['com'] = array('title'=>get_string('communitytags2', $tagslang), + // 'onclick'=>'f_commtags', + // 'text'=>get_string('communitytags1', $tagslang)); + //} + if ($coursetags) { + $coursetagslinks['crs'] = array('title'=>get_string('coursetags2', $tagslang), + 'onclick'=>'f_coursetags', + 'text'=>get_string('coursetags1', $tagslang)); + } + $this->content->footer .= coursetag_get_jscript_links($coursetagslinks); + + } else { + //if not logged in + $this->content->footer = '
'.get_string('please', $tagslang).' + '.get_string('login', $tagslang).' + '.get_string('tagunits', $tagslang); + } + } + // end of show course tags section return $this->content; } @@ -81,6 +331,21 @@ class block_tags extends block_base { notice(get_string('blockconfigbad'), str_replace('blockaction=', 'dummy=', qualified_me())); } } -} + /* + * function removed until rsslib supports dc/cc + */ + /* + function cron() { + if (SHOWCOURSETAGS) { + global $CFG; + require_once($CFG->dirroot.'/tag/coursetagslib.php'); + return coursetag_rss_feeds(); + } else { + return TRUE; +} + } + */ + +} ?> diff --git a/blocks/tags/coursetags.js b/blocks/tags/coursetags.js new file mode 100644 index 00000000000..de4f1780c21 --- /dev/null +++ b/blocks/tags/coursetags.js @@ -0,0 +1,62 @@ +/** + * coursetags.js + * @author j.beedell@open.ac.uk July07 + * + * getKeywords modified from an original script (Auto Complete Textfield) + * from The JavaScript Source http://javascript.internet.com + * originally created by: Timothy Groves http://www.brandspankingnew.net/ + */ + + +function ctags_show_div(mydiv) { + for(x in coursetagdivs) { + if(mydiv == coursetagdivs[x]) { + document.getElementById(coursetagdivs[x]).style.display="block"; + } else { + document.getElementById(coursetagdivs[x]).style.display="none"; + } + } + return false; +} + +var sug = ""; +var sug_disp = ""; + +function ctags_getKeywords() { + /* + // This 'workaround' removing the xhtml strict form autocomplete="off" needs to + // be added to the body onload() script to work - but decided not to include + // (having the browser list might help with screen readers more than this script) + // document.forms['coursetag'].setAttribute("autocomplete", "off"); + */ + var input = document.forms['coursetag'].coursetag_new_tag.value; + var len = input.length; + sug_disp = ""; sug = ""; + + if (input.length) { + for (ele in coursetag_tags) + { + if (coursetag_tags[ele].substr(0,len).toLowerCase() == input.toLowerCase()) + { + sug_disp = input + coursetag_tags[ele].substr(len); + sug = coursetag_tags[ele]; + break; + } + } + } + document.forms['coursetag'].coursetag_sug_keyword.value = sug_disp; + if (!sug.length || input == sug_disp) + document.getElementById('coursetag_sug_btn').style.display = "none"; + else + document.getElementById('coursetag_sug_btn').style.display = "block"; +} + +function ctags_setKeywords() { + document.forms['coursetag'].coursetag_new_tag.value = sug; + ctags_hideSug(); +} + +function ctags_hideSug() { + document.forms['coursetag'].coursetag_sug_keyword.value = ""; + document.getElementById('coursetag_sug_btn').style.display = "none"; +} diff --git a/blocks/tags/settings.php b/blocks/tags/settings.php new file mode 100644 index 00000000000..3e5bdea81bb --- /dev/null +++ b/blocks/tags/settings.php @@ -0,0 +1,6 @@ +add(new admin_setting_configcheckbox('block_tags_showcoursetags', get_string('showcoursetags', 'block_tags'), + get_string('showcoursetagsdef', 'block_tags'), 0)); + +?> diff --git a/blocks/tags/styles.php b/blocks/tags/styles.php new file mode 100644 index 00000000000..ef743369225 --- /dev/null +++ b/blocks/tags/styles.php @@ -0,0 +1,116 @@ +/* + * CSS for course tags + * @author j.beedell@open.ac.uk July07 + * + * Styles for block_tags.php + */ + +.coursetag_form_wrapper { + margin: auto; + width: 13em; +} + +.coursetag_form_positioner { + position: relative; + margin: 5px 0 0 0; + height: 25px; +} + +.coursetag_form_input1 { + position: absolute; + top: 0; + left: 0; + z-index: 1; +} + +.coursetag_form_input2 { + position: absolute; + top: 0; + left: 0; + z-index: 2; +} + +.coursetag_form_input3 { + position: absolute; + top: 3px; + left: 12.8em; + display: none; +} + +.coursetag_form_input1a { + background-color: white; + border: 1px solid #999; + width: 12em; + padding: 2px; +} + +.coursetag_form_input2a { + background: transparent; + color: #669954; + border: 1px solid #999; + width: 12em; + padding: 2px; +} + +.coursetag_morelink { + float: right; + font-size: 0.8em; + margin: -5px 5px 5px 0; +} + +.coursetag_list { + padding-top: 4px; +} + +/* Styles for edit_tags.php */ + +.coursetag_edit_centered { + position: relative; + width: 600px; + margin: 20px auto; +} + +.coursetag_edit_row { + margin: 5px 0 5px 0; + height: 30px; +} + +.coursetag_edit_left { + position: relative; + float: left; + padding: 3px 5px; +} + +.coursetag_edit_right { + position: relative; + float: left; + padding: 3px 0px; +} + +.coursetag_edit_input3 { + position: relative; + left: 10.5em; + display: none; +} + +/* Styles for more_tags.php */ + +.coursetag_more_title { + margin: 30px 30px -25px 30px; +} + +.coursetag_more_tags { + margin: 30px; +} + +.coursetag_more_large { + font-size: 120% +} + +.coursetag_more_small { + font-size: 80% +} + +.coursetag_more_link { + font-size: 80%; +} diff --git a/course/lib.php b/course/lib.php index 562f9863dc3..a6cb74bab79 100644 --- a/course/lib.php +++ b/course/lib.php @@ -40,6 +40,9 @@ function make_log_url($module, $url) { case 'upload': return $url; break; + case 'coursetags': + return '/'.$url; + break; case 'library': case '': return '/'; diff --git a/lang/en_utf8/block_tags.php b/lang/en_utf8/block_tags.php new file mode 100644 index 00000000000..559fdf1cd5a --- /dev/null +++ b/lang/en_utf8/block_tags.php @@ -0,0 +1,66 @@ + diff --git a/lang/en_utf8/tag.php b/lang/en_utf8/tag.php index a9976fb937e..256291ebcb4 100644 --- a/lang/en_utf8/tag.php +++ b/lang/en_utf8/tag.php @@ -10,12 +10,16 @@ $string['changetype'] = 'Change tag type'; $string['description'] = 'Description'; $string['delete'] = 'Delete'; $string['deleted'] = 'Deleted'; +$string['deletedcoursetags'] = 'Deleted - course tags'; $string['edittag'] = 'Edit this tag'; +$string['errordeleting'] = 'Error deleting tag with id $a, please report to your system administrator.'; +$string['errortagfrontpage'] = 'Tagging the site main page is not allowed'; +$string['errorupdatingrecord'] = 'Error updating tag record'; $string['flag'] = 'Flag'; $string['flagasinappropriate'] = 'Flag as inappropriate'; $string['helprelatedtags'] = 'Comma separated related tags'; $string['id'] = 'id'; -$string['relatedblogs'] = 'Recent blog entries with this tag'; +$string['relatedblogs'] = 'Most recent blog entries tagged with \"$a\"'; $string['managetags'] = 'Manage tags'; $string['name'] = 'Tag name'; $string['namesalreadybeeingused'] = 'Tag names already being used'; @@ -30,8 +34,10 @@ $string['removetagfrommyinterests'] = 'Remove \"$a\" from my interests'; $string['responsiblewillbenotified'] = 'The person responsible will be notified'; $string['resetflag'] = 'Reset flag'; $string['reset'] = 'Reset'; +$string['rsstitle'] = 'Course Tags RSS Feed for user: $a'; +$string['rssdesc'] = 'This RSS feed was automatically generated by Moodle and contains user generated tags for courses.'; $string['search'] = 'Search'; -$string['seeallblogs'] = 'See all blogs with this tag'; +$string['seeallblogs'] = 'See all blog entries tagged with \"$a\"...'; $string['searchresultsfor'] = 'Search results for \"$a\"'; $string['searchtags'] = 'Search tags'; $string['select'] = 'Select'; @@ -40,9 +46,9 @@ $string['tag'] = 'Tag'; $string['tagtype'] = 'Tag type'; $string['tagtype_official'] = 'Official'; $string['tagtype_default'] = 'Default'; +$string['tagindex_coursetitle'] = 'Courses tagged with \"$a\"'; $string['tags'] = 'Tags'; $string['tagsaredisabled'] = 'Tags are disabled'; -$string['thingstaggedwith'] = '$a->count things tagged with \"$a->name\"'; $string['thistaghasnodesc'] = 'This tag currently has no description.'; $string['timemodified'] = 'Modified'; $string['typechanged'] = 'Tag type changed'; diff --git a/lib/db/install.xml b/lib/db/install.xml index d0d1168a97d..3668dd7229d 100644 --- a/lib/db/install.xml +++ b/lib/db/install.xml @@ -1503,8 +1503,9 @@ - - + + + @@ -1512,7 +1513,7 @@ - + diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index b7255b4b5dc..4c20ff283b6 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -134,6 +134,28 @@ function xmldb_main_upgrade($oldversion=0) { upgrade_main_savepoint($result, 2008051203); } + if ($result && $oldversion < 2008063001) { + // table to be modified + $table = new xmldb_table('tag_instance'); + // add field + $field = new xmldb_field('tiuserid'); + if (!$dbman->field_exists($table, $field)) { + $field->set_attributes(XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, 0, 'itemid'); + $dbman->add_field($table, $field); + } + // modify index + $index = new xmldb_index('itemtype-itemid-tagid'); + $index->set_attributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid')); + $dbman->drop_index($table, $index); + $index = new xmldb_index('itemtype-itemid-tagid-tiuserid'); + $index->set_attributes(XMLDB_INDEX_UNIQUE, array('itemtype', 'itemid', 'tagid', 'tiuserid')); + $dbman->add_index($table, $index); + + /// Main savepoint reached + upgrade_main_savepoint($result, 2008063001); + } + + /* * TODO: * drop adodb_logsql table and create a new general sql log table diff --git a/lib/moodlelib.php b/lib/moodlelib.php index 8acd3d621f5..62d065216b5 100644 --- a/lib/moodlelib.php +++ b/lib/moodlelib.php @@ -154,8 +154,8 @@ define('PARAM_FILE', 0x0010); define('PARAM_TAG', 0x0011); /** - * PARAM_TAGLIST - list of tags separated by commas (interests, blogs, etc.) - */ + * PARAM_TAGLIST - list of tags separated by commas (interests, blogs, etc.) + */ define('PARAM_TAGLIST', 0x0012); /** @@ -2817,7 +2817,7 @@ function update_user_record($username, $authplugin) { } /** - * will truncate userinfo as it comes from auth_get_userinfo (from external auth) + * will truncate userinfo as it comes from auth_get_userinfo (from external auth) * which may have large fields */ function truncate_userinfo($info) { @@ -3543,6 +3543,10 @@ function remove_course_contents($courseid, $showfeedback=true) { remove_course_grades($courseid, $showfeedback); remove_grade_letters($context, $showfeedback); +/// Delete course tags + require_once($CFG->dirroot.'/tag/coursetagslib.php'); + coursetag_delete_course_tags($course->id, $showfeedback); + return $result; } diff --git a/tag/coursetags_add.php b/tag/coursetags_add.php new file mode 100644 index 00000000000..6154c9a21cd --- /dev/null +++ b/tag/coursetags_add.php @@ -0,0 +1,34 @@ +dirroot.'/tag/coursetagslib.php'); + + if ($courseid > 0 and $userid > 0) { + $myurl = 'tag/search.php'; + $keywords = explode(',', $keyword); + coursetag_store_keywords($keywords, $courseid, $userid, 'default', $myurl); + } +} + +// send back to originating page, where the new tag will be visible in the block +if ($courseid > 0) { + $myurl = $CFG->wwwroot.'/course/view.php?id='.$courseid; +} else { + $myurl = $CFG->wwwroot.'/'; +} + +redirect($myurl); + +?> diff --git a/tag/coursetags_edit.php b/tag/coursetags_edit.php new file mode 100644 index 00000000000..68375cbeb86 --- /dev/null +++ b/tag/coursetags_edit.php @@ -0,0 +1,177 @@ +dirroot.'/tag/coursetagslib.php'); +require_once($CFG->dirroot.'/tag/lib.php'); + +$courseid = optional_param('courseid', 0, PARAM_INT); +$keyword = optional_param('coursetag_new_tag', '', PARAM_TEXT); +$deltag = optional_param('del_tag', 0, PARAM_INT); + +if ($courseid != SITEID) { + if (! ($course = $DB->get_record('course', array('id' => $courseid), '*')) ) { + print_error('invalidcourse'); + } +} else { + print_error('errortagfrontpage', 'tag'); +} + +// Permissions +$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); +require_login($course->id); +$canedit = has_capability('moodle/tag:create', $sitecontext); + +// Language strings +$tagslang = 'block_tags'; + +// Store data +if ($data = data_submitted()) { + if (confirm_sesskey() and $courseid > 0 and $USER->id > 0 and $canedit) { + // store personal tag + if (trim(strip_tags($keyword))) { + $myurl = 'tag/search.php'; + $keywords = explode(',', $keyword); + try { + coursetag_store_keywords($keywords, $courseid, $USER->id, 'default', $myurl); + } + catch (Exception $e) { + notice($e->getmessage()); + } + } + // delete personal tag + if ($deltag > 0) { + coursetag_delete_keyword($deltag, $USER->id, $courseid); + } + } +} + +// The title and breadcrumb +$title = get_string('edittitle', $tagslang); +$coursefullname = format_string($course->fullname); +$courseshortname = format_string($course->shortname); +//$navigation[] = array('name' => $coursefullname, 'link' => $CFG->wwwroot.'/course/view.php?id='.$courseid, 'type' => 'misc'); +$navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc'); +$nav = build_navigation($navigation); +print_header_simple($title, '', $nav, '', '', false); + + // Print personal tags for all courses + $title = get_string('edittitle', $tagslang); + print_heading($title, 'center'); + + $mytags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default'), true); + $outstr = ' +
+
+ '.get_string('editmytags', $tagslang).' +
+
'; + + if ($mytags) { + $outstr .= $mytags; + } else { + $outstr .= get_string('editnopersonaltags', $tagslang); + } + + $outstr .= ' +
+
'; + echo $outstr; + + // Personal tag editing + if ($canedit) { + $title = get_string('editmytagsfor', $tagslang, '"'.$coursefullname.' ('.$courseshortname.')"'); + print_heading($title); + + // Deletion here is open to the users own tags for this course only + $selectoptions = ''; + $coursetabs = ''; + if ($options = coursetag_get_records($courseid, $USER->id)) { + $coursetabs = '"'; + foreach ($options as $option) { + $selectoptions .= ''; + $coursetabs .= $option->rawname . ', '; + } + $coursetabs = rtrim($coursetabs, ', '); + $coursetabs .= '"'; + } + if ($coursetabs) { + $outstr = ' +
+ '.get_string('editthiscoursetags', $tagslang, $coursetabs).' +
'; + } else { + $outstr = ' +
+ '.get_string('editnopersonaltags', $tagslang).' +
'; + } + + // Print the add and delete form + $script = coursetag_get_jscript(); + $addtagshelp = helpbutton('addtags', 'adding tags', $tagslang, TRUE, FALSE, '', TRUE); + $edittagthisunit = get_string('edittagthisunit', $tagslang); + $arrowtitle = get_string('arrowtitle', $tagslang); + $outstr .= << +
+ + +
+
+
+
+ $addtagshelp$edittagthisunit +
+
+
+ +
+
+ +
+
+ + enter + +
+
+
+EOT; + if ($coursetabs) { + $deletetagshelp = helpbutton('deletetags', 'deleting tags', $tagslang, TRUE, FALSE, '', TRUE); + $editdeletemytag = get_string('editdeletemytag', $tagslang); + $outstr .= << +
+ $deletetagshelp$editdeletemytag +
+
+ +
+
+EOT1; + } + $submitstr = get_string('submit'); + $outstr .= << +
+ +
+ + +EOT2; + echo $outstr; + } + +print_footer(); +?> diff --git a/tag/coursetags_more.php b/tag/coursetags_more.php new file mode 100644 index 00000000000..22cab395eab --- /dev/null +++ b/tag/coursetags_more.php @@ -0,0 +1,187 @@ +dirroot.'/tag/coursetagslib.php'); +require_once($CFG->dirroot.'/tag/lib.php'); + +$sort = optional_param('sort', 'alpha', PARAM_TEXT); //alpha, date or popularity +$show = optional_param('show', 'all', PARAM_TEXT); //all, my, official, community or course +$courseid = optional_param('courseid', 0, PARAM_INT); + +// Some things require logging in +if ($CFG->forcelogin or $show == 'my') { + require_login(); +} + +// Permissions +$sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID); +$isguest = has_capability('moodle/legacy:guest', $sitecontext, $USER->id, false); +$loggedin = isloggedin() && !$isguest; + +// Course check +if ($courseid) { + if (!($course = $DB->get_record('course', array('id'=>$courseid)))) { + $courseid = 0; + } + if ($courseid == SITEID) $courseid = 0; +} + +// Language strings +$tagslang = 'block_tags'; +$title = get_string('moretitle', $tagslang); +$link1 = get_string('moreshow', $tagslang); +$link2 = get_string('moreorder', $tagslang); +$showalltags = get_string('moreshowalltags', $tagslang); +$showofficialtags = get_string('moreshowofficialtags', $tagslang); +$showmytags = get_string('moreshowmytags', $tagslang); +$showcommtags = get_string('moreshowcommtags', $tagslang); +$orderalpha = get_string('moreorderalpha', $tagslang); +$orderdate = get_string('moreorderdate', $tagslang); +$orderpop = get_string('moreorderpop', $tagslang); +$welcome = get_string('morewelcome', $tagslang); + +// The title and breadcrumb +if ($courseid) { + $navigation[] = array('name' => format_string($course->shortname), 'link' => $CFG->wwwroot.'/course/view.php?id='.$courseid, 'type' => 'misc'); + $navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc'); +} else { + $navigation[] = array('name' => $title, 'link' => null, 'type' => 'misc'); +} +$nav = build_navigation($navigation); +print_header_simple($title, '', $nav, '', '', false); +print_heading($title, 'centre'); + +// Prepare data for tags +$courselink = ''; +if ($courseid) { $courselink = '&courseid='.$courseid; } +$myurl = $CFG->wwwroot.'/tag/coursetags_more.php'; +$myurl2 = $CFG->wwwroot.'/tag/coursetags_more.php?show='.$show; + +// Course tags +if ($show == 'course' and $courseid) { + + if ($sort == 'popularity') { + $tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'popularity'), true, 200, 90); + } else if ($sort == 'date') { + $tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'timemodified'), true, 200, 90); + } else { + $tags = coursetag_print_cloud(coursetag_get_tags($courseid, 0, '', 0, 'name'), true, 200, 90); + } + +// My tags +} else if ($show == 'my' and $loggedin) { + + if ($sort == 'popularity') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'popularity'), true, 200, 90); + } else if ($sort == 'date') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'timemodified'), true, 200, 90); + } else { + $tags = coursetag_print_cloud(coursetag_get_tags(0, $USER->id, 'default', 0, 'name'), true, 200, 90); + } + +// Official course tags +} else if ($show == 'official') { + + if ($sort == 'popularity') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'popularity'), true, 200, 90); + } else if ($sort == 'date') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'timemodified'), true, 200, 90); + } else { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'official', 0, 'name'), true, 200, 90); + } + +// Community (official and personal together) also called user tags +} else if ($show == 'community') { + + if ($sort == 'popularity') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'popularity'), true, 200, 90); + } else if ($sort == 'date') { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'timemodified'), true, 200, 90); + } else { + $tags = coursetag_print_cloud(coursetag_get_tags(0, 0, 'default', 0, 'name'), true, 200, 90); + } + +// All tags for courses and blogs and any thing else tagged - the fallback default ($show == all) +} else { + + $subtitle = $showalltags; + if ($sort == 'popularity') { + $tags = coursetag_print_cloud(coursetag_get_all_tags('popularity'), true, 200, 90); + } else if ($sort == 'date') { + $tags = coursetag_print_cloud(coursetag_get_all_tags('timemodified'), true, 200, 90); + } else { + $tags = coursetag_print_cloud(coursetag_get_all_tags('name'), true, 200, 90); + } + +} + +// Prepare the links for the show and order lines +if ($show == 'all') { + $link1 .= ''.$showalltags.''; +} else { + $link1 .= ''.$showalltags.''; +} +//if ($show == 'official') { //add back in if you start to use official course tags +// $link1 .= ' | '.$showofficialtags.''; +//} else { +// $link1 .= ' | '.$showofficialtags.''; +//} +if ($show == 'community') { + $link1 .= ' | '.$showcommtags.''; +} else { + $link1 .= ' | '.$showcommtags.''; +} +if ($loggedin) { + if ($show == 'my') { + $link1 .= ' | '.$showmytags.''; + } else { + $link1 .= ' | '.$showmytags.''; + } +} +if ($courseid) { + if ($show == 'course') { + $link1 .= ' | '.get_string('moreshowcoursetags', $tagslang, $course->fullname).''; + } else { + $link1 .= ' | '.get_string('moreshowcoursetags', $tagslang, $course->fullname).''; + } +} +if ($sort == 'alpha') { + $link2 .= ''.$orderalpha.' | '; +} else { + $link2 .= ''.$orderalpha.' | '; +} +if ($sort == 'popularity') { + $link2 .= ''.$orderpop.' | '; +} else { + $link2 .= ''.$orderpop.' | '; +} +if ($sort == 'date') { + $link2 .= ''.$orderdate.''; +} else { + $link2 .= ''.$orderdate.''; +} + +// Prepare output +$fclass = ''; +// make the tags larger when there are not so many +if (strlen($tags) < 10000) { $fclass = 'coursetag_more_large'; } +$outstr = ' +
+
'.$welcome. + helpbutton('usingtags', 'using tags', $tagslang, TRUE, FALSE, '', TRUE).' +
+ + +
+
'. + $tags.' +
'; +echo $outstr; + +print_footer(); +?> diff --git a/tag/coursetagslib.php b/tag/coursetagslib.php new file mode 100644 index 00000000000..cc898ba94bf --- /dev/null +++ b/tag/coursetagslib.php @@ -0,0 +1,698 @@ +dirroot.'/tag/lib.php'; + +/** + * Returns an ordered array of tags associated with visible courses + * (boosted replacement of get_all_tags() allowing association with user and tagtype). + * + * @uses $CFG + * @param int $courseid, a 0 will return all distinct tags for visible courses + * @param int $userid optional the user id, a default of 0 will return all users tags for the course + * @param string $tagtype optional 'official' or 'default', empty returns both tag types + * @param int $numtags optional number of tags to display, default of 80 is set in the block, 0 returns all + * @param string $sort optional selected sorting, default is alpha sort (name) also timemodified or popularity + * @return array + */ +function coursetag_get_tags($courseid, $userid=0, $tagtype='', $numtags=0, $sort='name') { + + global $CFG, $DB; + + // get visible course ids + $courselist = array(); + if ($courseid === 0) { + if ($courses = $DB->get_records_select('course', 'visible=1 AND category>0', null, '', 'id')) { + foreach ($courses as $key => $value) { + $courselist[] = $key; + } + } + } + + // get tags from the db ordered by highest count first + $params = array(); + $sql = "SELECT id as tkey, name, id, tagtype, rawname, f.timemodified, flag, count + FROM {tag} t, + (SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count + FROM {tag_instance} + WHERE itemtype = 'course' "; + + if ($courseid > 0) { + $sql .= " AND itemid = :courseid "; + $params['courseid'] = $courseid; + } else { + if (!empty($courselist)) { + list($usql, $uparams) = $DB->get_in_or_equal($courselist, SQL_PARAMS_NAMED); + $sql .= "AND itemid $usql "; + $params = $params + $uparams; + } + } + + if ($userid > 0) { + $sql .= " AND tiuserid = :userid "; + $params['userid'] = $userid; + } + + $sql .= " GROUP BY tagid) f + WHERE t.id = f.tagid "; + if ($tagtype != '') { + $sql .= "AND tagtype = :tagtype "; + $params['tagtype'] = $tagtype; + } + $sql .= "ORDER BY count DESC, name ASC"; + + // limit the number of tags for output + if ($numtags == 0) { + $tags = $DB->get_records_sql($sql, $params); + } else { + $tags = $DB->get_records_sql($sql, $params, 0, $numtags); + } + + // prepare the return + $return = array(); + if ($tags) { + // sort the tag display order + if ($sort != 'popularity') { + $CFG->tagsort = $sort; + usort($tags, "coursetag_sort"); + } + // avoid print_tag_cloud()'s ksort upsetting ordering by setting the key here + foreach ($tags as $value) { + $return[] = $value; + } + } + + return $return; + +} + +/** + * Returns an ordered array of tags + * (replaces popular_tags_count() allowing sorting). + * + * @uses $CFG + * @param string $sort optional selected sorting, default is alpha sort (name) also timemodified or popularity + * @param int $numtags optional number of tags to display, default of 20 is set in the block, 0 returns all + * @return array + */ +function coursetag_get_all_tags($sort='name', $numtags=0) { + + global $CFG, $DB; + + // note that this selects all tags except for courses that are not visible + $sql = "SELECT id, name, id, tagtype, rawname, f.timemodified, flag, count + FROM {tag} t, + (SELECT tagid, MAX(timemodified) as timemodified, COUNT(id) as count + FROM {tag_instance} WHERE tagid NOT IN + (SELECT tagid FROM {tag_instance} ti, {course} c + WHERE c.visible = 0 + AND ti.itemtype = 'course' + AND ti.itemid = c.id) + GROUP BY tagid) f + WHERE t.id = f.tagid + ORDER BY count DESC, name ASC"; + if ($numtags == 0) { + $tags = $DB->get_records_sql($sql); + } else { + $tags = $DB->get_records_sql($sql, null, 0, $numtags); + } + + $return = array(); + if ($tags) { + if ($sort != 'popularity') { + $CFG->tagsort = $sort; + usort($tags, "coursetag_sort"); + } + foreach ($tags as $value) { + $return[] = $value; + } + } + + return $return; +} + +/** + * Callback function for coursetag_get_tags() and coursetag_get_all_tags() only + * @uses $CFG + */ +function coursetag_sort($a, $b) { + // originally from block_blog_tags + global $CFG; + + // set up the variable $tagsort as either 'name' or 'timemodified' only, 'popularity' does not need sorting + if (empty($CFG->tagsort)) { + $tagsort = 'name'; + } else { + $tagsort = $CFG->tagsort; + } + + if (is_numeric($a->$tagsort)) { + return ($a->$tagsort == $b->$tagsort) ? 0 : ($a->$tagsort > $b->$tagsort) ? 1 : -1; + } elseif (is_string($a->$tagsort)) { + return strcmp($a->$tagsort, $b->$tagsort); + } else { + return 0; + } +} + +/** + * Prints a tag cloud + * + * @param array $tagcloud array of tag objects (fields: id, name, rawname, count and flag) + * @param int $max_size maximum text size, in percentage + * @param int $min_size minimum text size, in percentage + * @param $return if true return html string + */ +function coursetag_print_cloud($tagcloud, $return=false, $max_size=180, $min_size=80) { + + global $CFG; + + if (empty($tagcloud)) { + return; + } + + ksort($tagcloud); + + $count = array(); + foreach ($tagcloud as $key => $value) { + if(!empty($value->count)) { + $count[$key] = log10($value->count); + } else { + $count[$key] = 0; + } + } + + $max = max($count); + $min = min($count); + + $spread = $max - $min; + if (0 == $spread) { // we don't want to divide by zero + $spread = 1; + } + + $step = ($max_size - $min_size)/($spread); + + $systemcontext = get_context_instance(CONTEXT_SYSTEM); + $can_manage_tags = has_capability('moodle/tag:manage', $systemcontext); + + //prints the tag cloud + $output = '
    '; + foreach ($tagcloud as $key => $tag) { + + $size = $min_size + ((log10($tag->count) - $min) * $step); + $size = ceil($size); + + $style = 'style="font-size: '.$size.'%"'; + + if ($tag->count > 1) { + $title = 'title="'.s(get_string('thingstaggedwith','tag', $tag)).'"'; + } else { + $title = 'title="'.s(get_string('thingtaggedwith','tag', $tag)).'"'; + } + + $href = 'href="'.$CFG->wwwroot.'/tag/index.php?id='.$tag->id.'"'; + + //highlight tags that have been flagged as inappropriate for those who can manage them + $tagname = tag_display_name($tag); + if ($tag->flag > 0 && $can_manage_tags) { + $tagname = '' . tag_display_name($tag) . ''; + } + + $tag_link = '
  • '.$tagname.'
  • '; + + $output .= $tag_link; + + } + $output .= '
'."\n"; + + if ($return) { + return $output; + } else { + echo $output; + } +} + +/** + * Returns javascript for use in tags block and supporting pages + * @param string $coursetagdivs comma separated divs ids + * @uses $CFG + */ +function coursetag_get_jscript($coursetagdivs = '') { + + global $CFG, $DB; + + $tabscript = ''; + if ($coursetagdivs) { + $tabscript = 'var coursetagdivs = new Array('.$coursetagdivs.');'; + } + + $coursetags = $DB->get_records('tag', null, 'name ASC', 'name, id'); + $a = 0; + $coursetagscript = ''; + if (!empty($coursetags)) { + foreach ($coursetags as $key => $value) { + $coursetagscript .= "coursetag_tags[$a] = \"".addslashes_js($key)."\"; "; + $a++; + } + } + + $jserror1 = get_string('jserror1', 'block_tags'); + $jserror2 = get_string('jserror2', 'block_tags'); + + $inputscript = << 50) { + alert("$jserror1"); + return false; + //can't check this - unterminated string error } else if (val.indexOf("\\") > 0) { + } else if (val.indexOf("<") > 0) { + alert("$jserror2"); + return false; + } else if (val.indexOf(">") > 0) { + alert("$jserror2"); + return false; + } else { + return true; + } + } +EOT; + + $str = ' + + '; + + return $str; +} + +/** + * Returns javascript to create the links in the tag block footer. + */ +function coursetag_get_jscript_links($coursetagslinks) { + + $links = ''; + if (!empty($coursetagslinks)) { + $links .= '
'; + foreach ($coursetagslinks as $a) { + $links .= ''.$a['text'].' |'; + } + $links = addslashes_js(rtrim($links, '|')); + } + + $str = ' + '; + + return $str; +} + +/** + * Returns all tags created by a user for a course + * + * @uses $CFG + * @param int $courseid + * @param int $userid + */ +function coursetag_get_records($courseid, $userid) { + + global $CFG, $DB; + + $sql = "SELECT t.id, name, rawname + FROM {tag} t, {tag_instance} ti + WHERE t.id = ti.tagid + AND ti.tiuserid = :userid + AND ti.itemid = :courseid + ORDER BY name ASC"; + + return $DB->get_records_sql($sql, array('userid'=>$userid, 'courseid'=>$courseid)); +} + +/** + * Stores a tag for a course for a user + * + * @uses $CFG + * @param array $tags simple array of keywords to be stored + * @param integer $courseid + * @param integer $userid + * @param string $tagtype official or default only + * @param string $myurl optional for logging creation of course tags + */ +function coursetag_store_keywords($tags, $courseid, $userid=0, $tagtype='official', $myurl='') { + + global $CFG; + + if (is_array($tags) and !empty($tags)) { + + //tag_set_add('course', $courseid, $tags, $userid); + //if ($tagtype == 'official') { + // $tags_ids = tag_get_id($tags); + //} + + foreach($tags as $tag) { + $tag = trim($tag); + if (strlen($tag) > 0) { + tag_set_add('course', $courseid, $tag, $userid); + if ($myurl) { + $url = $myurl.'?query='.urlencode($tag); + } + if ($tagtype == 'default' and $myurl != '') { + // log the tagging request - note only for user added tags + add_to_log($courseid, 'coursetags', 'add', $url, 'Course tagged'); + } + if ($tagtype == 'official') { + tag_type_set(tag_get_id($tag), $tagtype); + } + } + } + } + +} + +/** + * Deletes a personal tag for a user for a course. + * + * @uses $CFG + * @param int $tagid + * @param int $userid + * @param int $courseid + */ +function coursetag_delete_keyword($tagid, $userid, $courseid) { + + global $CFG, $DB; + + $sql = "SELECT COUNT(*) + FROM {tag_instance} + WHERE tagid = $tagid + AND tiuserid = $userid + AND itemtype = 'course' + AND itemid = $courseid"; + if ($DB->count_records_sql($sql) == 1) { + $sql = "tagid = $tagid + AND tiuserid = $userid + AND itemtype = 'course' + AND itemid = $courseid"; + $DB->delete_records_select('tag_instance', $sql); + // if there are no other instances of the tag then consider deleting the tag as well + if (!$DB->record_exists('tag_instance', array('tagid' => $tagid))) { + // if the tag is a personal tag then delete it - don't do official tags + if ($DB->record_exists('tag', array('id' => $tagid, 'tagtype' => 'default'))) { + $DB->delete_records('tag', array('id' => $tagid, 'tagtype' => 'default')); + } + } + } else { + print_error("errordeleting", 'tag', '', $tagid); + } + +} + +/** + * Get courses tagged with a tag + * + * @param int $tagid + * @return array of course objects + */ +function coursetag_get_tagged_courses($tagid) { + + global $DB; + + $courses = array(); + if ($crs = $DB->get_records_select('tag_instance', "tagid=:tagid AND itemtype='course'", array('tagid'=>$tagid))) { + foreach ($crs as $c) { + //this capability check was introduced to stop display of courses that a student could not + //view, but arguably it is best that when clicking on a tag, the tagged course summary should + //be seen and then if the student clicks on that they will be given the opportunity to join + //note courses not visible should not have their tagid sent to this function + //if (has_capability('moodle/course:view', get_context_instance(CONTEXT_COURSE, $c->itemid))) { + $course = $DB->get_record('course', array('id'=>$c->itemid)); + $courses[$c->itemid] = $course; + //} + } + } + return $courses; + +} + +/** + * Course tagging function used only during the deletion of a + * course (called by lib/moodlelib.php) to clean up associated tags + * + * @param $courseid + * @param $showfeedback + */ +function coursetag_delete_course_tags($courseid, $showfeedback=false) { + + global $DB; + + if ($tags = $DB->get_records_select('tag_instance', "itemtype='course' AND itemid=:courseid", array('courseid'=>$courseid))) { + foreach ($tags as $tag) { + //delete the course tag instance record + $DB->delete_records('tag_instance', array('tagid'=>$tag->tagid, 'itemtype'=>'course', 'itemid'=> $courseid)); + // delete tag if there are no other tag_instance entries now + if (!($DB->record_exists('tag_instance', array('tagid'=>$tag->tagid)))) { + $DB->delete_records('tag', array('id'=>$tag->tagid)); + } + } + } + + if ($showfeedback) { + notify(get_string('deletedcoursetags', 'tag')); + } +} + +/** + * Function called by cron to create/update users rss feeds + * + * @uses $CFG + * @return true + * + * Function removed. + * rsslib.php needs updating to accept Dublin Core tags (dc/cc) input before this can work. + */ +/* +function coursetag_rss_feeds() { + + global $CFG, $DB; + require_once($CFG->dirroot.'/lib/dmllib.php'); + require_once($CFG->dirroot.'/lib/rsslib.php'); + + $status = true; + mtrace(' Preparing to update all user unit tags RSS feeds'); + if (empty($CFG->enablerssfeeds)) { + mtrace(' RSS DISABLED (admin variables - enablerssfeeds)'); + } else { + + // Load all the categories for use later on + $categories = $DB->get_records('course_categories'); + + // get list of users who have tagged a unit + $sql = " + SELECT DISTINCT u.id as userid, u.username, u.firstname, u.lastname, u.email + FROM {user} u, {course} c, {tag_instance} cti, {tag} t + WHERE c.id = cti.itemid + AND u.id = cti.tiuserid + AND t.id = cti.tagid + AND t.tagtype = 'personal' + AND u.confirmed = 1 + AND u.deleted = 0 + ORDER BY userid"; + if ($users = $DB->get_records_sql($sql)) { + + $items = array(); //contains rss data items for each user + foreach ($users as $user) { + + // loop through each user, getting the data (tags for courses) + $sql = " + SELECT cti.id, c.id as courseid, c.fullname, c.shortname, c.category, t.rawname, cti.timemodified + FROM {course} c, {tag_instance} cti, {tag} t + WHERE c.id = cti.itemid + AND cti.tiuserid = :userid{$user->userid} + AND cti.tagid = t.id + AND t.tagtype = 'personal' + ORDER BY courseid"; + if ($usertags = $DB->get_records_sql($sql, array('userid' => $user->userid))) { + $latest_date = 0; //latest date any tag was created by a user + $c = 0; //course identifier + + foreach ($usertags as $usertag) { + if ($usertag->courseid != $c) { + $c = $usertag->courseid; + $items[$c] = new stdClass(); + $items[$c]->title = $usertag->fullname . '(' . $usertag->shortname . ')'; + $items[$c]->link = $CFG->wwwroot . '/course/view.php?name=' . $usertag->shortname; + $items[$c]->description = ''; //needs to be blank + $items[$c]->category = $categories[$usertag->category]->name; + $items[$c]->subject[] = $usertag->rawname; + $items[$c]->pubdate = $usertag->timemodified; + $items[$c]->tag = true; + } else { + $items[$c]->subject[] .= $usertag->rawname; + } + // Check and set the latest modified date. + $latest_date = $usertag->timemodified > $latest_date ? $usertag->timemodified : $latest_date; + } + + // Setup some vars for use while creating the file + $path = $CFG->dataroot.'/1/usertagsrss/'.$user->userid; + $file_name = 'user_unit_tags_rss.xml'; + $title = get_string('rsstitle', 'tag', ucwords(strtolower($user->firstname.' '.$user->lastname))); + $desc = get_string('rssdesc', 'tag'); + // check that the path exists + if (!file_exists($path)) { + mtrace(' Creating folder '.$path); + check_dir_exists($path, TRUE, TRUE); + } + + // create or update the feed for the user + // this functionality can be copied into seperate lib as in next two lines + //require_once($CFG->dirroot.'/local/ocilib.php'); + //oci_create_rss_feed( $path, $file_name, $latest_date, $items, $title, $desc, $dc=true, $cc=false); + + // Set path to RSS file + $full_path = "$save_path/$file_name"; + + mtrace(" Preparing to update RSS feed for $file_name"); + + // First let's make sure there is work to do by checking the time the file was last modified, + // if a course was update after the file was mofified + if (file_exists($full_path)) { + if ($lastmodified = filemtime($full_path)) { + mtrace(" XML File $file_name Created on ".date( "D, j M Y G:i:s T", $lastmodified )); + mtrace(' Lastest course modification on '.date( "D, j M Y G:i:s T", $latest_date )); + if ($latest_date > $lastmodified) { + mtrace(" XML File $file_name needs updating"); + $changes = true; + } else { + mtrace(" XML File $file_name doesn't need updating"); + $changes = false; + } + } + } else { + mtrace(" XML File $file_name needs updating"); + $changes = true; + } + + if ($changes) { + // Now we know something has changed, write the new file + + if (!empty($items)) { + // First set rss feeds common headers + $header = rss_standard_header(strip_tags(format_string($title,true)), + $CFG->wwwroot, + $desc, + true, true); + // Now all the rss items + if (!empty($header)) { + $articles = rss_add_items($items,$dc,$cc); + } + // Now all rss feeds common footers + if (!empty($header) && !empty($articles)) { + $footer = rss_standard_footer(); + } + // Now, if everything is ok, concatenate it + if (!empty($header) && !empty($articles) && !empty($footer)) { + $result = $header.$articles.$footer; + } else { + $result = false; + } + } else { + $result = false; + } + + // Save the XML contents to file + if (!empty($result)) { + $rss_file = fopen($full_path, "w"); + if ($rss_file) { + $status = fwrite ($rss_file, $result); + fclose($rss_file); + } else { + $status = false; + } + } + + // Output result + if (empty($result)) { + // There was nothing to put into the XML file. Delete it! + if( is_file($full_path) ) { + mtrace(" There were no items for XML File $file_name. Deleting XML File"); + unlink($full_path); + mtrace(" $full_path -> (deleted)"); + } else { + mtrace(" There were no items for the XML File $file_name and no file to delete. Ignore."); + } + } else { + if (!empty($status)) { + mtrace(" $full_path -> OK"); + } else { + mtrace(" $full_path -> FAILED"); + } + } + } + //end of oci_create_rss_feed() + } + } + } + } + + return $status; +} + */ + +/** + * Get official keywords for the in header.html + * use: echo ''; + * @uses $CFG + * @param int $courseid + * @return string + * + * Function removed but fully working + * This function is potentially useful to anyone wanting to improve search results for course pages. + * The idea is to add official tags (not personal tags to prevent their deletion) to all + * courses (facility not added yet) which will be automatically added to the page header to boost + * search engine specificity/ratings. + */ +/* +function coursetag_get_official_keywords($courseid, $asarray=false) { + global $CFG; + $returnstr = ''; + $sql = "SELECT t.id, name, rawname + FROM {tag} t, {tag_instance} ti + WHERE ti.itemid = :courseid + AND ti.itemtype = 'course' + AND t.tagtype = 'official' + AND ti.tagid = t.id + ORDER BY name ASC"; + if ($tags = $DB->get_records_sql($sql, array('courseid' => $courseid))) { + if ($asarray) { + return $tags; + } + foreach ($tags as $tag) { + if( empty($CFG->keeptagnamecase) ) { + $textlib = textlib_get_instance(); + $name = $textlib->strtotitle($tag->name); + } else { + $name = $tag->rawname; + } + $returnstr .= $name.', '; + } + $returnstr = rtrim($returnstr, ', '); + } + return $returnstr; +} +*/ + +?> diff --git a/tag/edit.php b/tag/edit.php index 4c2696719e5..c17c2907664 100644 --- a/tag/edit.php +++ b/tag/edit.php @@ -90,7 +90,7 @@ if ($tagnew = $tagform->get_data()) { if (has_capability('moodle/tag:manage', $systemcontext)) { // rename tag if(!tag_rename($tag->id, $tagnew->rawname)) { - error('Error updating tag record'); + print_error('errorupdatingrecord', 'tag'); } } diff --git a/tag/index.php b/tag/index.php index 11d941b04bf..2e9747d19d1 100644 --- a/tag/index.php +++ b/tag/index.php @@ -14,7 +14,7 @@ if (empty($CFG->usetags)) { } $tagid = optional_param('id', 0, PARAM_INT); // tag id -$tagname = optional_param('tag', '', PARAM_TAG); // tag +$tagname = optional_param('tag', '', PARAM_TAG); // tag $edit = optional_param('edit', -1, PARAM_BOOL); $userpage = optional_param('userpage', 0, PARAM_INT); // which page to show @@ -78,8 +78,64 @@ print_heading($tagname, '', 2, 'headingblock header tag-heading'); tag_print_management_box($tag); tag_print_description_box($tag); -$usercount = tag_record_count('user', $tag->id); +// Display courses tagged with the tag +require_once($CFG->dirroot.'/tag/coursetagslib.php'); +if ($courses = coursetag_get_tagged_courses($tag->id)) { + $totalcount = count( $courses ); + print_box_start('generalbox', 'tag-blogs'); //could use an id separate from tag-blogs, but would have to copy the css style to make it look the same + + $heading = get_string('tagindex_coursetitle', 'tag', $tagname) .': '. $totalcount; + print_heading($heading, '', 3); + + foreach ($courses as $course) { + print_course($course); + } + + print_box_end(); +} + +// Print up to 10 previous blogs entries + +// I was not able to use get_items_tagged_with() because it automatically +// tries to join on 'blog' table, since the itemtype is 'blog'. However blogs +// uses the post table so this would not really work. - Yu 29/8/07 +if (has_capability('moodle/blog:view', $systemcontext)) { // You have to see blogs obviously + + $count = 10; + if ($blogs = blog_fetch_entries('', $count, 0, 'site', '', $tag->id)) { + + print_box_start('generalbox', 'tag-blogs'); + $heading = get_string('relatedblogs', 'tag', $tagname); + print_heading($heading, '', 3); + + echo ''; + + echo '

'.get_string('seeallblogs', 'tag', $tagname).'

'; + + print_box_end(); + } +} + +$usercount = tag_record_count('user', $tag->id); if ($usercount > 0) { //user table box @@ -95,49 +151,8 @@ if ($usercount > 0) { print_box_end(); } -// Print last 10 blogs - -// I was not able to use get_items_tagged_with() because it automatically -// tries to join on 'blog' table, since the itemtype is 'blog'. However blogs -// uses the post table so this would not really work. - Yu 29/8/07 -if (has_capability('moodle/blog:view', $systemcontext)) { // You have to see blogs obviously - - if ($blogs = blog_fetch_entries('', 10, 0, 'site', '', $tag->id)) { - - print_box_start('generalbox', 'tag-blogs'); - - print_heading(get_string('relatedblogs', 'tag'), '', 3); - - echo ''; - - echo '

'.get_string('seeallblogs', 'tag').'...

'; - - print_box_end(); - } -} - - echo ''; - //----------------- right column ----------------- $blocks_preferred_width = bounded_number(180, blocks_preferred_width($pageblocks[BLOCK_POS_RIGHT]), 210); @@ -151,9 +166,6 @@ if (blocks_have_content($pageblocks, BLOCK_POS_RIGHT) || $PAGE->user_is_editing( /// Finish the page echo '
'; - - $PAGE->print_footer(); - ?> diff --git a/tag/lib.php b/tag/lib.php index 14c9a26efc7..4e2b1e27fa0 100644 --- a/tag/lib.php +++ b/tag/lib.php @@ -63,9 +63,10 @@ define('TAG_RELATED_CORRELATED', 2); * @param int $record_id the id of the record to tag * @param array $tags the array of tags to set on the record. If * given an empty array, all tags will be removed. + * @param int $userid optional only required for course tagging * @return void */ -function tag_set($record_type, $record_id, $tags) { +function tag_set($record_type, $record_id, $tags, $userid = 0) { static $in_recursion_semaphore = false; // this is to prevent loops when tagging a tag if ( $record_type == 'tag' && !$in_recursion_semaphore) { @@ -108,7 +109,7 @@ function tag_set($record_type, $record_id, $tags) { $tag_current_id = $new_tag[$clean_tag]; } - tag_assign($record_type, $record_id, $tag_current_id, $ordering); + tag_assign($record_type, $record_id, $tag_current_id, $ordering, $userid); // if we are tagging a tag (adding a manually-assigned related tag), we // need to create the opposite relationship as well. @@ -127,17 +128,18 @@ function tag_set($record_type, $record_id, $tags) { * 'user' for users, etc. * @param int $record_id the id of the record to tag * @param string $tag the tag to add + * @param int $userid optional only required for course tagging * @return void */ -function tag_set_add($record_type, $record_id, $tag) { +function tag_set_add($record_type, $record_id, $tag, $userid = 0) { $new_tags = array(); - foreach( tag_get_tags($record_type, $record_id) as $current_tag ) { + foreach( tag_get_tags($record_type, $record_id, NULL, $userid) as $current_tag ) { $new_tags[] = $current_tag->rawname; } $new_tags[] = $tag; - return tag_set($record_type, $record_id, $new_tags); + return tag_set($record_type, $record_id, $new_tags, $userid); } /** @@ -236,9 +238,10 @@ function tag_get($field, $value, $returnfields='id, name, rawname') { * @param int $record_id the record id for which we want to get the tags * @param string $type the tag type (either 'default' or 'official'). By default, * all tags are returned. + * @param int $userid optional only required for course tagging * @return array the array of tags */ -function tag_get_tags($record_type, $record_id, $type=null) { +function tag_get_tags($record_type, $record_id, $type=null, $userid=0) { global $CFG, $DB; $params = array(); @@ -250,9 +253,15 @@ function tag_get_tags($record_type, $record_id, $type=null) { $sql_type = ''; } + $u = null; + if ($userid) { + $u = "AND ti.tiuserid = :userid "; + $params['userid'] = $userid; + } + $sql = "SELECT tg.id, tg.tagtype, tg.name, tg.rawname, tg.flag, ti.ordering FROM {tag_instance} ti JOIN {tag} tg ON tg.id = ti.tagid - WHERE ti.itemtype = :recordtype AND ti.itemid = :recordid $sql_type + WHERE ti.itemtype = :recordtype AND ti.itemid = :recordid $u $sql_type ORDER BY ti.ordering ASC"; $params['recordtype'] = $record_type; $params['recordid'] = $record_id; @@ -662,12 +671,13 @@ function tag_add($tags, $type="default") { * @param int $record_id the id of the record that will be tagged * @param string $tagid the tag id to set on the record. * @param int $ordering the order of the instance for this record + * @param int $userid optional only required for course tagging * @return bool true on success, false otherwise */ -function tag_assign($record_type, $record_id, $tagid, $ordering) { +function tag_assign($record_type, $record_id, $tagid, $ordering, $userid = 0) { global $DB; - if ( $tag_instance_object = $DB->get_record('tag_instance', array('tagid'=>$tagid, 'itemtype'=>$record_type, 'itemid'=>$record_id), 'id')) { + if ( $tag_instance_object = $DB->get_record('tag_instance', array('tagid'=>$tagid, 'itemtype'=>$record_type, 'itemid'=>$record_id, 'tiuserid'=>$userid), 'id')) { $tag_instance_object->ordering = $ordering; $tag_instance_object->timemodified = time(); return $DB->update_record('tag_instance', $tag_instance_object); @@ -678,6 +688,7 @@ function tag_assign($record_type, $record_id, $tagid, $ordering) { $tag_instance_object->itemtype = $record_type; $tag_instance_object->ordering = $ordering; $tag_instance_object->timemodified = time(); + $tag_instance_object->tiuserid = $userid; return $DB->insert_record('tag_instance', $tag_instance_object); } } diff --git a/version.php b/version.php index 7f6a528c15d..829a6299713 100644 --- a/version.php +++ b/version.php @@ -6,7 +6,7 @@ // This is compared against the values stored in the database to determine // whether upgrades should be performed (see lib/db/*.php) - $version = 2008051203; // YYYYMMDD = date of the last version bump + $version = 2008063001; // YYYYMMDD = date of the last version bump // XX = daily increments $release = '2.0 dev (Build: 20080630)'; // Human-friendly version name