コード例 #1
0
 public function display($forum)
 {
     $out = mod_forumng_utils::get_renderer();
     // Work out current status
     $manualmark = !mod_forumng::mark_read_automatically();
     $current = get_string($manualmark ? 'manualmark_manual' : 'manualmark_auto', 'forumngfeature_manualmark');
     // Make a help button
     $change = get_string('manualmark_change', 'forumngfeature_manualmark');
     $helpbutton = $out->help_icon('manualmark_change', 'forumngfeature_manualmark');
     // Get the button form
     $params = $forum->get_link_params_array();
     return parent::get_button($forum, $change, 'feature/manualmark/change.php', true, $params, $helpbutton, 'forumng-manualmark', $current . ' ', 'forumng-button-to-link');
 }
コード例 #2
0
 /**
  * Internal method. Queries for a number of discussions, including additional
  * data about unread posts etc. Returns the database result.
  * @param string $conditions WHERE clause (may refer to aliases 'd' for discussion)
  * @param array $conditionparams Parameters for conditions
  * @param int $userid User ID, 0 = current user, -1 = no unread data is needed
  * @param string $orderby ORDER BY clause
  * @param int $limitfrom Limit on results
  * @param int $limitnum Limit on results
  * @param mod_forumng $typeforum If set, this forum is used to potentially restrict
  *   the results based on forum type limits
  * @param boolean $flags set to indicate that flagged discussions are to be returned
  * @param boolean hastag set to indicate that tagged discussions are to be returned
  * @return adodb_recordset Database query results
  */
 public static function query_discussions($conditions, $conditionparams, $userid, $orderby, $limitfrom = '', $limitnum = '', $typeforum = null, $flags = false, $hastag = false)
 {
     global $USER, $DB;
     // For read tracking, we get a count of total number of posts in
     // discussion, and total number of read posts in the discussion (this
     // is so we can display the number of UNread posts, but the query
     // works that way around because it will return 0 if no read
     // information is stored).
     if (mod_forumng::enabled_read_tracking() && $userid != -1) {
         if (!$userid) {
             $userid = $USER->id;
         }
         $deadline = mod_forumng::get_read_tracking_deadline();
         $readjoin1 = "";
         $readwhere1 = "";
         $readtrackingparams = array($deadline, $userid, $userid, $deadline);
         $readtrackingjoinparams = array($userid);
         if (!mod_forumng::mark_read_automatically($userid)) {
             // Ind Mark read - check individual read_posts state.
             $readjoin1 = "LEFT JOIN {forumng_read_posts} frp2 on frp2.postid = fp3.id AND frp2.userid = ?";
             $readwhere1 = "OR frp2.id IS NOT NULL";
             $readtrackingparams = array($deadline, $userid, $userid, $userid, $deadline);
         }
         // Get unread count only when last added post is newer than deadline.
         // When PAST_SELL_BY, posts modified later than last will be unread but not picked up.
         $readtracking = "\n                    , (CASE WHEN fplast.modified IS NOT NULL AND fplast.modified < ? THEN " . self::PAST_SELL_BY . " ELSE (SELECT COUNT(1)\n                        FROM {forumng_posts} fp3\n                  {$readjoin1}\n                       WHERE fp3.discussionid = fd.id AND fp3.oldversion = 0\n                         AND fp3.deleted = 0\n                         AND (fp3.modified < fr.time OR fp3.edituserid = ?\n                            {$readwhere1}\n                            OR (fp3.edituserid IS NULL AND fp3.userid = ?)\n                            OR fp3.modified < ?)) END) AS numreadposts,\n                   fr.time AS timeread";
         // Join read info, get posts not authored by user: get latest modified post time.
         $readtrackingjoin = "LEFT JOIN {forumng_read} fr ON fd.id = fr.discussionid AND fr.userid = ?";
     } else {
         $readtracking = ", 0 AS numreadposts, NULL AS timeread";
         $readtrackingjoin = "";
         $readtrackingparams = array();
         $readtrackingjoinparams = array();
     }
     $order = $orderby ? 'ORDER BY ' . $orderby : '';
     // Handle forum type restriction
     $typejoin = '';
     $typeparams = array();
     $flagsjoin = '';
     $flagsquery = '';
     $flagparams = array();
     if ($typeforum && $userid != -1) {
         $type = $typeforum->get_type();
         if ($type->has_unread_restriction()) {
             list($restrictionsql, $restrictionparams) = $type->get_unread_restriction_sql($typeforum, $userid);
         } else {
             $restrictionsql = false;
         }
         if ($restrictionsql) {
             $typejoin = "\n    INNER JOIN {forumng} f ON f.id = fd.forumngid\n    INNER JOIN {course} c ON c.id = f.course\n    INNER JOIN {course_modules} cm ON cm.instance = f.id AND cm.course = f.course\n    INNER JOIN {modules} m ON m.id = cm.module";
             $conditions .= " AND m.name = 'forumng' AND {$restrictionsql}";
             $conditionparams = array_merge($conditionparams, $restrictionparams);
         }
     }
     if ($flags && $userid != -1) {
         $flagsjoin = "LEFT JOIN {forumng_flags} ff ON ff.discussionid = fd.id AND ff.userid = ?";
         $flagsquery = ', ff.flagged';
         $flagparams = array($userid);
     }
     // Tag join sql if needed.
     $tagjoin = '';
     if ($hastag) {
         $tagjoin = "LEFT JOIN {tag_instance} ti on ti.itemid = fd.id\n                            AND ti.itemtype = 'forumng_discussions'\n                            AND ti.component = 'mod_forumng'";
     }
     // Main query. This retrieves:
     // * Basic discussion information.
     // * Information about the discussion that is obtained from the first and
     //   last post.
     // * Information about the users responsible for first and last post.
     $rs = $DB->get_recordset_sql("\nSELECT * FROM (SELECT\n    fd.*,\n    fpfirst.created AS timecreated,\n    fplast.modified AS timemodified,\n    fpfirst.subject AS subject,\n    fplast.subject AS lastsubject,\n    fplast.message AS lastmessage,\n    fpfirst.asmoderator AS firstasmoderator,\n    fplast.asmoderator AS lastasmoderator,\n    " . mod_forumng_utils::select_username_fields('fu') . ",\n    " . mod_forumng_utils::select_username_fields('lu') . ",\n    (SELECT COUNT(1)\n        FROM {forumng_posts} fp2\n        WHERE fp2.discussionid = fd.id AND fp2.deleted = 0 AND fp2.oldversion = 0)\n        AS numposts,\n    g.name AS groupname\n    {$readtracking}\n    {$flagsquery}\nFROM\n    {forumng_discussions} fd\n    INNER JOIN {forumng_posts} fpfirst ON fd.postid = fpfirst.id\n    INNER JOIN {user} fu ON fpfirst.userid = fu.id\n    INNER JOIN {forumng_posts} fplast ON fd.lastpostid = fplast.id\n    INNER JOIN {user} lu ON fplast.userid = lu.id\n    LEFT JOIN {groups} g ON g.id = fd.groupid\n    {$readtrackingjoin}\n    {$typejoin}\n    {$flagsjoin}\n    {$tagjoin}\nWHERE\n    {$conditions}) x {$order}\n", array_merge($readtrackingparams, $readtrackingjoinparams, $flagparams, $conditionparams), $limitfrom, $limitnum);
     return $rs;
 }
