1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-05-08 08:35:31 +02:00

[ticket/11103] Store the item's parent id for marking things read

Mark topics/posts read from the markread() function.

Identify unread items by a grey background in the header (for now)

PHPBB3-11103
This commit is contained in:
Nathan Guse 2012-09-14 15:59:13 -05:00
parent 44aa773ce0
commit fb0ed78c8f
10 changed files with 197 additions and 95 deletions

View File

@ -1299,6 +1299,7 @@ function get_schema_struct()
'COLUMNS' => array(
'item_type' => array('VCHAR:25', ''),
'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0),
'unread' => array('BOOL', 1),
'time' => array('TIMESTAMP', 1),
@ -1312,8 +1313,10 @@ function get_schema_struct()
'KEYS' => array(
'item_type' => array('INDEX', 'item_type'),
'item_id' => array('INDEX', 'item_id'),
'item_pid' => array('INDEX', 'item_parent_id'),
'user_id' => array('INDEX', 'user_id'),
'time' => array('INDEX', 'time'),
'unread' => array('INDEX', 'unread'),
),
);

View File

@ -1285,15 +1285,20 @@ function phpbb_timezone_select($user, $default = '', $truncate = false)
function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $user_id = 0)
{
global $db, $user, $config;
global $request;
global $request, $phpbb_container;
if ($mode == 'all')
{
if ($forum_id === false || !sizeof($forum_id))
{
// Mark all forums read (index page)
// Mark all topic notifications read for this user
$notifications = $phpbb_container->get('notifications');
$notifications->mark_notifications_read('topic', false, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
{
// Mark all forums read (index page)
$db->sql_query('DELETE FROM ' . TOPICS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}");
$db->sql_query('DELETE FROM ' . FORUMS_TRACK_TABLE . " WHERE user_id = {$user->data['user_id']}");
$db->sql_query('UPDATE ' . USERS_TABLE . ' SET user_lastmark = ' . time() . " WHERE user_id = {$user->data['user_id']}");
@ -1330,6 +1335,10 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$forum_id = array($forum_id);
}
// Mark topic notifications read for this user in this forum
$notifications = $phpbb_container->get('notifications');
$notifications->mark_notifications_read_by_parent('topic', $forum_id, $user->data['user_id'], $post_time);
// Add 0 to forums array to mark global announcements correctly
// $forum_id[] = 0;
@ -1424,6 +1433,11 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
return;
}
// Mark post notifications read for this user in this topic
$notifications = $phpbb_container->get('notifications');
$notifications->mark_notifications_read_by_parent('post', $topic_id, $user->data['user_id'], $post_time);
$notifications->mark_notifications_read_by_parent('quote', $topic_id, $user->data['user_id'], $post_time);
if ($config['load_db_lastread'] && $user->data['is_registered'])
{
$sql = 'UPDATE ' . TOPICS_TRACK_TABLE . '

View File

@ -106,6 +106,52 @@ class phpbb_notifications_service
return $notifications;
}
/**
* Mark notifications read
*
* @param string $item_type item type
* @param bool|int|array $item_id Item id or array of item ids. False to mark read for all item ids
* @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
*/
public function mark_notifications_read($item_type, $item_id, $user_id, $time = false)
{
$time = ($time) ?: time();
$this->get_item_type_class_name($item_type);
$sql = 'UPDATE ' . NOTIFICATIONS_TABLE . "
SET unread = 0
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND time <= " . $time .
(($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
$this->db->sql_query($sql);
}
/**
* Mark notifications read from a parent identifier
*
* @param string $item_type item type
* @param bool|int|array $item_parent_id Item parent id or array of item parent ids. False to mark read for all item parent ids
* @param bool|int|array $user_id User id or array of user ids. False to mark read for all user ids
* @param bool|int $time Time at which to mark all notifications prior to as read. False to mark all as read. (Default: False)
*/
public function mark_notifications_read_by_parent($item_type, $item_parent_id, $user_id, $time = false)
{
$time = ($time) ?: time();
$item_type_class_name = $this->get_item_type_class_name($item_type);
$sql = 'UPDATE ' . NOTIFICATIONS_TABLE . "
SET unread = 0
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND time <= " . $time .
(($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id) : 'item_parent_id = ' . (int) $item_parent_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '');
$this->db->sql_query($sql);
}
/**
* Add a notification
*
@ -118,9 +164,6 @@ class phpbb_notifications_service
$item_id = $item_type_class_name::get_item_id($data);
// Update any existing notifications for this item
$this->update_notifications($item_type, $data);
// find out which users want to receive this type of notification
$notify_users = $item_type_class_name::find_users_for_notification($this->phpbb_container, $data);
@ -250,6 +293,8 @@ class phpbb_notifications_service
*/
public function delete_notifications($item_type, $item_id)
{
$this->get_item_type_class_name($item_type);
$sql = 'DELETE FROM ' . NOTIFICATIONS_TABLE . "
WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
AND " . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id);

View File

@ -40,6 +40,7 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
* Indentification data
* item_type
* item_id
* item_parent_id // Parent item id (ex: for topic => forum_id, for post => topic_id, etc)
* user_id
* unread
*
@ -145,33 +146,6 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
return $this->mark(true, $return);
}
/**
* Mark this item read/unread
*
* @param bool $unread Unread (True/False) (Default: False)
* @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False)
* @return string
*/
protected function mark($unread = true, $return = false)
{
$where = array(
'item_type = ' . $this->db->sql_escape($this->item_type),
'item_id = ' . (int) $this->item_id,
'user_id = ' . (int) $this->user_id,
);
$where = implode(' AND ' . $where);
if ($return)
{
return $where;
}
$sql = 'UPDATE ' . NOTIFICATIONS_TABLE . '
SET unread = ' . (bool) $unread . '
WHERE ' . $where;
$this->db->sql_query($sql);
}
/**
* Function for preparing the data for insertion in an SQL query
* (The service handles insertion)
@ -184,11 +158,14 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
{
// Defaults
$data = array_merge(array(
'item_type' => $this->get_item_type(),
'time' => time(),
'unread' => true,
'item_id' => static::get_item_id($type_data),
'item_type' => $this->get_item_type(),
'item_parent_id' => static::get_item_parent_id($type_data),
'data' => array(),
'time' => time(),
'unread' => true,
'data' => array(),
), $this->data);
$data['data'] = serialize($data['data']);
@ -219,49 +196,8 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
}
/**
* 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
* -------------- Fall back functions -------------------
*/
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;
}
protected function _get_avatar($user_id)
{
$user = $this->service->get_user($user_id);
if (!function_exists('get_user_avatar'))
{
include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
}
return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height'], $user['username'], false, 'notifications-avatar');
}
/**
* Get the formatted title of this notification (fall-back)
@ -306,4 +242,86 @@ abstract class phpbb_notifications_type_base implements phpbb_notifications_type
{
return;
}
/**
* -------------- Helper functions -------------------
*/
/**
* 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 avatar helper
*
* @param int $user_id
* @return string
*/
protected function _get_avatar($user_id)
{
$user = $this->service->get_user($user_id);
if (!function_exists('get_user_avatar'))
{
include($this->phpbb_root_path . 'includes/functions_display.' . $this->php_ext);
}
return get_user_avatar($user['user_avatar'], $user['user_avatar_type'], $user['user_avatar_width'], $user['user_avatar_height'], $user['username'], false, 'notifications-avatar');
}
/**
* Mark this item read/unread helper
*
* @param bool $unread Unread (True/False) (Default: False)
* @param bool $return True to return a string containing the SQL code to update this item, False to execute it (Default: False)
* @return string
*/
protected function mark($unread = true, $return = false)
{
$where = array(
'item_type = ' . $this->db->sql_escape($this->item_type),
'item_id = ' . (int) $this->item_id,
'user_id = ' . (int) $this->user_id,
);
$where = implode(' AND ' . $where);
if ($return)
{
return $where;
}
$sql = 'UPDATE ' . NOTIFICATIONS_TABLE . '
SET unread = ' . (bool) $unread . '
WHERE ' . $where;
$this->db->sql_query($sql);
}
}

View File

@ -44,6 +44,17 @@ class phpbb_notifications_type_pm extends phpbb_notifications_type_base
return (int) $pm['msg_id'];
}
/**
* Get the id of the parent
*
* @param array $pm The data from the pm
*/
public static function get_item_parent_id($pm)
{
// No parent
return 0;
}
/**
* Find the users who want to receive notifications
*
@ -164,8 +175,6 @@ class phpbb_notifications_type_pm extends phpbb_notifications_type_base
*/
public function create_insert_array($pm)
{
$this->item_id = $pm['msg_id'];
$this->set_data('from_user_id', $pm['from_user_id']);
$this->set_data('message_subject', $pm['message_subject']);

View File

@ -35,7 +35,7 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
}
/**
* Get the id of the
* Get the id of the item
*
* @param array $post The data from the post
*/
@ -44,6 +44,16 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
return (int) $post['post_id'];
}
/**
* Get the id of the parent
*
* @param array $post The data from the post
*/
public static function get_item_parent_id($post)
{
return (int) $post['topic_id'];
}
/**
* Find the users who want to receive notifications
*
@ -197,10 +207,6 @@ class phpbb_notifications_type_post extends phpbb_notifications_type_base
*/
public function create_insert_array($post)
{
$this->item_id = $post['post_id'];
$this->set_data('topic_id', $post['topic_id']);
$this->set_data('poster_id', $post['poster_id']);
$this->set_data('topic_title', $post['topic_title']);

View File

@ -183,8 +183,6 @@ class phpbb_notifications_type_quote extends phpbb_notifications_type_post
$add_notifications[$user_id] = $notifications[$user_id];
}
var_dump($old_notifications, $notifications, $remove_notifications, $add_notifications);
// Add the necessary notifications
$service->add_notifications_for_users(self::get_item_type(), $post, $add_notifications);

View File

@ -35,7 +35,7 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
}
/**
* Get the id of the
* Get the id of the item
*
* @param array $post The data from the post
*/
@ -44,6 +44,16 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
return (int) $post['topic_id'];
}
/**
* Get the id of the parent
*
* @param array $post The data from the post
*/
public static function get_item_parent_id($post)
{
return (int) $post['forum_id'];
}
/**
* Find the users who want to receive notifications
*
@ -166,7 +176,7 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
*/
public function get_url()
{
return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "f={$this->get_data('forum_id')}&amp;t={$this->item_id}");
return append_sid($this->phpbb_root_path . 'viewtopic.' . $this->php_ext, "f={$this->item_parent_id}&amp;t={$this->item_id}");
}
/**
@ -176,7 +186,7 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
*/
public function get_full_url()
{
return generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->get_data('forum_id')}&t={$this->item_id}";
return generate_board_url() . "/viewtopic.{$this->php_ext}?f={$this->item_parent_id}&t={$this->item_id}";
}
/**
@ -199,8 +209,6 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
*/
public function create_insert_array($post)
{
$this->item_id = $post['topic_id'];
$this->set_data('poster_id', $post['poster_id']);
$this->set_data('topic_title', $post['topic_title']);
@ -209,8 +217,6 @@ class phpbb_notifications_type_topic extends phpbb_notifications_type_base
$this->set_data('forum_name', $post['forum_name']);
$this->set_data('forum_id', $post['forum_id']);
return parent::create_insert_array($post);
}
}

View File

@ -1109,6 +1109,7 @@ function database_update_info()
'COLUMNS' => array(
'item_type' => array('VCHAR:25', ''),
'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0),
'unread' => array('BOOL', 1),
'time' => array('TIMESTAMP', 1),
@ -1122,8 +1123,10 @@ function database_update_info()
'KEYS' => array(
'item_type' => array('INDEX', 'item_type'),
'item_id' => array('INDEX', 'item_id'),
'item_pid' => array('INDEX', 'item_parent_id'),
'user_id' => array('INDEX', 'user_id'),
'time' => array('INDEX', 'time'),
'unread' => array('INDEX', 'unread'),
),
),
USER_NOTIFICATIONS_TABLE => array(

View File

@ -136,7 +136,7 @@
<div id="notification_list" style="display: block; position: absolute; width: 330px; background-color: #FFFFFF; z-index: 1;">
<ul style="list-style-type: none;">
<!-- BEGIN notifications -->
<li style="margin: 10px;">
<li style="padding: 10px; width: 310px;<!-- IF notifications.UNREAD --> background-color: grey;<!-- ENDIF -->">
<a href="{notifications.URL}" style="text-decoration: none;">
{notifications.AVATAR}
<div>