Skip to content

Commit

Permalink
[ticket/14754] Use dedicated table to stop receiving notifications
Browse files Browse the repository at this point in the history
PHPBB3-14754
  • Loading branch information
senky authored and marc1706 committed Mar 15, 2020
1 parent a3e0117 commit f3664b0
Show file tree
Hide file tree
Showing 6 changed files with 121 additions and 73 deletions.
6 changes: 1 addition & 5 deletions phpBB/config/default/container/services_notification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,7 @@ services:
- '@dbal.conn'
- '%core.root_path%'
- '%core.php_ext%'
- '%tables.topics_watch%'
- '%tables.topics_track%'
- '%tables.posts%'
- '%tables.forums_watch%'
- '%tables.forums_track%'
- '%tables.email_notifications%'
tags:
- { name: notification.method }

Expand Down
1 change: 1 addition & 0 deletions phpBB/config/default/container/tables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ parameters:
tables.confirm: '%core.table_prefix%confirm'
tables.disallow: '%core.table_prefix%disallow'
tables.drafts: '%core.table_prefix%drafts'
tables.email_notifications: '%core.table_prefix%email_notifications'
tables.ext: '%core.table_prefix%ext'
tables.extensions: '%core.table_prefix%extensions'
tables.extension_groups: '%core.table_prefix%extension_groups'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php
/**
*
* This file is part of the phpBB Forum Software package.
*
* @copyright (c) phpBB Limited <https://www.phpbb.com>
* @license GNU General Public License, version 2 (GPL-2.0)
*
* For full copyright and license information, please see
* the docs/CREDITS.txt file.
*
*/

namespace phpbb\db\migration\data\v32x;

class add_email_notifications_table extends \phpbb\db\migration\migration
{
static public function depends_on()
{
return array(
'\phpbb\db\migration\data\v32x\v323',
);
}

public function update_schema()
{
return array(
'add_tables' => array(
$this->table_prefix . 'email_notifications' => array(
'COLUMNS' => array(
'notification_type_id' => array('USINT', 0),
'item_id' => array('UINT', 0),
'item_parent_id' => array('UINT', 0),
'user_id' => array('UINT', 0),
),
'PRIMARY_KEY' => array('notification_type_id', 'item_id', 'item_parent_id', 'user_id'),
),
),
);
}

public function revert_schema()
{
return array(
'drop_tables' => array(
$this->table_prefix . 'email_notifications',
),
);
}
}
125 changes: 67 additions & 58 deletions phpBB/phpbb/notification/method/email.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,7 @@ class email extends \phpbb\notification\method\messenger_base
protected $db;

/** @var string */
protected $topics_watch_table;

/** @var string */
protected $topics_track_table;

/** @var string */
protected $posts_table;

/** @var string */
protected $forums_watch_table;

/** @var string */
protected $forums_track_table;
protected $email_notifications_table;

/**
* Notification Method email Constructor
Expand All @@ -55,24 +43,16 @@ class email extends \phpbb\notification\method\messenger_base
* @param \phpbb\db\driver\driver_interface $db
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $topics_watch_table
* @param string $topics_track_table
* @param string $posts_table
* @param string $forums_watch_table
* @param string $forums_track_table
* @param string $email_notifications_table
*/
public function __construct(\phpbb\user_loader $user_loader, \phpbb\user $user, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $topics_watch_table, $topics_track_table, $posts_table, $forums_watch_table, $forums_track_table)
public function __construct(\phpbb\user_loader $user_loader, \phpbb\user $user, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, $phpbb_root_path, $php_ext, $email_notifications_table)
{
parent::__construct($user_loader, $phpbb_root_path, $php_ext);

$this->user = $user;
$this->config = $config;
$this->db = $db;
$this->topics_watch_table = $topics_watch_table;
$this->topics_track_table = $topics_track_table;
$this->posts_table = $posts_table;
$this->forums_watch_table = $forums_watch_table;
$this->forums_track_table = $forums_track_table;
$this->email_notifications_table = $email_notifications_table;
}

/**
Expand Down Expand Up @@ -105,42 +85,18 @@ public function get_notified_users($notification_type_id, array $options)
{
$notified_users = array();

if ($notification_type_id == 'notification.type.post' && !empty($options['item_parent_id']))
$sql = 'SELECT user_id
FROM ' . $this->email_notifications_table . '
WHERE notification_type_id = ' . (int) $notification_type_id .
(isset($options['item_id']) ? ' AND item_id = ' . (int) $options['item_id'] : '') .
(isset($options['item_parent_id']) ? ' AND item_parent_id = ' . (int) $options['item_parent_id'] : '') .
(isset($options['user_id']) ? ' AND user_id = ' . (int) $options['user_id'] : '');
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
// Topics watch
$sql = 'SELECT tw.user_id
FROM ' . $this->topics_watch_table . ' tw
LEFT JOIN ' . $this->topics_track_table . ' tt
ON (tt.user_id = tw.user_id AND tt.topic_id = tw.topic_id)
LEFT JOIN ' . $this->posts_table . ' p
ON (p.topic_id = tw.topic_id)
WHERE tw.topic_id = ' . (int) $options['item_parent_id'] . '
AND p.post_time > tt.mark_time
HAVING COUNT(p.post_id) > 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$notified_users[$row['user_id']] = $row;
}
$this->db->sql_freeresult($result);

// Forums watch
$sql = 'SELECT fw.user_id
FROM ' . $this->forums_watch_table . ' fw
LEFT JOIN ' . $this->forums_track_table . ' ft
ON (ft.user_id = fw.user_id AND ft.forum_id = fw.forum_id)
LEFT JOIN ' . $this->posts_table . ' p
ON (p.forum_id = fw.forum_id)
WHERE p.topic_id = ' . (int) $options['item_parent_id'] . '
AND p.post_time > ft.mark_time
HAVING COUNT(p.post_id) > 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
{
$notified_users[$row['user_id']] = $row;
}
$this->db->sql_freeresult($result);
$notified_users[$row['user_id']] = $row;
}
$this->db->sql_freeresult($result);

return $notified_users;
}
Expand All @@ -150,6 +106,59 @@ public function get_notified_users($notification_type_id, array $options)
*/
public function notify()
{
$insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, $this->email_notifications_table);

