Commit | Line | Data |
---|---|---|
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 | 31 | define('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 | 34 | define('NO_MOODLE_COOKIES', true); |
fcce139a AD |
35 | |
36 | require_once('../config.php'); | |
37 | require_once($CFG->libdir.'/filelib.php'); | |
38 | require_once($CFG->libdir.'/rsslib.php'); | |
39 | ||
1502bf77 | 40 | // RSS feeds must be enabled site-wide. |
fcce139a | 41 | if (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(); |
47 | if (!$relativepath) { | |
b111858d | 48 | rss_error(); |
fcce139a AD |
49 | } |
50 | ||
1502bf77 | 51 | // Extract relative path components into variables. |
fcce139a AD |
52 | $args = explode('/', trim($relativepath, '/')); |
53 | if (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 |
65 | if ($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. |
65572738 MA |
118 | try { |
119 | list($context, $course, $cm) = get_context_info_array($contextid); | |
120 | } catch (dml_missing_record_exception $e) { | |
121 | rss_error(); | |
122 | } | |
e73cb1ac JF |
123 | |
124 | $PAGE->set_context($context); | |
125 | ||
fcce139a | 126 | $user = get_complete_user_data('id', $userid); |
e922fe23 | 127 | |
1502bf77 | 128 | // Let enrol plugins deal with new enrolments if necessary. |
a6cad23b | 129 | enrol_check_plugins($user, false); |
e922fe23 | 130 | |
1502bf77 | 131 | \core\session\manager::set_user($user); // For login and capability checks. |
fcce139a | 132 | |
52cede73 AD |
133 | try { |
134 | $autologinguest = true; | |
135 | $setwantsurltome = true; | |
136 | $preventredirect = true; | |
6e0ecbe9 | 137 | require_course_login($course, $autologinguest, $cm, $setwantsurltome, $preventredirect); |
52cede73 | 138 | } catch (Exception $e) { |
c61daed0 | 139 | if (isguestuser()) { |
20dbcc33 | 140 | rss_error('rsserrorguest', 'rss.xml', 0, '403 Forbidden'); |
c61daed0 | 141 | } else { |
20dbcc33 | 142 | rss_error('rsserrorauth', 'rss.xml', 0, '403 Forbidden'); |
c61daed0 | 143 | } |
52cede73 | 144 | } |
b111858d | 145 | |
1502bf77 | 146 | // Work out which component in Moodle we want (from the frankenstyle name). |
b0d1d941 | 147 | $componentdir = core_component::get_component_directory($componentname); |
56da374e | 148 | list($type, $plugin) = core_component::normalize_component($componentname); |
fcce139a | 149 | |
1502bf77 | 150 | // Call the component to check/update the feed and tell us the path to the cached file. |
fcce139a | 151 | $pathname = null; |
e417be4c | 152 | |
aa60291e AD |
153 | if (file_exists($componentdir)) { |
154 | require_once("$componentdir/rsslib.php"); | |
155 | $functionname = $plugin.'_rss_get_feed'; | |
156 | ||
157 | if (function_exists($functionname)) { | |
1502bf77 AD |
158 | // The $pathname will be null if there was a problem (eg user doesn't have the necessary capabilities). |
159 | // NOTE:the component providing the feed must do its own capability checks and security. | |
e73cb1ac JF |
160 | try { |
161 | $pathname = $functionname($context, $args); | |
162 | } catch (Exception $e) { | |
163 | rss_error('rsserror'); | |
164 | } | |
aa60291e | 165 | } |
fcce139a | 166 | } |
6f5e0852 | 167 | |
1502bf77 | 168 | // Check that file exists. |
fcce139a | 169 | if (empty($pathname) || !file_exists($pathname)) { |
b111858d | 170 | rss_error(); |
fcce139a | 171 | } |
8adcb49f | 172 | |
b111858d | 173 | // Send the RSS file to the user! |
1502bf77 | 174 | send_file($pathname, 'rss.xml', 3600); // Cached by browsers for 1 hour. |
e7f927a0 | 175 | |
13d1c9ed JF |
176 | /** |
177 | * Sends an error formatted as an rss file and then exits | |
178 | * | |
179 | * @package core_rss | |
180 | * @category rss | |
181 | * | |
182 | * @param string $error the error type, default is rsserror | |
20dbcc33 DP |
183 | * @param string $filename the name of the file to created |
184 | * @param int $unused | |
7a3451bc | 185 | * @param string $statuscode http 1.1 statuscode indicicating the error |
13d1c9ed | 186 | * @uses exit |
b111858d | 187 | */ |
20dbcc33 DP |
188 | function rss_error($error='rsserror', $filename='rss.xml', $unused=0, $statuscode='404 Not Found') { |
189 | header("HTTP/1.1 $statuscode"); | |
190 | header('Content-Disposition: inline; filename="'.$filename.'"'); | |
191 | header('Content-Type: application/xml'); | |
192 | echo rss_geterrorxmlfile($error); | |
b111858d | 193 | exit; |
fcce139a | 194 | } |