Skip to content

Commit

Permalink
RSS MDL-22204 committing new RSS code. Uses a token to ID the user. R…
Browse files Browse the repository at this point in the history
…SS feeds also generated/updated as needed rather than by cron.php
Andrew Davis committed May 2, 2010

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent d1e544b commit fcce139
Showing 16 changed files with 697 additions and 748 deletions.
11 changes: 0 additions & 11 deletions admin/cron.php
Original file line number Diff line number Diff line change
@@ -447,17 +447,6 @@
}
}

if (!empty($CFG->enablerssfeeds)) { //Defined in admin/variables page
include_once("$CFG->libdir/rsslib.php");
mtrace("Running rssfeeds if required...");

if ( ! cron_rss_feeds()) {
mtrace("Something went wrong while generating rssfeeds!!!");
} else {
mtrace("Rssfeeds finished");
}
}

/// Run the auth cron, if any
/// before enrolments because it might add users that will be needed in enrol plugins
$auths = get_enabled_auth_plugins();
2 changes: 1 addition & 1 deletion blocks/news_items/block_news_items.php
Original file line number Diff line number Diff line change
@@ -107,7 +107,7 @@ function get_content() {
} else {
$userid = $USER->id;
}
$this->content->footer .= '<br />'.rss_get_link($this->page->course->id, $userid, 'forum', $forum->id, $tooltiptext);
$this->content->footer .= '<br />'.rss_get_link($this->page->context->id, $userid, 'forum', $forum->id, $tooltiptext);
}

}
1 change: 1 addition & 0 deletions lang/en/moodle.php
Original file line number Diff line number Diff line change
@@ -1434,6 +1434,7 @@
$string['rss'] = 'RSS';
$string['rssarticles'] = 'Number of RSS recent articles';
$string['rsserror'] = 'Error reading RSS data';
$string['rsserrorauth'] = 'Your RSS link does not contain a valid authentication token.';
$string['rsstype'] = 'RSS feed for this activity';
$string['saveandnext'] = 'Save and show next';
$string['savedat'] = 'Saved at:';
1 change: 1 addition & 0 deletions lib/moodlelib.php
Original file line number Diff line number Diff line change
@@ -394,6 +394,7 @@
*/
define('EXTERNAL_TOKEN_EMBEDDED', 1);


/// PARAMETER HANDLING ////////////////////////////////////////////////////

