0ff00d58b3dc0d167cf1ba8ef4afe45bd6029ca9
[moodle.git] / rss / file.php
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/>.
17 /**
18  * rss/file.php - entry point to serve rss streams
19  *
20  * This script simply checks the parameters to construct a $USER
21  * then finds and calls a function in the relevant component to
22  * actually check security and create the RSS stream
23  *
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
28  */
31 /** NO_DEBUG_DISPLAY - bool, Disable moodle specific debug messages and any errors in output. Set to false to see any error messages during RSS generation */
32 define('NO_DEBUG_DISPLAY', true);
34 /** NO_MOODLE_COOKIES - bool, Disable the use of sessions/cookies - we recreate $USER for every call. */
35 define('NO_MOODLE_COOKIES', true);
37 require_once('../config.php');
38 require_once($CFG->libdir.'/filelib.php');
39 require_once($CFG->libdir.'/rsslib.php');
41 // RSS feeds must be enabled site-wide
42 if (empty($CFG->enablerssfeeds)) {
43     debugging('DISABLED (admin variables)');
44     rss_error();
45 }
48 // All the arguments are in the path
49 $relativepath = get_file_argument();
50 if (!$relativepath) {
51     rss_error();
52 }
55 // Extract relative path components into variables
56 $args = explode('/', trim($relativepath, '/'));
57 if (count($args) < 5) {
58     rss_error();
59 }
61 $contextid   = (int)$args[0];
62 $token  = clean_param($args[1], PARAM_ALPHANUM);
63 $componentname = clean_param($args[2], PARAM_FILE);
65 //check if they have requested a 1.9 RSS feed
66 //if token is an int its a user id (1.9 request)
67 //if token contains any letters its a token (2.0 request)
68 $inttoken = intval($token);
69 if ($token==="$inttoken") {
70     //they've requested a feed using a 1.9 url. redirect them to the 2.0 url using the guest account
72     $instanceid  = clean_param($args[3], PARAM_INT);
74     //1.9 URL puts course id where the context id is in 2.0 URLs
75     $courseid = $contextid;
76     unset($contextid);
78     //find the context id
79     if ($course = $DB->get_record('course', array('id' => $courseid))) {
80         $modinfo = get_fast_modinfo($course);
82         if (!isset($modinfo->instances[$componentname])) {
83             $modinfo->instances[$componentname] = array();
84         }
86         foreach ($modinfo->instances[$componentname] as $modinstanceid=>$cm) {
87             if ($modinstanceid==$instanceid) {
88                 $context = context_module::instance($cm->id, IGNORE_MISSING);
89                 break;
90             }
91         }
92     }
94     if (empty($context)) {
95         //this shouldnt happen. something bad is going on.
96         rss_error('rsserror');
97     }
99     //make sure that $CFG->siteguest is set
100     if (empty($CFG->siteguest)) {
101         if (!$guestid = $DB->get_field('user', 'id', array('username'=>'guest', 'mnethostid'=>$CFG->mnet_localhost_id))) {
102             // guest does not exist yet, weird
103             rss_error('rsserror');
104         }
105         set_config('siteguest', $guestid);
106     }
107     $guesttoken = rss_get_token($CFG->siteguest);
109     //change forum to mod_forum (for example)
110     $componentname = 'mod_'.$componentname;
112     $url = $PAGE->url;
113     $url->set_slashargument("/{$context->id}/$guesttoken/$componentname/$instanceid/rss.xml");
115     //redirect to the 2.0 rss URL
116     redirect($url);
117 } else {
118     // Authenticate the user from the token
119     $userid = rss_get_userid_from_token($token);
120     if (!$userid) {
121         rss_error('rsserrorauth');
122     }
125 // Check the context actually exists
126 list($context, $course, $cm) = get_context_info_array($contextid);
128 $PAGE->set_context($context);
130 $user = get_complete_user_data('id', $userid);
132 // let enrol plugins deal with new enrolments if necessary
133 enrol_check_plugins($user);
135 session_set_user($user); //for login and capability checks
137 try {
138     $autologinguest = true;
139     $setwantsurltome = true;
140     $preventredirect = true;
141     require_login($course, $autologinguest, $cm, $setwantsurltome, $preventredirect);
142 } catch (Exception $e) {
143     if (isguestuser()) {
144         rss_error('rsserrorguest');
145     } else {
146         rss_error('rsserrorauth');
147     }
150 // Work out which component in Moodle we want (from the frankenstyle name)
151 $componentdir = core_component::get_component_directory($componentname);
152 list($type, $plugin) = core_component::normalize_component($componentname);
155 // Call the component to check/update the feed and tell us the path to the cached file
156 $pathname = null;
158 if (file_exists($componentdir)) {
159     require_once("$componentdir/rsslib.php");
160     $functionname = $plugin.'_rss_get_feed';
162     if (function_exists($functionname)) {
163         // $pathname will be null if there was a problem (eg user doesn't have the necessary capabilities)
164         // NOTE:the component providing the feed must do its own capability checks and security
165         try {
166             $pathname = $functionname($context, $args);
167         } catch (Exception $e) {
168             rss_error('rsserror');
169         }
170     }
174 // Check that file exists
175 if (empty($pathname) || !file_exists($pathname)) {
176     rss_error();
179 // Send the RSS file to the user!
180 send_file($pathname, 'rss.xml', 3600);   // Cached by browsers for 1 hour
183 /**
184  * Sends an error formatted as an rss file and then exits
185  *
186  * @package core_rss
187  * @category rss
188  *
189  * @param string $error the error type, default is rsserror
190  * @param string $filename the name of the file to create (NOT USED)
191  * @param int $lifetime UNSURE (NOT USED)
192  * @uses exit
193  */
194 function rss_error($error='rsserror', $filename='rss.xml', $lifetime=0) {
195     send_file(rss_geterrorxmlfile($error), $filename, $lifetime, false, true);
196     exit;