diff --git a/phpBB/config/default/container/services_notification.yml b/phpBB/config/default/container/services_notification.yml
index c18e358114..65552b1e13 100644
--- a/phpBB/config/default/container/services_notification.yml
+++ b/phpBB/config/default/container/services_notification.yml
@@ -95,6 +95,15 @@ services:
tags:
- { name: notification.type }
+ notification.type.mention:
+ class: phpbb\notification\type\mention
+ shared: false
+ parent: notification.type.post
+ calls:
+ - [set_helper, ['@text_formatter.s9e.mention_helper']]
+ tags:
+ - { name: notification.type }
+
notification.type.pm:
class: phpbb\notification\type\pm
shared: false
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index adc09b9382..c7c6375b06 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -575,6 +575,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
// Mark all topic notifications read for this user
$phpbb_notifications->mark_notifications(array(
'notification.type.topic',
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -660,6 +661,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
$db->sql_freeresult($result);
$phpbb_notifications->mark_notifications_by_parent(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -771,6 +773,7 @@ function markread($mode, $forum_id = false, $topic_id = false, $post_time = 0, $
), $topic_id, $user->data['user_id'], $post_time);
$phpbb_notifications->mark_notifications_by_parent(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
diff --git a/phpBB/includes/functions_admin.php b/phpBB/includes/functions_admin.php
index dc76a2eb80..f0813708c3 100644
--- a/phpBB/includes/functions_admin.php
+++ b/phpBB/includes/functions_admin.php
@@ -908,6 +908,7 @@ function delete_posts($where_type, $where_ids, $auto_sync = true, $posted_sync =
// Notifications types to delete
$delete_notifications_types = array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.approve_post',
'notification.type.post_in_queue',
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 817a98f836..14b50a4a31 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -2405,6 +2405,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
{
case 'post':
$phpbb_notifications->add_notifications(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.topic',
), $notification_data);
@@ -2413,6 +2414,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
case 'reply':
case 'quote':
$phpbb_notifications->add_notifications(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -2432,6 +2434,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
}
$phpbb_notifications->update_notifications(array(
+ 'notification.type.mention',
'notification.type.bookmark',
'notification.type.topic',
'notification.type.post',
diff --git a/phpBB/includes/mcp/mcp_queue.php b/phpBB/includes/mcp/mcp_queue.php
index fe54a01de7..eebb8e4fc4 100644
--- a/phpBB/includes/mcp/mcp_queue.php
+++ b/phpBB/includes/mcp/mcp_queue.php
@@ -810,10 +810,14 @@ class mcp_queue
), $post_data);
}
}
- $phpbb_notifications->add_notifications(array('notification.type.quote'), $post_data);
+ $phpbb_notifications->add_notifications(array(
+ 'notification.type.mention',
+ 'notification.type.quote',
+ ), $post_data);
$phpbb_notifications->delete_notifications('notification.type.post_in_queue', $post_id);
$phpbb_notifications->mark_notifications(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.bookmark',
'notification.type.post',
@@ -1045,12 +1049,13 @@ class mcp_queue
if ($topic_data['topic_visibility'] == ITEM_UNAPPROVED)
{
$phpbb_notifications->add_notifications(array(
+ 'notification.type.mention',
'notification.type.quote',
'notification.type.topic',
), $topic_data);
}
- $phpbb_notifications->mark_notifications('quote', $topic_data['post_id'], $user->data['user_id']);
+ $phpbb_notifications->mark_notifications(array('mention', 'quote'), $topic_data['post_id'], $user->data['user_id']);
$phpbb_notifications->mark_notifications('topic', $topic_id, $user->data['user_id']);
if ($notify_poster)
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 24fd293326..f04a0e891b 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -475,6 +475,9 @@ $lang = array_merge($lang, array(
'NOTIFICATION_FORUM' => 'Forum: %1$s',
'NOTIFICATION_GROUP_REQUEST' => 'Group request from %1$s to join the group %2$s.',
'NOTIFICATION_GROUP_REQUEST_APPROVED' => 'Group request approved to join the group %1$s.',
+ 'NOTIFICATION_MENTION' => array(
+ 1 => 'Mentioned by %1$s in:',
+ ),
'NOTIFICATION_METHOD_INVALID' => 'The method "%s" does not refer to a valid notification method.',
'NOTIFICATION_PM' => 'Private Message from %1$s:',
'NOTIFICATION_POST' => array(
diff --git a/phpBB/language/en/email/mention.txt b/phpBB/language/en/email/mention.txt
new file mode 100644
index 0000000000..51c161453e
--- /dev/null
+++ b/phpBB/language/en/email/mention.txt
@@ -0,0 +1,20 @@
+Subject: Topic reply notification - "{TOPIC_TITLE}"
+
+Hello {USERNAME},
+
+You are receiving this notification because "{AUTHOR_NAME}" mentioned you in the topic "{TOPIC_TITLE}" at "{SITENAME}". You can use the following link to view the reply made.
+
+If you want to view the post where you have been mentioned, click the following link:
+{U_VIEW_POST}
+
+If you want to view the topic, click the following link:
+{U_TOPIC}
+
+If you want to view the forum, click the following link:
+{U_FORUM}
+
+If you no longer wish to receive updates about replies mentioning you, please update your notification settings here:
+
+{U_NOTIFICATION_SETTINGS}
+
+{EMAIL_SIG}
diff --git a/phpBB/language/en/ucp.php b/phpBB/language/en/ucp.php
index 446f357f5d..8c4e59904c 100644
--- a/phpBB/language/en/ucp.php
+++ b/phpBB/language/en/ucp.php
@@ -332,6 +332,7 @@ $lang = array_merge($lang, array(
'NOTIFICATION_TYPE_GROUP_REQUEST' => 'Someone requests to join a group you lead',
'NOTIFICATION_TYPE_FORUM' => 'Someone replies to a topic in a forum to which you are subscribed',
'NOTIFICATION_TYPE_IN_MODERATION_QUEUE' => 'A post or topic needs approval',
+ 'NOTIFICATION_TYPE_MENTION' => 'Someone mentiones you in a post',
'NOTIFICATION_TYPE_MODERATION_QUEUE' => 'Your topics/posts are approved or disapproved by a moderator',
'NOTIFICATION_TYPE_PM' => 'Someone sends you a private message',
'NOTIFICATION_TYPE_POST' => 'Someone replies to a topic to which you are subscribed',
diff --git a/phpBB/phpbb/notification/type/mention.php b/phpBB/phpbb/notification/type/mention.php
new file mode 100644
index 0000000000..54c180ad2c
--- /dev/null
+++ b/phpBB/phpbb/notification/type/mention.php
@@ -0,0 +1,172 @@
+
+* @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\notification\type;
+
+/**
+* Post mentioning notifications class
+* This class handles notifying users when they have been mentioned in a post
+*/
+
+class mention extends \phpbb\notification\type\post
+{
+ /**
+ * @var \phpbb\textformatter\s9e\mention_helper
+ */
+ protected $helper;
+
+ /**
+ * Get notification type name
+ *
+ * @return string
+ */
+ public function get_type()
+ {
+ return 'notification.type.mention';
+ }
+
+ /**
+ * Language key used to output the text
+ *
+ * @var string
+ */
+ protected $language_key = 'NOTIFICATION_MENTION';
+
+ /**
+ * Notification option data (for outputting to the user)
+ *
+ * @var bool|array False if the service should use it's default data
+ * Array of data (including keys 'id', 'lang', and 'group')
+ */
+ static public $notification_option = array(
+ 'lang' => 'NOTIFICATION_TYPE_MENTION',
+ 'group' => 'NOTIFICATION_GROUP_POSTING',
+ );
+
+ /**
+ * Is available
+ */
+ public function is_available()
+ {
+ return true;
+ }
+
+ /**
+ * Find the users who want to receive notifications
+ *
+ * @param array $post Data from submit_post
+ * @param array $options Options for finding users for notification
+ *
+ * @return array
+ */
+ public function find_users_for_notification($post, $options = array())
+ {
+ $options = array_merge(array(
+ 'ignore_users' => array(),
+ ), $options);
+
+ $user_ids = $this->helper->get_mentioned_users($post['post_text']);
+
+ $user_ids = array_unique($user_ids);
+
+ $user_ids = array_diff($user_ids, [(int) $post['poster_id']]);
+
+ if (empty($user_ids))
+ {
+ return array();
+ }
+
+ return $this->get_authorised_recipients($user_ids, $post['forum_id'], $options, true);
+ }
+
+ /**
+ * Update a notification
+ * TODO: decide what to do with this stuff
+ *
+ * @param array $post Data specific for this type that will be updated
+ * @return true
+ */
+ public function update_notifications($post)
+ {
+ $old_notifications = $this->notification_manager->get_notified_users($this->get_type(), array(
+ 'item_id' => static::get_item_id($post),
+ ));
+
+ // Find the new users to notify
+ $notifications = $this->find_users_for_notification($post);
+
+ // Find the notifications we must delete
+ $remove_notifications = array_diff(array_keys($old_notifications), array_keys($notifications));
+
+ // Find the notifications we must add
+ $add_notifications = array();
+ foreach (array_diff(array_keys($notifications), array_keys($old_notifications)) as $user_id)
+ {
+ $add_notifications[$user_id] = $notifications[$user_id];
+ }
+
+ // Add the necessary notifications
+ $this->notification_manager->add_notifications_for_users($this->get_type(), $post, $add_notifications);
+
+ // Remove the necessary notifications
+ if (!empty($remove_notifications))
+ {
+ $this->notification_manager->delete_notifications($this->get_type(), static::get_item_id($post), false, $remove_notifications);
+ }
+
+ // return true to continue with the update code in the notifications service (this will update the rest of the notifications)
+ return true;
+ }
+
+ /**
+ * {inheritDoc}
+ */
+ public function get_redirect_url()
+ {
+ return $this->get_url();
+ }
+
+ /**
+ * Get email template
+ *
+ * @return string|bool
+ */
+ public function get_email_template()
+ {
+ return 'mention';
+ }
+
+ /**
+ * Get email template variables
+ *
+ * @return array
+ */
+ public function get_email_template_variables()
+ {
+ $user_data = $this->user_loader->get_user($this->get_data('poster_id'));
+
+ return array_merge(parent::get_email_template_variables(), array(
+ 'AUTHOR_NAME' => htmlspecialchars_decode($user_data['username']),
+ ));
+ }
+
+ /**
+ * Set the helper service used to retrieve mentioned used
+ *
+ * @param \phpbb\textformatter\s9e\mention_helper $helper
+ */
+ public function set_helper(\phpbb\textformatter\s9e\mention_helper $helper)
+ {
+ $this->helper = $helper;
+ }
+}
diff --git a/phpBB/phpbb/textformatter/s9e/mention_helper.php b/phpBB/phpbb/textformatter/s9e/mention_helper.php
index b383dc46f7..66092dbbc5 100644
--- a/phpBB/phpbb/textformatter/s9e/mention_helper.php
+++ b/phpBB/phpbb/textformatter/s9e/mention_helper.php
@@ -149,4 +149,30 @@ class mention_helper
}
);
}
+
+ /**
+ * Get a list of mentioned users
+ * TODO: decide what to do with groups
+ *
+ * @param string $xml Parsed text
+ * @return int[] List of user IDs
+ */
+ public function get_mentioned_users($xml)
+ {
+ $user_ids = array();
+ if (strpos($xml, 'loadXML($xml);
+ $xpath = new \DOMXPath($dom);
+ foreach ($xpath->query('//MENTION/@user_id') as $user_id)
+ {
+ $user_ids[] = (int) $user_id->textContent;
+ }
+
+ return $user_ids;
+ }
}