/**
145 changes: 77 additions & 68 deletions lib/rsslib.php
Original file line number Diff line number Diff line change
@@ -29,110 +29,98 @@
* @global object
* @global object
*/
function rss_get_link($courseid, $userid, $modulename, $id, $tooltiptext='') {

function rss_get_link($contextid, $userid, $modulename, $id, $tooltiptext='') {
global $OUTPUT;

static $rsspath = '';

//In site course, if no logged (userid), use admin->id. Bug 2048.
if ($courseid == SITEID and empty($userid)) {
$admin = get_admin();
$userid = $admin->id;
}

$rsspath = rss_get_url($courseid, $userid, $modulename, $id);
$rsspath = rss_get_url($contextid, $userid, $modulename, $id);
$rsspix = $OUTPUT->pix_url('i/rss');

return '<a href="'. $rsspath .'"><img src="'. $rsspix .'" title="'. strip_tags($tooltiptext) .'" alt="'.get_string('rss').'" /></a>';

}

/**
* This function returns the URL for the RSS XML file.
*
* @global object
* @param int contextid the course id
* @param int userid the current user id
* @param string modulename the name of the current module. For example "forum"
* @param int id For modules, module instance id
*/
function rss_get_url($courseid, $userid, $modulename, $id) {
function rss_get_url($contextid, $userid, $modulename, $id) {
global $CFG;
require_once($CFG->libdir.'/filelib.php');
return get_file_url($courseid.'/'.$userid.'/'.$modulename.'/'.$id.'/rss.xml', null, 'rssfile');
$usertoken = rss_get_token($userid);
return get_file_url($contextid.'/'.$usertoken.'/'.$modulename.'/'.$id.'/rss.xml', null, 'rssfile');
}

/**
* This function prints the icon (from theme) with the link to rss/file.php
*/
function rss_print_link($courseid, $userid, $modulename, $id, $tooltiptext='') {
print rss_get_link($courseid, $userid, $modulename, $id, $tooltiptext);
function rss_print_link($contextid, $userid, $modulename, $id, $tooltiptext='') {
print rss_get_link($contextid, $userid, $modulename, $id, $tooltiptext);

}

/**
* This function iterates over each module in the server to see if
* it supports generating rss feeds, searching for a MODULENAME_rss_feeds()
* function and invoking it foreach activity as necessary
* Given an object, deletes all RSS files associated with it.
* Relies on a naming convention. See rss_get_filename()
*
* @global object
* @global object
* @param string $modname the name of the module ie 'forum'. Used to construct the cache path.
* @param object $instance An object with an id member variable ie $forum, $glossary.
* @return void
*/
function cron_rss_feeds () {
global $CFG, $DB;

$status = true;
function rss_delete_file($modname, $instance) {
global $CFG;

mtrace(' Generating rssfeeds...');
$dh = opendir("$CFG->dataroot/rss/$modname");
while (false !== ($filename = readdir($dh))) {
if ($filename!='.' && $filename!='..') {
if (preg_match("/{$instance->id}_/", $filename)) {
unlink("$CFG->dataroot/rss/$modname/$filename");
}
}
}
}

//Check for required functions...
if(!function_exists('utf8_encode')) {
mtrace(' ERROR: You need to add XML support to your PHP installation!');
return true;
/**
* Are RSS feeds enabled for the supplied module instance?
* @param object $instance An instance of an activity module ie $forum, $glossary.
* @param boolean $hasrsstype Should there be a rsstype member variable?
* @param boolean $hasrssarticles Should there be a rssarticles member variable?
*/
function rss_enabled($modname, $instance, $hasrsstype=true, $hasrssarticles=true) {
if ($hasrsstype) {
if (empty($instance->rsstype) || $instance->rsstype==0) {
return false;
}
}

if ($allmods = $DB->get_records('modules') ) {
foreach ($allmods as $mod) {
mtrace(' '.$mod->name.': ', '');
$modname = $mod->name;
$modfile = "$CFG->dirroot/mod/$modname/rsslib.php";
//If file exists and we have selected to restore that type of module
if (file_exists($modfile)) {
include_once($modfile);
$generaterssfeeds = $modname.'_rss_feeds';
if (function_exists($generaterssfeeds)) {
if ($status) {
mtrace('generating ', '');;
$status = $generaterssfeeds();
if (!empty($status)) {
mtrace('...OK');
} else {
mtrace('...FAILED');
}
} else {
mtrace('...SKIPPED (failed above)');
}
} else {
mtrace('...NOT SUPPORTED (function)');
}
} else {
mtrace('...NOT SUPPORTED (file)');
}
//have they set the RSS feed to return 0 results?
if ($hasrssarticles) {
if (empty($instance->rssarticles) || $instance->rssarticles==0) {
return false;
}
}
mtrace(' Ending rssfeeds...', '');
if (!empty($status)) {
mtrace('...OK');
} else {
mtrace('...FAILED');

if (!instance_is_visible($modname,$instance)) {
return false;
}

return $status;
return true;
}

/**
* This function saves to file the rss feed specified in the parameters
*
* @global object
* @param string $modname the module name ie forum. Used to create a cache directory.
* @param string $filename the name of the file to be created ie "1234"
* @param string $result the data to be written to the file
*/
function rss_save_file($modname, $mod, $result) {
function rss_save_file($modname, $filename, $result) {
global $CFG;

$status = true;
@@ -143,8 +131,8 @@ function rss_save_file($modname, $mod, $result) {
}

if ($status) {
$file = rss_file_name($modname, $mod);
$rss_file = fopen($file, "w");
$fullfilename = rss_get_file_full_name($modname, $filename);
$rss_file = fopen($fullfilename, "w");
if ($rss_file) {
$status = fwrite ($rss_file, $result);
fclose($rss_file);
@@ -156,10 +144,13 @@ function rss_save_file($modname, $mod, $result) {
}


function rss_file_name($modname, $mod) {
function rss_get_file_full_name($modname, $filename) {
global $CFG;
return "$CFG->dataroot/rss/$modname/$filename.xml";
}

return "$CFG->dataroot/rss/$modname/$mod->id.xml";
function rss_get_file_name($instance, $sql) {
return $instance->id.'_'.md5($sql);
}

/**
@@ -303,7 +294,7 @@ function rss_standard_footer($title = NULL, $link = NULL, $description = NULL) {
* to be sent when a rss is required (file.php)
* and something goes wrong
*/
function rss_geterrorxmlfile() {
function rss_geterrorxmlfile($errortype = 'rsserror') {
global $CFG;

$return = '';
@@ -317,7 +308,7 @@ function rss_geterrorxmlfile() {
$item->title = "RSS Error";
$item->link = $CFG->wwwroot;
$item->pubdate = time();
$item->description = get_string("rsserror");
$item->description = get_string($errortype);
$return .= rss_add_items(array($item));
}

@@ -329,6 +320,24 @@ function rss_geterrorxmlfile() {
return $return;
}

function rss_get_userid_from_token($token) {
global $DB;
$record = $DB->get_record('user_private_key', array('script'=>'rss','value' => $token), 'userid', IGNORE_MISSING);
if ($record) {
return $record->userid;
}
return null;
}

function rss_get_token($userid) {
return get_user_key('rss', $userid);
}

/*function rss_update_token_last_access($userid) {
global $DB;
$DB->set_field('rss_tokens', 'lastaccess', time(), array('userid'=>$userid));
}*/

// ===== This function are used to write XML tags =========
// [stronk7]: They are similar to the glossary export and backup generation
// but I've replicated them here because they have some minor
2 changes: 1 addition & 1 deletion mod/data/edit.php
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@

/// RSS and CSS and JS meta
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
$rsspath = rss_get_url($course->id, $USER->id, 'data', $data->id);
$rsspath = rss_get_url($context->id, $USER->id, 'data', $data->id);
$PAGE->add_alternate_version(format_string($course->shortname) . ': %fullname%',
$rsspath, 'application/rss+xml');
}
2 changes: 1 addition & 1 deletion mod/data/index.php
Original file line number Diff line number Diff line change
@@ -114,7 +114,7 @@

$rsslink = '';
if ($rss && $data->rssarticles > 0) {
$rsslink = rss_get_link($course->id, $USER->id, 'data', $data->id, 'RSS');
$rsslink = rss_get_link($context->id, $USER->id, 'data', $data->id, 'RSS');
}

if ($course->format == 'weeks' or $course->format == 'topics') {
218 changes: 117 additions & 101 deletions mod/data/rsslib.php
Original file line number Diff line number Diff line change
@@ -2,115 +2,131 @@
// This file adds support to rss feeds generation

// This function is the main entry point to database module
// rss feeds generation. Foreach database with rss enabled
// build one XML rss structure.


function data_rss_feeds() {
// rss feeds generation.
function data_rss_get_feed($context, $cm, $instance, $args) {
global $CFG, $DB;

$status = true;

// Check CFG->enablerssfeeds.
if (empty($CFG->enablerssfeeds)) {
debugging("DISABLED (admin variables)");
}
// Check CFG->data_enablerssfeeds.
else if (empty($CFG->data_enablerssfeeds)) {
if (empty($CFG->data_enablerssfeeds)) {
debugging("DISABLED (module configuration)");
return null;
}

$data = $DB->get_record('data', array('id' => $instance), '*', MUST_EXIST);

if (!rss_enabled('data', $data, false, true)) {
return null;
}

$sql = data_rss_get_sql($data, $cm);

//get the cache file info
$filename = rss_get_file_name($data, $sql);
$cachedfilepath = rss_get_file_full_name('data', $filename);

//Is the cache out of date?
$cachedfilelastmodified = 0;
if (file_exists($cachedfilepath)) {
$cachedfilelastmodified = filemtime($cachedfilepath);
}
// It's working so we start...
else {
// Iterate over all data.
if ($datas = $DB->get_records('data')) {
foreach ($datas as $data) {

if ($data->rssarticles > 0) {

// Get the first field in the list (a hack for now until we have a selector)

if (!$firstfield = $DB->get_record_sql('SELECT id,name FROM {data_fields} WHERE dataid = ? ORDER by id', array($data->id), true)) {
continue;
}


// Get the data_records out.
$approved = ($data->approval) ? ' AND dr.approved = 1 ' : ' ';

$sql = "SELECT dr.*, u.firstname, u.lastname
FROM {data_records} dr, {user} u
WHERE dr.dataid = ? $approved
AND dr.userid = u.id
ORDER BY dr.timecreated DESC";

if (!$records = $DB->get_records_sql($sql, array($data->id), 0, $data->rssarticles)) {
continue;
}

$firstrecord = array_shift($records); // Get the first and put it back
array_unshift($records, $firstrecord);

$filename = rss_file_name('data', $data);
if (file_exists($filename)) {
if (filemtime($filename) >= $firstrecord->timemodified) {
continue;
}
}

// Now create all the articles
mtrace('Creating feed for '.$data->name);

$items = array();
foreach ($records as $record) {

$recordarray = array();
array_push($recordarray, $record);

$item = null;

// guess title or not
if (!empty($data->rsstitletemplate)) {
$item->title = data_print_template('rsstitletemplate', $recordarray, $data, '', 0, true);
} else { // else we guess
$item->title = strip_tags($DB->get_field('data_content', 'content',
array('fieldid'=>$firstfield->id, 'recordid'=>$record->id)));
}
$item->description = data_print_template('rsstemplate', $recordarray, $data, '', 0, true);
$item->pubdate = $record->timecreated;
$item->link = $CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&rid='.$record->id;

array_push($items, $item);
}
$course = $DB->get_record('course', array('id'=>$data->course));

// First all rss feeds common headers.
$header = rss_standard_header($course->shortname.': '.format_string($data->name,true),
$CFG->wwwroot."/mod/data/view.php?d=".$data->id,
format_string($data->intro,true)); //TODO: fix format

if (!empty($header)) {
$articles = rss_add_items($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)) {
$rss = $header.$articles.$footer;

//Save the XML contents to file.
$status = rss_save_file('data', $data, $rss);
}
else {
$status = false;
}
}

if (data_rss_newstuff($data, $cm, $cachedfilelastmodified)) {
require_once($CFG->dirroot . '/mod/data/lib.php');

// Get the first field in the list (a hack for now until we have a selector)
if (!$firstfield = $DB->get_record_sql('SELECT id,name FROM {data_fields} WHERE dataid = ? ORDER by id', array($data->id), true)) {
return null;
}

if (!$records = $DB->get_records_sql($sql, array(), 0, $data->rssarticles)) {
return null;
}

$firstrecord = array_shift($records); // Get the first and put it back
array_unshift($records, $firstrecord);

// Now create all the articles
$items = array();
foreach ($records as $record) {
$recordarray = array();
array_push($recordarray, $record);

$item = null;

// guess title or not
if (!empty($data->rsstitletemplate)) {
$item->title = data_print_template('rsstitletemplate', $recordarray, $data, '', 0, true);
} else { // else we guess
$item->title = strip_tags($DB->get_field('data_content', 'content',
array('fieldid'=>$firstfield->id, 'recordid'=>$record->id)));
}
$item->description = data_print_template('rsstemplate', $recordarray, $data, '', 0, true);
$item->pubdate = $record->timecreated;
$item->link = $CFG->wwwroot.'/mod/data/view.php?d='.$data->id.'&rid='.$record->id;

array_push($items, $item);
}
$course = $DB->get_record('course', array('id'=>$data->course));

// First all rss feeds common headers.
$header = rss_standard_header($course->shortname.': '.format_string($data->name,true),
$CFG->wwwroot."/mod/data/view.php?d=".$data->id,
format_string($data->intro,true)); //TODO: fix format

if (!empty($header)) {
$articles = rss_add_items($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)) {
$rss = $header.$articles.$footer;

//Save the XML contents to file.
$status = rss_save_file('data', $filename, $rss);
}
}
return $status;

return $cachedfilepath;
}

function data_rss_get_sql($data, $cm, $time=0) {
//do we only want new posts?
if ($time) {
$time = " AND dr.timemodified > '$time'";
} else {
$time = '';
}

$approved = ($data->approval) ? ' AND dr.approved = 1 ' : ' ';

$sql = "SELECT dr.*, u.firstname, u.lastname
FROM {data_records} dr, {user} u
WHERE dr.dataid = {$data->id} $approved
AND dr.userid = u.id $time
ORDER BY dr.timecreated DESC";

return $sql;
}

/**
* If there is new stuff in since $time this returns true
* Otherwise it returns false.
*
* @param object $data the data activity object
* @param object $cm
* @param int $time timestamp
* @return bool
*/
function data_rss_newstuff($data, $cm, $time) {
global $DB;

$sql = data_rss_get_sql($data, $cm, $time);

$recs = $DB->get_records_sql($sql, null, 0, 1);//limit of 1. If we get even 1 back we have new stuff
return ($recs && !empty($recs));
}

4 changes: 2 additions & 2 deletions mod/data/view.php
Original file line number Diff line number Diff line change
@@ -266,7 +266,7 @@
/// RSS and CSS and JS meta
$meta = '';
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
$rsspath = rss_get_url($course->id, $USER->id, 'data', $data->id);
$rsspath = rss_get_url($context->id, $USER->id, 'data', $data->id);
$PAGE->add_alternate_version(format_string($course->shortname) . ': %fullname%',
$rsspath, 'application/rss+xml');
}
@@ -317,7 +317,7 @@
// Do we need to show a link to the RSS feed for the records?
if (!empty($CFG->enablerssfeeds) && !empty($CFG->data_enablerssfeeds) && $data->rssarticles > 0) {
echo '<div style="float:right;">';
rss_print_link($course->id, $USER->id, 'data', $data->id, get_string('rsstype'));
rss_print_link($context->id, $USER->id, 'data', $data->id, get_string('rsstype'));
echo '</div>';
echo '<div style="clear:both;"></div>';
}
4 changes: 2 additions & 2 deletions mod/forum/index.php
Original file line number Diff line number Diff line change
@@ -255,7 +255,7 @@
$tooltiptext = get_string('rsssubscriberssposts', 'forum', format_string($forum->name));
}
//Get html code for RSS link
$row[] = rss_get_link($course->id, $USER->id, 'forum', $forum->id, $tooltiptext);
$row[] = rss_get_link($context->id, $USER->id, 'forum', $forum->id, $tooltiptext);
} else {
$row[] = '&nbsp;';
}
@@ -389,7 +389,7 @@
$tooltiptext = get_string('rsssubscriberssposts', 'forum', format_string($forum->name));
}
//Get html code for RSS link
$row[] = rss_get_link($course->id, $USER->id, 'forum', $forum->id, $tooltiptext);
$row[] = rss_get_link($context->id, $USER->id, 'forum', $forum->id, $tooltiptext);
} else {
$row[] = '&nbsp;';
}
2 changes: 1 addition & 1 deletion mod/forum/lib.php
Original file line number Diff line number Diff line change
@@ -7510,7 +7510,7 @@ function forum_extend_settings_navigation(settings_navigation $settingsnav, navi
} else {
$userid = $USER->id;
}
$url = new moodle_url(rss_get_url($PAGE->course->id, $userid, "forum", $forumobject->id));
$url = new moodle_url(rss_get_url($PAGE->cm->context->id, $userid, "forum", $forumobject->id));
$forumnode->add($string, $url, settings_navigation::TYPE_SETTING, null, null, new pix_icon('i/rss', ''));
}
}
521 changes: 268 additions & 253 deletions mod/forum/rsslib.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mod/glossary/index.php
Original file line number Diff line number Diff line change
@@ -109,7 +109,7 @@
$userid = $USER->id;
}
//Get html code for RSS link
$rsslink = rss_get_link($course->id, $userid, "glossary", $glossary->id, $tooltiptext);
$rsslink = rss_get_link($context->id, $userid, "glossary", $glossary->id, $tooltiptext);
}
}

322 changes: 105 additions & 217 deletions mod/glossary/rsslib.php

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion mod/glossary/view.php
Original file line number Diff line number Diff line change
@@ -304,7 +304,7 @@
}
// print_box_start('rsslink');
echo '<span class="wrap rsslink">';
rss_print_link($course->id, $userid, "glossary", $glossary->id, $tooltiptext);
rss_print_link($context->id, $userid, "glossary", $glossary->id, $tooltiptext);
echo '</span>';
// print_box_end();
}
206 changes: 118 additions & 88 deletions rss/file.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?PHP
//This file returns the required rss feeds
//The URL format MUST include:
// course: the course id
// context: the context id
// user: the user id
// name: the name of the module (forum...)
// id: the id (instance) of the module (forumid...)
@@ -14,103 +14,133 @@
//obviously, but its the best I've thought!!

// disable moodle specific debug messages and any errors in output
define('NO_DEBUG_DISPLAY', true);
define('NO_MOODLE_COOKIES', true); // session not used here

require_once('../config.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/rsslib.php');

$lifetime = 3600; // Seconds for files to remain in caches - 1 hour

// this is a big one big hack - NO_MOODLE_COOKIES is not compatible with capabilities MDL-7243
// it should be replaced once we get to codes in urls

$relativepath = get_file_argument();


if (!$relativepath) {
define('NO_DEBUG_DISPLAY', true);//comment this out to see any error messages during RSS generation

// session not used here
if (!defined('NO_MOODLE_COOKIES')) { define('NO_MOODLE_COOKIES', true); }
if (!defined('USER_KEY_LOGIN')) { define('USER_KEY_LOGIN', true); }

require_once('../config.php');
require_once($CFG->libdir.'/filelib.php');
require_once($CFG->libdir.'/rsslib.php');

//Check RSS feeds are enabled
if (empty($CFG->enablerssfeeds)) {
debugging('DISABLED (admin variables)');
rss_not_found();
}

$lifetime = 3600; // Seconds for files to remain in caches - 1 hour
$filename = 'rss.xml';

// this is a big one big hack - NO_MOODLE_COOKIES is not compatible with capabilities MDL-7243
// it should be replaced once we get to codes in urls

$relativepath = get_file_argument();
if (!$relativepath) {
rss_not_found();
}

// extract relative path components
$args = explode('/', trim($relativepath, '/'));
if (count($args) < 5) {
rss_not_found();
}

$contextid = (int)$args[0];
$token = $args[1];
$modulename = clean_param($args[2], PARAM_FILE);
$instance = $args[3];

$userid = rss_get_userid_from_token($token);
if (!$userid) {
rss_not_authenticated();
}
$user = get_complete_user_data('id', $userid);
session_set_user($user);

$context = get_context_instance_by_id($contextid);
if (!$context) {
rss_not_found();
}
$PAGE->set_context($context);

$coursecontext = get_course_context($context);
$course = $DB->get_record('course', array('id' => $coursecontext->instanceid), '*', MUST_EXIST);

$isblog = ($modulename == 'blog');
if ($isblog) {
$blogid = (int)$args[4]; // could be groupid / courseid / userid depending on $instance
if ($args[5] != 'rss.xml') {
$tagid = (int)$args[5];
} else {
$tagid = 0;
}
} else {
$instance = (int)$instance; // we know it's an id number
}

//Check name of module
if (!$isblog) {
$mods = get_plugin_list('mod');
$mods = array_keys($mods);
if (!in_array(strtolower($modulename), $mods)) {
rss_not_found();
}

// extract relative path components
$args = explode('/', trim($relativepath, '/'));

if (count($args) < 5) {
//Get course_module to check it's visible
if (!$cm = get_coursemodule_from_instance($modulename,$instance)) {
rss_not_found();
}

$courseid = (int)$args[0];
$userid = (int)$args[1];
$modulename = clean_param($args[2], PARAM_FILE);
$instance = $args[3];
$filename = 'rss.xml';

if ($isblog = $modulename == 'blog') {
$blogid = (int)$args[4]; // could be groupid / courseid / userid depending on $instance
if ($args[5] != 'rss.xml') {
$tagid = (int)$args[5];
} else {
$tagid = 0;
}
} else {
$instance = (int)$instance; // we know it's an id number
}


if (!$course = $DB->get_record('course', array('id'=>$courseid))) {
$modcontext = get_context_instance(CONTEXT_MODULE, $cm->id);
//will $modcontext always be the same object as $context?
$isuser = has_capability('moodle/course:participate', $modcontext);
} else {
$isuser = has_capability('moodle/course:participate', $coursecontext);
}

//Check if course allows guests
if ($course->id != SITEID) {
if ((!$course->guest || $course->password) && (!$isuser)) {
rss_not_found();
}

//Check name of module
if (!$isblog) {
$mods = get_plugin_list('mod');
$mods = array_keys($mods);
if (!in_array(strtolower($modulename), $mods)) {
rss_not_found();
}
//Get course_module to check it's visible
if (!$cm = get_coursemodule_from_instance($modulename,$instance,$courseid)) {
rss_not_found();
}
$context = get_context_instance(CONTEXT_MODULE, $cm->id);
$isuser = has_capability('moodle/course:participate', $context, $userid); // Not ideal, this should be module-specific, but deferring until RSS gets a revamp with codes in the URLs
} else {
$context = get_context_instance(CONTEXT_COURSE, $course->id);
$isuser = has_capability('moodle/course:participate', $context, $userid);
}

//Check for "security" if the course is hidden or the activity is hidden
if (!$isblog and (!$course->visible || !$cm->visible) && (!has_capability('moodle/course:viewhiddenactivities', $context))) {
rss_not_found();
}

$pathname = null;
//Work out the filename of the cached RSS file
if ($isblog) {
require_once($CFG->dirroot.'/blog/rsslib.php');
$pathname = blog_generate_rss_feed($instance, $blogid, $tagid);
} else {
$functionname = $cm->modname.'_rss_get_feed';
require_once($CFG->dirroot."/mod/{$cm->modname}/rsslib.php");
if(function_exists($functionname)) {
$pathname = $functionname($context, $cm, $instance, $args);
}
}

//Check for "security" if !course->guest or course->password
if ($course->id != SITEID) {
if ((!$course->guest || $course->password) && (!$isuser)) {
rss_not_found();
}
}

//Check for "security" if the course is hidden or the activity is hidden
if (!$isblog and (!$course->visible || !$cm->visible) && (!has_capability('moodle/course:viewhiddenactivities', $context))) {
rss_not_found();
}
//Check that file exists
if (empty($pathname) || !file_exists($pathname)) {
rss_not_found();
}

//Work out the filename of the RSS file
if ($isblog) {
require_once($CFG->dirroot.'/blog/rsslib.php');
$pathname = blog_generate_rss_feed($instance, $blogid, $tagid);
} else {
$pathname = $CFG->dataroot.'/rss/'.$modulename.'/'.$instance.'.xml';
}
//rss_update_token_last_access($USER->id);

//Check that file exists
if (!file_exists($pathname)) {
rss_not_found();
}
//Send it to user!
send_file($pathname, $filename, $lifetime);

//Send it to user!
send_file($pathname, $filename, $lifetime);
function rss_not_found() {
/// error, send some XML with error message
global $lifetime, $filename;
send_file(rss_geterrorxmlfile(), $filename, $lifetime, false, true);
}

function rss_not_found() {
/// error, send some XML with error message
global $lifetime, $filename;
send_file(rss_geterrorxmlfile(), $filename, $lifetime, false, true);
}
function rss_not_authenticated() {
global $lifetime, $filename;
send_file(rss_geterrorxmlfile('rsserrorauth'), $filename, $lifetime, false, true);
}

0 comments on commit fcce139

Please sign in to comment.