/** * Given a user, return post user that is ready for display (EG: * anonymous is enforced as well as highlighting) * * @param object $user * @param object $post * @param object $forum * @param context_module $context * @return stdClass */ function hsuforum_get_postuser($user, $post, $forum, context_module $context) { static $cache = []; if (empty($forum->anonymous) or !empty($post->reveal)) { if (isset($cache[$user->id])) { return $cache[$user->id]; } } $postuser = hsuforum_anonymize_user($user, $forum, $post); if (property_exists($user, 'picture')) { $postuser->user_picture = new user_picture($postuser); $postuser->user_picture->courseid = $forum->course; $postuser->user_picture->link = !hsuforum_is_anonymous_user($postuser); } $postuser->fullname = fullname($postuser, \mod_hsuforum\local::cached_has_capability('moodle/site:viewfullnames', $context)); if (empty($forum->anonymous) or !empty($post->reveal)) { $cache[$user->id] = $postuser; } return $postuser; }
/** * Get the simple edit post form * * @param object $cm * @param bool $isedit If we are editing or not * @param int $postid If editing, then the ID of the post we are editing. If * not editing, then the ID of the post we are replying to. * @param array $data Template data * @return string */ public function simple_edit_post($cm, $isedit = false, $postid = 0, array $data = array()) { global $DB, $CFG, $USER, $OUTPUT; $context = context_module::instance($cm->id); $forum = hsuforum_get_cm_forum($cm); $postuser = $USER; $ownpost = false; if ($isedit) { $param = 'edit'; $legend = get_string('editingpost', 'hsuforum'); $post = $DB->get_record('hsuforum_posts', ['id' => $postid]); if ($post->userid == $USER->id) { $ownpost = true; } else { $postuser = $DB->get_record('user', ['id' => $post->userid]); $postuser = hsuforum_anonymize_user($postuser, $forum, $post); $data['userpicture'] = $this->output->user_picture($postuser, array('link' => false, 'size' => 100)); } } else { // It is a reply, AKA new post $ownpost = true; $param = 'reply'; $legend = get_string('addareply', 'hsuforum'); $thresholdwarning = hsuforum_check_throttling($forum, $cm); if (!empty($thresholdwarning)) { $message = get_string($thresholdwarning->errorcode, $thresholdwarning->module, $thresholdwarning->additional); $data['thresholdwarning'] = $OUTPUT->notification($message); if ($thresholdwarning->canpost === false) { $data['thresholdblocked'] = " hsuforum-threshold-blocked "; } } } $data += array('itemid' => 0, 'privatereply' => 0, 'reveal' => 0, 'messageformat' => FORMAT_HTML); $actionurl = new moodle_url('/mod/hsuforum/route.php', array('action' => $isedit ? 'update_post' : 'reply', $param => $postid, 'sesskey' => sesskey(), 'contextid' => $context->id, 'itemid' => $data['itemid'], 'messageformat' => $data['messageformat'])); $extrahtml = ''; if (has_capability('mod/hsuforum:allowprivate', $context, $postuser) && $forum->allowprivatereplies !== '0') { $extrahtml .= html_writer::tag('label', html_writer::checkbox('privatereply', 1, !empty($data['privatereply'])) . get_string('privatereply', 'hsuforum')); } if ($forum->anonymous && !$isedit || $forum->anonymous && $isedit && $ownpost) { $extrahtml .= html_writer::tag('label', html_writer::checkbox('reveal', 1, !empty($data['reveal'])) . get_string('reveal', 'hsuforum')); } $data += array('postid' => $isedit ? $postid : 0, 'context' => $context, 'forum' => $forum, 'actionurl' => $actionurl, 'class' => 'hsuforum-reply', 'legend' => $legend, 'extrahtml' => $extrahtml, 'subjectrequired' => $isedit, 'advancedurl' => new moodle_url('/mod/hsuforum/post.php', array($param => $postid))); return $this->simple_edit_template($data); }
/** * Get recent forum activity for all accessible forums across all courses. * @param bool|int|stdclass $userorid * @param int $limit * @param int|null $since timestamp, only return posts from after this * @return array * @throws \coding_exception */ public static function recent_forum_activity($userorid = false, $limit = 10, $since = null) { global $CFG, $DB; if (file_exists($CFG->dirroot . '/mod/hsuforum')) { require_once $CFG->dirroot . '/mod/hsuforum/lib.php'; } $user = self::get_user($userorid); if (!$user) { return []; } if ($since === null) { $since = time() - 12 * WEEKSECS; } // Get all relevant forum ids for SQL in statement. // We use the post limit for the number of forums we are interested in too - // as they are ordered by most recent post. $userforums = new user_forums($user, $limit); $forumids = $userforums->forumids(); $forumidsallgroups = $userforums->forumidsallgroups(); $hsuforumids = $userforums->hsuforumids(); $hsuforumidsallgroups = $userforums->hsuforumidsallgroups(); if (empty($forumids) && empty($hsuforumids)) { return []; } $sqls = []; $params = []; if ($limit > 0) { $limitsql = self::limit_sql(0, $limit); // Note, this is here for performance optimisations only. } else { $limitsql = ''; } if (!empty($forumids)) { list($finsql, $finparams) = $DB->get_in_or_equal($forumids, SQL_PARAMS_NAMED, 'fina'); $params = $finparams; $params = array_merge($params, ['sepgps1a' => SEPARATEGROUPS, 'sepgps2a' => SEPARATEGROUPS, 'user1a' => $user->id, 'user2a' => $user->id]); $fgpsql = ''; if (!empty($forumidsallgroups)) { // Where a forum has a group mode of SEPARATEGROUPS we need a list of those forums where the current // user has the ability to access all groups. // This will be used in SQL later on to ensure they can see things in any groups. list($fgpsql, $fgpparams) = $DB->get_in_or_equal($forumidsallgroups, SQL_PARAMS_NAMED, 'allgpsa'); $fgpsql = ' OR f1.id ' . $fgpsql; $params = array_merge($params, $fgpparams); } $params['user2a'] = $user->id; $sqls[] = "(SELECT " . $DB->sql_concat("'F'", 'fp1.id') . " AS id, 'forum' AS type, fp1.id AS postid,\n fd1.forum, fp1.discussion, fp1.parent, fp1.userid, fp1.modified, fp1.subject,\n fp1.message, 0 AS reveal, cm1.id AS cmid,\n 0 AS forumanonymous, f1.course, f1.name AS forumname,\n u1.firstnamephonetic, u1.lastnamephonetic, u1.middlename, u1.alternatename, u1.firstname,\n u1.lastname, u1.picture, u1.imagealt, u1.email,\n c.shortname AS courseshortname, c.fullname AS coursefullname\n\t FROM {forum_posts} fp1\n\t JOIN {user} u1 ON u1.id = fp1.userid\n JOIN {forum_discussions} fd1 ON fd1.id = fp1.discussion\n\t JOIN {forum} f1 ON f1.id = fd1.forum AND f1.id {$finsql}\n\t JOIN {course_modules} cm1 ON cm1.instance = f1.id\n\t JOIN {modules} m1 ON m1.name = 'forum' AND cm1.module = m1.id\n\t JOIN {course} c ON c.id = f1.course\n\t LEFT JOIN {groups_members} gm1\n ON cm1.groupmode = :sepgps1a\n AND gm1.groupid = fd1.groupid\n AND gm1.userid = :user1a\n\t WHERE (cm1.groupmode <> :sepgps2a OR (gm1.userid IS NOT NULL {$fgpsql}))\n\t AND fp1.userid <> :user2a\n AND fp1.modified > {$since}\n ORDER BY fp1.modified DESC\n {$limitsql}\n )\n\t "; // TODO - when moodle gets private reply (anonymous) forums, we need to handle this here. } if (!empty($hsuforumids)) { list($afinsql, $afinparams) = $DB->get_in_or_equal($hsuforumids, SQL_PARAMS_NAMED, 'finb'); $params = array_merge($params, $afinparams); $params = array_merge($params, ['sepgps1b' => SEPARATEGROUPS, 'sepgps2b' => SEPARATEGROUPS, 'user1b' => $user->id, 'user2b' => $user->id, 'user3b' => $user->id, 'user4b' => $user->id]); $afgpsql = ''; if (!empty($hsuforumidsallgroups)) { // Where a forum has a group mode of SEPARATEGROUPS we need a list of those forums where the current // user has the ability to access all groups. // This will be used in SQL later on to ensure they can see things in any groups. list($afgpsql, $afgpparams) = $DB->get_in_or_equal($hsuforumidsallgroups, SQL_PARAMS_NAMED, 'allgpsb'); $afgpsql = ' OR f2.id ' . $afgpsql; $params = array_merge($params, $afgpparams); } $sqls[] = "(SELECT " . $DB->sql_concat("'A'", 'fp2.id') . " AS id, 'hsuforum' AS type, fp2.id AS postid,\n fd2.forum, fp2.discussion, fp2.parent, fp2.userid, fp2.modified, fp2.subject,\n fp2.message, fp2.reveal, cm2.id AS cmid,\n f2.anonymous AS forumanonymous, f2.course, f2.name AS forumname,\n u2.firstnamephonetic, u2.lastnamephonetic, u2.middlename, u2.alternatename, u2.firstname,\n u2.lastname, u2.picture, u2.imagealt, u2.email,\n c.shortname AS courseshortname, c.fullname AS coursefullname\n FROM {hsuforum_posts} fp2\n JOIN {user} u2 ON u2.id = fp2.userid\n JOIN {hsuforum_discussions} fd2 ON fd2.id = fp2.discussion\n JOIN {hsuforum} f2 ON f2.id = fd2.forum AND f2.id {$afinsql}\n\t JOIN {course_modules} cm2 ON cm2.instance = f2.id\n\t JOIN {modules} m2 ON m2.name = 'hsuforum' AND cm2.module = m2.id\n\t JOIN {course} c ON c.id = f2.course\n\t LEFT JOIN {groups_members} gm2\n\t ON cm2.groupmode = :sepgps1b\n\t AND gm2.groupid = fd2.groupid\n\t AND gm2.userid = :user1b\n WHERE (cm2.groupmode <> :sepgps2b OR (gm2.userid IS NOT NULL {$afgpsql}))\n AND (fp2.privatereply = 0 OR fp2.privatereply = :user2b OR fp2.userid = :user3b)\n AND fp2.userid <> :user4b\n AND fp2.modified > {$since}\n ORDER BY fp2.modified DESC\n {$limitsql}\n )\n "; } $sql = '-- Snap sql' . "\n" . implode("\n" . ' UNION ALL ' . "\n", $sqls); if (count($sqls) > 1) { $sql .= "\n" . ' ORDER BY modified DESC'; } $posts = $DB->get_records_sql($sql, $params, 0, $limit); $activities = []; if (!empty($posts)) { foreach ($posts as $post) { $postuser = (object) ['id' => $post->userid, 'firstnamephonetic' => $post->firstnamephonetic, 'lastnamephonetic' => $post->lastnamephonetic, 'middlename' => $post->middlename, 'alternatename' => $post->alternatename, 'firstname' => $post->firstname, 'lastname' => $post->lastname, 'picture' => $post->picture, 'imagealt' => $post->imagealt, 'email' => $post->email]; if ($post->type === 'hsuforum') { $postuser = hsuforum_anonymize_user($postuser, (object) array('id' => $post->forum, 'course' => $post->course, 'anonymous' => $post->forumanonymous), $post); } $activities[] = (object) ['type' => $post->type, 'cmid' => $post->cmid, 'name' => $post->subject, 'courseshortname' => $post->courseshortname, 'coursefullname' => $post->coursefullname, 'forumname' => $post->forumname, 'sectionnum' => null, 'timestamp' => $post->modified, 'content' => (object) ['id' => $post->postid, 'discussion' => $post->discussion, 'subject' => $post->subject, 'parent' => $post->parent], 'user' => $postuser]; } } return $activities; }
/** * 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; }