コード例 #3
0
 /**
  * Display a post. This method is used for:
  * - The normal HTML display of a post
  * - HTML email of a post
  * - Text-only email of a post
  * These are all combined in one method since ordinarily they change at
  * the same time (i.e. if adding/hiding information it is usually added to
  * or hidden from all views).
  *
  * $options is an associative array from a mod_forumng_post::OPTION_xx constant.
  * All available options are always set - if they were not set by
  * the user, they will have been set to false before this call happens,
  * so there is no need to use empty() or isset().
  *
  * Options are as follows. These are available in email mode:
  *
  * OPTION_TIME_ZONE (int) - Moodle time zone
  * OPTION_VIEW_FULL_NAMES (bool) - If user is allowed to see full names
  * OPTION_EMAIL (bool) - True if this is an email (false = standard view)
  * OPTION_DIGEST (bool) - True if this is part of an email digest
  * OPTION_COMMAND_REPLY (bool) - True if 'Reply' link should be displayed
  *   (available in email too)
  *
  * These options only apply in non-email usage:
  *
  * OPTION_SUMMARY (bool) - True if the entire post should not be displayed,
  *   only a short summary
  * OPTION_NO_COMMANDS (bool) - True if this post is being printed on its own
  * OPTION_COMMAND_EDIT (bool) - Display 'Edit' command
  * OPTION_COMMAND_DELETE (bool) - Display 'Edit' command
  * OPTION_COMMAND_SPLIT (bool) - Display 'Split' command
  * OPTION_RATINGS_VIEW (bool) - True to display current ratings
  * OPTION_RATINGS_EDIT (bool) - True to display ratings edit combo
  * OPTION_LEAVE_DIV_OPEN (bool) - True to not close post div (means that
  *   child posts can be added within).
  * OPTION_EXPANDED (bool) - True to show full post, otherwise abbreviate
  * OPTION_DISCUSSION_SUBJECT (bool) - If true, and only IF post is a
  *   discussion root, includes subject (HTML, shortened as it would be for
  *   header display) as a hidden field.
  *
  * @param mod_forumng_post $post Post object
  * @param bool $html True if using HTML, false to output in plain text
  * @param array $options Associative array of name=>option, as above
  * @return string HTML or text of post
  */
 public function render_post($post, $html, $options)
 {
     global $CFG, $USER, $THEME, $OUTPUT;
     $discussion = $post->get_discussion();
     $expanded = $options[mod_forumng_post::OPTION_EXPANDED];
     $export = $options[mod_forumng_post::OPTION_EXPORT];
     $email = $options[mod_forumng_post::OPTION_EMAIL];
     // When posts are deleted we hide a lot of info - except when the person
     // viewing it has the ability to view deleted posts.
     $deletedhide = $post->get_deleted() && !$options[mod_forumng_post::OPTION_VIEW_DELETED_INFO];
     // Hide deleted messages if they have no replies
     if ($deletedhide && ($export || !$email) && !$post->has_children()) {
         // note: !email check is to deal with posts that are deleted
         // between when the mail list finds them, and when it sends out
         // mail. It would be confusing to send out a blank email so let's
         // not do that. Also, ->has_children() is not safe to call during
         // email processing because it doesn't load the whole discussion.
         return '';
     }
     // Save some bandwidth by not sending link full paths except in emails
     if ($options[mod_forumng_post::OPTION_FULL_ADDRESSES]) {
         $linkprefix = $CFG->wwwroot . '/mod/forumng/';
     } else {
         $linkprefix = '';
     }
     $postnumber = ($options[mod_forumng_post::OPTION_NO_COMMANDS] || $email) && !$options[mod_forumng_post::OPTION_VISIBLE_POST_NUMBERS] ? '' : $post->get_number();
     $lf = "\n";
     // Initialise result
     $out = '';
     if ($html) {
         if ($export) {
             $out .= '<hr />';
         }
         // Basic intro
         $classes = $expanded ? ' forumng-full' : ' forumng-short';
         $classes .= $post->is_important() ? ' forumng-important' : '';
         $classes .= !$email && !$options[mod_forumng_post::OPTION_UNREAD_NOT_HIGHLIGHTED] && $post->is_unread() ? ' forumng-unread' : ' forumng-read';
         $classes .= $post->get_deleted() ? ' forumng-deleted' : '';
         $classes .= ' forumng-p' . $postnumber;
         if ($options[mod_forumng_post::OPTION_INDICATE_MODERATOR] == true) {
             $classes .= ' forumng-imoderator';
         }
         $out .= $lf . '<div class="forumng-post' . $classes . '">' . '<div class="post-deco"><div class="post-deco-bar"></div></div><a id="p' . $post->get_id() . '"></a>';
         if ($options[mod_forumng_post::OPTION_FIRST_UNREAD]) {
             $out .= '<a id="firstunread"></a>';
         }
         // Theme hooks
         if (!empty($THEME->forumng_post_hooks)) {
             for ($i = 1; $i <= $THEME->forumng_post_hooks; $i++) {
                 $out .= '<div class="forumng-' . $i . '"></div>';
             }
         }
     }
     if ($html || $options[mod_forumng_post::OPTION_VISIBLE_POST_NUMBERS]) {
         // Accessible text giving post a number so we can make links unique
         // etc.
         if ($postnumber) {
             $data = new stdClass();
             $data->num = $postnumber;
             if ($post->get_parent()) {
                 if ($html) {
                     $data->parent = '<a class="forumng-parentlink" href="#p' . $post->get_parent()->get_id() . '">' . $post->get_parent()->get_number() . '</a>';
                 } else {
                     $data->parent = $post->get_parent()->get_number();
                 }
                 $data->info = '';
                 if ($post->is_unread()) {
                     $data->info = get_string('postinfo_unread', 'forumng');
                 }
                 if (!$expanded) {
                     $data->info .= ' ' . get_string('postinfo_short', 'forumng');
                 }
                 if ($post->get_deleted()) {
                     $data->info .= ' ' . get_string('postinfo_deleted', 'forumng');
                 }
                 $data->info = trim($data->info);
                 if ($data->info) {
                     $data->info = ' (' . $data->info . ')';
                 }
                 $info = get_string('postnumreply', 'forumng', $data);
             } else {
                 $info = get_string('postnum', 'forumng', $data);
             }
             if ($options[mod_forumng_post::OPTION_VISIBLE_POST_NUMBERS]) {
                 if (!$html) {
                     $out .= "## " . $info . "\n";
                 }
             }
         }
     }
     // Discussion subject (root only)
     if ($options[mod_forumng_post::OPTION_DISCUSSION_SUBJECT] && $post->is_root_post()) {
         $out .= '<input type="hidden" name="discussion_subject" value="' . shorten_text(htmlspecialchars($post->get_subject())) . '" />';
     }
     // Pictures (HTML version only)
     if ($html) {
         $out .= $lf . html_writer::start_tag('div', array('class' => 'forumng-pic-info'));
     }
     if ($html && !$export && $options[mod_forumng_post::OPTION_USER_IMAGE]) {
         $out .= $lf . html_writer::start_tag('div', array('class' => 'forumng-pic'));
         // User picture.
         if (!$options[mod_forumng_post::OPTION_IS_ANON]) {
             $out .= $deletedhide ? '' : $post->display_user_picture();
         } else {
             if ($options[mod_forumng_post::OPTION_VIEW_ANON_INFO]) {
                 $out .= $deletedhide ? '' : $post->display_user_picture();
             }
         }
         // Group pictures if any - only for expanded version
         if ($expanded) {
             $grouppics = $post->display_group_pictures();
             if ($grouppics) {
                 $out .= '<div class="forumng-grouppicss">' . $grouppics . '</div>';
             }
         }
         $out .= html_writer::end_tag('div');
     }
     // Link used to expand post
     $expandlink = '';
     if (!$expanded && !$deletedhide) {
         $expandlink = $this->render_expand_link($linkprefix, $discussion, $post);
     }
     // Byline
     $by = new stdClass();
     $by->name = $deletedhide ? '' : fullname($post->get_user(), $options[mod_forumng_post::OPTION_VIEW_FULL_NAMES]);
     $by->date = $deletedhide ? '' : userdate($post->get_created(), get_string('strftimedatetime', 'langconfig'), $options[mod_forumng_post::OPTION_TIME_ZONE]);
     if ($html) {
         $out .= $lf . '<div class="forumng-info"><h2 class="forumng-author">';
         $out .= $post->is_important() ? '<img src="' . $this->pix_url('exclamation_mark', 'mod_forumng') . '" alt="' . get_string('important', 'forumng') . '" ' . 'title = "' . get_string('important', 'forumng') . '"/>' : '';
         if ($export) {
             if (!$options[mod_forumng_post::OPTION_IS_ANON]) {
                 $out .= $by->name . ' ';
             }
         } else {
             if (!$options[mod_forumng_post::OPTION_IS_ANON]) {
                 $out .= '<a href="' . $CFG->wwwroot . '/user/view.php?id=' . $post->get_user()->id . ($post->get_forum()->is_shared() ? '' : '&amp;course=' . $post->get_forum()->get_course_id()) . '">' . $by->name . '</a>';
             }
         }
         if ($options[mod_forumng_post::OPTION_IS_ANON] || $options[mod_forumng_post::OPTION_INDICATE_MODERATOR]) {
             $moderator = get_string('moderator', 'forumng');
             $out .= html_writer::tag('div', get_string('moderator', 'forumng'), array('class' => 'forumng-moderator-flag'));
         }
         if ($postnumber) {
             if ($options[mod_forumng_post::OPTION_VISIBLE_POST_NUMBERS]) {
                 $out .= html_writer::tag('small', ' ' . $info, array('class' => 'accesshide', 'style' => 'position:static'));
             } else {
                 $out .= '<span class="accesshide"> ' . $info . ' </span>';
             }
         }
         $out .= $deletedhide ? '' : '</h2> <span class="forumng-separator">&#x2022;</span> ';
         $out .= '<span class="forumng-date">' . $by->date . '</span>';
         // Should not show editing user info, if poster is anonymous and
         // current user can�t view anonymous info .
         if ($options[mod_forumng_post::OPTION_IS_ANON] && $discussion->get_forum()->can_post_anonymously() || $options[mod_forumng_post::OPTION_INDICATE_MODERATOR] || !$options[mod_forumng_post::OPTION_IS_ANON] && !$email) {
             if ($edituser = $post->get_edit_user()) {
                 $out .= ' <span class="forumng-separator">&#x2022;</span> ' . '<span class="forumng-edit">';
                 $edit = new stdClass();
                 $edit->date = userdate($post->get_modified(), get_string('strftimedatetime', 'langconfig'), $options[mod_forumng_post::OPTION_TIME_ZONE]);
                 $edit->name = fullname($edituser, $options[mod_forumng_post::OPTION_VIEW_FULL_NAMES]);
                 if ($edituser->id == $post->get_user()->id) {
                     $out .= get_string('editbyself', 'forumng', $edit->date);
                 } else {
                     $out .= get_string('editbyother', 'forumng', $edit);
                 }
                 if ($options[mod_forumng_post::OPTION_COMMAND_HISTORY]) {
                     $out .= ' (<a href="history.php?' . $post->get_link_params(mod_forumng::PARAM_HTML) . '">' . get_string('history', 'forumng') . '</a>)';
                 }
                 $out .= '</span>';
             }
         }
         if ($options[mod_forumng_post::OPTION_SELECTABLE]) {
             $out .= '<span class="forumng-separator"> &#x2022; </span>' . '<input type="checkbox" name="selectp' . $post->get_id() . '" id="id_selectp' . $post->get_id() . '" /><label class="accesshide" for="id_selectp' . $post->get_id() . '">' . get_string('selectlabel', 'forumng', $postnumber) . '</label>';
         }
         // End: forumng-info.
         $out .= html_writer::end_tag('div');
         // End: forumng-pic-info.
         $out .= html_writer::end_tag('div');
     } else {
         require_once dirname(__FILE__) . '/mod_forumng_cron.php';
         $out .= $by->name . ' - ' . $by->date . $lf;
         $out .= mod_forumng_cron::EMAIL_DIVIDER;
     }
     // Add a outer div to main contents
     if ($html) {
         $out .= '<div class="forumng-post-outerbox">';
     }
     if ($html && $post->get_deleted()) {
         $out .= '<p class="forumng-deleted-info"><strong>' . get_string('deletedpost', 'forumng') . '</strong> ';
         if ($deletedhide) {
             $out .= get_string($post->get_delete_user()->id == $post->get_user()->id ? 'deletedbyauthor' : 'deletedbymoderator', 'forumng', userdate($post->get_deleted()));
         } else {
             $a = new stdClass();
             $a->date = userdate($post->get_deleted());
             $a->user = '******' . $CFG->wwwroot . '/user/view.php?id=' . $post->get_delete_user()->id . '&amp;course=' . $post->get_forum()->get_course_id() . '">' . fullname($post->get_delete_user(), $options[mod_forumng_post::OPTION_VIEW_FULL_NAMES]) . '</a>';
             $out .= get_string('deletedbyuser', 'forumng', $a);
         }
         $out .= '</p>';
     }
     if ($options[mod_forumng_post::OPTION_IS_ANON] && $options[mod_forumng_post::OPTION_VIEW_ANON_INFO] && !$email) {
         $a = html_writer::link(new moodle_url('/user/view.php', array('id' => $post->get_user()->id, 'course' => $post->get_forum()->get_course_id())), fullname($post->get_user(), $options[mod_forumng_post::OPTION_VIEW_FULL_NAMES]));
         $out .= get_string('createdbymoderator', 'forumng', $a);
     }
     // Get subject. This may make a db query when showing a single post
     // (which includes parent subject).
     if ($options[mod_forumng_post::OPTION_EMAIL] || $options[mod_forumng_post::OPTION_NO_COMMANDS]) {
         $subject = $post->get_effective_subject(true);
     } else {
         $subject = $post->get_subject();
     }
     // Otherwise, subject is only displayed if it has changed
     if ($subject !== null && $expanded && !$deletedhide) {
         if ($html) {
             $out .= $lf . '<h3 class="forumng-subject">';
             if ($options[mod_forumng_post::OPTION_DIGEST]) {
                 // Digest contains link to original post
                 $out .= '<a href="' . $linkprefix . 'discuss.php?' . $discussion->get_link_params(mod_forumng::PARAM_HTML) . '#p' . $post->get_id() . '">' . format_string($subject) . '</a>';
             } else {
                 $out .= format_string($subject);
             }
             $out .= '</h3>';
         } else {
             $out .= format_string($subject, true);
             if ($options[mod_forumng_post::OPTION_DIGEST]) {
                 // Link to original post
                 $out .= " <{$linkprefix}discuss.php?" . $discussion->get_link_params(mod_forumng::PARAM_HTML) . $discussion->get_id() . '#p' . $post->get_id() . '>';
             }
             $out .= $lf;
         }
     }
     // Get content of actual message in HTML
     if ($html) {
         $message = $post->get_formatted_message();
         if (!$expanded && !$deletedhide) {
             // When not expanded and no subject, we include a summary of the
             // message
             $stripped = strip_tags(preg_replace('~<script.*?</script>~s', '', $message));
             $messagetosummarise = $subject !== null ? '<h3>' . $subject . '</h3>&nbsp;' . $stripped : $stripped;
             $summary = self::nice_shorten_text($messagetosummarise, 50);
             $out .= $lf . '<div class="forumng-summary"><div class="forumng-text">' . $summary . '</div> ' . $expandlink . '</div>';
         }
     }
     // Start of post main section
     if ($expanded && !$deletedhide) {
         if ($html) {
             $out .= '<div class="forumng-postmain">';
         }
         // Attachments
         $attachments = $post->get_attachment_names();
         if (count($attachments)) {
             if ($html) {
                 $out .= $lf;
                 if (count($attachments) == 1) {
                     $attachmentlabel = get_string('attachment', 'forumng');
                 } else {
                     $attachmentlabel = get_string('attachments', 'forumng');
                 }
                 $out .= '<span class="accesshide">' . $attachmentlabel . '</span><ul class="forumng-attachments">';
             }
             foreach ($attachments as $attachment) {
                 if ($html) {
                     require_once $CFG->libdir . '/filelib.php';
                     $iconsrc = $this->pix_url('/f/' . mimeinfo('icon', $attachment));
                     $alt = get_mimetype_description(mimeinfo('type', $attachment));
                     $out .= '<li><a href="' . $post->get_attachment_url($attachment) . '">' . '<img src="' . $iconsrc . '" alt="' . $alt . '" /> <span>' . htmlspecialchars($attachment) . '</span></a> </li>';
                 } else {
                     // Right-align the entry to 70 characters
                     $padding = 70 - strlen($attachment);
                     if ($padding > 0) {
                         $out .= str_repeat(' ', $padding);
                     }
                     // Add filename
                     $out .= $attachment . $lf;
                 }
             }
             if ($html) {
                 $out .= '</ul>' . $lf;
             } else {
                 $out .= $lf;
                 // Extra line break after attachments
             }
         }
         // Display actual content
         if ($html) {
             if ($options[mod_forumng_post::OPTION_PRINTABLE_VERSION]) {
                 $message = preg_replace('~<a[^>]*\\shref\\s*=\\s*[\'"](http:.*?)[\'"][^>]*>' . '(?!(http:|www\\.)).*?</a>~', "\$0 [\$1]", $message);
             }
             $out .= $lf . '<div class="forumng-message">' . $message . '</div>';
         } else {
             $out .= $post->get_email_message();
             $out .= "\n\n";
         }
         if ($html) {
             $out .= $lf . '<div class="clear forumng-postfooter">';
         }
         // Ratings.
         $ratings = '';
         $ratingclasses = '';
         if ($options[mod_forumng_post::OPTION_RATINGS_VIEW]) {
             $ratingclasses .= ' forumng-canview';
             if ($post->get_num_ratings() >= $post->get_forum()->get_rating_threshold()) {
                 if ($html) {
                     $ratings .= '<div class="forumng-rating">';
                     $a = new stdClass();
                     $a->avg = '<strong id="rating_for_' . $post->get_id() . '">' . $post->get_average_rating(true) . '</strong>';
                     $a->num = '<span class="forumng-count">' . $post->get_num_ratings() . '</span>';
                     $ratings .= get_string('averagerating', 'forumng', $a);
                     $ratings .= '</div>';
                 } else {
                     $ratings .= strip_tags($post->get_average_rating(true));
                 }
             }
         }
         if ($options[mod_forumng_post::OPTION_RATINGS_EDIT] && $html) {
             $ratingclasses .= ' forumng-canedit';
             $ratings .= '<div class="forumng-editrating">' . get_string('yourrating', 'forumng') . ' ';
             $ratings .= html_writer::select($post->get_forum()->get_rating_options(), 'rating' . $post->get_id(), $post->get_own_rating(), array(mod_forumng_post::NO_RATING => '-'));
             $ratings .= '</div>';
         }
         if ($post->get_forum()->get_enableratings() == mod_forumng::FORUMNG_STANDARD_RATING && $post->get_ratings()) {
             $out .= html_writer::div($OUTPUT->render($post->get_ratings()), 'forumng-ratings-standard');
         } else {
             if ($ratings) {
                 $out .= '<div class="forumng-ratings' . $ratingclasses . '">' . $ratings . '</div>';
             }
         }
         // Commands at bottom of mail
         $mobileclass = '';
         if ($html) {
             $commandsarray = array();
             $expires = $post->can_ignore_edit_time_limit() ? '' : '&amp;expires=' . ($post->get_edit_time_limit() - time());
             $expandparam = !empty($options[mod_forumng_post::OPTION_CHILDREN_EXPANDED]) ? '&amp;expand=1' : '';
             // Jump box
             if ($options[mod_forumng_post::OPTION_JUMP_PREVIOUS] || $options[mod_forumng_post::OPTION_JUMP_NEXT] || $options[mod_forumng_post::OPTION_JUMP_PARENT]) {
                 $nextid = $options[mod_forumng_post::OPTION_JUMP_NEXT];
                 $pid = $options[mod_forumng_post::OPTION_JUMP_PREVIOUS];
                 $parentid = $options[mod_forumng_post::OPTION_JUMP_PARENT];
                 if ($jumptotext = $this->render_commands_jumpto($nextid, $pid, $parentid)) {
                     $thiscommand = '<span class="forumng-jumpto-label">' . get_string('jumpto', 'forumng') . '</span>' . $jumptotext;
                     $commandsarray['forumng-jumpto'] = $thiscommand;
                 }
             }
             // Mark post read.
             if ($CFG->forumng_trackreadposts && !isguestuser() && $post->is_unread() && !mod_forumng::mark_read_automatically()) {
                 $commandsarray['forumng-markread'] = html_writer::link(new moodle_url('/mod/forumng/markread.php', array('p' => $post->get_id())), get_string('markpostread', 'forumng'));
             }
             // Flag link.
             if ($options[mod_forumng_post::OPTION_FLAG_CONTROL]) {
                 $flagurl = new moodle_url('flagpost.php?', array('p' => $post->get_id(), 'timeread' => $options[mod_forumng_post::OPTION_READ_TIME], 'flag' => $post->is_flagged() ? 0 : 1));
                 $icon = "flag." . ($post->is_flagged() ? 'on' : 'off');
                 $iconalt = get_string($post->is_flagged() ? 'clearflag' : 'setflag', 'forumng');
                 $bnstr = get_string($post->is_flagged() ? 'clearflag' : 'flagpost', 'forumng');
                 $iconhtml = $OUTPUT->pix_icon($icon, '', 'forumng');
                 $iconhtml .= html_writer::span($bnstr, 'flagtext');
                 $link = html_writer::link($flagurl, $iconhtml, array('title' => $iconalt));
                 $commandsarray['forumng-flagpost'] = html_writer::div($link, 'forumng-flagpost');
             }
             // Direct link.
             if ($options[mod_forumng_post::OPTION_COMMAND_DIRECTLINK]) {
                 $commandsarray['forumng-permalink'] = '<a href="discuss.php?' . $discussion->get_link_params(mod_forumng::PARAM_HTML) . '#p' . $post->get_id() . '" title="' . get_string('directlinktitle', 'forumng') . '">' . get_string('directlink', 'forumng', $postnumber) . '</a>';
             }
             // Alert link.
             $forum = $discussion->get_forum();
             if ($options[mod_forumng_post::OPTION_COMMAND_REPORT] && !($options[mod_forumng_post::OPTION_IS_ANON] || $options[mod_forumng_post::OPTION_INDICATE_MODERATOR])) {
                 $reportabuselink = '';
                 if ($forum->oualerts_enabled()) {
                     $itmurl = $CFG->wwwroot . '/mod/forumng/discuss.php';
                     $itmurl .= '?' . $discussion->get_link_params(mod_forumng::PARAM_PLAIN);
                     $itemurl = $itmurl . '#p' . $post->get_id();
                     $context = $post->get_forum()->get_context(false);
                     $reportabuselink = oualerts_generate_alert_form_url('forumng', $context->id, 'post', $post->get_id(), $itemurl, $itemurl, $USER->id, false, true);
                 } else {
                     $reportabuselink = $linkprefix . 'alert.php?' . $post->get_link_params(mod_forumng::PARAM_HTML) . $expandparam;
                 }
                 $commandsarray['forumng-alert'] = '<a href="' . $reportabuselink . '" title="' . get_string('alert_linktitle', 'forumng') . '">' . get_string('alert_link', 'forumng', $postnumber) . '</a>';
             }
             // Split link
             if ($options[mod_forumng_post::OPTION_COMMAND_SPLIT]) {
                 $commandsarray['forumng-split'] = '<a href="' . $linkprefix . 'splitpost.php?' . $post->get_link_params(mod_forumng::PARAM_HTML) . $expandparam . '">' . get_string('split', 'forumng', $postnumber) . '</a>';
             }
             // Delete link
             if ($options[mod_forumng_post::OPTION_COMMAND_DELETE]) {
                 $commandsarray['forumng-delete'] = '<a' . $mobileclass . ' href="' . $linkprefix . 'deletepost.php?' . $post->get_link_params(mod_forumng::PARAM_HTML, true) . $expandparam . $expires . '">' . get_string('delete', 'forumng', $postnumber) . '</a>';
             }
             // Undelete link
             if ($options[mod_forumng_post::OPTION_COMMAND_UNDELETE]) {
                 $commandsarray['forumng-undelete'] = '<a href="' . $linkprefix . 'deletepost.php?' . $post->get_link_params(mod_forumng::PARAM_HTML) . $expandparam . '&amp;delete=0">' . get_string('undelete', 'forumng', $postnumber) . '</a>';
             }
             // Edit link
             if ($options[mod_forumng_post::OPTION_COMMAND_EDIT]) {
                 $commandsarray['forumng-edit'] = '<a' . $mobileclass . ' href="' . $linkprefix . 'editpost.php?' . $post->get_link_params(mod_forumng::PARAM_HTML) . $expandparam . $expires . '">' . get_string('edit', 'forumng', $postnumber) . '</a>';
             }
             // Reply link
             if ($options[mod_forumng_post::OPTION_COMMAND_REPLY]) {
                 $commandsarray['forumng-replylink'] = '<a' . $mobileclass . ' href="' . $linkprefix . 'editpost.php?replyto=' . $post->get_id() . $post->get_forum()->get_clone_param(mod_forumng::PARAM_HTML) . $expandparam . '">' . get_string('reply', 'forumng', $postnumber) . '</a>';
             }
             if (count($commandsarray)) {
                 $out .= $lf . $this->render_commands($commandsarray);
             }
         } else {
             // Reply link
             if ($options[mod_forumng_post::OPTION_COMMAND_REPLY]) {
                 $out .= mod_forumng_cron::EMAIL_DIVIDER;
                 if ($options[mod_forumng_post::OPTION_EMAIL]) {
                     $course = $post->get_forum()->get_course();
                     $out .= get_string("postmailinfo", "forumng", $course->shortname) . $lf;
                 }
                 $out .= "{$linkprefix}editpost.php?replyto=" . $post->get_id() . $post->get_forum()->get_clone_param(mod_forumng::PARAM_PLAIN) . $lf;
             }
             // Only the reply command is available in text mode
         }
         // End: forumng-postfooter and forumng-postmain.
         if ($html) {
             $out .= html_writer::end_tag('div') . html_writer::end_tag('div');
         }
     }
     // End of post div
     if ($html) {
         // Useful empty div at end of post.
         $out .= html_writer::tag('div', '', array('class' => 'forumng-endpost'));
         // End: forumng-post-outerbox.
         $out .= html_writer::end_tag('div');
         // Export has a couple blank lines after post (but within div, for validity).
         if ($export) {
             $out .= '<br /><br />';
         }
         // End: forumng-post.
         $out .= html_writer::end_tag('div');
     }
     return $out;
 }
コード例 #4
0
 /**
  * Displays the discussion page.
  * @param mod_forumng_discussion $discussion Discussion
  */
 public function print_discussion_page($discussion)
 {
     global $PAGE;
     $out = mod_forumng_utils::get_renderer();
     $previousread = (int) $discussion->get_time_read();
     // 'Read date' option (used when viewing all posts so that they keep
     // their read/unread colouring)
     $timeread = optional_param('timeread', 0, PARAM_INT);
     if ($timeread) {
         $discussion->pretend_time_read($timeread);
         $previousread = $timeread;
     }
     // 'Expand all' option (always chosen for non-JS browsers)
     $expandall = optional_param('expand', 0, PARAM_INT) || $PAGE->devicetypeinuse == 'legacy';
     // 'Expand all' option (always chosen for non-JS browsers)
     $collapseall = optional_param('collapse', 0, PARAM_INT);
     if (!$collapseall && !$expandall && $PAGE->devicetypeinuse == 'mobile') {
         $collapseall = 1;
     }
     // Link back to first unread post if there is one
     print $discussion->display_unread_skip_link();
     // Magic expand tracker (for use in JS only, never set server-side).
     // This tracks expanded posts, and makes the Back button 'work' in
     // the sense that it will expand these posts again.
     print '<form method="post" action="."><div>' . '<input type="hidden" id="expanded_posts" name="expanded_posts" ' . 'value="" /></div></form>';
     // Get content for all posts in the discussion
     $options = array();
     if ($expandall) {
         $options[mod_forumng_post::OPTION_CHILDREN_EXPANDED] = true;
     }
     if ($collapseall) {
         $options[mod_forumng_post::OPTION_CHILDREN_COLLAPSED] = true;
     }
     $content = $out->render_discussion($discussion, $options);
     // Some post display options use the read time to construct links
     // (usually for non-JS version) so that unread state is maintained.
     $options[mod_forumng_post::OPTION_READ_TIME] = $previousread;
     // Display expand all option if there are any 'Expand' links in content
     $fakedate = '&amp;timeread=' . $previousread;
     print '<div id="forumng-expandall">';
     $showexpandall = preg_match('~<a [^>]*href="discuss\\.php\\?d=[0-9]+[^"]*&amp;expand=1#p[0-9]+">~', $content);
     // Note: On bad browsers we always expand all posts
     $showcollapseall = preg_match('~<div class="forumng-post forumng-full.*<div class="forumng-post forumng-full~s', $content) && $PAGE->devicetypeinuse != 'legacy';
     if ($showexpandall) {
         print '<a class="forumng-expandall-link" href="' . $discussion->get_url(mod_forumng::PARAM_HTML) . '&amp;expand=1' . $fakedate . '">' . get_string('expandall', 'forumng') . '</a>';
         if ($showcollapseall) {
             print '<span class="forumng-dot-separator"> &#x2022; </span>';
         }
     }
     if ($showcollapseall) {
         print '<a class="forumng-collapseall-link" href="' . $discussion->get_url(mod_forumng::PARAM_HTML) . '&amp;collapse=1' . $fakedate . '">' . get_string('collapseall', 'forumng') . '</a> ';
     }
     print '</div>';
     // Display content
     print $content;
     // Link back to forum
     print $discussion->display_link_back_to_forum();
     // Display discussion features (row of buttons)
     print $discussion->display_forumngfeature_discussions();
     // Display the subscription options to this disucssion if available
     print $discussion->display_subscribe_options();
     // Atom/RSS links
     print $discussion->display_feed_links();
     // Set read data [shouldn't this logic be somewhere else as it is not
     // part of display?]
     if (mod_forumng::mark_read_automatically()) {
         $discussion->mark_read();
     }
 }
