[ticket/11103] Post notifications

PHPBB3-11103
This commit is contained in:
Nathan Guse 2012-09-09 13:29:47 -05:00
parent 570fe6cee8
commit 74e2a8f893
5 changed files with 122 additions and 241 deletions

View file

@ -1173,237 +1173,6 @@ function topic_review($topic_id, $forum_id, $mode = 'topic_review', $cur_post_id
return true;
}
/**
* User Notification
*/
function user_notification($mode, $subject, $topic_title, $forum_name, $forum_id, $topic_id, $post_id)
{
global $db, $user, $config, $phpbb_root_path, $phpEx, $auth;
$topic_notification = ($mode == 'reply' || $mode == 'quote') ? true : false;
$forum_notification = ($mode == 'post') ? true : false;
if (!$topic_notification && !$forum_notification)
{
trigger_error('NO_MODE');
}
if (($topic_notification && !$config['allow_topic_notify']) || ($forum_notification && !$config['allow_forum_notify']))
{
return;
}
$topic_title = ($topic_notification) ? $topic_title : $subject;
$topic_title = censor_text($topic_title);
// Exclude guests, current user and banned users from notifications
if (!function_exists('phpbb_get_banned_user_ids'))
{
include($phpbb_root_path . 'includes/functions_user.' . $phpEx);
}
$sql_ignore_users = phpbb_get_banned_user_ids();
$sql_ignore_users[ANONYMOUS] = ANONYMOUS;
$sql_ignore_users[$user->data['user_id']] = $user->data['user_id'];
$notify_rows = array();
// -- get forum_userids || topic_userids
$sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
FROM ' . (($topic_notification) ? TOPICS_WATCH_TABLE : FORUMS_WATCH_TABLE) . ' w, ' . USERS_TABLE . ' u
WHERE w.' . (($topic_notification) ? 'topic_id' : 'forum_id') . ' = ' . (($topic_notification) ? $topic_id : $forum_id) . '
AND ' . $db->sql_in_set('w.user_id', $sql_ignore_users, true) . '
AND w.notify_status = ' . NOTIFY_YES . '
AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
AND u.user_id = w.user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$notify_user_id = (int) $row['user_id'];
$notify_rows[$notify_user_id] = array(
'user_id' => $notify_user_id,
'username' => $row['username'],
'user_email' => $row['user_email'],
'user_jabber' => $row['user_jabber'],
'user_lang' => $row['user_lang'],
'notify_type' => ($topic_notification) ? 'topic' : 'forum',
'template' => ($topic_notification) ? 'topic_notify' : 'newtopic_notify',
'method' => $row['user_notify_type'],
'allowed' => false
);
// Add users who have been already notified to ignore list
$sql_ignore_users[$notify_user_id] = $notify_user_id;
}
$db->sql_freeresult($result);
// forum notification is sent to those not already receiving topic notifications
if ($topic_notification)
{
$sql = 'SELECT u.user_id, u.username, u.user_email, u.user_lang, u.user_notify_type, u.user_jabber
FROM ' . FORUMS_WATCH_TABLE . ' fw, ' . USERS_TABLE . " u
WHERE fw.forum_id = $forum_id
AND " . $db->sql_in_set('fw.user_id', $sql_ignore_users, true) . '
AND fw.notify_status = ' . NOTIFY_YES . '
AND u.user_type IN (' . USER_NORMAL . ', ' . USER_FOUNDER . ')
AND u.user_id = fw.user_id';
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
$notify_user_id = (int) $row['user_id'];
$notify_rows[$notify_user_id] = array(
'user_id' => $notify_user_id,
'username' => $row['username'],
'user_email' => $row['user_email'],
'user_jabber' => $row['user_jabber'],
'user_lang' => $row['user_lang'],
'notify_type' => 'forum',
'template' => 'forum_notify',
'method' => $row['user_notify_type'],
'allowed' => false
);
}
$db->sql_freeresult($result);
}
if (!sizeof($notify_rows))
{
return;
}
// Make sure users are allowed to read the forum
foreach ($auth->acl_get_list(array_keys($notify_rows), 'f_read', $forum_id) as $forum_id => $forum_ary)
{
foreach ($forum_ary as $auth_option => $user_ary)
{
foreach ($user_ary as $user_id)
{
$notify_rows[$user_id]['allowed'] = true;
}
}
}
// Now, we have to do a little step before really sending, we need to distinguish our users a little bit. ;)
$msg_users = $delete_ids = $update_notification = array();
foreach ($notify_rows as $user_id => $row)
{
if (!$row['allowed'] || !trim($row['user_email']))
{
$delete_ids[$row['notify_type']][] = $row['user_id'];
}
else
{
$msg_users[] = $row;
$update_notification[$row['notify_type']][] = $row['user_id'];
/*
* We also update the forums watch table for this user when we are
* sending out a topic notification to prevent sending out another
* notification in case this user is also subscribed to the forum
* this topic was posted in.
* Since an UPDATE query is used, this has no effect on users only
* subscribed to the topic (i.e. no row is created) and should not
* be a performance issue.
*/
if ($row['notify_type'] === 'topic')
{
$update_notification['forum'][] = $row['user_id'];
}
}
}
unset($notify_rows);
// Now, we are able to really send out notifications
if (sizeof($msg_users))
{
include_once($phpbb_root_path . 'includes/functions_messenger.' . $phpEx);
$messenger = new messenger();
$msg_list_ary = array();
foreach ($msg_users as $row)
{
$pos = (!isset($msg_list_ary[$row['template']])) ? 0 : sizeof($msg_list_ary[$row['template']]);
$msg_list_ary[$row['template']][$pos]['method'] = $row['method'];
$msg_list_ary[$row['template']][$pos]['email'] = $row['user_email'];
$msg_list_ary[$row['template']][$pos]['jabber'] = $row['user_jabber'];
$msg_list_ary[$row['template']][$pos]['name'] = $row['username'];
$msg_list_ary[$row['template']][$pos]['lang'] = $row['user_lang'];
$msg_list_ary[$row['template']][$pos]['user_id']= $row['user_id'];
}
unset($msg_users);
foreach ($msg_list_ary as $email_template => $email_list)
{
foreach ($email_list as $addr)
{
$messenger->template($email_template, $addr['lang']);
$messenger->to($addr['email'], $addr['name']);
$messenger->im($addr['jabber'], $addr['name']);
$messenger->assign_vars(array(
'USERNAME' => htmlspecialchars_decode($addr['name']),
'TOPIC_TITLE' => htmlspecialchars_decode($topic_title),
'FORUM_NAME' => htmlspecialchars_decode($forum_name),
'U_FORUM' => generate_board_url() . "/viewforum.$phpEx?f=$forum_id",
'U_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id",
'U_NEWEST_POST' => generate_board_url() . "/viewtopic.$phpEx?f=$forum_id&t=$topic_id&p=$post_id&e=$post_id",
'U_STOP_WATCHING_TOPIC' => generate_board_url() . "/viewtopic.$phpEx?uid={$addr['user_id']}&f=$forum_id&t=$topic_id&unwatch=topic",
'U_STOP_WATCHING_FORUM' => generate_board_url() . "/viewforum.$phpEx?uid={$addr['user_id']}&f=$forum_id&unwatch=forum",
));
$messenger->send($addr['method']);
}
}
unset($msg_list_ary);
$messenger->save_queue();
}
// Handle the DB updates
$db->sql_transaction('begin');
if (!empty($update_notification['topic']))
{
$sql = 'UPDATE ' . TOPICS_WATCH_TABLE . '
SET notify_status = ' . NOTIFY_NO . "
WHERE topic_id = $topic_id
AND " . $db->sql_in_set('user_id', $update_notification['topic']);
$db->sql_query($sql);
}
if (!empty($update_notification['forum']))
{
$sql = 'UPDATE ' . FORUMS_WATCH_TABLE . '
SET notify_status = ' . NOTIFY_NO . "
WHERE forum_id = $forum_id
AND " . $db->sql_in_set('user_id', $update_notification['forum']);
$db->sql_query($sql);
}
// Now delete the user_ids not authorised to receive notifications on this topic/forum
if (!empty($delete_ids['topic']))
{
$sql = 'DELETE FROM ' . TOPICS_WATCH_TABLE . "
WHERE topic_id = $topic_id
AND " . $db->sql_in_set('user_id', $delete_ids['topic']);
$db->sql_query($sql);
}
if (!empty($delete_ids['forum']))
{
$sql = 'DELETE FROM ' . FORUMS_WATCH_TABLE . "
WHERE forum_id = $forum_id
AND " . $db->sql_in_set('user_id', $delete_ids['forum']);
$db->sql_query($sql);
}
$db->sql_transaction('commit');
}
//
// Post handling functions
//
@ -1640,6 +1409,7 @@ function delete_post($forum_id, $topic_id, $post_id, &$data)
function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $update_message = true, $update_search_index = true)
{
global $db, $auth, $user, $config, $phpEx, $template, $phpbb_root_path;
global $phpbb_container;
// We do not handle erasing posts here
if ($mode == 'delete')
@ -2452,7 +2222,23 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll, &$data, $u
// Send Notifications
if (($mode == 'reply' || $mode == 'quote' || $mode == 'post') && $post_approval)
{
user_notification($mode, $subject, $data['topic_title'], $data['forum_name'], $data['forum_id'], $data['topic_id'], $data['post_id']);
$notifications = $phpbb_container->get('notifications');
switch ($mode)
{
case 'reply' :
case 'quote' :
$notifications->add_notifications('post', array_merge($data, array(
'post_username' => $username,
)));
break;
case 'post' :
$notifications->add_notifications('topic', array_merge($data, array(
'post_username' => $username,
)));
break;
}
}
$params = $add_anchor = '';

View file

@ -639,12 +639,12 @@ function approve_post($post_id_list, $id, $mode)
if ($post_id == $post_data['topic_first_post_id'] && $post_id == $post_data['topic_last_post_id'])
{
// Forum Notifications
user_notification('post', $post_data['topic_title'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id);
$notifications->add_notifications('topic', $post_data);
}
else
{
// Topic Notifications
user_notification('reply', $post_data['post_subject'], $post_data['topic_title'], $post_data['forum_name'], $post_data['forum_id'], $post_data['topic_id'], $post_id);
$notifications->add_notifications('post', $post_data);
}
}

View file

@ -174,6 +174,38 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
return $data;
}
/**
* Find the users who want to receive notifications (helper)
*
* @param ContainerBuilder $phpbb_container
* @param array $item_id The item_id to search for
*
* @return array
*/
protected static function _find_users_for_notification(ContainerBuilder $phpbb_container, $item_id)
{
$db = $phpbb_container->get('dbal.conn');
$rowset = array();
$sql = 'SELECT * FROM ' . USER_NOTIFICATIONS_TABLE . "
WHERE item_type = '" . static::get_item_type() . "'
AND item_id = " . (int) $item_id;
$result = $db->sql_query($sql);
while ($row = $db->sql_fetchrow($result))
{
if (!isset($rowset[$row['user_id']]))
{
$rowset[$row['user_id']] = array();
}
$rowset[$row['user_id']][] = $row['method'];
}
$db->sql_freeresult($result);
return $rowset;
}
/**
* Get the formatted title of this notification (fall-back)
*

View file

@ -47,7 +47,9 @@ class phpbb_notifications_type_pm extends phpbb_notifications_type_base
/**
* Find the users who want to receive notifications
*
* @param ContainerBuilder $phpbb_container
* @param array $pm Data from
*
* @return array
*/
public static function find_users_for_notification(ContainerBuilder $phpbb_container, $pm)

