mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Thanks
synced 2024-11-27 16:20:12 +00:00
Add support to the Thanks API for thanking log entries
Add a 'log' API parameter (for the log ID to thank), and add a whitelist config variable for specifying which log types are thankable. Bug: T186855 Change-Id: I58ae90c9729c0066f952e90fca2cf99b029d0d9b
This commit is contained in:
parent
e754b25c6a
commit
b84eedc74e
|
@ -184,7 +184,18 @@
|
|||
"config": {
|
||||
"ThanksSendToBots": false,
|
||||
"ThanksLogging": true,
|
||||
"ThanksConfirmationRequired": true
|
||||
"ThanksConfirmationRequired": true,
|
||||
"ThanksLogTypeWhitelist": [
|
||||
"contentmodel",
|
||||
"delete",
|
||||
"import",
|
||||
"merge",
|
||||
"patrol",
|
||||
"protect",
|
||||
"tag",
|
||||
"managetags",
|
||||
"rights"
|
||||
]
|
||||
},
|
||||
"manifest_version": 1
|
||||
}
|
||||
|
|
13
i18n/en.json
13
i18n/en.json
|
@ -10,6 +10,8 @@
|
|||
"thanks-button-thank": "{{GENDER:$1|{{GENDER:$2|Thank}}}}",
|
||||
"thanks-button-thanked": "{{GENDER:$1|{{GENDER:$2|Thanked}}}}",
|
||||
"thanks-error-undefined": "Thank action failed (error code: $1). Please try again.",
|
||||
"thanks-error-invalid-log-type": "Log type '$1' is not in the whitelist of permitted log types.",
|
||||
"thanks-error-log-deleted": "The requested log entry has been deleted and thanks cannot be given for it.",
|
||||
"thanks-error-invalidrevision": "Revision ID is not valid.",
|
||||
"thanks-error-revdeleted": "Revision has been deleted",
|
||||
"thanks-error-notitle": "Page title could not be retrieved",
|
||||
|
@ -19,6 +21,7 @@
|
|||
"thanks-error-echonotinstalled": "Echo is not installed on this wiki",
|
||||
"thanks-error-notloggedin": "Anonymous users cannot send thanks",
|
||||
"thanks-error-ratelimited": "{{GENDER:$1|You}}'ve exceeded your rate limit. Please wait some time and try again.",
|
||||
"thanks-error-api-params": "Either the 'revid' or the 'logid' parameter must be provided",
|
||||
"thanks-thank-tooltip": "{{GENDER:$1|Send}} a thank you notification to this {{GENDER:$2|user}}",
|
||||
"thanks-thank-tooltip-no": "{{GENDER:$1|Cancel}} the thank you notification",
|
||||
"thanks-thank-tooltip-yes": "{{GENDER:$1|Send}} the thank you notification",
|
||||
|
@ -31,9 +34,11 @@
|
|||
"echo-pref-tooltip-edit-thank": "Notify me when someone thanks me for an edit I made.",
|
||||
"echo-category-title-edit-thank": "Thanks",
|
||||
"notification-thanks-diff-link": "your edit",
|
||||
"notification-header-edit-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your edit on <strong>$3</strong>.",
|
||||
"notification-header-rev-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your edit on <strong>$3</strong>.",
|
||||
"notification-header-log-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|you}} for your action relating to <strong>$3</strong>.",
|
||||
"notification-compact-header-edit-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$3|you}}.",
|
||||
"notification-bundle-header-edit-thank": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your edit on <strong>$2</strong>.",
|
||||
"notification-bundle-header-rev-thank": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your edit on <strong>$2</strong>.",
|
||||
"notification-bundle-header-log-thank": "{{PLURAL:$1|One person|$1 people|100=99+ people}} thanked {{GENDER:$3|you}} for your action relating to <strong>$2</strong>.",
|
||||
"log-name-thanks": "Thanks log",
|
||||
"log-description-thanks": "Below is a list of users thanked by other users.",
|
||||
"logentry-thanks-thank": "$1 {{GENDER:$2|thanked}} {{GENDER:$4|$3}}",
|
||||
|
@ -41,6 +46,7 @@
|
|||
"thanks-error-no-id-specified": "You must specify a revision ID to send thanks.",
|
||||
"thanks-confirmation-special": "Do you want to publicly send thanks for this edit?",
|
||||
"notification-link-text-view-post": "View comment",
|
||||
"notification-link-text-view-logentry": "View log entry",
|
||||
"thanks-error-invalidpostid": "Post ID is not valid.",
|
||||
"flow-thanks-confirmation-special": "Do you want to publicly send thanks for this comment?",
|
||||
"flow-thanks-thanked-notice": "{{GENDER:$3|You}} thanked $1 for {{GENDER:$2|his|her|their}} comment.",
|
||||
|
@ -54,7 +60,8 @@
|
|||
"apihelp-flowthank-example-1": "Send thanks for the comment with <kbd>UUID xyz789</kbd>",
|
||||
"apihelp-thank-description": "Send a thank-you notification to an editor.",
|
||||
"apihelp-thank-summary": "Send a thank-you notification to an editor.",
|
||||
"apihelp-thank-param-rev": "Revision ID to thank someone for.",
|
||||
"apihelp-thank-param-rev": "Revision ID to thank someone for. This or 'log' must be provided.",
|
||||
"apihelp-thank-param-log": "Log ID to thank someone for. This or 'rev' must be provided.",
|
||||
"apihelp-thank-param-source": "A short string describing the source of the request, for example <kbd>diff</kbd> or <kbd>history</kbd>.",
|
||||
"apihelp-thank-example-1": "Send thanks for revision <kbd>ID 456</kbd>, with the source being a diff page"
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
"thanks-button-thank": "Text of a button to thank another user. Same as {{msg-mw|Thanks-thank}}, but the context is in a button.\n\nFor languages that need it, the gender of each of the thanked and thanking users is available.\n\nParameters:\n* $1 - The user that is thanking\n* $2 - The user that is being thanked\n\n{{Identical|Thank}}",
|
||||
"thanks-button-thanked": "This message immediately replaces the message {{msg-mw|Thanks-button-thank}} after it's pressed. It means that the thanking operation has been completed. Same as {{msg-mw|Thanks-thanked}}, but the context is in a button.\n\nFor languages that need it, the gender of each of the thanked and thanking users is available.\n\nParameters:\n* $1 - The user that is thanking\n* $2 - The user that has been thanked\n\n{{Identical|Thanked}}",
|
||||
"thanks-error-undefined": "Error message that is displayed when the thank action fails. $1 is the error code returned by the API (an English string).",
|
||||
"thanks-error-invalid-log-type": "Error message that is displayed when thanks is attempted for a log entry of a non-whitelisted type. $1 is the offending log type.",
|
||||
"thanks-error-log-deleted": "Error message that is displayed when thanks is attempted for a deleted log entry.",
|
||||
"thanks-error-invalidrevision": "Error message that is displayed when the revision ID is not valid",
|
||||
"thanks-error-revdeleted": "Error message that is displayed when the revision has been deleted (RevDel)",
|
||||
"thanks-error-notitle": "Error message that is displayed when the title of the page cannot be determined",
|
||||
|
@ -30,6 +32,7 @@
|
|||
"thanks-error-echonotinstalled": "Error message that is displayed when Echo is not installed",
|
||||
"thanks-error-notloggedin": "Error message that is displayed when the user is not logged in",
|
||||
"thanks-error-ratelimited": "Error message that is displayed when user exceeds rate limit.\n\nParameters:\n* $1 - The user sending the thanks. Can be used for GENDER support.",
|
||||
"thanks-error-api-params": "Error message shown when both the 'rev' and 'log' API parameters are absent",
|
||||
"thanks-thank-tooltip": "Tooltip that appears when a user hovers over the \"thank\" link.\n\nParameters:\n* $1 - The user sending the thanks. Can be used for GENDER support.\n* $2 - The user receiving the thanks. Can be used for GENDER support.",
|
||||
"thanks-thank-tooltip-no": "Tooltip that appears when a user hovers over the {{msg-mw|confirmable-no}} link, which cancels the thank action.\n\nParameters:\n* $1 - The user sending the thanks. Can be used for GENDER support.",
|
||||
"thanks-thank-tooltip-yes": "Tooltip that appears when a user hovers over the {{msg-mw|confirmable-yes}} link, which confirms the thank action.\n\nParameters:\n* $1 - The user sending the thanks. Can be used for GENDER support.",
|
||||
|
@ -42,9 +45,11 @@
|
|||
"echo-pref-tooltip-edit-thank": "{{doc-echo-pref-tooltip|title=Echo-category-title-edit-thank}}\nYou can use parameterless <code><nowiki>{{GENDER:}}</nowiki></code> here.",
|
||||
"echo-category-title-edit-thank": "{{doc-echo-category-title|tooltip=Echo-pref-tooltip-edit-thank}}\n{{Identical|Thank}}",
|
||||
"notification-thanks-diff-link": "The text of a link to the user's edit.\n\nUsed for <code>$2</code> in {{msg-mw|Notification-thanks}}. Should have capitalization appropriate for the middle of a sentence.\n\nThis is an object in a sentence so it should be in object case in languages where there is a special object form for words.",
|
||||
"notification-header-edit-thank": "Header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the title of the page the thanked user edited.\n* $4 is the username of the user being thanked, for use in GENDER.",
|
||||
"notification-header-rev-thank": "Header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the title of the page the thanked user edited.\n* $4 is the username of the user being thanked, for use in GENDER.",
|
||||
"notification-header-log-thank": "Header text for a notification when a user is thanked for a log entry. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the title of the page that is the target of the log entry.\n* $4 is the username of the user being thanked, for use in GENDER.",
|
||||
"notification-compact-header-edit-thank": "Compact header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the username of the user sending the thanks (not suitable for GENDER).\n* $2 is the thanking user's name for use in GENDER.\n* $3 is the username of the user being thanked, for use in GENDER.",
|
||||
"notification-bundle-header-edit-thank": "Bundle header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the number of users who sent thanks for the same edit. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the title of the page the thanked user edited.\n* $3 is the username of the user being thanked, for use in GENDER.\n{{Related|Notification-bundle}}",
|
||||
"notification-bundle-header-rev-thank": "Bundle header text for a notification when a user is thanked for their edit. Parameters:\n* $1 is the number of users who sent thanks for the same edit. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the title of the page the thanked user edited.\n* $3 is the username of the user being thanked, for use in GENDER.\n{{Related|Notification-bundle}}",
|
||||
"notification-bundle-header-log-thank": "Bundle header text for a notification when a user is thanked for a log entry. Parameters:\n* $1 is the number of users who sent thanks for the same edit. When used with PLURAL, the value 100 represents more than 99.\n* $2 is the title of the page that is the target of the log entry.\n* $3 is the username of the user being thanked, for use in GENDER.\n{{Related|Notification-bundle}}",
|
||||
"log-name-thanks": "Name of log that appears on [[Special:Log]].",
|
||||
"log-description-thanks": "Description of thanks log",
|
||||
"logentry-thanks-thank": "Log entry that is created when a user thanks another user for an edit. Parameters:\n* $1 is a user link, for example \"Jane Doe (Talk | contribs)\"\n* $2 is a username. Can be used for GENDER.\n* $3 is a user link, for example \"John Doe (Talk | contribs)\n* $4 is the username of the recipient. Can be used for GENDER.\n{{Identical|Thanked}}",
|
||||
|
@ -52,6 +57,7 @@
|
|||
"thanks-error-no-id-specified": "Error message shown to the user when they visit Special:Thanks without specifying a revision ID",
|
||||
"thanks-confirmation-special": "A confirmation message shown on [[Special:Thanks]] to make sure the user wants to send thanks for an edit (publicly).\n\nSee also:\n* {{msg-mw|Flow-thanks-confirmation-special}}\n* {{msg-mw|Thanks-confirmation2}}",
|
||||
"notification-link-text-view-post": "Label for button that links to a comment on a Flow board",
|
||||
"notification-link-text-view-logentry": "Label for button that links to a log entry",
|
||||
"thanks-error-invalidpostid": "Error message that is displayed when the Flow post UUID is not valid",
|
||||
"flow-thanks-confirmation-special": "A confirmation message shown on [[Special:Thanks]] to make sure the user wants to send thanks for a comment (publicly).\n\nSee also:\n* {{msg-mw|Thanks-confirmation-special}}\n* {{msg-mw|Thanks-confirmation2}}",
|
||||
"flow-thanks-thanked-notice": "{{doc-singularthey}}\nMessage displayed after a user has thanked another user for their comment.\n\nParameters:\n* $1 - The username of the user that was thanked.\n* $2 - The gender of the user that was thanked.\n* $3 - The user sending the thanks. Can be used for GENDER support.\n\nSee also:\n* {{msg-mw|Thanks-thanked-notice}}",
|
||||
|
@ -66,6 +72,7 @@
|
|||
"apihelp-thank-description": "{{doc-apihelp-description|thank}}",
|
||||
"apihelp-thank-summary": "{{doc-apihelp-summary|thank}}",
|
||||
"apihelp-thank-param-rev": "{{doc-apihelp-param|thank|rev}}",
|
||||
"apihelp-thank-param-log": "{{doc-apihelp-param|thank|log}}",
|
||||
"apihelp-thank-param-source": "{{doc-apihelp-param|thank|source}}",
|
||||
"apihelp-thank-example-1": "{{doc-apihelp-example|thank}}"
|
||||
}
|
||||
|
|
|
@ -1,41 +1,87 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* API module to send thanks notifications for revisions
|
||||
* API module to send thanks notifications for revisions and log entries.
|
||||
*
|
||||
* @ingroup API
|
||||
* @ingroup Extensions
|
||||
*/
|
||||
class ApiCoreThank extends ApiThank {
|
||||
public function execute() {
|
||||
$this->dieIfEchoNotInstalled();
|
||||
|
||||
/**
|
||||
* Perform the API request.
|
||||
*/
|
||||
public function execute() {
|
||||
// Initial setup.
|
||||
$this->dieIfEchoNotInstalled();
|
||||
$user = $this->getUser();
|
||||
$this->dieOnBadUser( $user );
|
||||
|
||||
$params = $this->extractRequestParams();
|
||||
$revision = $this->getRevisionFromParams( $params );
|
||||
|
||||
if ( $this->userAlreadySentThanksForRevision( $user, $revision ) ) {
|
||||
$this->markResultSuccess( $revision->getUserText() );
|
||||
// Extract type and ID from the parameters.
|
||||
if ( isset( $params['rev'] ) && !isset( $params['log'] ) ) {
|
||||
$type = 'rev';
|
||||
$id = $params['rev'];
|
||||
} elseif ( !isset( $params['rev'] ) && isset( $params['log'] ) ) {
|
||||
$type = 'log';
|
||||
$id = $params['log'];
|
||||
} else {
|
||||
$this->dieWithError( 'thanks-error-api-params', 'thanks-error-api-params' );
|
||||
}
|
||||
|
||||
// Determine thanks parameters.
|
||||
if ( $type === 'log' ) {
|
||||
$logEntry = $this->getLogEntryFromId( $id );
|
||||
// If there's an associated revision, thank for that instead.
|
||||
if ( $logEntry->getAssociatedRevId() ) {
|
||||
$type = 'rev';
|
||||
$id = $logEntry->getAssociatedRevId();
|
||||
} else {
|
||||
$formatter = LogFormatter::newFromEntry( $logEntry );
|
||||
$excerpt = $formatter->getPlainActionText();
|
||||
$title = $logEntry->getTarget();
|
||||
$recipient = $this->getUserFromLog( $logEntry );
|
||||
$recipientUsername = $recipient->getName();
|
||||
}
|
||||
}
|
||||
if ( $type === 'rev' ) {
|
||||
$revision = $this->getRevisionFromParams( $params );
|
||||
$excerpt = EchoDiscussionParser::getEditExcerpt( $revision, $this->getLanguage() );
|
||||
$title = $this->getTitleFromRevision( $revision );
|
||||
$recipient = $this->getUserFromRevision( $revision );
|
||||
$recipientUsername = $revision->getUserText();
|
||||
}
|
||||
|
||||
// Send thanks.
|
||||
if ( $this->userAlreadySentThanks( $user, $type, $id ) ) {
|
||||
$this->markResultSuccess( $recipientUsername );
|
||||
} else {
|
||||
$this->dieOnBadRecipient( $user, $recipient );
|
||||
$this->sendThanks(
|
||||
$user,
|
||||
$revision,
|
||||
$type,
|
||||
$id,
|
||||
$excerpt,
|
||||
$recipient,
|
||||
$this->getSourceFromParams( $params )
|
||||
$this->getSourceFromParams( $params ),
|
||||
$title
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
protected function userAlreadySentThanksForRevision( User $user, Revision $revision ) {
|
||||
return $user->getRequest()->getSessionData( "thanks-thanked-{$revision->getId()}" );
|
||||
/**
|
||||
* Check the session data for an indication of whether this user has already sent this thanks.
|
||||
* @param User $user The user being thanked.
|
||||
* @param string $type Either 'rev' or 'log'.
|
||||
* @param int $id The revision or log ID.
|
||||
* @return bool
|
||||
*/
|
||||
protected function userAlreadySentThanks( User $user, $type, $id ) {
|
||||
return (bool)$user->getRequest()->getSessionData( "thanks-thanked-$type$id" );
|
||||
}
|
||||
|
||||
private function getRevisionFromParams( $params ) {
|
||||
$revision = Revision::newFromId( $params['rev'] );
|
||||
|
||||
// Revision ID 1 means an invalid argument was passed in.
|
||||
if ( !$revision || $revision->getId() === 1 ) {
|
||||
$this->dieWithError( 'thanks-error-invalidrevision', 'invalidrevision' );
|
||||
|
@ -45,6 +91,40 @@ class ApiCoreThank extends ApiThank {
|
|||
return $revision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the log entry from the ID.
|
||||
* @param int $logId The log entry ID.
|
||||
* @return DatabaseLogEntry
|
||||
*/
|
||||
protected function getLogEntryFromId( $logId ) {
|
||||
$queryInfo = DatabaseLogEntry::getSelectQueryData();
|
||||
$queryInfo['conds'] += [ 'log_id' => $logId ];
|
||||
$db = wfGetDB( DB_REPLICA );
|
||||
$logEntryData = $db->select(
|
||||
$queryInfo['tables'],
|
||||
$queryInfo['fields'],
|
||||
$queryInfo['conds'],
|
||||
__METHOD__,
|
||||
$queryInfo['options'],
|
||||
$queryInfo['join_conds']
|
||||
);
|
||||
$logEntry = DatabaseLogEntry::newFromRow( $logEntryData->current() );
|
||||
|
||||
// Make sure this log type is whitelisted.
|
||||
$logTypeWhitelist = $this->getConfig()->get( 'ThanksLogTypeWhitelist' );
|
||||
if ( !in_array( $logEntry->getType(), $logTypeWhitelist ) ) {
|
||||
$err = $this->msg( 'thanks-error-invalid-log-type', $logEntry->getType() );
|
||||
$this->dieWithError( $err, 'thanks-error-invalid-log-type' );
|
||||
}
|
||||
|
||||
// Don't permit thanks if any part of the log entry is deleted.
|
||||
if ( $logEntry->getDeleted() ) {
|
||||
$this->dieWithError( 'thanks-error-log-deleted', 'thanks-error-log-deleted' );
|
||||
}
|
||||
|
||||
return $logEntry;
|
||||
}
|
||||
|
||||
private function getTitleFromRevision( Revision $revision ) {
|
||||
$title = Title::newFromID( $revision->getPage() );
|
||||
if ( !$title instanceof Title ) {
|
||||
|
@ -55,6 +135,8 @@ class ApiCoreThank extends ApiThank {
|
|||
|
||||
/**
|
||||
* Set the source of the thanks, e.g. 'diff' or 'history'
|
||||
* @param string[] $params Incoming API parameters, with a 'source' key.
|
||||
* @return string The source, or 'undefined' if not provided.
|
||||
*/
|
||||
private function getSourceFromParams( $params ) {
|
||||
if ( $params['source'] ) {
|
||||
|
@ -72,8 +154,30 @@ class ApiCoreThank extends ApiThank {
|
|||
return User::newFromId( $recipient );
|
||||
}
|
||||
|
||||
private function sendThanks( User $user, Revision $revision, User $recipient, $source ) {
|
||||
$uniqueId = "rev-{$revision->getId()}";
|
||||
private function getUserFromLog( LogEntry $logEntry ) {
|
||||
$recipient = $logEntry->getPerformer();
|
||||
if ( !$recipient ) {
|
||||
$this->dieWithError( 'thanks-error-invalidrecipient', 'invalidrecipient' );
|
||||
}
|
||||
return $recipient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the thanks notification event, and log the thanks.
|
||||
* @param User $user The thanks-sending user.
|
||||
* @param string $type The thanks type ('rev' or 'log').
|
||||
* @param int $id The log or revision ID.
|
||||
* @param string $excerpt The excerpt to display as the thanks notification. This will only
|
||||
* be used if it is not possible to retrieve the relevant excerpt at the time the
|
||||
* notification is displayed (in order to account for changing visibility in the meantime).
|
||||
* @param User $recipient The recipient of the thanks.
|
||||
* @param string $source Where the thanks was given.
|
||||
* @param Title $title The title of the page for which thanks is given.
|
||||
*/
|
||||
protected function sendThanks(
|
||||
User $user, $type, $id, $excerpt, User $recipient, $source, Title $title
|
||||
) {
|
||||
$uniqueId = $type . '-' . $id;
|
||||
// Do one last check to make sure we haven't sent Thanks before
|
||||
if ( $this->haveAlreadyThanked( $user, $uniqueId ) ) {
|
||||
// Pretend the thanks were sent
|
||||
|
@ -81,22 +185,21 @@ class ApiCoreThank extends ApiThank {
|
|||
return;
|
||||
}
|
||||
|
||||
$title = $this->getTitleFromRevision( $revision );
|
||||
// Create the notification via Echo extension
|
||||
EchoEvent::create( [
|
||||
'type' => 'edit-thank',
|
||||
'title' => $title,
|
||||
'extra' => [
|
||||
'revid' => $revision->getId(),
|
||||
$type . 'id' => $id,
|
||||
'thanked-user-id' => $recipient->getId(),
|
||||
'source' => $source,
|
||||
'excerpt' => EchoDiscussionParser::getEditExcerpt( $revision, $this->getLanguage() ),
|
||||
'excerpt' => $excerpt,
|
||||
],
|
||||
'agent' => $user,
|
||||
] );
|
||||
|
||||
// And mark the thank in session for a cheaper check to prevent duplicates (Bug 46690).
|
||||
$user->getRequest()->setSessionData( "thanks-thanked-{$revision->getId()}", true );
|
||||
// And mark the thank in session for a cheaper check to prevent duplicates (Phab:T48690).
|
||||
$user->getRequest()->setSessionData( "thanks-thanked-$type$id", true );
|
||||
// Set success message
|
||||
$this->markResultSuccess( $recipient->getName() );
|
||||
$this->logThanks( $user, $recipient, $uniqueId );
|
||||
|
@ -107,7 +210,12 @@ class ApiCoreThank extends ApiThank {
|
|||
'rev' => [
|
||||
ApiBase::PARAM_TYPE => 'integer',
|
||||
ApiBase::PARAM_MIN => 1,
|
||||
ApiBase::PARAM_REQUIRED => true,
|
||||
ApiBase::PARAM_REQUIRED => false,
|
||||
],
|
||||
'log' => [
|
||||
ApiBase::PARAM_TYPE => 'integer',
|
||||
ApiBase::PARAM_MIN => 1,
|
||||
ApiBase::PARAM_REQUIRED => false,
|
||||
],
|
||||
'token' => [
|
||||
ApiBase::PARAM_TYPE => 'string',
|
||||
|
|
|
@ -9,14 +9,15 @@ class EchoCoreThanksPresentationModel extends EchoEventPresentationModel {
|
|||
}
|
||||
|
||||
public function getHeaderMessage() {
|
||||
$type = $this->event->getExtraParam( 'logid' ) ? 'log' : 'rev';
|
||||
if ( $this->isBundled() ) {
|
||||
$msg = $this->msg( 'notification-bundle-header-edit-thank' );
|
||||
$msg = $this->msg( "notification-bundle-header-$type-thank" );
|
||||
$msg->params( $this->getBundleCount() );
|
||||
$msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
|
||||
$msg->params( $this->getViewingUserForGender() );
|
||||
return $msg;
|
||||
} else {
|
||||
$msg = $this->getMessageWithAgent( 'notification-header-edit-thank' );
|
||||
$msg = $this->getMessageWithAgent( "notification-header-$type-thank" );
|
||||
$msg->params( $this->getTruncatedTitleText( $this->event->getTitle(), true ) );
|
||||
$msg->params( $this->getViewingUserForGender() );
|
||||
return $msg;
|
||||
|
@ -30,7 +31,7 @@ class EchoCoreThanksPresentationModel extends EchoEventPresentationModel {
|
|||
}
|
||||
|
||||
public function getBodyMessage() {
|
||||
$comment = $this->getEditComment();
|
||||
$comment = $this->getRevOrLogComment();
|
||||
if ( $comment ) {
|
||||
$msg = new RawMessage( '$1' );
|
||||
$msg->plaintextParams( $comment );
|
||||
|
@ -57,26 +58,48 @@ class EchoCoreThanksPresentationModel extends EchoEventPresentationModel {
|
|||
return $summary ?: false;
|
||||
}
|
||||
|
||||
private function getEditComment() {
|
||||
// try to get edit summary
|
||||
$summary = $this->getRevisionEditSummary();
|
||||
if ( $summary ) {
|
||||
return $summary;
|
||||
}
|
||||
|
||||
// fallback on edit excerpt
|
||||
if ( $this->userCan( Revision::DELETED_TEXT ) ) {
|
||||
return $this->event->getExtraParam( 'excerpt', false );
|
||||
/**
|
||||
* Get the comment/summary/excerpt of the log entry or revision,
|
||||
* for use in the notification body.
|
||||
* @return string|bool The comment or false if it could not be retrieved.
|
||||
*/
|
||||
protected function getRevOrLogComment() {
|
||||
if ( $this->event->getExtraParam( 'logid' ) ) {
|
||||
// Use the saved log entry excerpt.
|
||||
$excerpt = $this->event->getExtraParam( 'excerpt', false );
|
||||
// Turn wikitext into plaintext
|
||||
$excerpt = Linker::formatComment( $excerpt );
|
||||
$excerpt = Sanitizer::stripAllTags( $excerpt );
|
||||
return $excerpt;
|
||||
} else {
|
||||
// Try to get edit summary.
|
||||
$summary = $this->getRevisionEditSummary();
|
||||
if ( $summary ) {
|
||||
return $summary;
|
||||
}
|
||||
// Fallback on edit excerpt.
|
||||
if ( $this->userCan( Revision::DELETED_TEXT ) ) {
|
||||
return $this->event->getExtraParam( 'excerpt', false );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getPrimaryLink() {
|
||||
return [
|
||||
'url' => $this->event->getTitle()->getLocalURL( [
|
||||
if ( $this->event->getExtraParam( 'logid' ) ) {
|
||||
$logId = $this->event->getExtraParam( 'logid' );
|
||||
$url = Title::newFromText( "Special:Redirect/logid/$logId" )->getCanonicalURL();
|
||||
$label = 'notification-link-text-view-logentry';
|
||||
} else {
|
||||
$url = $this->event->getTitle()->getLocalURL( [
|
||||
'oldid' => 'prev',
|
||||
'diff' => $this->event->getExtraParam( 'revid' )
|
||||
] ),
|
||||
'label' => $this->msg( 'notification-link-text-view-edit' )->text(),
|
||||
] );
|
||||
$label = 'notification-link-text-view-edit';
|
||||
}
|
||||
return [
|
||||
'url' => $url,
|
||||
// Label is only used for non-JS clients.
|
||||
'label' => $this->msg( $label )->text(),
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -340,9 +340,13 @@ class ThanksHooks {
|
|||
switch ( $event->getType() ) {
|
||||
case 'edit-thank':
|
||||
$bundleString = 'edit-thank';
|
||||
$revId = $event->getExtraParam( 'revid' );
|
||||
if ( $revId ) {
|
||||
$bundleString .= $event->getExtraParam( 'revid' );
|
||||
// Try to get either the revid (old name) or id (new name) parameter.
|
||||
$revOrLogId = $event->getExtraParam( 'revid' );
|
||||
if ( !$revOrLogId ) {
|
||||
$revOrLogId = $event->getExtraParam( 'id' );
|
||||
}
|
||||
if ( $revOrLogId ) {
|
||||
$bundleString .= $revOrLogId;
|
||||
}
|
||||
break;
|
||||
case 'flow-thank':
|
||||
|
|
|
@ -19,6 +19,11 @@ class ApiCoreThankIntegrationTest extends ApiTestCase {
|
|||
*/
|
||||
private $revId;
|
||||
|
||||
/**
|
||||
* @var int The ID of a deletion log entry.
|
||||
*/
|
||||
protected $logId;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
|
@ -31,6 +36,13 @@ class ApiCoreThankIntegrationTest extends ApiTestCase {
|
|||
$revision = $result['revision'];
|
||||
$this->revId = $revision->getId();
|
||||
|
||||
// Create a 2nd page and delete it, so we can thank for the log entry.
|
||||
$pageToDeleteTitle = Title::newFromText( 'Page to delete' );
|
||||
$pageToDelete = WikiPage::factory( $pageToDeleteTitle );
|
||||
$pageToDelete->doEditContent( ContentHandler::makeContent( '', $pageToDeleteTitle ), '' );
|
||||
$deleteStatus = $pageToDelete->doDeleteArticleReal( '' );
|
||||
$this->logId = $deleteStatus->getValue();
|
||||
|
||||
$this->doLogin( 'sysop' );
|
||||
DeferredUpdates::clearPendingUpdates();
|
||||
}
|
||||
|
@ -44,7 +56,7 @@ class ApiCoreThankIntegrationTest extends ApiTestCase {
|
|||
] );
|
||||
}
|
||||
|
||||
public function testValidRequest() {
|
||||
public function testValidRevRequest() {
|
||||
list( $result,, ) = $this->doApiRequestWithToken( [
|
||||
'action' => 'thank',
|
||||
'rev' => $this->revId,
|
||||
|
@ -52,6 +64,53 @@ class ApiCoreThankIntegrationTest extends ApiTestCase {
|
|||
$this->assertSuccess( $result );
|
||||
}
|
||||
|
||||
public function testValidLogRequest() {
|
||||
list( $result,, ) = $this->doApiRequestWithToken( [
|
||||
'action' => 'thank',
|
||||
'log' => $this->logId,
|
||||
] );
|
||||
$this->assertSuccess( $result );
|
||||
}
|
||||
|
||||
public function testLogRequestWithDisallowedLogType() {
|
||||
// Empty the log-type whitelist.
|
||||
$this->setMwGlobals( [ 'wgThanksLogTypeWhitelist' => [] ] );
|
||||
$this->setExpectedException(
|
||||
ApiUsageException::class,
|
||||
"Log type 'delete' is not in the whitelist of permitted log types."
|
||||
);
|
||||
$this->doApiRequestWithToken( [
|
||||
'action' => 'thank',
|
||||
'log' => $this->logId,
|
||||
] );
|
||||
}
|
||||
|
||||
public function testLogThanksForADeletedLogEntry() {
|
||||
global $wgUser;
|
||||
|
||||
// Mark our test log entry as deleted.
|
||||
// To do this we briefly switch back to our 'uploader' test user.
|
||||
$this->doLogin( 'uploader' );
|
||||
$wgUser->mRights[] = 'deletelogentry';
|
||||
$this->doApiRequestWithToken( [
|
||||
'action' => 'revisiondelete',
|
||||
'type' => 'logging',
|
||||
'ids' => $this->logId,
|
||||
'hide' => 'content',
|
||||
] );
|
||||
$this->doLogin( 'sysop' );
|
||||
|
||||
// Then try to thank for it, and we should get an exception.
|
||||
$this->setExpectedException(
|
||||
ApiUsageException::class,
|
||||
"The requested log entry has been deleted and thanks cannot be given for it."
|
||||
);
|
||||
$this->doApiRequestWithToken( [
|
||||
'action' => 'thank',
|
||||
'log' => $this->logId,
|
||||
] );
|
||||
}
|
||||
|
||||
public function testValidRequestWithSource() {
|
||||
list( $result,, ) = $this->doApiRequestWithToken( [
|
||||
'action' => 'thank',
|
||||
|
|
Loading…
Reference in a new issue