/** * Print a forum post * * @global object * @global object * @uses FORUM_MODE_THREADED * @uses PORTFOLIO_FORMAT_PLAINHTML * @uses PORTFOLIO_FORMAT_FILE * @uses PORTFOLIO_FORMAT_RICHHTML * @uses PORTFOLIO_ADD_TEXT_LINK * @uses CONTEXT_MODULE * @param object $post The post to print. * @param object $discussion * @param object $forum * @param object $cm * @param object $course * @param boolean $ownpost Whether this post belongs to the current user. * @param boolean $reply Whether to print a 'reply' link at the bottom of the message. * @param boolean $link Just print a shortened version of the post as a link to the full post. * @param string $footer Extra stuff to print after the message. * @param string $highlight Space-separated list of terms to highlight. * @param int $post_read true, false or -99. If we already know whether this user * has read this post, pass that in, otherwise, pass in -99, and this * function will work it out. * @param boolean $dummyifcantsee When forum_user_can_see_post says that * the current user can't see this post, if this argument is true * (the default) then print a dummy 'you can't see this post' post. * If false, don't output anything at all. * @param bool|null $istracked * @return void */ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost=false, $reply=false, $link=false, $footer="", $highlight="", $postisread=null, $dummyifcantsee=true, $istracked=null, $return=false) { global $USER, $CFG, $OUTPUT; require_once($CFG->libdir . '/filelib.php'); // String cache static $str; $modcontext = context_module::instance($cm->id); $post->course = $course->id; $post->forum = $forum->id; $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id); if (!empty($CFG->enableplagiarism)) { require_once($CFG->libdir.'/plagiarismlib.php'); $post->message .= plagiarism_get_links(array('userid' => $post->userid, 'content' => $post->message, 'cmid' => $cm->id, 'course' => $post->course, 'forum' => $post->forum)); } // caching if (!isset($cm->cache)) { $cm->cache = new stdClass; } if (!isset($cm->cache->caps)) { $cm->cache->caps = array(); $cm->cache->caps['mod/forum:viewdiscussion'] = has_capability('mod/forum:viewdiscussion', $modcontext); $cm->cache->caps['moodle/site:viewfullnames'] = has_capability('moodle/site:viewfullnames', $modcontext); $cm->cache->caps['mod/forum:editanypost'] = has_capability('mod/forum:editanypost', $modcontext); $cm->cache->caps['mod/forum:splitdiscussions'] = has_capability('mod/forum:splitdiscussions', $modcontext); $cm->cache->caps['mod/forum:deleteownpost'] = has_capability('mod/forum:deleteownpost', $modcontext); $cm->cache->caps['mod/forum:deleteanypost'] = has_capability('mod/forum:deleteanypost', $modcontext); $cm->cache->caps['mod/forum:viewanyrating'] = has_capability('mod/forum:viewanyrating', $modcontext); $cm->cache->caps['mod/forum:exportpost'] = has_capability('mod/forum:exportpost', $modcontext); $cm->cache->caps['mod/forum:exportownpost'] = has_capability('mod/forum:exportownpost', $modcontext); } if (!isset($cm->uservisible)) { $cm->uservisible = coursemodule_visible_for_user($cm); } if ($istracked && is_null($postisread)) { $postisread = forum_tp_is_post_read($USER->id, $post); } if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) { $output = ''; if (!$dummyifcantsee) { if ($return) { return $output; } echo $output; return; } $output .= html_writer::tag('a', '', array('id'=>'p'.$post->id)); $output .= html_writer::start_tag('div', array('class'=>'forumpost clearfix')); $output .= html_writer::start_tag('div', array('class'=>'row header')); $output .= html_writer::tag('div', '', array('class'=>'left picture')); // Picture if ($post->parent) { $output .= html_writer::start_tag('div', array('class'=>'topic')); } else { $output .= html_writer::start_tag('div', array('class'=>'topic starter')); } $output .= html_writer::tag('div', get_string('forumsubjecthidden','forum'), array('class'=>'subject')); // Subject $output .= html_writer::tag('div', get_string('forumauthorhidden','forum'), array('class'=>'author')); // author $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // row $output .= html_writer::start_tag('div', array('class'=>'row')); $output .= html_writer::tag('div', ' ', array('class'=>'left side')); // Groups $output .= html_writer::tag('div', get_string('forumbodyhidden','forum'), array('class'=>'content')); // Content $output .= html_writer::end_tag('div'); // row $output .= html_writer::end_tag('div'); // forumpost if ($return) { return $output; } echo $output; return; } if (empty($str)) { $str = new stdClass; $str->edit = get_string('edit', 'forum'); $str->delete = get_string('delete', 'forum'); $str->reply = get_string('reply', 'forum'); $str->parent = get_string('parent', 'forum'); $str->pruneheading = get_string('pruneheading', 'forum'); $str->prune = get_string('prune', 'forum'); $str->displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); $str->markread = get_string('markread', 'forum'); $str->markunread = get_string('markunread', 'forum'); } $discussionlink = new moodle_url('/mod/forum/discuss.php', array('d'=>$post->discussion)); // Build an object that represents the posting user $postuser = new stdClass; $postuser->id = $post->userid; $postuser->firstname = $post->firstname; $postuser->lastname = $post->lastname; $postuser->imagealt = $post->imagealt; $postuser->picture = $post->picture; $postuser->email = $post->email; // Some handy things for later on $postuser->fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']); $postuser->profilelink = new moodle_url('/user/view.php', array('id'=>$post->userid, 'course'=>$course->id)); // Prepare the groups the posting user belongs to if (isset($cm->cache->usersgroups)) { $groups = array(); if (isset($cm->cache->usersgroups[$post->userid])) { foreach ($cm->cache->usersgroups[$post->userid] as $gid) { $groups[$gid] = $cm->cache->groups[$gid]; } } } else { $groups = groups_get_all_groups($course->id, $post->userid, $cm->groupingid); } // Prepare the attachements for the post, files then images list($attachments, $attachedimages) = forum_print_attachments($post, $cm, 'separateimages'); // Determine if we need to shorten this post $shortenpost = ($link && (strlen(strip_tags($post->message)) > $CFG->forum_longpost)); // Prepare an array of commands $commands = array(); // SPECIAL CASE: The front page can display a news item post to non-logged in users. // Don't display the mark read / unread controls in this case. if ($istracked && $CFG->forum_usermarksread && isloggedin()) { $url = new moodle_url($discussionlink, array('postid'=>$post->id, 'mark'=>'unread')); $text = $str->markunread; if (!$postisread) { $url->param('mark', 'read'); $text = $str->markread; } if ($str->displaymode == FORUM_MODE_THREADED) { $url->param('parent', $post->parent); } else { $url->set_anchor('p'.$post->id); } $commands[] = array('url'=>$url, 'text'=>$text); } // Zoom in to the parent specifically if ($post->parent) { $url = new moodle_url($discussionlink); if ($str->displaymode == FORUM_MODE_THREADED) { $url->param('parent', $post->parent); } else { $url->set_anchor('p'.$post->parent); } $commands[] = array('url'=>$url, 'text'=>$str->parent); } // Hack for allow to edit news posts those are not displayed yet until they are displayed $age = time() - $post->created; if (!$post->parent && $forum->type == 'news' && $discussion->timestart > time()) { $age = 0; } if ($forum->type == 'single' and $discussion->firstpost == $post->id) { if (has_capability('moodle/course:manageactivities', $modcontext)) { // The first post in single simple is the forum description. $commands[] = array('url'=>new moodle_url('/course/modedit.php', array('update'=>$cm->id, 'sesskey'=>sesskey(), 'return'=>1)), 'text'=>$str->edit); } } else if (($ownpost && $age < $CFG->maxeditingtime) || $cm->cache->caps['mod/forum:editanypost']) { $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('edit'=>$post->id)), 'text'=>$str->edit); } if ($cm->cache->caps['mod/forum:splitdiscussions'] && $post->parent && $forum->type != 'single') { $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('prune'=>$post->id)), 'text'=>$str->prune, 'title'=>$str->pruneheading); } if ($forum->type == 'single' and $discussion->firstpost == $post->id) { // Do not allow deleting of first post in single simple type. } else if (($ownpost && $age < $CFG->maxeditingtime && $cm->cache->caps['mod/forum:deleteownpost']) || $cm->cache->caps['mod/forum:deleteanypost']) { $commands[] = array('url'=>new moodle_url('/mod/forum/post.php', array('delete'=>$post->id)), 'text'=>$str->delete); } if ($reply) { $commands[] = array('url'=>new moodle_url('/mod/forum/post.php#mformforum', array('reply'=>$post->id)), 'text'=>$str->reply); } if ($CFG->enableportfolios && ($cm->cache->caps['mod/forum:exportpost'] || ($ownpost && $cm->cache->caps['mod/forum:exportownpost']))) { $p = array('postid' => $post->id); require_once($CFG->libdir.'/portfoliolib.php'); $button = new portfolio_add_button(); $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), 'mod_forum'); if (empty($attachments)) { $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML); } else { $button->set_formats(PORTFOLIO_FORMAT_RICHHTML); } $porfoliohtml = $button->to_html(PORTFOLIO_ADD_TEXT_LINK); if (!empty($porfoliohtml)) { $commands[] = $porfoliohtml; } } // Finished building commands // Begin output $output = ''; if ($istracked) { if ($postisread) { $forumpostclass = ' read'; } else { $forumpostclass = ' unread'; $output .= html_writer::tag('a', '', array('name'=>'unread')); } } else { // ignore trackign status if not tracked or tracked param missing $forumpostclass = ''; } $topicclass = ''; if (empty($post->parent)) { $topicclass = ' firstpost starter'; } $output .= html_writer::tag('a', '', array('id'=>'p'.$post->id)); $output .= html_writer::start_tag('div', array('class'=>'forumpost clearfix'.$forumpostclass.$topicclass)); $output .= html_writer::start_tag('div', array('class'=>'row header clearfix')); $output .= html_writer::start_tag('div', array('class'=>'left picture')); $output .= $OUTPUT->user_picture($postuser, array('courseid'=>$course->id)); $output .= html_writer::end_tag('div'); $output .= html_writer::start_tag('div', array('class'=>'topic'.$topicclass)); $postsubject = $post->subject; if (empty($post->subjectnoformat)) { $postsubject = format_string($postsubject); } $output .= html_writer::tag('div', $postsubject, array('class'=>'subject')); $by = new stdClass(); $by->name = html_writer::link($postuser->profilelink, $postuser->fullname); $by->date = userdate($post->modified); $output .= html_writer::tag('div', get_string('bynameondate', 'forum', $by), array('class'=>'author')); $output .= html_writer::end_tag('div'); //topic $output .= html_writer::end_tag('div'); //row $output .= html_writer::start_tag('div', array('class'=>'row maincontent clearfix')); $output .= html_writer::start_tag('div', array('class'=>'left')); $groupoutput = ''; if ($groups) { $groupoutput = print_group_picture($groups, $course->id, false, true, true); } if (empty($groupoutput)) { $groupoutput = ' '; } $output .= html_writer::tag('div', $groupoutput, array('class'=>'grouppictures')); $output .= html_writer::end_tag('div'); //left side $output .= html_writer::start_tag('div', array('class'=>'no-overflow')); $output .= html_writer::start_tag('div', array('class'=>'content')); if (!empty($attachments)) { $output .= html_writer::tag('div', $attachments, array('class'=>'attachments')); } $options = new stdClass; $options->para = false; $options->trusted = $post->messagetrust; $options->context = $modcontext; if ($shortenpost) { // Prepare shortened version $postclass = 'shortenedpost'; $postcontent = format_text(forum_shorten_post($post->message), $post->messageformat, $options, $course->id); $postcontent .= html_writer::link($discussionlink, get_string('readtherest', 'forum')); $postcontent .= html_writer::tag('div', '('.get_string('numwords', 'moodle', count_words($post->message)).')', array('class'=>'post-word-count')); } else { // Prepare whole post $postclass = 'fullpost'; $postcontent = format_text($post->message, $post->messageformat, $options, $course->id); if (!empty($highlight)) { $postcontent = highlight($highlight, $postcontent); } if (!empty($forum->displaywordcount)) { $postcontent .= html_writer::tag('div', get_string('numwords', 'moodle', count_words($post->message)), array('class'=>'post-word-count')); } $postcontent .= html_writer::tag('div', $attachedimages, array('class'=>'attachedimages')); } // Output the post content $output .= html_writer::tag('div', $postcontent, array('class'=>'posting '.$postclass)); $output .= html_writer::end_tag('div'); // Content $output .= html_writer::end_tag('div'); // Content mask $output .= html_writer::end_tag('div'); // Row $output .= html_writer::start_tag('div', array('class'=>'row side')); $output .= html_writer::tag('div',' ', array('class'=>'left')); $output .= html_writer::start_tag('div', array('class'=>'options clearfix')); // Output ratings if (!empty($post->rating)) { $output .= html_writer::tag('div', $OUTPUT->render($post->rating), array('class'=>'forum-post-rating')); } // Output the commands $commandhtml = array(); foreach ($commands as $command) { if (is_array($command)) { $commandhtml[] = html_writer::link($command['url'], $command['text']); } else { $commandhtml[] = $command; } } $output .= html_writer::tag('div', implode(' | ', $commandhtml), array('class'=>'commands')); // Output link to post if required if ($link) { if ($post->replies == 1) { $replystring = get_string('repliesone', 'forum', $post->replies); } else { $replystring = get_string('repliesmany', 'forum', $post->replies); } $output .= html_writer::start_tag('div', array('class'=>'link')); $output .= html_writer::link($discussionlink, get_string('discussthistopic', 'forum')); $output .= ' ('.$replystring.')'; $output .= html_writer::end_tag('div'); // link } // Output footer if required if ($footer) { $output .= html_writer::tag('div', $footer, array('class'=>'footer')); } // Close remaining open divs $output .= html_writer::end_tag('div'); // content $output .= html_writer::end_tag('div'); // row $output .= html_writer::end_tag('div'); // forumpost // Mark the forum post as read if required if ($istracked && !$CFG->forum_usermarksread && !$postisread) { forum_tp_mark_post_read($USER->id, $post, $forum->id); } if ($return) { return $output; } echo $output; return; }
/** * Print a forum post * * @global object * @global object * @uses FORUM_MODE_THREADED * @uses PORTFOLIO_FORMAT_PLAINHTML * @uses PORTFOLIO_FORMAT_FILE * @uses PORTFOLIO_FORMAT_RICHHTML * @uses PORTFOLIO_ADD_TEXT_LINK * @uses CONTEXT_MODULE * @param object $post The post to print. * @param object $discussion * @param object $forum * @param object $cm * @param object $course * @param boolean $ownpost Whether this post belongs to the current user. * @param boolean $reply Whether to print a 'reply' link at the bottom of the message. * @param boolean $link Just print a shortened version of the post as a link to the full post. * @param string $footer Extra stuff to print after the message. * @param string $highlight Space-separated list of terms to highlight. * @param int $post_read true, false or -99. If we already know whether this user * has read this post, pass that in, otherwise, pass in -99, and this * function will work it out. * @param boolean $dummyifcantsee When forum_user_can_see_post says that * the current user can't see this post, if this argument is true * (the default) then print a dummy 'you can't see this post' post. * If false, don't output anything at all. * @param bool|null $istracked * @return void */ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost = false, $reply = false, $link = false, $footer = "", $highlight = "", $postisread = null, $dummyifcantsee = true, $istracked = null, $return = false) { global $USER, $CFG, $OUTPUT; require_once $CFG->libdir . '/filelib.php'; // String cache static $str; // This is an extremely hacky way to ensure we only print the 'unread' anchor // the first time we encounter an unread post on a page. Ideally this would // be moved into the caller somehow, and be better testable. But at the time // of dealing with this bug, this static workaround was the most surgical and // it fits together with only printing th unread anchor id once on a given page. static $firstunreadanchorprinted = false; $modcontext = context_module::instance($cm->id); $post->course = $course->id; $post->forum = $forum->id; $post->message = file_rewrite_pluginfile_urls($post->message, 'pluginfile.php', $modcontext->id, 'mod_forum', 'post', $post->id); if (!empty($CFG->enableplagiarism)) { require_once $CFG->libdir . '/plagiarismlib.php'; $post->message .= plagiarism_get_links(array('userid' => $post->userid, 'content' => $post->message, 'cmid' => $cm->id, 'course' => $post->course, 'forum' => $post->forum)); } // caching if (!isset($cm->cache)) { $cm->cache = new stdClass(); } if (!isset($cm->cache->caps)) { $cm->cache->caps = array(); $cm->cache->caps['mod/forum:viewdiscussion'] = has_capability('mod/forum:viewdiscussion', $modcontext); $cm->cache->caps['moodle/site:viewfullnames'] = has_capability('moodle/site:viewfullnames', $modcontext); $cm->cache->caps['mod/forum:editanypost'] = has_capability('mod/forum:editanypost', $modcontext); $cm->cache->caps['mod/forum:splitdiscussions'] = has_capability('mod/forum:splitdiscussions', $modcontext); $cm->cache->caps['mod/forum:deleteownpost'] = has_capability('mod/forum:deleteownpost', $modcontext); $cm->cache->caps['mod/forum:deleteanypost'] = has_capability('mod/forum:deleteanypost', $modcontext); $cm->cache->caps['mod/forum:viewanyrating'] = has_capability('mod/forum:viewanyrating', $modcontext); $cm->cache->caps['mod/forum:exportpost'] = has_capability('mod/forum:exportpost', $modcontext); $cm->cache->caps['mod/forum:exportownpost'] = has_capability('mod/forum:exportownpost', $modcontext); } if (!isset($cm->uservisible)) { $cm->uservisible = \core_availability\info_module::is_user_visible($cm, 0, false); } if ($istracked && is_null($postisread)) { $postisread = forum_tp_is_post_read($USER->id, $post); } if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) { $output = ''; if (!$dummyifcantsee) { if ($return) { return $output; } echo $output; return; } $output .= html_writer::tag('a', '', array('id' => 'p' . $post->id)); $output .= html_writer::start_tag('div', array('class' => 'forumpost clearfix', 'role' => 'region', 'aria-label' => get_string('hiddenforumpost', 'forum'))); $output .= html_writer::start_tag('div', array('class' => 'row header')); $output .= html_writer::tag('div', '', array('class' => 'left picture')); // Picture if ($post->parent) { $output .= html_writer::start_tag('div', array('class' => 'topic')); } else { $output .= html_writer::start_tag('div', array('class' => 'topic starter')); } $output .= html_writer::tag('div', get_string('forumsubjecthidden', 'forum'), array('class' => 'subject', 'role' => 'header')); // Subject. $output .= html_writer::tag('div', get_string('forumauthorhidden', 'forum'), array('class' => 'author', 'role' => 'header')); // Author. $output .= html_writer::end_tag('div'); $output .= html_writer::end_tag('div'); // row $output .= html_writer::start_tag('div', array('class' => 'row')); $output .= html_writer::tag('div', ' ', array('class' => 'left side')); // Groups $output .= html_writer::tag('div', get_string('forumbodyhidden', 'forum'), array('class' => 'content')); // Content $output .= html_writer::end_tag('div'); // row $output .= html_writer::end_tag('div'); // forumpost if ($return) { return $output; } echo $output; return; } if (empty($str)) { $str = new stdClass(); $str->edit = get_string('edit', 'forum'); $str->delete = get_string('delete', 'forum'); $str->reply = get_string('reply', 'forum'); $str->parent = get_string('parent', 'forum'); $str->pruneheading = get_string('pruneheading', 'forum'); $str->prune = get_string('prune', 'forum'); $str->displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); $str->markread = get_string('markread', 'forum'); $str->markunread = get_string('markunread', 'forum'); } $discussionlink = new moodle_url('/mod/forum/discuss.php', array('d' => $post->discussion)); // Build an object that represents the posting user $postuser = new stdClass(); $postuserfields = explode(',', user_picture::fields()); $postuser = username_load_fields_from_object($postuser, $post, null, $postuserfields); $postuser->id = $post->userid; $postuser->fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']); $postuser->profilelink = new moodle_url('/user/view.php', array('id' => $post->userid, 'course' => $course->id)); // Prepare the groups the posting user belongs to if (isset($cm->cache->usersgroups)) { $groups = array(); if (isset($cm->cache->usersgroups[$post->userid])) { foreach ($cm->cache->usersgroups[$post->userid] as $gid) { $groups[$gid] = $cm->cache->groups[$gid]; } } } else { $groups = groups_get_all_groups($course->id, $post->userid, $cm->groupingid); } // Prepare the attachements for the post, files then images list($attachments, $attachedimages) = forum_print_attachments($post, $cm, 'separateimages'); // Determine if we need to shorten this post $shortenpost = $link && strlen(strip_tags($post->message)) > $CFG->forum_longpost; // Prepare an array of commands $commands = array(); // Add a permalink. $permalink = new moodle_url($discussionlink); $permalink->set_anchor('p' . $post->id); $commands[] = array('url' => $permalink, 'text' => get_string('permalink', 'forum')); // SPECIAL CASE: The front page can display a news item post to non-logged in users. // Don't display the mark read / unread controls in this case. if ($istracked && $CFG->forum_usermarksread && isloggedin()) { $url = new moodle_url($discussionlink, array('postid' => $post->id, 'mark' => 'unread')); $text = $str->markunread; if (!$postisread) { $url->param('mark', 'read'); $text = $str->markread; } if ($str->displaymode == FORUM_MODE_THREADED) { $url->param('parent', $post->parent); } else { $url->set_anchor('p' . $post->id); } $commands[] = array('url' => $url, 'text' => $text); } // Zoom in to the parent specifically if ($post->parent) { $url = new moodle_url($discussionlink); if ($str->displaymode == FORUM_MODE_THREADED) { $url->param('parent', $post->parent); } else { $url->set_anchor('p' . $post->parent); } $commands[] = array('url' => $url, 'text' => $str->parent); } // Hack for allow to edit news posts those are not displayed yet until they are displayed $age = time() - $post->created; if (!$post->parent && $forum->type == 'news' && $discussion->timestart > time()) { $age = 0; } if ($forum->type == 'single' and $discussion->firstpost == $post->id) { if (has_capability('moodle/course:manageactivities', $modcontext)) { // The first post in single simple is the forum description. $commands[] = array('url' => new moodle_url('/course/modedit.php', array('update' => $cm->id, 'sesskey' => sesskey(), 'return' => 1)), 'text' => $str->edit); } } else { if ($ownpost && $age < $CFG->maxeditingtime || $cm->cache->caps['mod/forum:editanypost']) { $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('edit' => $post->id)), 'text' => $str->edit); } } if ($cm->cache->caps['mod/forum:splitdiscussions'] && $post->parent && $forum->type != 'single') { $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('prune' => $post->id)), 'text' => $str->prune, 'title' => $str->pruneheading); } if ($forum->type == 'single' and $discussion->firstpost == $post->id) { // Do not allow deleting of first post in single simple type. } else { if ($ownpost && $age < $CFG->maxeditingtime && $cm->cache->caps['mod/forum:deleteownpost'] || $cm->cache->caps['mod/forum:deleteanypost']) { $commands[] = array('url' => new moodle_url('/mod/forum/post.php', array('delete' => $post->id)), 'text' => $str->delete); } } if ($reply) { $commands[] = array('url' => new moodle_url('/mod/forum/post.php#mformforum', array('reply' => $post->id)), 'text' => $str->reply); } if ($CFG->enableportfolios && ($cm->cache->caps['mod/forum:exportpost'] || $ownpost && $cm->cache->caps['mod/forum:exportownpost'])) { $p = array('postid' => $post->id); require_once $CFG->libdir . '/portfoliolib.php'; $button = new portfolio_add_button(); $button->set_callback_options('forum_portfolio_caller', array('postid' => $post->id), 'mod_forum'); if (empty($attachments)) { $button->set_formats(PORTFOLIO_FORMAT_PLAINHTML); } else { $button->set_formats(PORTFOLIO_FORMAT_RICHHTML); } $porfoliohtml = $button->to_html(PORTFOLIO_ADD_TEXT_LINK); if (!empty($porfoliohtml)) { $commands[] = $porfoliohtml; } } // Finished building commands // Begin output $output = ''; if ($istracked) { if ($postisread) { $forumpostclass = ' read'; } else { $forumpostclass = ' unread'; // If this is the first unread post printed then give it an anchor and id of unread. if (!$firstunreadanchorprinted) { $output .= html_writer::tag('a', '', array('id' => 'unread')); $firstunreadanchorprinted = true; } } } else { // ignore trackign status if not tracked or tracked param missing $forumpostclass = ''; } $topicclass = ''; if (empty($post->parent)) { $topicclass = ' firstpost starter'; } if (!empty($post->lastpost)) { $forumpostclass .= ' lastpost'; } // Flag to indicate whether we should hide the author or not. $authorhidden = forum_is_author_hidden($post, $forum); $postbyuser = new stdClass(); $postbyuser->post = $post->subject; $postbyuser->user = $postuser->fullname; $discussionbyuser = get_string('postbyuser', 'forum', $postbyuser); $output .= html_writer::tag('a', '', array('id' => 'p' . $post->id)); // Begin forum post. $output .= html_writer::start_div('forumpost clearfix' . $forumpostclass . $topicclass, ['role' => 'region', 'aria-label' => $discussionbyuser]); // Begin header row. $output .= html_writer::start_div('row header clearfix'); // User picture. if (!$authorhidden) { $picture = $OUTPUT->user_picture($postuser, ['courseid' => $course->id]); $output .= html_writer::div($picture, 'left picture'); $topicclass = 'topic' . $topicclass; } // Begin topic column. $output .= html_writer::start_div($topicclass); $postsubject = $post->subject; if (empty($post->subjectnoformat)) { $postsubject = format_string($postsubject); } $output .= html_writer::div($postsubject, 'subject', ['role' => 'heading', 'aria-level' => '2']); if ($authorhidden) { $bytext = userdate($post->modified); } else { $by = new stdClass(); $by->date = userdate($post->modified); $by->name = html_writer::link($postuser->profilelink, $postuser->fullname); $bytext = get_string('bynameondate', 'forum', $by); } $bytextoptions = ['role' => 'heading', 'aria-level' => '2']; $output .= html_writer::div($bytext, 'author', $bytextoptions); // End topic column. $output .= html_writer::end_div(); // End header row. $output .= html_writer::end_div(); // Row with the forum post content. $output .= html_writer::start_div('row maincontent clearfix'); // Show if author is not hidden or we have groups. if (!$authorhidden || $groups) { $output .= html_writer::start_div('left'); $groupoutput = ''; if ($groups) { $groupoutput = print_group_picture($groups, $course->id, false, true, true); } if (empty($groupoutput)) { $groupoutput = ' '; } $output .= html_writer::div($groupoutput, 'grouppictures'); $output .= html_writer::end_div(); // Left side. } $output .= html_writer::start_tag('div', array('class' => 'no-overflow')); $output .= html_writer::start_tag('div', array('class' => 'content')); $options = new stdClass(); $options->para = false; $options->trusted = $post->messagetrust; $options->context = $modcontext; if ($shortenpost) { // Prepare shortened version by filtering the text then shortening it. $postclass = 'shortenedpost'; $postcontent = format_text($post->message, $post->messageformat, $options); $postcontent = shorten_text($postcontent, $CFG->forum_shortpost); $postcontent .= html_writer::link($discussionlink, get_string('readtherest', 'forum')); $postcontent .= html_writer::tag('div', '(' . get_string('numwords', 'moodle', count_words($post->message)) . ')', array('class' => 'post-word-count')); } else { // Prepare whole post $postclass = 'fullpost'; $postcontent = format_text($post->message, $post->messageformat, $options, $course->id); if (!empty($highlight)) { $postcontent = highlight($highlight, $postcontent); } if (!empty($forum->displaywordcount)) { $postcontent .= html_writer::tag('div', get_string('numwords', 'moodle', count_words($post->message)), array('class' => 'post-word-count')); } $postcontent .= html_writer::tag('div', $attachedimages, array('class' => 'attachedimages')); } // Output the post content $output .= html_writer::tag('div', $postcontent, array('class' => 'posting ' . $postclass)); $output .= html_writer::end_tag('div'); // Content $output .= html_writer::end_tag('div'); // Content mask $output .= html_writer::end_tag('div'); // Row $output .= html_writer::start_tag('div', array('class' => 'row side')); $output .= html_writer::tag('div', ' ', array('class' => 'left')); $output .= html_writer::start_tag('div', array('class' => 'options clearfix')); if (!empty($attachments)) { $output .= html_writer::tag('div', $attachments, array('class' => 'attachments')); } // Output ratings if (!empty($post->rating)) { $output .= html_writer::tag('div', $OUTPUT->render($post->rating), array('class' => 'forum-post-rating')); } // Output the commands $commandhtml = array(); foreach ($commands as $command) { if (is_array($command)) { $commandhtml[] = html_writer::link($command['url'], $command['text']); } else { $commandhtml[] = $command; } } $output .= html_writer::tag('div', implode(' | ', $commandhtml), array('class' => 'commands')); // Output link to post if required if ($link) { if (forum_user_can_post($forum, $discussion, $USER, $cm, $course, $modcontext)) { $langstring = 'discussthistopic'; } else { $langstring = 'viewthediscussion'; } if ($post->replies == 1) { $replystring = get_string('repliesone', 'forum', $post->replies); } else { $replystring = get_string('repliesmany', 'forum', $post->replies); } if (!empty($discussion->unread) && $discussion->unread !== '-') { $replystring .= ' <span class="sep">/</span> <span class="unread">'; if ($discussion->unread == 1) { $replystring .= get_string('unreadpostsone', 'forum'); } else { $replystring .= get_string('unreadpostsnumber', 'forum', $discussion->unread); } $replystring .= '</span>'; } $output .= html_writer::start_tag('div', array('class' => 'link')); $output .= html_writer::link($discussionlink, get_string($langstring, 'forum')); $output .= ' (' . $replystring . ')'; $output .= html_writer::end_tag('div'); // link } // Output footer if required if ($footer) { $output .= html_writer::tag('div', $footer, array('class' => 'footer')); } // Close remaining open divs $output .= html_writer::end_tag('div'); // content $output .= html_writer::end_tag('div'); // row $output .= html_writer::end_tag('div'); // forumpost // Mark the forum post as read if required if ($istracked && !$CFG->forum_usermarksread && !$postisread) { forum_tp_mark_post_read($USER->id, $post, $forum->id); } if ($return) { return $output; } echo $output; return; }
/** * Print a forum post * * @param object $post The post to print. * @param integer $courseid The course this post belongs to. * @param boolean $ownpost Whether this post belongs to the current user. * @param boolean $reply Whether to print a 'reply' link at the bottom of the message. * @param boolean $link Just print a shortened version of the post as a link to the full post. * @param object $ratings -- I don't really know -- * @param string $footer Extra stuff to print after the message. * @param string $highlight Space-separated list of terms to highlight. * @param int $post_read true, false or -99. If we already know whether this user * has read this post, pass that in, otherwise, pass in -99, and this * function will work it out. * @param boolean $dummyifcantsee When forum_user_can_see_post says that * the current user can't see this post, if this argument is true * (the default) then print a dummy 'you can't see this post' post. * If false, don't output anything at all. */ function forum_print_post($post, $discussion, $forum, &$cm, $course, $ownpost = false, $reply = false, $link = false, $ratings = NULL, $footer = "", $highlight = "", $post_read = null, $dummyifcantsee = true, $istracked = null) { global $USER, $CFG; static $stredit, $strdelete, $strreply, $strparent, $strprune; static $strpruneheading, $displaymode; static $strmarkread, $strmarkunread; $post->course = $course->id; $post->forum = $forum->id; // caching if (!isset($cm->cache)) { $cm->cache = new object(); } if (!isset($cm->cache->caps)) { $cm->cache->caps = array(); $modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); $cm->cache->caps['mod/forum:viewdiscussion'] = has_capability('mod/forum:viewdiscussion', $modcontext); $cm->cache->caps['moodle/site:viewfullnames'] = has_capability('moodle/site:viewfullnames', $modcontext); $cm->cache->caps['mod/forum:editanypost'] = has_capability('mod/forum:editanypost', $modcontext); $cm->cache->caps['mod/forum:splitdiscussions'] = has_capability('mod/forum:splitdiscussions', $modcontext); $cm->cache->caps['mod/forum:deleteownpost'] = has_capability('mod/forum:deleteownpost', $modcontext); $cm->cache->caps['mod/forum:deleteanypost'] = has_capability('mod/forum:deleteanypost', $modcontext); $cm->cache->caps['mod/forum:viewanyrating'] = has_capability('mod/forum:viewanyrating', $modcontext); } if (!isset($cm->uservisible)) { $cm->uservisible = coursemodule_visible_for_user($cm); } if (!forum_user_can_see_post($forum, $discussion, $post, NULL, $cm)) { if (!$dummyifcantsee) { return; } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost">'; echo '<tr class="header"><td class="picture left">'; // print_user_picture($post->userid, $courseid, $post->picture); echo '</td>'; if ($post->parent) { echo '<td class="topic">'; } else { echo '<td class="topic starter">'; } echo '<div class="subject">' . get_string('forumsubjecthidden', 'forum') . '</div>'; echo '<div class="author">'; print_string('forumauthorhidden', 'forum'); echo '</div></td></tr>'; echo '<tr><td class="left side">'; echo ' '; // Actual content echo '</td><td class="content">' . "\n"; echo get_string('forumbodyhidden', 'forum'); echo '</td></tr></table>'; return; } if (empty($stredit)) { $stredit = get_string('edit', 'forum'); $strdelete = get_string('delete', 'forum'); $strreply = get_string('reply', 'forum'); $strparent = get_string('parent', 'forum'); $strpruneheading = get_string('pruneheading', 'forum'); $strprune = get_string('prune', 'forum'); $displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); $strmarkread = get_string('markread', 'forum'); $strmarkunread = get_string('markunread', 'forum'); } $read_style = ''; // ignore trackign status if not tracked or tracked param missing if ($istracked) { if (is_null($post_read)) { debugging('fetching post_read info'); $post_read = forum_tp_is_post_read($USER->id, $post); } if ($post_read) { $read_style = ' read'; } else { $read_style = ' unread'; echo '<a name="unread"></a>'; } } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost' . $read_style . '">'; // Picture $postuser = new object(); $postuser->id = $post->userid; $postuser->firstname = $post->firstname; $postuser->lastname = $post->lastname; $postuser->imagealt = $post->imagealt; $postuser->picture = $post->picture; echo '<tr class="header"><td class="picture left">'; print_user_picture($postuser, $course->id); echo '</td>'; if ($post->parent) { echo '<td class="topic">'; } else { echo '<td class="topic starter">'; } if (!empty($post->subjectnoformat)) { echo '<div class="subject">' . $post->subject . '</div>'; } else { echo '<div class="subject">' . format_string($post->subject) . '</div>'; } echo '<div class="author">'; $fullname = fullname($postuser, $cm->cache->caps['moodle/site:viewfullnames']); $by = new object(); $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $post->userid . '&course=' . $course->id . '">' . $fullname . '</a>'; $by->date = userdate($post->modified); print_string('bynameondate', 'forum', $by); echo '</div></td></tr>'; echo '<tr><td class="left side">'; if (isset($cm->cache->usersgroups)) { $groups = array(); if (isset($cm->cache->usersgroups[$post->userid])) { foreach ($cm->cache->usersgroups[$post->userid] as $gid) { $groups[$gid] = $cm->cache->groups[$gid]; } } } else { $groups = groups_get_all_groups($course->id, $post->userid, $cm->groupingid); } if ($groups) { print_group_picture($groups, $course->id, false, false, true); } else { echo ' '; } // Actual content echo '</td><td class="content">' . "\n"; if ($post->attachment) { echo '<div class="attachments">'; $attachedimages = forum_print_attachments($post); echo '</div>'; } else { $attachedimages = ''; } $options = new object(); $options->para = false; $options->trusttext = true; if ($link and strlen(strip_tags($post->message)) > $CFG->forum_longpost) { // Print shortened version echo format_text(forum_shorten_post($post->message), $post->format, $options, $course->id); $numwords = count_words(strip_tags($post->message)); echo '<p><a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">'; echo get_string('readtherest', 'forum'); echo '</a> (' . get_string('numwords', '', $numwords) . ')...</p>'; } else { // Print whole message if ($highlight) { echo highlight($highlight, format_text($post->message, $post->format, $options, $course->id)); } else { echo format_text($post->message, $post->format, $options, $course->id); } echo $attachedimages; } // Commands $commands = array(); if ($istracked) { // SPECIAL CASE: The front page can display a news item post to non-logged in users. // Don't display the mark read / unread controls in this case. if ($CFG->forum_usermarksread and isloggedin()) { if ($post_read) { $mcmd = '&mark=unread&postid=' . $post->id; $mtxt = $strmarkunread; } else { $mcmd = '&mark=read&postid=' . $post->id; $mtxt = $strmarkread; } if ($displaymode == FORUM_MODE_THREADED) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->id . $mcmd . '">' . $mtxt . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . $mcmd . '#p' . $post->id . '">' . $mtxt . '</a>'; } } } if ($post->parent) { // Zoom in to the parent specifically if ($displaymode == FORUM_MODE_THREADED) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->parent . '">' . $strparent . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '#p' . $post->parent . '">' . $strparent . '</a>'; } } $age = time() - $post->created; // Hack for allow to edit news posts those are not displayed yet until they are displayed if (!$post->parent and $forum->type == 'news' and $discussion->timestart > time()) { $age = 0; } $editanypost = $cm->cache->caps['mod/forum:editanypost']; if ($ownpost or $editanypost) { if ($age < $CFG->maxeditingtime or $editanypost) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?edit=' . $post->id . '">' . $stredit . '</a>'; } } if ($cm->cache->caps['mod/forum:splitdiscussions'] && $post->parent && $forum->type != 'single') { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?prune=' . $post->id . '" title="' . $strpruneheading . '">' . $strprune . '</a>'; } if ($ownpost and $age < $CFG->maxeditingtime and $cm->cache->caps['mod/forum:deleteownpost'] or $cm->cache->caps['mod/forum:deleteanypost']) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?delete=' . $post->id . '">' . $strdelete . '</a>'; } if ($reply) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?reply=' . $post->id . '">' . $strreply . '</a>'; } echo '<div class="commands">'; echo implode(' | ', $commands); echo '</div>'; // Ratings $ratingsmenuused = false; if (!empty($ratings) and isloggedin()) { echo '<div class="ratings">'; $useratings = true; if ($ratings->assesstimestart and $ratings->assesstimefinish) { if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) { $useratings = false; } } if ($useratings) { $mypost = $USER->id == $post->userid; $canviewallratings = $cm->cache->caps['mod/forum:viewanyrating']; if (isset($cm->cache->ratings)) { if (isset($cm->cache->ratings[$post->id])) { $allratings = $cm->cache->ratings[$post->id]; } else { $allratings = array(); // no reatings present yet } } else { $allratings = NULL; // not preloaded } if (isset($cm->cache->myratings)) { if (isset($cm->cache->myratings[$post->id])) { $myrating = $cm->cache->myratings[$post->id]; } else { $myrating = FORUM_UNSET_POST_RATING; // no reatings present yet } } else { $myrating = NULL; // not preloaded } if ($canviewallratings and !$mypost) { forum_print_ratings($post->id, $ratings->scale, $forum->assessed, $canviewallratings, $allratings); if (!empty($ratings->allow)) { echo ' '; forum_print_rating_menu($post->id, $USER->id, $ratings->scale, $myrating); $ratingsmenuused = true; } } else { if ($mypost) { forum_print_ratings($post->id, $ratings->scale, $forum->assessed, true, $allratings); } else { if (!empty($ratings->allow)) { forum_print_rating_menu($post->id, $USER->id, $ratings->scale, $myrating); $ratingsmenuused = true; } } } } echo '</div>'; } // Link to post if required if ($link) { echo '<div class="link">'; if ($post->replies == 1) { $replystring = get_string('repliesone', 'forum', $post->replies); } else { $replystring = get_string('repliesmany', 'forum', $post->replies); } echo '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">' . get_string('discussthistopic', 'forum') . '</a> (' . $replystring . ')'; echo '</div>'; } if ($footer) { echo '<div class="footer">' . $footer . '</div>'; } echo '</td></tr></table>' . "\n\n"; if ($istracked && !$CFG->forum_usermarksread && !$post_read) { forum_tp_mark_post_read($USER->id, $post, $forum->id); } return $ratingsmenuused; }
/** * The plaintext version of the attachments list. * * @param \stdClass $cm * @param \stdClass $post * @return string */ public function format_message_attachments($cm, $post) { return forum_print_attachments($post, $cm, "text"); }
/** * Print a forum post * * @param object $post The post to print. * @param integer $courseid The course this post belongs to. * @param boolean $ownpost Whether this post belongs to the current user. * @param boolean $reply Whether to print a 'reply' link at the bottom of the message. * @param boolean $link Just print a shortened version of the post as a link to the full post. * @param object $ratings -- I don't really know -- * @param string $footer Extra stuff to print after the message. * @param string $highlight Space-separated list of terms to highlight. * @param int $post_read true, false or -99. If we already know whether this user * has read this post, pass that in, otherwise, pass in -99, and this * function will work it out. * @param boolean $dummyifcantsee When forum_user_can_see_post says that * the current user can't see this post, if this argument is true * (the default) then print a dummy 'you can't see this post' post. * If false, don't output anything at all. */ function forum_print_post(&$post, $courseid, $ownpost = false, $reply = false, $link = false, $ratings = NULL, $footer = "", $highlight = "", $post_read = -99, $dummyifcantsee = true) { global $USER, $CFG; static $stredit, $strdelete, $strreply, $strparent, $strprune; static $strpruneheading, $displaymode; static $strmarkread, $strmarkunread, $istracked; if (empty($post->modcontext)) { // Have to generate it, which is expensive! Should always be set. if (empty($post->forum)) { $discussion = get_record('forum_discussions', 'id', $post->discussion); $post->forum = $discussion->forum; } if (!($cm = get_coursemodule_from_instance('forum', $post->forum))) { error('Course Module ID was incorrect'); } $post->modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); } if (!forum_user_can_see_post($post->forum, $post->discussion, $post)) { if (!$dummyifcantsee) { return; } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost">'; echo '<tr class="header"><td class="picture left">'; // print_user_picture($post->userid, $courseid, $post->picture); echo '</td>'; if ($post->parent) { echo '<td class="topic">'; } else { echo '<td class="topic starter">'; } echo '<div class="subject">' . get_string('forumsubjecthidden', 'forum') . '</div>'; echo '<div class="author">'; print_string('forumauthorhidden', 'forum'); echo '</div></td></tr>'; echo '<tr><td class="left side">'; echo ' '; // Actual content echo '</td><td class="content">' . "\n"; echo get_string('forumbodyhidden', 'forum'); echo '</td></tr></table>'; return; } if (empty($stredit)) { $stredit = get_string('edit', 'forum'); $strdelete = get_string('delete', 'forum'); $strreply = get_string('reply', 'forum'); $strparent = get_string('parent', 'forum'); $strpruneheading = get_string('pruneheading', 'forum'); $strprune = get_string('prune', 'forum'); $displaymode = get_user_preferences('forum_displaymode', $CFG->forum_displaymode); $strmarkread = get_string('markread', 'forum'); $strmarkunread = get_string('markunread', 'forum'); if (!empty($post->forum)) { $istracked = forum_tp_can_track_forums($post->forum) && forum_tp_is_tracked($post->forum); } else { $istracked = false; } } if ($istracked) { if ($post_read == -99) { // If we don't know yet... // The front page can display a news item post to non-logged in users. This should // always appear as 'read'. $post_read = empty($USER) || forum_tp_is_post_read($USER->id, $post); } if ($post_read) { $read_style = ' read'; } else { $read_style = ' unread'; echo '<a name="unread"></a>'; } } else { $read_style = ''; } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost' . $read_style . '">'; // Picture $postuser = new object(); $postuser->id = $post->userid; $postuser->firstname = $post->firstname; $postuser->lastname = $post->lastname; $postuser->imagealt = $post->imagealt; $postuser->picture = $post->picture; echo '<tr class="header"><td class="picture left">'; print_user_picture($postuser, $courseid); echo '</td>'; if ($post->parent) { echo '<td class="topic">'; } else { echo '<td class="topic starter">'; } if (!empty($post->subjectnoformat)) { echo '<div class="subject">' . $post->subject . '</div>'; } else { echo '<div class="subject">' . format_string($post->subject) . '</div>'; } echo '<div class="author">'; $fullname = fullname($post, has_capability('moodle/site:viewfullnames', $post->modcontext)); $by = new object(); $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $post->userid . '&course=' . $courseid . '">' . $fullname . '</a>'; $by->date = userdate($post->modified); print_string('bynameondate', 'forum', $by); echo '</div></td></tr>'; echo '<tr><td class="left side">'; if ($group = groups_get_all_groups($courseid, $post->userid)) { print_group_picture($group, $courseid, false, false, true); } else { echo ' '; } // Actual content echo '</td><td class="content">' . "\n"; if ($post->attachment) { $post->course = $courseid; $post->forum = get_field('forum_discussions', 'forum', 'id', $post->discussion); echo '<div class="attachments">'; $attachedimages = forum_print_attachments($post); echo '</div>'; } else { $attachedimages = ''; } $options = new Object(); $options->para = false; $options->trusttext = true; if ($link and strlen(strip_tags($post->message)) > $CFG->forum_longpost) { // Print shortened version echo format_text(forum_shorten_post($post->message), $post->format, $options, $courseid); $numwords = count_words(strip_tags($post->message)); echo '<p><a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">'; echo get_string('readtherest', 'forum'); echo '</a> (' . get_string('numwords', '', $numwords) . ')...</p>'; } else { // Print whole message if ($highlight) { echo highlight($highlight, format_text($post->message, $post->format, $options, $courseid)); } else { echo format_text($post->message, $post->format, $options, $courseid); } echo $attachedimages; } // Commands $commands = array(); if ($istracked) { // SPECIAL CASE: The front page can display a news item post to non-logged in users. // Don't display the mark read / unread controls in this case. if ($CFG->forum_usermarksread && !empty($USER)) { if ($post_read) { $mcmd = '&mark=unread&postid=' . $post->id; $mtxt = $strmarkunread; } else { $mcmd = '&mark=read&postid=' . $post->id; $mtxt = $strmarkread; } if ($displaymode == FORUM_MODE_THREADED) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->id . $mcmd . '">' . $mtxt . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . $mcmd . '#p' . $post->id . '">' . $mtxt . '</a>'; } } } if ($post->parent) { // Zoom in to the parent specifically if ($displaymode == FORUM_MODE_THREADED) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->parent . '">' . $strparent . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '#p' . $post->parent . '">' . $strparent . '</a>'; } } if (!isset($post->forumtype)) { $post->forumtype = get_field('forum', 'type', 'id', $post->forum); } $age = time() - $post->created; // Hack for allow to edit news posts those are not displayed yet until they are displayed if (!$post->parent && $post->forumtype == 'news' && get_field_sql("SELECT id FROM {$CFG->prefix}forum_discussions WHERE id = {$post->discussion} AND timestart > " . time())) { $age = 0; } $editanypost = has_capability('mod/forum:editanypost', $post->modcontext); if ($ownpost or $editanypost) { if ($age < $CFG->maxeditingtime or $editanypost) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?edit=' . $post->id . '">' . $stredit . '</a>'; } } if (has_capability('mod/forum:splitdiscussions', $post->modcontext) && $post->parent && $post->forumtype != 'single') { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?prune=' . $post->id . '" title="' . $strpruneheading . '">' . $strprune . '</a>'; } if ($ownpost and $age < $CFG->maxeditingtime and has_capability('mod/forum:deleteownpost', $post->modcontext) or has_capability('mod/forum:deleteanypost', $post->modcontext)) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?delete=' . $post->id . '">' . $strdelete . '</a>'; } if ($reply) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?reply=' . $post->id . '">' . $strreply . '</a>'; } echo '<div class="commands">'; echo implode(' | ', $commands); echo '</div>'; // Ratings $ratingsmenuused = false; if (!empty($ratings) and !empty($USER->id)) { echo '<div class="ratings">'; $useratings = true; if ($ratings->assesstimestart and $ratings->assesstimefinish) { if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) { $useratings = false; } } if ($useratings) { $mypost = $USER->id == $post->userid; $canviewallratings = has_capability('mod/forum:viewanyrating', $post->modcontext); if ($canviewallratings and !$mypost) { forum_print_ratings_mean($post->id, $ratings->scale, $canviewallratings); if (!empty($ratings->allow)) { echo ' '; forum_print_rating_menu($post->id, $USER->id, $ratings->scale); $ratingsmenuused = true; } } else { if ($mypost) { forum_print_ratings_mean($post->id, $ratings->scale, true); } else { if (!empty($ratings->allow)) { forum_print_rating_menu($post->id, $USER->id, $ratings->scale); $ratingsmenuused = true; } } } } echo '</div>'; } // Link to post if required if ($link) { echo '<div class="link">'; if ($post->replies == 1) { $replystring = get_string('repliesone', 'forum', $post->replies); } else { $replystring = get_string('repliesmany', 'forum', $post->replies); } echo '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">' . get_string('discussthistopic', 'forum') . '</a> (' . $replystring . ')'; echo '</div>'; } if ($footer) { echo '<div class="footer">' . $footer . '</div>'; } echo '</td></tr></table>' . "\n\n"; if ($istracked && !$CFG->forum_usermarksread && !empty($post->forum)) { forum_tp_mark_post_read($USER->id, $post, $post->forum); } return $ratingsmenuused; }
/** * TODO document */ function forum_print_post(&$post, $courseid, $ownpost = false, $reply = false, $link = false, $ratings = NULL, $footer = "", $highlight = "", $post_read = -99) { global $USER, $CFG, $SESSION; static $stredit, $strdelete, $strreply, $strparent, $strprune; static $strpruneheading, $threadedmode; static $strmarkread, $strmarkunread, $istracked; if (empty($post->modcontext)) { // Have to generate it, which is expensive! Should always be set. if (empty($post->forum)) { $discussion = get_record('forum_discussions', 'id', $post->discussion); $post->forum = $discussion->forum; } if (!($cm = get_coursemodule_from_instance('forum', $post->forum))) { error('Course Module ID was incorrect'); } $post->modcontext = get_context_instance(CONTEXT_MODULE, $cm->id); } if (!forum_user_can_see_post($post->forum, $post->discussion, $post)) { if (empty($SESSION->forum_search)) { // just viewing, return return; } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost">'; echo '<tr class="header"><td class="picture left">'; // print_user_picture($post->userid, $courseid, $post->picture); echo '</td>'; if ($post->parent) { echo '<td class="topic">'; } else { echo '<td class="topic starter">'; } echo '<div class="subject">' . get_string('forumsubjecthidden', 'forum') . '</div>'; echo '<div class="author">'; print_string('forumauthorhidden', 'forum'); echo '</div></td></tr>'; echo '<tr><td class="left side">'; echo ' '; // Actual content echo '</td><td class="content">' . "\n"; echo get_string('forumbodyhidden', 'forum'); echo '</td></tr></table>'; return; } if (empty($stredit)) { $stredit = get_string('edit', 'forum'); $strdelete = get_string('delete', 'forum'); $strreply = get_string('reply', 'forum'); $strparent = get_string('parent', 'forum'); $strpruneheading = get_string('pruneheading', 'forum'); $strprune = get_string('prune', 'forum'); $threadedmode = (!empty($USER->mode) and $USER->mode == FORUM_MODE_THREADED); $strmarkread = get_string('markread', 'forum'); $strmarkunread = get_string('markunread', 'forum'); if (!empty($post->forum)) { $istracked = forum_tp_can_track_forums($post->forum) && forum_tp_is_tracked($post->forum); } else { $istracked = false; } } if ($istracked) { if ($post_read == -99) { // If we don't know yet... // The front page can display a news item post to non-logged in users. This should // always appear as 'read'. $post_read = empty($USER) || forum_tp_is_post_read($USER->id, $post); } if ($post_read) { $read_style = ' read'; } else { $read_style = ' unread'; echo '<a name="unread"></a>'; } } else { $read_style = ''; } echo '<a id="p' . $post->id . '"></a>'; echo '<table cellspacing="0" class="forumpost' . $read_style . ' ' . PM_POST_CLASS . '" id="m' . $post->id . '">'; // Picture $postuser = new object(); $postuser->id = $post->userid; $postuser->firstname = $post->firstname; $postuser->lastname = $post->lastname; $postuser->imagealt = $post->imagealt; $postuser->picture = $post->picture; echo '<tr class="header"><td class="picture left">'; print_user_picture($postuser, $courseid); echo '</td>'; if ($post->parent) { echo '<td class="topic" colspan="3">'; } else { echo '<td class="topic starter" colspan="3">'; } echo '<div class="subject ' . PM_TITLE_CLASS . '">' . format_string($post->subject) . '</div>'; // #GEOF# Annotations must use a unique value for the user ID // This should be a string, and it should be human-readable and suitable for // outside consumption. I'm therefore using username rather than ID. // If Moodle displayed these values, the fields wouldn'n need to be hidden. $rootpath = $CFG->wwwroot; //parse_url( $CFG->wwwroot ); //$rootpath = $rootpath[ 'path' ]; $refurl = "{$rootpath}/mod/forum/permalink.php?p={$post->id}"; $discussurl = "{$rootpath}/mod/forum/discuss.php?d={$post->discussion}"; // used for summary link // This class author, used by Marginalia, must preceed the one below, used by Moodle. (Well, not in Moodle 1.8) // Unfortunately I can't use that one - it's marked author but it is not, in fact, the author // - it also includes "by", the date, etc. (grrr) #geof# echo "<span style='display:none' class='" . PM_AUTHOR_CLASS . "' title='" . htmlspecialchars($post->username) . "'>" . htmlspecialchars($post->firstname . ' ' . $post->lastname) . "</span>\n"; echo "<abbr style='display:none' class='" . PM_DATE_CLASS . "' title='" . date('Ymd', $post->modified) . 'T' . date('HiO', $post->modified) . "'></abbr>\n"; echo "<a style='display:none' rel='" . PM_URL_REL . "' href='{$refurl}'></a>\n"; echo '<div class="author">'; $fullname = fullname($post, has_capability('moodle/site:viewfullnames', $post->modcontext)); $by->name = '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $post->userid . '&course=' . $courseid . '">' . $fullname . '</a>'; $by->date = userdate($post->modified); // This, I presume, is to localize string display. Unfortunately it's // unstructured text, so I can't insert the necessary <abbr> element with the date. // Instead that's done in a hidden tag above. print_string('bynameondate', 'forum', $by); echo '</div></td></tr>'; echo '<tr><td class="left side">'; if ($group = user_group($courseid, $post->userid)) { print_group_picture($group, $courseid, false, false, true); } else { echo ' '; } // Actual content echo '</td><td class="content ' . PM_CONTENT_CLASS . '" valign="top">' . "\n"; if ($post->attachment) { $post->course = $courseid; $post->forum = get_field('forum_discussions', 'forum', 'id', $post->discussion); echo '<div class="attachments">'; $attachedimages = forum_print_attachments($post); echo '</div>'; } else { $attachedimages = ''; } $options = new Object(); $options->para = false; $options->trusttext = true; if ($link and strlen(strip_tags($post->message)) > $CFG->forum_longpost) { // Print shortened version echo format_text(forum_shorten_post($post->message), $post->format, $options, $courseid); $numwords = count_words(strip_tags($post->message)); echo '<p><a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">'; echo get_string('readtherest', 'forum'); echo '</a> (' . get_string('numwords', '', $numwords) . ')...</p>'; } else { // Print whole message if ($highlight) { echo highlight($highlight, format_text($post->message, $post->format, $options, $courseid)); } else { echo format_text($post->message, $post->format, $options, $courseid); } echo $attachedimages; } // Commands $commands = array(); if ($istracked) { // SPECIAL CASE: The front page can display a news item post to non-logged in users. // Don't display the mark read / unread controls in this case. if ($CFG->forum_usermarksread && !empty($USER)) { if ($post_read) { $mcmd = '&mark=unread&postid=' . $post->id; $mtxt = $strmarkunread; } else { $mcmd = '&mark=read&postid=' . $post->id; $mtxt = $strmarkread; } if ($threadedmode) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->id . $mcmd . '">' . $mtxt . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . $mcmd . '#p' . $post->id . '">' . $mtxt . '</a>'; } } } if ($post->parent) { if ($threadedmode) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '&parent=' . $post->parent . '">' . $strparent . '</a>'; } else { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '#p' . $post->parent . '">' . $strparent . '</a>'; } } if (!isset($post->forumtype)) { $post->forumtype = get_field('forum', 'type', 'id', $post->forum); } $age = time() - $post->created; // Hack for allow to edit news posts those are not displayed yet until they are displayed if (!$post->parent && $post->forumtype == 'news' && get_field_sql("SELECT id FROM {$CFG->prefix}forum_discussions WHERE id = {$post->discussion} AND timestart > " . time())) { $age = 0; } $editanypost = has_capability('mod/forum:editanypost', $post->modcontext); if ($ownpost or $editanypost) { if ($age < $CFG->maxeditingtime or $editanypost) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?edit=' . $post->id . '">' . $stredit . '</a>'; } } if (has_capability('mod/forum:splitdiscussions', $post->modcontext) && $post->parent && $post->forumtype != 'single') { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?prune=' . $post->id . '" title="' . $strpruneheading . '">' . $strprune . '</a>'; } if ($ownpost and $age < $CFG->maxeditingtime and has_capability('mod/forum:deleteownpost', $post->modcontext) or has_capability('mod/forum:deleteanypost', $post->modcontext)) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?delete=' . $post->id . '">' . $strdelete . '</a>'; } // The span below is to allow text-decoration:underline, which doesn't seem // to work otherwise (Firefox bug?) $commands[] = "<button class='smartquote'><span>Quote</span></button>"; if ($reply) { $commands[] = '<a href="' . $CFG->wwwroot . '/mod/forum/post.php?reply=' . $post->id . '">' . $strreply . '</a>'; } echo '<div class="commands">'; echo implode(' | ', $commands); echo '</div>'; // Ratings $ratingsmenuused = false; if (!empty($ratings) and !empty($USER->id)) { echo '<div class="ratings">'; $useratings = true; if ($ratings->assesstimestart and $ratings->assesstimefinish) { if ($post->created < $ratings->assesstimestart or $post->created > $ratings->assesstimefinish) { $useratings = false; } } if ($useratings) { $mypost = $USER->id == $post->userid; $canviewallratings = has_capability('mod/forum:viewanyrating', $post->modcontext); if ($canviewallratings and !$mypost) { forum_print_ratings_mean($post->id, $ratings->scale, $canviewallratings); if (!empty($ratings->allow)) { echo ' '; forum_print_rating_menu($post->id, $USER->id, $ratings->scale); $ratingsmenuused = true; } } else { if ($mypost) { forum_print_ratings_mean($post->id, $ratings->scale, true); } else { if (!empty($ratings->allow)) { forum_print_rating_menu($post->id, $USER->id, $ratings->scale); $ratingsmenuused = true; } } } } echo '</div>'; } // Link to post if required if ($link) { echo '<div class="link">'; if ($post->replies == 1) { $replystring = get_string('repliesone', 'forum', $post->replies); } else { $replystring = get_string('repliesmany', 'forum', $post->replies); } echo '<a href="' . $CFG->wwwroot . '/mod/forum/discuss.php?d=' . $post->discussion . '">' . get_string('discussthistopic', 'forum') . '</a> (' . $replystring . ')'; echo '</div>'; } if ($footer) { echo '<div class="footer">' . $footer . '</div>'; } // if ( $canannotate ) // { echo "</td><td class='control-margin'><div><button type='button' " . " title='" . htmlspecialchars(get_string('create_button', ANNOTATION_STRINGS)) . "'" . " onclick='window.moodleMarginalia.createAnnotation(event,\"m{$post->id}\")'><span>></span></button></div></td>\n"; echo "<td class='" . AN_NOTES_CLASS . "' valign='top'><div>"; echo "<ol></ol>\n"; echo "</div></td>\n"; // } // else // echo "<td></td><td></td>"; echo '</tr></table>' . "\n\n"; if ($istracked && !$CFG->forum_usermarksread && !empty($post->forum)) { forum_tp_mark_post_read($USER->id, $post, $post->forum); } return $ratingsmenuused; }