Search moodle.org's
Developer Documentation

  • 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.
  • /mod/forum/ -> view.php (source)

    Differences Between: [Versions 310 and 311] [Versions 311 and 400] [Versions 37 and 311] [Versions 38 and 311] [Versions 39 and 311]

       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   * Displays the list of discussions in a forum.
      19   *
      20   * @package   mod_forum
      21   * @copyright 2019 Andrew Nicols <andrew@nicols.co.uk>
      22   * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
      23   */
      24  
      25  use mod_forum\grades\forum_gradeitem;
      26  
      27  require_once('../../config.php');
      28  
      29  $managerfactory = mod_forum\local\container::get_manager_factory();
      30  $legacydatamapperfactory = mod_forum\local\container::get_legacy_data_mapper_factory();
      31  $vaultfactory = mod_forum\local\container::get_vault_factory();
      32  $forumvault = $vaultfactory->get_forum_vault();
      33  $discussionvault = $vaultfactory->get_discussion_vault();
      34  $postvault = $vaultfactory->get_post_vault();
      35  $discussionlistvault = $vaultfactory->get_discussions_in_forum_vault();
      36  
      37  $cmid = optional_param('id', 0, PARAM_INT);
      38  $forumid = optional_param('f', 0, PARAM_INT);
      39  $mode = optional_param('mode', 0, PARAM_INT);
      40  $showall = optional_param('showall', '', PARAM_INT);
      41  $pageno = optional_param('page', 0, PARAM_INT);
      42  $search = optional_param('search', '', PARAM_CLEAN);
      43  $pageno = optional_param('p', $pageno, PARAM_INT);
      44  $pagesize = optional_param('s', 0, PARAM_INT);
      45  $sortorder = optional_param('o', null, PARAM_INT);
      46  
      47  if (!$cmid && !$forumid) {
      48      print_error('missingparameter');
      49  }
      50  
      51  if ($cmid) {
      52      $forum = $forumvault->get_from_course_module_id($cmid);
      53      if (empty($forum)) {
      54          throw new \moodle_exception('Unable to find forum with cmid ' . $cmid);
      55      }
      56  } else {
      57      $forum = $forumvault->get_from_id($forumid);
      58      if (empty($forum)) {
      59          throw new \moodle_exception('Unable to find forum with id ' . $forumid);
      60      }
      61  }
      62  
      63  if (!empty($showall)) {
      64      // The user wants to see all discussions.
      65      $pageno = 0;
      66      $pagesize = 0;
      67  }
      68  
      69  $urlfactory = mod_forum\local\container::get_url_factory();
      70  $capabilitymanager = $managerfactory->get_capability_manager($forum);
      71  
      72  $url = $urlfactory->get_forum_view_url_from_forum($forum);
      73  $PAGE->set_url($url);
      74  
      75  $course = $forum->get_course_record();
      76  $coursemodule = $forum->get_course_module_record();
      77  $cm = \cm_info::create($coursemodule);
      78  
      79  require_course_login($course, true, $cm);
      80  
      81  $istypesingle = $forum->get_type() === 'single';
      82  $saveddisplaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode);
      83  
      84  if ($mode) {
      85      $displaymode = $mode;
      86  } else {
      87      $displaymode = $saveddisplaymode;
      88  }
      89  
      90  if (get_user_preferences('forum_useexperimentalui', false)) {
      91      if ($displaymode == FORUM_MODE_NESTED) {
      92          $displaymode = FORUM_MODE_NESTED_V2;
      93      }
      94  } else {
      95      if ($displaymode == FORUM_MODE_NESTED_V2) {
      96          $displaymode = FORUM_MODE_NESTED;
      97      }
      98  }
      99  
     100  if ($displaymode != $saveddisplaymode) {
     101      set_user_preference('forum_displaymode', $displaymode);
     102  }
     103  
     104  $PAGE->set_context($forum->get_context());
     105  $PAGE->set_title($forum->get_name());
     106  $PAGE->add_body_class('forumtype-' . $forum->get_type());
     107  $PAGE->set_heading($course->fullname);
     108  $PAGE->set_button(forum_search_form($course, $search));
     109  
     110  if ($istypesingle && $displaymode == FORUM_MODE_NESTED_V2) {
     111      $PAGE->add_body_class('nested-v2-display-mode reset-style');
     112      $settingstrigger = $OUTPUT->render_from_template('mod_forum/settings_drawer_trigger', null);
     113      $PAGE->add_header_action($settingstrigger);
     114  }
     115  
     116  if (empty($cm->visible) && !has_capability('moodle/course:viewhiddenactivities', $forum->get_context())) {
     117      redirect(
     118          $urlfactory->get_course_url_from_forum($forum),
     119          get_string('activityiscurrentlyhidden'),
     120          null,
     121          \core\output\notification::NOTIFY_WARNING
     122      );
     123  }
     124  
     125  if (!$capabilitymanager->can_view_discussions($USER)) {
     126      redirect(
     127          $urlfactory->get_course_url_from_forum($forum),
     128          get_string('noviewdiscussionspermission', 'forum'),
     129          null,
     130          \core\output\notification::NOTIFY_WARNING
     131      );
     132  }
     133  
     134  // Mark viewed and trigger the course_module_viewed event.
     135  $forumdatamapper = $legacydatamapperfactory->get_forum_data_mapper();
     136  $forumrecord = $forumdatamapper->to_legacy_object($forum);
     137  forum_view(
     138      $forumrecord,
     139      $forum->get_course_record(),
     140      $forum->get_course_module_record(),
     141      $forum->get_context()
     142  );
     143  
     144  // Return here if we post or set subscription etc.
     145  $SESSION->fromdiscussion = qualified_me();
     146  
     147  if (!empty($CFG->enablerssfeeds) && !empty($CFG->forum_enablerssfeeds) && $forum->get_rss_type() && $forum->get_rss_articles()) {
     148      require_once("{$CFG->libdir}/rsslib.php");
     149  
     150      $rsstitle = format_string($course->shortname, true, [
     151              'context' => context_course::instance($course->id),
     152          ]) . ': ' . format_string($forum->get_name());
     153      rss_add_http_header($forum->get_context(), 'mod_forum', $forumrecord, $rsstitle);
     154  }
     155  
     156  echo $OUTPUT->header();
     157  echo $OUTPUT->heading(format_string($forum->get_name()), 2);
     158  
     159  // Render the activity information.
     160  $completiondetails = \core_completion\cm_completion_details::get_instance($cm, $USER->id);
     161  $activitydates = \core\activity_dates::get_dates_for_module($cm, $USER->id);
     162  echo $OUTPUT->activity_information($cm, $completiondetails, $activitydates);
     163  
     164  if (!$istypesingle && !empty($forum->get_intro())) {
     165      echo $OUTPUT->box(format_module_intro('forum', $forumrecord, $cm->id), 'generalbox', 'intro');
     166  }
     167  
     168  if ($sortorder) {
     169      set_user_preference('forum_discussionlistsortorder', $sortorder);
     170  }
     171  
     172  $sortorder = get_user_preferences('forum_discussionlistsortorder', $discussionlistvault::SORTORDER_LASTPOST_DESC);
     173  
     174  // Fetch the current groupid.
     175  $groupid = groups_get_activity_group($cm, true) ?: null;
     176  $rendererfactory = mod_forum\local\container::get_renderer_factory();
     177  switch ($forum->get_type()) {
     178      case 'single':
     179          $forumgradeitem = forum_gradeitem::load_from_forum_entity($forum);
     180          if ($capabilitymanager->can_grade($USER)) {
     181  
     182              if ($forumgradeitem->is_grading_enabled()) {
     183                  $groupid = groups_get_activity_group($cm, true) ?: null;
     184                  $gradeobj = (object) [
     185                      'contextid' => $forum->get_context()->id,
     186                      'cmid' => $cmid,
     187                      'name' => format_string($forum->get_name()),
     188                      'courseid' => $course->id,
     189                      'coursename' => format_string($course->shortname),
     190                      'experimentaldisplaymode' => $displaymode == FORUM_MODE_NESTED_V2,
     191                      'groupid' => $groupid,
     192                      'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
     193                      'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
     194                      'sendstudentnotifications' => $forum->should_notify_students_default_when_grade_for_forum(),
     195                  ];
     196                  echo $OUTPUT->render_from_template('mod_forum/grades/grade_button', $gradeobj);
     197              }
     198          } else {
     199              if ($forumgradeitem->is_grading_enabled()) {
     200                  $groupid = groups_get_activity_group($cm, true) ?: null;
     201                  $gradeobj = (object) [
     202                      'contextid' => $forum->get_context()->id,
     203                      'cmid' => $cmid,
     204                      'name' => format_string($forum->get_name()),
     205                      'courseid' => $course->id,
     206                      'coursename' => format_string($course->shortname),
     207                      'groupid' => $groupid,
     208                      'userid' => $USER->id,
     209                      'gradingcomponent' => $forumgradeitem->get_grading_component_name(),
     210                      'gradingcomponentsubtype' => $forumgradeitem->get_grading_component_subtype(),
     211                  ];
     212                  echo $OUTPUT->render_from_template('mod_forum/grades/view_grade_button', $gradeobj);
     213              }
     214          }
     215          $discussion = $discussionvault->get_last_discussion_in_forum($forum);
     216          $discussioncount = $discussionvault->get_count_discussions_in_forum($forum);
     217          $hasmultiplediscussions = $discussioncount > 1;
     218          $discussionsrenderer = $rendererfactory->get_single_discussion_list_renderer($forum, $discussion,
     219              $hasmultiplediscussions, $displaymode);
     220          $post = $postvault->get_from_id($discussion->get_first_post_id());
     221          $orderpostsby = $displaymode == FORUM_MODE_FLATNEWEST ? 'created DESC' : 'created ASC';
     222          $replies = $postvault->get_replies_to_post(
     223                  $USER,
     224                  $post,
     225                  $capabilitymanager->can_view_any_private_reply($USER),
     226                  $orderpostsby
     227              );
     228          echo $discussionsrenderer->render($USER, $post, $replies);
     229  
     230          if (!$CFG->forum_usermarksread && forum_tp_is_tracked($forumrecord, $USER)) {
     231              $postids = array_map(function($post) {
     232                  return $post->get_id();
     233              }, array_merge([$post], array_values($replies)));
     234              forum_tp_mark_posts_read($USER, $postids);
     235          }
     236          break;
     237      case 'blog':
     238          $discussionsrenderer = $rendererfactory->get_blog_discussion_list_renderer($forum);
     239          // Blog forums always show discussions newest first.
     240          echo $discussionsrenderer->render($USER, $cm, $groupid, $discussionlistvault::SORTORDER_CREATED_DESC,
     241              $pageno, $pagesize);
     242  
     243          if (!$CFG->forum_usermarksread && forum_tp_is_tracked($forumrecord, $USER)) {
     244              $discussions = mod_forum_get_discussion_summaries($forum, $USER, $groupid, null, $pageno, $pagesize);
     245              $firstpostids = array_map(function($discussion) {
     246                  return $discussion->get_first_post()->get_id();
     247              }, array_values($discussions));
     248              forum_tp_mark_posts_read($USER, $firstpostids);
     249          }
     250          break;
     251      default:
     252          $discussionsrenderer = $rendererfactory->get_discussion_list_renderer($forum);
     253          echo $discussionsrenderer->render($USER, $cm, $groupid, $sortorder, $pageno, $pagesize, $displaymode);
     254  }
     255  
     256  echo $OUTPUT->footer();