EBernhardson has uploaded a new change for review.
https://gerrit.wikimedia.org/r/150437
Change subject: Generalize a couple implementations of
EchoGetDefaultNotifiedUsers
......................................................................
Generalize a couple implementations of EchoGetDefaultNotifiedUsers
There are a variety of generic strategies you could define to choose
which users should be notified about an event, such as 'users watching the
title'
or 'talk page owner' (User_talk only).
This adds a new way to generically implement these in Echo and expose them
to other extensions rather than having each extension implement these
generic strategies themselves.
This patch only adds new functionality, adjusting echo to internally use these
and implement other strategies will come in future patches. The first user
of this will be Flow for notifying all users watching a particular talk page.
Change-Id: I19bb6a794d22565f3bb5421de92426d390197796
---
M Echo.php
M controller/NotificationController.php
A includes/LocateTalkPageOwner.php
A includes/LocateUsersWatchingTitle.php
A includes/UserLocator.php
5 files changed, 120 insertions(+), 1 deletion(-)
git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Echo
refs/changes/37/150437/1
diff --git a/Echo.php b/Echo.php
index 2568095..c9921af 100644
--- a/Echo.php
+++ b/Echo.php
@@ -56,6 +56,11 @@
$wgAutoloadClasses['MWDbEchoEmailBundler'] = $dir .
'includes/DbEmailBundler.php';
$wgAutoloadClasses['MWEchoEventLogging'] = $dir . 'includes/EventLogging.php';
+// Locate users to send events to
+$wgAutoloadClasses['EchoUserLocator'] = $dir . 'includes/UserLocator.php';
+$wgAutoloadClasses['EchoLocateUsersWatchingTitle'] = $dir .
'includes/LocateUsersWatchingTitle.php';
+$wgAutoloadClasses['EchoLocateTalkPageOwner'] = $dir .
'includes/LocateTalkPageOwner.php';
+
// Formatters
$wgAutoloadClasses['EchoNotificationFormatter'] = $dir .
'formatters/NotificationFormatter.php';
$wgAutoloadClasses['EchoBasicFormatter'] = $dir .
'formatters/BasicFormatter.php';
@@ -319,6 +324,13 @@
'email' => array( 'EchoNotifier', 'notifyWithEmail' ),
);
+// List of classes that can lookup users for an event. These are specified
from the
+// `user-locator` key of the events in $wgEchoNotifications
+$wgEchoUserLocators = array(
+ 'watching-event-title' => 'EchoLocateUsersWatchingTitle',
+ 'talk-page-owner' => 'EchoLocateTalkPageOwner',
+);
+
// List of usernames that will not trigger notification creation. This is
initially
// for bots that perform automated edits that are not important enough to
regularly
// spam people with notifications. Set to empty array when not in use.
diff --git a/controller/NotificationController.php
b/controller/NotificationController.php
index 638cb75..3557d9b 100644
--- a/controller/NotificationController.php
+++ b/controller/NotificationController.php
@@ -296,10 +296,27 @@
* @return Array of User objects
*/
protected static function getUsersToNotifyForEvent( $event ) {
+ global $wgEchoNotifications, $wgEchoUserLocators;
+
+ $type = $event->getType();
$users = $notifyList = array();
+ if ( isset( $wgEchoNotifications[$type]['user-locators'] ) ) {
+ foreach ( $wgEchoNotifications[$type]['user-locators']
as $name ) {
+ if ( isset( $wgEchoUserLocators[$name] ) ) {
+ $notifyList += $this
+ ->createUserLocator(
$wgEchoUserLocators[$name] )
+ ->evaluate( $event );
+ } else {
+ // @todo some sort of error?
+ }
+ }
+ }
+
+ // Additional hook for injecting more users. Use only if
+ // a locator can't do what you need for some reason.
wfRunHooks( 'EchoGetDefaultNotifiedUsers', array( $event,
&$users ) );
- // Make sure there is no duplicated users
foreach ( $users as $user ) {
+ // Key notifyList by user id to ensure there is no
duplicated users
$notifyList[$user->getId()] = $user;
}
@@ -313,6 +330,22 @@
}
/**
+ * Initial YAGNI implementation accepts a class name and instantiats
it. If necessary
+ * this could be extended to accept a callable to instantiate objects
with parameters.
+ *
+ * @param string $options
+ * @return EchoUserLocator
+ */
+ protected function createUserLocator( $options ) {
+ if ( !is_string( $options ) ) {
+ // Initial YAHNI implementatio only accepts a class
name as options.
+ // extend later
+ throw new MWException( '$wgEchoUserLocators can only
contain class names currently' );
+ }
+ return new $options;
+ }
+
+ /**
* Formats a notification
*
* @param $event EchoEvent that the notification is for.
diff --git a/includes/LocateTalkPageOwner.php b/includes/LocateTalkPageOwner.php
new file mode 100644
index 0000000..6601f69
--- /dev/null
+++ b/includes/LocateTalkPageOwner.php
@@ -0,0 +1,17 @@
+<?php
+
+class EchoLocateTalkPageOwner implements EchoUserLocator {
+ public function evaluate( EchoEvent $event ) {
+ $title = $event->getTitle();
+ if ( !$title || $title->getNamespace() !== NS_USER_TALK ) {
+ return array();
+ }
+
+ $user = User::newFromName( $title->getDBkey() );
+ if ( $user && !$user->isAnon() ) {
+ return array( $user->getId() => $user );
+ } else {
+ return array();
+ }
+ }
+}
diff --git a/includes/LocateUsersWatchingTitle.php
b/includes/LocateUsersWatchingTitle.php
new file mode 100644
index 0000000..76c1580
--- /dev/null
+++ b/includes/LocateUsersWatchingTitle.php
@@ -0,0 +1,37 @@
+<?php
+
+// @todo
+// * Many titles (not flow enabled) have 1k+ watchers, this needs to move
twords
+// EchoBatchRowIterator at some point. To make effective use of that though
+// the Iterator needs to pass all the way through rather than being
pre-evaluated
+// and loaded into an array.
+// * The echo job queue must be enabled to prevent slowdowns submitting to
+// heavily watched pages
+class EchoLocateUsersWatchingTitle implements EchoUserLocator {
+ public function evaluate( EchoEvent $event ) {
+ $title = $event->getTitle();
+ if ( !$title ) {
+ return array();
+ }
+
+ $dbr = wfGetDB( DB_SLAVE, 'watchlist' );
+ $res = $dbr->select(
+ array( 'watchlist' ),
+ array( 'wl_user' ),
+ array(
+ 'wl_namespace' => $title->getNamespace(),
+ 'wl_title' => $title->getDBkey(),
+ ),
+ __METHOD__
+ );
+
+ $users = array();
+ if ( $res ) {
+ foreach ( $res as $row ) {
+ $users[$row->wl_user] = User::newFromId(
$row->wl_user );
+ }
+ }
+
+ return $users;
+ }
+}
diff --git a/includes/UserLocator.php b/includes/UserLocator.php
new file mode 100644
index 0000000..db09bbb
--- /dev/null
+++ b/includes/UserLocator.php
@@ -0,0 +1,20 @@
+<?php
+
+/**
+ * Interface used by EchoNotificationController::getUsersToNotifyForEvent
+ *
+ * Individual implementations are chosen by event type. Implementations must
+ * return an array of user id => User object that will be notified about the
+ * event.
+ *
+ * Locator's implement specific strategys, such as 'Owner of talk page' which
+ * will return an array containing the talk page owner iff the event is
+ * against a non-anonymous talk page.
+ */
+interface EchoUserLocator {
+ /**
+ * @param EchoEvent $event
+ * @return array userid => User
+ */
+ function evaluate( EchoEvent $event );
+}
--
To view, visit https://gerrit.wikimedia.org/r/150437
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I19bb6a794d22565f3bb5421de92426d390197796
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/Echo
Gerrit-Branch: master
Gerrit-Owner: EBernhardson <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits