mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Echo
synced 2024-11-27 17:20:40 +00:00
8da85396d6
This version is very rough. For an example set of Minimum Releasable Functionality, this version will notify users on changes to their watchlists or to their user talk pages. However, it is still missing a conversion script to turn watchlists into echo subscriptions. For now, notifications can be viewed through the new special page Special:Notifications, or through the API module provided. Change-Id: I5867226e3e6195fbed81f4b5803e2310f057ffc4
180 lines
5 KiB
PHP
180 lines
5 KiB
PHP
<?php
|
|
|
|
class EchoNotificationController {
|
|
/**
|
|
* Retrieves number of unread notifications that a user has.
|
|
*
|
|
* @param $user User object to check notifications for
|
|
* @param $cached Whether or not to return cached results.
|
|
* @return Integer: Number of unread notifications.
|
|
*/
|
|
public static function getNotificationCount( $user, $cached = true ) {
|
|
global $wgMemc;
|
|
|
|
$memcKey = wfMemcKey( 'echo-notification-count', $user->getId() );
|
|
|
|
if ( $wgMemc->get($memcKey) !== false && $cached ) {
|
|
return $wgMemc->get($memcKey);
|
|
}
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
$count = $dbr->selectField( 'echo_notification', 'count(*)',
|
|
array(
|
|
'notification_user' => $user->getId(),
|
|
'notification_read_timestamp' => null,
|
|
),
|
|
__METHOD__);
|
|
|
|
$wgMemc->set($memcKey, $count, 86400);
|
|
|
|
return $count;
|
|
}
|
|
|
|
/**
|
|
* Mark one or more notifications read for a user.
|
|
*
|
|
* @param $user User object to mark items read for.
|
|
* @param $eventIDs Array of event IDs to mark read
|
|
*/
|
|
public static function markRead( $user, $eventIDs ) {
|
|
$dbw = wfGetDB( DB_MASTER );
|
|
|
|
$eventIDs = array_filter( (array)$eventIDs, 'is_numeric' );
|
|
|
|
$dbw->update( 'echo_notification',
|
|
array( 'notification_read_timestamp' => $dbw->timestamp(wfTimestampNow()) ),
|
|
array(
|
|
'notification_user' => $user->getId(),
|
|
'notification_event' => $eventIDs,
|
|
),
|
|
__METHOD__
|
|
);
|
|
|
|
self::resetNotificationCount($user);
|
|
}
|
|
|
|
/**
|
|
* Recalculates the number of notifications that a user has.
|
|
*
|
|
* @param $user User object
|
|
*/
|
|
public static function resetNotificationCount( $user ) {
|
|
self::getNotificationCount( $user, false );
|
|
}
|
|
|
|
/**
|
|
* Processes notifications for a newly-created EchoEvent
|
|
*
|
|
* @todo Port to Job Queue
|
|
* @param $event EchoEvent to do notifications for
|
|
*/
|
|
public static function notify( $event ) {
|
|
$subscriptions = self::getSubscriptionsForEvent( $event );
|
|
|
|
foreach( $subscriptions as $subscription ) {
|
|
$user = $subscription->getUser();
|
|
$notifyTypes = $subscription->getNotificationTypes();
|
|
|
|
$notifyTypes = array_keys( array_filter($notifyTypes) );
|
|
|
|
foreach( $notifyTypes as $type ) {
|
|
self::doNotification( $event, $user, $type );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Processes a single notification for an EchoEvent
|
|
*
|
|
* @param $event The EchoEvent to do a notification for.
|
|
* @param $user The User object to notify.
|
|
* @param $type The type of notification to process.
|
|
*/
|
|
public static function doNotification( $event, $user, $type ) {
|
|
global $wgEchoNotifiers;
|
|
|
|
if ( ! isset($wgEchoNotifiers[$type]) ) {
|
|
throw new MWException( "Invalid notification type $type" );
|
|
}
|
|
|
|
call_user_func_array( $wgEchoNotifiers[$type], array( $user, $event ) );
|
|
}
|
|
|
|
/**
|
|
* Retrieves an array of EchoSubscription objects applicable to an EchoEvent.
|
|
*
|
|
* @param $event EchoEvent to retrieve EchoSubscriptions for.
|
|
* @return Array of EchoSubscription objects.
|
|
*/
|
|
protected static function getSubscriptionsForEvent( $event ) {
|
|
$dbr = wfGetDB( DB_SLAVE );
|
|
|
|
$conds = array( 'sub_event_type' => $event->getType() );
|
|
|
|
if ( $event->getTitle() ) {
|
|
$conds['sub_page_namespace'] = $event->getTitle()->getNamespace();
|
|
$conds['sub_page_title'] = $event->getTitle()->getDBkey();
|
|
}
|
|
|
|
$res = $dbr->select('echo_subscription', '*', $conds, __METHOD__,
|
|
array( 'order by' => 'sub_user asc' ) );
|
|
|
|
$subscriptions = array();
|
|
$rowCollection = array();
|
|
$lastUser = null;
|
|
|
|
foreach( $res as $row ) {
|
|
if ( $lastUser && $row->sub_user != $lastUser ) {
|
|
$subscriptions[$lastUser] = EchoSubscription::newFromRows( $rowCollection );
|
|
$rowCollection = array();
|
|
}
|
|
|
|
$rowCollection[] = $row;
|
|
$lastUser = $row->sub_user;
|
|
}
|
|
|
|
if ( count($rowCollection) ) {
|
|
$subscriptions[$lastUser] = EchoSubscription::newFromRows( $rowCollection );
|
|
}
|
|
|
|
$users = array();
|
|
wfRunHooks( 'EchoGetDefaultNotifiedUsers', array( $event, &$users ) );
|
|
foreach( $users as $u ) {
|
|
if ( !isset($subscriptions[$u->getId()]) ) {
|
|
$subscriptions[$u->getId()] = new EchoSubscription( $u, $event->getType(), $event->getTitle() );
|
|
}
|
|
}
|
|
|
|
// Don't notify the person who made the edit, that's a bit silly.
|
|
if ( $event->getAgent() ) {
|
|
unset( $subscriptions[$event->getAgent()->getId()]);
|
|
}
|
|
|
|
return $subscriptions;
|
|
}
|
|
|
|
/**
|
|
* Formats a notification
|
|
*
|
|
* @param $event EchoEvent that the notification is for.
|
|
* @param $user The User to format the notification for.
|
|
* @param $format The format to show the notification in: text or html
|
|
* @param $type The type of notification being distributed (e.g. email, notify)
|
|
* @return type description
|
|
*/
|
|
public static function formatNotification( $event, $user, $format = 'text', $type = 'notify' ) {
|
|
global $wgEchoNotificationFormatters;
|
|
|
|
$eventType = $event->getType();
|
|
|
|
if ( isset($wgEchoNotificationFormatters[$eventType]) ) {
|
|
$params = $wgEchoNotificationFormatters[$eventType];
|
|
$notifier = EchoNotificationFormatter::factory($params);
|
|
$notifier->setOutputFormat( $format );
|
|
|
|
return $notifier->format($event, $user, $type);
|
|
}
|
|
|
|
// throw new MWException( "Unable to find notification formatter for event " . $event->getType() );
|
|
}
|
|
} |