コード例 #5
0
 /**
  * Internal method. Queries for a number of forums, including additional
  * data about unread posts etc. Returns the database result.
  * @param array $cmids If specified, array of course-module IDs of desired
  *   forums
  * @param object $course If specified, course object
  * @param int $userid User ID, 0 = current user
  * @param int $unread Type of unread data to obtain (UNREAD_xx constant).
  * @param array $groups Array of group IDs to which the given user belongs
  *   (may be null if unread data not required)
  * @param array $aagforums Array of forums in which the user has
  *   'access all groups' (may be null if unread data not required)
  * @param array $viewhiddenforums Array of forums in which the user has
  *   'view hidden discussions' (may be null if unread data not required)
  * @return array Array of row objects
  */
 private static function query_forums($cmids = array(), $course = null, $userid, $unread, $groups, $aagforums, $viewhiddenforums)
 {
     global $DB, $CFG, $USER;
     if (!count($cmids) && !$course) {
         throw new coding_exception("mod_forumng::query_forums requires course id or cmids");
     }
     if (count($cmids)) {
         list($in, $conditionsparams) = mod_forumng_utils::get_in_array_sql('cm.id', $cmids);
         $conditions = $in;
     } else {
         $conditions = "f.course = ?";
         $conditionsparams = array($course->id);
     }
     $singleforum = count($cmids) == 1 ? reset($cmids) : false;
     list($inviewhiddenforums, $inviewhiddenforumsparams) = mod_forumng_utils::get_in_array_sql('fd.forumngid', $viewhiddenforums);
     list($cfdinviewhiddenforums, $inviewhiddenforumsparams) = mod_forumng_utils::get_in_array_sql('cfd.forumngid', $viewhiddenforums);
     // This array of additional results is used later if combining
     // standard results with single-forum calls.
     $plusresult = array();
     // For read tracking, we get a count of total number of posts in
     // forum, and total number of read posts in the forum (this
     // is so we can display the number of UNread posts, but the query
     // works that way around because it will return 0 if no read
     // information is stored).
     if ($unread != self::UNREAD_NONE && self::enabled_read_tracking()) {
         // Work out when unread status ends
         $endtime = time() - $CFG->forumng_readafterdays * 24 * 3600;
         if (!$userid) {
             $userid = $USER->id;
         }
         list($ingroups, $ingroupsparams) = mod_forumng_utils::get_in_array_sql('fd.groupid', $groups);
         list($inaagforums, $inaagforumsparams) = mod_forumng_utils::get_in_array_sql('fd.forumngid', $aagforums);
         $restrictionsql = '';
         $restrictionparams = array();
         if ($singleforum) {
             // If it is for a single forum, get the restriction from the
             // forum type
             $forum = self::get_from_cmid($singleforum, self::CLONE_DIRECT);
             $type = $forum->get_type();
             if ($type->has_unread_restriction()) {
                 list($value, $restrictionparams) = $type->get_unread_restriction_sql($forum);
                 if ($value) {
                     $restrictionsql = 'AND ' . $value;
                 }
             }
         } else {
             // When it is not for a single forum, we can only group together
             // results for types that do not place restrictions on the
             // unread count.
             $modinfo = get_fast_modinfo($course);
             $okayids = array();
             if (array_key_exists('forumng', $modinfo->instances)) {
                 foreach ($modinfo->instances['forumng'] as $info) {
                     if (count($cmids) && !in_array($info->id, $cmids)) {
                         continue;
                     }
                     $type = self::get_type_from_modinfo_info($info);
                     if (forumngtype::get_new($type)->has_unread_restriction()) {
                         // This one's a problem! Do it individually
                         $problemresults = self::query_forums(array($info->id), null, $userid, $unread, $groups, $aagforums, $viewhiddenforums);
                         foreach ($problemresults as $problemresult) {
                             $plusresult[$problemresult->f_id] = $problemresult;
                         }
                     } else {
                         $okayids[] = $info->id;
                     }
                 }
             }
             if (count($okayids) == 0) {
                 // There are no 'normal' forums, so return result so far
                 // after sorting it
                 uasort($plusresult, 'mod_forumng::sort_mod_forumng_result');
                 return $plusresult;
             } else {
                 // Fall through to normal calculation, but change conditions
                 // to include only the 'normal' forums
                 list($in, $inparams) = mod_forumng_utils::get_in_array_sql('cm.id', $okayids);
                 $conditions .= " AND " . $in;
                 $conditionsparams = array_merge($conditionsparams, $inparams);
             }
         }
         $indreadpart = '';
         $indreadparms = array();
         $indreadwhere = '';
         // Get individual posts unread if manual read marking (on unread discussions only).
         if (!mod_forumng::mark_read_automatically($userid)) {
             $indreadpart = "INNER JOIN {forumng_posts} fp ON fp.discussionid = discussions.id\n                                 LEFT JOIN {forumng_read_posts} frp ON frp.postid = fp.id AND frp.userid = ?";
             $indreadwhere = "AND frp.id IS NULL\n                                 AND ((fp.edituserid IS NOT NULL AND fp.edituserid <> ?)\n                                       OR (fp.edituserid IS NULL AND fp.userid <> ?))\n                                 AND fp.deleted = ?\n                                 AND fp.oldversion = ?\n                                 AND fp.modified > ?\n                                 AND (discussions.time IS NULL OR fp.modified > discussions.time)";
             $indreadparms = array($userid, $userid, $userid, 0, 0, $endtime);
         }
         // NOTE fpfirst is used only by forum types, not here
         $now = time();
         $sharedquerypart = "\n        FROM\n     (SELECT fd.id, fr.time, fd.forumngid\n        FROM {forumng_discussions} fd\n  INNER JOIN {forumng_posts} fplast ON fd.lastpostid = fplast.id\n  INNER JOIN {forumng_posts} fpfirst ON fd.postid = fpfirst.id\n   LEFT JOIN {forumng_read} fr ON fd.id = fr.discussionid AND fr.userid = ?\n  INNER JOIN {course_modules} cm2 ON cm2.instance = fd.forumngid\n             AND cm2.module = (SELECT id FROM {modules} WHERE name = 'forumng')\n       WHERE fplast.modified > ?\n         AND (\n             (fd.groupid IS NULL)\n             OR ({$ingroups})\n             OR cm2.groupmode = " . VISIBLEGROUPS . "\n             OR ({$inaagforums})\n         )\n         AND fd.deleted = 0\n         AND (\n             ((fd.timestart = 0 OR fd.timestart <= ?)\n             AND (fd.timeend = 0 OR fd.timeend > ? OR ({$inviewhiddenforums})))\n         )\n         AND ((fplast.edituserid IS NOT NULL AND fplast.edituserid <> ?)\n          OR fplast.userid <> ?)\n         AND (fr.time IS NULL OR fplast.modified > fr.time)\n    {$restrictionsql}\n    ) discussions\n    {$indreadpart}\n       WHERE discussions.forumngid = f.id\n    {$indreadwhere}";
         $sharedqueryparams = array_merge(array($userid, $endtime), $ingroupsparams, $inaagforumsparams, array($now, $now), $inviewhiddenforumsparams, array($userid, $userid), $restrictionparams, $indreadparms);
         // Note: There is an unusual case in which this number can
         // be inaccurate. It is to do with ignoring messages the user
         // posted. We consider a discussion as 'not unread' if the last
         // message is by current user. In actual fact, a discussion could
         // contain unread messages if messages were posted by other users
         // after this user viewed the forum last, but before they posted
         // their reply. Since this should be an infrequent occurrence I
         // believe this behaviour is acceptable.
         if ($unread == self::UNREAD_BINARY) {
             // Query to get 0/1 unread discussions count
             $readtracking = self::select_exists("SELECT 1 {$sharedquerypart}") . "AS f_hasunreaddiscussions";
             $readtrackingparams = $sharedqueryparams;
         } else {
             // Query to get full unread discussions count
             $readtracking = "\n(SELECT\n    COUNT(DISTINCT discussions.id)\n{$sharedquerypart}\n) AS f_numunreaddiscussions";
             $readtrackingparams = $sharedqueryparams;
         }
     } else {
         $readtracking = "NULL AS numreadposts, NULL AS timeread";
         $readtrackingparams = array();
     }
     $now = time();
     $orderby = "LOWER(f.name)";
     // Main query. This retrieves:
     // - Full forum fields
     // - Basic course-module and course data (not whole tables)
     // - Discussion count
     // - Unread data, if enabled
     // - User subscription data
     $result = $DB->get_records_sql($sql = "\nSELECT\n    " . mod_forumng_utils::select_mod_forumng_fields('f') . ",\n    " . mod_forumng_utils::select_course_module_fields('cm') . ",\n    " . mod_forumng_utils::select_course_fields('c') . ",\n    (SELECT COUNT(1)\n        FROM {forumng_discussions} cfd\n        WHERE cfd.forumngid = f.id AND cfd.deleted = 0\n        AND (\n            ((cfd.timestart = 0 OR cfd.timestart <= ?)\n            AND (cfd.timeend = 0 OR cfd.timeend > ?))\n            OR ({$cfdinviewhiddenforums})\n        )\n        ) AS f_numdiscussions,\n    {$readtracking}\nFROM\n    {forumng} f\n    INNER JOIN {course_modules} cm ON cm.instance = f.id\n        AND cm.module = (SELECT id from {modules} WHERE name = 'forumng')\n    INNER JOIN {course} c ON c.id = f.course\nWHERE\n    {$conditions}\nORDER BY\n    {$orderby}", array_merge(array($now, $now), $inviewhiddenforumsparams, $readtrackingparams, $conditionsparams));
     if (count($plusresult) > 0) {
         foreach ($plusresult as $key => $value) {
             $result[$key] = $value;
         }
         uasort($result, 'mod_forumng::sort_mod_forumng_result');
     }
     return $result;
 }
コード例 #6
0
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
/**
 * Script called when you change the value of manual-mark option.
 * @package forumngfeature
 * @subpackage manualmark
 * @copyright 2011 The Open University
 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
 */
require_once '../../../../config.php';
require_once '../../mod_forumng.php';
// This script toggles the user's 'automatically mark read' preference.
$id = required_param('id', PARAM_INT);
$cloneid = optional_param('clone', 0, PARAM_INT);
$forum = mod_forumng::get_from_cmid($id, $cloneid);
$groupid = mod_forumng::get_activity_group($forum->get_course_module(), false);
$forum->require_view($groupid);
$manualmark = !mod_forumng::mark_read_automatically();
if ($manualmark) {
    unset_user_preference('forumng_manualmark');
} else {
    set_user_preference('forumng_manualmark', 1);
}
redirect($forum->get_url(mod_forumng::PARAM_PLAIN));
 public function should_display($discussion)
 {
     return !mod_forumng::mark_read_automatically() && $discussion->get_forum()->can_mark_read() && $discussion->get_num_unread_posts();
 }