r40365 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r40364‎ | r40365 | r40366 >
Date:08:11, 3 September 2008
Author:nad
Status:old
Tags:
Comment:
New extension to be notified of membership changes to watched categroies. See MW:Extension:CategoryWatch for details
Modified paths:
  • /trunk/extensions/CategoryWatch (added) (history)
  • /trunk/extensions/CategoryWatch/CategoryWatch.php (added) (history)

Diff [purge]

Index: trunk/extensions/CategoryWatch/CategoryWatch.php
@@ -0,0 +1,162 @@
 2+<?php
 3+/**
 4+ * CategoryWatch extension
 5+ * - Extends watchlist functionality to include notification about membership changes of watched categories
 6+ *
 7+ * See http://www.mediawiki.org/Extension:CategoryWatch for installation and usage details
 8+ * See http://www.organicdesign.co.nz/Extension_talk:CategoryWatch for development notes and disucssion
 9+ * {{Category:Extensions|CategoryWatch}}{{php}}
 10+ * @package MediaWiki
 11+ * @subpackage Extensions
 12+ * @author Aran Dunkley [http://www.organicdesign.co.nz/nad User:Nad]
 13+ * @copyright © 2007 Aran Dunkley
 14+ * @licence GNU General Public Licence 2.0 or later
 15+ */
 16+
 17+if (!defined('MEDIAWIKI')) die('Not an entry point.');
 18+
 19+define('CATEGORYWATCH_VERSION', '0.1.0, 2008-09-03');
 20+
 21+$wgCategoryWatchNotifyEditor = false;
 22+
 23+$wgExtensionFunctions[] = 'wfSetupCategoryWatch';
 24+$wgExtensionCredits['other'][] = array(
 25+ 'name' => 'CategoryWatch',
 26+ 'author' => '[http://www.organicdesign.co.nz/User:Nad User:Nad]',
 27+ 'description' => 'Extends watchlist functionality to include notification about membership changes of watched categories',
 28+ 'url' => 'http://www.mediawiki.org/wiki/Extension:CategoryWatch',
 29+ 'version' => CATEGORYWATCH_VERSION
 30+ );
 31+
 32+class CategoryWatch {
 33+
 34+ function __construct() {
 35+ global $wgHooks;
 36+ $wgHooks['ArticleSave'][] = $this;
 37+ $wgHooks['ArticleSaveComplete'][] = $this;
 38+ }
 39+
 40+ /**
 41+ * Get a list of categories before article updated
 42+ */
 43+ function onArticleSave(&$article, &$user, &$text) {
 44+ $this->before = array();
 45+ $dbr = &wfGetDB(DB_SLAVE);
 46+ $cl = $dbr->tableName('categorylinks');
 47+ $id = $article->getID();
 48+ $res = $dbr->select($cl, 'cl_to', "cl_from = $id", __METHOD__, array('ORDER BY' => 'cl_sortkey'));
 49+ while ($row = $dbr->fetchRow($res)) $this->before[] = $row[0];
 50+ $dbr->freeResult($res);
 51+ return true;
 52+ }
 53+
 54+ /**
 55+ * Find changes in categorisation and send messages to watching users
 56+ */
 57+ function onArticleSaveComplete(&$article, &$user, &$text) {
 58+
 59+ # Get cats after update
 60+ $this->after = array();
 61+ $dbr = &wfGetDB(DB_SLAVE);
 62+ $cl = $dbr->tableName('categorylinks');
 63+ $id = $article->getID();
 64+ $res = $dbr->select($cl, 'cl_to', "cl_from = $id", __METHOD__, array('ORDER BY' => 'cl_sortkey'));
 65+ while ($row = $dbr->fetchRow($res)) $this->after[] = $row[0];
 66+ $dbr->freeResult($res);
 67+
 68+ # Get list of added and removed cats
 69+ $add = array_diff($this->after, $this->before);
 70+ $sub = array_diff($this->before, $this->after);
 71+
 72+ # Notify watchers of each cat about the addition or removal of this article
 73+ $page = $article->getTitle()->getText();
 74+ if (count($add) == 1 && count($sub) == 1) {
 75+ $add = array_shift($add);
 76+ $sub = array_shift($sub);
 77+
 78+ $title = Title::newFromText($add, NS_CATEGORY);
 79+ $message = wfMsg('categorywatch-catmovein', $page, $add, $sub);
 80+ $this->notifyWatchers($title, $user, $message);
 81+
 82+ $title = Title::newFromText($sub, NS_CATEGORY);
 83+ $message = wfMsg('categorywatch-catmoveout', $page, $sub, $add);
 84+ $this->notifyWatchers($title, $user, $message);
 85+ }
 86+ else {
 87+
 88+ foreach ($add as $cat) {
 89+ $title = Title::newFromText($cat, NS_CATEGORY);
 90+ $message = wfMsg('categorywatch-catadd', $page, $cat);
 91+ $this->notifyWatchers($title, $user, $message);
 92+ }
 93+
 94+ foreach ($sub as $cat) {
 95+ $title = Title::newFromText($cat, NS_CATEGORY);
 96+ $message = wfMsg('categorywatch-catsub', $page, $cat);
 97+ $this->notifyWatchers($title, $user, $message);
 98+ }
 99+ }
 100+
 101+ return true;
 102+ }
 103+
 104+ function notifyWatchers(&$title, &$editor, &$message) {
 105+ global $wgLang, $wgEmergencyContact, $wgNoReplyAddress, $wgCategoryWatchNotifyEditor;
 106+
 107+ # Get list of users watching this category
 108+ $dbr = wfGetDB(DB_SLAVE);
 109+ $conds = array('wl_title' => $title->getDBkey(), 'wl_namespace' => $title->getNamespace());
 110+ if (!$wgCategoryWatchNotifyEditor) $conds[] = 'wl_user <> '.intval($editor->getId());
 111+ $res = $dbr->select('watchlist', array('wl_user'), $conds, __METHOD__);
 112+
 113+ # Wrap message with common body and send to each watcher
 114+ $page = $title->getText();
 115+ $from = new MailAddress($wgEmergencyContact, 'WikiAdmin');
 116+ $replyto = new MailAddress($wgNoReplyAddress);
 117+ foreach ($res as $row) {
 118+ $watchingUser = User::newFromId($row->wl_user);
 119+ if ($watchingUser->getOption('enotifwatchlistpages') && $watchingUser->isEmailConfirmed()) {
 120+ $to = new MailAddress($watchingUser);
 121+ $timecorrection = $watchingUser->getOption('timecorrection');
 122+ $editdate = $wgLang->timeanddate(wfTimestampNow(), true, false, $timecorrection);
 123+ $body = wfMsg(
 124+ 'categorywatch-emailbody',
 125+ $watchingUser->getName(),
 126+ $page,
 127+ $editdate,
 128+ $editor->getName(),
 129+ $message
 130+ );
 131+ UserMailer::send(
 132+ $to,
 133+ $from,
 134+ wfMsg('categorywatch-emailsubject', $page),
 135+ $body,
 136+ $replyto
 137+ );
 138+ }
 139+ }
 140+
 141+ $dbr->freeResult($res);
 142+ }
 143+}
 144+
 145+function wfSetupCategoryWatch() {
 146+ global $wgCategoryWatch, $wgLanguageCode, $wgMessageCache;
 147+
 148+ # Instantiate the CategoryWatch singleton now that the environment is prepared
 149+ $wgCategoryWatch = new CategoryWatch();
 150+
 151+ # Add messages
 152+ if ($wgLanguageCode == 'en') {
 153+ $wgMessageCache->addMessages(array(
 154+ 'categorywatch-emailbody' => "Hi $1, you have received this message because you are watching the \"$2\" category. This message is to notify you that at $3 user $4 $5.",
 155+ 'categorywatch-emailsubject' => "Activity involving watched category \"$1\"",
 156+ 'categorywatch-catmovein' => "moved $1 into category $2 from $3",
 157+ 'categorywatch-catmoveout' => "moved $1 out of category $2 into $3",
 158+ 'categorywatch-catadd' => "added $1 to category $2",
 159+ 'categorywatch-catsub' => "removed $1 from category $2"
 160+ ));
 161+ }
 162+}
 163+