summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'Thanks/includes/ThanksHooks.php')
-rw-r--r--Thanks/includes/ThanksHooks.php180
1 files changed, 91 insertions, 89 deletions
diff --git a/Thanks/includes/ThanksHooks.php b/Thanks/includes/ThanksHooks.php
index d2308a1a..34cadd69 100644
--- a/Thanks/includes/ThanksHooks.php
+++ b/Thanks/includes/ThanksHooks.php
@@ -1,6 +1,9 @@
<?php
+use MediaWiki\Linker\LinkTarget;
use MediaWiki\MediaWikiServices;
+use MediaWiki\Revision\RevisionRecord;
+use MediaWiki\User\UserIdentity;
/**
* Hooks for Thanks extension
@@ -11,43 +14,35 @@ use MediaWiki\MediaWikiServices;
class ThanksHooks {
/**
- * ResourceLoaderTestModules hook handler
- * @see https://www.mediawiki.org/wiki/Manual:Hooks/ResourceLoaderTestModules
+ * Handler for HistoryTools and DiffTools hooks.
*
- * @param array &$testModules The modules array to add to.
- * @param ResourceLoader &$resourceLoader The resource loader.
- * @return bool
+ * Insert a 'thank' link into revision interface, if the user is allowed to thank.
+ *
+ * @param RevisionRecord $revisionRecord RevisionRecord object to add the thank link for
+ * @param array &$links Links to add to the revision interface
+ * @param ?RevisionRecord $oldRevisionRecord RevisionRecord object of the "old" revision
+ * when viewing a diff
+ * @param UserIdentity $userIdentity The user performing the thanks.
*/
- public static function onResourceLoaderTestModules( array &$testModules,
- ResourceLoader &$resourceLoader
+ public static function insertThankLink(
+ RevisionRecord $revisionRecord,
+ array &$links,
+ ?RevisionRecord $oldRevisionRecord,
+ UserIdentity $userIdentity
) {
- if ( class_exists( 'SpecialMobileDiff' ) ) {
- $testModules['qunit']['tests.ext.thanks.mobilediff'] = [
- 'localBasePath' => dirname( __DIR__ ),
- 'remoteExtPath' => 'Thanks',
- 'dependencies' => [ 'ext.thanks.mobilediff' ],
- 'scripts' => [
- 'tests/qunit/test_ext.thanks.mobilediff.js',
- ],
- 'targets' => [ 'desktop', 'mobile' ],
- ];
+ $recipient = $revisionRecord->getUser();
+ if ( $recipient === null ) {
+ // Cannot see the user
+ return;
}
- return true;
- }
- /**
- * Handler for HistoryRevisionTools and DiffRevisionTools hooks.
- * Inserts 'thank' link into revision interface
- * @param Revision $rev Revision object to add the thank link for
- * @param array &$links Links to add to the revision interface
- * @param Revision|null $oldRev Revision object of the "old" revision when viewing a diff
- * @param User $user The user performing the thanks.
- * @return bool
- */
- public static function insertThankLink( $rev, &$links, $oldRev, User $user ) {
- $recipientId = $rev->getUser();
- $recipient = User::newFromId( $recipientId );
- $prev = $rev->getPrevious();
+ $recipient = User::newFromIdentity( $recipient );
+ $previous = MediaWikiServices::getInstance()
+ ->getRevisionLookup()
+ ->getPreviousRevision( $revisionRecord );
+
+ $user = User::newFromIdentity( $userIdentity );
+
// Don't let users thank themselves.
// Exclude anonymous users.
// Exclude users who are blocked.
@@ -56,16 +51,35 @@ class ThanksHooks {
// (It supports discontinuous history created by Import or CX but
// prevents thanking diff across multiple revisions)
if ( !$user->isAnon()
- && $recipientId !== $user->getId()
- && !$user->isBlocked()
+ && !$user->equals( $recipient )
+ && !self::isUserBlockedFromTitle( $user, $revisionRecord->getPageAsLinkTarget() )
&& !$user->isBlockedGlobally()
&& self::canReceiveThanks( $recipient )
- && !$rev->isDeleted( Revision::DELETED_TEXT )
- && ( !$oldRev || !$prev || $prev->getId() === $oldRev->getId() )
+ && !$revisionRecord->isDeleted( RevisionRecord::DELETED_TEXT )
+ && ( !$oldRevisionRecord || !$previous ||
+ $previous->getId() === $oldRevisionRecord->getId() )
) {
- $links[] = self::generateThankElement( $rev->getId(), $recipient );
+ $links[] = self::generateThankElement(
+ $revisionRecord->getId(),
+ $user,
+ $recipient
+ );
}
- return true;
+ }
+
+ /**
+ * Check whether the user is blocked from the title associated with the revision.
+ *
+ * This queries the replicas for a block; if 'no block' is incorrectly reported, it
+ * will be caught by ApiThank::dieOnBlockedUser when the user attempts to thank.
+ *
+ * @param User $user
+ * @param LinkTarget $title
+ * @return bool
+ */
+ private static function isUserBlockedFromTitle( User $user, LinkTarget $title ) {
+ return MediaWikiServices::getInstance()->getPermissionManager()
+ ->isBlockedFrom( $user, $title, true );
}
/**
@@ -77,7 +91,7 @@ class ThanksHooks {
protected static function canReceiveThanks( User $user ) {
global $wgThanksSendToBots;
- if ( $user->isAnon() ) {
+ if ( $user->isAnon() || $user->isSystemUser() ) {
return false;
}
@@ -92,28 +106,30 @@ class ThanksHooks {
* Helper for self::insertThankLink
* Creates either a thank link or thanked span based on users session
* @param int $id Revision or log ID to generate the thank element for.
+ * @param User $sender User who sends thanks notification.
* @param User $recipient User who receives thanks notification.
* @param string $type Either 'revision' or 'log'.
* @return string
*/
- protected static function generateThankElement( $id, $recipient, $type = 'revision' ) {
- global $wgUser;
+ protected static function generateThankElement(
+ $id, User $sender, User $recipient, $type = 'revision'
+ ) {
// Check if the user has already thanked for this revision or log entry.
// Session keys are backwards-compatible, and are also used in the ApiCoreThank class.
$sessionKey = ( $type === 'revision' ) ? $id : $type . $id;
- if ( $wgUser->getRequest()->getSessionData( "thanks-thanked-$sessionKey" ) ) {
+ if ( $sender->getRequest()->getSessionData( "thanks-thanked-$sessionKey" ) ) {
return Html::element(
'span',
[ 'class' => 'mw-thanks-thanked' ],
- wfMessage( 'thanks-thanked', $wgUser, $recipient->getName() )->text()
+ wfMessage( 'thanks-thanked', $sender->getName(), $recipient->getName() )->text()
);
}
$genderCache = MediaWikiServices::getInstance()->getGenderCache();
// Add 'thank' link
$tooltip = wfMessage( 'thanks-thank-tooltip' )
- ->params( $wgUser->getName(), $recipient->getName() )
- ->text();
+ ->params( $sender->getName(), $recipient->getName() )
+ ->text();
$subpage = ( $type === 'revision' ) ? '' : 'Log/';
return Html::element(
@@ -125,7 +141,7 @@ class ThanksHooks {
'data-' . $type . '-id' => $id,
'data-recipient-gender' => $genderCache->getGenderOf( $recipient->getName(), __METHOD__ ),
],
- wfMessage( 'thanks-thank', $wgUser, $recipient->getName() )->text()
+ wfMessage( 'thanks-thank', $sender->getName(), $recipient->getName() )->text()
);
}
@@ -142,32 +158,26 @@ class ThanksHooks {
/**
* Handler for PageHistoryBeforeList hook.
- * @see http://www.mediawiki.org/wiki/Manual:Hooks/PageHistoryBeforeList
- * @param WikiPage|Article|ImagePage|CategoryPage|Page &$page The page for which the history
- * is loading.
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/PageHistoryBeforeList
+ *
+ * @param WikiPage|Article|ImagePage|CategoryPage $page Not used
* @param RequestContext $context RequestContext object
- * @return bool true in all cases
*/
- public static function onPageHistoryBeforeList( &$page, $context ) {
+ public static function onPageHistoryBeforeList( $page, $context ) {
if ( $context->getUser()->isLoggedIn() ) {
static::addThanksModule( $context->getOutput() );
}
- return true;
}
/**
- * Handler for DiffViewHeader hook.
- * @see http://www.mediawiki.org/wiki/Manual:Hooks/DiffViewHeader
+ * Handler for DifferenceEngineViewHeader hook.
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/DifferenceEngineViewHeader
* @param DifferenceEngine $diff DifferenceEngine object that's calling.
- * @param Revision $oldRev Revision object of the "old" revision (may be null/invalid)
- * @param Revision $newRev Revision object of the "new" revision
- * @return bool true in all cases
*/
- public static function onDiffViewHeader( $diff, $oldRev, $newRev ) {
+ public static function onDifferenceEngineViewHeader( $diff ) {
if ( $diff->getUser()->isLoggedIn() ) {
static::addThanksModule( $diff->getOutput() );
}
- return true;
}
/**
@@ -176,7 +186,6 @@ class ThanksHooks {
* @param array &$notifications array of Echo notifications
* @param array &$notificationCategories array of Echo notification categories
* @param array &$icons array of icon details
- * @return bool
*/
public static function onBeforeCreateEchoEvent(
&$notifications, &$notificationCategories, &$icons
@@ -197,7 +206,7 @@ class ThanksHooks {
],
];
- if ( class_exists( Flow\FlowPresentationModel::class ) ) {
+ if ( ExtensionRegistry::getInstance()->isLoaded( 'Flow' ) ) {
$notifications['flow-thank'] = [
'category' => 'edit-thank',
'group' => 'positive',
@@ -216,15 +225,12 @@ class ThanksHooks {
'rtl' => 'Thanks/userTalk-constructive-rtl.svg'
]
];
-
- return true;
}
/**
* Add user to be notified on echo event
* @param EchoEvent $event The event.
* @param User[] &$users The user list to add to.
- * @return bool
*/
public static function onEchoGetDefaultNotifiedUsers( $event, &$users ) {
switch ( $event->getType() ) {
@@ -239,15 +245,13 @@ class ThanksHooks {
$users[$recipientId] = $recipient;
break;
}
- return true;
}
/**
* Handler for LocalUserCreated hook
- * @see http://www.mediawiki.org/wiki/Manual:Hooks/LocalUserCreated
+ * @see https://www.mediawiki.org/wiki/Manual:Hooks/LocalUserCreated
* @param User $user User object that was created.
* @param bool $autocreated True when account was auto-created
- * @return bool
*/
public static function onAccountCreated( $user, $autocreated ) {
// New users get echo preferences set that are not the default settings for existing users.
@@ -256,15 +260,14 @@ class ThanksHooks {
$user->setOption( 'echo-subscriptions-email-edit-thank', true );
$user->saveSettings();
}
- return true;
}
/**
* Add thanks button to SpecialMobileDiff page
* @param OutputPage &$output OutputPage object
* @param MobileContext $ctx MobileContext object
- * @param array $revisions Array of the two revisions that are being compared in the diff
- * @return bool true in all cases
+ * @param array $revisions Array with two elements, either nulls or RevisionRecord objects for
+ * the two revisions that are being compared in the diff
*/
public static function onBeforeSpecialMobileDiffDisplay( &$output, $ctx, $revisions ) {
$rev = $revisions[1];
@@ -272,8 +275,9 @@ class ThanksHooks {
// If the MobileFrontend extension is installed and the user is
// logged in or recipient is not a bot if bots cannot receive thanks, show a 'Thank' link.
if ( $rev
- && class_exists( 'SpecialMobileDiff' )
- && self::canReceiveThanks( User::newFromId( $rev->getUser() ) )
+ && ExtensionRegistry::getInstance()->isLoaded( 'MobileFrontend' )
+ && $rev->getUser()
+ && self::canReceiveThanks( User::newFromIdentity( $rev->getUser() ) )
&& $output->getUser()->isLoggedIn()
) {
$output->addModules( [ 'ext.thanks.mobilediff' ] );
@@ -284,7 +288,6 @@ class ThanksHooks {
}
}
- return true;
}
/**
@@ -292,11 +295,9 @@ class ThanksHooks {
* So users can just type in a username for target and it'll work.
* @link https://www.mediawiki.org/wiki/Manual:Hooks/GetLogTypesOnUser
* @param string[] &$types The list of log types, to add to.
- * @return bool
*/
public static function onGetLogTypesOnUser( array &$types ) {
$types[] = 'thanks';
- return true;
}
/**
@@ -306,7 +307,6 @@ class ThanksHooks {
* @link https://www.mediawiki.org/wiki/Manual:Hooks/BeforePageDisplay
* @param OutputPage $out OutputPage object
* @param Skin $skin The skin in use.
- * @return bool
*/
public static function onBeforePageDisplay( OutputPage $out, $skin ) {
$title = $out->getTitle();
@@ -318,7 +318,6 @@ class ThanksHooks {
if ( $title->isSpecial( 'Log' ) ) {
static::addThanksModule( $out );
}
- return true;
}
/**
@@ -326,17 +325,15 @@ class ThanksHooks {
* Flow is installed.
*
* @param ApiModuleManager $moduleManager Module manager instance
- * @return bool
*/
public static function onApiMainModuleManager( ApiModuleManager $moduleManager ) {
- if ( class_exists( 'FlowHooks' ) ) {
+ if ( ExtensionRegistry::getInstance()->isLoaded( 'Flow' ) ) {
$moduleManager->addModule(
'flowthank',
'action',
'ApiFlowThank'
);
}
- return true;
}
/**
@@ -344,7 +341,6 @@ class ThanksHooks {
*
* @param EchoEvent $event The event being notified.
* @param string &$bundleString Determines how the notification should be bundled.
- * @return bool True for success
*/
public static function onEchoGetBundleRules( $event, &$bundleString ) {
switch ( $event->getType() ) {
@@ -370,10 +366,11 @@ class ThanksHooks {
}
break;
}
- return true;
}
/**
+ * Insert a 'thank' link into the log interface, if the user is allowed to thank.
+ *
* @link https://www.mediawiki.org/wiki/Manual:Hooks/LogEventsListLineEnding
* @param LogEventsList $page The log events list.
* @param string &$ret The lineending HTML, to modify.
@@ -385,10 +382,15 @@ class ThanksHooks {
public static function onLogEventsListLineEnding(
LogEventsList $page, &$ret, DatabaseLogEntry $entry, &$classes, &$attribs
) {
- global $wgUser;
-
- // Don't thank if anonymous or blocked
- if ( $wgUser->isAnon() || $wgUser->isBlocked() || $wgUser->isBlockedGlobally() ) {
+ $user = $page->getUser();
+
+ // Don't thank if anonymous or blocked or if user is deleted from the log entry
+ if (
+ $user->isAnon()
+ || $entry->isDeleted( LogPage::DELETED_USER )
+ || self::isUserBlockedFromTitle( $user, $entry->getTarget() )
+ || $user->isBlockedGlobally()
+ ) {
return;
}
@@ -405,7 +407,7 @@ class ThanksHooks {
// Don't check for deleted revision (this avoids extraneous queries from Special:Log).
$recipient = $entry->getPerformer();
if ( !$recipient
- || $recipient->getId() === $wgUser->getId()
+ || $recipient->getId() === $user->getId()
|| !self::canReceiveThanks( $recipient )
) {
return;
@@ -414,8 +416,8 @@ class ThanksHooks {
// Create thank link either for the revision (if there is an associated revision ID)
// or the log entry.
$type = $entry->getAssociatedRevId() ? 'revision' : 'log';
- $id = $entry->getAssociatedRevId() ? $entry->getAssociatedRevId() : $entry->getId();
- $thankLink = self::generateThankElement( $id, $recipient, $type );
+ $id = $entry->getAssociatedRevId() ?: $entry->getId();
+ $thankLink = self::generateThankElement( $id, $user, $recipient, $type );
// Add parentheses to match what's done with Thanks in revision lists and diff displays.
$ret .= ' ' . wfMessage( 'parentheses' )->rawParams( $thankLink )->escaped();