View file

@ -44,6 +44,61 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
return $post['post_id'];
}
/**
* Find the users who want to receive notifications
*
* @param ContainerBuilder $phpbb_container
* @param array $post Data from
*
* @return array
*/
public static function find_users_for_notification(ContainerBuilder $phpbb_container, $post)
{
$users = parent::_find_users_for_notification($phpbb_container, $post['topic_id']);
if (!sizeof($users))
{
return array();
}
$auth_read = $phpbb_container->get('auth')->acl_get_list(array_keys($users), 'f_read', $post['forum_id']);
if (empty($auth_read))
{
return array();
}
$notify_users = array();
foreach ($auth_read[$post['forum_id']]['f_read'] as $user_id)
{
$notify_users[$user_id] = $users[$user_id];
}
return $notify_users;
}
/**
* Get the HTML formatted title of this notification
*
* @return string
*/
public function get_formatted_title()
{
if ($this->get_data('post_username'))
{
$username = $this->get_data('post_username');
}
else
{
$user_data = $this->service->get_user($this->get_data('poster_id'));
$username = get_username_string('no_profile', $user_data['user_id'], $user_data['username'], $user_data['user_colour']);
}
return $username . ' posted in the topic ' . censor_text($this->get_data('topic_title'));
}
/**
* Get the title of this notification
*
@ -57,9 +112,7 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
}
else
{
$user_data = $this->get_user($this->get_data('poster_id'));
$username = get_username_string('no_profile', $user_data['user_id'], $user_data['username'], $user_data['user_colour']);
$username = $user_data['username'];
}
return $username . ' posted in the topic ' . censor_text($this->get_data('topic_title'));
@ -75,6 +128,16 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "p={$this->item_id}#p{$this->item_id}");
}
/**
* Get the full url to this item
*
* @return string URL
*/
public function get_full_url()
{
return generate_board_url() . "/viewtopic.{$this->php_ext}?p={$this->item_id}#p{$this->item_id}";
}
/**
* Users needed to query before this notification can be displayed
*
@ -103,8 +166,6 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
$this->set_data('post_username', $post['post_username']);
$this->time = $post['post_time'];
return parent::create_insert_array($post);
}
}