mirror of https://github.com/BOINC/boinc.git
- web: add general-purpose notification mechanism.
Users can choose whether to get 1 email per notification, a daily "digest" email, or no email. (All notifications are shown on the Account page). Currently used for: - Friend requests and confirmations - Posts to subscribed threads - Private messages NOTE: To implement the "daily digest" feature, projects must add a periodic task for html/ops/notify.php to config.xml - web: have project_footer() generate links for Account Page and Message Boards as well as Home NOTE: projects that want this change will have to modify their own project.inc. svn path=/trunk/boinc/; revision=14447
This commit is contained in:
parent
40f594b07c
commit
f183b6f47f
|
@ -22,3 +22,8 @@ David Dec 19 2007
|
|||
user/
|
||||
bolt_course.php
|
||||
bolt_sched.php
|
||||
|
||||
David Dec 27 2007
|
||||
- preliminary implementation of exercise_set
|
||||
|
||||
inc/bolt.inc
|
||||
|
|
|
@ -12561,3 +12561,46 @@ David 27 Dec 2007
|
|||
hosts_user.php
|
||||
tools/
|
||||
upgrade
|
||||
|
||||
David 30 Dec 2007
|
||||
- web: add general-purpose notification mechanism.
|
||||
Users can choose whether to get 1 email per notification,
|
||||
a daily "digest" email, or no email.
|
||||
(All notifications are shown on the Account page).
|
||||
Currently used for:
|
||||
- Friend requests and confirmations
|
||||
- Posts to subscribed threads
|
||||
- Private messages
|
||||
|
||||
NOTE: To implement the "daily digest" feature, projects must add
|
||||
a periodic task for html/ops/notify.php to config.xml
|
||||
- web: have project_footer() generate links for
|
||||
Account Page and Message Boards as well as Home
|
||||
NOTE: projects that want this change
|
||||
will have to modify their own project.inc.
|
||||
|
||||
db/
|
||||
constraints.sql
|
||||
schema.sql
|
||||
html/
|
||||
inc/
|
||||
boinc_db.inc
|
||||
friend.inc (new)
|
||||
forum.inc
|
||||
forum_db.inc
|
||||
forum_email.inc
|
||||
pm.inc
|
||||
user.inc
|
||||
ops/
|
||||
db_update.php
|
||||
notify.php
|
||||
project.sample/
|
||||
project.inc
|
||||
user/
|
||||
edit_forum_preferences_action.php
|
||||
edit_forum_preferences_form.php
|
||||
forum_subscribe.php
|
||||
forum_thread.php
|
||||
pm.php
|
||||
tools/
|
||||
make_project
|
||||
|
|
|
@ -122,4 +122,4 @@ alter table friend
|
|||
add unique friend_u (user_src, user_dest);
|
||||
|
||||
alter table notify
|
||||
add index notify_u (userid);
|
||||
add unique notify_un (userid, type, opaque);
|
||||
|
|
|
@ -398,8 +398,11 @@ create table subscriptions (
|
|||
userid integer not null,
|
||||
threadid integer not null,
|
||||
notified_time integer not null default 0
|
||||
-- deprecated
|
||||
) engine=InnoDB;
|
||||
|
||||
-- actually: prefs for all community features
|
||||
--
|
||||
create table forum_preferences (
|
||||
userid integer not null default 0,
|
||||
signature varchar(254) not null default '',
|
||||
|
@ -425,6 +428,10 @@ create table forum_preferences (
|
|||
ignore_sticky_posts tinyint not null default 0,
|
||||
banished_until integer not null default 0,
|
||||
pm_notification tinyint not null default 0,
|
||||
-- actually controls all notifications.
|
||||
-- 0 = no email
|
||||
-- 1 = email per event
|
||||
-- 2 = digest email
|
||||
primary key (userid)
|
||||
) engine=MyISAM;
|
||||
|
||||
|
|
|
@ -265,7 +265,9 @@ class BoincPrivateMessage {
|
|||
}
|
||||
static function insert($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->insert('private_messages', $clause);
|
||||
$ret = $db->insert('private_messages', $clause);
|
||||
if (!$ret) return $ret;
|
||||
return $db->insert_id();
|
||||
}
|
||||
static function count($clause) {
|
||||
$db = BoincDb::get();
|
||||
|
|
|
@ -710,6 +710,16 @@ function post_warning() {
|
|||
";
|
||||
}
|
||||
|
||||
function notify_subscriber($thread, $user) {
|
||||
BoincForumPrefs::lookup($user);
|
||||
if ($user->prefs->pm_notification == 1) {
|
||||
send_reply_notification_email($thread, $user);
|
||||
}
|
||||
$now = time();
|
||||
$type = NOTIFY_SUBSCRIBED_POST;
|
||||
BoincNotify::replace("userid=$user->id, create_time=$now, type=$type, opaque=$thread->id");
|
||||
}
|
||||
|
||||
// Various functions for adding/hiding/unhiding stuff.
|
||||
// These take care of counts and timestamps.
|
||||
// Don't do these things directly - use these functions
|
||||
|
@ -722,16 +732,13 @@ function create_post($content, $parent_id, $user, $forum, $thread, $signature) {
|
|||
$id = BoincPost::insert("(thread, user, timestamp, content, parent_post, signature) values ($thread->id, $user->id, $now, '$content', $parent_id, $sig)");
|
||||
if (!$id) return null;
|
||||
|
||||
// send emails to subscribed users
|
||||
// notify subscribed users
|
||||
//
|
||||
$subs = BoincSubscription::enum("threadid=$thread->id");
|
||||
foreach ($subs as $sub) {
|
||||
if ($user->id == $sub->userid) continue;
|
||||
$user2 = BoincUser::lookup_id($sub->userid);
|
||||
$visit_time = thread_last_visit($user2, $thread);
|
||||
if ($visit_time > $sub->notified_time) {
|
||||
send_reply_notification_email($thread, $user2);
|
||||
}
|
||||
notify_subscriber($thread, $user2);
|
||||
}
|
||||
$user->update("posts=posts+1");
|
||||
$thread->update("replies=replies+1, timestamp=$now");
|
||||
|
@ -1060,5 +1067,15 @@ function is_forum_visible_to_user($forum, $user) {
|
|||
return true;
|
||||
}
|
||||
|
||||
function subscribed_post_email_line($notify) {
|
||||
$thread = BoincThread::lookup_id($notify->opaque);
|
||||
return "There are new posts in the thread '$thread->title'";
|
||||
}
|
||||
|
||||
function subscribed_post_web_line($notify) {
|
||||
$thread = BoincThread::lookup_id($notify->opaque);
|
||||
return "New posts in the thread <a href=forum_thread.php?id=$thread->id>$thread->title</a>";
|
||||
}
|
||||
|
||||
|
||||
?>
|
||||
|
|
|
@ -241,6 +241,15 @@ class BoincFriend {
|
|||
$db = BoincDb::get();
|
||||
return $db->enum('friend', 'BoincFriend', $clause);
|
||||
}
|
||||
static function delete($id1, $id2) {
|
||||
$db = BoincDb::get();
|
||||
$db->delete_aux('friend', "user_src=$id1 and user_dest=$id2");
|
||||
$db->delete_aux('friend', "user_src=$id2 and user_dest=$id1");
|
||||
}
|
||||
static function replace($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->replace('friend', $clause);
|
||||
}
|
||||
}
|
||||
|
||||
class BoincNotify {
|
||||
|
@ -250,6 +259,10 @@ class BoincNotify {
|
|||
if (!$ret) return null;
|
||||
return $db->insert_id();
|
||||
}
|
||||
static function replace($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->replace('notify', $clause);
|
||||
}
|
||||
static function enum($clause) {
|
||||
$db = BoincDb::get();
|
||||
return $db->enum('notify', 'BoincNotify', $clause);
|
||||
|
@ -262,9 +275,19 @@ class BoincNotify {
|
|||
$db = BoincDb::get();
|
||||
return $db->delete($this, 'notify');
|
||||
}
|
||||
function delete_aux($clause) {
|
||||
$db = BoincDb::get();
|
||||
$db->delete_aux('notify', $clause);
|
||||
}
|
||||
static function enum_general($query) {
|
||||
$db = BoincDb::get();
|
||||
return $db->enum_general('BoincNotify', $query);
|
||||
}
|
||||
}
|
||||
|
||||
define ('NOTIFY_FRIEND_REQ', 1);
|
||||
define ('NOTIFY_FRIEND_ACCEPT', 2);
|
||||
define ('NOTIFY_PM', 3);
|
||||
define ('NOTIFY_SUBSCRIBED_POST', 4);
|
||||
|
||||
?>
|
||||
|
|
|
@ -110,8 +110,15 @@ For further information and assistance with ".PROJECT." go to ".MASTER_URL;
|
|||
function send_reply_notification_email($thread, $user){
|
||||
$title = PROJECT . ": A user has posted to '". stripslashes($thread->title) ."'";
|
||||
$link = URL_BASE . "forum_thread.php?id=" . $thread->id;
|
||||
$body = "Another " . PROJECT . " user has posted to the thread \"" . stripslashes($thread->title) . "\".\n"
|
||||
."To view the updated thread, visit the following URL:\n\n$link";
|
||||
$body = "Another " . PROJECT . " user has posted to the thread
|
||||
\"" . stripslashes($thread->title) . "\".\n"
|
||||
."To view the updated thread, visit:\n$link
|
||||
|
||||
--------------------------
|
||||
To change email preferences, visit:
|
||||
".URL_BASE."edit_forum_preferences_form.php
|
||||
Do not reply to this message.
|
||||
";
|
||||
return send_email($user, $title, $body);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
// The following two are what gets put into notification email digests
|
||||
//
|
||||
function friend_notify_req_email_line($notify) {
|
||||
$src_user = BoincUser::lookup($notify->opaque);
|
||||
if (!$src_user) return "";
|
||||
return "$src_user->name has added you as a friend; please confirm";
|
||||
}
|
||||
|
||||
function friend_notify_accept_email_line($notify) {
|
||||
$src_user = BoincUser::lookup($notify->opaque);
|
||||
if (!$src_user) return "";
|
||||
return "$src_user->name has confirmed you as a friend";
|
||||
}
|
||||
|
||||
// The following two are what gets put in the Notification
|
||||
// area of user's Account page
|
||||
//
|
||||
function friend_notify_req_web_line($notify) {
|
||||
$user = BoincUser::lookup_id($notify->opaque);
|
||||
return "
|
||||
<a href=friend.php?action=query&userid=$notify->opaque>Friendship request</a> from $user->name
|
||||
";
|
||||
}
|
||||
|
||||
function friend_notify_accept_web_line($notify) {
|
||||
$user = BoincUser::lookup_id($notify->opaque);
|
||||
return "
|
||||
<a href=friend.php?action=accepted&userid=$notify->opaque>Friendship confirmation</a> from $user->name
|
||||
";
|
||||
}
|
||||
|
||||
function send_friend_request_email($src_user, $dest_user, $msg) {
|
||||
$message = "
|
||||
$src_user->name has added you as a friend at ".PROJECT.".
|
||||
";
|
||||
if (strlen($msg)) {
|
||||
$message .= "
|
||||
$src_user->name says: $msg
|
||||
";
|
||||
}
|
||||
|
||||
$message .= "
|
||||
Please accept or decline by visiting
|
||||
".URL_BASE."home.php
|
||||
|
||||
--------------------------
|
||||
To change email preferences, visit:
|
||||
".URL_BASE."edit_forum_preferences_form.php
|
||||
Do not reply to this message.
|
||||
" ;
|
||||
send_email($dest_user, "[".PROJECT."] friend request", $message);
|
||||
}
|
||||
|
||||
function send_friend_accept_email($dest_user, $src_user, $msg) {
|
||||
$message = "
|
||||
$dest_user->name has confirmed you as a friend at ".PROJECT.".
|
||||
";
|
||||
if (strlen($msg)) {
|
||||
$message .= "
|
||||
$dest_user->name says: $msg
|
||||
";
|
||||
}
|
||||
|
||||
$message .= "
|
||||
Visit your Account page at
|
||||
".URL_BASE."home.php
|
||||
|
||||
--------------------------
|
||||
To change email preferences, visit:
|
||||
".URL_BASE."edit_forum_preferences_form.php
|
||||
Do not reply to this message.
|
||||
" ;
|
||||
send_email($src_user, "[".PROJECT."] friend confirmed", $message);
|
||||
}
|
||||
|
||||
?>
|
|
@ -77,19 +77,10 @@ function pm_create_new($error = null) {
|
|||
exit();
|
||||
}
|
||||
|
||||
function pm_send($to, $subject, $content) {
|
||||
global $logged_in_user;
|
||||
$userid = $to->id;
|
||||
$senderid = $logged_in_user->id;
|
||||
$sql_subject = mysql_real_escape_string($subject);
|
||||
$sql_content = mysql_real_escape_string($content);
|
||||
$to_user = BoincUser::lookup_id($userid);
|
||||
BoincForumPrefs::lookup($to_user);
|
||||
$send_email = false;
|
||||
if ($to_user->prefs->pm_notification) $send_email = true;
|
||||
BoincPrivateMessage::insert("(userid, senderid, date, subject, content) VALUES ($userid, $senderid, UNIX_TIMESTAMP(), '$sql_subject', '$sql_content')");
|
||||
if ($send_email) {
|
||||
$message = "
|
||||
function send_pm_notification_email(
|
||||
$logged_in_user, $to_user, $subject, $content
|
||||
) {
|
||||
$message = "
|
||||
You have received a new private message at ".PROJECT.".
|
||||
|
||||
From: $logged_in_user->name (ID $logged_in_user->id)
|
||||
|
@ -101,12 +92,50 @@ $content
|
|||
To delete or respond to this message, visit:
|
||||
".URL_BASE."pm.php
|
||||
|
||||
To disable email delivery of private messages, visit:
|
||||
To change email preferences, visit:
|
||||
".URL_BASE."edit_forum_preferences_form.php
|
||||
Do not reply to this message.
|
||||
" ;
|
||||
send_email($to, "[".PROJECT."] private message", $message);
|
||||
send_email($to_user, "[".PROJECT."] private message", $message);
|
||||
}
|
||||
|
||||
function pm_email_line($notify) {
|
||||
$pm = BoincPrivateMessage::lookup_id($notify->opaque);
|
||||
$from_user = BoincUser::lookup_id($pm->senderid);
|
||||
return "$from_user->name sent you a private message; subject: '$pm->subject'";
|
||||
}
|
||||
|
||||
function pm_web_line($notify) {
|
||||
$pm = BoincPrivateMessage::lookup_id($notify->opaque);
|
||||
$from_user = BoincUser::lookup_id($pm->senderid);
|
||||
return "<a href=pm.php>Private message</a> from $from_user->name, subject: $pm->subject";
|
||||
}
|
||||
|
||||
function pm_send($to_user, $subject, $content) {
|
||||
global $logged_in_user;
|
||||
$sql_subject = mysql_real_escape_string($subject);
|
||||
$sql_content = mysql_real_escape_string($content);
|
||||
$mid = BoincPrivateMessage::insert("(userid, senderid, date, subject, content) VALUES ($to_user->id, $logged_in_user->id, UNIX_TIMESTAMP(), '$sql_subject', '$sql_content')");
|
||||
if (!$mid) {
|
||||
error_page("Couldn't create message");
|
||||
}
|
||||
// send email notification if needed
|
||||
//
|
||||
BoincForumPrefs::lookup($to_user);
|
||||
switch ($to_user->prefs->pm_notification) {
|
||||
case 0:
|
||||
case 2:
|
||||
break;
|
||||
case 1:
|
||||
send_pm_notification_email(
|
||||
$logged_in_user, $to_user, $subject, $content
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
// create notification in any case
|
||||
//
|
||||
BoincNotify::insert("(userid, create_time, type, opaque) values ($to_user->id, ".time().", ".NOTIFY_PM.", $mid)");
|
||||
}
|
||||
|
||||
function pm_count($userid, $duration) {
|
||||
|
|
|
@ -4,6 +4,7 @@ require_once("../inc/credit.inc");
|
|||
require_once("../inc/email.inc");
|
||||
require_once("../inc/util.inc");
|
||||
require_once("../inc/team.inc");
|
||||
require_once("../inc/friend.inc");
|
||||
require_once("../inc/forum_db.inc");
|
||||
|
||||
function parse_project($f) {
|
||||
|
@ -150,20 +151,15 @@ function show_user_stats_private($user) {
|
|||
function notify_description($notify) {
|
||||
switch ($notify->type) {
|
||||
case NOTIFY_FRIEND_REQ:
|
||||
$user = BoincUser::lookup_id($notify->opaque);
|
||||
return "
|
||||
<a href=friend.php?action=query&userid=$notify->opaque>Friend request from $user->name</a>
|
||||
<br>
|
||||
";
|
||||
break;
|
||||
return friend_notify_req_web_line($notify);
|
||||
case NOTIFY_FRIEND_ACCEPT:
|
||||
$user = BoincUser::lookup_id($notify->opaque);
|
||||
return "
|
||||
<a href=friend.php?action=accepted&userid=$notify->opaque>$user->name confirmed as friend</a>
|
||||
<br>
|
||||
";
|
||||
break;
|
||||
return friend_notify_accept_web_line($notify);
|
||||
case NOTIFY_PM:
|
||||
return pm_web_line($notify);
|
||||
case NOTIFY_SUBSCRIBED_POST:
|
||||
return subscribed_post_web_line($notify);
|
||||
}
|
||||
return "Unknown notification type: $notify->type";
|
||||
}
|
||||
|
||||
// show static user info (private)
|
||||
|
@ -222,17 +218,18 @@ function show_user_info_private($user) {
|
|||
if (count($notifies)) {
|
||||
$x = "";
|
||||
foreach ($notifies as $notify) {
|
||||
$x .= notify_description($notify);
|
||||
$x .= notify_description($notify)."<br>";
|
||||
}
|
||||
row2("Notifications", $x);
|
||||
}
|
||||
|
||||
$friends = BoincFriend::enum("user_src=$user->id and reciprocated=1");
|
||||
if (count($friends)) {
|
||||
$x = "";
|
||||
$x = null;
|
||||
foreach($friends as $friend) {
|
||||
if ($x) $x .= " | ";
|
||||
$fuser = BoincUser::lookup_id($friend->user_dest);
|
||||
$x .= " ". user_links($fuser);
|
||||
$x .= user_links($fuser, true);
|
||||
}
|
||||
row2("Friends", $x);
|
||||
}
|
||||
|
@ -305,10 +302,11 @@ function show_user_summary_public($user) {
|
|||
|
||||
$friends = BoincFriend::enum("user_src=$user->id and reciprocated=1");
|
||||
if (count($friends)) {
|
||||
$x = "";
|
||||
$x = null;
|
||||
foreach($friends as $friend) {
|
||||
if ($x) $x .= " | ";
|
||||
$fuser = BoincUser::lookup_id($friend->user_dest);
|
||||
$x .= " ".user_links($fuser, true);
|
||||
$x .= user_links($fuser, true);
|
||||
}
|
||||
row2("Friends", $x);
|
||||
}
|
||||
|
@ -316,8 +314,12 @@ function show_user_summary_public($user) {
|
|||
if ($g_logged_in_user && $g_logged_in_user->id != $user->id) {
|
||||
row2("Contact", "<a href=\"pm.php?action=new&userid=".$user->id."\">Send private message</a>");
|
||||
$friend = BoincFriend::lookup($g_logged_in_user->id, $user->id);
|
||||
if (!$friend) {
|
||||
row2("Community", "<a href=friend.php?action=add&userid=".$user->id.">Add as friend</a>");
|
||||
if ($friend && $friend->reciprocated) {
|
||||
row2("This person is a friend",
|
||||
"<a href=friend.php?action=cancel_confirm&userid=$user->id>Cancel friendship</a>"
|
||||
);
|
||||
} else {
|
||||
row2("Community", "<a href=friend.php?action=add&userid=$user->id>Add as friend</a>");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -534,6 +534,13 @@ function update_12_18_2007() {
|
|||
");
|
||||
}
|
||||
|
||||
function update_12_28_2007() {
|
||||
do_query("alter table notify drop index notify_u");
|
||||
do_query("alter table notify
|
||||
add unique notify_un (userid, type, opaque)
|
||||
");
|
||||
}
|
||||
|
||||
// modify the following to call the function you want.
|
||||
// Make sure you do all needed functions, in order.
|
||||
// (Look at your DB structure using "explain" queries to see
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
#!/usr/bin/env php
|
||||
|
||||
<?php
|
||||
|
||||
// Script to delete old notifications and send notification emails.
|
||||
// Run once a day.
|
||||
//
|
||||
// We send emails for notifications generated in the last day.
|
||||
// This is a slight kludge - since the timing of period tasks
|
||||
// is not precise, notifications may be delivered twice or not at all.
|
||||
// We use a 1-hour slop factor to err on the side of twice.
|
||||
//
|
||||
|
||||
require_once("../inc/boinc_db.inc");
|
||||
require_once("../inc/util.inc");
|
||||
require_once("../project/project.inc");
|
||||
|
||||
// delete notifications older than 90 days
|
||||
//
|
||||
function delete_old_notifies() {
|
||||
$t = time()-90*86400;
|
||||
BoincNotify::delete_aux("create_time < $t");
|
||||
}
|
||||
|
||||
function send_notify_email($userid, $message) {
|
||||
$user = BoincUser::lookup_id($userid);
|
||||
$subject = "Daily notification summary from ".PROJECT;
|
||||
$body = "The following events occurred in the past day at ".PROJECT.".
|
||||
For details, visit your Account page at
|
||||
".URL_BASE."home.php
|
||||
|
||||
$message
|
||||
---------------
|
||||
To change your email preferences for ".PROJECT.", visit:
|
||||
".URL_BASE."edit_forum_preferences_form.php
|
||||
|
||||
Do not reply to this email.
|
||||
";
|
||||
send_email($user, $subject, $body);
|
||||
|
||||
echo "sending to $user->email_addr\n";
|
||||
}
|
||||
|
||||
function send_notify_emails() {
|
||||
$t = time() - (86400 + 3600); // 1-hour slop factor
|
||||
$query = "select notify.* from DBNAME.notify, DBNAME.forum_preferences where forum_preferences.pm_notification=2 and notify.userid = forum_preferences.userid and notify.create_time > $t";
|
||||
|
||||
$notifies = BoincNotify::enum_general($query);
|
||||
$userid = 0;
|
||||
$message = "";
|
||||
$i = 1;
|
||||
foreach ($notifies as $notify) {
|
||||
if ($userid && $notify->userid != $userid) {
|
||||
send_notify_email($userid, $message);
|
||||
$message = "";
|
||||
$i = 1;
|
||||
}
|
||||
$userid = $notify->userid;
|
||||
$message .= "$i) ";
|
||||
switch ($notify->type) {
|
||||
case NOTIFY_FRIEND_REQ:
|
||||
$message .= friend_notify_req_email_line($notify);
|
||||
break;
|
||||
case NOTIFY_FRIEND_ACCEPT:
|
||||
$message .= friend_notify_accept_email_line($notify);
|
||||
break;
|
||||
case NOTIFY_PM:
|
||||
$message .= pm_email_line($notify);
|
||||
break;
|
||||
case NOTIFY_SUBSCRIBED_POST:
|
||||
$message .= subscribed_post_email_line($notify);
|
||||
break;
|
||||
}
|
||||
$message .= "\n";
|
||||
$i++;
|
||||
}
|
||||
if ($userid) {
|
||||
send_notify_email($userid, $message);
|
||||
}
|
||||
}
|
||||
|
||||
$t = time_str(time());
|
||||
echo "Starting at $t\n";
|
||||
|
||||
delete_old_notifies();
|
||||
send_notify_emails();
|
||||
|
||||
$t = time_str(time());
|
||||
echo "Ending at $t\n\n";
|
||||
|
||||
?>
|
|
@ -7,7 +7,7 @@
|
|||
require_once("../inc/util.inc");
|
||||
|
||||
$master_url = parse_config(get_config(), "<master_url>");
|
||||
define("PROJECT", "Test Project");
|
||||
define("PROJECT", "REPLACE WITH PROJECT NAME");
|
||||
define("URL_BASE", $master_url);
|
||||
define("IMAGE_PATH", "../user_profile/images/");
|
||||
define("IMAGE_URL", "user_profile/images/");
|
||||
|
@ -15,9 +15,10 @@ define("PROFILE_PATH", "../user_profile/");
|
|||
define("PROFILE_URL", "user_profile/");
|
||||
define("LANGUAGE_FILE", "languages.txt");
|
||||
define("STYLESHEET", "white.css");
|
||||
define("COPYRIGHT_HOLDER", "Test Group");
|
||||
define("COPYRIGHT_HOLDER", "REPLACE WITH COPYRIGHT HOLDER");
|
||||
define("SYS_ADMIN_EMAIL", "admin@$master_url");
|
||||
define("UOTD_ADMIN_EMAIL", "admin@$master_url"); # who gets user of the day pool running low e-mails?
|
||||
define("UOTD_ADMIN_EMAIL", "admin@$master_url");
|
||||
// who gets user of the day pool running low e-mails?
|
||||
|
||||
// Email addresses separated by pipe ( | ) that will receive user reported
|
||||
// offensive forum posts.
|
||||
|
@ -37,7 +38,7 @@ function project_banner($title) {
|
|||
function project_footer($show_return, $show_date) {
|
||||
echo "<br><hr noshade size=1><center>";
|
||||
if ($show_return) {
|
||||
echo "<a href=\"".URL_BASE."\">Return to ".PROJECT." main page</a><br>\n";
|
||||
echo "<a href=index.php>Home</a> | <a href=home.php>My Account</a> | <a href=forum_index.php>Message Boards</a><br>\n";
|
||||
}
|
||||
echo "<br><br>Copyright © ".date("Y ").COPYRIGHT_HOLDER."</center>\n";
|
||||
if ($show_date) {
|
||||
|
|
|
@ -83,7 +83,6 @@ if ($avatar_type==0){
|
|||
}
|
||||
}
|
||||
|
||||
// Update some simple prefs that are either on or off
|
||||
$images_as_links = ($_POST["forum_images_as_links"]!="")?1:0;
|
||||
$link_popup = ($_POST["forum_link_popup"]!="")?1:0;
|
||||
$hide_avatars = ($_POST["forum_hide_avatars"]!="")?1:0;
|
||||
|
@ -91,7 +90,7 @@ $hide_signatures = ($_POST["forum_hide_signatures"]!="")?1:0;
|
|||
$jump_to_unread = ($_POST["forum_jump_to_unread"]!="")?1:0;
|
||||
$ignore_sticky_posts = ($_POST["forum_ignore_sticky_posts"]!="")?1:0;
|
||||
$no_signature_by_default = ($_POST["signature_by_default"]!="")?0:1;
|
||||
$pm_notification = ($_POST["pm_notification"]!="")?1:0;
|
||||
$pm_notification = post_int("pm_notification");
|
||||
//$low_rating_threshold = post_int("forum_low_rating_threshold");
|
||||
//$high_rating_threshold = post_int("forum_high_rating_threshold");
|
||||
$signature = stripslashes($_POST["signature"]);
|
||||
|
|
|
@ -27,15 +27,31 @@ echo "<script type=\"text/javascript\">
|
|||
start_table();
|
||||
echo "<form method=\"post\" action=\"edit_forum_preferences_action.php\" enctype=\"multipart/form-data\">";
|
||||
|
||||
// ------------ Notification -----------
|
||||
|
||||
row1("Notifications");
|
||||
$ch0 = $user->prefs->pm_notification==0?"checked":"";
|
||||
$ch1 = $user->prefs->pm_notification==1?"checked":"";
|
||||
$ch2 = $user->prefs->pm_notification==2?"checked":"";
|
||||
row2(
|
||||
"How should we notify you of new private messages, friend requests, posts in subscribed threads, and other events?",
|
||||
"<input type=radio name=pm_notification value=0 $ch0> On my Account page (no email)
|
||||
<br><input type=radio name=pm_notification value=1 $ch1> Immediately, by email
|
||||
<br><input type=radio name=pm_notification value=2 $ch2> In a single daily email
|
||||
"
|
||||
);
|
||||
|
||||
// ------------ Forum identity -----------
|
||||
|
||||
$zero_select = $two_select = "";
|
||||
if (strlen($user->prefs->avatar)){
|
||||
$two_select="checked=\"true\"";
|
||||
} else {
|
||||
$zero_select="checked=\"true\"";
|
||||
}
|
||||
row1("Identity");
|
||||
row1("Message-board identity");
|
||||
row2("Avatar
|
||||
<br><span class=note>An image representing you.
|
||||
<br><span class=note>An image representing you on the message boards.
|
||||
<br>Format: JPG or /PNG. Size: at most 4 KB, 100x100 pixels</span>",
|
||||
"<input type=\"radio\" name=\"avatar_select\" value=\"0\" ".$zero_select.">Don't use an avatar <br><input type=\"radio\" name=\"avatar_select\" value=\"2\" ".$two_select.">Use this uploaded avatar: <input type=\"file\" name=\"picture\">"
|
||||
);
|
||||
|
@ -52,7 +68,7 @@ if (!$user->prefs->no_signature_by_default){
|
|||
$signature=stripslashes($user->prefs->signature);
|
||||
$maxlen=250;
|
||||
row2(
|
||||
"Signature<br>
|
||||
"Signature for message board posts<br>
|
||||
<span class=note>Max length is $maxlen chars.</span>".
|
||||
html_info(),
|
||||
"<textarea name=\"signature\" rows=4 cols=50 id=\"signature\" onkeydown=\"textCounter(this.form.signature, this.form.remLen,$maxlen);\"
|
||||
|
@ -67,16 +83,7 @@ if ($user->prefs->signature!=""){
|
|||
);
|
||||
}
|
||||
|
||||
row1("Private message notification");
|
||||
if ($user->prefs->pm_notification){
|
||||
$pm_notification="checked=\"checked\"";
|
||||
} else {
|
||||
$pm_notification="";
|
||||
}
|
||||
row2(
|
||||
"Send email notification of new private messages",
|
||||
"<input type=\"checkbox\" id=\"pm_notification\" name=\"pm_notification\" ".$pm_notification.">"
|
||||
);
|
||||
// ------------ Message display -----------
|
||||
|
||||
if ($user->prefs->hide_avatars){
|
||||
$forum_hide_avatars = "checked=\"checked\"";
|
||||
|
@ -132,6 +139,8 @@ row2("How to sort",
|
|||
"
|
||||
);
|
||||
|
||||
// ------------ Message filtering -----------
|
||||
|
||||
row1("Message filtering");
|
||||
|
||||
$filtered_userlist = get_ignored_list($user);
|
||||
|
|
|
@ -29,7 +29,7 @@ function subscribe($forum, $thread, $user) {
|
|||
show_forum_header($user);
|
||||
show_title($forum, $thread);
|
||||
echo "<p>You are now subscribed to <b>", cleanup_title($thread->title), "</b>.
|
||||
You will receive an email whenever someone posts to the thread.";
|
||||
You will be notified whenever there is a new post.";
|
||||
} else {
|
||||
page_head("Subscription failed");
|
||||
echo "<p>We are currently unable to subscribe you to this thread (<b>", cleanup_title($thread->title), "</b>).
|
||||
|
|
|
@ -115,6 +115,8 @@ if (can_reply($thread, $forum, $logged_in_user)) {
|
|||
}
|
||||
|
||||
if ($is_subscribed) {
|
||||
$type = NOTIFY_SUBSCRIBED_POST;
|
||||
BoincNotify::delete_aux("userid=$logged_in_user->id and type=$type and opaque=$thread->id");
|
||||
$url = "forum_subscribe.php?action=unsubscribe&thread=".$thread->id."$tokens";
|
||||
show_button($url, tra("Unsubscribe"), "You are subscribed to this thread. Click here to unsubscribe.");
|
||||
} else {
|
||||
|
|
|
@ -5,36 +5,28 @@
|
|||
require_once("../inc/forum_db.inc");
|
||||
require_once("../inc/profile.inc");
|
||||
|
||||
// tell src:
|
||||
// You are about to add X as a friend.
|
||||
// We will notify X, who wil have to confirm that you are friends
|
||||
// (add message here)
|
||||
// add/cancel
|
||||
// see if there's already a request,
|
||||
// and whether the notification record is there
|
||||
//
|
||||
// send PM or email to dest saying
|
||||
// subject: X added you as a friend on Project
|
||||
// X added you as a friend on Project.
|
||||
|
||||
// X says: Y
|
||||
|
||||
// To confirm this friend request, please visit:
|
||||
// Z
|
||||
//
|
||||
// Thanks -- Project
|
||||
//
|
||||
// To control the emails you receive from Project, please visit W
|
||||
//
|
||||
// link goes to page:
|
||||
// You have a friend request.
|
||||
// (show picture)
|
||||
// Name (conutry)
|
||||
// You and X have friends in common:
|
||||
// buttons: Confirm, Ignore
|
||||
// small links: Send a message, report this person
|
||||
|
||||
// no rate-limiting mechanism
|
||||
|
||||
function send_request() {
|
||||
function check_pending($user, $destuser) {
|
||||
$friend = BoincFriend::lookup($user->id, $destuser->id);
|
||||
if ($friend) {
|
||||
if ($friend->reciprocated) {
|
||||
error_page("Already friends");
|
||||
}
|
||||
$notify = BoincNotify::lookup($destuser->id, NOTIFY_FRIEND_REQ, $user->id);
|
||||
if ($notify) {
|
||||
page_head("Request pending");
|
||||
$t = date_str($friend->create_time);
|
||||
echo "You requested friendship with $destuser->name on $t.
|
||||
<p>
|
||||
This request is still pending confirmation.
|
||||
";
|
||||
page_tail();
|
||||
exit();
|
||||
}
|
||||
BoincFriend::delete($user->id, $destuser->id);
|
||||
}
|
||||
}
|
||||
|
||||
// user has clicked "add to friends". Ask them if they really mean it.
|
||||
|
@ -46,10 +38,9 @@ function handle_add($user) {
|
|||
}
|
||||
$destuser = BoincUser::lookup_id($destid);
|
||||
if (!$destuser) error_page("No such user");
|
||||
$friend = BoincFriend::lookup($user->id, $destid);
|
||||
if ($friend) {
|
||||
error_page("Friend request already exists");
|
||||
}
|
||||
|
||||
check_pending($user, $destuser);
|
||||
|
||||
page_head("Add friend");
|
||||
echo "
|
||||
<form method=post action=friend.php>
|
||||
|
@ -64,7 +55,7 @@ function handle_add($user) {
|
|||
<textarea name=message cols=64 rows=4></textarea>
|
||||
<p>
|
||||
<input type=submit value=OK>
|
||||
<input type=submit value=Cancel>
|
||||
</form>
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
@ -76,20 +67,28 @@ function handle_add_confirm($user) {
|
|||
$destuser = BoincUser::lookup_id($destid);
|
||||
if (!$destuser) error_page("No such user");
|
||||
|
||||
check_pending($user, $destuser);
|
||||
|
||||
$msg = post_str('message', true);
|
||||
if ($msg) $msg = strip_tags(process_user_text($msg));
|
||||
|
||||
$now = time();
|
||||
$ret = BoincFriend::insert("(user_src, user_dest, message, create_time, reciprocated) values ($user->id, $destid, '$msg', $now, 0)");
|
||||
$ret = BoincFriend::replace("user_src=$user->id, user_dest=$destid, message='$msg', create_time=$now, reciprocated=0");
|
||||
if (!$ret) {
|
||||
error_page("database error");
|
||||
}
|
||||
$ret = BoincNotify::insert("(userid, create_time, type, opaque) values ($destid, $now, ".NOTIFY_FRIEND_REQ.", $user->id)");
|
||||
if (!$ret) {
|
||||
error_page("Database error");
|
||||
$now = time();
|
||||
$type = NOTIFY_FRIEND_REQ;
|
||||
BoincNotify::replace("userid=$destid, create_time=$now, type=$type, opaque=$user->id");
|
||||
|
||||
BoincForumPrefs::lookup($destuser);
|
||||
if ($destuser->prefs->pm_notification == 1) {
|
||||
send_friend_request_email($user, $destuser, $msg);
|
||||
}
|
||||
page_head("Friend request sent");
|
||||
echo "We have notified <b>$destuser->name</b> of your request.";
|
||||
echo "
|
||||
We have notified <b>$destuser->name</b> of your request.
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
||||
|
@ -105,19 +104,18 @@ function handle_query($user) {
|
|||
$x = user_links($srcuser, true);
|
||||
echo "
|
||||
$x has added you as a friend.
|
||||
If $srcuser->name is in fact your friend, please click Accept.
|
||||
";
|
||||
$img_url = profile_user_thumb_url($srcuser);
|
||||
if ($img_url) {
|
||||
echo "<p><img src=$img_url><p>\n";
|
||||
}
|
||||
if (strlen($friend->message)) {
|
||||
echo "<p>$srcuser->name says: $friend->message<p>";
|
||||
}
|
||||
echo "
|
||||
<p>
|
||||
<a href=friend.php?action=accept&userid=$srcid>Accept</a> |
|
||||
<a href=friend.php?action=ignore&userid=$srcid>Ignore</a>
|
||||
<a href=friend.php?action=accept&userid=$srcid>Accept</a>
|
||||
(click if $srcuser->name is in fact a friend)
|
||||
<p>
|
||||
<a href=friend.php?action=ignore&userid=$srcid>Decline</a>
|
||||
(click if $srcuser->name is not a friend)
|
||||
<p>
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
@ -139,24 +137,26 @@ function handle_accept($user) {
|
|||
$msg = post_str('message', true);
|
||||
if ($msg) $msg = strip_tags(process_user_text($msg));
|
||||
$now = time();
|
||||
$ret = BoincFriend::insert("(user_src, user_dest, message, create_time, reciprocated) values ($user->id, $srcid, '$msg', $now, 1)");
|
||||
$ret = BoincFriend::replace("user_src=$user->id, user_dest=$srcid, message='$msg', create_time=$now, reciprocated=1");
|
||||
if (!$ret) {
|
||||
error_page("database error");
|
||||
}
|
||||
$ret = BoincNotify::insert("(userid, create_time, type, opaque) values ($srcid, $now, ".NOTIFY_FRIEND_ACCEPT.", $user->id)");
|
||||
if (!$ret) {
|
||||
error_page("Database error");
|
||||
$type = NOTIFY_FRIEND_ACCEPT;
|
||||
BoincNotify::replace("userid=$srcid, create_time=$now, type=$type, opaque=$user->id");
|
||||
BoincForumPrefs::lookup($srcuser);
|
||||
if ($srcuser->prefs->pm_notification == 1) {
|
||||
send_friend_accept_email($user, $srcuser, $msg);
|
||||
}
|
||||
|
||||
$notify = BoincNotify::lookup($user->id, NOTIFY_FRIEND_REQ, $srcid);
|
||||
if ($notify) {
|
||||
$notify->delete();
|
||||
} else {
|
||||
echo "?? notification not found";
|
||||
}
|
||||
|
||||
page_head("Friendship confirmed");
|
||||
echo "Your friendship with <b>$srcuser->name</b> has been confirmed.";
|
||||
echo "
|
||||
Your friendship with <b>$srcuser->name</b> has been confirmed.
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
||||
|
@ -173,11 +173,11 @@ function handle_ignore($user) {
|
|||
$notify = BoincNotify::lookup($user->id, NOTIFY_FRIEND_REQ, $srcid);
|
||||
if ($notify) {
|
||||
$notify->delete();
|
||||
} else {
|
||||
echo "?? notification not found";
|
||||
}
|
||||
page_head("Friendship declined");
|
||||
echo "You have declined friendship with <b>$srcuser->name</b>.";
|
||||
echo "
|
||||
You have declined friendship with <b>$srcuser->name</b>
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
||||
|
@ -201,6 +201,33 @@ function handle_accepted($user) {
|
|||
page_tail();
|
||||
}
|
||||
|
||||
function handle_cancel_confirm($user) {
|
||||
$destid = get_int('userid');
|
||||
$destuser = BoincUser::lookup_id($destid);
|
||||
if (!$destuser) error_page("No such user");
|
||||
page_head("Cancel friendship?");
|
||||
echo "
|
||||
Are you sure you want to cancel your friendship with $destuser->name?
|
||||
<p>
|
||||
";
|
||||
show_button("friend.php?action=cancel&userid=$destid", "Yes", "Cancel friendship");
|
||||
echo "<p>";
|
||||
show_button("home.php", "No", "Don't cancel friendship");
|
||||
page_tail();
|
||||
}
|
||||
|
||||
function handle_cancel($user) {
|
||||
$destid = get_int('userid');
|
||||
$destuser = BoincUser::lookup_id($destid);
|
||||
if (!$destuser) error_page("No such user");
|
||||
BoincFriend::delete($user->id, $destid);
|
||||
page_head("Friendship cancelled");
|
||||
echo "
|
||||
Your friendship with $destuser->name has been cancelled.
|
||||
";
|
||||
page_tail();
|
||||
}
|
||||
|
||||
// "home page" has Requests area
|
||||
// (icon) N friend request(s)
|
||||
|
||||
|
@ -228,6 +255,12 @@ case 'accepted':
|
|||
case 'ignore':
|
||||
handle_ignore($user);
|
||||
break;
|
||||
case 'cancel_confirm':
|
||||
handle_cancel_confirm($user);
|
||||
break;
|
||||
case 'cancel':
|
||||
handle_cancel($user);
|
||||
break;
|
||||
default:
|
||||
error_page("unknown action");
|
||||
}
|
||||
|
|
|
@ -45,6 +45,9 @@ function make_script() {
|
|||
";
|
||||
}
|
||||
|
||||
// show all private messages,
|
||||
// and delete notifications of new messages
|
||||
//
|
||||
function do_inbox($logged_in_user) {
|
||||
page_head(tra("Private messages").": ".tra("Inbox"));
|
||||
|
||||
|
@ -54,6 +57,8 @@ function do_inbox($logged_in_user) {
|
|||
}
|
||||
$options = get_output_options($logged_in_user);
|
||||
|
||||
BoincNotify::delete_aux("userid=$logged_in_user->id and type=".NOTIFY_PM);
|
||||
|
||||
$msgs = BoincPrivateMessage::enum(
|
||||
"userid=$logged_in_user->id ORDER BY date DESC"
|
||||
);
|
||||
|
|
|
@ -258,6 +258,11 @@ t.period = '24 hours'
|
|||
t.output = 'team_import.out'
|
||||
t.cmd = 'run_in_ops team_import.php'
|
||||
|
||||
t = project.config.tasks.make_node_and_append("task")
|
||||
t.period = '24 hours'
|
||||
t.output = 'notify.out'
|
||||
t.cmd = 'run_in_ops notify.php'
|
||||
|
||||
project.config.write()
|
||||
|
||||
svn_version_file = proot+'/local.revision'
|
||||
|
|
Loading…
Reference in New Issue