Search moodle.org's
Developer Documentation


Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.
  • /rss/ -> file.php (source)
       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
      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   */
      29  
      30  /** NO_DEBUG_DISPLAY - bool, Disable moodle debug and error messages. Set to false to see any errors during RSS generation */
      31  define('NO_DEBUG_DISPLAY', true);
      32  
      33  /** NO_MOODLE_COOKIES - bool, Disable the use of sessions/cookies - we recreate $USER for every call. */
      34  define('NO_MOODLE_COOKIES', true);
      35  
      36  require_once('../config.php');
      37  require_once($CFG->libdir.'/filelib.php');
      38  require_once($CFG->libdir.'/rsslib.php');
      39  
      40  // RSS feeds must be enabled site-wide.
      41  if (empty($CFG->enablerssfeeds)) {
      42      rss_error();
      43  }
      44  
      45  // All the arguments are in the path.
      46  $relativepath = get_file_argument();
      47  if (!$relativepath) {
      48      rss_error();
      49  }
      50  
      51  // Extract relative path components into variables.
      52  $args = explode('/', trim($relativepath, '/'));
      53  if (count($args) < 5) {
      54      rss_error();
      55  }
      56  
      57  $contextid   = (int)$args[0];
      58  $token  = clean_param($args[1], PARAM_ALPHANUM);
      59  $componentname = clean_param($args[2], PARAM_FILE);
      60  
      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).
      64  $inttoken = intval($token);
      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.
      67  
      68      $instanceid  = clean_param($args[3], PARAM_INT);
      69  
      70      // 1.9 URL puts course id where the context id is in 2.0 URLs.
      71      $courseid = $contextid;
      72      unset($contextid);
      73  
      74      // Find the context id.
      75      if ($course = $DB->get_record('course', array('id' => $courseid))) {
      76          $modinfo = get_fast_modinfo($course);
      77  
      78          foreach ($modinfo->get_instances_of($componentname) as $modinstanceid => $cm) {
      79              if ($modinstanceid == $instanceid) {
      80                  $context = context_module::instance($cm->id, IGNORE_MISSING);
      81                  break;
      82              }
      83          }
      84      }
      85  
      86      if (empty($context)) {
      87          // This shouldnt happen. something bad is going on.
      88          rss_error();
      89      }
      90  
      91      // Make sure that $CFG->siteguest is set.
      92      if (empty($CFG->siteguest)) {
      93          if (!$guestid = $DB->get_field('user', 'id', array('username' => 'guest', 'mnethostid' => $CFG->mnet_localhost_id))) {
      94              // Guest does not exist yet, weird.
      95              rss_error();
      96          }
      97          set_config('siteguest', $guestid);
      98      }
      99      $guesttoken = rss_get_token($CFG->siteguest);
     100  
     101      // Change forum to mod_forum (for example).
     102      $componentname = 'mod_'.$componentname;
     103  
     104      $url = $PAGE->url;
     105      $url->set_slashargument("/{$context->id}/$guesttoken/$componentname/$instanceid/rss.xml");
     106  
     107      // Redirect to the 2.0 rss URL.
     108      redirect($url);
     109  } else {
     110      // Authenticate the user from the token.
     111      $userid = rss_get_userid_from_token($token);
     112      if (!$userid) {
     113          rss_error('rsserrorauth', 'rss.xml', 0, '403 Forbidden');
     114      }
     115  }
     116  
     117  // Check the context actually exists.
     118  try {
     119      list($context, $course, $cm) = get_context_info_array($contextid);
     120  } catch (dml_missing_record_exception $e) {
     121      rss_error();
     122  }
     123  
     124  $PAGE->set_context($context);
     125  
     126  $user = get_complete_user_data('id', $userid);
     127  
     128  // Let enrol plugins deal with new enrolments if necessary.
     129  enrol_check_plugins($user);
     130  
     131  \core\session\manager::set_user($user); // For login and capability checks.
     132  
     133  try {
     134      $autologinguest = true;
     135      $setwantsurltome = true;
     136      $preventredirect = true;
     137      require_course_login($course, $autologinguest, $cm, $setwantsurltome, $preventredirect);
     138  } catch (Exception $e) {
     139      if (isguestuser()) {
     140          rss_error('rsserrorguest', 'rss.xml', 0, '403 Forbidden');
     141      } else {
     142          rss_error('rsserrorauth', 'rss.xml', 0, '403 Forbidden');
     143      }
     144  }
     145  
     146  // Work out which component in Moodle we want (from the frankenstyle name).
     147  $componentdir = core_component::get_component_directory($componentname);
     148  list($type, $plugin) = core_component::normalize_component($componentname);
     149  
     150  // Call the component to check/update the feed and tell us the path to the cached file.
     151  $pathname = null;
     152  
     153  if (file_exists($componentdir)) {
     154      require_once("$componentdir/rsslib.php");
     155      $functionname = $plugin.'_rss_get_feed';
     156  
     157      if (function_exists($functionname)) {
     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.
     160          try {
     161              $pathname = $functionname($context, $args);
     162          } catch (Exception $e) {
     163              rss_error('rsserror');
     164          }
     165      }
     166  }
     167  
     168  // Check that file exists.
     169  if (empty($pathname) || !file_exists($pathname)) {
     170      rss_error();
     171  }
     172  
     173  // Send the RSS file to the user!
     174  send_file($pathname, 'rss.xml', 3600);   // Cached by browsers for 1 hour.
     175  
     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
     183   * @param string $filename the name of the file to created
     184   * @param int $unused
     185   * @param string $statuscode http 1.1 statuscode indicicating the error
     186   * @uses exit
     187   */
     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);
     193      exit;
     194  }
    

    Search This Site: