mediawiki-extensions-Thanks/Thanks.hooks.php
wctaiwan ab8b7847c3 Change UI of special page and support Flow Thanks
Change the UI to ask for confirmation instead of allowing the user to
change the revision ID, disallow using Special:Thanks directly, and add
support for Flow Thanks.

Bug: 63509
Change-Id: I48ef5e51fd3ac76ff5caf6907bc53d09357634bd
2014-06-02 04:10:21 +00:00

358 lines
11 KiB
PHP

<?php
/**
* Hooks for Thanks extension
*
* @file
* @ingroup Extensions
*/
class ThanksHooks {
/**
* Handler for HistoryRevisionTools and DiffRevisionTools hooks.
* Inserts 'thank' link into revision interface
* @param $rev Revision object to add the thank link for
* @param &$links array Links to add to the revision interface
* @param $oldRev Revision object of the "old" revision when viewing a diff
* @return bool
*/
public static function insertThankLink( $rev, &$links, $oldRev = null ) {
global $wgUser, $wgThanksSendToBots;
// Make sure Echo is turned on.
// Exclude anonymous users.
// Don't let users thank themselves.
// Exclude users who are blocked.
if ( class_exists( 'EchoNotifier' )
&& !$wgUser->isAnon()
&& $rev->getUser() !== $wgUser->getId()
&& !$wgUser->isBlocked()
&& !$rev->isDeleted( Revision::DELETED_TEXT )
&& ( !$oldRev || $rev->getParentId() == $oldRev->getId() )
) {
$recipient = User::newFromId( $rev->getUser() );
$recipientAllowed = true;
// If bots are not allowed, exclude them as recipients
if ( !$wgThanksSendToBots ) {
$recipientAllowed = !in_array( 'bot', $recipient->getGroups() );
}
if ( $recipientAllowed && !$recipient->isAnon() ) {
$links[] = self::generateThankElement( $rev, $recipient );
}
}
return true;
}
/**
* Helper for self::insertThankLink
* Creates either a thank link or thanked span based on users session
* @param $rev Revision object to generate the thank element for
* @param $recipient User who receives thanks notification
* @return string
*/
protected static function generateThankElement( $rev, $recipient ) {
global $wgUser;
// User has already thanked for revision
if ( $wgUser->getRequest()->getSessionData( "thanks-thanked-{$rev->getId()}" ) ) {
return Html::element(
'span',
array( 'class' => 'mw-thanks-thanked' ),
wfMessage( 'thanks-thanked', $wgUser )->text()
);
}
// Add 'thank' link
$tooltip = wfMessage( 'thanks-thank-tooltip' )
->params( $wgUser->getName(), $recipient->getName() )
->text();
return Html::element(
'a',
array(
'class' => 'mw-thanks-thank-link',
'href' => SpecialPage::getTitleFor( 'Thanks', $rev->getId() )->getFullURL(),
'title' => $tooltip,
'data-revision-id' => $rev->getId(),
),
wfMessage( 'thanks-thank' )->plain()
);
}
/**
* Handler for PageHistoryBeforeList hook.
* @see http://www.mediawiki.org/wiki/Manual:Hooks/PageHistoryBeforeList
* @param &$page WikiPage|Article|ImagePage|CategoryPage|Page The page that the history is loading for.
* @param $context RequestContext object
* @return bool true in all cases
*/
public static function onPageHistoryBeforeList( &$page, $context ) {
global $wgThanksConfirmationRequired;
if ( class_exists( 'EchoNotifier' )
&& $context->getUser()->isLoggedIn()
) {
// Load the module for the thank links
$context->getOutput()->addModules( array( 'ext.thanks.revthank' ) );
$context->getOutput()->addJsConfigVars( 'thanks-confirmation-required',
$wgThanksConfirmationRequired );
}
return true;
}
/**
* Handler for DiffViewHeader hook.
* @see http://www.mediawiki.org/wiki/Manual:Hooks/DiffViewHeader
* @param $diff DifferenceEngine
* @param $oldRev Revision object of the "old" revision (may be null/invalid)
* @param $newRev Revision object of the "new" revision
* @return bool true in all cases
*/
public static function onDiffViewHeader( $diff, $oldRev, $newRev ) {
global $wgThanksConfirmationRequired;
if ( class_exists( 'EchoNotifier' )
&& $diff->getUser()->isLoggedIn()
) {
// Load the module for the thank link
$diff->getOutput()->addModules( array( 'ext.thanks.revthank' ) );
$diff->getOutput()->addJsConfigVars( 'thanks-confirmation-required',
$wgThanksConfirmationRequired );
}
return true;
}
/**
* Add Thanks events to Echo
*
* @param $notifications array of Echo notifications
* @param $notificationCategories array of Echo notification categories
* @param $icons array of icon details
* @return bool
*/
public static function onBeforeCreateEchoEvent( &$notifications, &$notificationCategories, &$icons ) {
$notificationCategories['edit-thank'] = array(
'priority' => 3,
'tooltip' => 'echo-pref-tooltip-edit-thank',
);
$notifications['edit-thank'] = array(
'primary-link' => array( 'message' => 'notification-link-text-view-edit', 'destination' => 'diff' ),
'category' => 'edit-thank',
'group' => 'positive',
'formatter-class' => 'EchoThanksFormatter',
'title-message' => 'notification-thanks',
'title-params' => array( 'agent', 'difflink', 'title' ),
'flyout-message' => 'notification-thanks-flyout2',
'flyout-params' => array( 'agent', 'title' ),
'payload' => array( 'summary' ),
'email-subject-message' => 'notification-thanks-email-subject',
'email-subject-params' => array( 'agent' ),
'email-body-batch-message' => 'notification-thanks-email-batch-body',
'email-body-batch-params' => array( 'agent', 'title' ),
'icon' => 'thanks',
);
$notifications['flow-thank'] = array(
'primary-link' => array ( 'message' => 'notification-link-text-view-post', 'destination' => 'post' ),
'category' => 'edit-thank',
'group' => 'positive',
'formatter-class' => 'EchoFlowThanksFormatter',
'title-message' => 'notification-flow-thanks',
'title-params' => array( 'agent', 'postlink', 'topictitle', 'title' ),
'flyout-message' => 'notification-flow-thanks-flyout',
'flyout-params' => array( 'agent', 'topictitle', 'title' ),
'email-subject-message' => 'notification-flow-thanks-email-subject',
'email-subject-params' => array( 'agent' ),
'email-body-batch-message' => 'notification-flow-thanks-email-batch-body',
'email-body-batch-params' => array( 'agent', 'topictitle', 'title' ),
'icon' => 'thanks',
);
$icons['thanks'] = array(
'path' => 'Thanks/ThankYou.png',
);
return true;
}
/**
* Add user to be notified on echo event
* @param $event EchoEvent
* @param $users array
* @return bool
*/
public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) {
switch ( $event->getType() ) {
case 'edit-thank':
case 'flow-thank':
$extra = $event->getExtra();
if ( !$extra || !isset( $extra['thanked-user-id'] ) ) {
break;
}
$recipientId = $extra['thanked-user-id'];
$recipient = User::newFromId( $recipientId );
$users[$recipientId] = $recipient;
break;
}
return true;
}
/**
* 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".
* @return bool
*/
public static function onAccountCreated( $user, $byEmail ) {
// New users get echo preferences set that are not the default settings for existing users.
// Specifically, new users are opted into email notifications for thanks.
$user->setOption( 'echo-subscriptions-email-edit-thank', true );
$user->saveSettings();
return true;
}
/**
* Add thanks button to SpecialMobileDiff page
* @param &$output OutputPage object
* @param $ctx MobileContext object
* @param $revisions Array of the two revisions that are being compared in the diff
* @return bool true in all cases
*/
public static function onBeforeSpecialMobileDiffDisplay( &$output, $ctx, $revisions ) {
// If the Echo and MobileFrontend extensions are installed and the user is
// logged in, show a 'Thank' link.
if ( class_exists( 'EchoNotifier' )
&& class_exists( 'SpecialMobileDiff' )
&& $output->getUser()->isLoggedIn()
) {
$output->addModules( array( 'ext.thanks.mobilediff' ) );
$rev = $revisions[1];
if ( $rev ) {
if ( $output->getRequest()->getSessionData( 'thanks-thanked-' . $rev->getId() ) ) {
// User already sent thanks for this revision
$output->addJsConfigVars( 'wgThanksAlreadySent', true );
}
}
}
return true;
}
/**
* Hook to add PHPUnit test cases.
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UnitTestsList
*
* @param array &$files
*
* @return boolean
*/
public static function registerUnitTests( array &$files ) {
// @codeCoverageIgnoreStart
$directoryIterator = new RecursiveDirectoryIterator( __DIR__ . '/tests/' );
/**
* @var SplFileInfo $fileInfo
*/
$ourFiles = array();
foreach ( new RecursiveIteratorIterator( $directoryIterator ) as $fileInfo ) {
if ( substr( $fileInfo->getFilename(), -8 ) === 'Test.php' ) {
$ourFiles[] = $fileInfo->getPathname();
}
}
$files = array_merge( $files, $ourFiles );
return true;
// @codeCoverageIgnoreEnd
}
/**
* So users can just type in a username for target and it'll work
* @param array $types
* @return bool
*/
public static function onGetLogTypesOnUser( array &$types ) {
$types[] = 'thanks';
return true;
}
/**
* Handler for FlowAddModules
* @param OutputPage $out OutputPage object
* @return bool
*/
public static function onFlowAddModules( OutputPage $out ) {
$out->addModules( 'ext.thanks.flowthank' );
return true;
}
/**
* Handler for FlowAddInteractionLinks
* Appends a 'thank' button or a 'thanked' label to interaction links for Flow comments
* @param Flow\Model\PostRevision $post Flow PostRevision object for the comment
* @param User $user User viewing the page
* @param array $links Array of interaction links to be displayed
* @return bool
*/
public static function onFlowAddPostInteractionLinks( $post, $user, &$links ) {
global $wgThanksSendToBots;
// Make sure Echo is turned on.
// Exclude anonymous users.
// Don't let users thank themselves.
// Exclude users who are blocked.
if ( class_exists( 'EchoNotifier' )
&& !$user->isAnon()
&& $post->getCreatorId() != $user->getId()
&& !$user->isBlocked()
) {
$recipient = User::newFromId( $post->getCreatorId() );
$recipientAllowed = true;
// If bots are not allowed, exclude them as recipients
if ( !$wgThanksSendToBots ) {
$recipientAllowed = !in_array( 'bot', $recipient->getGroups() );
}
if ( $recipientAllowed && !$recipient->isAnon() ) {
$links[] = self::generateFlowThankElement( $post, $user, $recipient );
}
}
return true;
}
/**
* Creates either a 'thank' button or a 'thanked' label based on session data
* @param Flow\Model\PostRevision $post Flow PostRevision object for the comment
* @param User $user User viewing the page
* @param User $recipient User who receives thanks notification
* @return string HTML segment for the links
*/
protected static function generateFlowThankElement( $post, $user, $recipient ) {
$cssActiveClass = 'mw-thanks-flow-thank-link mw-ui-button mw-ui-quiet mw-ui-constructive';
$cssInactiveClass = 'mw-thanks-flow-thanked mw-ui-button mw-ui-quiet mw-ui-disabled';
$uuid = $post->getPostId()->getAlphadecimal();
// User has already thanked for revision
if ( $user->getRequest()->getSessionData( "flow-thanked-{$uuid}" ) ) {
return Html::rawElement(
'span',
array( 'class' => $cssInactiveClass ),
wfMessage( 'thanks-button-thanked', $user )->escaped()
);
}
// Add 'thank' link
$tooltip = wfMessage( 'thanks-thank-tooltip' )
->params( $user->getName(), $recipient->getName() )
->text();
return Html::rawElement(
'a',
array(
'class' => $cssActiveClass,
'href' => SpecialPage::getTitleFor(
'Thanks',
'Flow/' . $uuid
)->getFullURL(),
'title' => $tooltip,
'data-post-id' => $uuid
),
wfMessage( 'thanks-button-thank', $user )->escaped()
);
}
}