aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes/notification
diff options
context:
space:
mode:
Diffstat (limited to 'phpBB/includes/notification')
-rw-r--r--phpBB/includes/notification/exception.php29
-rw-r--r--phpBB/includes/notification/manager.php253
-rw-r--r--phpBB/includes/notification/method/base.php2
-rw-r--r--phpBB/includes/notification/method/email.php82
-rw-r--r--phpBB/includes/notification/method/jabber.php26
-rw-r--r--phpBB/includes/notification/method/messenger_base.php100
-rw-r--r--phpBB/includes/notification/type/base.php22
-rw-r--r--phpBB/includes/notification/type/bookmark.php9
-rw-r--r--phpBB/includes/notification/type/post.php25
-rw-r--r--phpBB/includes/notification/type/post_in_queue.php11
-rw-r--r--phpBB/includes/notification/type/quote.php23
-rw-r--r--phpBB/includes/notification/type/topic.php2
-rw-r--r--phpBB/includes/notification/type/topic_in_queue.php11
13 files changed, 369 insertions, 226 deletions
diff --git a/phpBB/includes/notification/exception.php b/phpBB/includes/notification/exception.php
new file mode 100644
index 0000000000..a52d6fdc57
--- /dev/null
+++ b/phpBB/includes/notification/exception.php
@@ -0,0 +1,29 @@
+<?php
+/**
+*
+* @package notifications
+* @copyright (c) 2013 phpBB Group
+* @license http://opensource.org/licenses/gpl-license.php GNU Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Notifications exception
+*
+* @package notifications
+*/
+class phpbb_notification_exception extends \Exception
+{
+ public function __toString()
+ {
+ return $this->getMessage();
+ }
+}
diff --git a/phpBB/includes/notification/manager.php b/phpBB/includes/notification/manager.php
index ff83d4bb37..97833710c0 100644
--- a/phpBB/includes/notification/manager.php
+++ b/phpBB/includes/notification/manager.php
@@ -36,6 +36,9 @@ class phpbb_notification_manager
/** @var phpbb_db_driver */
protected $db;
+ /** @var phpbb_cache_service */
+ protected $cache;
+
/** @var phpbb_user */
protected $user;
@@ -70,7 +73,7 @@ class phpbb_notification_manager
* @param string $user_notifications_table
* @return phpbb_notification_manager
*/
- public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
+ public function __construct($notification_types, $notification_methods, $phpbb_container, phpbb_user_loader $user_loader, phpbb_db_driver $db, phpbb_cache_service $cache, $user, $phpbb_root_path, $php_ext, $notification_types_table, $notifications_table, $user_notifications_table)
{
$this->notification_types = $notification_types;
$this->notification_methods = $notification_methods;
@@ -78,6 +81,7 @@ class phpbb_notification_manager
$this->user_loader = $user_loader;
$this->db = $db;
+ $this->cache = $cache;
$this->user = $user;
$this->phpbb_root_path = $phpbb_root_path;
@@ -145,7 +149,7 @@ class phpbb_notification_manager
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . '
AND n.notification_read = 0
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
$unread_count = (int) $this->db->sql_fetchfield('unread_count', $result);
@@ -158,7 +162,7 @@ class phpbb_notification_manager
$sql = 'SELECT COUNT(n.notification_id) AS total_count
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . '
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
$total_count = (int) $this->db->sql_fetchfield('total_count', $result);
@@ -170,11 +174,11 @@ class phpbb_notification_manager
$rowset = array();
// Get the main notifications
- $sql = 'SELECT n.*
+ $sql = 'SELECT n.*, nt.notification_type_name
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] .
(($options['notification_id']) ? ((is_array($options['notification_id'])) ? ' AND ' . $this->db->sql_in_set('n.notification_id', $options['notification_id']) : ' AND n.notification_id = ' . (int) $options['notification_id']) : '') . '
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1
ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
$result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
@@ -188,12 +192,12 @@ class phpbb_notification_manager
// Get all unread notifications
if ($unread_count && $options['all_unread'] && !empty($rowset))
{
- $sql = 'SELECT n.*
+ $sql = 'SELECT n.*, nt.notification_type_name
FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
WHERE n.user_id = ' . (int) $options['user_id'] . '
AND n.notification_read = 0
AND ' . $this->db->sql_in_set('n.notification_id', array_keys($rowset), true) . '
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1
ORDER BY n.' . $this->db->sql_escape($options['order_by']) . ' ' . $this->db->sql_escape($options['order_dir']);
$result = $this->db->sql_query_limit($sql, $options['limit'], $options['start']);
@@ -207,17 +211,17 @@ class phpbb_notification_manager
foreach ($rowset as $row)
{
- $notification = $this->get_item_type_class($row['item_type'], $row);
+ $notification = $this->get_item_type_class($row['notification_type_name'], $row);
// Array of user_ids to query all at once
$user_ids = array_merge($user_ids, $notification->users_to_query());
// Some notification types also require querying additional tables themselves
- if (!isset($load_special[$row['item_type']]))
+ if (!isset($load_special[$row['notification_type_name']]))
{
- $load_special[$row['item_type']] = array();
+ $load_special[$row['notification_type_name']] = array();
}
- $load_special[$row['item_type']] = array_merge($load_special[$row['item_type']], $notification->get_load_special());
+ $load_special[$row['notification_type_name']] = array_merge($load_special[$row['notification_type_name']], $notification->get_load_special());
$notifications[$row['notification_id']] = $notification;
}
@@ -243,19 +247,22 @@ class phpbb_notification_manager
/**
* Mark notifications read
*
- * @param bool|string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
+ * @param bool|string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types). False to mark read for all item types
* @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)
+ public function mark_notifications_read($notification_type_name, $item_id, $user_id, $time = false)
{
$time = ($time !== false) ? $time : time();
$sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1
WHERE notification_time <= " . (int) $time .
- (($item_type !== false) ? ' AND ' . (is_array($item_type) ? $this->db->sql_in_set('item_type', $item_type) : " item_type = '" . $this->db->sql_escape($item_type) . "'") : '') .
+ (($notification_type_name !== false) ? ' AND ' .
+ (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name))
+ : '') .
+ (($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);
}
@@ -263,29 +270,21 @@ class phpbb_notification_manager
/**
* Mark notifications read from a parent identifier
*
- * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @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)
+ public function mark_notifications_read_by_parent($notification_type_name, $item_parent_id, $user_id, $time = false)
{
- if (is_array($item_type))
- {
- foreach ($item_type as $type)
- {
- $this->mark_notifications_read_by_parent($type, $item_parent_id, $user_id, $time);
- }
-
- return;
- }
-
$time = ($time !== false) ? $time : time();
$sql = 'UPDATE ' . $this->notifications_table . "
SET notification_read = 1
- WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
- AND notification_time <= " . (int) $time .
+ WHERE notification_time <= " . (int) $time .
+ (($notification_type_name !== false) ? ' AND ' .
+ (is_array($notification_type_name) ? $this->db->sql_in_set('notification_type_id', $this->get_notification_type_ids($notification_type_name)) : 'notification_type_id = ' . $this->get_notification_type_id($notification_type_name))
+ : '') .
(($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);
@@ -311,7 +310,7 @@ class phpbb_notification_manager
/**
* Add a notification
*
- * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* Note: If you send an array of types, any user who could receive multiple notifications from this single item will only receive
* a single notification. If they MUST receive multiple notifications, call this function multiple times instead of sending an array
* @param array $data Data specific for this type that will be inserted
@@ -319,18 +318,18 @@ class phpbb_notification_manager
* ignore_users array of data to specify which users should not receive certain types of notifications
* @return array Information about what users were notified and how they were notified
*/
- public function add_notifications($item_type, $data, array $options = array())
+ public function add_notifications($notification_type_name, $data, array $options = array())
{
$options = array_merge(array(
'ignore_users' => array(),
), $options);
- if (is_array($item_type))
+ if (is_array($notification_type_name))
{
$notified_users = array();
$temp_options = $options;
- foreach ($item_type as $type)
+ foreach ($notification_type_name as $type)
{
$temp_options['ignore_users'] = $options['ignore_users'] + $notified_users;
$notified_users += $this->add_notifications($type, $data, $temp_options);
@@ -339,12 +338,12 @@ class phpbb_notification_manager
return $notified_users;
}
- $item_id = $this->get_item_type_class($item_type)->get_item_id($data);
+ $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
// find out which users want to receive this type of notification
- $notify_users = $this->get_item_type_class($item_type)->find_users_for_notification($data, $options);
+ $notify_users = $this->get_item_type_class($notification_type_name)->find_users_for_notification($data, $options);
- $this->add_notifications_for_users($item_type, $data, $notify_users);
+ $this->add_notifications_for_users($notification_type_name, $data, $notify_users);
return $notify_users;
}
@@ -352,15 +351,15 @@ class phpbb_notification_manager
/**
* Add a notification for specific users
*
- * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param array $data Data specific for this type that will be inserted
* @param array $notify_users User list to notify
*/
- public function add_notifications_for_users($item_type, $data, $notify_users)
+ public function add_notifications_for_users($notification_type_name, $data, $notify_users)
{
- if (is_array($item_type))
+ if (is_array($notification_type_name))
{
- foreach ($item_type as $type)
+ foreach ($notification_type_name as $type)
{
$this->add_notifications_for_users($type, $data, $notify_users);
}
@@ -368,28 +367,12 @@ class phpbb_notification_manager
return;
}
- $sql = 'SELECT notification_type
- FROM ' . $this->notification_types_table . "
- WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
- $result = $this->db->sql_query($sql);
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
- if ($this->db->sql_fetchrow($result) === false)
- {
- // Does not exist in the database, must add the item type
- $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
- 'notification_type' => $item_type,
- 'notification_type_enabled' => 1,
- ));
- $this->db->sql_query($sql);
- }
-
- $this->db->sql_freeresult($result);
-
- $item_id = $this->get_item_type_class($item_type)->get_item_id($data);
+ $item_id = $this->get_item_type_class($notification_type_name)->get_item_id($data);
$user_ids = array();
$notification_objects = $notification_methods = array();
- $new_rows = array();
// Never send notifications to the anonymous user!
unset($notify_users[ANONYMOUS]);
@@ -397,10 +380,10 @@ class phpbb_notification_manager
// Make sure not to send new notifications to users who've already been notified about this item
// This may happen when an item was added, but now new users are able to see the item
$sql = 'SELECT n.user_id
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
- WHERE n.item_type = '" . $this->db->sql_escape($item_type) . "'
- AND n.item_id = " . (int) $item_id . '
- AND nt.notification_type = n.item_type
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $notification_type_id . '
+ AND n.item_id = ' . (int) $item_id . '
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@@ -415,19 +398,21 @@ class phpbb_notification_manager
}
// Allow notifications to perform actions before creating the insert array (such as run a query to cache some data needed for all notifications)
- $notification = $this->get_item_type_class($item_type);
+ $notification = $this->get_item_type_class($notification_type_name);
$pre_create_data = $notification->pre_create_insert_array($data, $notify_users);
unset($notification);
+ $insert_buffer = new phpbb_db_sql_insert_buffer($this->db, $this->notifications_table);
+
// Go through each user so we can insert a row in the DB and then notify them by their desired means
foreach ($notify_users as $user => $methods)
{
- $notification = $this->get_item_type_class($item_type);
+ $notification = $this->get_item_type_class($notification_type_name);
$notification->user_id = (int) $user;
- // Store the creation array in our new rows that will be inserted later
- $new_rows[] = $notification->create_insert_array($data, $pre_create_data);
+ // Insert notification row using buffer.
+ $insert_buffer->insert($notification->create_insert_array($data, $pre_create_data));
// Users are needed to send notifications
$user_ids = array_merge($user_ids, $notification->users_to_query());
@@ -447,8 +432,7 @@ class phpbb_notification_manager
}
}
- // insert into the db
- $this->db->sql_multi_insert($this->notifications_table, $new_rows);
+ $insert_buffer->flush();
// We need to load all of the users to send notifications
$this->user_loader->load_users($user_ids);
@@ -463,14 +447,14 @@ class phpbb_notification_manager
/**
* Update a notification
*
- * @param string|array $item_type Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $data is identical for the specified types)
* @param array $data Data specific for this type that will be updated
*/
- public function update_notifications($item_type, $data)
+ public function update_notifications($notification_type_name, $data)
{
- if (is_array($item_type))
+ if (is_array($notification_type_name))
{
- foreach ($item_type as $type)
+ foreach ($notification_type_name as $type)
{
$this->update_notifications($type, $data);
}
@@ -478,7 +462,7 @@ class phpbb_notification_manager
return;
}
- $notification = $this->get_item_type_class($item_type);
+ $notification = $this->get_item_type_class($notification_type_name);
// Allow the notifications class to over-ride the update_notifications functionality
if (method_exists($notification, 'update_notifications'))
@@ -490,28 +474,29 @@ class phpbb_notification_manager
}
}
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
$item_id = $notification->get_item_id($data);
$update_array = $notification->create_update_array($data);
$sql = 'UPDATE ' . $this->notifications_table . '
- SET ' . $this->db->sql_build_array('UPDATE', $update_array) . "
- WHERE item_type = '" . $this->db->sql_escape($item_type) . "'
- AND item_id = " . (int) $item_id;
+ SET ' . $this->db->sql_build_array('UPDATE', $update_array) . '
+ WHERE notification_type_id = ' . (int) $notification_type_id . '
+ AND item_id = ' . (int) $item_id;
$this->db->sql_query($sql);
}
/**
* Delete a notification
*
- * @param string|array $item_type Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
+ * @param string|array $notification_type_name Type identifier or array of item types (only acceptable if the $item_id is identical for the specified types)
* @param int|array $item_id Identifier within the type (or array of ids)
* @param array $data Data specific for this type that will be updated
*/
- public function delete_notifications($item_type, $item_id)
+ public function delete_notifications($notification_type_name, $item_id)
{
- if (is_array($item_type))
+ if (is_array($notification_type_name))
{
- foreach ($item_type as $type)
+ foreach ($notification_type_name as $type)
{
$this->delete_notifications($type, $item_id);
}
@@ -519,9 +504,11 @@ class phpbb_notification_manager
return;
}
- $sql = 'DELETE FROM ' . $this->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);
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
+
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id . '
+ AND ' . (is_array($item_id) ? $this->db->sql_in_set('item_id', $item_id) : 'item_id = ' . (int) $item_id);
$this->db->sql_query($sql);
}
@@ -654,7 +641,8 @@ class phpbb_notification_manager
{
if ($method !== '')
{
- $this->add_subscription($item_type, $item_type, '', $user_id);
+ // Make sure to subscribe them to the base subscription
+ $this->add_subscription($item_type, $item_id, '', $user_id);
}
$user_id = ($user_id === false) ? $this->user->data['user_id'] : $user_id;
@@ -754,13 +742,13 @@ class phpbb_notification_manager
* is disabled so that all those notifications are hidden and do not
* cause errors
*
- * @param string $item_type Type identifier of the subscription
+ * @param string $notification_type_name Type identifier of the subscription
*/
- public function disable_notifications($item_type)
+ public function disable_notifications($notification_type_name)
{
$sql = 'UPDATE ' . $this->notification_types_table . "
SET notification_type_enabled = 0
- WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
+ WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
$this->db->sql_query($sql);
}
@@ -770,17 +758,21 @@ class phpbb_notification_manager
* This should be called when an extension which has notification types
* is purged so that all those notifications are removed
*
- * @param string $item_type Type identifier of the subscription
+ * @param string $notification_type_name Type identifier of the subscription
*/
- public function purge_notifications($item_type)
+ public function purge_notifications($notification_type_name)
{
- $sql = 'DELETE FROM ' . $this->notifications_table . "
- WHERE item_type = '" . $this->db->sql_escape($item_type) . "'";
+ $notification_type_id = $this->get_notification_type_id($notification_type_name);
+
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql);
- $sql = 'DELETE FROM ' . $this->notification_types_table . "
- WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
+ $sql = 'DELETE FROM ' . $this->notification_types_table . '
+ WHERE notification_type_id = ' . (int) $notification_type_id;
$this->db->sql_query($sql);
+
+ $this->cache->destroy('notification_type_ids');
}
/**
@@ -790,13 +782,13 @@ class phpbb_notification_manager
* that was disabled is re-enabled so that all those notifications that
* were hidden are shown again
*
- * @param string $item_type Type identifier of the subscription
+ * @param string $notification_type_name Type identifier of the subscription
*/
- public function enable_notifications($item_type)
+ public function enable_notifications($notification_type_name)
{
$sql = 'UPDATE ' . $this->notification_types_table . "
SET notification_type_enabled = 1
- WHERE notification_type = '" . $this->db->sql_escape($item_type) . "'";
+ WHERE notification_type_name = '" . $this->db->sql_escape($notification_type_name) . "'";
$this->db->sql_query($sql);
}
@@ -815,11 +807,11 @@ class phpbb_notification_manager
/**
* Helper to get the notifications item type class and set it up
*/
- public function get_item_type_class($item_type, $data = array())
+ public function get_item_type_class($notification_type_name, $data = array())
{
- $item_type = (strpos($item_type, 'notification.type.') === 0) ? $item_type : 'notification.type.' . $item_type;
+ $notification_type_name = (strpos($notification_type_name, 'notification.type.') === 0) ? $notification_type_name : 'notification.type.' . $notification_type_name;
- $item = $this->load_object($item_type);
+ $item = $this->load_object($notification_type_name);
$item->set_initial_data($data);
@@ -850,4 +842,69 @@ class phpbb_notification_manager
return $object;
}
+
+ /**
+ * Get the notification type id from the name
+ *
+ * @param string $notification_type_name The name
+ * @return int the notification_type_id
+ */
+ public function get_notification_type_id($notification_type_name)
+ {
+ $notification_type_ids = $this->cache->get('notification_type_ids');
+
+ if ($notification_type_ids === false)
+ {
+ $notification_type_ids = array();
+
+ $sql = 'SELECT notification_type_id, notification_type_name
+ FROM ' . $this->notification_types_table;
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $notification_type_ids[$row['notification_type_name']] = (int) $row['notification_type_id'];
+ }
+ $this->db->sql_freeresult($result);
+
+ $this->cache->put('notification_type_ids', $notification_type_ids);
+ }
+
+ if (!isset($notification_type_ids[$notification_type_name]))
+ {
+ if (!isset($this->notification_types[$notification_type_name]) && !isset($this->notification_types['notification.type.' . $notification_type_name]))
+ {
+ throw new phpbb_notification_exception($this->user->lang('NOTIFICATION_TYPE_NOT_EXIST', $notification_type_name));
+ }
+
+ $sql = 'INSERT INTO ' . $this->notification_types_table . ' ' . $this->db->sql_build_array('INSERT', array(
+ 'notification_type_name' => $notification_type_name,
+ 'notification_type_enabled' => 1,
+ ));
+ $this->db->sql_query($sql);
+
+ $notification_type_ids[$notification_type_name] = (int) $this->db->sql_nextid();
+
+ $this->cache->put('notification_type_ids', $notification_type_ids);
+ }
+
+ return $notification_type_ids[$notification_type_name];
+ }
+
+ /**
+ * Get notification type ids (as an array)
+ *
+ * @param array $notification_type_names Array of strings
+ * @return array Array of integers
+ */
+ public function get_notification_type_ids(array $notification_type_names)
+ {
+ $notification_type_ids = array();
+
+ foreach ($notification_type_names as $name)
+ {
+ $notification_type_ids[$name] = $this->get_notification_type_id($name);
+ }
+
+ return $notification_type_ids;
+ }
}
diff --git a/phpBB/includes/notification/method/base.php b/phpBB/includes/notification/method/base.php
index 22418c9be8..b633956d01 100644
--- a/phpBB/includes/notification/method/base.php
+++ b/phpBB/includes/notification/method/base.php
@@ -30,7 +30,7 @@ abstract class phpbb_notification_method_base implements phpbb_notification_meth
/** @var phpbb_db_driver */
protected $db;
- /** @var phpbb_cache_service */
+ /** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_template */
diff --git a/phpBB/includes/notification/method/email.php b/phpBB/includes/notification/method/email.php
index 4a7fea6df3..571b0ec656 100644
--- a/phpBB/includes/notification/method/email.php
+++ b/phpBB/includes/notification/method/email.php
@@ -21,7 +21,7 @@ if (!defined('IN_PHPBB'))
*
* @package notifications
*/
-class phpbb_notification_method_email extends phpbb_notification_method_base
+class phpbb_notification_method_email extends phpbb_notification_method_messenger_base
{
/**
* Get notification method name
@@ -34,26 +34,12 @@ class phpbb_notification_method_email extends phpbb_notification_method_base
}
/**
- * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication)
- *
- * @var mixed
- */
- protected $notify_method = NOTIFY_EMAIL;
-
- /**
- * Base directory to prepend to the email template name
- *
- * @var string
- */
- protected $email_template_base_dir = '';
-
- /**
* Is this method available for the user?
* This is checked on the notifications options
*/
public function is_available()
{
- return (bool) $this->config['email_enable'];
+ return $this->config['email_enable'] && $this->user->data['user_email'];
}
/**
@@ -61,68 +47,6 @@ class phpbb_notification_method_email extends phpbb_notification_method_base
*/
public function notify()
{
- if (!sizeof($this->queue))
- {
- return;
- }
-
- // Load all users we want to notify (we need their email address)
- $user_ids = $users = array();
- foreach ($this->queue as $notification)
- {
- $user_ids[] = $notification->user_id;
- }
-
- // We do not send emails to banned users
- if (!function_exists('phpbb_get_banned_user_ids'))
- {
- include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
- }
- $banned_users = phpbb_get_banned_user_ids($user_ids);
-
- // Load all the users we need
- $this->user_loader->load_users($user_ids);
-
- // Load the messenger
- if (!class_exists('messenger'))
- {
- include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext);
- }
- $messenger = new messenger();
- $board_url = generate_board_url();
-
- // Time to go through the queue and send emails
- foreach ($this->queue as $notification)
- {
- if ($notification->get_email_template() === false)
- {
- continue;
- }
-
- $user = $this->user_loader->get_user($notification->user_id);
-
- if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users))
- {
- continue;
- }
-
- $messenger->template($this->email_template_base_dir . $notification->get_email_template(), $user['user_lang']);
-
- $messenger->to($user['user_email'], $user['username']);
-
- $messenger->assign_vars(array_merge(array(
- 'USERNAME' => $user['username'],
-
- 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications',
- ), $notification->get_email_template_variables()));
-
- $messenger->send($this->notify_method);
- }
-
- // Save the queue in the messenger class (has to be called or these emails could be lost?)
- $messenger->save_queue();
-
- // We're done, empty the queue
- $this->empty_queue();
+ return $this->notify_using_messenger(NOTIFY_EMAIL);
}
}
diff --git a/phpBB/includes/notification/method/jabber.php b/phpBB/includes/notification/method/jabber.php
index 863846b8a5..d3b756d020 100644
--- a/phpBB/includes/notification/method/jabber.php
+++ b/phpBB/includes/notification/method/jabber.php
@@ -21,7 +21,7 @@ if (!defined('IN_PHPBB'))
*
* @package notifications
*/
-class phpbb_notification_method_jabber extends phpbb_notification_method_email
+class phpbb_notification_method_jabber extends phpbb_notification_method_messenger_base
{
/**
* Get notification method name
@@ -34,20 +34,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email
}
/**
- * Notify method (since jabber gets sent through the same messenger, we let the jabber class inherit from this to reduce code duplication)
- *
- * @var mixed
- */
- protected $notify_method = NOTIFY_IM;
-
- /**
- * Base directory to prepend to the email template name
- *
- * @var string
- */
- protected $email_template_base_dir = 'short/';
-
- /**
* Is this method available for the user?
* This is checked on the notifications options
*/
@@ -62,7 +48,13 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email
*/
public function global_available()
{
- return ($this->config['jab_enable'] && @extension_loaded('xml'));
+ return !(
+ empty($this->config['jab_enable']) ||
+ empty($this->config['jab_host']) ||
+ empty($this->config['jab_username']) ||
+ empty($this->config['jab_password']) ||
+ !@extension_loaded('xml')
+ );
}
public function notify()
@@ -72,6 +64,6 @@ class phpbb_notification_method_jabber extends phpbb_notification_method_email
return;
}
- return parent::notify();
+ return $this->notify_using_messenger(NOTIFY_IM, 'short/');
}
}
diff --git a/phpBB/includes/notification/method/messenger_base.php b/phpBB/includes/notification/method/messenger_base.php
new file mode 100644
index 0000000000..4966aa94bc
--- /dev/null
+++ b/phpBB/includes/notification/method/messenger_base.php
@@ -0,0 +1,100 @@
+<?php
+/**
+*
+* @package notifications
+* @copyright (c) 2012 phpBB Group
+* @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+/**
+* Abstract notification method handling email and jabber notifications
+* using the phpBB messenger.
+*
+* @package notifications
+*/
+abstract class phpbb_notification_method_messenger_base extends phpbb_notification_method_base
+{
+ /**
+ * Notify using phpBB messenger
+ *
+ * @param int $notify_method Notify method for messenger (e.g. NOTIFY_IM)
+ * @param string $template_dir_prefix Base directory to prepend to the email template name
+ *
+ * @return null
+ */
+ protected function notify_using_messenger($notify_method, $template_dir_prefix = '')
+ {
+ if (empty($this->queue))
+ {
+ return;
+ }
+
+ // Load all users we want to notify (we need their email address)
+ $user_ids = $users = array();
+ foreach ($this->queue as $notification)
+ {
+ $user_ids[] = $notification->user_id;
+ }
+
+ // We do not send emails to banned users
+ if (!function_exists('phpbb_get_banned_user_ids'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
+ }
+ $banned_users = phpbb_get_banned_user_ids($user_ids);
+
+ // Load all the users we need
+ $this->user_loader->load_users($user_ids);
+
+ // Load the messenger
+ if (!class_exists('messenger'))
+ {
+ include($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext);
+ }
+ $messenger = new messenger();
+ $board_url = generate_board_url();
+
+ // Time to go through the queue and send emails
+ foreach ($this->queue as $notification)
+ {
+ if ($notification->get_email_template() === false)
+ {
+ continue;
+ }
+
+ $user = $this->user_loader->get_user($notification->user_id);
+
+ if ($user['user_type'] == USER_IGNORE || in_array($notification->user_id, $banned_users))
+ {
+ continue;
+ }
+
+ $messenger->template($template_dir_prefix . $notification->get_email_template(), $user['user_lang']);
+
+ $messenger->set_addresses($user);
+
+ $messenger->assign_vars(array_merge(array(
+ 'USERNAME' => $user['username'],
+
+ 'U_NOTIFICATION_SETTINGS' => generate_board_url() . '/ucp.' . $this->php_ext . '?i=ucp_notifications',
+ ), $notification->get_email_template_variables()));
+
+ $messenger->send($notify_method);
+ }
+
+ // Save the queue in the messenger class (has to be called or these emails could be lost?)
+ $messenger->save_queue();
+
+ // We're done, empty the queue
+ $this->empty_queue();
+ }
+}
diff --git a/phpBB/includes/notification/type/base.php b/phpBB/includes/notification/type/base.php
index 600ef7c965..46517f1c9b 100644
--- a/phpBB/includes/notification/type/base.php
+++ b/phpBB/includes/notification/type/base.php
@@ -30,7 +30,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
/** @var phpbb_db_driver */
protected $db;
- /** @var phpbb_cache_service */
+ /** @var phpbb_cache_driver_interface */
protected $cache;
/** @var phpbb_template */
@@ -69,10 +69,18 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
public static $notification_option = false;
/**
+ * The notification_type_id, set upon creation of the class
+ * This is the notification_type_id from the notification_types table
+ *
+ * @var int
+ */
+ protected $notification_type_id;
+
+ /**
* Indentification data
- * item_type - Type of the item (translates to the notification type)
- * item_id - ID of the item (e.g. post_id, msg_id)
- * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc)
+ * notification_type_id - ID of the item type (auto generated, from notification types table)
+ * item_id - ID of the item (e.g. post_id, msg_id)
+ * item_parent_id - Parent item id (ex: for topic => forum_id, for post => topic_id, etc)
* user_id
* notification_read
* notification_time
@@ -124,6 +132,8 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
public function set_notification_manager(phpbb_notification_manager $notification_manager)
{
$this->notification_manager = $notification_manager;
+
+ $this->notification_type_id = $this->notification_manager->get_notification_type_id($this->get_type());
}
/**
@@ -211,7 +221,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
// Defaults
$this->data = array_merge(array(
'item_id' => static::get_item_id($type_data),
- 'item_type' => $this->get_type(),
+ 'notification_type_id' => $this->notification_type_id,
'item_parent_id' => static::get_item_parent_id($type_data),
'notification_time' => time(),
@@ -460,7 +470,7 @@ abstract class phpbb_notification_type_base implements phpbb_notification_type_i
$this->notification_read = (bool) !$unread;
$where = array(
- "item_type = '" . $this->db->sql_escape($this->item_type) . "'",
+ 'notification_type_id = ' . (int) $this->notification_type_id,
'item_id = ' . (int) $this->item_id,
'user_id = ' . (int) $this->user_id,
);
diff --git a/phpBB/includes/notification/type/bookmark.php b/phpBB/includes/notification/type/bookmark.php
index 4e48a967d0..ae2e75d3eb 100644
--- a/phpBB/includes/notification/type/bookmark.php
+++ b/phpBB/includes/notification/type/bookmark.php
@@ -89,6 +89,7 @@ class phpbb_notification_type_bookmark extends phpbb_notification_type_post
{
return array();
}
+ sort($users);
$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
@@ -102,11 +103,11 @@ class phpbb_notification_type_bookmark extends phpbb_notification_type_post
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
- WHERE n.item_type = '" . $this->get_type() . "'
- AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
+ AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
diff --git a/phpBB/includes/notification/type/post.php b/phpBB/includes/notification/type/post.php
index ddfa720e5e..9207fd866e 100644
--- a/phpBB/includes/notification/type/post.php
+++ b/phpBB/includes/notification/type/post.php
@@ -106,11 +106,26 @@ class phpbb_notification_type_post extends phpbb_notification_type_base
}
$this->db->sql_freeresult($result);
+ $sql = 'SELECT user_id
+ FROM ' . FORUMS_WATCH_TABLE . '
+ WHERE forum_id = ' . (int) $post['forum_id'] . '
+ AND notify_status = ' . NOTIFY_YES . '
+ AND user_id <> ' . (int) $post['poster_id'];
+ $result = $this->db->sql_query($sql);
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $users[] = $row['user_id'];
+ }
+ $this->db->sql_freeresult($result);
+
if (empty($users))
{
return array();
}
+ $users = array_unique($users);
+ sort($users);
+
$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
if (empty($auth_read))
@@ -123,11 +138,11 @@ class phpbb_notification_type_post extends phpbb_notification_type_base
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
- WHERE n.item_type = '" . $this->get_type() . "'
- AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
+ AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@@ -216,7 +231,7 @@ class phpbb_notification_type_post extends phpbb_notification_type_base
}
else
{
- $username = $this->user_loader->get_username($this->get_data('poster_id'), 'no_profile');
+ $username = $this->user_loader->get_username($this->get_data('poster_id'), 'username');
}
return array(
diff --git a/phpBB/includes/notification/type/post_in_queue.php b/phpBB/includes/notification/type/post_in_queue.php
index 9c719205e6..bc4b15cdc3 100644
--- a/phpBB/includes/notification/type/post_in_queue.php
+++ b/phpBB/includes/notification/type/post_in_queue.php
@@ -82,7 +82,7 @@ class phpbb_notification_type_post_in_queue extends phpbb_notification_type_post
'ignore_users' => array(),
), $options);
- // 0 is for global
+ // 0 is for global moderator permissions
$auth_approve = $this->auth->acl_get_list(false, $this->permission, array($post['forum_id'], 0));
if (empty($auth_approve))
@@ -101,8 +101,15 @@ class phpbb_notification_type_post_in_queue extends phpbb_notification_type_post
{
$has_permission = array_unique(array_merge($has_permission, $auth_approve[0][$this->permission]));
}
+ sort($has_permission);
- return $this->check_user_notification_options($has_permission, array_merge($options, array(
+ $auth_read = $this->auth->acl_get_list($has_permission, 'f_read', $post['forum_id']);
+ if (empty($auth_read))
+ {
+ return array();
+ }
+
+ return $this->check_user_notification_options($auth_read[$post['forum_id']]['f_read'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}
diff --git a/phpBB/includes/notification/type/quote.php b/phpBB/includes/notification/type/quote.php
index 5453b267c8..0ed13f36fb 100644
--- a/phpBB/includes/notification/type/quote.php
+++ b/phpBB/includes/notification/type/quote.php
@@ -108,6 +108,7 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
{
return array();
}
+ sort($users);
$auth_read = $this->auth->acl_get_list($users, 'f_read', $post['forum_id']);
@@ -121,11 +122,11 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
// Try to find the users who already have been notified about replies and have not read the topic since and just update their notifications
$update_notifications = array();
$sql = 'SELECT n.*
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
- WHERE n.item_type = '" . $this->get_type() . "'
- AND n.item_parent_id = " . (int) self::get_item_parent_id($post) . '
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
+ AND n.item_parent_id = ' . (int) self::get_item_parent_id($post) . '
AND n.notification_read = 0
- AND nt.notification_type = n.item_type
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@@ -153,10 +154,10 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
{
$old_notifications = array();
$sql = 'SELECT n.user_id
- FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . " nt
- WHERE n.item_type = '" . $this->get_type() . "'
- AND n.item_id = " . self::get_item_id($post) . '
- AND nt.notification_type = n.item_type
+ FROM ' . $this->notifications_table . ' n, ' . $this->notification_types_table . ' nt
+ WHERE n.notification_type_id = ' . (int) $this->notification_type_id . '
+ AND n.item_id = ' . self::get_item_id($post) . '
+ AND nt.notification_type_id = n.notification_type_id
AND nt.notification_type_enabled = 1';
$result = $this->db->sql_query($sql);
while ($row = $this->db->sql_fetchrow($result))
@@ -184,9 +185,9 @@ class phpbb_notification_type_quote extends phpbb_notification_type_post
// Remove the necessary notifications
if (!empty($remove_notifications))
{
- $sql = 'DELETE FROM ' . $this->notifications_table . "
- WHERE item_type = '" . $this->get_type() . "'
- AND item_id = " . self::get_item_id($post) . '
+ $sql = 'DELETE FROM ' . $this->notifications_table . '
+ WHERE notification_type_id = ' . (int) $this->notification_type_id . '
+ AND item_id = ' . self::get_item_id($post) . '
AND ' . $this->db->sql_in_set('user_id', $remove_notifications);
$this->db->sql_query($sql);
}
diff --git a/phpBB/includes/notification/type/topic.php b/phpBB/includes/notification/type/topic.php
index 2549b29409..22436d3fb1 100644
--- a/phpBB/includes/notification/type/topic.php
+++ b/phpBB/includes/notification/type/topic.php
@@ -178,7 +178,7 @@ class phpbb_notification_type_topic extends phpbb_notification_type_base
}
else
{
- $username = $this->user_loader->get_username($this->get_data('poster_id'), 'no_profile');
+ $username = $this->user_loader->get_username($this->get_data('poster_id'), 'username');
}
return array(
diff --git a/phpBB/includes/notification/type/topic_in_queue.php b/phpBB/includes/notification/type/topic_in_queue.php
index c501434c43..f735e10c00 100644
--- a/phpBB/includes/notification/type/topic_in_queue.php
+++ b/phpBB/includes/notification/type/topic_in_queue.php
@@ -82,7 +82,7 @@ class phpbb_notification_type_topic_in_queue extends phpbb_notification_type_top
'ignore_users' => array(),
), $options);
- // 0 is for global
+ // 0 is for global moderator permissions
$auth_approve = $this->auth->acl_get_list(false, 'm_approve', array($topic['forum_id'], 0));
if (empty($auth_approve))
@@ -101,8 +101,15 @@ class phpbb_notification_type_topic_in_queue extends phpbb_notification_type_top
{
$has_permission = array_unique(array_merge($has_permission, $auth_approve[0][$this->permission]));
}
+ sort($has_permission);
- return $this->check_user_notification_options($has_permission, array_merge($options, array(
+ $auth_read = $this->auth->acl_get_list($has_permission, 'f_read', $topic['forum_id']);
+ if (empty($auth_read))
+ {
+ return array();
+ }
+
+ return $this->check_user_notification_options($auth_read[$topic['forum_id']]['f_read'], array_merge($options, array(
'item_type' => self::$notification_option['id'],
)));
}