dirroot/files/mimetypes.php"); /// CONSTANTS /////////////////////////////////////////////////////////// define("FORUM_MODE_FLATOLDEST", 1); define("FORUM_MODE_FLATNEWEST", -1); define("FORUM_MODE_THREADED", 2); define("FORUM_MODE_NESTED", 3); $FORUM_LAYOUT_MODES = array ( FORUM_MODE_FLATOLDEST => get_string("modeflatoldestfirst", "forum"), FORUM_MODE_FLATNEWEST => get_string("modeflatnewestfirst", "forum"), FORUM_MODE_THREADED => get_string("modethreaded", "forum"), FORUM_MODE_NESTED => get_string("modenested", "forum") ); // These are course content forums that can be added to the course manually $FORUM_TYPES = array ("general" => get_string("generalforum", "forum"), "eachuser" => get_string("eachuserforum", "forum"), "single" => get_string("singleforum", "forum") ); $FORUM_OPEN_MODES = array ("2" => get_string("openmode2", "forum"), "1" => get_string("openmode1", "forum"), "0" => get_string("openmode0", "forum") ); if (!isset($CFG->forum_displaymode)) { set_config("forum_displaymode", FORUM_MODE_NESTED); } if (!isset($CFG->forum_shortpost)) { set_config("forum_shortpost", 300); // Less non-HTML characters than this is short } if (!isset($CFG->forum_longpost)) { set_config("forum_longpost", 600); // More non-HTML characters than this is long } if (!isset($CFG->forum_manydiscussions)) { set_config("forum_manydiscussions", 100); // Number of discussions on a page } if (!isset($CFG->forum_maxbytes)) { set_config("forum_maxbytes", 512000); // Default maximum size for all forums } /// STANDARD FUNCTIONS /////////////////////////////////////////////////////////// function forum_add_instance($forum) { // Given an object containing all the necessary data, // (defined by the form in mod.html) this function // will create a new instance and return the id number // of the new instance. global $CFG; $forum->timemodified = time(); if (! $forum->id = insert_record("forum", $forum)) { return false; } if (!$forum->userating) { $forum->assessed = 0; } if (!empty($forum->ratingtime)) { $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday, $forum->starthour, $forum->startminute, 0); $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday, $forum->finishhour, $forum->finishminute, 0); } else { $forum->assesstimestart = 0; $forum->assesstimefinish = 0; } if ($forum->type == "single") { // Create related discussion. $discussion->course = $forum->course; $discussion->forum = $forum->id; $discussion->name = $forum->name; $discussion->intro = $forum->intro; $discussion->assessed = $forum->assessed; if (! forum_add_discussion($discussion)) { error("Could not add the discussion for this forum"); } } return $forum->id; } function forum_update_instance($forum) { // Given an object containing all the necessary data, // (defined by the form in mod.html) this function // will update an existing instance with new data. $forum->timemodified = time(); $forum->id = $forum->instance; if (!$forum->userating) { $forum->assessed = 0; } if (!empty($forum->ratingtime)) { $forum->assesstimestart = make_timestamp($forum->startyear, $forum->startmonth, $forum->startday, $forum->starthour, $forum->startminute, 0); $forum->assesstimefinish = make_timestamp($forum->finishyear, $forum->finishmonth, $forum->finishday, $forum->finishhour, $forum->finishminute, 0); } else { $forum->assesstimestart = 0; $forum->assesstimefinish = 0; } if ($forum->type == "single") { // Update related discussion and post. if (! $discussion = get_record("forum_discussions", "forum", $forum->id)) { if ($discussions = get_records("forum_discussions", "forum", $forum->id, "timemodified ASC")) { notify("Warning! There is more than one discussion in this forum - using the most recent"); $discussion = array_pop($discussions); } else { error("Could not find the discussion in this forum"); } } if (! $post = get_record("forum_posts", "id", $discussion->firstpost)) { error("Could not find the first post in this forum discussion"); } $post->subject = $forum->name; $post->message = $forum->intro; $post->modified = $forum->timemodified; if (! update_record("forum_posts", $post)) { error("Could not update the first post"); } $discussion->name = $forum->name; if (! update_record("forum_discussions", $discussion)) { error("Could not update the discussion"); } } return update_record("forum", $forum); } function forum_delete_instance($id) { // Given an ID of an instance of this module, // this function will permanently delete the instance // and any data that depends on it. if (! $forum = get_record("forum", "id", "$id")) { return false; } $result = true; if ($discussions = get_records("forum_discussions", "forum", $forum->id)) { foreach ($discussions as $discussion) { if (! forum_delete_discussion($discussion)) { $result = false; } } } if (! delete_records("forum_subscriptions", "forum", "$forum->id")) { $result = false; } if (! delete_records("forum", "id", "$forum->id")) { $result = false; } return $result; } function forum_cron () { /// Function to be run periodically according to the moodle cron /// Finds all posts that have yet to be mailed out, and mails them /// out to all subscribers global $CFG, $USER; if (!empty($USER)) { // Remember real USER account if necessary $realuser = $USER; } $cutofftime = time() - $CFG->maxeditingtime; if ($posts = forum_get_unmailed_posts($cutofftime)) { /// Mark them all now as being mailed. It's unlikely but possible there /// might be an error later so that a post is NOT actually mailed out, /// but since mail isn't crucial, we can accept this risk. Doing it now /// prevents the risk of duplicated mails, which is a worse problem. foreach ($posts as $key => $post) { if (! set_field("forum_posts", "mailed", "1", "id", "$post->id")) { echo "Error marking post id post->id as being mailed. This post will not be mailed.\n"; unset($posts[$key]); } } $timenow = time(); foreach ($posts as $post) { echo "\n"; print_string("processingpost", "forum", $post->id); echo "\n"; if (! $userfrom = get_record("user", "id", "$post->userid")) { echo "Could not find user $post->userid\n"; continue; } if (! $discussion = get_record("forum_discussions", "id", "$post->discussion")) { echo "Could not find discussion $post->discussion\n"; continue; } if (! $forum = get_record("forum", "id", "$discussion->forum")) { echo "Could not find forum $discussion->forum\n"; continue; } if (! $course = get_record("course", "id", "$forum->course")) { echo "Could not find course $forum->course\n"; continue; } if (!empty($course->lang)) { $CFG->courselang = $course->lang; } else { unset($CFG->courselang); } $groupmode = false; if ($cm = get_coursemodule_from_instance("forum", $forum->id, $course->id)) { if ($groupmode = groupmode($course, $cm)) { // Groups are being used if (!$group = get_record("groups", "id", $discussion->groupid)) { // Can't find group continue; // Be safe and don't send it to anyone } } } else { $cm->id = 0; } if ($users = forum_subscribed_users($course, $forum)) { $canunsubscribe = ! forum_is_forcesubscribed($forum->id); $mailcount=0; $errorcount=0; foreach ($users as $userto) { if ($groupmode) { // Look for a reason not to send this email if (!isteacheredit($course->id, $userto->id)) { if (!ismember($group->id, $userto->id)) { continue; } } } /// GWD: reset timelimit so that script does not get timed out when posting to many users set_time_limit(10); /// Override the language and timezone of the "current" user, so that /// mail is customised for the receiver. $USER->lang = $userto->lang; $USER->timezone = $userto->timezone; $canreply = forum_user_can_post($forum, $userto); $by->name = fullname($userfrom, isteacher($course->id, $userto->id)); $by->date = userdate($post->modified, "", $userto->timezone); $strbynameondate = get_string("bynameondate", "forum", $by); $strforums = get_string("forums", "forum"); $postsubject = "$course->shortname: $post->subject"; $posttext = "$course->shortname -> $strforums -> $forum->name"; if ($discussion->name == $forum->name) { $posttext .= "\n"; } else { $posttext .= " -> $discussion->name\n"; } $posttext .= "---------------------------------------------------------------------\n"; $posttext .= "$post->subject\n"; $posttext .= $strbynameondate."\n"; $posttext .= "---------------------------------------------------------------------\n"; $posttext .= format_text_email($post->message, $post->format); $posttext .= "\n\n"; if ($post->attachment) { $post->course = $course->id; $post->forum = $forum->id; $posttext .= forum_print_attachments($post, "text"); } if ($canreply) { $posttext .= "---------------------------------------------------------------------\n"; $posttext .= get_string("postmailinfo", "forum", $course->shortname)."\n"; $posttext .= "$CFG->wwwroot/mod/forum/post.php?reply=$post->id\n"; } if ($canunsubscribe) { $posttext .= "\n---------------------------------------------------------------------\n"; $posttext .= get_string("unsubscribe", "forum"); $posttext .= ": $CFG->wwwroot/mod/forum/subscribe.php?id=$forum->id\n"; } if ($userto->mailformat == 1) { // HTML $posthtml = "
". "wwwroot/course/view.php?id=$course->id\">$course->shortname -> ". "wwwroot/mod/forum/index.php?id=$course->id\">$strforums -> ". "wwwroot/mod/forum/view.php?f=$forum->id\">$forum->name"; if ($discussion->name == $forum->name) { $posthtml .= "
"; } else { $posthtml .= " -> wwwroot/mod/forum/discuss.php?d=$discussion->id\">$discussion->name"; } $posthtml .= forum_make_mail_post($post, $userfrom, $userto, $course, false, $canreply, false, false); if ($canunsubscribe) { $posthtml .= "\nwwwroot/mod/forum/subscribe.php?id=$forum->id\">".get_string("unsubscribe", "forum")."
"; } } else { $posthtml = ""; } if (! email_to_user($userto, $userfrom, $postsubject, $posttext, $posthtml)) { echo "Error: mod/forum/cron.php: Could not send out mail for id $post->id to user $userto->id ($userto->email) .. not trying again.\n"; add_to_log($course->id, 'forum', 'mail error', "discuss.php?d=$discussion->id#$post->id", substr($post->subject,0,15), $cm->id, $userto->id); $errorcount++; } else { $mailcount++; } } echo ".... mailed to $mailcount users.\n"; if ($errorcount) { set_field("forum_posts", "mailed", "2", "id", "$post->id"); } } } } if (!empty($realuser)) { // Restore real USER if necessary $USER = $realuser; } return true; } function forum_user_outline($course, $user, $mod, $forum) { if ($posts = forum_get_user_posts($forum->id, $user->id)) { $result->info = get_string("numposts", "forum", count($posts)); $lastpost = array_pop($posts); $result->time = $lastpost->modified; return $result; } return NULL; } function forum_user_complete($course, $user, $mod, $forum) { global $CFG; if ($posts = forum_get_user_posts($forum->id, $user->id)) { foreach ($posts as $post) { forum_print_post($post, $course->id, $ownpost=false, $reply=false, $link=false, $rate=false); } } else { echo "".get_string("noposts", "forum")."
"; } } function forum_print_recent_activity($course, $isteacher, $timestart) { /// Given a course and a date, prints a summary of all the new /// messages posted in the course since that date global $CFG; $heading = false; $content = false; if (!$logs = get_records_select("log", "time > '$timestart' AND ". "course = '$course->id' AND ". "module = 'forum' AND ". "action LIKE 'add %' ", "time ASC")){ return false; } $strftimerecent = get_string("strftimerecent"); $isteacheredit = isteacheredit($course->id); $mygroupid = mygroupid($course->id); $groupmode = array(); /// To cache group modes foreach ($logs as $log) { //Get post info, I'll need it later $post = forum_get_post_from_log($log); //Create a temp valid module structure (course,id) $tempmod->course = $log->course; $tempmod->id = $post->forum; //Obtain the visible property from the instance $modvisible = instance_is_visible($log->module, $tempmod); //Only if the mod is visible if ($modvisible) { if ($post) { /// Check whether this is for teachers only $teacheronly = ""; if ($forum = get_record("forum", "id", $post->forum)) { if ($forum->type == "teacher") { if ($isteacher) { $teacheronly = "class=\"teacheronly\""; } else { continue; } } } /// Check whether this is belongs to a discussion in a group that /// should NOT be accessible to the current user if (!$isteacheredit) { /// Because editing teachers can see everything anyway if (!isset($cm[$post->forum])) { $cm[$forum->id] = get_coursemodule_from_instance("forum", $forum->id, $course->id); $groupmode[$forum->id] = groupmode($course, $cm[$forum->id]); } if ($groupmode[$forum->id]) { if ($mygroupid != $post->groupid) { continue; } } } if (! $heading) { print_headline(get_string("newforumposts", "forum").":"); $heading = true; $content = true; } $date = userdate($post->modified, $strftimerecent); $fullname = fullname($post, $isteacher); echo "$date - $fullname
";
echo "\"wwwroot/mod/forum/$log->url\">";
if (!empty($CFG->filterall)) {
$post->subject = filter_text($post->subject, $course->id);
}
if ($log->action == "add discussion") {
echo "$post->subject";
} else {
echo "$post->subject";
}
echo "\"
';
$output .= '
cellheading2\" class=\"forumpostheadertopic\" width=\"100%\">";
echo "wwwroot/mod/forum/discuss.php?d=$post->discussion\">$post->subject";
echo " | \n";
// Picture
echo "cellcontent2\" class=\"forumpostheaderpicture\" width=35>";
print_user_picture($post->userid, $courseid, $post->picture);
echo " | \n";
// User name
$fullname = fullname($post, isteacher($courseid));
echo "cellcontent2\" class=\"forumpostheadername\" align=left nowrap>";
echo "wwwroot/user/view.php?id=$post->userid&course=$courseid\">$fullname";
echo " | \n";
// Replies
echo "cellcontent2\" class=\"forumpostheaderreplies\" align=center nowrap>";
echo "wwwroot/mod/forum/discuss.php?d=$post->discussion\">$post->replies";
echo " | \n";
echo "cellcontent2\" class=\"forumpostheaderdate\" align=right nowrap>";
if (!empty($post->timemodified)) {
echo userdate($post->timemodified, $datestring);
} else {
echo userdate($post->modified, $datestring);
}
echo " | \n";
echo ""; popup_form("discuss.php?d=$discussion&mode=", $FORUM_LAYOUT_MODES, "mode", $mode, ""); echo "
"; } else if ($return == "text") { $output .= "$strattachment $file:\n$CFG->wwwroot/$ffurl\n"; } else { if ($icon == "image.gif") { // Image attachments don't get printed as links $imagereturn .= " wwwroot/$ffurl\">"; } else { link_to_popup_window("/$ffurl", "attachment", $image, 500, 500, $strattachment); echo "wwwroot/$ffurl\">$file"; echo " "; } } } } } if ($return) { return $output; } return $imagereturn; } function forum_add_attachment($post, $newfile) { // $post is a full post record, including course and forum // $newfile is a full upload array from $_FILES // If successful, this function returns the name of the file global $CFG; if (empty($newfile['name'])) { return ""; } if (!$forum = get_record("forum", "id", $post->forum)) { return ""; } if (!$course = get_record("course", "id", $forum->course)) { return ""; } $maxbytes = get_max_upload_file_size($CFG->maxbytes, $course->maxbytes, $forum->maxbytes); $newfile_name = clean_filename($newfile['name']); if (valid_uploaded_file($newfile)) { if ($maxbytes and $newfile['size'] > $maxbytes) { return ""; } if (! $newfile_name) { notify("This file had a wierd filename and couldn't be uploaded"); } else if (! $dir = forum_file_area($post)) { notify("Attachment could not be stored"); $newfile_name = ""; } else { if (move_uploaded_file($newfile['tmp_name'], "$dir/$newfile_name")) { chmod("$dir/$newfile_name", $CFG->directorypermissions); forum_delete_old_attachments($post, $newfile_name); } else { notify("An error happened while saving the file on the server"); $newfile_name = ""; } } } else { $newfile_name = ""; } return $newfile_name; } function forum_add_new_post($post) { $post->created = $post->modified = time(); $post->mailed = "0"; $newfile = $post->attachment; $post->attachment = ""; if (! $post->id = insert_record("forum_posts", $post)) { return false; } if ($post->attachment = forum_add_attachment($post, $newfile)) { set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); } // Update discussion modified date set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion); set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion); return $post->id; } function forum_update_post($post) { $post->modified = time(); if (!$post->parent) { // Post is a discussion starter - update discussion title too set_field("forum_discussions", "name", $post->subject, "id", $post->discussion); } if ($newfilename = forum_add_attachment($post, $post->attachment)) { $post->attachment = $newfilename; } else { unset($post->attachment); } // Update discussion modified date set_field("forum_discussions", "timemodified", $post->modified, "id", $post->discussion); set_field("forum_discussions", "usermodified", $post->userid, "id", $post->discussion); return update_record("forum_posts", $post); } function forum_add_discussion($discussion) { // Given an object containing all the necessary data, // create a new discussion and return the id GLOBAL $USER; $timenow = time(); // The first post is stored as a real post, and linked // to from the discuss entry. $post->discussion = 0; $post->parent = 0; $post->userid = $USER->id; $post->created = $timenow; $post->modified = $timenow; $post->mailed = 0; $post->subject = $discussion->name; $post->message = $discussion->intro; $post->attachment = ""; $post->forum = $discussion->forum; $post->course = $discussion->course; $post->format = $discussion->format; if (! $post->id = insert_record("forum_posts", $post) ) { return 0; } if ($post->attachment = forum_add_attachment($post, $discussion->attachment)) { set_field("forum_posts", "attachment", $post->attachment, "id", $post->id); //ignore errors } // Now do the main entry for the discussion, // linking to this first post $discussion->firstpost = $post->id; $discussion->timemodified = $timenow; $discussion->usermodified = $post->userid; if (! $discussion->id = insert_record("forum_discussions", $discussion) ) { delete_records("forum_posts", "id", $post->id); return 0; } // Finally, set the pointer on the post. if (! set_field("forum_posts", "discussion", $discussion->id, "id", $post->id)) { delete_records("forum_posts", "id", $post->id); delete_records("forum_discussions", "id", $discussion->id); return 0; } return $discussion->id; } function forum_delete_discussion($discussion) { // $discussion is a discussion record object $result = true; if ($posts = get_records("forum_posts", "discussion", $discussion->id)) { foreach ($posts as $post) { $post->course = $discussion->course; $post->forum = $discussion->forum; if (! delete_records("forum_ratings", "post", "$post->id")) { $result = false; } if (! forum_delete_post($post)) { $result = false; } } } if (! delete_records("forum_discussions", "id", "$discussion->id")) { $result = false; } return $result; } function forum_delete_post($post) { if (delete_records("forum_posts", "id", $post->id)) { delete_records("forum_ratings", "post", $post->id); // Just in case if ($post->attachment) { $discussion = get_record("forum_discussions", "id", $post->discussion); $post->course = $discussion->course; $post->forum = $discussion->forum; forum_delete_old_attachments($post); } return true; } return false; } function forum_print_user_discussions($courseid, $userid) { global $CFG, $USER; $maxdiscussions = 10; $countdiscussions = 0; if ($discussions = forum_get_user_discussions($courseid, $userid)) { $user = get_record("user", "id", $userid); echo " "; $fullname = fullname($user, isteacher($courseid)); print_heading( get_string("discussionsstartedbyrecent", "forum", $fullname) ); $replies = forum_count_discussion_replies(); foreach ($discussions as $discussion) { $countdiscussions++; if ($countdiscussions > $maxdiscussions) { break; } if (($discussion->forumtype == "teacher") and !isteacher($courseid)) { continue; } if (!empty($replies[$discussion->discussion])) { $discussion->replies = $replies[$discussion->discussion]->replies; } else { $discussion->replies = 0; } $inforum = get_string("inforum", "forum", "wwwroot/mod/forum/view.php?f=$discussion->forumid\">$discussion->forumname"); $discussion->subject .= " ($inforum)"; if (!empty($USER->id)) { $ownpost = ($discussion->userid == $USER->id); } else { $ownpost = false; } forum_print_post($discussion, $courseid, $ownpost, $reply=0, $link=1, $assessed=false); echo " \n"; } } } function forum_forcesubscribe($forumid, $value=1) { return set_field("forum", "forcesubscribe", $value, "id", $forumid); } function forum_is_forcesubscribed($forumid) { return get_field("forum", "forcesubscribe", "id", $forumid); } function forum_is_subscribed($userid, $forumid) { if (forum_is_forcesubscribed($forumid)) { return true; } return record_exists("forum_subscriptions", "userid", $userid, "forum", $forumid); } function forum_subscribe($userid, $forumid) { /// Adds user to the subscriber list $sub->userid = $userid; $sub->forum = $forumid; return insert_record("forum_subscriptions", $sub); } function forum_unsubscribe($userid, $forumid) { /// Removes user from the subscriber list return delete_records("forum_subscriptions", "userid", $userid, "forum", $forumid); } function forum_post_subscription($post) { /// Given a new post, subscribes or unsubscribes as appropriate. /// Returns some text which describes what happened. global $USER; if (empty($post->subscribe) and empty($post->unsubscribe)) { return ""; } if (!$forum = get_record("forum", "id", $post->forum)) { return ""; } $info->name = "$USER->firstname $USER->lastname"; $info->forum = $forum->name; if (!empty($post->subscribe)) { forum_subscribe($USER->id, $post->forum); return " ".get_string("nowsubscribed", "forum", $info)." "; } forum_unsubscribe($USER->id, $post->forum); return "".get_string("nownotsubscribed", "forum", $info)." "; } function forum_user_has_posted_discussion($forumid, $userid) { if ($discussions = forum_get_discussions($forumid, "", $userid)) { return true; } else { return false; } } function forum_user_can_post_discussion($forum, $currentgroup=false) { // $forum is an object global $USER; if ($forum->type == "eachuser") { return (! forum_user_has_posted_discussion($forum->id, $USER->id)); } else if ($forum->type == "teacher") { return isteacher($forum->course); } else if ($currentgroup) { return (isteacheredit($forum->course) or ismember($currentgroup)); } else if (isteacher($forum->course)) { return true; } else { return ($forum->open == 2); } } function forum_user_can_post($forum, $user=NULL) { // $forum, $user are objects if ($user) { $isteacher = isteacher($forum->course, $user->id); } else { $isteacher = isteacher($forum->course); } if ($forum->type == "teacher") { return $isteacher; } else if ($isteacher) { return true; } else { return $forum->open; } } function forum_print_latest_discussions($forum_id=0, $forum_numdiscussions=5, $forum_style="plain", $forum_sort="", $currentgroup=0) { global $CFG, $USER; if ($forum_id) { if (! $forum = get_record("forum", "id", $forum_id)) { error("Forum ID was incorrect"); } if (! $course = get_record("course", "id", $forum->course)) { error("Could not find the course this forum belongs to!"); } if ($course->category) { require_login($course->id); } } else { if (! $course = get_record("course", "category", 0)) { error("Could not find a top-level course!"); } if (! $forum = forum_get_course_forum($course->id, "news")) { error("Could not find or create a main forum in this course (id $course->id)"); } } if (forum_user_can_post_discussion($forum, $currentgroup)) { echo ""; echo "wwwroot/mod/forum/post.php?forum=$forum->id\">"; if ($forum->type == "news") { echo get_string("addanewtopic", "forum")."..."; } else { echo get_string("addanewdiscussion", "forum")."..."; } echo " \n"; } if ((!$forum_numdiscussions) && ($forum_style == "plain")) { $forum_style = "header"; // Abbreviate display by default } if ($forum_style == "minimal") { $forum_sort = "p.modified DESC"; } $fullpost = false; if ($forum_style == "plain") { $fullpost = true; } if (! $discussions = forum_get_discussions($forum->id, $forum_sort, 0, $fullpost, $currentgroup) ) { if ($forum->type == "news") { echo "(".get_string("nonews", "forum").") "; } else { echo "(".get_string("nodiscussions", "forum").") "; } return; } $replies = forum_count_discussion_replies($forum->id); $canreply = forum_user_can_post($forum); $discussioncount = 0; $olddiscussionlink = false; $strdatestring = get_string("strftimedaydatetime"); if ($forum_style == "minimal") { $strftimerecent = get_string("strftimerecent"); $strmore = get_string("more", "forum"); } if ($forum_style == "header") { echo "
"; } else { $by->name = fullname($post, isteacher($course->id)); $by->date = userdate($post->modified); echo "
"; if (forum_print_posts_nested($post->id, $course, $ratings, $reply)) { $ratingsmenuused = true; } echo "
|