/** * This function checks whether the user can reply to posts in a forum * discussion. Use forum_user_can_post_discussion() to check whether the user * can start discussions. * * @global object * @global object * @uses DEBUG_DEVELOPER * @uses CONTEXT_MODULE * @uses VISIBLEGROUPS * @param object $forum forum object * @param object $discussion * @param object $user * @param object $cm * @param object $course * @param object $context * @return bool */ function forum_user_can_post($forum, $discussion, $user = NULL, $cm = NULL, $course = NULL, $context = NULL) { global $USER, $DB; if (empty($user)) { $user = $USER; } // shortcut - guest and not-logged-in users can not post if (isguestuser($user) or empty($user->id)) { return false; } if (!isset($discussion->groupid)) { debugging('incorrect discussion parameter', DEBUG_DEVELOPER); return false; } if (!$cm) { debugging('missing cm', DEBUG_DEVELOPER); if (!($cm = get_coursemodule_from_instance('forum', $forum->id, $forum->course))) { print_error('invalidcoursemodule'); } } if (!$course) { debugging('missing course', DEBUG_DEVELOPER); if (!($course = $DB->get_record('course', array('id' => $forum->course)))) { print_error('invalidcourseid'); } } if (!$context) { $context = context_module::instance($cm->id); } // Check whether the discussion is locked. if (forum_discussion_is_locked($forum, $discussion)) { if (!has_capability('mod/forum:canoverridediscussionlock', $context)) { return false; } } // normal users with temporary guest access can not post, suspended users can not post either if (!is_viewing($context, $user->id) and !is_enrolled($context, $user->id, '', true)) { return false; } if ($forum->type == 'news') { $capname = 'mod/forum:replynews'; } else { $capname = 'mod/forum:replypost'; } if (!has_capability($capname, $context, $user->id)) { return false; } if (!($groupmode = groups_get_activity_groupmode($cm, $course))) { return true; } if (has_capability('moodle/site:accessallgroups', $context)) { return true; } if ($groupmode == VISIBLEGROUPS) { if ($discussion->groupid == -1) { // allow students to reply to all participants discussions - this was not possible in Moodle <1.8 return true; } return groups_is_member($discussion->groupid); } else { //separate groups if ($discussion->groupid == -1) { return false; } return groups_is_member($discussion->groupid); } }
/** * Test the forum_discussion_is_locked function. * * @dataProvider forum_discussion_is_locked_provider * @param stdClass $forum * @param stdClass $discussion * @param bool $expect */ public function test_forum_discussion_is_locked($forum, $discussion, $expect) { $this->assertEquals($expect, forum_discussion_is_locked($forum, $discussion)); }
/** * Returns a list of forum discussions optionally sorted and paginated. * * @param int $forumid the forum instance id * @param string $sortby sort by this element (id, timemodified, timestart or timeend) * @param string $sortdirection sort direction: ASC or DESC * @param int $page page number * @param int $perpage items per page * * @return array the forum discussion details including warnings * @since Moodle 2.8 */ public static function get_forum_discussions_paginated($forumid, $sortby = 'timemodified', $sortdirection = 'DESC', $page = -1, $perpage = 0) { global $CFG, $DB, $USER, $PAGE; require_once $CFG->dirroot . "/mod/forum/lib.php"; $warnings = array(); $discussions = array(); $params = self::validate_parameters(self::get_forum_discussions_paginated_parameters(), array('forumid' => $forumid, 'sortby' => $sortby, 'sortdirection' => $sortdirection, 'page' => $page, 'perpage' => $perpage)); // Compact/extract functions are not recommended. $forumid = $params['forumid']; $sortby = $params['sortby']; $sortdirection = $params['sortdirection']; $page = $params['page']; $perpage = $params['perpage']; $sortallowedvalues = array('id', 'timemodified', 'timestart', 'timeend'); if (!in_array($sortby, $sortallowedvalues)) { throw new invalid_parameter_exception('Invalid value for sortby parameter (value: ' . $sortby . '),' . 'allowed values are: ' . implode(',', $sortallowedvalues)); } $sortdirection = strtoupper($sortdirection); $directionallowedvalues = array('ASC', 'DESC'); if (!in_array($sortdirection, $directionallowedvalues)) { throw new invalid_parameter_exception('Invalid value for sortdirection parameter (value: ' . $sortdirection . '),' . 'allowed values are: ' . implode(',', $directionallowedvalues)); } $forum = $DB->get_record('forum', array('id' => $forumid), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('forum', $forum->id, $course->id, false, MUST_EXIST); // Validate the module context. It checks everything that affects the module visibility (including groupings, etc..). $modcontext = context_module::instance($cm->id); self::validate_context($modcontext); // Check they have the view forum capability. require_capability('mod/forum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); $sort = 'd.pinned DESC, d.' . $sortby . ' ' . $sortdirection; $alldiscussions = forum_get_discussions($cm, $sort, true, -1, -1, true, $page, $perpage, FORUM_POSTS_ALL_USER_GROUPS); if ($alldiscussions) { $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); // Get the unreads array, this takes a forum id and returns data for all discussions. $unreads = array(); if ($cantrack = forum_tp_can_track_forums($forum)) { if ($forumtracked = forum_tp_is_tracked($forum)) { $unreads = forum_get_discussions_unread($cm); } } // The forum function returns the replies for all the discussions in a given forum. $replies = forum_count_discussion_replies($forumid, $sort, -1, $page, $perpage); foreach ($alldiscussions as $discussion) { // This function checks for qanda forums. // Note that the forum_get_discussions returns as id the post id, not the discussion id so we need to do this. $discussionrec = clone $discussion; $discussionrec->id = $discussion->discussion; if (!forum_user_can_see_discussion($forum, $discussionrec, $modcontext)) { $warning = array(); // Function forum_get_discussions returns forum_posts ids not forum_discussions ones. $warning['item'] = 'post'; $warning['itemid'] = $discussion->id; $warning['warningcode'] = '1'; $warning['message'] = 'You can\'t see this discussion'; $warnings[] = $warning; continue; } $discussion->numunread = 0; if ($cantrack && $forumtracked) { if (isset($unreads[$discussion->discussion])) { $discussion->numunread = (int) $unreads[$discussion->discussion]; } } $discussion->numreplies = 0; if (!empty($replies[$discussion->discussion])) { $discussion->numreplies = (int) $replies[$discussion->discussion]->replies; } $discussion->name = external_format_string($discussion->name, $modcontext->id); $discussion->subject = external_format_string($discussion->subject, $modcontext->id); // Rewrite embedded images URLs. list($discussion->message, $discussion->messageformat) = external_format_text($discussion->message, $discussion->messageformat, $modcontext->id, 'mod_forum', 'post', $discussion->id); // List attachments. if (!empty($discussion->attachment)) { $discussion->attachments = external_util::get_area_files($modcontext->id, 'mod_forum', 'attachment', $discussion->id); } $messageinlinefiles = external_util::get_area_files($modcontext->id, 'mod_forum', 'post', $discussion->id); if (!empty($messageinlinefiles)) { $discussion->messageinlinefiles = $messageinlinefiles; } $discussion->locked = forum_discussion_is_locked($forum, $discussion); $discussion->canreply = forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); if (forum_is_author_hidden($discussion, $forum)) { $discussion->userid = null; $discussion->userfullname = null; $discussion->userpictureurl = null; $discussion->usermodified = null; $discussion->usermodifiedfullname = null; $discussion->usermodifiedpictureurl = null; } else { $picturefields = explode(',', user_picture::fields()); // Load user objects from the results of the query. $user = new stdclass(); $user->id = $discussion->userid; $user = username_load_fields_from_object($user, $discussion, null, $picturefields); // Preserve the id, it can be modified by username_load_fields_from_object. $user->id = $discussion->userid; $discussion->userfullname = fullname($user, $canviewfullname); $userpicture = new user_picture($user); $userpicture->size = 1; // Size f1. $discussion->userpictureurl = $userpicture->get_url($PAGE)->out(false); $usermodified = new stdclass(); $usermodified->id = $discussion->usermodified; $usermodified = username_load_fields_from_object($usermodified, $discussion, 'um', $picturefields); // Preserve the id (it can be overwritten due to the prefixed $picturefields). $usermodified->id = $discussion->usermodified; $discussion->usermodifiedfullname = fullname($usermodified, $canviewfullname); $userpicture = new user_picture($usermodified); $userpicture->size = 1; // Size f1. $discussion->usermodifiedpictureurl = $userpicture->get_url($PAGE)->out(false); } $discussions[] = $discussion; } } $result = array(); $result['discussions'] = $discussions; $result['warnings'] = $warnings; return $result; }
} echo "</div>"; } if (has_capability('mod/forum:pindiscussions', $modcontext)) { if ($discussion->pinned == FORUM_DISCUSSION_PINNED) { $pinlink = FORUM_DISCUSSION_UNPINNED; $pintext = get_string('discussionunpin', 'forum'); } else { $pinlink = FORUM_DISCUSSION_PINNED; $pintext = get_string('discussionpin', 'forum'); } $button = new single_button(new moodle_url('discuss.php', array('pin' => $pinlink, 'd' => $discussion->id)), $pintext, 'post'); echo html_writer::tag('div', $OUTPUT->render($button), array('class' => 'discussioncontrol pindiscussion')); } echo "</div></div>"; if (forum_discussion_is_locked($forum, $discussion)) { echo html_writer::div(get_string('discussionlocked', 'forum'), 'discussionlocked'); } if (!empty($forum->blockafter) && !empty($forum->blockperiod)) { $a = new stdClass(); $a->blockafter = $forum->blockafter; $a->blockperiod = get_string('secondstotime' . $forum->blockperiod); echo $OUTPUT->notification(get_string('thisforumisthrottled', 'forum', $a)); } if ($forum->type == 'qanda' && !has_capability('mod/forum:viewqandawithoutposting', $modcontext) && !forum_user_has_posted($forum->id, $discussion->id, $USER->id)) { echo $OUTPUT->notification(get_string('qandanotify', 'forum')); } if ($move == -1 and confirm_sesskey()) { echo $OUTPUT->notification(get_string('discussionmoved', 'forum', format_string($forum->name, true)), 'notifysuccess'); } $canrate = has_capability('mod/forum:rate', $modcontext);