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 * @package   mod_forum
20 * @copyright 1999 onwards Martin Dougiamas  {@link http://moodle.com}
21 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
22 */
23
24require_once(__DIR__ . '/../../config.php');
25require_once($CFG->dirroot . '/course/lib.php');
26require_once($CFG->dirroot . '/mod/forum/lib.php');
27require_once($CFG->libdir . '/rsslib.php');
28
29$id = optional_param('id', 0, PARAM_INT);                   // Course id
30$subscribe = optional_param('subscribe', null, PARAM_INT);  // Subscribe/Unsubscribe all forums
31
32$url = new moodle_url('/mod/forum/index.php', array('id' => $id));
33if ($subscribe !== null) {
34    require_sesskey();
35    $url->param('subscribe', $subscribe);
36}
37$PAGE->set_url($url);
38
39if ($id) {
40    if (!$course = $DB->get_record('course', array('id' => $id))) {
41        print_error('invalidcourseid');
42    }
43} else {
44    $course = get_site();
45}
46
47require_course_login($course);
48$PAGE->set_pagelayout('incourse');
49$coursecontext = context_course::instance($course->id);
50
51unset($SESSION->fromdiscussion);
52
53$params = array(
54    'context' => context_course::instance($course->id)
55);
56$event = \mod_forum\event\course_module_instance_list_viewed::create($params);
57$event->add_record_snapshot('course', $course);
58$event->trigger();
59
60$strforums       = get_string('forums', 'forum');
61$strforum        = get_string('forum', 'forum');
62$strdescription  = get_string('description');
63$strdiscussions  = get_string('discussions', 'forum');
64$strsubscribed   = get_string('subscribed', 'forum');
65$strunreadposts  = get_string('unreadposts', 'forum');
66$strtracking     = get_string('tracking', 'forum');
67$strmarkallread  = get_string('markallread', 'forum');
68$strtrackforum   = get_string('trackforum', 'forum');
69$strnotrackforum = get_string('notrackforum', 'forum');
70$strsubscribe    = get_string('subscribe', 'forum');
71$strunsubscribe  = get_string('unsubscribe', 'forum');
72$stryes          = get_string('yes');
73$strno           = get_string('no');
74$strrss          = get_string('rss');
75$stremaildigest  = get_string('emaildigest');
76
77$searchform = forum_search_form($course);
78
79// Start of the table for General Forums.
80$generaltable = new html_table();
81$generaltable->head  = array ($strforum, $strdescription, $strdiscussions);
82$generaltable->align = array ('left', 'left', 'center');
83
84if ($usetracking = forum_tp_can_track_forums()) {
85    $untracked = forum_tp_get_untracked_forums($USER->id, $course->id);
86
87    $generaltable->head[] = $strunreadposts;
88    $generaltable->align[] = 'center';
89
90    $generaltable->head[] = $strtracking;
91    $generaltable->align[] = 'center';
92}
93
94// Fill the subscription cache for this course and user combination.
95\mod_forum\subscriptions::fill_subscription_cache_for_course($course->id, $USER->id);
96
97$usesections = course_format_uses_sections($course->format);
98
99$table = new html_table();
100
101// Parse and organise all the forums.  Most forums are course modules but
102// some special ones are not.  These get placed in the general forums
103// category with the forums in section 0.
104
105$forums = $DB->get_records_sql("
106    SELECT f.*,
107           d.maildigest
108      FROM {forum} f
109 LEFT JOIN {forum_digests} d ON d.forum = f.id AND d.userid = ?
110     WHERE f.course = ?
111    ", array($USER->id, $course->id));
112
113$generalforums  = array();
114$learningforums = array();
115$modinfo = get_fast_modinfo($course);
116$showsubscriptioncolumns = false;
117
118foreach ($modinfo->get_instances_of('forum') as $forumid => $cm) {
119    if (!$cm->uservisible or !isset($forums[$forumid])) {
120        continue;
121    }
122
123    $forum = $forums[$forumid];
124
125    if (!$context = context_module::instance($cm->id, IGNORE_MISSING)) {
126        // Shouldn't happen.
127        continue;
128    }
129
130    if (!has_capability('mod/forum:viewdiscussion', $context)) {
131        // User can't view this one - skip it.
132        continue;
133    }
134
135    // Determine whether subscription options should be displayed.
136    $forum->cansubscribe = mod_forum\subscriptions::is_subscribable($forum);
137    $forum->cansubscribe = $forum->cansubscribe || has_capability('mod/forum:managesubscriptions', $context);
138    $forum->issubscribed = mod_forum\subscriptions::is_subscribed($USER->id, $forum, null, $cm);
139
140    $showsubscriptioncolumns = $showsubscriptioncolumns || $forum->issubscribed || $forum->cansubscribe;
141
142    // Fill two type array - order in modinfo is the same as in course.
143    if ($forum->type == 'news' or $forum->type == 'social') {
144        $generalforums[$forum->id] = $forum;
145
146    } else if ($course->id == SITEID or empty($cm->sectionnum)) {
147        $generalforums[$forum->id] = $forum;
148
149    } else {
150        $learningforums[$forum->id] = $forum;
151    }
152}
153
154if ($showsubscriptioncolumns) {
155    // The user can subscribe to at least one forum.
156    $generaltable->head[] = $strsubscribed;
157    $generaltable->align[] = 'center';
158
159    $generaltable->head[] = $stremaildigest . ' ' . $OUTPUT->help_icon('emaildigesttype', 'mod_forum');
160    $generaltable->align[] = 'center';
161
162}
163
164if ($show_rss = (($showsubscriptioncolumns || $course->id == SITEID) &&
165                 isset($CFG->enablerssfeeds) && isset($CFG->forum_enablerssfeeds) &&
166                 $CFG->enablerssfeeds && $CFG->forum_enablerssfeeds)) {
167    $generaltable->head[] = $strrss;
168    $generaltable->align[] = 'center';
169}
170
171
172// Do course wide subscribe/unsubscribe if requested
173if (!is_null($subscribe)) {
174    if (isguestuser() or !$showsubscriptioncolumns) {
175        // There should not be any links leading to this place, just redirect.
176        redirect(
177                new moodle_url('/mod/forum/index.php', array('id' => $id)),
178                get_string('subscribeenrolledonly', 'forum'),
179                null,
180                \core\output\notification::NOTIFY_ERROR
181            );
182    }
183    // Can proceed now, the user is not guest and is enrolled
184    foreach ($modinfo->get_instances_of('forum') as $forumid => $cm) {
185        $forum = $forums[$forumid];
186        $modcontext = context_module::instance($cm->id);
187        $cansub = false;
188
189        if (has_capability('mod/forum:viewdiscussion', $modcontext)) {
190            $cansub = true;
191        }
192        if ($cansub && $cm->visible == 0 &&
193            !has_capability('mod/forum:managesubscriptions', $modcontext))
194        {
195            $cansub = false;
196        }
197        if (!\mod_forum\subscriptions::is_forcesubscribed($forum)) {
198            $subscribed = \mod_forum\subscriptions::is_subscribed($USER->id, $forum, null, $cm);
199            $canmanageactivities = has_capability('moodle/course:manageactivities', $coursecontext, $USER->id);
200            if (($canmanageactivities || \mod_forum\subscriptions::is_subscribable($forum)) && $subscribe && !$subscribed && $cansub) {
201                \mod_forum\subscriptions::subscribe_user($USER->id, $forum, $modcontext, true);
202            } else if (!$subscribe && $subscribed) {
203                \mod_forum\subscriptions::unsubscribe_user($USER->id, $forum, $modcontext, true);
204            }
205        }
206    }
207    $returnto = forum_go_back_to(new moodle_url('/mod/forum/index.php', array('id' => $course->id)));
208    $shortname = format_string($course->shortname, true, array('context' => context_course::instance($course->id)));
209    if ($subscribe) {
210        redirect(
211                $returnto,
212                get_string('nowallsubscribed', 'forum', $shortname),
213                null,
214                \core\output\notification::NOTIFY_SUCCESS
215            );
216    } else {
217        redirect(
218                $returnto,
219                get_string('nowallunsubscribed', 'forum', $shortname),
220                null,
221                \core\output\notification::NOTIFY_SUCCESS
222            );
223    }
224}
225
226if ($generalforums) {
227    // Process general forums.
228    foreach ($generalforums as $forum) {
229        $cm      = $modinfo->instances['forum'][$forum->id];
230        $context = context_module::instance($cm->id);
231
232        $count = forum_count_discussions($forum, $cm, $course);
233
234        if ($usetracking) {
235            if ($forum->trackingtype == FORUM_TRACKING_OFF) {
236                $unreadlink  = '-';
237                $trackedlink = '-';
238
239            } else {
240                if (isset($untracked[$forum->id])) {
241                        $unreadlink  = '-';
242                } else if ($unread = forum_tp_count_forum_unread_posts($cm, $course)) {
243                    $unreadlink = '<span class="unread"><a href="view.php?f='.$forum->id.'#unread">'.$unread.'</a>';
244                    $icon = $OUTPUT->pix_icon('t/markasread', $strmarkallread);
245                    $unreadlink .= '<a title="'.$strmarkallread.'" href="markposts.php?f='.
246                                   $forum->id.'&amp;mark=read&amp;sesskey=' . sesskey() . '">' . $icon . '</a></span>';
247                } else {
248                    $unreadlink = '<span class="read">0</span>';
249                }
250
251                if (($forum->trackingtype == FORUM_TRACKING_FORCED) && ($CFG->forum_allowforcedreadtracking)) {
252                    $trackedlink = $stryes;
253                } else if ($forum->trackingtype === FORUM_TRACKING_OFF || ($USER->trackforums == 0)) {
254                    $trackedlink = '-';
255                } else {
256                    $aurl = new moodle_url('/mod/forum/settracking.php', array(
257                            'id' => $forum->id,
258                            'sesskey' => sesskey(),
259                        ));
260                    if (!isset($untracked[$forum->id])) {
261                        $trackedlink = $OUTPUT->single_button($aurl, $stryes, 'post', array('title' => $strnotrackforum));
262                    } else {
263                        $trackedlink = $OUTPUT->single_button($aurl, $strno, 'post', array('title' => $strtrackforum));
264                    }
265                }
266            }
267        }
268
269        $forum->intro = shorten_text(format_module_intro('forum', $forum, $cm->id), $CFG->forum_shortpost);
270        $forumname = format_string($forum->name, true);
271
272        if ($cm->visible) {
273            $style = '';
274        } else {
275            $style = 'class="dimmed"';
276        }
277        $forumlink = "<a href=\"view.php?f=$forum->id\" $style>".format_string($forum->name,true)."</a>";
278        $discussionlink = "<a href=\"view.php?f=$forum->id\" $style>".$count."</a>";
279
280        $row = array ($forumlink, $forum->intro, $discussionlink);
281        if ($usetracking) {
282            $row[] = $unreadlink;
283            $row[] = $trackedlink;    // Tracking.
284        }
285
286        if ($showsubscriptioncolumns) {
287            $row[] = forum_get_subscribe_link($forum, $context, array('subscribed' => $stryes,
288                'unsubscribed' => $strno, 'forcesubscribed' => $stryes,
289                'cantsubscribe' => '-'), false, false, true);
290            $row[] = forum_index_get_forum_subscription_selector($forum);
291        }
292
293        // If this forum has RSS activated, calculate it.
294        if ($show_rss) {
295            if ($forum->rsstype and $forum->rssarticles) {
296                //Calculate the tooltip text
297                if ($forum->rsstype == 1) {
298                    $tooltiptext = get_string('rsssubscriberssdiscussions', 'forum');
299                } else {
300                    $tooltiptext = get_string('rsssubscriberssposts', 'forum');
301                }
302
303                if (!isloggedin() && $course->id == SITEID) {
304                    $userid = guest_user()->id;
305                } else {
306                    $userid = $USER->id;
307                }
308                //Get html code for RSS link
309                $row[] = rss_get_link($context->id, $userid, 'mod_forum', $forum->id, $tooltiptext);
310            } else {
311                $row[] = '&nbsp;';
312            }
313        }
314
315        $generaltable->data[] = $row;
316    }
317}
318
319
320// Start of the table for Learning Forums
321$learningtable = new html_table();
322$learningtable->head  = array ($strforum, $strdescription, $strdiscussions);
323$learningtable->align = array ('left', 'left', 'center');
324
325if ($usetracking) {
326    $learningtable->head[] = $strunreadposts;
327    $learningtable->align[] = 'center';
328
329    $learningtable->head[] = $strtracking;
330    $learningtable->align[] = 'center';
331}
332
333if ($showsubscriptioncolumns) {
334    $learningtable->head[] = $strsubscribed;
335    $learningtable->align[] = 'center';
336
337    $learningtable->head[] = $stremaildigest . ' ' . $OUTPUT->help_icon('emaildigesttype', 'mod_forum');
338    $learningtable->align[] = 'center';
339}
340
341if ($show_rss = (($showsubscriptioncolumns || $course->id == SITEID) &&
342                 isset($CFG->enablerssfeeds) && isset($CFG->forum_enablerssfeeds) &&
343                 $CFG->enablerssfeeds && $CFG->forum_enablerssfeeds)) {
344    $learningtable->head[] = $strrss;
345    $learningtable->align[] = 'center';
346}
347
348// Now let's process the learning forums.
349if ($course->id != SITEID) {    // Only real courses have learning forums
350    // 'format_.'$course->format only applicable when not SITEID (format_site is not a format)
351    $strsectionname  = get_string('sectionname', 'format_'.$course->format);
352    // Add extra field for section number, at the front
353    array_unshift($learningtable->head, $strsectionname);
354    array_unshift($learningtable->align, 'center');
355
356
357    if ($learningforums) {
358        $currentsection = '';
359            foreach ($learningforums as $forum) {
360            $cm      = $modinfo->instances['forum'][$forum->id];
361            $context = context_module::instance($cm->id);
362
363            $count = forum_count_discussions($forum, $cm, $course);
364
365            if ($usetracking) {
366                if ($forum->trackingtype == FORUM_TRACKING_OFF) {
367                    $unreadlink  = '-';
368                    $trackedlink = '-';
369
370                } else {
371                    if (isset($untracked[$forum->id])) {
372                        $unreadlink  = '-';
373                    } else if ($unread = forum_tp_count_forum_unread_posts($cm, $course)) {
374                        $unreadlink = '<span class="unread"><a href="view.php?f='.$forum->id.'#unread">'.$unread.'</a>';
375                        $icon = $OUTPUT->pix_icon('t/markasread', $strmarkallread);
376                        $unreadlink .= '<a title="'.$strmarkallread.'" href="markposts.php?f='.
377                                       $forum->id.'&amp;mark=read&sesskey=' . sesskey() . '">' . $icon . '</a></span>';
378                    } else {
379                        $unreadlink = '<span class="read">0</span>';
380                    }
381
382                    if (($forum->trackingtype == FORUM_TRACKING_FORCED) && ($CFG->forum_allowforcedreadtracking)) {
383                        $trackedlink = $stryes;
384                    } else if ($forum->trackingtype === FORUM_TRACKING_OFF || ($USER->trackforums == 0)) {
385                        $trackedlink = '-';
386                    } else {
387                        $aurl = new moodle_url('/mod/forum/settracking.php', array('id' => $forum->id));
388                        if (!isset($untracked[$forum->id])) {
389                            $trackedlink = $OUTPUT->single_button($aurl, $stryes, 'post', array('title' => $strnotrackforum));
390                        } else {
391                            $trackedlink = $OUTPUT->single_button($aurl, $strno, 'post', array('title' => $strtrackforum));
392                        }
393                    }
394                }
395            }
396
397            $forum->intro = shorten_text(format_module_intro('forum', $forum, $cm->id), $CFG->forum_shortpost);
398
399            if ($cm->sectionnum != $currentsection) {
400                $printsection = get_section_name($course, $cm->sectionnum);
401                if ($currentsection) {
402                    $learningtable->data[] = 'hr';
403                }
404                $currentsection = $cm->sectionnum;
405            } else {
406                $printsection = '';
407            }
408
409            $forumname = format_string($forum->name,true);
410
411            if ($cm->visible) {
412                $style = '';
413            } else {
414                $style = 'class="dimmed"';
415            }
416            $forumlink = "<a href=\"view.php?f=$forum->id\" $style>".format_string($forum->name,true)."</a>";
417            $discussionlink = "<a href=\"view.php?f=$forum->id\" $style>".$count."</a>";
418
419            $row = array ($printsection, $forumlink, $forum->intro, $discussionlink);
420            if ($usetracking) {
421                $row[] = $unreadlink;
422                $row[] = $trackedlink;    // Tracking.
423            }
424
425            if ($showsubscriptioncolumns) {
426                $row[] = forum_get_subscribe_link($forum, $context, array('subscribed' => $stryes,
427                    'unsubscribed' => $strno, 'forcesubscribed' => $stryes,
428                    'cantsubscribe' => '-'), false, false, true);
429                $row[] = forum_index_get_forum_subscription_selector($forum);
430            }
431
432            //If this forum has RSS activated, calculate it
433            if ($show_rss) {
434                if ($forum->rsstype and $forum->rssarticles) {
435                    //Calculate the tolltip text
436                    if ($forum->rsstype == 1) {
437                        $tooltiptext = get_string('rsssubscriberssdiscussions', 'forum');
438                    } else {
439                        $tooltiptext = get_string('rsssubscriberssposts', 'forum');
440                    }
441                    //Get html code for RSS link
442                    $row[] = rss_get_link($context->id, $USER->id, 'mod_forum', $forum->id, $tooltiptext);
443                } else {
444                    $row[] = '&nbsp;';
445                }
446            }
447
448            $learningtable->data[] = $row;
449        }
450    }
451}
452
453// Output the page.
454$PAGE->navbar->add($strforums);
455$PAGE->set_title("$course->shortname: $strforums");
456$PAGE->set_heading($course->fullname);
457$PAGE->set_button($searchform);
458echo $OUTPUT->header();
459
460if (!isguestuser() && isloggedin() && $showsubscriptioncolumns) {
461    // Show the subscribe all options only to non-guest, enrolled users.
462    echo $OUTPUT->box_start('subscription');
463
464    $subscriptionlink = new moodle_url('/mod/forum/index.php', [
465        'id'        => $course->id,
466        'sesskey'   => sesskey(),
467    ]);
468
469    // Subscribe all.
470    $subscriptionlink->param('subscribe', 1);
471    echo html_writer::tag('div', html_writer::link($subscriptionlink, get_string('allsubscribe', 'forum')), [
472            'class' => 'helplink',
473        ]);
474
475    // Unsubscribe all.
476    $subscriptionlink->param('subscribe', 0);
477    echo html_writer::tag('div', html_writer::link($subscriptionlink, get_string('allunsubscribe', 'forum')), [
478            'class' => 'helplink',
479        ]);
480
481    echo $OUTPUT->box_end();
482    echo $OUTPUT->box('&nbsp;', 'clearer');
483}
484
485if ($generalforums) {
486    echo $OUTPUT->heading(get_string('generalforums', 'forum'), 2);
487    echo html_writer::table($generaltable);
488}
489
490if ($learningforums) {
491    echo $OUTPUT->heading(get_string('learningforums', 'forum'), 2);
492    echo html_writer::table($learningtable);
493}
494
495echo $OUTPUT->footer();
496
497/**
498 * Get the content of the forum subscription options for this forum.
499 *
500 * @param   stdClass    $forum      The forum to return options for
501 * @return  string
502 */
503function forum_index_get_forum_subscription_selector($forum) {
504    global $OUTPUT, $PAGE;
505
506    if ($forum->cansubscribe || $forum->issubscribed) {
507        if ($forum->maildigest === null) {
508            $forum->maildigest = -1;
509        }
510
511        $renderer = $PAGE->get_renderer('mod_forum');
512        return $OUTPUT->render($renderer->render_digest_options($forum, $forum->maildigest));
513    } else {
514        // This user can subscribe to some forums. Add the empty fields.
515        return '';
516    }
517};
518