/** * Marks a post as read * * @throws coding_exception */ public function markread_action() { global $PAGE, $DB, $CFG, $USER; if (!AJAX_SCRIPT) { throw new coding_exception('This is an AJAX action and you cannot access it directly'); } require_once $CFG->dirroot . '/rating/lib.php'; $postid = required_param('postid', PARAM_INT); $forum = $PAGE->activityrecord; $cm = $PAGE->cm; if (!($post = hsuforum_get_post_full($postid))) { print_error("notexists", 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } $discussion = $DB->get_record('hsuforum_discussions', array('id' => $post->discussion), '*', MUST_EXIST); if ($forum->type == 'news') { if (!($USER->id == $discussion->userid || ($discussion->timestart == 0 || $discussion->timestart <= time()) && ($discussion->timeend == 0 || $discussion->timeend > time()))) { print_error('invaliddiscussionid', 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } } if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { print_error('nopermissiontoview', 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } hsuforum_tp_add_read_record($USER->id, $post->id); return new json_response(array('postid' => $postid, 'discussionid' => $discussion->id)); }
/** * Get a discussion posts and related info * * @param $discussionid * @return array */ public function get_posts($discussionid) { global $PAGE, $DB, $CFG, $COURSE, $USER; $discussion = $DB->get_record('hsuforum_discussions', array('id' => $discussionid), '*', MUST_EXIST); $forum = $PAGE->activityrecord; $course = $COURSE; $cm = get_coursemodule_from_id('hsuforum', $PAGE->cm->id, $course->id, false, MUST_EXIST); // Cannot use cm_info because it is read only. $context = $PAGE->context; if ($forum->type == 'news') { if (!($USER->id == $discussion->userid || ($discussion->timestart == 0 || $discussion->timestart <= time()) && ($discussion->timeend == 0 || $discussion->timeend > time()))) { print_error('invaliddiscussionid', 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } } if (!($post = hsuforum_get_post_full($discussion->firstpost))) { print_error("notexists", 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { print_error('nopermissiontoview', 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } $posts = hsuforum_get_all_discussion_posts($discussion->id); $canreply = hsuforum_user_can_post($forum, $discussion, $USER, $cm, $course, $context); hsuforum_get_ratings_for_posts($context, $forum, $posts); return array($cm, $discussion, $posts, $canreply); }
/** * Serves the forum attachments. Implements needed access control ;-) * * @package mod_hsuforum * @category files * @param stdClass $course course object * @param stdClass $cm course module object * @param stdClass $context context object * @param string $filearea file area * @param array $args extra arguments * @param bool $forcedownload whether or not force download * @param array $options additional options affecting the file serving * @return bool false if file not found, does not return if found - justsend the file */ function hsuforum_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options = array()) { global $CFG, $DB; if ($context->contextlevel != CONTEXT_MODULE) { return false; } require_course_login($course, true, $cm); $areas = hsuforum_get_file_areas($course, $cm, $context); // Try comment area first. SC INT-4387. hsuforum_forum_comments_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, $options); // filearea must contain a real area if (!isset($areas[$filearea])) { return false; } $postid = (int) array_shift($args); if (!($post = $DB->get_record('hsuforum_posts', array('id' => $postid)))) { return false; } if (!($discussion = $DB->get_record('hsuforum_discussions', array('id' => $post->discussion)))) { return false; } if (!($forum = $DB->get_record('hsuforum', array('id' => $cm->instance)))) { return false; } $fs = get_file_storage(); $relativepath = implode('/', $args); $fullpath = "/{$context->id}/mod_hsuforum/{$filearea}/{$postid}/{$relativepath}"; if (!($file = $fs->get_file_by_hash(sha1($fullpath))) or $file->is_directory()) { return false; } // Make sure groups allow this user to see this file if ($discussion->groupid > 0) { $groupmode = groups_get_activity_groupmode($cm, $course); if ($groupmode == SEPARATEGROUPS) { if (!groups_is_member($discussion->groupid) and !has_capability('moodle/site:accessallgroups', $context)) { return false; } } } // Make sure we're allowed to see it... if (!hsuforum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) { return false; } // finally send the file send_stored_file($file, 0, 0, true, $options); // download MUST be forced - security! }
$PAGE->navbar->add(format_string($toppost->subject, true), "discuss.php?d={$discussion->id}"); } if ($post->parent) { $PAGE->navbar->add(get_string('reply', 'hsuforum')); } if ($edit) { $PAGE->navbar->add(get_string('edit', 'hsuforum')); } $PAGE->set_title("{$course->shortname}: {$strdiscussionname} {$toppost->subject}"); $PAGE->set_heading($course->fullname); $renderer = $PAGE->get_renderer('mod_hsuforum'); $PAGE->requires->js_init_call('M.mod_hsuforum.init', null, false, $renderer->get_js_module()); echo $OUTPUT->header(); echo $OUTPUT->heading(format_string($forum->name), 2); // checkup if (!empty($parent) && !hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { print_error('cannotreply', 'hsuforum'); } if (!empty($parent) && !empty($parent->privatereply)) { print_error('cannotreply', 'hsuforum'); } if (empty($parent) && empty($edit) && !hsuforum_user_can_post_discussion($forum, $groupid, -1, $cm, $modcontext)) { print_error('cannotcreatediscussion', 'hsuforum'); } if ($forum->type == 'qanda' && !has_capability('mod/hsuforum:viewqandawithoutposting', $modcontext) && !empty($discussion->id) && !hsuforum_user_has_posted($forum->id, $discussion->id, $USER->id)) { echo $OUTPUT->notification(get_string('qandanotify', 'hsuforum')); } // If there is a warning message and we are not editing a post we need to handle the warning. if (!empty($thresholdwarning) && !$edit) { // Here we want to throw an exception if they are no longer allowed to post. hsuforum_check_blocking_threshold($thresholdwarning);
redirect($return . '&moved=-1&sesskey=' . sesskey()); } } $params = array('context' => $modcontext, 'objectid' => $discussion->id); $event = \mod_hsuforum\event\discussion_viewed::create($params); $event->add_record_snapshot('hsuforum_discussions', $discussion); $event->add_record_snapshot('hsuforum', $forum); $event->trigger(); unset($SESSION->fromdiscussion); if (!$root) { $root = $discussion->firstpost; } if (!($post = hsuforum_get_post_full($root))) { print_error("notexists", 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?f={$forum->id}"); } if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { print_error('noviewdiscussionspermission', 'hsuforum', "{$CFG->wwwroot}/mod/hsuforum/view.php?id={$forum->id}"); } if ($mark == 'read') { hsuforum_tp_add_read_record($USER->id, $postid); } $forumnode = $PAGE->navigation->find($cm->id, navigation_node::TYPE_ACTIVITY); if (empty($forumnode)) { $forumnode = $PAGE->navbar; } else { $forumnode->make_active(); } $node = $forumnode->add(format_string($discussion->name), new moodle_url('/mod/hsuforum/discuss.php', array('d' => $discussion->id))); $node->display = false; if ($node && $post->id != $discussion->firstpost) { $node->add(format_string($post->subject), $PAGE->url);
/** * Render a single post * * @param \stdClass $cm The forum course module * @param \stdClass $discussion The post's discussion * @param \stdClass $post The post to render * @param bool $canreply * @param null|object $parent Optional, parent post * @param array $commands Override default post commands * @param int $depth Depth of the post * @return string */ public function post($cm, $discussion, $post, $canreply = false, $parent = null, $commands = array(), $depth = 0, $search = '') { global $USER, $CFG, $DB; $forum = hsuforum_get_cm_forum($cm); if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { // Return a message about why you cannot see the post return "<div class='hsuforum-post-content-hidden'>" . get_string('forumbodyhidden', 'hsuforum') . "</div>"; } if ($commands === false) { $commands = array(); } else { if (empty($commands)) { $commands = $this->post_get_commands($post, $discussion, $cm, $canreply, false); } else { if (!is_array($commands)) { throw new coding_exception('$commands must be false, empty or populated array'); } } } $postuser = hsuforum_extract_postuser($post, $forum, context_module::instance($cm->id)); $postuser->user_picture->size = 100; // $post->breadcrumb comes from search btw. $data = new stdClass(); $data->id = $post->id; $data->discussionid = $discussion->id; $data->fullname = $postuser->fullname; $data->subject = property_exists($post, 'breadcrumb') ? $post->breadcrumb : $this->raw_post_subject($post); $data->message = $this->post_message($post, $cm, $search); $data->created = userdate($post->created, get_string('articledateformat', 'hsuforum')); $data->rawcreated = $post->created; $data->datetime = date(DATE_W3C, usertime($post->created)); $data->privatereply = $post->privatereply; $data->imagesrc = $postuser->user_picture->get_url($this->page)->out(); $data->userurl = $this->get_post_user_url($cm, $postuser); $data->unread = empty($post->postread) ? true : false; $data->permalink = new moodle_url('/mod/hsuforum/discuss.php#p' . $post->id, array('d' => $discussion->id)); $data->isreply = false; $data->parentfullname = ''; $data->parentuserurl = ''; $data->tools = implode(' ', $commands); $data->postflags = implode(' ', $this->post_get_flags($post, $cm, $discussion->id, false)); $data->depth = $depth; $data->revealed = false; if ($forum->anonymous && $postuser->id === $USER->id && $post->reveal) { $data->revealed = true; } if (!empty($post->children)) { $post->replycount = count($post->children); } $data->replycount = ''; // Only show reply count if replies and not first post if (!empty($post->replycount) && $post->replycount > 0 && $post->parent) { $data->replycount = hsuforum_xreplies($post->replycount); } // Mark post as read. if ($data->unread) { hsuforum_mark_post_read($USER->id, $post, $forum->id); } if (!empty($parent)) { $parentuser = hsuforum_extract_postuser($parent, $forum, context_module::instance($cm->id)); $data->parenturl = $CFG->wwwroot . '/mod/hsuforum/discuss.php?d=' . $parent->discussion . '#p' . $parent->id; $data->parentfullname = $parentuser->fullname; if (!empty($parentuser->user_picture)) { $parentuser->user_picture->size = 100; $data->parentuserurl = $this->get_post_user_url($cm, $parentuser); $data->parentuserpic = $this->output->user_picture($parentuser, array('link' => false, 'size' => 100, 'alttext' => false)); } } if ($depth > 0) { // Top level responses don't count. $data->isreply = true; } return $this->post_template($data); }
/** * Process posts by removing unwanted data, etc. * * @param \stdClass $discussion * @param \stdClass[] $posts */ public function clean_posts($discussion, &$posts) { foreach ($posts as $key => $post) { if (!hsuforum_user_can_see_post(hsuforum_get_cm_forum($this->cm), $discussion, $post, null, $this->cm)) { unset($posts[$key]); continue; } // Remove children, not processing them. unset($post->children); } }
/** * This function return the XML rss contents about the forum * It returns false if something is wrong * * @param stdClass $forum the forum object * @param string $sql the SQL used to retrieve the contents from the database * @param array $params the SQL parameters used * @param object $context the context this forum relates to * @return bool|string false if the contents is empty, otherwise the contents of the feed is returned * * @Todo MDL-31129 implement post attachment handling */ function hsuforum_rss_feed_contents($forum, $sql, $params, $context) { global $CFG, $DB, $USER; $status = true; $recs = $DB->get_recordset_sql($sql, $params, 0, $forum->rssarticles); //set a flag. Are we displaying discussions or posts? $isdiscussion = true; if (!empty($forum->rsstype) && $forum->rsstype != 1) { $isdiscussion = false; } if (!($cm = get_coursemodule_from_instance('hsuforum', $forum->id, $forum->course))) { print_error('invalidcoursemodule'); } $formatoptions = new stdClass(); $items = array(); foreach ($recs as $rec) { $item = new stdClass(); $discussion = new stdClass(); $discussion->id = $rec->discussionid; $discussion->groupid = $rec->groupid; $discussion->timestart = $rec->timestart; $discussion->timeend = $rec->timeend; $post = null; if (!$isdiscussion) { $post = new stdClass(); $post->id = $rec->postid; $post->parent = $rec->postparent; $post->userid = $rec->userid; $post->privatereply = $rec->postprivatereply; } if ($isdiscussion && !hsuforum_user_can_see_discussion($forum, $discussion, $context)) { // This is a discussion which the user has no permission to view $item->title = get_string('forumsubjecthidden', 'hsuforum'); $message = get_string('forumbodyhidden', 'hsuforum'); $item->author = get_string('forumauthorhidden', 'hsuforum'); } else { if (!$isdiscussion && !hsuforum_user_can_see_post($forum, $discussion, $post, $USER, $cm)) { // This is a post which the user has no permission to view $item->title = get_string('forumsubjecthidden', 'hsuforum'); $message = get_string('forumbodyhidden', 'hsuforum'); $item->author = get_string('forumauthorhidden', 'hsuforum'); } else { // The user must have permission to view if ($isdiscussion && !empty($rec->discussionname)) { $item->title = format_string($rec->discussionname); } else { if (!empty($rec->postsubject)) { $item->title = format_string($rec->postsubject); } else { //we should have an item title by now but if we dont somehow then substitute something somewhat meaningful $item->title = format_string($forum->name . ' ' . userdate($rec->postcreated, get_string('strftimedatetimeshort', 'langconfig'))); } } $user = hsuforum_anonymize_user($rec, $forum, (object) array('id' => $rec->postid, 'reveal' => $rec->postreveal)); $item->author = fullname($user); $message = file_rewrite_pluginfile_urls($rec->postmessage, 'pluginfile.php', $context->id, 'mod_hsuforum', 'post', $rec->postid); $formatoptions->trusted = $rec->posttrust; } } if ($isdiscussion) { $item->link = $CFG->wwwroot . "/mod/hsuforum/discuss.php?d=" . $rec->discussionid; } else { $item->link = $CFG->wwwroot . "/mod/hsuforum/discuss.php?d=" . $rec->discussionid . "&parent=" . $rec->postid; } $formatoptions->trusted = $rec->posttrust; $item->description = format_text($message, $rec->postformat, $formatoptions, $forum->course); //TODO: MDL-31129 implement post attachment handling /*if (!$isdiscussion) { $post_file_area_name = str_replace('//', '/', "$forum->course/$CFG->moddata/hsuforum/$forum->id/$rec->postid"); $post_files = get_directory_list("$CFG->dataroot/$post_file_area_name"); if (!empty($post_files)) { $item->attachments = array(); } }*/ $item->pubdate = $rec->postcreated; $items[] = $item; } $recs->close(); // Create the RSS header. $header = rss_standard_header(strip_tags(format_string($forum->name, true)), $CFG->wwwroot . "/mod/hsuforum/view.php?f=" . $forum->id, format_string($forum->intro, true)); // TODO: fix format // Now all the RSS items, if there are any. $articles = ''; if (!empty($items)) { $articles = rss_add_items($items); } // Create the RSS footer. $footer = rss_standard_footer(); return $header . $articles . $footer; }
/** * Returns a list of forum posts for a discussion * * @param int $discussionid the post ids * * @return array the forum post details * @since Moodle 2.7 */ public static function get_forum_discussion_posts($discussionid) { global $CFG, $DB, $USER; $warnings = array(); // Validate the parameter. $params = self::validate_parameters(self::get_forum_discussion_posts_parameters(), array('discussionid' => $discussionid)); // Compact/extract functions are not recommended. $discussionid = $params['discussionid']; $discussion = $DB->get_record('hsuforum_discussions', array('id' => $discussionid), '*', MUST_EXIST); $forum = $DB->get_record('hsuforum', array('id' => $discussion->forum), '*', MUST_EXIST); $course = $DB->get_record('course', array('id' => $forum->course), '*', MUST_EXIST); $cm = get_coursemodule_from_instance('hsuforum', $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); // This require must be here, see mod/hsuforum/discuss.php. require_once $CFG->dirroot . "/mod/hsuforum/lib.php"; // Check they have the view forum capability. require_capability('mod/hsuforum:viewdiscussion', $modcontext, null, true, 'noviewdiscussionspermission', 'forum'); if (!($post = hsuforum_get_post_full($discussion->firstpost))) { throw new moodle_exception('notexists', 'hsuforum'); } // This function check groups, qanda, timed discussions, etc. if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { throw new moodle_exception('noviewdiscussionspermission', 'hsuforum'); } $canviewfullname = has_capability('moodle/site:viewfullnames', $modcontext); // We will add this field in the response. $canreply = hsuforum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext); $posts = hsuforum_get_all_discussion_posts($discussion->id); foreach ($posts as $pid => $post) { if (!hsuforum_user_can_see_post($forum, $discussion, $post, null, $cm)) { $warning = array(); $warning['item'] = 'post'; $warning['itemid'] = $post->id; $warning['warningcode'] = '1'; $warning['message'] = 'You can\'t see this post'; $warnings[] = $warning; continue; } // Function hsuforum_get_all_discussion_posts adds postread field. // Note that the value returned can be a boolean or an integer. The WS expects a boolean. if (empty($post->postread)) { $posts[$pid]->postread = false; } else { $posts[$pid]->postread = true; } $posts[$pid]->canreply = $canreply; if (!empty($posts[$pid]->children)) { $posts[$pid]->children = array_keys($posts[$pid]->children); } else { $posts[$pid]->children = array(); } $user = new stdclass(); $user = username_load_fields_from_object($user, $post); $posts[$pid]->userfullname = fullname($user, $canviewfullname); $posts[$pid] = (array) $post; } $result = array(); $result['posts'] = $posts; $result['warnings'] = $warnings; return $result; }