diff --git a/config/services.yml b/config/services.yml
index b0343ebc5..7312bc6e4 100644
--- a/config/services.yml
+++ b/config/services.yml
@@ -334,6 +334,7 @@ services:
- '@phpbb.titania.message'
- '@phpbb.titania.access'
- '@phpbb.titania.subscriptions'
+ - '@path_helper'
- '@phpbb.titania.attachment.operator'
phpbb.titania.queue.stats:
@@ -431,18 +432,61 @@ services:
tags:
- { name: titania.contribution.type }
+ phpbb.titania.notification.type.base:
+ abstract: true
+ class: phpbb\titania\notification\type\base
+ parent: notification.type.base
+ calls:
+ - [set_user_loader, ['@user_loader']]
+
+ phpbb.titania.notification.type.posted:
+ class: phpbb\titania\notification\type\posted
+ shared: false
+ parent: phpbb.titania.notification.type.base
+ tags:
+ - { name: notification.type }
+
+ phpbb.titania.notification.type.contribution:
+ class: phpbb\titania\notification\type\contribution
+ shared: false
+ parent: phpbb.titania.notification.type.base
+ tags:
+ - { name: notification.type }
+
+ phpbb.titania.notification.type.queue:
+ class: phpbb\titania\notification\type\queue
+ shared: false
+ parent: phpbb.titania.notification.type.base
+ calls:
+ - [set_type_collection, ['@phpbb.titania.contribution.type.collection']]
+ tags:
+ - { name: notification.type }
+
+ phpbb.titania.notification.type.queue_move:
+ class: phpbb\titania\notification\type\queue_move
+ shared: false
+ parent: phpbb.titania.notification.type.queue
+ tags:
+ - { name: notification.type }
+
+ phpbb.titania.notification.type.attention:
+ class: phpbb\titania\notification\type\attention
+ shared: false
+ parent: phpbb.titania.notification.type.base
+ calls:
+ - [set_type_collection, ['@phpbb.titania.contribution.type.collection']]
+ tags:
+ - { name: notification.type }
+
phpbb.titania.subscriptions:
class: phpbb\titania\subscriptions
arguments:
- '@dbal.conn'
- - '@config'
- '@request'
- '@template'
- '@user'
- '@path_helper'
- - '%tables.users%'
- - '%core.root_path%'
- - '%core.php_ext%'
+ - '@notification_manager'
phpbb.titania.sync:
class: phpbb\titania\sync
diff --git a/controller/contribution/revision.php b/controller/contribution/revision.php
index 72a8bb7ea..ce400d181 100644
--- a/controller/contribution/revision.php
+++ b/controller/contribution/revision.php
@@ -270,13 +270,18 @@ public function add($contrib_type, $contrib)
'U_VIEW' => $this->queue->get_url(),
);
- $this->subscriptions->send_notifications(
- ext::TITANIA_QUEUE,
- $this->contrib->contrib_type,
- 'subscribe_notify_forum',
- $email_vars,
- $this->user->data['user_id']
- );
+ $this->subscriptions->send_notifications('queue', array(
+ 'item_id' => $this->queue->queue_id,
+ 'item_parent_id' => $this->contrib->contrib_id,
+ 'watch' => array(array(ext::TITANIA_QUEUE, $this->contrib->contrib_type)),
+ 'exclude_user' => $this->user->data['user_id'],
+ 'lang_key' => 'NOTIFICATION_TITANIA_QUEUE_NEW',
+ 'reference' => $this->contrib->contrib_name . ' ' . $this->revision->revision_version,
+ 'url' => $email_vars['U_VIEW'],
+ 'email_template' => 'subscribe_notify_forum',
+ 'email_vars' => $email_vars,
+ 'actor_id' => $this->user->data['user_id'],
+ ));
}
redirect($this->contrib->get_url());
}
diff --git a/event/main_listener.php b/event/main_listener.php
index 11227cac2..7a67b0bec 100644
--- a/event/main_listener.php
+++ b/event/main_listener.php
@@ -103,6 +103,8 @@ static public function getSubscribedEvents()
{
return array(
'core.permissions' => 'add_permissions',
+ 'core.user_setup' => 'load_language',
+ 'core.user_add_modify_notifications_data' => 'add_notifications_data',
'kernel.request' => array(array('startup', -1)),
'core.page_header_after' => 'overwrite_template_vars',
'core.text_formatter_s9e_configure_after' => 'inject_bbcode_code_lang',
@@ -192,6 +194,50 @@ public function add_permissions($event)
));
}
+ /**
+ * Load the notification language file on every page, so the notification
+ * dropdown and the UCP notification options can render Titania's types.
+ *
+ * @param data $event
+ */
+ public function load_language($event)
+ {
+ $lang_set_ext = $event['lang_set_ext'];
+ $lang_set_ext[] = array(
+ 'ext_name' => 'phpbb/titania',
+ 'lang_set' => 'notifications',
+ );
+ $event['lang_set_ext'] = $lang_set_ext;
+ }
+
+ /**
+ * Give new users email delivery for the Titania notification types by
+ * default, like the core does for the post and topic types, so
+ * subscribing keeps its historical mail-me meaning.
+ *
+ * @param data $event
+ */
+ public function add_notifications_data($event)
+ {
+ $notifications_data = $event['notifications_data'];
+
+ foreach (ext::get_notification_types() as $type)
+ {
+ // queue_move shares the queue type's preferences
+ if ($type === 'phpbb.titania.notification.type.queue_move')
+ {
+ continue;
+ }
+
+ $notifications_data[] = array(
+ 'item_type' => $type,
+ 'method' => 'notification.method.email',
+ );
+ }
+
+ $event['notifications_data'] = $notifications_data;
+ }
+
public function startup($event)
{
if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST ||
diff --git a/ext.php b/ext.php
index 389805fe8..aef4f9296 100644
--- a/ext.php
+++ b/ext.php
@@ -105,4 +105,80 @@ public static function get_filtered_repository_branches(): array
{
return [40];
}
+
+ /**
+ * The notification types this extension provides
+ *
+ * @return array Array of notification type service names
+ */
+ public static function get_notification_types(): array
+ {
+ return [
+ 'phpbb.titania.notification.type.posted',
+ 'phpbb.titania.notification.type.contribution',
+ 'phpbb.titania.notification.type.queue',
+ 'phpbb.titania.notification.type.queue_move',
+ 'phpbb.titania.notification.type.attention',
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function enable_step($old_state)
+ {
+ if ($old_state === false)
+ {
+ $notification_manager = $this->container->get('notification_manager');
+
+ foreach (self::get_notification_types() as $type)
+ {
+ $notification_manager->enable_notifications($type);
+ }
+
+ return 'notifications';
+ }
+
+ return parent::enable_step($old_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function disable_step($old_state)
+ {
+ if ($old_state === false)
+ {
+ $notification_manager = $this->container->get('notification_manager');
+
+ foreach (self::get_notification_types() as $type)
+ {
+ $notification_manager->disable_notifications($type);
+ }
+
+ return 'notifications';
+ }
+
+ return parent::disable_step($old_state);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function purge_step($old_state)
+ {
+ if ($old_state === false)
+ {
+ $notification_manager = $this->container->get('notification_manager');
+
+ foreach (self::get_notification_types() as $type)
+ {
+ $notification_manager->purge_notifications($type);
+ }
+
+ return 'notifications';
+ }
+
+ return parent::purge_step($old_state);
+ }
}
diff --git a/includes/objects/attention.php b/includes/objects/attention.php
index a7398e087..67c0f104a 100644
--- a/includes/objects/attention.php
+++ b/includes/objects/attention.php
@@ -91,8 +91,12 @@ public function check_auth()
public function submit()
{
- // Subscriptions
- if (!$this->attention_id)
+ $is_new = !$this->attention_id;
+
+ parent::submit();
+
+ // Subscriptions; sent after the parent submit so the attention id exists
+ if ($is_new)
{
$u_view = $this->controller_helper->route('phpbb.titania.manage.attention.redirect', array(
'type' => $this->attention_type,
@@ -102,16 +106,35 @@ public function submit()
'NAME' => $this->attention_title,
'U_VIEW' => $this->path_helper->strip_url_params($u_view, 'sid'),
);
- $this->subscriptions->send_notifications(
- ext::TITANIA_ATTENTION,
- 0,
- 'subscribe_notify',
- $email_vars,
- $this->attention_poster_id
- );
- }
- parent::submit();
+ switch ($this->attention_type)
+ {
+ case ext::TITANIA_ATTENTION_REPORTED:
+ $lang_key = 'NOTIFICATION_TITANIA_ATTENTION_REPORT';
+ break;
+
+ case ext::TITANIA_ATTENTION_UNAPPROVED:
+ $lang_key = 'NOTIFICATION_TITANIA_ATTENTION_UNAPPROVED';
+ break;
+
+ default:
+ $lang_key = 'NOTIFICATION_TITANIA_ATTENTION';
+ break;
+ }
+
+ $this->subscriptions->send_notifications('attention', array(
+ 'item_id' => $this->attention_id,
+ 'item_parent_id' => $this->attention_object_id,
+ 'watch' => array(array(ext::TITANIA_ATTENTION, 0)),
+ 'exclude_user' => $this->attention_poster_id,
+ 'lang_key' => $lang_key,
+ 'reference' => $this->attention_title,
+ 'url' => $email_vars['U_VIEW'],
+ 'email_template' => 'subscribe_notify',
+ 'email_vars' => $email_vars,
+ 'actor_id' => $this->attention_requester,
+ ));
+ }
}
/**
diff --git a/includes/objects/attention_types/post.php b/includes/objects/attention_types/post.php
index 8cfe2a54d..de8b8d31b 100644
--- a/includes/objects/attention_types/post.php
+++ b/includes/objects/attention_types/post.php
@@ -273,10 +273,12 @@ protected function approve_post()
$message_vars = array(
'U_VIEW' => $this->path_helper->strip_url_params($u_view, 'sid'),
);
- $object_type = array(ext::TITANIA_TOPIC, ext::TITANIA_SUPPORT);
- $object_id = array($this->post->topic_id, $this->post->topic->parent_id);
+ $watch = array(
+ array(ext::TITANIA_TOPIC, $this->post->topic_id),
+ array(ext::TITANIA_SUPPORT, $this->post->topic->parent_id),
+ );
- $this->send_notifications($object_type, $object_id, 'subscribe_notify_contrib', $message_vars);
+ $this->send_notifications($watch, 'NOTIFICATION_TITANIA_REPLY_CONTRIB', 'subscribe_notify_contrib', $message_vars);
}
}
@@ -296,20 +298,21 @@ protected function approve_topic()
if ($this->post->topic->topic_last_post_id == $this->post->post_id)
{
$message_vars = array('U_VIEW' => $this->post->topic->get_url());
+ $watch = array(array($this->post->post_type, $this->post->topic->parent_id));
- $this->send_notifications($this->post->post_type, $this->post->topic->parent_id, 'subscribe_notify_forum_contrib', $message_vars);
+ $this->send_notifications($watch, 'NOTIFICATION_TITANIA_TOPIC_CONTRIB', 'subscribe_notify_forum_contrib', $message_vars);
}
}
/**
* Send notifications.
*
- * @param int|array $object_type
- * @param int|array $object_id
+ * @param array $watch Array of array(watch_object_type, watch_object_id) pairs
+ * @param string $lang_key Language key for the board notification title
* @param string $email_template
* @param array $message_vars
*/
- public function send_notifications($object_type, $object_id, $email_template, $message_vars)
+ public function send_notifications($watch, $lang_key, $email_template, $message_vars)
{
$this->load_contrib_object();
@@ -318,13 +321,19 @@ public function send_notifications($object_type, $object_id, $email_template, $m
'CONTRIB_NAME' => $this->contrib->contrib_name,
));
- $this->subscriptions->send_notifications(
- $object_type,
- $object_id,
- $email_template,
- $message_vars,
- $this->post->post_user_id
- );
+ $this->subscriptions->send_notifications('posted', array(
+ 'item_id' => $this->post->post_id,
+ 'item_parent_id' => $this->post->topic_id,
+ 'watch' => $watch,
+ 'exclude_user' => $this->post->post_user_id,
+ 'lang_key' => $lang_key,
+ 'lang_params' => array($this->contrib->contrib_name),
+ 'reference' => $this->post->topic->topic_subject,
+ 'url' => $message_vars['U_VIEW'],
+ 'email_template' => $email_template,
+ 'email_vars' => $message_vars,
+ 'actor_id' => $this->post->post_user_id,
+ ));
}
/**
diff --git a/includes/objects/contribution.php b/includes/objects/contribution.php
index c4b74f3d0..651a74f01 100644
--- a/includes/objects/contribution.php
+++ b/includes/objects/contribution.php
@@ -2313,12 +2313,28 @@ public function delete()
// Change the status to new (handles resetting counts)
$this->change_status(ext::TITANIA_CONTRIB_NEW);
- // Remove any attention items
+ // Remove any attention items and their notifications
+ $attention_ids = array();
+ $sql = 'SELECT attention_id FROM ' . TITANIA_ATTENTION_TABLE . '
+ WHERE attention_object_type = ' . ext::TITANIA_CONTRIB . '
+ AND attention_object_id = ' . $this->contrib_id;
+ $result = phpbb::$db->sql_query($sql);
+ while ($row = phpbb::$db->sql_fetchrow($result))
+ {
+ $attention_ids[] = (int) $row['attention_id'];
+ }
+ phpbb::$db->sql_freeresult($result);
+
$sql = 'DELETE FROM ' . TITANIA_ATTENTION_TABLE . '
WHERE attention_object_type = ' . ext::TITANIA_CONTRIB . '
AND attention_object_id = ' . $this->contrib_id;
phpbb::$db->sql_query($sql);
+ if (!empty($attention_ids))
+ {
+ phpbb::$container->get('notification_manager')->delete_notifications('phpbb.titania.notification.type.attention', $attention_ids);
+ }
+
// Delete the release topic
if ($this->contrib_release_topic_id)
{
diff --git a/includes/objects/post.php b/includes/objects/post.php
index 15a0b1742..1ef265450 100644
--- a/includes/objects/post.php
+++ b/includes/objects/post.php
@@ -765,12 +765,32 @@ public function hard_delete()
// @todo remove attachments and other things
- // Remove any attention items
+ // Remove any attention items and their notifications
+ $attention_ids = array();
+ $sql = 'SELECT attention_id FROM ' . TITANIA_ATTENTION_TABLE . '
+ WHERE attention_object_type = ' . ext::TITANIA_POST . '
+ AND attention_object_id = ' . $this->post_id;
+ $result = phpbb::$db->sql_query($sql);
+ while ($row = phpbb::$db->sql_fetchrow($result))
+ {
+ $attention_ids[] = (int) $row['attention_id'];
+ }
+ phpbb::$db->sql_freeresult($result);
+
$sql = 'DELETE FROM ' . TITANIA_ATTENTION_TABLE . '
WHERE attention_object_type = ' . ext::TITANIA_POST . '
AND attention_object_id = ' . $this->post_id;
phpbb::$db->sql_query($sql);
+ // Remove any notifications for this post and its attention items
+ $notification_manager = phpbb::$container->get('notification_manager');
+ $notification_manager->delete_notifications('phpbb.titania.notification.type.posted', $this->post_id);
+
+ if (!empty($attention_ids))
+ {
+ $notification_manager->delete_notifications('phpbb.titania.notification.type.attention', $attention_ids);
+ }
+
// Decrement the user's postcount if we must
if (!$this->post_deleted && $this->post_approved && in_array($this->post_type, titania::$config->increment_postcount))
{
diff --git a/includes/objects/queue.php b/includes/objects/queue.php
index 0d9dc6c5b..09c90196d 100644
--- a/includes/objects/queue.php
+++ b/includes/objects/queue.php
@@ -323,6 +323,12 @@ public function delete()
WHERE revision_id = ' . $this->revision_id;
phpbb::$db->sql_query($sql);
+ // Remove any notifications for this queue item
+ phpbb::$container->get('notification_manager')->delete_notifications(
+ array('phpbb.titania.notification.type.queue', 'phpbb.titania.notification.type.queue_move'),
+ $this->queue_id
+ );
+
// Assplode
parent::delete();
}
@@ -353,13 +359,19 @@ public function move($new_status, \phpbb\titania\tags $tags)
'CATEGORY_NAME' => $to,
'U_VIEW_QUEUE' => $path_helper->strip_url_params($u_view_queue, 'sid'),
);
- $this->subscriptions->send_notifications(
- ext::TITANIA_QUEUE_TAG,
- $new_status,
- 'new_contrib_queue_cat',
- $vars,
- phpbb::$user->data['user_id']
- );
+ $this->subscriptions->send_notifications('queue_move', array(
+ 'item_id' => $this->queue_id,
+ 'item_parent_id' => $this->contrib_id,
+ 'watch' => array(array(ext::TITANIA_QUEUE_TAG, $new_status)),
+ 'exclude_user' => phpbb::$user->data['user_id'],
+ 'lang_key' => 'NOTIFICATION_TITANIA_QUEUE_MOVE',
+ 'lang_params' => array($to),
+ 'reference' => $contrib->contrib_name,
+ 'url' => $vars['U_VIEW_QUEUE'],
+ 'email_template' => 'new_contrib_queue_cat',
+ 'email_vars' => $vars,
+ 'actor_id' => phpbb::$user->data['user_id'],
+ ));
}
public function in_progress()
@@ -461,7 +473,17 @@ public function approve($public_notes, $robot_user_id = 0)
'NAME' => $contrib->contrib_name,
'U_VIEW' => $contrib->get_url(),
);
- $this->subscriptions->send_notifications(ext::TITANIA_CONTRIB, $this->contrib_id, 'subscribe_notify', $email_vars);
+ $this->subscriptions->send_notifications('contribution', array(
+ 'item_id' => $revision->revision_id,
+ 'item_parent_id' => $this->contrib_id,
+ 'watch' => array(array(ext::TITANIA_CONTRIB, $this->contrib_id)),
+ 'lang_key' => 'NOTIFICATION_TITANIA_CONTRIB_UPDATED',
+ 'lang_params' => array($revision->revision_version),
+ 'reference' => $contrib->contrib_name,
+ 'url' => $email_vars['U_VIEW'],
+ 'email_template' => 'subscribe_notify',
+ 'email_vars' => $email_vars,
+ ));
$this->trash_queue_topic();
}
diff --git a/includes/objects/revision.php b/includes/objects/revision.php
index ca80bee86..10c5a6247 100644
--- a/includes/objects/revision.php
+++ b/includes/objects/revision.php
@@ -297,6 +297,8 @@ public function display($tpl_block = 'revisions', $show_queue = false, $all_vers
*/
public function submit()
{
+ $notify_subscribers = false;
+
if (!$this->revision_id)
{
// Update the contrib_last_update if required here
@@ -312,17 +314,8 @@ public function submit()
WHERE contrib_id = ' . $this->contrib_id;
phpbb::$db->sql_query($sql);
- // Subscriptions
- $email_vars = array(
- 'NAME' => $this->contrib->contrib_name,
- 'U_VIEW' => $this->contrib->get_url(),
- );
- $this->subscriptions->send_notifications(
- ext::TITANIA_CONTRIB,
- $this->contrib_id,
- 'subscribe_notify',
- $email_vars
- );
+ // Notify the subscribers once the revision row exists
+ $notify_subscribers = true;
}
}
else if (sizeof($this->phpbb_versions))
@@ -378,6 +371,26 @@ public function submit()
{
$this->contrib->update_release_topic();
}
+
+ // Subscriptions
+ if ($notify_subscribers)
+ {
+ $email_vars = array(
+ 'NAME' => $this->contrib->contrib_name,
+ 'U_VIEW' => $this->contrib->get_url(),
+ );
+ $this->subscriptions->send_notifications('contribution', array(
+ 'item_id' => $this->revision_id,
+ 'item_parent_id' => $this->contrib_id,
+ 'watch' => array(array(ext::TITANIA_CONTRIB, $this->contrib_id)),
+ 'lang_key' => 'NOTIFICATION_TITANIA_CONTRIB_UPDATED',
+ 'lang_params' => array($this->revision_version),
+ 'reference' => $this->contrib->contrib_name,
+ 'url' => $email_vars['U_VIEW'],
+ 'email_template' => 'subscribe_notify',
+ 'email_vars' => $email_vars,
+ ));
+ }
}
/**
@@ -590,6 +603,9 @@ public function delete()
// $translations = new titania_attachment(TITANIA_TRANSLATION, $this->revision_id);
// $attachment->delete_all();
+ // Remove any notifications for this revision
+ phpbb::$container->get('notification_manager')->delete_notifications('phpbb.titania.notification.type.contribution', $this->revision_id);
+
// Self-destruct
parent::delete();
}
diff --git a/language/en/notifications.php b/language/en/notifications.php
new file mode 100644
index 000000000..d8a016a9a
--- /dev/null
+++ b/language/en/notifications.php
@@ -0,0 +1,57 @@
+
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* DO NOT CHANGE
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+if (empty($lang) || !is_array($lang))
+{
+ $lang = array();
+}
+
+// DEVELOPERS PLEASE NOTE
+//
+// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
+//
+// Placeholders can now contain order information, e.g. instead of
+// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
+// translators to re-order the output of data while ensuring it remains correct
+//
+// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
+// equally where a string contains only two placeholders which are used to wrap text
+// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
+
+$lang = array_merge($lang, array(
+ 'NOTIFICATION_GROUP_TITANIA' => 'Customisation Database',
+
+ 'NOTIFICATION_TYPE_TITANIA_POSTED' => 'Someone posts in a subscribed topic or support area',
+ 'NOTIFICATION_TYPE_TITANIA_CONTRIBUTION' => 'A new version of a subscribed contribution is released',
+ 'NOTIFICATION_TYPE_TITANIA_QUEUE' => 'A watched validation queue changes',
+ 'NOTIFICATION_TYPE_TITANIA_ATTENTION' => 'Content is reported or awaits approval',
+
+ 'NOTIFICATION_TITANIA_REPLY' => 'Reply from %1$s to the topic:',
+ 'NOTIFICATION_TITANIA_REPLY_CONTRIB' => 'Reply from %1$s in the support area of %2$s to the topic:',
+ 'NOTIFICATION_TITANIA_TOPIC' => 'New topic from %1$s:',
+ 'NOTIFICATION_TITANIA_TOPIC_CONTRIB' => 'New topic from %1$s in the support area of %2$s:',
+ 'NOTIFICATION_TITANIA_CONTRIB_UPDATED' => 'New version %1$s released for the contribution:',
+ 'NOTIFICATION_TITANIA_QUEUE_NEW' => 'New queue item:',
+ 'NOTIFICATION_TITANIA_QUEUE_MOVE' => 'Queue item moved to %1$s:',
+ 'NOTIFICATION_TITANIA_ATTENTION' => 'Needs attention:',
+ 'NOTIFICATION_TITANIA_ATTENTION_REPORT' => 'Reported:',
+ 'NOTIFICATION_TITANIA_ATTENTION_UNAPPROVED' => 'Awaiting approval:',
+));
diff --git a/migrations/notifications_integration.php b/migrations/notifications_integration.php
new file mode 100644
index 000000000..3e610e6c9
--- /dev/null
+++ b/migrations/notifications_integration.php
@@ -0,0 +1,138 @@
+
+* @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\titania\migrations;
+
+use phpbb\titania\ext;
+
+/**
+* Seed notification preferences for existing subscribers.
+*
+* The legacy dispatcher emailed every watcher. The notification system's
+* default delivery for users without preference rows is the board method only,
+* so existing subscribers would silently stop receiving emails. Give every
+* current watcher explicit board + email preferences for the notification
+* types their subscriptions map to; new subscribers from here on get the
+* standard core defaults.
+*/
+class notifications_integration extends base
+{
+ static public function depends_on()
+ {
+ return array('\phpbb\titania\migrations\release_1_1_0');
+ }
+
+ public function update_data()
+ {
+ return array(
+ array('custom', array(array($this, 'seed_user_notifications'))),
+ );
+ }
+
+ /**
+ * Seed user_notifications rows chunk by chunk.
+ *
+ * @param mixed $start Offset carried between calls by the migrator
+ * @return mixed True when done, else the next offset
+ */
+ public function seed_user_notifications($start)
+ {
+ $limit = 500;
+ $start = (int) $start;
+
+ $option_map = array(
+ ext::TITANIA_CONTRIB => 'phpbb.titania.notification.type.contribution',
+ ext::TITANIA_SUPPORT => 'phpbb.titania.notification.type.posted',
+ ext::TITANIA_TOPIC => 'phpbb.titania.notification.type.posted',
+ ext::TITANIA_QUEUE_DISCUSSION => 'phpbb.titania.notification.type.posted',
+ ext::TITANIA_QUEUE => 'phpbb.titania.notification.type.queue',
+ ext::TITANIA_QUEUE_TAG => 'phpbb.titania.notification.type.queue',
+ ext::TITANIA_ATTENTION => 'phpbb.titania.notification.type.attention',
+ );
+
+ $watch_table = $this->get_titania_table_prefix() . 'watch';
+
+ $sql = 'SELECT DISTINCT w.watch_user_id, w.watch_object_type
+ FROM ' . $watch_table . ' w, ' . $this->table_prefix . 'users u
+ WHERE w.watch_user_id = u.user_id
+ AND w.watch_type = ' . \phpbb\titania\subscriptions::EMAIL . '
+ ORDER BY w.watch_user_id, w.watch_object_type';
+ $result = $this->db->sql_query_limit($sql, $limit, $start);
+
+ $row_count = 0;
+ $wanted = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $row_count++;
+
+ if (isset($option_map[$row['watch_object_type']]))
+ {
+ $wanted[(int) $row['watch_user_id']][$option_map[$row['watch_object_type']]] = true;
+ }
+ }
+ $this->db->sql_freeresult($result);
+
+ if (!$row_count)
+ {
+ return true;
+ }
+
+ if (!empty($wanted))
+ {
+ // Users who already have a preference row for a type keep it untouched
+ $sql = 'SELECT user_id, item_type, method
+ FROM ' . $this->table_prefix . 'user_notifications
+ WHERE item_id = 0
+ AND ' . $this->db->sql_in_set('user_id', array_keys($wanted)) . '
+ AND ' . $this->db->sql_in_set('item_type', array_values($option_map));
+ $result = $this->db->sql_query($sql);
+
+ $existing = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $existing[(int) $row['user_id']][$row['item_type']] = true;
+ }
+ $this->db->sql_freeresult($result);
+
+ // The board method delivers by default without a row; an explicit
+ // email row is all that is needed, like the rows user registration
+ // creates for the post and topic types.
+ $insert = array();
+ foreach ($wanted as $user_id => $options)
+ {
+ foreach ($options as $option => $null)
+ {
+ if (isset($existing[$user_id][$option]))
+ {
+ continue;
+ }
+
+ $insert[] = array(
+ 'item_type' => $option,
+ 'item_id' => 0,
+ 'user_id' => $user_id,
+ 'method' => 'notification.method.email',
+ 'notify' => 1,
+ );
+ }
+ }
+
+ if (!empty($insert))
+ {
+ $this->db->sql_multi_insert($this->table_prefix . 'user_notifications', $insert);
+ }
+ }
+
+ return ($row_count == $limit) ? $start + $limit : true;
+ }
+}
diff --git a/notification/type/attention.php b/notification/type/attention.php
new file mode 100644
index 000000000..9b9990df7
--- /dev/null
+++ b/notification/type/attention.php
@@ -0,0 +1,60 @@
+
+* @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\titania\notification\type;
+
+/**
+* A new attention item (report or content needing approval) was created.
+*/
+class attention extends base
+{
+ /** @var \phpbb\titania\contribution\type\collection */
+ protected $type_collection;
+
+ /**
+ * {@inheritdoc}
+ */
+ static public $notification_option = array(
+ 'lang' => 'NOTIFICATION_TYPE_TITANIA_ATTENTION',
+ 'group' => 'NOTIFICATION_GROUP_TITANIA',
+ );
+
+ /**
+ * Set the contribution type collection.
+ *
+ * @param \phpbb\titania\contribution\type\collection $type_collection
+ */
+ public function set_type_collection(\phpbb\titania\contribution\type\collection $type_collection)
+ {
+ $this->type_collection = $type_collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'phpbb.titania.notification.type.attention';
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Mirrors the attention page's own access check.
+ */
+ public function is_available()
+ {
+ return $this->auth->acl_gets('u_titania_mod_contrib_mod', 'u_titania_mod_post_mod')
+ || count($this->type_collection->find_authed('moderate')) > 0;
+ }
+}
diff --git a/notification/type/base.php b/notification/type/base.php
new file mode 100644
index 000000000..6021167c5
--- /dev/null
+++ b/notification/type/base.php
@@ -0,0 +1,205 @@
+
+* @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\titania\notification\type;
+
+/**
+* Base class for Titania notification types.
+*
+* All Titania subscription events are data driven: the dispatcher passes the
+* watch pairs to select the recipients from, the language key and parameters
+* for the board notification, the url, and the email template with its
+* variables. Subclasses only differ in their type name, their UCP option and
+* their availability.
+*/
+abstract class base extends \phpbb\notification\type\base
+{
+ /** @var \phpbb\user_loader */
+ protected $user_loader;
+
+ /**
+ * Set the user loader (used for actor avatars and names)
+ *
+ * @param \phpbb\user_loader $user_loader
+ */
+ public function set_user_loader(\phpbb\user_loader $user_loader)
+ {
+ $this->user_loader = $user_loader;
+ }
+
+ /**
+ * The item type the user's notification preferences are stored under.
+ * Types sharing a UCP option (via $notification_option['id']) share it.
+ *
+ * @return string
+ */
+ protected function get_option_type()
+ {
+ if (static::$notification_option !== false && isset(static::$notification_option['id']))
+ {
+ return static::$notification_option['id'];
+ }
+ return $this->get_type();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_item_id($type_data)
+ {
+ return (int) $type_data['item_id'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ static public function get_item_parent_id($type_data)
+ {
+ return (isset($type_data['item_parent_id'])) ? (int) $type_data['item_parent_id'] : 0;
+ }
+
+ /**
+ * Find the users subscribed to the given watch pairs.
+ *
+ * @param array $type_data Expects 'watch' (array of array(object_type, object_id)
+ * pairs) and optionally 'exclude_user'.
+ * @param array $options
+ * @return array
+ */
+ public function find_users_for_notification($type_data, $options = array())
+ {
+ $options = array_merge(array(
+ 'ignore_users' => array(),
+ ), $options);
+
+ // The watch table constant only exists once Titania's common.php ran,
+ // which is the case on every page that dispatches a notification.
+ if (empty($type_data['watch']) || !defined('TITANIA_WATCH_TABLE'))
+ {
+ return array();
+ }
+
+ $sql_objects = array();
+ foreach ($type_data['watch'] as $watch)
+ {
+ $sql_objects[] = '(watch_object_type = ' . (int) $watch[0] . '
+ AND watch_object_id = ' . (int) $watch[1] . ')';
+ }
+
+ $sql = 'SELECT watch_user_id
+ FROM ' . TITANIA_WATCH_TABLE . '
+ WHERE (' . implode(' OR ', $sql_objects) . ')' .
+ ((!empty($type_data['exclude_user'])) ? ' AND watch_user_id <> ' . (int) $type_data['exclude_user'] : '');
+ $result = $this->db->sql_query($sql);
+
+ $users = array();
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $users[(int) $row['watch_user_id']] = true;
+ }
+ $this->db->sql_freeresult($result);
+
+ if (empty($users))
+ {
+ return array();
+ }
+ $users = array_keys($users);
+ sort($users);
+
+ return $this->check_user_notification_options($users, array_merge($options, array(
+ 'item_type' => $this->get_option_type(),
+ )));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function create_insert_array($type_data, $pre_create_data = array())
+ {
+ $this->set_data('lang_key', $type_data['lang_key']);
+ $this->set_data('lang_params', (isset($type_data['lang_params'])) ? $type_data['lang_params'] : array());
+ $this->set_data('reference', (isset($type_data['reference'])) ? $type_data['reference'] : '');
+ $this->set_data('url', (isset($type_data['url'])) ? $type_data['url'] : '');
+ $this->set_data('email_template', $type_data['email_template']);
+ $this->set_data('email_vars', (isset($type_data['email_vars'])) ? $type_data['email_vars'] : array());
+ $this->set_data('actor_id', (isset($type_data['actor_id'])) ? (int) $type_data['actor_id'] : 0);
+
+ parent::create_insert_array($type_data, $pre_create_data);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_title()
+ {
+ $params = $this->get_data('lang_params');
+
+ return $this->language->lang_array($this->get_data('lang_key'), (is_array($params)) ? $params : array());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_reference()
+ {
+ $reference = $this->get_data('reference');
+
+ return ($reference) ? $this->language->lang('NOTIFICATION_REFERENCE', $reference) : '';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_url()
+ {
+ return $this->get_data('url');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_email_template()
+ {
+ return '@phpbb_titania/' . $this->get_data('email_template');
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_email_template_variables()
+ {
+ $vars = $this->get_data('email_vars');
+
+ return (is_array($vars)) ? $vars : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function users_to_query()
+ {
+ $actor_id = (int) $this->get_data('actor_id');
+
+ return ($actor_id) ? array($actor_id) : array();
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_avatar()
+ {
+ $actor_id = (int) $this->get_data('actor_id');
+
+ return ($actor_id) ? $this->user_loader->get_avatar($actor_id, false, true) : '';
+ }
+}
diff --git a/notification/type/contribution.php b/notification/type/contribution.php
new file mode 100644
index 000000000..3faa13c45
--- /dev/null
+++ b/notification/type/contribution.php
@@ -0,0 +1,36 @@
+
+* @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\titania\notification\type;
+
+/**
+* A new revision of a subscribed contribution was released.
+*/
+class contribution extends base
+{
+ /**
+ * {@inheritdoc}
+ */
+ static public $notification_option = array(
+ 'lang' => 'NOTIFICATION_TYPE_TITANIA_CONTRIBUTION',
+ 'group' => 'NOTIFICATION_GROUP_TITANIA',
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'phpbb.titania.notification.type.contribution';
+ }
+}
diff --git a/notification/type/posted.php b/notification/type/posted.php
new file mode 100644
index 000000000..75d3cc23a
--- /dev/null
+++ b/notification/type/posted.php
@@ -0,0 +1,53 @@
+
+* @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\titania\notification\type;
+
+/**
+* New topics and replies in subscribed topics and support areas.
+*/
+class posted extends base
+{
+ /**
+ * {@inheritdoc}
+ */
+ static public $notification_option = array(
+ 'lang' => 'NOTIFICATION_TYPE_TITANIA_POSTED',
+ 'group' => 'NOTIFICATION_GROUP_TITANIA',
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'phpbb.titania.notification.type.posted';
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * The poster's name is resolved at display time through the user loader,
+ * like core's post notification does.
+ */
+ public function get_title()
+ {
+ $params = $this->get_data('lang_params');
+ $username = $this->user_loader->get_username((int) $this->get_data('actor_id'), 'no_profile');
+
+ return $this->language->lang_array(
+ $this->get_data('lang_key'),
+ array_merge(array($username), (is_array($params)) ? $params : array())
+ );
+ }
+}
diff --git a/notification/type/queue.php b/notification/type/queue.php
new file mode 100644
index 000000000..ff1416f98
--- /dev/null
+++ b/notification/type/queue.php
@@ -0,0 +1,59 @@
+
+* @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\titania\notification\type;
+
+/**
+* A new item entered a watched validation queue.
+*/
+class queue extends base
+{
+ /** @var \phpbb\titania\contribution\type\collection */
+ protected $type_collection;
+
+ /**
+ * {@inheritdoc}
+ */
+ static public $notification_option = array(
+ 'lang' => 'NOTIFICATION_TYPE_TITANIA_QUEUE',
+ 'group' => 'NOTIFICATION_GROUP_TITANIA',
+ );
+
+ /**
+ * Set the contribution type collection.
+ *
+ * @param \phpbb\titania\contribution\type\collection $type_collection
+ */
+ public function set_type_collection(\phpbb\titania\contribution\type\collection $type_collection)
+ {
+ $this->type_collection = $type_collection;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'phpbb.titania.notification.type.queue';
+ }
+
+ /**
+ * {@inheritdoc}
+ *
+ * Only users who can view at least one validation queue see the option.
+ */
+ public function is_available()
+ {
+ return count($this->type_collection->find_authed('view')) > 0;
+ }
+}
diff --git a/notification/type/queue_move.php b/notification/type/queue_move.php
new file mode 100644
index 000000000..e98591d24
--- /dev/null
+++ b/notification/type/queue_move.php
@@ -0,0 +1,41 @@
+
+* @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\titania\notification\type;
+
+/**
+* A queue item moved to a watched queue category.
+*
+* A separate type from queue only because both events concern the same queue
+* item and notifications deduplicate per type and item id; it shares the queue
+* type's UCP option and preferences.
+*/
+class queue_move extends queue
+{
+ /**
+ * {@inheritdoc}
+ */
+ static public $notification_option = array(
+ 'id' => 'phpbb.titania.notification.type.queue',
+ 'lang' => 'NOTIFICATION_TYPE_TITANIA_QUEUE',
+ 'group' => 'NOTIFICATION_GROUP_TITANIA',
+ );
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_type()
+ {
+ return 'phpbb.titania.notification.type.queue_move';
+ }
+}
diff --git a/posting.php b/posting.php
index 2c5f32988..ce70f6698 100644
--- a/posting.php
+++ b/posting.php
@@ -48,6 +48,9 @@ class posting
/** @var \phpbb\titania\subscriptions */
protected $subscriptions;
+ /** @var \phpbb\path_helper */
+ protected $path_helper;
+
/** @var \phpbb\titania\attachment\operator */
protected $attachments;
@@ -76,9 +79,10 @@ class posting
* @param message $message
* @param access $access
* @param subscriptions $subscriptions
+ * @param \phpbb\path_helper $path_helper
* @param \phpbb\titania\attachment\operator $attachments
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\request\request_interface $request, \phpbb\template\template $template, controller\helper $controller_helper, message $message, access $access, subscriptions $subscriptions, \phpbb\titania\attachment\operator $attachments)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_interface $db, \phpbb\user $user, \phpbb\request\request_interface $request, \phpbb\template\template $template, controller\helper $controller_helper, message $message, access $access, subscriptions $subscriptions, \phpbb\path_helper $path_helper, \phpbb\titania\attachment\operator $attachments)
{
$this->auth = $auth;
$this->db = $db;
@@ -89,6 +93,7 @@ public function __construct(\phpbb\auth\auth $auth, \phpbb\db\driver\driver_inte
$this->message = $message;
$this->access = $access;
$this->subscriptions = $subscriptions;
+ $this->path_helper = $path_helper;
$this->attachments = $attachments;
}
@@ -1259,16 +1264,18 @@ protected function send_notifications(\titania_post $post, $mode)
$email_vars = array(
'NAME' => htmlspecialchars_decode($post->topic->topic_subject),
);
+ $lang_params = array();
if ($is_support_topic)
{
$email_vars['CONTRIB_NAME'] = $this->contrib->contrib_name;
+ $lang_params[] = $this->contrib->contrib_name;
}
if ($mode == 'reply')
{
- $object_type = array(ext::TITANIA_TOPIC);
- $object_id = array($post->topic_id);
+ $watch = array(array(ext::TITANIA_TOPIC, $post->topic_id));
+ $lang_key = 'NOTIFICATION_TITANIA_REPLY';
$topic_params = array(
'view' => 'unread',
'#' => 'unread',
@@ -1277,26 +1284,32 @@ protected function send_notifications(\titania_post $post, $mode)
if ($is_support_topic)
{
// Support topic reply
- $object_id[] = $post->topic->parent_id;
- $object_type[] = ext::TITANIA_SUPPORT;
- $template .= '_contrib';
+ $watch[] = array(ext::TITANIA_SUPPORT, $post->topic->parent_id);
+ $template .= '_contrib';
+ $lang_key = 'NOTIFICATION_TITANIA_REPLY_CONTRIB';
}
}
else
{
- $object_type = $post->post_type;
- $object_id = $post->topic->parent_id;
- $template .= ($is_support_topic) ? '_forum_contrib' : '_forum';
+ $watch = array(array($post->post_type, $post->topic->parent_id));
+ $template .= ($is_support_topic) ? '_forum_contrib' : '_forum';
+ $lang_key = ($is_support_topic) ? 'NOTIFICATION_TITANIA_TOPIC_CONTRIB' : 'NOTIFICATION_TITANIA_TOPIC';
}
$email_vars['U_VIEW'] = $post->topic->get_url(false, $topic_params);
- $this->subscriptions->send_notifications(
- $object_type,
- $object_id,
- $template,
- $email_vars,
- $post->post_user_id
- );
+ $this->subscriptions->send_notifications('posted', array(
+ 'item_id' => $post->post_id,
+ 'item_parent_id' => $post->topic_id,
+ 'watch' => $watch,
+ 'exclude_user' => $post->post_user_id,
+ 'lang_key' => $lang_key,
+ 'lang_params' => $lang_params,
+ 'reference' => $post->topic->topic_subject,
+ 'url' => $email_vars['U_VIEW'],
+ 'email_template' => $template,
+ 'email_vars' => $email_vars,
+ 'actor_id' => $post->post_user_id,
+ ));
}
/**
diff --git a/subscriptions.php b/subscriptions.php
index c0b3ec3be..9b7213afc 100644
--- a/subscriptions.php
+++ b/subscriptions.php
@@ -18,58 +18,50 @@ class subscriptions
/** @var \phpbb\db\driver\driver_interface */
protected $db;
- /** @var \phpbb\config\config */
- protected $config;
-
/** @var \phpbb\request\request_interface */
protected $request;
+ /** @var \phpbb\template\template */
+ protected $template;
+
/** @var \phpbb\user */
protected $user;
/** @var \phpbb\path_helper */
protected $path_helper;
- /** @var string */
- protected $users_table;
+ /** @var \phpbb\notification\manager */
+ protected $notification_manager;
/** @var string */
protected $watch_table;
- /** @var string */
- protected $phpbb_root_path;
-
- /** @var string */
- protected $php_ext;
-
+ /**
+ * The historical delivery type stored in watch_type. Every row carries
+ * EMAIL; delivery preferences now live in the notification system, so the
+ * column only distinguishes subscription rows, not how they are delivered.
+ */
const EMAIL = 1;
- const WATCH = 2;
/**
* Constructor
*
* @param \phpbb\db\driver\driver_interface $db
- * @param \phpbb\config\config $config
* @param \phpbb\request\request_interface $request
* @param \phpbb\template\template $template
* @param \phpbb\user $user
* @param \phpbb\path_helper $path_helper
- * @param string $users_table
- * @param string $phpbb_root_path
- * @param string $php_ext
+ * @param \phpbb\notification\manager $notification_manager
*/
- public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\request\request_interface $request, \phpbb\template\template $template, \phpbb\user $user, \phpbb\path_helper $path_helper, $users_table, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\request\request_interface $request, \phpbb\template\template $template, \phpbb\user $user, \phpbb\path_helper $path_helper, \phpbb\notification\manager $notification_manager)
{
$this->db = $db;
- $this->config = $config;
$this->request = $request;
$this->template = $template;
$this->user = $user;
$this->path_helper = $path_helper;
- $this->users_table = $users_table;
+ $this->notification_manager = $notification_manager;
$this->watch_table = TITANIA_WATCH_TABLE;
- $this->phpbb_root_path = $phpbb_root_path;
- $this->php_ext = $php_ext;
}
/**
@@ -201,125 +193,36 @@ public function unsubscribe($object_type, $object_id, $user_id = false)
}
/**
- * Send Notifications
- *
- * Using this function:
- * Call this function when you know the Object type, object id, and the email
- * template name.
- * Sample usage:
- *
- *
- *
- * $object_type = SOME_OBJECT_CONSTANT_TYPE;
- * $obhect)id = 242974;
+ * Send subscription notifications through the phpBB notification system.
*
- * titania_subscriptions::send_notifications($object_type, $object_id, 'mod_subscribe', array(
- * 'OBJECT_NAME' => 'Some MOD',
- * ));
- *
- *
- *
- * The vars parameter will be used in the messanger assign vars, which will act
- * as the common vars when sending out the notifications. Data such as the MOD's
- * or Style's name should go here, what action was taken, etc. The usernaeme and
- * emails of the recepiants will be personalised by the function. Ensure the
- * email template has the {USERNAME} var present.
- *
- * @param $exclude_user User_id of the one who posted the item to exclude them from the sending
+ * Watchers of the given watch pairs receive the notification through the
+ * delivery methods they enabled in the UCP (board and/or email); the email
+ * method renders the same Titania email templates the legacy dispatcher
+ * used, with the same variables plus USERNAME added by the core.
*
+ * @param string $type Titania notification type suffix
+ * (posted|contribution|queue|queue_move|attention)
+ * @param array $type_data Notification data:
+ * 'item_id' int the notified item (post, revision, queue, attention id)
+ * 'item_parent_id' int its parent (optional)
+ * 'watch' array of array(watch_object_type, watch_object_id)
+ * pairs selecting the recipients
+ * 'exclude_user' int user to exclude, normally the acting user (optional)
+ * 'lang_key' string language key for the board notification title
+ * 'lang_params' array parameters for the language key (optional)
+ * 'url' string url the notification links to
+ * 'email_template' string Titania email template name
+ * 'email_vars' array variables for the email template (optional)
+ * 'actor_id' int user shown as the notification's actor (optional)
*/
- public function send_notifications($object_type, $object_id, $email_tpl, $vars, $exclude_user = false)
+ public function send_notifications($type, array $type_data)
{
- $sql = 'SELECT w.watch_user_id, w.watch_type, u.user_id, u.username, u.user_email, u.user_lang
- FROM ' . $this->watch_table . ' w, ' . $this->users_table . ' u
- WHERE w.watch_user_id = u.user_id ';
-
- if (is_array($object_type) || is_array($object_id))
- {
- // Both needs to be arrays if one is and they need to have the same number of elements.
- if (!is_array($object_type) || !is_array($object_id) || sizeof($object_type) != sizeof($object_id))
- {
- return;
- }
-
- $sql_objects = '';
- foreach ($object_type as $key => $value)
- {
- $sql_objects .= (($sql_objects == '') ? '' : ' OR ') . '(w.watch_object_type = ' . (int) $value . '
- AND w.watch_object_id = ' . (int) $object_id[$key] . ')';
- }
- $sql .= 'AND (' . $sql_objects . ')';
-
- unset($sql_objects);
- }
- else
- {
- $sql .= 'AND w.watch_object_type = ' . (int) $object_type . '
- AND w.watch_object_id = ' . (int) $object_id;
- }
- $sql .= ($exclude_user) ? ' AND w.watch_user_id <> ' . (int) $exclude_user : '';
-
- $result = $this->db->sql_query($sql);
-
- // Throw everything here
- $user_data = array();
- while ($row = $this->db->sql_fetchrow($result))
- {
- // Use user_id for the keys to not send duplicates.
- $user_data[$row['user_id']] = array(
- 'username' => $row['username'],
- 'user_email' => $row['user_email'],
- 'user_lang' => $row['user_lang'],
- 'watch_type' => $row['watch_type'],
- );
- }
- $this->db->sql_freeresult($result);
-
- // No one subscribed? We're done.
- if (empty($user_data))
- {
- return;
- }
- $messenger = null;
-
- // Send to each user
- // Add a new case statment for each subscription type
- foreach ($user_data as $data)
+ // A stored notification url must never carry a session id
+ if (!empty($type_data['url']))
{
- /*
- * Switch between the types.
- * ------------------------------------------
- * When adding a type, the final message will
- * be stored in $message, and the subject is
- * stored in $vars['SUBJECT'].
- */
- switch($data['watch_type'])
- {
- case self::EMAIL:
-
- if ($messenger === null)
- {
- // Only make the object if we need it
- if (!class_exists('\messenger'))
- {
- require($this->phpbb_root_path . 'includes/functions_messenger.' . $this->php_ext);
- }
- $messenger = new \messenger;
- }
-
- $messenger->anti_abuse_headers($this->config, $this->user);
- $messenger->template('@phpbb_titania/' . $email_tpl, $data['user_lang']);
- $messenger->to($data['user_email'], $data['username']);
- $messenger->assign_vars(array_merge($vars, array(
- 'USERNAME' => $data['username'],
- )));
-
- $messenger->send();
- $messenger->save_queue();
- break;
- }
+ $type_data['url'] = $this->path_helper->strip_url_params($type_data['url'], 'sid');
}
- return;
+ $this->notification_manager->add_notifications('phpbb.titania.notification.type.' . $type, $type_data);
}
}