';
if (has_capability('moodle/category:update', $context)) { // Print button to update this category
unset($options);
$options['id'] = $category->id;
@@ -475,7 +480,7 @@
echo '
';
}
- echo '
';
Index: course/editcategory.php
===================================================================
RCS file: /cvsroot/moodle/moodle/course/editcategory.php,v
retrieving revision 1.5
diff -u -r1.5 editcategory.php
--- course/editcategory.php 9 Jan 2008 10:49:59 -0000 1.5
+++ course/editcategory.php 30 Jan 2008 10:45:07 -0000
@@ -25,13 +25,13 @@
error("Site isn't defined!");
}
-if ($categoryadd) { // Show Add category form: if $id is given, it is used as the parent category
+if ($categoryadd) { // Show Add category form: if $id is given, it is used as the parent category
$strtitle = get_string("addnewcategory");
$context = get_context_instance(CONTEXT_SYSTEM);
$category = null;
} elseif (!is_null($id) && !$categoryadd) { // Show Edit category form: $id is given as the identifier of the category being edited
$strtitle = get_string("editcategorysettings");
- $context = get_context_instance(CONTEXT_COURSECAT, $id);
+ $context = get_context_instance(CONTEXT_COURSECAT, $id);
if (!$category = get_record("course_categories", "id", $id)) {
error("Category not known!");
}
@@ -40,33 +40,34 @@
$mform = new editcategory_form('editcategory.php', compact(array('category', 'id')));
if (!empty($category)) {
- $mform->set_data($category);
+ $mform->set_data($category);
} elseif (!is_null($id)) {
$data = new stdClass();
$data->parent = $id;
$data->categoryadd = 1;
$mform->set_data($data);
}
-
+
if ($mform->is_cancelled()){
if (empty($category)) {
redirect($CFG->wwwroot .'/course/index.php?categoryedit=on');
} else {
redirect($CFG->wwwroot.'/course/category.php?categoryedit=on&id='.$category->id);
- }
+ }
} else if (($data = $mform->get_data())) {
$newcategory = new stdClass();
$newcategory->name = $data->name;
$newcategory->description = $data->description;
$newcategory->sortorder = 999;
$newcategory->parent = $data->parent; // if $id = 0, the new category will be a top-level category
+ $newcategory->enablerss = $data->enablerss;
if (!empty($data->theme) && !empty($CFG->allowcategorythemes)) {
$newcategory->theme = $data->theme;
theme_setup();
}
- if (empty($category) && has_capability('moodle/category:create', $context)) { // Create a new category
+ if (empty($category) && has_capability('moodle/category:create', $context)) { // Create a new category
if (!$newcategory->id = insert_record('course_categories', $newcategory)) {
notify( "Could not insert the new category '$newcategory->name' ");
} else {
@@ -88,18 +89,18 @@
if ($newcategory->parent == 0) {
$redirect_link = 'index.php?categoryedit=on';
} else {
- $redirect_link = 'category.php?id='.$newcategory->id.'&categoryedit=on';
+ $redirect_link = 'category.php?id='.$newcategory->id.'&categoryedit=on';
}
fix_course_sortorder();
redirect($redirect_link);
}
- }
+ }
}
// If id is given, but not categoryadd or categoryupdate, we show the category with its list of subcategories
-if ($id && !$categoryadd && !$categoryupdate && false) {
+if ($id && !$categoryadd && !$categoryupdate && false) {
/* TODO implement
if ($CFG->forcelogin) {
@@ -124,7 +125,7 @@
$creatorediting = false;
}
- // Resort the category if requested
+ // Resort the category if requested
if ($resort and confirm_sesskey()) {
if ($courses = get_courses($id, "fullname ASC", 'c.id,c.fullname,c.sortorder')) {
// move it off the range
@@ -140,8 +141,8 @@
fix_course_sortorder($category->id);
}
}
-
- // Print headings
+
+ // Print headings
$numcategories = count_records("course_categories");
$stradministration = get_string("administration");
@@ -179,7 +180,7 @@
echo '
';
}
-
+
// Print the category selector
$displaylist = array();
@@ -198,8 +199,8 @@
echo $category->description;
print_box_end();
}
-
- // Editing functions
+
+ // Editing functions
if ($creatorediting) {
// Move a specified category to a new category
@@ -211,11 +212,11 @@
if (!$destcategory = get_record("course_categories", "id", $data->moveto)) {
error("Error finding the destination category");
- }
+ }
// TODO function to move the category
}
- // Hide or show a category
+ // Hide or show a category
if ((!empty($hide) or !empty($show)) and confirm_sesskey()) {
require_capability('moodle/category:visibility', $context);
if (!empty($hide)) {
@@ -233,7 +234,7 @@
}
- // Move a category up or down
+ // Move a category up or down
if ((!empty($moveup) or !empty($movedown)) and confirm_sesskey()) {
require_capability('moodle/category:update', $context);
$movecategory = NULL;
@@ -302,7 +303,7 @@
$mform->display();
}
*/
-}
+}
// Print the form
$site = get_site();
Index: lang/en_utf8/admin.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/admin.php,v
retrieving revision 1.181
diff -u -r1.181 admin.php
--- lang/en_utf8/admin.php 11 Jan 2008 23:22:50 -0000 1.181
+++ lang/en_utf8/admin.php 30 Jan 2008 10:45:08 -0000
@@ -723,5 +723,8 @@
$string['webproxy'] = 'Web proxy';
$string['webproxyinfo'] = 'Fill in following options if your Moodle server can not access internet directly. Internet access is required for download of environment data, language packs, RSS feeds, timezones, etc.
PHP cURL extension is highly recommended.';
$string['xmlstrictheaders'] = 'XML strict headers';
+$string['rsscount'] = 'Ammount if items in RSS feeds';
+$string['configrsscount'] = 'This controls how many items there are in the complete site feed and each category feed. It does not effect the module RSS feeds (i.e. the forums).';
+$string['enablerss'] = 'Enable RSS feeds';
?>
Index: lang/en_utf8/moodle.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/moodle.php,v
retrieving revision 1.166
diff -u -r1.166 moodle.php
--- lang/en_utf8/moodle.php 25 Jan 2008 13:03:14 -0000 1.166
+++ lang/en_utf8/moodle.php 30 Jan 2008 10:45:08 -0000
@@ -1162,8 +1162,8 @@
$string['phpinfo'] = 'PHP info';
$string['pleaseclose'] = 'Please close this window now.';
$string['plugincheck'] = 'Plugins check';
-$string['pluginchecknotice'] = 'The following tables show the modules, blocks and filters that have been detected in your current Moodle installation;
-They indicate which plugins are standard, and which are not. All non-standard plugins should be checked and upgraded to their most recent versions
+$string['pluginchecknotice'] = 'The following tables show the modules, blocks and filters that have been detected in your current Moodle installation;
+They indicate which plugins are standard, and which are not. All non-standard plugins should be checked and upgraded to their most recent versions
before continuing with this Moodle upgrade.';
$string['pluginsetup'] = 'Setting up plugin tables';
$string['policyaccept'] = 'I understand and agree';
@@ -1637,6 +1637,7 @@
$string['yourself'] = 'yourself';
$string['yourteacher'] = 'your $a';
$string['zippingbackup'] = 'Zipping backup';
+$string['enablerss'] = 'Enable RSS feed for this category';
$string['authenticationplugins'] = 'Authentication Plugins';
$string['chooseauthmethod'] = 'Choose authentication plugin';
Index: version.php
===================================================================
RCS file: /cvsroot/moodle/moodle/version.php,v
retrieving revision 1.575
diff -u -r1.575 version.php
--- version.php 29 Jan 2008 05:54:42 -0000 1.575
+++ version.php 30 Jan 2008 10:45:07 -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 = 2007101508; // YYYYMMDD = date
+ $version = 2007101509; // YYYYMMDD = date
// XY = increments within a single day
$release = '2.0 dev'; // Human-friendly version name
Index: admin/settings/server.php
===================================================================
RCS file: /cvsroot/moodle/moodle/admin/settings/server.php,v
retrieving revision 1.34
diff -u -r1.34 server.php
--- admin/settings/server.php 30 Dec 2007 22:25:16 -0000 1.34
+++ admin/settings/server.php 30 Jan 2008 10:45:07 -0000
@@ -95,6 +95,7 @@
// "rss" settingpage
$temp = new admin_settingpage('rss', get_string('rss'));
$temp->add(new admin_setting_configcheckbox('enablerssfeeds', get_string('enablerssfeeds', 'admin'), get_string('configenablerssfeeds', 'admin'), 0));
+$temp->add(new admin_setting_configtext('rsscount', get_string('rsscount', 'admin'), get_string('configrsscount', 'admin'), 0));
$ADMIN->add('server', $temp);
Index: lib/db/upgrade.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/upgrade.php,v
retrieving revision 1.175
diff -u -r1.175 upgrade.php
--- lib/db/upgrade.php 29 Jan 2008 05:54:42 -0000 1.175
+++ lib/db/upgrade.php 30 Jan 2008 10:45:08 -0000
@@ -2309,7 +2309,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 +2354,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 +2516,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 +2539,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,7 +2575,7 @@
$readmefilename = $oldusersdir . '/README.txt';
if ($handle = fopen($readmefilename, 'w+b')) {
if (!fwrite($handle, get_string('olduserdirectory'))) {
- // Could not write to the readme file. No cause for huge concern
+ // Could not write to the readme file. No cause for huge concern
notify("Could not write to the README.txt file in $readmefilename.");
}
fclose($handle);
@@ -2583,22 +2583,22 @@
// Could not create the readme file. No cause for huge concern
notify("Could not create the README.txt file in $readmefilename.");
}
- }
+ }
if ($result && $oldversion < 2007101502) {
/// try to remove duplicate entries
-
+
$SQL = "SELECT userid, itemid, COUNT(*)
FROM {$CFG->prefix}grade_grades
GROUP BY userid, itemid
HAVING COUNT( * ) >1";
// duplicates found
-
+
if ($rs = get_recordset_sql($SQL)) {
if ($rs && $rs->RecordCount() > 0) {
while ($dup = rs_fetch_next_record($rs)) {
- if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades
+ if ($thisdups = get_records_sql("SELECT id FROM {$CFG->prefix}grade_grades
WHERE itemid = $dup->itemid AND userid = $dup->userid
ORDER BY timemodified DESC")) {
@@ -2626,7 +2626,7 @@
/// Main savepoint reached
upgrade_main_savepoint($result, 2007101502);
- }
+ }
if ($result && $oldversion < 2007101503) {
// Update courses that used weekscss to weeks
@@ -2661,7 +2661,7 @@
$sql = "DELETE
FROM {$CFG->prefix}context
WHERE contextlevel=20";
-
+
execute_sql($sql);
/// Main savepoint reached
@@ -2694,6 +2694,24 @@
upgrade_main_savepoint($result, 2007101508);
}
+ if ($result && $oldversion < 2007101509) {
+ $db->debug = false;
+ notify('Modifying course_categories table, adding enablerss field...', 'notifysuccess');
+ // Adding enablerss field into course_categories table
+ $table = new XMLDBTable('course_categories');
+ $field = new XMLDBField('enablerss');
+ $field->setAttributes(XMLDB_TYPE_INTEGER, '1', null, null, null, null, null, null, 'theme');
+
+ // Launch add fields
+ $result = $result && add_field($table, $field);
+
+ notify('enablerss field added to course_categories', 'notifysuccess');
+ $db->debug = true;
+
+ // Main savepoint reached
+ upgrade_main_savepoint($result, 2007101509);
+ }
+
return $result;
}
Index: lib/db/install.xml
===================================================================
RCS file: /cvsroot/moodle/moodle/lib/db/install.xml,v
retrieving revision 1.137
diff -u -r1.137 install.xml
--- lib/db/install.xml 15 Dec 2007 00:49:05 -0000 1.137
+++ lib/db/install.xml 30 Jan 2008 10:45:08 -0000
@@ -96,7 +96,8 @@
-
+
+
@@ -1170,7 +1171,7 @@
-
+
Index: admin/cron.php
===================================================================
RCS file: /cvsroot/moodle/moodle/admin/cron.php,v
retrieving revision 1.131
diff -u -r1.131 cron.php
--- admin/cron.php 13 Jan 2008 18:46:55 -0000 1.131
+++ admin/cron.php 30 Jan 2008 10:45:07 -0000
@@ -9,11 +9,11 @@
/// version of PHP compiled for CGI.
///
/// eg wget -q -O /dev/null 'http://moodle.somewhere.edu/admin/cron.php'
-/// or php /web/moodle/admin/cron.php
+/// or php /web/moodle/admin/cron.php
set_time_limit(0);
$starttime = microtime();
-/// The following is a hack necessary to allow this script to work well
+/// The following is a hack necessary to allow this script to work well
/// from the command line.
define('FULLME', 'cron');
@@ -48,7 +48,7 @@
/// check if execution allowed
if (isset($_SERVER['REMOTE_ADDR'])) { // if the script is accessed via the web.
- if (!empty($CFG->cronclionly)) {
+ if (!empty($CFG->cronclionly)) {
// This script can only be run via the cli.
print_error('cronerrorclionly', 'admin');
exit;
@@ -58,7 +58,7 @@
$pass = optional_param('password', '', PARAM_RAW);
if($pass != $CFG->cronremotepassword) {
// wrong password.
- print_error('cronerrorpassword', 'admin');
+ print_error('cronerrorpassword', 'admin');
exit;
}
}
@@ -139,7 +139,7 @@
if (file_exists($blockfile)) {
require_once($blockfile);
$classname = 'block_'.$block->name;
- $blockobj = new $classname;
+ $blockobj = new $classname;
if (method_exists($blockobj,'cron')) {
mtrace("Processing cron function for ".$block->name.'....','');
if ($blockobj->cron()) {
@@ -195,7 +195,7 @@
/// Run all core cron jobs, but not every time since they aren't too important.
-/// These don't have a timer to reduce load, so we'll use a random number
+/// These don't have a timer to reduce load, so we'll use a random number
/// to randomly choose the percentage of times we should run these jobs.
srand ((double) microtime() * 10000000);
@@ -310,21 +310,21 @@
mtrace('Synchronised metacourses');
//
- // generate new password emails for users
+ // generate new password emails for users
//
mtrace('checking for create_password');
if (count_records('user_preferences', 'name', 'create_password', 'value', '1')) {
mtrace('creating passwords for new users');
- $newusers = get_records_sql("SELECT u.id as id, u.email, u.firstname,
+ $newusers = get_records_sql("SELECT u.id as id, u.email, u.firstname,
u.lastname, u.username,
- p.id as prefid
- FROM {$CFG->prefix}user u
+ p.id as prefid
+ FROM {$CFG->prefix}user u
JOIN {$CFG->prefix}user_preferences p ON u.id=p.userid
WHERE p.name='create_password' AND p.value=1 AND u.email !='' ");
foreach ($newusers as $newuserid => $newuser) {
$newuser->emailstop = 0; // send email regardless
- // email user
+ // email user
if (setnew_password_and_mail($newuser)) {
// remove user pref
delete_records('user_preferences', 'id', $newuser->prefid);
@@ -333,20 +333,20 @@
}
}
}
-
+
if(!empty($CFG->usetags)){
require_once($CFG->dirroot.'/tag/lib.php');
tag_cron();
mtrace ('Executed tag cron');
}
-
+
// Accesslib stuff
cleanup_contexts();
mtrace ('Cleaned up contexts');
gc_cache_flags();
mtrace ('Cleaned cache flags');
// If you suspect that the context paths are somehow corrupt
- // replace the line below with: build_context_path(true);
+ // replace the line below with: build_context_path(true);
build_context_path();
mtrace ('Built context paths');
@@ -361,8 +361,8 @@
@set_time_limit(0);
@raise_memory_limit("192M");
if (function_exists('apache_child_terminate')) {
- // if we are running from Apache, give httpd a hint that
- // it can recycle the process after it's done. Apache's
+ // if we are running from Apache, give httpd a hint that
+ // it can recycle the process after it's done. Apache's
// memory management is truly awful but we can help it.
@apache_child_terminate();
}
@@ -375,7 +375,7 @@
include_once("$CFG->dirroot/backup/lib.php");
require_once ("$CFG->libdir/blocklib.php");
mtrace("Running backups if required...");
-
+
if (! schedule_backup_cron()) {
mtrace("ERROR: Something went wrong while performing backup tasks!!!");
} else {
@@ -393,6 +393,10 @@
} else {
mtrace("Rssfeeds finished");
}
+
+ include_once("$CFG->dirroot/course/rssfeeds.php");
+ // Now do the rss feeds for the courses
+ $feeds = new courserss();
}
/// Run the enrolment cron, if any
@@ -474,44 +478,44 @@
// run gradebook import/export/report cron
if ($gradeimports = get_list_of_plugins('grade/import')) {
- foreach ($gradeimports as $gradeimport) {
+ foreach ($gradeimports as $gradeimport) {
if (file_exists($CFG->dirroot.'/grade/import/'.$gradeimport.'/lib.php')) {
require_once($CFG->dirroot.'/grade/import/'.$gradeimport.'/lib.php');
- $cron_function = 'grade_import_'.$gradeimport.'_cron';
+ $cron_function = 'grade_import_'.$gradeimport.'_cron';
if (function_exists($cron_function)) {
mtrace("Processing gradebook import function $cron_function ...", '');
- $cron_function;
+ $cron_function;
}
}
- }
+ }
}
if ($gradeexports = get_list_of_plugins('grade/export')) {
- foreach ($gradeexports as $gradeexport) {
+ foreach ($gradeexports as $gradeexport) {
if (file_exists($CFG->dirroot.'/grade/export/'.$gradeexport.'/lib.php')) {
require_once($CFG->dirroot.'/grade/export/'.$gradeexport.'/lib.php');
- $cron_function = 'grade_export_'.$gradeexport.'_cron';
+ $cron_function = 'grade_export_'.$gradeexport.'_cron';
if (function_exists($cron_function)) {
mtrace("Processing gradebook export function $cron_function ...", '');
- $cron_function;
+ $cron_function;
}
}
}
}
if ($gradereports = get_list_of_plugins('grade/report')) {
- foreach ($gradereports as $gradereport) {
+ foreach ($gradereports as $gradereport) {
if (file_exists($CFG->dirroot.'/grade/report/'.$gradereport.'/lib.php')) {
require_once($CFG->dirroot.'/grade/report/'.$gradereport.'/lib.php');
- $cron_function = 'grade_report_'.$gradereport.'_cron';
+ $cron_function = 'grade_report_'.$gradereport.'_cron';
if (function_exists($cron_function)) {
mtrace("Processing gradebook report function $cron_function ...", '');
- $cron_function;
+ $cron_function;
}
}
}
}
-
+
// run any customized cronjobs, if any
// looking for functions in lib/local/cron.php
if (file_exists($CFG->dirroot.'/local/cron.php')) {
@@ -528,7 +532,7 @@
mtrace("Cron script completed correctly");
$difftime = microtime_diff($starttime, microtime());
- mtrace("Execution took ".$difftime." seconds");
+ mtrace("Execution took ".$difftime." seconds");
/// finish the IE hack
if (check_browser_version('MSIE')) {
Index: course/rssfeeds.php
===================================================================
RCS file: course/rssfeeds.php
diff -N course/rssfeeds.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ course/rssfeeds.php 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,543 @@
+dirroot.'/lib/dmllib.php');
+ require_once($CFG->dirroot.'/lib/rsslib.php');
+
+ class courserss {
+
+ private $courses;
+ private $categories;
+ private $ordered_categories;
+ private $ordered_courses;
+ private $courses_lastmodified;
+ private $categories_lastmodified;
+ private $datadir;
+ private $filename;
+ private $title;
+ private $desc;
+ private $lastmodified;
+ private $updates;
+ private $items;
+
+ function __construct() {
+ global $CFG;
+
+ if(empty($CFG->enablerssfeeds)) {
+ mtrace(get_string('rssdisabled','rss'));
+ return false;
+ }
+
+ mtrace(get_string('prepupdate','rss'));
+
+ // Set the $this->categories array
+ $this->set_categories();
+
+ // Setup the vars needed for the feeds.
+ $site = get_site();
+ $sitename = $site->fullname;
+
+ // Data for the all courses feed
+ $this->datadir = "{$CFG->dataroot}/".SITEID;
+
+ // We will need the main xml rss file name for the feeds_need_updating()
+ // check
+ $this->set_xml_filename($sitename);
+
+ // Firsts thing we need to do is get the latest modified date for
+ // each category and also the latest modified date for the entire
+ // site and the check to see if the feeds need updating or deleting
+ // due to a category being made invis. or all the courses inside
+ // it being made invis.
+ $this->updates = array();
+ if( !$this->feeds_need_updating() ) {
+ mtrace(' '.get_string('noupdates','rss'));
+ return false;
+ }
+
+ // The latest time a course has been updated. This will be used to
+ // check if the rss file to be overwritten (if there is one) is
+ // newer that the latest updated course.
+ $this->courses_lastmodified = false;
+
+ // An array of categories and latest time a course within that
+ // category has been updated. This will be used to check if the rss
+ // file to be overwritten (if there is one) is newer that the latest
+ // updated course within any category.
+ $this->categories_lastmodified = false;
+
+ // This function will set the $this->courses array and also the two
+ // time stamp holders. $this->courses_lastmodified is the timestamp of
+ // the latest updated course and $this->categories_lastmodified is an
+ // array with the time for the latest course within each category.
+ // It will only set this data if the $this->updates[xmlfile.xml] flag
+ // is set (i.e. this category/site file needs updating)
+ $this->set_courses_and_times();
+
+ // A copy of $this->courses that we will use to build the all units
+ // rss feed
+ $this->ordered_courses = $this->get_ordered_courses('all');
+
+ // An array of categories and the courses within them
+ $this->ordered_categories = $this->get_ordered_courses('category');
+
+ // By this point we should have all the data we need to create the feeds
+
+ $this->set_xml_filename($sitename);
+ // Check if this feed needs updating
+ if($this->updates[$this->filename]) {
+ // For the filemane, title and desc use class properties so that I
+ // don't need to pass the data into the function. The function that
+ // creates the RSS feed will always clear these properties once it
+ // has run, and it will check they exist before it does anything.
+ $this->title = get_string('maintitle','rss',array('sitename' => $sitename));
+ $this->desc = get_string('maindesc','rss',array('sitename' => $sitename));
+ $this->lastmodified = $this->courses_lastmodified;
+ $this->items = $this->ordered_courses;
+
+ // Now create the feed for the all courses feed
+ $this->create_rss_feed();
+ }
+
+
+ // Data for the category feeds
+ foreach($this->ordered_categories as $catid => $data) {
+ $catname = $this->categories[$catid]->name;
+ $this->set_xml_filename($catname);
+
+ // Check if this feed needs updating
+ if($this->updates[$this->filename]) {
+ // Setup the properties for the RSS feed.
+ $this->title = get_string('cattitle','rss',array('catname' => $catname, 'sitename' => $sitename));
+ $this->desc = get_string('catdesc','rss',array('catname' => $catname, 'sitename' => $sitename));
+ $this->lastmodified = $this->categories_lastmodified[$catid];
+ $this->items = $data;
+
+ // Now create the feed the given category
+ $this->create_rss_feed();
+ }
+ }
+ }
+
+ /**
+ * This function returns an array structured in one of two ways. Either
+ * all courses ordered by date modified desc array[] = rssitemobj
+ * or a two level array ordered into categories in an like this
+ * array[catid][] = rssitemobj
+ *
+ * @param $type The type of array wanted. Supports all and category
+ */
+ private function get_ordered_courses($type) {
+ global $CFG;
+ switch($type) {
+ case 'all':
+ case 'category':
+ break;
+ default:
+ return false;
+ break;
+ }
+
+ // Now we know we are looking for one of the supported types.
+
+ // We can create or return the data depending on what format it's
+ // needed in
+
+ if($type == 'all') {
+ // Setup a temp var to hold the data
+ $temp = array();
+
+ // Loop through the courses array and sort them out into categories
+ $i = 0;
+ foreach($this->courses as $index => $data) {
+ // Check if we have reached the amount of items allowd in a feed.
+ if(!empty($CFG->rsscount) && $i >= $CFG->rsscount) {
+ return $temp;
+ }
+
+ // Add into the items array a new object that holds all
+ // the data we want to put into the xml rss file.
+ $temp[$i] = new stdClass();
+ $temp[$i]->title = $data->fullname;
+ $temp[$i]->link = $CFG->wwwroot.'/course/view.php?name='.$data->shortname;
+ $temp[$i]->description = $data->summary;
+ $temp[$i]->category = $this->categories[$data->category]->name;
+ $temp[$i]->pubdate = $data->timemodified;
+
+ // Increment the count
+ $i++;
+ }
+ return $temp;
+ } else if($type == 'category') {
+ // Setup a temp var to hold the data
+ $temp = array();
+
+ // Loop through the courses array and sort them out into categories
+ foreach($this->courses as $index => $data) {
+ // Check if the count has been set, if not set it.
+ if(empty($cout[$data->category])) {
+ $cout[$data->category] = 0;
+ }
+
+ // Check if we have reached the amount of items allowd in a feed.
+ // Continue onto the next item
+ if(!empty($CFG->rsscount) && $cout[$data->category] >= $CFG->rsscount) {
+ continue;
+ } else {
+ // Add into the items array a new object that holds all
+ // the data we want to put into the xml rss file.
+ $temp[$data->category][$cout[$data->category]] = new stdClass();
+ $temp[$data->category][$cout[$data->category]]->title = $data->fullname;
+ $temp[$data->category][$cout[$data->category]]->link = $CFG->wwwroot.'/course/view.php?name='.$data->shortname;
+ $temp[$data->category][$cout[$data->category]]->description = $data->summary;
+ $temp[$data->category][$cout[$data->category]]->category = $this->categories[$data->category]->name;
+ $temp[$data->category][$cout[$data->category]]->pubdate = $data->timemodified;
+
+ // Increment the count
+ $cout[$data->category]++;
+ }
+ }
+
+ return $temp;
+ }
+
+ }
+
+ /**
+ * This function will set the $this->courses array and also the two
+ * timestamp holders. $this->courses_lastmodified is the timestamp of the
+ * latest updated course and $this->categories_lastmodified is an array
+ * with the time for the latest course within each category
+ */
+ private function set_courses_and_times() {
+ global $CFG;
+ // Check if we have already gotten the courses from the database,
+ // if not get them now.
+ if(empty($this->courses)) {
+ // loop through the categories and only get the courses in those
+ // that need updating
+ $in = '';
+ foreach( $this->categories as $data ) {
+ $this->set_xml_filename($data->name);
+ if(!empty($this->updates[$this->filename])) {
+ if(!empty($in)) {
+ $in .= ',';
+ }
+ $in .= $data->id;
+ }
+ }
+
+ if(empty($in)) {
+ // Shouldn't ever get in here as it should have already
+ // worked out there is nothing to update.
+ return false;
+ }
+
+ // Get all the courses. The limits are worked out later as we need
+ // to get everything in time order for the main rss feed.
+ $this->courses = get_records_sql('SELECT * FROM '.$CFG->prefix.'course WHERE category IN('.$in.') ORDER BY timemodified DESC');
+
+ foreach($this->courses as $key => $data) {
+
+ // Check the course is visible and that it's not the main
+ // course. Also check if the category enablerss flag is set.
+ // If any of these are not set remove from the array
+ if(empty($data->visible) || empty($this->categories[$data->category]->visible) || empty($this->categories[$data->category]->enablerss) || $data->id == SITEID) {
+ unset($this->courses[$key]);
+ } else {
+ // Set $this->courses_lastmodified if it's empty or if the
+ // current course in this loop has a higher time.
+ // This has to be done in a loop as the courses array
+ // may not always be ordered by timemodified.
+ if(empty($this->courses_lastmodified) || $data->timemodified > $this->courses_lastmodified) {
+ $this->courses_lastmodified = $data->timemodified;
+ }
+
+ // Now check and set the categories_lastmodified if the current
+ // time is greater than the time set.
+ if(empty($this->categories_lastmodified[$data->category]) || $data->timemodified > $this->categories_lastmodified[$data->category]) {
+ $this->categories_lastmodified[$data->category] = $data->timemodified;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * This function sets $this->categories to hold all the course_categories
+ *
+ */
+ private function set_categories() {
+ // Check if we have already gotten the set_categories from the
+ // database, if not get them now.
+ if(empty($this->categories)) {
+ // Get all categories including invis ones. This is so all the
+ // correct files are either deleted or marked for update
+ $this->categories = get_records('course_categories');
+ }
+ }
+
+ /**
+ * This function will build an RSS file from the array it's passed
+ *
+ */
+ private function create_rss_feed() {
+ global $CFG;
+
+ $fullpath = $this->datadir.'/'.$this->filename;
+
+ mtrace('Preparing to update RSS feed for '.$this->filename);
+
+ // 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($fullpath)) {
+ if($latestdate = filemtime($fullpath)) {
+ mtrace(' '.get_string('filecreated','rss',array('filename' => $this->filename, 'date' => date("D, j M Y G:i:s T", $latestdate))));
+ mtrace(' '.get_string('lastmod','rss',array('date' => date("D, j M Y G:i:s T", $this->lastmodified))));
+ if($this->lastmodified > $latestdate) {
+ mtrace(' '.get_string('needupdate','rss',array('filename' => $this->filename)));
+ $changes = true;
+ } else {
+ mtrace(' '.get_string('noupdate','rss',array('filename' => $this->filename)));
+ $changes = false;
+ }
+ }
+ } else {
+ mtrace(' '.get_string('needupdate','rss',array('filename' => $this->filename)));
+ $changes = true;
+ }
+
+ if($changes) {
+ // Now we know something has changed, write the new file
+
+ if(!empty($this->items)) {
+ // First set rss feeds common headers
+ $header = rss_standard_header($this->title,$CFG->wwwroot,$this->desc);
+
+ // Now all the rss items
+ if(!empty($header)) {
+ $articles = rss_add_items($this->items);
+ }
+ // 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($fullpath, "w");
+ if($rss_file) {
+ $status = fwrite ($rss_file, $result);
+ fclose($rss_file);
+ } else {
+ $status = false;
+ }
+ }
+
+ // Output result
+ // There was nothing to put into the XML file. Delete it!
+ // This shouldn't in theory happen as the XML file would
+ // have been deleted earlier on in the process but just
+ // in case...
+ if(empty($result)) {
+ if(is_file($fullpath)) {
+ mtrace(' '.get_string('noitemsdel','rss',array('filename' => $this->filename)));
+ unlink($fullpath);
+ mtrace(' '.$fullpath.' -> (deleted)');
+ } else {
+ mtrace(' '.get_string('noitemsnofile','rss',array('filename' => $this->filename)));
+ }
+ } else {
+ if(!empty($status)) {
+ mtrace(' '.$fullpath.' -> OK');
+ } else {
+ mtrace(' '.$fullpath.' -> FAILED');
+ }
+ }
+ }
+ }
+
+ /**
+ * This function takes a string and removes all the unwanted chars to
+ * make a clean, useable filename.
+ *
+ * @param string $data Text to turn into a filename
+ */
+ private function set_xml_filename($data) {
+ $this->filename = ereg_replace("[^A-Za-z0-9_]", "", str_replace(' ', '_', strtolower($data))).'.xml';
+ }
+
+ /**
+ * This function will check if the feeds need updating by getting the
+ * last course updated on the site and within each category. It will
+ * then check if the files exists and if it needs updating. If it
+ * needs updating it will remove the file so that it gets recreated.
+ *
+ */
+ private function feeds_need_updating() {
+ global $CFG;
+
+ // Before we come into this function $this->filename should be set
+ // to the main all courses xml file.
+ $fullpath = $this->datadir.'/'.$this->filename;
+
+ // First thing we need to do is check that there are visible courses
+ // if there aren't we have to check if a file exists, if it does it
+ // needs removing as there are no longer any visible courses
+ if(!get_record_sql('SELECT c.id FROM '.$CFG->prefix.'course c,'.$CFG->prefix.'course_categories g WHERE c.category = g.id and c.visible = 1 and g.visible = 1 and g.enablerss = 1')) {
+ // There is no vis courses for the entire site! Check if a file exists,
+ // if it does delete it as it's no longer needed because all the
+ // courses have been made invis.
+ if(file_exists($fullpath)) {
+ if( !unlink($fullpath) ) {
+ // TODO - Make it return some kind of error. This
+ // shouldn't ever fail as this script creates the
+ // files so it should be able to delete them unless
+ // someone messes around with the permissions
+ }
+ }
+
+ // Now we have to loop through the categories removing all the
+ // files if they exist as there are no vis courses.
+ foreach( $this->categories as $id => $data ) {
+ // Setup the $this->filename property.
+ $this->set_xml_filename($data->name);
+ $fullpath = $this->datadir.'/'.$this->filename;
+
+ if(file_exists($fullpath)) {
+ if( !unlink($fullpath) ) {
+ // TODO - Make it return some kind of error. This
+ // shouldn't ever fail as this script creates the
+ // files so it should be able to delete them unless
+ // someone messes around with the permissions
+ }
+ }
+ }
+
+ // No courses needed updating. All files that need removing
+ // have been removed.
+ return false;
+ } else {
+ // If we get here there should be at least some visible courses.
+ // Get the highest timestamp from the database. The get_record_sql
+ // function should limit it to one record. This could be an invis
+ // or vis course as a course could have been made vis or invis
+ // therefore the feed need updating.
+ $latestcourse = get_record_sql('SELECT timemodified FROM '.$CFG->prefix.'course ORDER BY timemodified DESC');
+
+ if(!empty($latestcourse)) {
+ $this->updates[$this->filename] = $this->check_file_time($fullpath,$latestcourse->timemodified);
+ } else {
+ // There is no data for the entire site!. Check if a file exists,
+ // if it does delete it as it's no longer needed because all the
+ // courses have been deleted!
+ if(file_exists($fullpath)) {
+ if( !unlink($fullpath) ) {
+ // TODO - Make it return some kind of error. This
+ // shouldn't ever fail as this script creates the
+ // files so it should be able to delete them unless
+ // someone messes around with the permissions
+ }
+ }
+ // Set the update flag to false
+ $this->updates[$this->filename] = false;
+ }
+
+ foreach( $this->categories as $id => $data ) {
+ // Before we do anything check if there are visible courses
+ // within this category. If not delete the rss file and continue.
+ if(!get_record_sql('SELECT c.id FROM '.$CFG->prefix.'course c,'.$CFG->prefix.'course_categories g WHERE c.category = '.$data->id.' and g.id = '.$data->id.' and c.visible = 1 and g.visible = 1 and g.enablerss = 1')) {
+ // Setup the $this->filename property.
+ $this->set_xml_filename($data->name);
+ $fullpath = $this->datadir.'/'.$this->filename;
+
+ if(file_exists($fullpath)) {
+ if( !unlink($fullpath) ) {
+ // TODO - Make it return some kind of error. This
+ // shouldn't ever fail as this script creates the
+ // files so it should be able to delete them unless
+ // someone messes around with the permissions
+ }
+ }
+
+ $this->updates[$this->filename] = false;
+ } else {
+ // Get the highest timestamp from the database for the given
+ // course id. The get_record_sql function should limit it to
+ // one record.
+ $latestcourse = get_record_sql('SELECT timemodified FROM '.$CFG->prefix.'course WHERE category = '.$data->id.' ORDER BY timemodified DESC');
+
+ // Setup the $this->filename property.
+ $this->set_xml_filename($data->name);
+ $fullpath = $this->datadir.'/'.$this->filename;
+
+ if(!empty($latestcourse)) {
+ $this->updates[$this->filename] = $this->check_file_time($fullpath,$latestcourse->timemodified);
+ } else {
+ // There is no data for this category. Check if a file exists,
+ // if it does delete it as it's no longer needed because all
+ // the courses inside this category have been deleted
+ if(file_exists($fullpath)) {
+ if( !unlink($fullpath) ) {
+ // TODO - Make it return some kind of error. This
+ // shouldn't ever fail as this script creates the
+ // files so it should be able to delete them unless
+ // someone messes around with the permissions
+ }
+ }
+ // Set the update flag to false
+ $this->updates[$this->filename] = false;
+ }
+ }
+ }
+
+ // Now we should have an array of all the files and which ones need
+ // updating.
+ return in_array(true, $this->updates);
+ }
+ }
+
+ /**
+ * This function will check a given filepath to see if the date passed
+ * is greater than the last mod date of the file. If so the file needs
+ * updating.
+ *
+ * @param string $filepath Path of file to check time of
+ * @param int $checktime Timestamp to check against file
+ * @return bool True if file needs updating, false if not.
+ */
+ private function check_file_time($filepath, $checktime) {
+ // Now check if the time we have is greater than that of the all
+ // courses xml rss feed
+ if(file_exists($filepath)) {
+ // This should ever fail if we have a file.
+ if($latestdate = filemtime($filepath)) {
+ if($checktime > $latestdate) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ } else {
+ return true;
+ }
+ }
+ }
+?>
Index: lang/en_utf8/rss.php
===================================================================
RCS file: lang/en_utf8/rss.php
diff -N lang/en_utf8/rss.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ lang/en_utf8/rss.php 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,16 @@
+