weekly release 3.3dev
[moodle.git] / rss / file.php
CommitLineData
b111858d
MD
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * rss/file.php - entry point to serve rss streams
e922fe23 19 *
b111858d 20 * This script simply checks the parameters to construct a $USER
e922fe23 21 * then finds and calls a function in the relevant component to
b111858d
MD
22 * actually check security and create the RSS stream
23 *
13d1c9ed
JF
24 * @package core_rss
25 * @category rss
26 * @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
27 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
b111858d
MD
28 */
29
1502bf77 30/** NO_DEBUG_DISPLAY - bool, Disable moodle debug and error messages. Set to false to see any errors during RSS generation */
13d1c9ed 31define('NO_DEBUG_DISPLAY', true);
fcce139a 32
13d1c9ed 33/** NO_MOODLE_COOKIES - bool, Disable the use of sessions/cookies - we recreate $USER for every call. */
30d24538 34define('NO_MOODLE_COOKIES', true);
fcce139a
AD
35
36require_once('../config.php');
37require_once($CFG->libdir.'/filelib.php');
38require_once($CFG->libdir.'/rsslib.php');
39
1502bf77 40// RSS feeds must be enabled site-wide.
fcce139a 41if (empty($CFG->enablerssfeeds)) {
b111858d 42 rss_error();
fcce139a
AD
43}
44
1502bf77 45// All the arguments are in the path.
fcce139a
AD
46$relativepath = get_file_argument();
47if (!$relativepath) {
b111858d 48 rss_error();
fcce139a
AD
49}
50
1502bf77 51// Extract relative path components into variables.
fcce139a
AD
52$args = explode('/', trim($relativepath, '/'));
53if (count($args) < 5) {
b111858d 54 rss_error();
fcce139a
AD
55}
56
57$contextid = (int)$args[0];
83b912e0 58$token = clean_param($args[1], PARAM_ALPHANUM);
aa60291e 59$componentname = clean_param($args[2], PARAM_FILE);
fcce139a 60
1502bf77
AD
61// Check if they have requested a 1.9 RSS feed.
62// If token is an int it is a user id (1.9 request).
63// If token contains any letters it is a token (2.0 request).
c61daed0 64$inttoken = intval($token);
1502bf77
AD
65if ($token === "$inttoken") {
66 // They have requested a feed using a 1.9 url. redirect them to the 2.0 url using the guest account.
c61daed0
AD
67
68 $instanceid = clean_param($args[3], PARAM_INT);
69
1502bf77 70 // 1.9 URL puts course id where the context id is in 2.0 URLs.
c61daed0
AD
71 $courseid = $contextid;
72 unset($contextid);
73
1502bf77 74 // Find the context id.
c61daed0 75 if ($course = $DB->get_record('course', array('id' => $courseid))) {
f20edd52 76 $modinfo = get_fast_modinfo($course);
c61daed0 77
1502bf77
AD
78 foreach ($modinfo->get_instances_of($componentname) as $modinstanceid => $cm) {
79 if ($modinstanceid == $instanceid) {
43731030 80 $context = context_module::instance($cm->id, IGNORE_MISSING);
c61daed0
AD
81 break;
82 }
83 }
84 }
85
86 if (empty($context)) {
1502bf77 87 // This shouldnt happen. something bad is going on.
20dbcc33 88 rss_error();
c61daed0
AD
89 }
90
1502bf77 91 // Make sure that $CFG->siteguest is set.
c05ccf3f 92 if (empty($CFG->siteguest)) {
1502bf77
AD
93 if (!$guestid = $DB->get_field('user', 'id', array('username' => 'guest', 'mnethostid' => $CFG->mnet_localhost_id))) {
94 // Guest does not exist yet, weird.
20dbcc33 95 rss_error();
c05ccf3f
AD
96 }
97 set_config('siteguest', $guestid);
98 }
c61daed0
AD
99 $guesttoken = rss_get_token($CFG->siteguest);
100
1502bf77 101 // Change forum to mod_forum (for example).
c61daed0
AD
102 $componentname = 'mod_'.$componentname;
103
104 $url = $PAGE->url;
105 $url->set_slashargument("/{$context->id}/$guesttoken/$componentname/$instanceid/rss.xml");
106
1502bf77 107 // Redirect to the 2.0 rss URL.
c61daed0
AD
108 redirect($url);
109} else {
1502bf77 110 // Authenticate the user from the token.
c61daed0
AD
111 $userid = rss_get_userid_from_token($token);
112 if (!$userid) {
20dbcc33 113 rss_error('rsserrorauth', 'rss.xml', 0, '403 Forbidden');
c61daed0 114 }
fcce139a 115}
b111858d 116
1502bf77 117// Check the context actually exists.
e73cb1ac
JF
118list($context, $course, $cm) = get_context_info_array($contextid);
119
120$PAGE->set_context($context);
121
fcce139a 122$user = get_complete_user_data('id', $userid);
e922fe23 123
1502bf77 124// Let enrol plugins deal with new enrolments if necessary.
e922fe23
PS
125enrol_check_plugins($user);
126
1502bf77 127\core\session\manager::set_user($user); // For login and capability checks.
fcce139a 128
52cede73
AD
129try {
130 $autologinguest = true;
131 $setwantsurltome = true;
132 $preventredirect = true;
6e0ecbe9 133 require_course_login($course, $autologinguest, $cm, $setwantsurltome, $preventredirect);
52cede73 134} catch (Exception $e) {
c61daed0 135 if (isguestuser()) {
20dbcc33 136 rss_error('rsserrorguest', 'rss.xml', 0, '403 Forbidden');
c61daed0 137 } else {
20dbcc33 138 rss_error('rsserrorauth', 'rss.xml', 0, '403 Forbidden');
c61daed0 139 }
52cede73 140}
b111858d 141
1502bf77 142// Work out which component in Moodle we want (from the frankenstyle name).
b0d1d941 143$componentdir = core_component::get_component_directory($componentname);
56da374e 144list($type, $plugin) = core_component::normalize_component($componentname);
fcce139a 145
1502bf77 146// Call the component to check/update the feed and tell us the path to the cached file.
fcce139a 147$pathname = null;
e417be4c 148
aa60291e
AD
149if (file_exists($componentdir)) {
150 require_once("$componentdir/rsslib.php");
151 $functionname = $plugin.'_rss_get_feed';
152
153 if (function_exists($functionname)) {
1502bf77
AD
154 // The $pathname will be null if there was a problem (eg user doesn't have the necessary capabilities).
155 // NOTE:the component providing the feed must do its own capability checks and security.
e73cb1ac
JF
156 try {
157 $pathname = $functionname($context, $args);
158 } catch (Exception $e) {
159 rss_error('rsserror');
160 }
aa60291e 161 }
fcce139a 162}
6f5e0852 163
1502bf77 164// Check that file exists.
fcce139a 165if (empty($pathname) || !file_exists($pathname)) {
b111858d 166 rss_error();
fcce139a 167}
8adcb49f 168
b111858d 169// Send the RSS file to the user!
1502bf77 170send_file($pathname, 'rss.xml', 3600); // Cached by browsers for 1 hour.
e7f927a0 171
13d1c9ed
JF
172/**
173 * Sends an error formatted as an rss file and then exits
174 *
175 * @package core_rss
176 * @category rss
177 *
178 * @param string $error the error type, default is rsserror
20dbcc33
DP
179 * @param string $filename the name of the file to created
180 * @param int $unused
7a3451bc 181 * @param string $statuscode http 1.1 statuscode indicicating the error
13d1c9ed 182 * @uses exit
b111858d 183 */
20dbcc33
DP
184function rss_error($error='rsserror', $filename='rss.xml', $unused=0, $statuscode='404 Not Found') {
185 header("HTTP/1.1 $statuscode");
186 header('Content-Disposition: inline; filename="'.$filename.'"');
187 header('Content-Type: application/xml');
188 echo rss_geterrorxmlfile($error);
b111858d 189 exit;
fcce139a 190}