Search moodle.org's
Developer Documentation

See Release Notes

  • Bug fixes for general core bugs in 3.11.x will end 14 Nov 2022 (12 months plus 6 months extension).
  • Bug fixes for security issues in 3.11.x will end 13 Nov 2023 (18 months plus 12 months extension).
  • PHP version: minimum PHP 7.3.0 Note: minimum PHP version has increased since Moodle 3.10. PHP 7.4.x is supported too.

Differences Between: [Versions 310 and 311] [Versions 39 and 311]

   1  <?php
   2  
   3  // This file is part of Moodle - http://moodle.org/
   4  //
   5  // Moodle is free software: you can redistribute it and/or modify
   6  // it under the terms of the GNU General Public License as published by
   7  // the Free Software Foundation, either version 3 of the License, or
   8  // (at your option) any later version.
   9  //
  10  // Moodle is distributed in the hope that it will be useful,
  11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13  // GNU General Public License for more details.
  14  //
  15  // You should have received a copy of the GNU General Public License
  16  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  17  
  18  
  19  /**
  20   * This file adds support to rss feeds generation
  21   *
  22   * @package mod_glossary
  23   * @category rss
  24   * @copyright  1999 onwards Martin Dougiamas  {@link http://moodle.com}
  25   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  26   */
  27  
  28  /**
  29   * Returns the path to the cached rss feed contents. Creates/updates the cache if necessary.
  30   *
  31   * @param stdClass $context the context
  32   * @param array    $args    the arguments received in the url
  33   * @return string the full path to the cached RSS feed directory. Null if there is a problem.
  34   */
  35      function glossary_rss_get_feed($context, $args) {
  36          global $CFG, $DB, $COURSE, $USER;
  37  
  38          $status = true;
  39  
  40          if (empty($CFG->glossary_enablerssfeeds)) {
  41              debugging("DISABLED (module configuration)");
  42              return null;
  43          }
  44  
  45          $glossaryid  = clean_param($args[3], PARAM_INT);
  46          $cm = get_coursemodule_from_instance('glossary', $glossaryid, 0, false, MUST_EXIST);
  47          $modcontext = context_module::instance($cm->id);
  48  
  49          if ($COURSE->id == $cm->course) {
  50              $course = $COURSE;
  51          } else {
  52              $course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
  53          }
  54          //context id from db should match the submitted one
  55          if ($context->id != $modcontext->id || !has_capability('mod/glossary:view', $modcontext)) {
  56              return null;
  57          }
  58  
  59          $glossary = $DB->get_record('glossary', array('id' => $glossaryid), '*', MUST_EXIST);
  60          if (!rss_enabled_for_mod('glossary', $glossary)) {
  61              return null;
  62          }
  63  
  64          $sql = glossary_rss_get_sql($glossary);
  65  
  66          //get the cache file info
  67          $filename = rss_get_file_name($glossary, $sql);
  68          $cachedfilepath = rss_get_file_full_name('mod_glossary', $filename);
  69  
  70          //Is the cache out of date?
  71          $cachedfilelastmodified = 0;
  72          if (file_exists($cachedfilepath)) {
  73              $cachedfilelastmodified = filemtime($cachedfilepath);
  74          }
  75          //if the cache is more than 60 seconds old and there's new stuff
  76          $dontrecheckcutoff = time()-60;
  77          if ( $dontrecheckcutoff > $cachedfilelastmodified && glossary_rss_newstuff($glossary, $cachedfilelastmodified)) {
  78              if (!$recs = $DB->get_records_sql($sql, array(), 0, $glossary->rssarticles)) {
  79                  return null;
  80              }
  81  
  82              $items = array();
  83  
  84              $formatoptions = new stdClass();
  85              $formatoptions->trusttext = true;
  86  
  87              foreach ($recs as $rec) {
  88                  $item = new stdClass();
  89                  $item->title = $rec->entryconcept;
  90  
  91                  if ($glossary->rsstype == 1) {//With author
  92                      $item->author = fullname($rec);
  93                  }
  94  
  95                  $item->pubdate = $rec->entrytimecreated;
  96                  $item->link = $CFG->wwwroot."/mod/glossary/showentry.php?courseid=".$glossary->course."&eid=".$rec->entryid;
  97  
  98                  $definition = file_rewrite_pluginfile_urls($rec->entrydefinition, 'pluginfile.php',
  99                      $modcontext->id, 'mod_glossary', 'entry', $rec->entryid);
 100                  $item->description = format_text($definition, $rec->entryformat, $formatoptions, $glossary->course);
 101                  $items[] = $item;
 102              }
 103  
 104              //First all rss feeds common headers
 105              $header = rss_standard_header(format_string($glossary->name,true),
 106                                            $CFG->wwwroot."/mod/glossary/view.php?g=".$glossary->id,
 107                                            format_string($glossary->intro,true));
 108              //Now all the rss items
 109              if (!empty($header)) {
 110                  $articles = rss_add_items($items);
 111              }
 112              //Now all rss feeds common footers
 113              if (!empty($header) && !empty($articles)) {
 114                  $footer = rss_standard_footer();
 115              }
 116              //Now, if everything is ok, concatenate it
 117              if (!empty($header) && !empty($articles) && !empty($footer)) {
 118                  $rss = $header.$articles.$footer;
 119  
 120                  //Save the XML contents to file.
 121                  $status = rss_save_file('mod_glossary', $filename, $rss);
 122              }
 123          }
 124  
 125          if (!$status) {
 126              $cachedfilepath = null;
 127          }
 128  
 129          return $cachedfilepath;
 130      }
 131  
 132      /**
 133       * The appropriate SQL query for the glossary items to go into the RSS feed
 134       *
 135       * @param stdClass $glossary the glossary object
 136       * @param int      $time     check for items since this epoch timestamp
 137       * @return string the SQL query to be used to get the entried from the glossary table of the database
 138       */
 139      function glossary_rss_get_sql($glossary, $time=0) {
 140          //do we only want new items?
 141          if ($time) {
 142              $time = "AND e.timecreated > $time";
 143          } else {
 144              $time = "";
 145          }
 146  
 147          if ($glossary->rsstype == 1) {//With author
 148              $userfieldsapi = \core_user\fields::for_name();
 149              $allnamefields = $userfieldsapi->get_sql('u', false, '', '', false)->selects;
 150              $sql = "SELECT e.id AS entryid,
 151                        e.concept AS entryconcept,
 152                        e.definition AS entrydefinition,
 153                        e.definitionformat AS entryformat,
 154                        e.definitiontrust AS entrytrust,
 155                        e.timecreated AS entrytimecreated,
 156                        u.id AS userid,
 157                        $allnamefields
 158                   FROM {glossary_entries} e,
 159                        {user} u
 160                  WHERE e.glossaryid = {$glossary->id} AND
 161                        u.id = e.userid AND
 162                        e.approved = 1 $time
 163               ORDER BY e.timecreated desc";
 164          } else {//Without author
 165              $sql = "SELECT e.id AS entryid,
 166                        e.concept AS entryconcept,
 167                        e.definition AS entrydefinition,
 168                        e.definitionformat AS entryformat,
 169                        e.definitiontrust AS entrytrust,
 170                        e.timecreated AS entrytimecreated,
 171                        u.id AS userid
 172                   FROM {glossary_entries} e,
 173                        {user} u
 174                  WHERE e.glossaryid = {$glossary->id} AND
 175                        u.id = e.userid AND
 176                        e.approved = 1 $time
 177               ORDER BY e.timecreated desc";
 178          }
 179  
 180          return $sql;
 181      }
 182  
 183      /**
 184       * If there is new stuff in since $time this returns true
 185       * Otherwise it returns false.
 186       *
 187       * @param stdClass $glossary the glossary activity object
 188       * @param int      $time     epoch timestamp to compare new items against, 0 for everyting
 189       * @return bool true if there are new items
 190       */
 191      function glossary_rss_newstuff($glossary, $time) {
 192          global $DB;
 193  
 194          $sql = glossary_rss_get_sql($glossary, $time);
 195  
 196          $recs = $DB->get_records_sql($sql, null, 0, 1);//limit of 1. If we get even 1 back we have new stuff
 197          return ($recs && !empty($recs));
 198      }
 199  
 200      /**
 201        * Given a glossary object, deletes all cached RSS files associated with it.
 202        *
 203        * @param stdClass $glossary
 204        */
 205      function glossary_rss_delete_file($glossary) {
 206          global $CFG;
 207          require_once("$CFG->libdir/rsslib.php");
 208  
 209          rss_delete_file('mod_glossary', $glossary);
 210      }