From 06360b6d0d1f4c361c45ad225309fb7ff3c66985 Mon Sep 17 00:00:00 2001 From: Kunal Mehta Date: Wed, 23 Oct 2013 18:13:43 -0700 Subject: [PATCH] Add Special:Thanks as a non-JS fallback If the user has JavaScript disabled, clicking on "thank" will send the user to Special:Thanks with the revision id already filled in. When submitted, the form calls the API internally and then shows the user an error or confirmation message. Special:Thanks is not a listed special page since it's mainly intended as a fallback. The API was modified to return the user name of the editor who is being thanked if a new notification was created. Bug: 49161 Change-Id: I7ba4664b92bb0da425784350487ed0e7ca352b4e --- ApiThank.php | 11 ++-- SpecialThanks.php | 111 +++++++++++++++++++++++++++++++++++++++++ Thanks.hooks.php | 2 +- Thanks.i18n.php | 6 +++ Thanks.php | 4 ++ tests/ApiThankTest.php | 7 ++- 6 files changed, 135 insertions(+), 6 deletions(-) create mode 100644 SpecialThanks.php diff --git a/ApiThank.php b/ApiThank.php index 5568ef6e..62cd6f5d 100644 --- a/ApiThank.php +++ b/ApiThank.php @@ -16,7 +16,7 @@ class ApiThank extends ApiBase { $revision = $this->getRevisionFromParams( $params ); if ( $this->userAlreadySentThanksForRevision( $user, $revision ) ) { - $this->markResultSuccess(); + $this->markResultSuccess( $revision ); } else { $recipient = $this->getUserFromRevision( $revision ); $this->dieOnBadRecipient( $user, $recipient ); @@ -86,8 +86,11 @@ class ApiThank extends ApiBase { return User::newFromId( $recipient ); } - private function markResultSuccess(){ - $this->getResult()->addValue( null, 'result', array( 'success' => 1 ) ); + private function markResultSuccess( Revision $revision ) { + $this->getResult()->addValue( null, 'result', array( + 'success' => 1, + 'recipient' => $revision->getUserText( Revision::FOR_PUBLIC ) + ) ); } private function dieOnBadRecipient( User $agent, User $recipient ) { @@ -119,7 +122,7 @@ class ApiThank extends ApiBase { // Mark the thank in session to prevent duplicates (Bug 46690) $user->getRequest()->setSessionData( "thanks-thanked-{$revision->getId()}", true ); // Set success message - $this->markResultSuccess(); + $this->markResultSuccess( $revision ); // Log it if we're supposed to log it if ( $wgThanksLogging ) { $logEntry = new ManualLogEntry( 'thanks', 'thank' ); diff --git a/SpecialThanks.php b/SpecialThanks.php new file mode 100644 index 00000000..f917d702 --- /dev/null +++ b/SpecialThanks.php @@ -0,0 +1,111 @@ + array( + 'id' => 'mw-thanks-form-revid', + 'name' => 'revid', + 'type' => 'int', + 'label-message' => 'thanks-form-revid', + 'default' => $this->getRequest()->getInt( 'revid', $this->par ) ?: '', + ) + ); + } + + /** + * Make it look pretty + * @param HTMLForm $form + */ + protected function alterForm( HTMLForm $form ) { + $form->setDisplayFormat( 'vform' ); + $form->setWrapperLegend( false ); + } + + /** + * Calls the API internally + * @param array $data + * @return Status + */ + public function onSubmit( array $data ) { + if ( !isset( $data['revid'] ) ) { + return Status::newFatal( 'thanks-error-invalidrevision' ); + } + + $request = new DerivativeRequest( + $this->getRequest(), + array( + 'action' => 'thank', + 'rev' => (int)$data['revid'], + 'source' => 'specialpage', + 'token' => $this->getUser()->getEditToken(), + ), + true // posted + ); + + $api = new ApiMain( + $request, + true // enable write mode + ); + + try { + $api->execute(); + } catch ( UsageException $e ) { + return $this->handleErrorCodes( $e->getCodeString() ); + } + + $result = $api->getResult()->getData(); + $this->result = $result['result']; + return Status::newGood(); + } + + /** + * Handles error codes returned by the API + * @param $code + * @return Status + */ + protected function handleErrorCodes( $code ) { + $status = new Status; + switch ( $code ) { + case 'invalidrevision': + case 'ratelimited': + $status->fatal( "thanks-error-$code" ); + break; + case 'notloggedin': + case 'blockedtext': + $status->fatal( $code ); + break; + default: + $status->fatal( 'thanks-error-undefined' ); + } + return $status; + } + + /** + * Display a message to the user + */ + public function onSuccess() { + $recipient = User::newFromName( $this->result['recipient'] ); + $link = Linker::userLink( $recipient->getId(), $recipient->getName() ); + $this->getOutput()->addHTML( $this->msg( 'thanks-thanked-notice' ) + ->rawParams( $link ) + ->params( $recipient->getName() )->parse() + ); + } + + public function isListed() { + return false; + } +} diff --git a/Thanks.hooks.php b/Thanks.hooks.php index eb0796d4..9f56f79b 100644 --- a/Thanks.hooks.php +++ b/Thanks.hooks.php @@ -66,7 +66,7 @@ class ThanksHooks { 'a', array( 'class' => 'mw-thanks-thank-link', - 'href' => '#', + 'href' => SpecialPage::getTitleFor( 'Thanks', $rev->getId() )->getFullURL(), 'title' => $tooltip, 'data-revision-id' => $rev->getId(), ), diff --git a/Thanks.i18n.php b/Thanks.i18n.php index cd21a2e3..1bf07c4e 100644 --- a/Thanks.i18n.php +++ b/Thanks.i18n.php @@ -23,6 +23,9 @@ $messages['en'] = array( 'thanks-thank-tooltip' => '{{GENDER:$1|Send}} a thank you notification to this {{GENDER:$2|user}}', 'thanks-confirmation' => 'Do you want to {{GENDER:$1|thank}} $2 for this edit?', 'thanks-thanked-notice' => '$1 was notified that you liked {{GENDER:$2|his|her|their}} edit.', + 'thanks' => 'Send thanks', + 'thanks-form-revid' => 'Revision ID for edit', + 'thanks-already-thanked' => '{{GENDER:$1|You}} have already sent thanks for this edit.', 'echo-pref-subscription-edit-thank' => 'Thanks me for my edit', 'echo-pref-tooltip-edit-thank' => 'Notify me when someone thanks me for an edit I made.', 'echo-category-title-edit-thank' => 'Thanks', @@ -86,6 +89,9 @@ Pop-up message that is displayed after a user has thanked another user for their Parameters: * $1 - the username of the user that was thanked * $2 - the gender of the user that was thanked', + 'thanks' => '{{doc-special|Thanks}}', + 'thanks-form-revid' => 'Label for form field where the user inputs the revision id', + 'thanks-already-thanked' => 'Message shown to user if they have already sent thanks for this edit. $1 is the user\'s username.', 'echo-pref-subscription-edit-thank' => 'Option for getting notifications when someone thanks the user for their edit. This is the conclusion of the sentence begun by the header: {{msg-mw|Prefs-echosubscriptions}}.', diff --git a/Thanks.php b/Thanks.php index e4c2d00d..5441204a 100644 --- a/Thanks.php +++ b/Thanks.php @@ -45,11 +45,15 @@ $wgAutoloadClasses['ThanksHooks'] = $dir . '/Thanks.hooks.php'; $wgAutoloadClasses['EchoThanksFormatter'] = $dir . '/ThanksFormatter.php'; $wgAutoloadClasses['ApiThank'] = $dir . '/ApiThank.php'; $wgAutoloadClasses['ThanksLogFormatter'] = $dir . '/ThanksLogFormatter.php'; +$wgAutoloadClasses['SpecialThanks'] = $dir . '/SpecialThanks.php'; $wgExtensionMessagesFiles['Thanks'] = $dir . '/Thanks.i18n.php'; // Register APIs $wgAPIModules['thank'] = 'ApiThank'; +// Register special page +$wgSpecialPages['Thanks'] = 'SpecialThanks'; + // Register hooks $wgHooks['HistoryRevisionTools'][] = 'ThanksHooks::insertThankLink'; $wgHooks['DiffRevisionTools'][] = 'ThanksHooks::insertThankLink'; diff --git a/tests/ApiThankTest.php b/tests/ApiThankTest.php index 5b4f3bca..102006dc 100644 --- a/tests/ApiThankTest.php +++ b/tests/ApiThankTest.php @@ -59,7 +59,12 @@ class ApiThankTest extends \ApiTestCase { } protected function assertSuccess( $result ){ - $this->assertEquals( array( 'result' => array( 'success' => 1 ) ), $result ); + $this->assertEquals( array( + 'result' => array( + 'success' => 1, + 'recipient' => self::$users['uploader']->username, + ), + ), $result ); } public function testInvalidRequest(){