[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/forum/ -> rsslib.php (source)

   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   * This file adds support to rss feeds generation
  20   *
  21   * @package   mod_forum
  22   * @category rss
  23   * @copyright 2001 Eloy Lafuente (stronk7) http://contiento.com
  24   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  25   */
  26  
  27  /* Include the core RSS lib */
  28  require_once($CFG->libdir.'/rsslib.php');
  29  
  30  /**
  31   * Returns the path to the cached rss feed contents. Creates/updates the cache if necessary.
  32   * @param stdClass $context the context
  33   * @param array    $args    the arguments received in the url
  34   * @return string the full path to the cached RSS feed directory. Null if there is a problem.
  35   */
  36  function forum_rss_get_feed($context, $args) {
  37      global $CFG, $DB, $USER;
  38  
  39      $status = true;
  40  
  41      //are RSS feeds enabled?
  42      if (empty($CFG->forum_enablerssfeeds)) {
  43          debugging('DISABLED (module configuration)');
  44          return null;
  45      }
  46  
  47      $forumid  = clean_param($args[3], PARAM_INT);
  48      $cm = get_coursemodule_from_instance('forum', $forumid, 0, false, MUST_EXIST);
  49      $modcontext = context_module::instance($cm->id);
  50  
  51      //context id from db should match the submitted one
  52      if ($context->id != $modcontext->id || !has_capability('mod/forum:viewdiscussion', $modcontext)) {
  53          return null;
  54      }
  55  
  56      $forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST);
  57      if (!rss_enabled_for_mod('forum', $forum)) {
  58          return null;
  59      }
  60  
  61      //the sql that will retreive the data for the feed and be hashed to get the cache filename
  62      list($sql, $params) = forum_rss_get_sql($forum, $cm);
  63  
  64      // Hash the sql to get the cache file name.
  65      $filename = rss_get_file_name($forum, $sql, $params);
  66      $cachedfilepath = rss_get_file_full_name('mod_forum', $filename);
  67  
  68      //Is the cache out of date?
  69      $cachedfilelastmodified = 0;
  70      if (file_exists($cachedfilepath)) {
  71          $cachedfilelastmodified = filemtime($cachedfilepath);
  72      }
  73      // Used to determine if we need to generate a new RSS feed.
  74      $dontrecheckcutoff = time() - 60; // Sixty seconds ago.
  75  
  76      // If it hasn't been generated we need to create it.
  77      // Otherwise, if it has been > 60 seconds since we last updated, check for new items.
  78      if (($cachedfilelastmodified == 0) || (($dontrecheckcutoff > $cachedfilelastmodified) &&
  79          forum_rss_newstuff($forum, $cm, $cachedfilelastmodified))) {
  80          // Need to regenerate the cached version.
  81          $result = forum_rss_feed_contents($forum, $sql, $params, $modcontext);
  82          $status = rss_save_file('mod_forum', $filename, $result);
  83      }
  84  
  85      //return the path to the cached version
  86      return $cachedfilepath;
  87  }
  88  
  89  /**
  90   * Given a forum object, deletes all cached RSS files associated with it.
  91   *
  92   * @param stdClass $forum
  93   */
  94  function forum_rss_delete_file($forum) {
  95      rss_delete_file('mod_forum', $forum);
  96  }
  97  
  98  ///////////////////////////////////////////////////////
  99  //Utility functions
 100  
 101  /**
 102   * If there is new stuff in the forum since $time this returns true
 103   * Otherwise it returns false.
 104   *
 105   * @param stdClass $forum the forum object
 106   * @param stdClass $cm    Course Module object
 107   * @param int      $time  check for items since this epoch timestamp
 108   * @return bool True for new items
 109   */
 110  function forum_rss_newstuff($forum, $cm, $time) {
 111      global $DB;
 112  
 113      list($sql, $params) = forum_rss_get_sql($forum, $cm, $time);
 114  
 115      return $DB->record_exists_sql($sql, $params);
 116  }
 117  
 118  /**
 119   * Determines which type of SQL query is required, one for posts or one for discussions, and returns the appropriate query
 120   *
 121   * @param stdClass $forum the forum object
 122   * @param stdClass $cm    Course Module object
 123   * @param int      $time  check for items since this epoch timestamp
 124   * @return string the SQL query to be used to get the Discussion/Post details from the forum table of the database
 125   */
 126  function forum_rss_get_sql($forum, $cm, $time=0) {
 127      if ($forum->rsstype == 1) { // Discussion RSS
 128          return forum_rss_feed_discussions_sql($forum, $cm, $time);
 129      } else { // Post RSS
 130          return forum_rss_feed_posts_sql($forum, $cm, $time);
 131      }
 132  }
 133  
 134  /**
 135   * Generates the SQL query used to get the Discussion details from the forum table of the database
 136   *
 137   * @param stdClass $forum     the forum object
 138   * @param stdClass $cm        Course Module object
 139   * @param int      $newsince  check for items since this epoch timestamp
 140   * @return string the SQL query to be used to get the Discussion details from the forum table of the database
 141   */
 142  function forum_rss_feed_discussions_sql($forum, $cm, $newsince=0) {
 143      global $CFG, $DB, $USER;
 144  
 145      $timelimit = '';
 146  
 147      $modcontext = null;
 148  
 149      $now = round(time(), -2);
 150      $params = array();
 151  
 152      $modcontext = context_module::instance($cm->id);
 153  
 154      if (!empty($CFG->forum_enabletimedposts)) { /// Users must fulfill timed posts
 155          if (!has_capability('mod/forum:viewhiddentimedposts', $modcontext)) {
 156              $timelimit = " AND ((d.timestart <= :now1 AND (d.timeend = 0 OR d.timeend > :now2))";
 157              $params['now1'] = $now;
 158              $params['now2'] = $now;
 159              if (isloggedin()) {
 160                  $timelimit .= " OR d.userid = :userid";
 161                  $params['userid'] = $USER->id;
 162              }
 163              $timelimit .= ")";
 164          }
 165      }
 166  
 167      // Do we only want new posts?
 168      if ($newsince) {
 169          $params['newsince'] = $newsince;
 170          $newsince = " AND p.modified > :newsince";
 171      } else {
 172          $newsince = '';
 173      }
 174  
 175      // Get group enforcing SQL.
 176      $groupmode = groups_get_activity_groupmode($cm);
 177      $currentgroup = groups_get_activity_group($cm);
 178      list($groupselect, $groupparams) = forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext);
 179  
 180      // Add the groupparams to the params array.
 181      $params = array_merge($params, $groupparams);
 182  
 183      $forumsort = "d.timemodified DESC";
 184      $postdata = "p.id AS postid, p.subject, p.created as postcreated, p.modified, p.discussion, p.userid, p.message as postmessage, p.messageformat AS postformat, p.messagetrust AS posttrust";
 185      $userpicturefields = user_picture::fields('u', null, 'userid');
 186  
 187      $sql = "SELECT $postdata, d.id as discussionid, d.name as discussionname, d.timemodified, d.usermodified, d.groupid,
 188                     d.timestart, d.timeend, $userpicturefields
 189                FROM {forum_discussions} d
 190                     JOIN {forum_posts} p ON p.discussion = d.id
 191                     JOIN {user} u ON p.userid = u.id
 192               WHERE d.forum = {$forum->id} AND p.parent = 0
 193                     $timelimit $groupselect $newsince
 194            ORDER BY $forumsort";
 195      return array($sql, $params);
 196  }
 197  
 198  /**
 199   * Generates the SQL query used to get the Post details from the forum table of the database
 200   *
 201   * @param stdClass $forum     the forum object
 202   * @param stdClass $cm        Course Module object
 203   * @param int      $newsince  check for items since this epoch timestamp
 204   * @return string the SQL query to be used to get the Post details from the forum table of the database
 205   */
 206  function forum_rss_feed_posts_sql($forum, $cm, $newsince=0) {
 207      $modcontext = context_module::instance($cm->id);
 208  
 209      // Get group enforcement SQL.
 210      $groupmode = groups_get_activity_groupmode($cm);
 211      $currentgroup = groups_get_activity_group($cm);
 212      $params = array();
 213  
 214      list($groupselect, $groupparams) = forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext);
 215  
 216      // Add the groupparams to the params array.
 217      $params = array_merge($params, $groupparams);
 218  
 219      // Do we only want new posts?
 220      if ($newsince) {
 221          $params['newsince'] = $newsince;
 222          $newsince = " AND p.modified > :newsince";
 223      } else {
 224          $newsince = '';
 225      }
 226  
 227      $usernamefields = get_all_user_name_fields(true, 'u');
 228      $sql = "SELECT p.id AS postid,
 229                   d.id AS discussionid,
 230                   d.name AS discussionname,
 231                   d.groupid,
 232                   d.timestart,
 233                   d.timeend,
 234                   u.id AS userid,
 235                   $usernamefields,
 236                   p.subject AS postsubject,
 237                   p.message AS postmessage,
 238                   p.created AS postcreated,
 239                   p.messageformat AS postformat,
 240                   p.messagetrust AS posttrust,
 241                   p.parent as postparent
 242              FROM {forum_discussions} d,
 243                 {forum_posts} p,
 244                 {user} u
 245              WHERE d.forum = {$forum->id} AND
 246                  p.discussion = d.id AND
 247                  u.id = p.userid $newsince
 248                  $groupselect
 249              ORDER BY p.created desc";
 250  
 251      return array($sql, $params);
 252  }
 253  
 254  /**
 255   * Retrieve the correct SQL snippet for group-only forums
 256   *
 257   * @param stdClass $cm           Course Module object
 258   * @param int      $groupmode    the mode in which the forum's groups are operating
 259   * @param bool     $currentgroup true if the user is from the a group enabled on the forum
 260   * @param stdClass $modcontext   The context instance of the forum module
 261   * @return string SQL Query for group details of the forum
 262   */
 263  function forum_rss_get_group_sql($cm, $groupmode, $currentgroup, $modcontext=null) {
 264      $groupselect = '';
 265      $params = array();
 266  
 267      if ($groupmode) {
 268          if ($groupmode == VISIBLEGROUPS or has_capability('moodle/site:accessallgroups', $modcontext)) {
 269              if ($currentgroup) {
 270                  $groupselect = "AND (d.groupid = :groupid OR d.groupid = -1)";
 271                  $params['groupid'] = $currentgroup;
 272              }
 273          } else {
 274              // Separate groups without access all.
 275              if ($currentgroup) {
 276                  $groupselect = "AND (d.groupid = :groupid OR d.groupid = -1)";
 277                  $params['groupid'] = $currentgroup;
 278              } else {
 279                  $groupselect = "AND d.groupid = -1";
 280              }
 281          }
 282      }
 283  
 284      return array($groupselect, $params);
 285  }
 286  
 287  /**
 288   * This function return the XML rss contents about the forum
 289   * It returns false if something is wrong
 290   *
 291   * @param stdClass $forum the forum object
 292   * @param string $sql the SQL used to retrieve the contents from the database
 293   * @param array $params the SQL parameters used
 294   * @param object $context the context this forum relates to
 295   * @return bool|string false if the contents is empty, otherwise the contents of the feed is returned
 296   *
 297   * @Todo MDL-31129 implement post attachment handling
 298   */
 299  
 300  function forum_rss_feed_contents($forum, $sql, $params, $context) {
 301      global $CFG, $DB, $USER;
 302  
 303      $status = true;
 304  
 305      $recs = $DB->get_recordset_sql($sql, $params, 0, $forum->rssarticles);
 306  
 307      //set a flag. Are we displaying discussions or posts?
 308      $isdiscussion = true;
 309      if (!empty($forum->rsstype) && $forum->rsstype!=1) {
 310          $isdiscussion = false;
 311      }
 312  
 313      if (!$cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course)) {
 314          print_error('invalidcoursemodule');
 315      }
 316  
 317      $formatoptions = new stdClass();
 318      $items = array();
 319      foreach ($recs as $rec) {
 320              $item = new stdClass();
 321  
 322              $discussion = new stdClass();
 323              $discussion->id = $rec->discussionid;
 324              $discussion->groupid = $rec->groupid;
 325              $discussion->timestart = $rec->timestart;
 326              $discussion->timeend = $rec->timeend;
 327  
 328              $post = null;
 329              if (!$isdiscussion) {
 330                  $post = new stdClass();
 331                  $post->id = $rec->postid;
 332                  $post->parent = $rec->postparent;
 333                  $post->userid = $rec->userid;
 334              }
 335  
 336              if ($isdiscussion && !forum_user_can_see_discussion($forum, $discussion, $context)) {
 337                  // This is a discussion which the user has no permission to view
 338                  $item->title = get_string('forumsubjecthidden', 'forum');
 339                  $message = get_string('forumbodyhidden', 'forum');
 340                  $item->author = get_string('forumauthorhidden', 'forum');
 341              } else if (!$isdiscussion && !forum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) {
 342                  // This is a post which the user has no permission to view
 343                  $item->title = get_string('forumsubjecthidden', 'forum');
 344                  $message = get_string('forumbodyhidden', 'forum');
 345                  $item->author = get_string('forumauthorhidden', 'forum');
 346              } else {
 347                  // The user must have permission to view
 348                  if ($isdiscussion && !empty($rec->discussionname)) {
 349                      $item->title = format_string($rec->discussionname);
 350                  } else if (!empty($rec->postsubject)) {
 351                      $item->title = format_string($rec->postsubject);
 352                  } else {
 353                      //we should have an item title by now but if we dont somehow then substitute something somewhat meaningful
 354                      $item->title = format_string($forum->name.' '.userdate($rec->postcreated,get_string('strftimedatetimeshort', 'langconfig')));
 355                  }
 356                  $item->author = fullname($rec);
 357                  $message = file_rewrite_pluginfile_urls($rec->postmessage, 'pluginfile.php', $context->id,
 358                          'mod_forum', 'post', $rec->postid);
 359                  $formatoptions->trusted = $rec->posttrust;
 360              }
 361  
 362              if ($isdiscussion) {
 363                  $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid;
 364              } else {
 365                  $item->link = $CFG->wwwroot."/mod/forum/discuss.php?d=".$rec->discussionid."&parent=".$rec->postid;
 366              }
 367  
 368              $formatoptions->trusted = $rec->posttrust;
 369              $item->description = format_text($message, $rec->postformat, $formatoptions, $forum->course);
 370  
 371              //TODO: MDL-31129 implement post attachment handling
 372              /*if (!$isdiscussion) {
 373                  $post_file_area_name = str_replace('//', '/', "$forum->course/$CFG->moddata/forum/$forum->id/$rec->postid");
 374                  $post_files = get_directory_list("$CFG->dataroot/$post_file_area_name");
 375  
 376                  if (!empty($post_files)) {
 377                      $item->attachments = array();
 378                  }
 379              }*/
 380              $item->pubdate = $rec->postcreated;
 381  
 382              $items[] = $item;
 383          }
 384      $recs->close();
 385  
 386      // Create the RSS header.
 387      $header = rss_standard_header(strip_tags(format_string($forum->name,true)),
 388                                    $CFG->wwwroot."/mod/forum/view.php?f=".$forum->id,
 389                                    format_string($forum->intro,true)); // TODO: fix format
 390      // Now all the RSS items, if there are any.
 391      $articles = '';
 392      if (!empty($items)) {
 393          $articles = rss_add_items($items);
 394      }
 395      // Create the RSS footer.
 396      $footer = rss_standard_footer();
 397  
 398      return $header . $articles . $footer;
 399  }


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1