/** @var \phpbb\notification\type\type_interface $notification */
foreach ($this->queue as $notification)
{
$data = $this->clean_data($notification->get_insert_array());
$insert_buffer->insert($data);
}

$insert_buffer->flush();

return $this->notify_using_messenger(NOTIFY_EMAIL);
}

/**
* {@inheritdoc}
*/
public function mark_notifications($notification_type_id, $item_id, $user_id, $time = false, $mark_read = true)
{
$sql = 'DELETE FROM ' . $this->email_notifications_table . '
WHERE ' . (($notification_type_id !== false) ? (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') .
(($item_id !== false) ? ' AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id) : '');
$this->db->sql_query($sql);
}

/**
* {@inheritdoc}
*/
public function mark_notifications_by_parent($notification_type_id, $item_parent_id, $user_id, $time = false, $mark_read = true)
{
$sql = 'DELETE FROM ' . $this->email_notifications_table . '
WHERE ' . (($notification_type_id !== false) ? (is_array($notification_type_id) ? $this->db->sql_in_set('notification_type_id', $notification_type_id) : 'notification_type_id = ' . $notification_type_id) : '') .
(($user_id !== false) ? ' AND ' . (is_array($user_id) ? $this->db->sql_in_set('user_id', $user_id) : 'user_id = ' . (int) $user_id) : '') .
(($item_parent_id !== false) ? ' AND ' . (is_array($item_parent_id) ? $this->db->sql_in_set('item_parent_id', $item_parent_id, false, true) : 'item_parent_id = ' . (int) $item_parent_id) : '');
$this->db->sql_query($sql);
}

/**
* Clean data to contain only what we need for email notifications table
*
* @param array $data Notification data
* @return array Cleaned notification data
*/
protected function clean_data(array $data)
{
$model = array(
'notification_type_id' => null,
'item_id' => null,
'item_parent_id' => null,
'user_id' => null,
);

return array_intersect_key($data, $model);
}
}
6 changes: 1 addition & 5 deletions tests/notification/base.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,7 @@ protected function setUp(): void
$phpbb_container->setParameter('tables.notifications', 'phpbb_notifications');
$phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications');
$phpbb_container->setParameter('tables.notification_types', 'phpbb_notification_types');
$phpbb_container->setParameter('tables.topics_watch', 'phpbb_topics_watch');
$phpbb_container->setParameter('tables.topics_track', 'phpbb_topics_track');
$phpbb_container->setParameter('tables.posts', 'phpbb_posts');
$phpbb_container->setParameter('tables.forums_watch', 'phpbb_forums_watch');
$phpbb_container->setParameter('tables.forums_track', 'phpbb_forums_track');
$phpbb_container->setParameter('tables.email_notifications', 'phpbb_email_notifications');

$this->notifications = new phpbb_notification_manager_helper(
array(),
Expand Down
6 changes: 1 addition & 5 deletions tests/notification/submit_post_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,7 @@ public function setUp(): void
$phpbb_container->setParameter('tables.notifications', 'phpbb_notifications');
$phpbb_container->setParameter('tables.user_notifications', 'phpbb_user_notifications');
$phpbb_container->setParameter('tables.notification_types', 'phpbb_notification_types');
$phpbb_container->setParameter('tables.topics_watch', 'phpbb_topics_watch');
$phpbb_container->setParameter('tables.topics_track', 'phpbb_topics_track');
$phpbb_container->setParameter('tables.posts', 'phpbb_posts');
$phpbb_container->setParameter('tables.forums_watch', 'phpbb_forums_watch');
$phpbb_container->setParameter('tables.forums_track', 'phpbb_forums_track');
$phpbb_container->setParameter('tables.email_notifications', 'phpbb_email_notifications');
$phpbb_container->set('content.visibility', new \phpbb\content_visibility($auth, $config, $phpbb_dispatcher, $db, $user, $phpbb_root_path, $phpEx, FORUMS_TABLE, POSTS_TABLE, TOPICS_TABLE, USERS_TABLE));
$phpbb_container->compile();

Expand Down

0 comments on commit f3664b0

Please sign in to comment.