diff --git a/README.md b/README.md
index 6dfef17..7542727 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ A wiki for phpBB with version history, side-by-side compare, and a moderation qu
- A contributions page for every member, at `/wiki/contributions/`, lists every version they saved across all articles, newest first. Author names on articles and in the version history link to it. Versions waiting for approval, and those of switched-off articles, show only to moderators and to the author.
- Files can be uploaded to an article by members who hold the **Can upload files to articles** permission. They are checked against the board's allowed file types and size limit, stored outside public view under `store/phpbbmodders_wiki/`, and read only through the wiki, which checks that the reader may see the article. In the text, `[[File:Diagram.png]]` shows an uploaded image and `[[File:notes.zip|the notes]]` links to any other file. The member who uploaded a file, or a moderator who may delete versions, can remove it, and deleting an article deletes its files.
- Notifications when an edit is waiting for approval.
+- **Watch article** on every article page, for signed-in members: they are notified when a new version of a watched article goes live (a moderator approved an edit, or a trusted editor's edit went live directly), never about their own edit. It is a notification type in phpBB's notification settings, so members choose the bell, email or both. With the ACP setting **Watch edited articles** (on by default, under **Extensions > Wiki > Settings**), saving an edit also starts watching the article. Watches are removed with the article and with the member.
- The Wiki link in the board header shows the Wikipedia icon by default. Under **Extensions > Wiki > Settings** in the ACP the icon can be changed to any [Font Awesome](https://fontawesome.com/v4.7.0/icons/) icon name, or left blank for no icon.
- A **Start discussion** button on each article creates its discussion topic in a forum chosen under **Extensions > Wiki > Settings** in the ACP, and links the topic to the article. It shows to members who hold the "Can change the discussion topic for an article" permission and may post in that forum, and stays hidden until a forum is chosen.
- Separate permissions for viewing, editing, version history, deleting and moderating.
diff --git a/acp/main_module.php b/acp/main_module.php
index 05e37e0..ede38d4 100644
--- a/acp/main_module.php
+++ b/acp/main_module.php
@@ -54,6 +54,7 @@ public function main($id, $mode)
$forum_id = $request->variable('wiki_discussion_forum_id', 0);
$icon = trim($request->variable('wiki_icon', ''));
$feed_format = $request->variable('wiki_feed_format', '');
+ $auto_watch = $request->variable('wiki_auto_watch', 0) ? 1 : 0;
if (!\phpbbmodders\wiki\wiki\feed::is_valid_setting($feed_format))
{
@@ -85,6 +86,7 @@ public function main($id, $mode)
$config->set('wiki_discussion_forum_id', $forum_id);
$config->set('wiki_icon', $icon);
$config->set('wiki_feed_format', $feed_format);
+ $config->set('wiki_auto_watch', $auto_watch);
trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($this->u_action));
}
@@ -98,6 +100,7 @@ public function main($id, $mode)
$template->assign_vars(array(
'S_WIKI_FEED_OPTIONS' => $feed_options,
+ 'S_WIKI_AUTO_WATCH' => !isset($config['wiki_auto_watch']) || !empty($config['wiki_auto_watch']),
'WIKI_ICON' => isset($config['wiki_icon']) ? $config['wiki_icon'] : \phpbbmodders\wiki\wiki\icon::DEFAULT_ICON,
'U_ACTION' => $this->u_action,
'S_WIKI_FORUM_OPTIONS' => ''
diff --git a/adm/style/acp_wiki_settings.html b/adm/style/acp_wiki_settings.html
index 5472513..20aec56 100644
--- a/adm/style/acp_wiki_settings.html
+++ b/adm/style/acp_wiki_settings.html
@@ -12,6 +12,13 @@
{L_ACP_WIKI_SETTINGS}
{L_WIKI_ICON_EXPLAIN}
+
+
{L_WIKI_AUTO_WATCH_EXPLAIN}
+
+
+
+
+
{L_WIKI_FEED_FORMAT_EXPLAIN}
diff --git a/config/services.yml b/config/services.yml
index 5e0c483..9161bf9 100644
--- a/config/services.yml
+++ b/config/services.yml
@@ -1,6 +1,7 @@
parameters:
tables.wiki.article: '%core.table_prefix%wiki_article'
tables.wiki.file: '%core.table_prefix%wiki_file'
+ tables.wiki.watch: '%core.table_prefix%wiki_watch'
services:
_defaults:
@@ -52,6 +53,18 @@ services:
- '%core.root_path%'
- '%core.php_ext%'
+ phpbbmodders.wiki.watch:
+ class: phpbbmodders\wiki\wiki\watch
+ arguments:
+ - '@auth'
+ - '@dbal.conn'
+ - '@controller.helper'
+ - '@request'
+ - '@template'
+ - '@user'
+ - '%tables.wiki.watch%'
+ - '%tables.wiki.article%'
+
phpbbmodders.wiki.files:
class: phpbbmodders\wiki\wiki\files
arguments:
@@ -83,6 +96,7 @@ services:
- '@phpbbmodders.wiki.view'
- '@phpbbmodders.wiki.discussion'
- '@phpbbmodders.wiki.files'
+ - '@phpbbmodders.wiki.watch'
- '%core.root_path%'
- '%core.php_ext%'
phpbbmodders.wiki.listener:
@@ -94,6 +108,7 @@ services:
- '@notification_manager'
- '@template'
- '@user'
+ - '@phpbbmodders.wiki.watch'
tags:
- { name: event.listener }
phpbbmodders.wiki.edit:
@@ -110,6 +125,7 @@ services:
- '%tables.wiki.article%'
- '%core.root_path%'
- '%core.php_ext%'
+ - '@phpbbmodders.wiki.watch'
phpbbmodders.wiki.compare:
class: phpbbmodders\wiki\wiki\compare
arguments:
@@ -134,6 +150,7 @@ services:
- '%tables.wiki.article%'
- '@phpbbmodders.wiki.files'
- '@request'
+ - '@phpbbmodders.wiki.watch'
phpbbmodders.wiki.view:
class: phpbbmodders\wiki\wiki\view
arguments:
@@ -150,6 +167,7 @@ services:
- '@phpbbmodders.wiki.links'
- '@phpbbmodders.wiki.discussion'
- '@phpbbmodders.wiki.files'
+ - '@phpbbmodders.wiki.watch'
phpbbmodders.wiki.discussion:
class: phpbbmodders\wiki\wiki\discussion
arguments:
@@ -196,4 +214,16 @@ services:
calls:
- [set_name, [phpbbmodders_wiki_article]]
tags:
- - { name: text_reparser.plugin}
\ No newline at end of file
+ - { name: text_reparser.plugin}
+ phpbbmodders.wiki.notification.type.article_watch:
+ class: phpbbmodders\wiki\notification\article_watch
+ parent: notification.type.base
+ # Symfony 3.4 (phpBB 3.3.x) does not let a service with a parent take "public" from _defaults.
+ public: true
+ shared: false
+ calls:
+ - [set_user_loader, ['@user_loader']]
+ - [set_helper, ['@controller.helper']]
+ - [set_watch, ['@phpbbmodders.wiki.watch']]
+ tags:
+ - { name: notification.type }
diff --git a/controller/main.php b/controller/main.php
index 8a6c54f..0610f81 100644
--- a/controller/main.php
+++ b/controller/main.php
@@ -45,6 +45,9 @@ class main
/** @var \phpbbmodders\wiki\wiki\files */
protected $files;
+ /** @var \phpbbmodders\wiki\wiki\watch */
+ protected $watch;
+
/** @var string phpbb_root_path */
protected $phpbb_root_path;
@@ -65,10 +68,11 @@ class main
* @param \phpbbmodders\wiki\wiki\view $view View Wiki object
* @param \phpbbmodders\wiki\wiki\discussion $discussion Start discussion object
* @param \phpbbmodders\wiki\wiki\files $files Uploaded files object
+ * @param \phpbbmodders\wiki\wiki\watch $watch Watched articles object
* @param string $phpbb_root_path
* @param string $php_ext
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\controller\helper $helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, \phpbbmodders\wiki\wiki\delete $delete, \phpbbmodders\wiki\wiki\edit $edit, \phpbbmodders\wiki\wiki\compare $compare, \phpbbmodders\wiki\wiki\view $view, \phpbbmodders\wiki\wiki\discussion $discussion, \phpbbmodders\wiki\wiki\files $files, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\controller\helper $helper, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, \phpbbmodders\wiki\wiki\delete $delete, \phpbbmodders\wiki\wiki\edit $edit, \phpbbmodders\wiki\wiki\compare $compare, \phpbbmodders\wiki\wiki\view $view, \phpbbmodders\wiki\wiki\discussion $discussion, \phpbbmodders\wiki\wiki\files $files, \phpbbmodders\wiki\wiki\watch $watch, $phpbb_root_path, $php_ext)
{
$this->auth = $auth;
$this->helper = $helper;
@@ -81,6 +85,7 @@ public function __construct(\phpbb\auth\auth $auth, \phpbb\controller\helper $he
$this->view = $view;
$this->discussion = $discussion;
$this->files = $files;
+ $this->watch = $watch;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
@@ -154,6 +159,12 @@ public function article($article)
case 'start_discussion':
return $this->discussion->start($article);
+ case 'watch':
+ return $this->watch->handle($article, true);
+
+ case 'unwatch':
+ return $this->watch->handle($article, false);
+
case 'upload':
return $this->files->upload($article);
diff --git a/docs/TODO.md b/docs/TODO.md
index 05227d1..6f2163a 100644
--- a/docs/TODO.md
+++ b/docs/TODO.md
@@ -53,14 +53,6 @@ new URL and losing the connection to its history. Needs a "move" action
permission) that renames `article_url` across all of an article's versions
and optionally leaves a redirect stub at the old URL.
-## Watch/subscribe to an article
-
-The existing notification type only fires for "pending approval" (aimed at
-moderators). Regular readers have no way to ask "notify me when this
-specific article changes" the way forum topic-watching works. Would need a
-second notification type plus a subscribe/unsubscribe action on the article
-view page.
-
## Categories/tags
Browsing is flat today — Popular/Latest/All/Sticky/Pending on the overview
diff --git a/event/listener.php b/event/listener.php
index 684825f..55d8726 100644
--- a/event/listener.php
+++ b/event/listener.php
@@ -26,6 +26,9 @@ class listener implements EventSubscriberInterface
/** @var \phpbb\config\config */
protected $config;
+ /** @var \phpbbmodders\wiki\wiki\watch */
+ protected $watch;
+
/** @var \phpbb\controller\helper */
protected $helper;
@@ -48,8 +51,9 @@ class listener implements EventSubscriberInterface
* @param \phpbb\template $template Template object
* @param \phpbb\user $user User object
*/
- public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\controller\helper $helper, \phpbb\notification\manager $notification_manager, \phpbb\template\template $template, \phpbb\user $user)
+ public function __construct(\phpbb\auth\auth $auth, \phpbb\config\config $config, \phpbb\controller\helper $helper, \phpbb\notification\manager $notification_manager, \phpbb\template\template $template, \phpbb\user $user, \phpbbmodders\wiki\wiki\watch $watch)
{
+ $this->watch = $watch;
$this->auth = $auth;
$this->config = $config;
$this->helper = $helper;
@@ -64,6 +68,7 @@ public static function getSubscribedEvents()
'core.page_header' => 'page_header',
'core.permissions' => 'permissions',
'core.user_setup' => 'user_setup',
+ 'core.delete_user_after' => 'delete_user_after',
);
}
@@ -193,4 +198,15 @@ public function user_setup($event)
$event['lang_set_ext'] = $lang_ary;
}
+
+ /**
+ * A deleted member no longer watches anything.
+ *
+ * @param \phpbb\event\data $event The event object
+ * @return void
+ */
+ public function delete_user_after($event)
+ {
+ $this->watch->delete_for_users(array_map('intval', (array) $event['user_ids']));
+ }
}
diff --git a/ext.php b/ext.php
index dc9a01e..c9c344e 100644
--- a/ext.php
+++ b/ext.php
@@ -46,6 +46,9 @@ class ext extends \phpbb\extension\base
];
const NEW_NOTIFICATION_TYPE = 'phpbbmodders.wiki.notification.type.article_edit';
+ /** Notification type that tells watchers a new version went live */
+ const WATCH_NOTIFICATION_TYPE = 'phpbbmodders.wiki.notification.type.article_watch';
+
/** Text reparser service name (the key of its CLI resume data) before and after the rename */
const OLD_REPARSER_NAME = 'tas2580.wiki.text_reparser.article_text';
const NEW_REPARSER_NAME = 'phpbbmodders.wiki.text_reparser.article_text';
@@ -120,7 +123,7 @@ public function enable_step($old_state)
{
case false:
case '':
- return $this->notification_handler('enable', [self::NEW_NOTIFICATION_TYPE]);
+ return $this->notification_handler('enable', [self::NEW_NOTIFICATION_TYPE, self::WATCH_NOTIFICATION_TYPE]);
default:
return parent::enable_step($old_state);
@@ -139,7 +142,7 @@ public function disable_step($old_state)
{
case false:
case '':
- return $this->notification_handler('disable', [self::NEW_NOTIFICATION_TYPE]);
+ return $this->notification_handler('disable', [self::NEW_NOTIFICATION_TYPE, self::WATCH_NOTIFICATION_TYPE]);
default:
return parent::disable_step($old_state);
@@ -158,7 +161,7 @@ public function purge_step($old_state)
{
case false:
case '':
- return $this->notification_handler('purge', [self::NEW_NOTIFICATION_TYPE]);
+ return $this->notification_handler('purge', [self::NEW_NOTIFICATION_TYPE, self::WATCH_NOTIFICATION_TYPE]);
default:
return parent::purge_step($old_state);
diff --git a/language/de/acp_wiki.php b/language/de/acp_wiki.php
index df043ba..4c7ba51 100644
--- a/language/de/acp_wiki.php
+++ b/language/de/acp_wiki.php
@@ -23,6 +23,8 @@
'WIKI_ICON' => 'Symbol des Kopfzeilen-Links',
'WIKI_ICON_EXPLAIN' => 'Gib den Namen eines Font-Awesome-Symbols für den Wiki-Link in der Kopfzeile des Forums ein. Standard ist wikipedia-w. Lass das Feld leer, um kein Symbol anzuzeigen.',
'WIKI_ICON_INVALID' => 'Das Symbol des Wiki-Links enthält ungültige Zeichen.',
+ 'WIKI_AUTO_WATCH' => 'Bearbeitete Artikel beobachten',
+ 'WIKI_AUTO_WATCH_EXPLAIN' => 'Wenn aktiv, beobachtet ein Mitglied einen Artikel automatisch, sobald es eine Bearbeitung speichert, und wird benachrichtigt, wenn eine neue Version aktiv wird. Das Beobachten kann im Artikel beendet werden.',
'WIKI_FEED_FORMAT' => 'Feed der letzten Änderungen',
'WIKI_FEED_FORMAT_EXPLAIN' => 'Welche Feed-Formate die Seite „Letzte Änderungen“ anbietet und die Kopfzeile Feed-Readern mitteilt.',
'WIKI_FEED_FORMAT_BOTH' => 'RSS und Atom',
diff --git a/language/de/common.php b/language/de/common.php
index d0cf3c5..b426858 100644
--- a/language/de/common.php
+++ b/language/de/common.php
@@ -61,6 +61,10 @@
'CONTRIBUTIONS_SAVED' => 'Gespeichert',
'CONTRIBUTIONS_STATUS' => 'Status',
'CONTRIBUTIONS_NONE' => 'Es gibt keine Versionen, die angezeigt werden können.',
+ 'WIKI_WATCH' => 'Artikel beobachten',
+ 'WIKI_UNWATCH' => 'Nicht mehr beobachten',
+ 'WIKI_NOW_WATCHING' => 'Du beobachtest diesen Artikel jetzt. Du wirst benachrichtigt, wenn eine neue Version aktiv wird.',
+ 'WIKI_NO_LONGER_WATCHING' => 'Du beobachtest diesen Artikel nicht mehr.',
'WIKI_RECENT_CHANGES' => 'Letzte Änderungen',
'WIKI_RECENT_CHANGES_EXPLAIN' => 'Jede im Wiki gespeicherte Version, die aktiv ist oder war, die neuesten zuerst.',
'WIKI_FEED_RSS_LINK' => 'RSS-Feed',
diff --git a/language/de/email/mail_article_watch.txt b/language/de/email/mail_article_watch.txt
new file mode 100644
index 0000000..3358527
--- /dev/null
+++ b/language/de/email/mail_article_watch.txt
@@ -0,0 +1,14 @@
+Subject: "{SITENAME}" — Beobachteter Wiki-Artikel aktualisiert
+
+Hallo {USERNAME},
+
+{NOTIFICATION_SUBJECT}
+
+Artikel ansehen: {U_LINK}
+
+Du erhältst diese Nachricht, weil du den Artikel beobachtest. Beende das Beobachten auf der Artikelseite oder ändere die Benachrichtigungen in deinen Benachrichtigungseinstellungen im Kontrollzentrum.
+
+Zur Forenübersicht:
+{U_INDEX}
+
+{EMAIL_SIG}
diff --git a/language/de/link.php b/language/de/link.php
index 6e6f2be..435cec5 100644
--- a/language/de/link.php
+++ b/language/de/link.php
@@ -36,5 +36,7 @@
$lang = array_merge($lang, array(
'WIKI' => 'KB',
'WIKI_NEW_ARTICLE_UPDATE' => 'Ein neue Version zum Artikel %1$s in der KB wartet auf Freischaltung.',
+ 'WIKI_WATCHED_ARTICLE' => 'Ein Wiki-Artikel, den du beobachtest, hat eine neue Version',
+ 'WIKI_WATCHED_ARTICLE_LIVE' => 'Eine neue Version des Wiki-Artikels %1$s ist jetzt aktiv.',
));
diff --git a/language/en/acp_wiki.php b/language/en/acp_wiki.php
index 1fe82ad..627d73b 100644
--- a/language/en/acp_wiki.php
+++ b/language/en/acp_wiki.php
@@ -23,6 +23,8 @@
'WIKI_ICON' => 'Header link icon',
'WIKI_ICON_EXPLAIN' => 'Enter the name of a Font Awesome icon to use for the Wiki link in the board header. The default is wikipedia-w. Leave this field blank for no icon.',
'WIKI_ICON_INVALID' => 'The Wiki link icon contains invalid characters.',
+ 'WIKI_AUTO_WATCH' => 'Watch edited articles',
+ 'WIKI_AUTO_WATCH_EXPLAIN' => 'When on, a member who saves an edit also starts watching that article and is notified when a new version goes live. They can stop watching from the article.',
'WIKI_FEED_FORMAT' => 'Recent changes feed',
'WIKI_FEED_FORMAT_EXPLAIN' => 'Which feed formats the Recent changes page offers, and the header advertises to feed readers.',
'WIKI_FEED_FORMAT_BOTH' => 'RSS and Atom',
diff --git a/language/en/common.php b/language/en/common.php
index c9a83a9..83ba920 100644
--- a/language/en/common.php
+++ b/language/en/common.php
@@ -101,6 +101,10 @@
'CONTRIBUTIONS_SAVED' => 'Saved',
'CONTRIBUTIONS_STATUS' => 'Status',
'CONTRIBUTIONS_NONE' => 'There are no versions to show.',
+ 'WIKI_WATCH' => 'Watch article',
+ 'WIKI_UNWATCH' => 'Stop watching',
+ 'WIKI_NOW_WATCHING' => 'You are now watching this article. You will be notified when a new version goes live.',
+ 'WIKI_NO_LONGER_WATCHING' => 'You are no longer watching this article.',
'WIKI_RECENT_CHANGES' => 'Recent changes',
'WIKI_RECENT_CHANGES_EXPLAIN' => 'Every version saved to the wiki that is or was live, newest first.',
'WIKI_FEED_RSS_LINK' => 'RSS feed',
diff --git a/language/en/email/mail_article_watch.txt b/language/en/email/mail_article_watch.txt
new file mode 100644
index 0000000..b34a3a3
--- /dev/null
+++ b/language/en/email/mail_article_watch.txt
@@ -0,0 +1,14 @@
+Subject: "{SITENAME}" — Watched wiki article updated
+
+Hello {USERNAME},
+
+{NOTIFICATION_SUBJECT}
+
+View the article: {U_LINK}
+
+You are receiving this because you watch the article. Stop watching it from the article page, or change how you are notified under Notification settings in your control panel.
+
+Board index:
+{U_INDEX}
+
+{EMAIL_SIG}
diff --git a/language/en/link.php b/language/en/link.php
index 34bad89..cefa566 100644
--- a/language/en/link.php
+++ b/language/en/link.php
@@ -36,6 +36,9 @@
$lang = array_merge($lang, array(
'WIKI' => 'Wiki',
'WIKI_NEW_ARTICLE_UPDATE' => 'A new version of the article %1$s in the Wiki is awaiting approval.',
+ 'WIKI_ARTICLE_UPDATE' => 'An edit of a wiki article is awaiting approval',
+ 'WIKI_WATCHED_ARTICLE' => 'A wiki article you watch has a new version',
+ 'WIKI_WATCHED_ARTICLE_LIVE' => 'A new version of the wiki article %1$s is now live.',
'WIKI_LINK_BUTTON' => 'Wiki link: [[Article name]] or [[Article name|link text]]',
'WIKI_LINK_NEW_ARTICLE' => 'This article doesn’t exist yet. Follow the link to create it.',
'WIKI_WHAT_LINKS_HERE' => 'What links here',
diff --git a/migrations/add_article_watch.php b/migrations/add_article_watch.php
new file mode 100644
index 0000000..50d9ec9
--- /dev/null
+++ b/migrations/add_article_watch.php
@@ -0,0 +1,62 @@
+ array(
+ $this->table_prefix . 'wiki_watch' => array(
+ 'COLUMNS' => array(
+ 'watch_id' => array('UINT', null, 'auto_increment'),
+ 'user_id' => array('UINT', 0),
+ // The article's URL name: a watch follows the article, not one version of it
+ 'article_url' => array('VCHAR:255', ''),
+ 'watch_time' => array('TIMESTAMP', 0),
+ ),
+ 'PRIMARY_KEY' => 'watch_id',
+ 'KEYS' => array(
+ 'user_id' => array('INDEX', 'user_id'),
+ ),
+ ),
+ ),
+ );
+ }
+
+ public function revert_schema()
+ {
+ return array(
+ 'drop_tables' => array(
+ $this->table_prefix . 'wiki_watch',
+ ),
+ );
+ }
+
+ public function update_data()
+ {
+ return array(
+ // 1: saving an edit also watches the article; an administrator can turn it off
+ array('config.add', array('wiki_auto_watch', 1)),
+ );
+ }
+}
diff --git a/notification/article_watch.php b/notification/article_watch.php
new file mode 100644
index 0000000..4200ae5
--- /dev/null
+++ b/notification/article_watch.php
@@ -0,0 +1,82 @@
+ 'WIKI_WATCHED_ARTICLE',
+ 'group' => 'NOTIFICATION_GROUP_MISCELLANEOUS',
+ );
+
+ /** @var \phpbbmodders\wiki\wiki\watch */
+ protected $watch;
+
+ /**
+ * @param \phpbbmodders\wiki\wiki\watch $watch
+ * @return void
+ */
+ public function set_watch(\phpbbmodders\wiki\wiki\watch $watch)
+ {
+ $this->watch = $watch;
+ }
+
+ /**
+ * Who is told: the article's watchers who may view the wiki, minus the editor.
+ *
+ * @param array $notification_data article_id, article_title, article_url, user_id (the editor)
+ * @param array $options
+ * @return array
+ */
+ public function find_users_for_notification($notification_data, $options = array())
+ {
+ $options = array_merge(array(
+ 'ignore_users' => array(),
+ ), $options);
+
+ $watchers = array_diff($this->watch->get_watchers($notification_data['article_url']), array((int) $notification_data['user_id']));
+ if (!$watchers)
+ {
+ return array();
+ }
+
+ $allowed = $this->auth->acl_get_list($watchers, $this->permission);
+ $users = !empty($allowed[0][$this->permission]) ? $allowed[0][$this->permission] : array();
+
+ return $this->check_user_notification_options(array_unique($users), $options);
+ }
+
+ /**
+ * @return string
+ */
+ public function get_type()
+ {
+ return 'phpbbmodders.wiki.notification.type.article_watch';
+ }
+
+ /**
+ * @return string
+ */
+ public function get_email_template()
+ {
+ return '@phpbbmodders_wiki/mail_article_watch';
+ }
+}
diff --git a/styles/prosilver/template/article_body.html b/styles/prosilver/template/article_body.html
index 8cfcf1c..2df1dfb 100644
--- a/styles/prosilver/template/article_body.html
+++ b/styles/prosilver/template/article_body.html
@@ -9,7 +9,7 @@