2012-04-27 15:14:24 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
class EchoHooks {
|
2012-11-16 21:03:57 +00:00
|
|
|
const EMAIL_NEVER = -1; // Never send email notifications
|
|
|
|
const EMAIL_IMMEDIATELY = 0; // Send email notificaitons immediately as they come in
|
|
|
|
const EMAIL_DAILY_DIGEST = 1; // Send daily email digests
|
|
|
|
const EMAIL_WEEKLY_DIGEST = 7; // Send weekly email digests
|
2012-05-17 00:29:37 +00:00
|
|
|
|
2013-01-15 23:21:39 +00:00
|
|
|
/**
|
|
|
|
* Initialize Echo extension with necessary data, this function is invoked
|
|
|
|
* from $wgExtensionFunctions
|
|
|
|
*/
|
|
|
|
public static function initEchoExtension() {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoBackend, $wgEchoBackendName, $wgEchoNotifications,
|
|
|
|
$wgEchoNotificationCategories;
|
|
|
|
|
|
|
|
// allow extensions to define their own event
|
|
|
|
wfRunHooks( 'BeforeCreateEchoEvent', array( &$wgEchoNotifications, &$wgEchoNotificationCategories ) );
|
|
|
|
|
2013-01-15 23:21:39 +00:00
|
|
|
$wgEchoBackend = MWEchoBackend::factory( $wgEchoBackendName );
|
|
|
|
}
|
|
|
|
|
2013-03-01 00:26:59 +00:00
|
|
|
/**
|
|
|
|
* Handler for ResourceLoaderRegisterModules hook
|
|
|
|
*/
|
|
|
|
public static function onResourceLoaderRegisterModules( ResourceLoader &$resourceLoader ) {
|
|
|
|
global $wgResourceModules, $wgEchoConfig;
|
|
|
|
|
|
|
|
$eventLogEnabled = function_exists( 'efLogServerSideEvent' );
|
|
|
|
|
|
|
|
foreach ( $wgEchoConfig['eventlogging'] as $schema => $property ) {
|
|
|
|
if ( $eventLogEnabled && $property['enabled'] ) {
|
|
|
|
$wgResourceModules[ 'schema.' . $schema ] = array(
|
|
|
|
'class' => 'ResourceLoaderSchemaModule',
|
|
|
|
'schema' => $schema,
|
|
|
|
'revision' => $property['revision'],
|
|
|
|
);
|
|
|
|
$wgResourceModules['ext.echo.base']['dependencies'][] = 'schema.' . $schema;
|
|
|
|
} else {
|
|
|
|
$wgEchoConfig['eventlogging'][$schema]['enabled'] = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Attempt to log the event
|
|
|
|
* @param $schema string
|
|
|
|
* @param $data array
|
|
|
|
*/
|
|
|
|
public static function logEvent( $schema, $data ) {
|
|
|
|
global $wgEchoConfig;
|
|
|
|
|
|
|
|
if ( !empty( $wgEchoConfig['eventlogging'][$schema]['enabled'] ) ) {
|
|
|
|
efLogServerSideEvent( $schema, $wgEchoConfig['eventlogging'][$schema]['revision'], $data );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* @param $updater DatabaseUpdater object
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
|
|
|
public static function getSchemaUpdates( $updater ) {
|
2012-08-31 21:50:46 +00:00
|
|
|
$dir = __DIR__;
|
2012-04-27 15:14:24 +00:00
|
|
|
$baseSQLFile = "$dir/echo.sql";
|
|
|
|
$updater->addExtensionTable( 'echo_subscription', $baseSQLFile );
|
2012-11-27 01:53:35 +00:00
|
|
|
$updater->addExtensionTable( 'echo_email_batch', "$dir/db_patches/echo_email_batch.sql" );
|
2012-04-27 15:14:24 +00:00
|
|
|
|
|
|
|
$updater->modifyField( 'echo_event', 'event_agent',
|
|
|
|
"$dir/db_patches/patch-event_agent-split.sql", true );
|
2012-05-18 01:07:30 +00:00
|
|
|
$updater->modifyField( 'echo_event', 'event_variant',
|
|
|
|
"$dir/db_patches/patch-event_variant_nullability.sql", true );
|
2012-07-27 22:16:19 +00:00
|
|
|
$updater->modifyField( 'echo_event', 'event_extra',
|
|
|
|
"$dir/db_patches/patch-event_extra-size.sql", true );
|
2012-04-27 15:14:24 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* Handler for EchoGetDefaultNotifiedUsers hook.
|
2012-09-02 09:30:38 +00:00
|
|
|
* @param $event EchoEvent to get implicitly subscribed users for
|
2012-05-17 00:29:37 +00:00
|
|
|
* @param &$users Array to append implicitly subscribed users to.
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
|
|
|
public static function getDefaultNotifiedUsers( $event, &$users ) {
|
2012-08-31 21:50:46 +00:00
|
|
|
switch ( $event->getType() ) {
|
2012-08-01 19:53:05 +00:00
|
|
|
// Everyone deserves to know when something happens
|
2012-10-28 16:47:41 +00:00
|
|
|
// on their user talk page
|
2012-04-27 15:14:24 +00:00
|
|
|
case 'edit-user-talk':
|
|
|
|
if ( !$event->getTitle() || !$event->getTitle()->getNamespace() == NS_USER_TALK ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$username = $event->getTitle()->getText();
|
|
|
|
$user = User::newFromName( $username );
|
2012-08-01 19:53:05 +00:00
|
|
|
if ( $user && $user->getId() ) {
|
2012-04-27 15:14:24 +00:00
|
|
|
$users[$user->getId()] = $user;
|
|
|
|
}
|
2012-08-31 21:50:46 +00:00
|
|
|
break;
|
2012-07-27 22:16:19 +00:00
|
|
|
case 'add-comment':
|
|
|
|
case 'add-talkpage-topic':
|
2012-08-01 19:53:05 +00:00
|
|
|
// Handled by EchoDiscussionParser
|
2012-07-27 22:16:19 +00:00
|
|
|
$extraData = $event->getExtra();
|
|
|
|
|
|
|
|
if ( !isset( $extraData['revid'] ) || !$extraData['revid'] ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$revision = Revision::newFromId( $extraData['revid'] );
|
2012-10-28 16:47:41 +00:00
|
|
|
if ( $revision ) {
|
|
|
|
$users += EchoDiscussionParser::getNotifiedUsersForComment( $revision );
|
|
|
|
}
|
2012-08-31 21:50:46 +00:00
|
|
|
break;
|
2012-08-31 23:35:16 +00:00
|
|
|
case 'welcome':
|
|
|
|
$users[$event->getAgent()->getId()] = $event->getAgent();
|
|
|
|
break;
|
2012-07-18 19:39:33 +00:00
|
|
|
case 'reverted':
|
|
|
|
$extra = $event->getExtra();
|
|
|
|
|
|
|
|
if ( !$extra || !isset( $extra['reverted-user-id'] ) ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$victimID = $extra['reverted-user-id'];
|
|
|
|
$victim = User::newFromId( $victimID );
|
|
|
|
$users[$victim->getId()] = $victim;
|
|
|
|
break;
|
2012-12-26 22:05:29 +00:00
|
|
|
case 'article-linked':
|
|
|
|
$extra = $event->getExtra();
|
|
|
|
$agent = $event->getAgent();
|
|
|
|
|
|
|
|
if ( !$event->getTitle() || !isset( $extra['new-links'] )
|
|
|
|
|| !is_array( $extra['new-links'] ) || !$agent
|
|
|
|
) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
global $wgEchoUseJobQueue;
|
|
|
|
$count = 0;
|
|
|
|
$agentId = $agent->getID();
|
|
|
|
$dbr = wfGetDB( DB_SLAVE );
|
2013-01-04 19:58:30 +00:00
|
|
|
$updated = false;
|
2012-12-26 22:05:29 +00:00
|
|
|
|
2013-01-04 19:58:30 +00:00
|
|
|
// @Todo: Title::newFromText() would trigger individual query for each title, this is not
|
|
|
|
// efficient if there are a lot of new links, since we only need the page_id, this can be done
|
|
|
|
// by one big query
|
2012-12-26 22:05:29 +00:00
|
|
|
foreach( $extra['new-links'] as $page ) {
|
|
|
|
$count++;
|
|
|
|
// processing a lot of links on a normal web request is expensive, we should cap
|
|
|
|
// this till we have job queue enabled
|
|
|
|
if ( !$wgEchoUseJobQueue && $count > 100 ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
$title = Title::newFromText( $page['pl_title'], $page['pl_namespace'] );
|
2013-01-04 19:58:30 +00:00
|
|
|
if ( !$title || $title->getArticleID() <= 0 ) {
|
2012-12-26 22:05:29 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
$res = $dbr->selectRow(
|
|
|
|
array( 'revision' ),
|
|
|
|
array( 'rev_user' ),
|
|
|
|
array( 'rev_page' => $title->getArticleID() ),
|
|
|
|
__METHOD__,
|
|
|
|
array( 'LIMIT' => 1, 'ORDER BY' => 'rev_timestamp, rev_id' )
|
|
|
|
);
|
|
|
|
// No notification if agents link their own articles
|
|
|
|
if ( $res && $res->rev_user && $agentId != $res->rev_user ) {
|
|
|
|
// Map each linked page to a corresponding author
|
|
|
|
if ( !isset( $extra['notif-list'][$res->rev_user] ) ) {
|
|
|
|
$extra['notif-list'][$res->rev_user] = array();
|
|
|
|
}
|
|
|
|
if ( isset( $users[$res->rev_user] ) ) {
|
|
|
|
$user = $users[$res->rev_user];
|
|
|
|
} else {
|
|
|
|
$user = User::newFromId( $res->rev_user );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $user ) {
|
|
|
|
$users[$user->getID()] = $user;
|
|
|
|
$extra['notif-list'][$res->rev_user][] = $page;
|
2013-01-04 19:58:30 +00:00
|
|
|
$updated = true;
|
2012-12-26 22:05:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-04 19:58:30 +00:00
|
|
|
if ( $updated ) {
|
|
|
|
$event->updateExtra( $extra );
|
|
|
|
}
|
2012-12-26 22:05:29 +00:00
|
|
|
break;
|
2012-10-28 16:47:41 +00:00
|
|
|
case 'mention':
|
|
|
|
$extraData = $event->getExtra();
|
|
|
|
$users += $extraData['mentioned-users'];
|
|
|
|
break;
|
2012-04-27 15:14:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-02-28 23:52:12 +00:00
|
|
|
/**
|
|
|
|
* @param $subscription EchoSubscription
|
|
|
|
* @param $event EchoEvent
|
|
|
|
* @param $notifyTypes
|
|
|
|
* @return bool
|
|
|
|
*/
|
2012-06-08 05:27:59 +00:00
|
|
|
public static function getNotificationTypes( $subscription, $event, &$notifyTypes ) {
|
|
|
|
$type = $event->getType();
|
|
|
|
$user = $subscription->getUser();
|
|
|
|
|
|
|
|
// Figure out when to disallow email notifications
|
|
|
|
if ( $type == 'edit' ) {
|
2012-08-31 21:50:46 +00:00
|
|
|
if ( !$user->getOption( 'enotifwatchlistpages' ) ) {
|
2012-08-30 16:04:39 +00:00
|
|
|
$notifyTypes = array_diff( $notifyTypes, array( 'email' ) );
|
2012-06-08 05:27:59 +00:00
|
|
|
}
|
|
|
|
} elseif ( $type == 'edit-user-talk' ) {
|
2012-08-31 21:50:46 +00:00
|
|
|
if ( !$user->getOption( 'enotifusertalkpages' ) ) {
|
2012-08-30 16:04:39 +00:00
|
|
|
$notifyTypes = array_diff( $notifyTypes, array( 'email' ) );
|
2012-06-08 05:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-31 21:50:46 +00:00
|
|
|
if ( !$user->getOption( 'enotifminoredits' ) ) {
|
2012-06-08 05:27:59 +00:00
|
|
|
$extra = $event->getExtra();
|
2012-08-30 16:04:39 +00:00
|
|
|
if ( !empty( $extra['revid'] ) ) {
|
|
|
|
$rev = Revision::newFromID( $extra['revid'] );
|
2012-06-08 05:27:59 +00:00
|
|
|
|
|
|
|
if ( $rev->isMinor() ) {
|
2012-08-30 16:04:39 +00:00
|
|
|
$notifyTypes = array_diff( $notifyTypes, array( 'email' ) );
|
2012-06-08 05:27:59 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* Handler for GetPreferences hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/GetPreferences
|
|
|
|
* @param $user User to get preferences for
|
|
|
|
* @param &$preferences Preferences array
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2012-04-27 15:14:24 +00:00
|
|
|
public static function getPreferences( $user, &$preferences ) {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoDefaultNotificationTypes, $wgAuth, $wgEchoEnableEmailBatch,
|
|
|
|
$wgEchoNotifiers, $wgEchoNotificationCategories;
|
2012-11-16 21:03:57 +00:00
|
|
|
|
|
|
|
// Show email frequency options
|
|
|
|
$never = wfMessage( 'echo-pref-email-frequency-never' )->plain();
|
|
|
|
$immediately = wfMessage( 'echo-pref-email-frequency-immediately' )->plain();
|
2012-12-14 20:48:41 +00:00
|
|
|
$freqOptions = array(
|
|
|
|
$never => self::EMAIL_NEVER,
|
|
|
|
$immediately => self::EMAIL_IMMEDIATELY,
|
|
|
|
);
|
|
|
|
// Only show digest options if email batch is enabled
|
|
|
|
if ( $wgEchoEnableEmailBatch ) {
|
|
|
|
$daily = wfMessage( 'echo-pref-email-frequency-daily' )->plain();
|
|
|
|
$weekly = wfMessage( 'echo-pref-email-frequency-weekly' )->plain();
|
|
|
|
$freqOptions += array(
|
|
|
|
$daily => self::EMAIL_DAILY_DIGEST,
|
|
|
|
$weekly => self::EMAIL_WEEKLY_DIGEST
|
|
|
|
);
|
|
|
|
}
|
2012-11-16 21:03:57 +00:00
|
|
|
$preferences['echo-email-frequency'] = array(
|
|
|
|
'type' => 'select',
|
|
|
|
//'label-message' => 'echo-pref-email-frequency',
|
|
|
|
'section' => 'echo/emailfrequency',
|
2012-12-14 20:48:41 +00:00
|
|
|
'options' => $freqOptions
|
2012-11-16 21:03:57 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
// Display information about the user's currently set email address
|
|
|
|
$prefsTitle = SpecialPage::getTitleFor( 'Preferences', false, 'mw-prefsection-echo' );
|
|
|
|
$link = Linker::link(
|
|
|
|
SpecialPage::getTitleFor( 'ChangeEmail' ),
|
|
|
|
wfMessage( $user->getEmail() ? 'prefs-changeemail' : 'prefs-setemail' )->escaped(),
|
|
|
|
array(),
|
|
|
|
array( 'returnto' => $prefsTitle->getFullText() )
|
|
|
|
);
|
|
|
|
$emailAddress = $user->getEmail() ? htmlspecialchars( $user->getEmail() ) : '';
|
|
|
|
if ( $wgAuth->allowPropChange( 'emailaddress' ) ) {
|
|
|
|
if ( $emailAddress === '' ) {
|
|
|
|
$emailAddress .= $link;
|
|
|
|
} else {
|
|
|
|
$emailAddress .= wfMessage( 'word-separator' )->escaped()
|
|
|
|
. wfMessage( 'parentheses' )->rawParams( $link )->escaped();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
$emailContent = wfMessage( 'youremail' )->escaped()
|
|
|
|
. wfMessage( 'word-separator' )->escaped() . $emailAddress;
|
|
|
|
$preferences['echo-emailaddress'] = array(
|
|
|
|
'type' => 'info',
|
|
|
|
'raw' => true,
|
|
|
|
'default' => $emailContent,
|
2013-01-14 23:52:46 +00:00
|
|
|
'section' => 'echo/emailfrequency'
|
2012-11-16 21:03:57 +00:00
|
|
|
);
|
|
|
|
|
2013-02-16 02:20:34 +00:00
|
|
|
// Sort notification categories by priority
|
|
|
|
$categoriesAndPriorities = array();
|
|
|
|
foreach ( $wgEchoNotificationCategories as $category => $categoryData ) {
|
|
|
|
// See if the category is not dismissable at all. Must do strict
|
|
|
|
// comparison to true since no-dismiss can also be an array
|
|
|
|
if ( isset( $categoryData['no-dismiss'] ) && in_array( 'all' , $categoryData['no-dismiss'] ) ) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
// See if user is eligible to recieve this notification (per user group restrictions)
|
|
|
|
if ( EchoNotificationController::getCategoryEligibility( $user, $category ) ) {
|
|
|
|
$categoriesAndPriorities[$category] = EchoNotificationController::getCategoryPriority( $category );
|
2013-01-14 23:52:46 +00:00
|
|
|
}
|
|
|
|
}
|
2013-02-16 02:20:34 +00:00
|
|
|
asort( $categoriesAndPriorities );
|
|
|
|
$validSortedCategories = array_keys( $categoriesAndPriorities );
|
2013-01-14 23:52:46 +00:00
|
|
|
|
|
|
|
// Show subscription options
|
2013-02-16 02:20:34 +00:00
|
|
|
|
|
|
|
// $oldPrefs are prefs that we are replacing
|
2013-01-14 23:52:46 +00:00
|
|
|
$oldPrefs['email']['edit-user-talk'] = 'enotifusertalkpages';
|
2013-02-16 02:20:34 +00:00
|
|
|
|
|
|
|
// Build the columns (output formats)
|
|
|
|
$columns = array();
|
|
|
|
foreach ( $wgEchoNotifiers as $notifierType => $notifierData ) {
|
|
|
|
$formatMessage = wfMessage( 'echo-pref-' . $notifierType )->plain();
|
|
|
|
$columns[$formatMessage] = $notifierType;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Build the rows (notification categories)
|
|
|
|
$rows = array();
|
|
|
|
foreach ( $validSortedCategories as $category ) {
|
|
|
|
$categoryMessage = wfMessage( 'echo-pref-subscription-' . $category )->plain();
|
|
|
|
$rows[$categoryMessage] = $category;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Figure out the individual exceptions in the matrix and make them disabled
|
|
|
|
$removeOptions = array();
|
|
|
|
foreach ( $wgEchoNotifiers as $notifierType => $notifierData ) {
|
|
|
|
foreach ( $validSortedCategories as $category ) {
|
|
|
|
// See if this output format is non-dismissable
|
|
|
|
if ( isset( $wgEchoNotificationCategories[$category]['no-dismiss'] )
|
|
|
|
&& in_array( $notifierType, $wgEchoNotificationCategories[$category]['no-dismiss'] ) )
|
2013-01-14 23:52:46 +00:00
|
|
|
{
|
2013-02-16 02:20:34 +00:00
|
|
|
$removeOptions[] = "$notifierType-$category";
|
2013-01-14 23:52:46 +00:00
|
|
|
}
|
2013-02-16 02:20:34 +00:00
|
|
|
|
|
|
|
// Make sure this output format is possible for this notification category
|
|
|
|
if ( isset( $wgEchoDefaultNotificationTypes[$category] ) ) {
|
|
|
|
if ( !$wgEchoDefaultNotificationTypes[$category][$notifierType] ) {
|
|
|
|
$removeOptions[] = "$notifierType-$category";
|
2013-01-14 23:52:46 +00:00
|
|
|
}
|
2013-02-16 02:20:34 +00:00
|
|
|
} elseif ( !$wgEchoDefaultNotificationTypes['all'][$notifierType] ) {
|
|
|
|
$removeOptions[] = "$notifierType-$category";
|
2013-01-14 23:52:46 +00:00
|
|
|
}
|
2013-02-16 02:20:34 +00:00
|
|
|
|
|
|
|
// Unset redundant prefs while we're cycling through the matrix
|
|
|
|
if ( isset( $oldPrefs[$notifierType][$category] ) ) {
|
|
|
|
unset( $preferences[$oldPrefs[$notifierType][$category]] );
|
2013-01-14 23:52:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-16 02:20:34 +00:00
|
|
|
$preferences['echo-subscriptions'] = array(
|
|
|
|
'class' => 'HTMLCheckMatrix',
|
|
|
|
'section' => 'echo/echosubscriptions',
|
|
|
|
'rows' => $rows,
|
|
|
|
'columns' => $columns,
|
|
|
|
'remove-options' => $removeOptions,
|
2012-04-27 15:14:24 +00:00
|
|
|
);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* Handler for ArticleSaveComplete hook
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/ArticleSaveComplete
|
|
|
|
* @param $article Article edited
|
|
|
|
* @param $user User who edited
|
2012-09-02 09:30:38 +00:00
|
|
|
* @param $text string New article text
|
|
|
|
* @param $summary string Edit summary
|
|
|
|
* @param $minoredit bool Minor edit or not
|
|
|
|
* @param $watchthis bool Watch this article?
|
2012-09-26 05:09:43 +00:00
|
|
|
* @param $sectionanchor string Section that was edited
|
|
|
|
* @param $flags int Edit flags
|
2012-05-17 00:29:37 +00:00
|
|
|
* @param $revision Revision that was created
|
|
|
|
* @param $status Status
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2012-08-31 21:50:46 +00:00
|
|
|
public static function onArticleSaved( &$article, &$user, $text, $summary, $minoredit, $watchthis, $sectionanchor, &$flags, $revision, &$status ) {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoNotifications, $wgRequest;
|
2012-07-18 19:39:33 +00:00
|
|
|
if ( $revision ) {
|
|
|
|
EchoEvent::create( array(
|
|
|
|
'type' => 'edit',
|
|
|
|
'title' => $article->getTitle(),
|
|
|
|
'extra' => array( 'revid' => $revision->getID() ),
|
|
|
|
'agent' => $user,
|
|
|
|
) );
|
|
|
|
|
|
|
|
if ( $article->getTitle()->isTalkPage() ) {
|
|
|
|
EchoDiscussionParser::generateEventsForRevision( $revision );
|
|
|
|
}
|
2012-07-27 22:16:19 +00:00
|
|
|
|
2012-07-18 19:39:33 +00:00
|
|
|
// Handle the case of someone undoing an edit, either through the
|
|
|
|
// 'undo' link in the article history or via the API.
|
2013-02-16 02:20:34 +00:00
|
|
|
if ( isset( $wgEchoNotifications['reverted'] ) ) {
|
2013-01-17 01:38:46 +00:00
|
|
|
$undidRevId = $wgRequest->getVal( 'wpUndidRevision' );
|
2012-11-01 20:15:37 +00:00
|
|
|
if ( $undidRevId ) {
|
|
|
|
$undidRevision = Revision::newFromId( $undidRevId );
|
|
|
|
if ( $undidRevision ) {
|
|
|
|
$victimId = $undidRevision->getUser();
|
|
|
|
if ( $victimId ) { // No notifications for anonymous users
|
|
|
|
EchoEvent::create( array(
|
|
|
|
'type' => 'reverted',
|
|
|
|
'title' => $article->getTitle(),
|
|
|
|
'extra' => array(
|
|
|
|
'revid' => $revision->getId(),
|
|
|
|
'reverted-user-id' => $victimId,
|
|
|
|
'reverted-revision-id' => $undidRevId,
|
|
|
|
'method' => 'undo',
|
|
|
|
),
|
|
|
|
'agent' => $user,
|
|
|
|
) );
|
|
|
|
}
|
2012-07-18 19:39:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-04-27 15:14:24 +00:00
|
|
|
|
2012-11-01 20:15:37 +00:00
|
|
|
}
|
2012-04-27 15:14:24 +00:00
|
|
|
return true;
|
|
|
|
}
|
2012-06-01 10:57:09 +00:00
|
|
|
|
2012-08-31 23:35:16 +00:00
|
|
|
/**
|
|
|
|
* Handler for AddNewAccount hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/AddNewAccount
|
|
|
|
* @param $user User object that was created.
|
|
|
|
* @param $byEmail bool True when account was created "by email".
|
2012-09-26 05:09:43 +00:00
|
|
|
* @return bool
|
2012-08-31 23:35:16 +00:00
|
|
|
*/
|
|
|
|
public static function onAccountCreated( $user, $byEmail ) {
|
2012-09-26 05:09:43 +00:00
|
|
|
EchoEvent::create( array(
|
2012-08-31 23:35:16 +00:00
|
|
|
'type' => 'welcome',
|
|
|
|
'agent' => $user,
|
|
|
|
) );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-12-26 22:05:29 +00:00
|
|
|
/**
|
|
|
|
* Handler for LinksUpdateAfterInsert hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/LinksUpdateAfterInsert
|
|
|
|
* @param $linksUpdate LinksUpdate
|
|
|
|
* @param $table string
|
|
|
|
* @param $insertions array
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
public static function onLinksUpdateAfterInsert( $linksUpdate, $table, $insertions ) {
|
2013-01-16 00:13:58 +00:00
|
|
|
// Handle only
|
|
|
|
// 1. inserts to pagelinks table &&
|
|
|
|
// 2. content namespace pages &&
|
|
|
|
// 3. non-transcluding pages &&
|
|
|
|
// 4. non-redirect pages
|
|
|
|
if ( $table !== 'pagelinks' || !MWNamespace::isContent( $linksUpdate->mTitle->getNamespace() )
|
|
|
|
|| !$linksUpdate->mRecursive || $linksUpdate->mTitle->isRedirect() )
|
|
|
|
{
|
2013-01-04 01:36:12 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-01-08 23:57:28 +00:00
|
|
|
// Only create notifications for links to content namespace pages
|
2013-01-04 01:36:12 +00:00
|
|
|
foreach ( $insertions as $key => $page ) {
|
2013-01-07 20:02:45 +00:00
|
|
|
if ( !MWNamespace::isContent( $page['pl_namespace'] ) ) {
|
2013-01-04 01:36:12 +00:00
|
|
|
unset( $insertions[$key] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-08 23:57:28 +00:00
|
|
|
// Exits if there is no new link
|
2013-01-04 01:36:12 +00:00
|
|
|
if ( !$insertions ) {
|
2012-12-26 22:05:29 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
global $wgUser;
|
|
|
|
EchoEvent::create( array(
|
|
|
|
'type' => 'article-linked',
|
|
|
|
'title' => $linksUpdate->mTitle,
|
|
|
|
'agent' => $wgUser,
|
|
|
|
'extra' => array(
|
|
|
|
'new-links' => $insertions,
|
|
|
|
'notif-list' => array()
|
|
|
|
)
|
|
|
|
) );
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* Handler for BeforePageDisplay hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
|
|
|
|
* @param $out OutputPage object
|
|
|
|
* @param $skin Skin being used.
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2012-06-01 10:57:09 +00:00
|
|
|
static function beforePageDisplay( $out, $skin ) {
|
2012-11-01 21:59:53 +00:00
|
|
|
$user = $out->getUser();
|
2012-11-16 21:03:57 +00:00
|
|
|
if ( $user->isLoggedIn() && !$user->getOption( 'echo-notify-hide-link' ) ) {
|
2012-11-01 21:59:53 +00:00
|
|
|
// Load the module for the Notifications flyout
|
2012-08-30 16:04:39 +00:00
|
|
|
$out->addModules( array( 'ext.echo.overlay' ) );
|
2012-06-01 10:57:09 +00:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
|
|
|
* Handler for PersonalUrls hook.
|
2012-11-01 21:59:53 +00:00
|
|
|
* Add a "Notifications" item to the user toolbar ('personal URLs').
|
2012-05-17 00:29:37 +00:00
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/PersonalUrls
|
|
|
|
* @param &$personal_urls Array of URLs to append to.
|
|
|
|
* @param &$title Title of page being visited.
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2012-06-01 10:57:09 +00:00
|
|
|
static function onPersonalUrls( &$personal_urls, &$title ) {
|
2012-12-12 02:18:51 +00:00
|
|
|
global $wgUser, $wgEchoShowFullNotificationsLink;
|
2012-11-16 21:03:57 +00:00
|
|
|
// Add a "My notifications" item to personal URLs
|
|
|
|
if ( $wgUser->isAnon() || $wgUser->getOption( 'echo-notify-hide-link' ) ) {
|
2012-06-01 10:57:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
$notificationCount = EchoNotificationController::getNotificationCount( $wgUser );
|
2012-12-12 02:18:51 +00:00
|
|
|
if ( $wgEchoShowFullNotificationsLink ) {
|
|
|
|
// Add a "Notifications" item to personal URLs
|
|
|
|
$msg = wfMessage( $notificationCount == 0 ? 'echo-link' : 'echo-link-new' );
|
|
|
|
$text = $msg->params( EchoNotificationController::formatNotificationCount( $notificationCount ) )->text();
|
|
|
|
} else {
|
|
|
|
// Just add a number
|
|
|
|
$text = wfMessage( 'parentheses', $notificationCount )->plain();
|
|
|
|
}
|
2012-06-01 10:57:09 +00:00
|
|
|
$url = SpecialPage::getTitleFor( 'Notifications' )->getLocalURL();
|
|
|
|
|
|
|
|
$notificationsLink = array(
|
|
|
|
'href' => $url,
|
2012-12-12 02:18:51 +00:00
|
|
|
'text' => $text,
|
|
|
|
'active' => ( $url == $title->getLocalUrl() ),
|
2012-06-01 10:57:09 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
$insertUrls = array( 'notifications' => $notificationsLink );
|
2012-12-14 02:01:04 +00:00
|
|
|
if ( $wgEchoShowFullNotificationsLink ) {
|
|
|
|
$personal_urls = wfArrayInsertAfter( $personal_urls, $insertUrls, 'mytalk' );
|
|
|
|
} else {
|
|
|
|
$personal_urls = wfArrayInsertAfter( $personal_urls, $insertUrls, 'userpage' );
|
|
|
|
}
|
2012-06-01 10:57:09 +00:00
|
|
|
return true;
|
|
|
|
}
|
2012-07-17 22:19:32 +00:00
|
|
|
|
2012-05-17 00:29:37 +00:00
|
|
|
/**
|
2012-12-19 22:35:45 +00:00
|
|
|
* Handler for AbortEmailNotification and UpdateUserMailerFormattedPageStatus hook.
|
2012-05-17 00:29:37 +00:00
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/AbortEmailNotification
|
2012-12-19 22:35:45 +00:00
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/UpdateUserMailerFormattedPageStatus
|
2012-09-02 09:30:38 +00:00
|
|
|
* @return bool true in all cases
|
2012-05-17 00:29:37 +00:00
|
|
|
*/
|
2012-12-19 22:35:45 +00:00
|
|
|
static function disableStandUserTalkEnotif() {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgEchoNotifications, $wgEnotifUserTalk;
|
|
|
|
if ( isset( $wgEchoNotifications['edit-user-talk'] ) ) {
|
2012-11-16 21:03:57 +00:00
|
|
|
// Disable the standard email notification for talk page messages
|
|
|
|
$wgEnotifUserTalk = false;
|
|
|
|
}
|
|
|
|
// Don't abort watchlist email notifications
|
|
|
|
return true;
|
2012-07-17 22:19:32 +00:00
|
|
|
}
|
2012-07-31 21:18:16 +00:00
|
|
|
|
2012-11-01 21:59:53 +00:00
|
|
|
/**
|
|
|
|
* Handler for MakeGlobalVariablesScript hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/MakeGlobalVariablesScript
|
2013-02-28 23:52:12 +00:00
|
|
|
* @param &$vars array Variables to be added into the output
|
2012-11-01 21:59:53 +00:00
|
|
|
* @param $outputPage OutputPage instance calling the hook
|
|
|
|
* @return bool true in all cases
|
|
|
|
*/
|
2012-09-02 09:30:38 +00:00
|
|
|
public static function makeGlobalVariablesScript( &$vars, OutputPage $outputPage ) {
|
2013-01-04 21:56:30 +00:00
|
|
|
global $wgEchoShowFullNotificationsLink, $wgEchoHelpPage;
|
2012-07-31 21:18:16 +00:00
|
|
|
$user = $outputPage->getUser();
|
|
|
|
|
2012-08-01 19:53:05 +00:00
|
|
|
// Provide info for the Overlay
|
|
|
|
|
2012-09-02 09:30:38 +00:00
|
|
|
$timestamp = new MWTimestamp( wfTimestampNow() );
|
|
|
|
if ( ! $user->isAnon() ) {
|
2012-07-31 21:18:16 +00:00
|
|
|
$vars['wgEchoOverlayConfiguration'] = array(
|
2012-12-12 02:18:51 +00:00
|
|
|
'notifications-link-full' => $wgEchoShowFullNotificationsLink,
|
2012-09-02 09:30:38 +00:00
|
|
|
'timestamp' => $timestamp->getTimestamp( TS_UNIX ),
|
2012-11-13 23:06:11 +00:00
|
|
|
'notification-count' => EchoNotificationController::getFormattedNotificationCount( $user ),
|
2012-07-31 21:18:16 +00:00
|
|
|
);
|
2013-01-04 21:56:30 +00:00
|
|
|
$vars['wgEchoHelpPage'] = $wgEchoHelpPage;
|
2012-07-31 21:18:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-31 00:29:49 +00:00
|
|
|
|
2012-11-01 21:59:53 +00:00
|
|
|
/**
|
|
|
|
* Handler for UnitTestsList hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList
|
|
|
|
* @param &$files Array of unit test files
|
|
|
|
* @return bool true in all cases
|
|
|
|
*/
|
2012-07-31 00:29:49 +00:00
|
|
|
static function getUnitTests( &$files ) {
|
|
|
|
$dir = dirname( __FILE__ ) . '/tests';
|
|
|
|
$files[] = "$dir/DiscussionParserTest.php";
|
2012-08-07 18:54:42 +00:00
|
|
|
return true;
|
2012-07-31 00:29:49 +00:00
|
|
|
}
|
2012-07-31 20:44:43 +00:00
|
|
|
|
2012-11-01 21:59:53 +00:00
|
|
|
/**
|
|
|
|
* Handler for ArticleEditUpdateNewTalk hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/ArticleEditUpdateNewTalk
|
2013-02-28 23:52:12 +00:00
|
|
|
* @param $page WikiPage The WikiPage object of the talk page being updated
|
2012-11-01 21:59:53 +00:00
|
|
|
* @return bool
|
|
|
|
*/
|
2012-11-16 21:03:57 +00:00
|
|
|
static function abortNewTalkNotification( $page ) {
|
2013-02-16 02:20:34 +00:00
|
|
|
global $wgUser, $wgEchoNotifications;
|
2012-11-01 21:59:53 +00:00
|
|
|
// If the user has the notifications flyout turned on and is receiving
|
|
|
|
// notifications for talk page messages, disable the yellow-bar-style notice.
|
2012-11-16 21:03:57 +00:00
|
|
|
if ( !$wgUser->getOption( 'echo-notify-hide-link' )
|
2013-02-16 02:20:34 +00:00
|
|
|
&& isset( $wgEchoNotifications['edit-user-talk'] ) )
|
2012-11-01 21:59:53 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-31 20:44:43 +00:00
|
|
|
}
|
2012-07-18 19:39:33 +00:00
|
|
|
|
2012-11-01 21:59:53 +00:00
|
|
|
/**
|
|
|
|
* Handler for ArticleRollbackComplete hook.
|
|
|
|
* @see http://www.mediawiki.org/wiki/Manual:Hooks/ArticleRollbackComplete
|
2013-02-28 23:52:12 +00:00
|
|
|
* @param $page WikiPage The article that was edited
|
|
|
|
* @param $agent User The user who did the rollback
|
|
|
|
* @param $newRevision Revision The revision the page was reverted back to
|
|
|
|
* @param $oldRevision Revision The revision of the top edit that was reverted
|
2012-11-01 21:59:53 +00:00
|
|
|
* @return bool true in all cases
|
|
|
|
*/
|
2012-07-18 19:39:33 +00:00
|
|
|
static function onRollbackComplete( $page, $agent, $newRevision, $oldRevision ) {
|
|
|
|
$victimId = $oldRevision->getUser();
|
|
|
|
|
|
|
|
if ( $victimId ) { // No notifications for anonymous users
|
|
|
|
EchoEvent::create( array(
|
|
|
|
'type' => 'reverted',
|
|
|
|
'title' => $page->getTitle(),
|
|
|
|
'extra' => array(
|
|
|
|
'revid' => $page->getRevision()->getId(),
|
|
|
|
'reverted-user-id' => $victimId,
|
|
|
|
'reverted-revision-id' => $oldRevision->getId(),
|
|
|
|
'method' => 'rollback',
|
|
|
|
),
|
|
|
|
'agent' => $agent,
|
|
|
|
) );
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
2012-07-18 16:28:41 +00:00
|
|
|
}
|