diff --git a/ApiVoteNY.php b/ApiVoteNY.php
new file mode 100644
index 0000000..90d5e00
--- /dev/null
+++ b/ApiVoteNY.php
@@ -0,0 +1,143 @@
+getUser();
+
+ // Get the request parameters
+ $params = $this->extractRequestParams();
+
+ $action = $params['what'];
+
+ // If the "what" param isn't present, we don't know what to do!
+ if ( !$action || $action === null ) {
+ $this->dieUsageMsg( 'missingparam' );
+ }
+
+ // Need to have sufficient user rights to proceed...
+ if ( !$user->isAllowed( 'voteny' ) ) {
+ $this->dieUsageMsg( 'badaccess-group0' );
+ }
+
+ // Ensure that the page ID is present and that it really is numeric
+ $pageId = $params['pageId'];
+
+ if ( !$pageId || $pageId === null || !is_numeric( $pageId ) ) {
+ $this->dieUsageMsg( array( 'missingparam', 'pageId' ) );
+ }
+
+ // Vote value is needed for actual vote actions, i.e. everything but "delete"
+ $voteValue = $params['voteValue'];
+
+ if ( !( $voteValue || $voteValue === null ) && $action !== 'delete' ) {
+ $this->dieUsageMsg( array( 'missingparam', 'voteValue' ) );
+ }
+
+ // Set the private class member variable and do something...
+ if ( isset( $params['type'] ) && $params['type'] && $params['type'] == 'stars' ) {
+ $this->vote = new VoteStars( $pageId );
+
+ switch ( $action ) {
+ case 'delete':
+ $this->vote->delete();
+ $output = $this->vote->display();
+ break;
+ case 'multi':
+ if ( $this->vote->UserAlreadyVoted() ) {
+ $this->vote->delete();
+ }
+ $this->vote->insert( $voteValue );
+ $output = $this->vote->displayScore();
+ break;
+ case 'vote':
+ default:
+ if ( $this->vote->UserAlreadyVoted() ) {
+ $this->vote->delete();
+ }
+ $this->vote->insert( $voteValue );
+ $output = $this->vote->display( $voteValue );
+ break;
+ }
+ } else {
+ $this->vote = new Vote( $pageId );
+
+ switch ( $action ) {
+ case 'delete':
+ $this->vote->delete();
+ $output = $this->vote->count( 1 );
+ break;
+ case 'vote':
+ default:
+ $this->vote->insert( $voteValue );
+ $output = $this->vote->count( 1 );
+ break;
+ }
+ }
+
+ // Top level
+ $this->getResult()->addValue( null, $this->getModuleName(),
+ array( 'result' => $output )
+ );
+
+ return true;
+ }
+
+ public function needsToken() {
+ return 'csrf';
+ }
+
+ public function isWriteMode() {
+ return true;
+ }
+
+ /**
+ * @return array
+ */
+ public function getAllowedParams() {
+ return array(
+ 'what' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'pageId' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ApiBase::PARAM_REQUIRED => true
+ ),
+ 'voteValue' => array(
+ ApiBase::PARAM_TYPE => 'integer',
+ ),
+ 'type' => array(
+ ApiBase::PARAM_TYPE => 'string',
+ )
+ );
+ }
+
+ /**
+ * @see ApiBase::getExamplesMessages()
+ */
+ protected function getExamplesMessages() {
+ return array(
+ 'action=voteny&what=vote&pageId=666' => 'apihelp-voteny-example-1',
+ 'action=voteny&what=delete&pageId=666' => 'apihelp-voteny-example-2',
+ 'action=voteny&what=vote&type=stars&pageId=666&voteValue=3' => 'apihelp-voteny-example-3',
+ 'action=voteny&what=delete&type=stars&pageId=666' => 'apihelp-voteny-example-4',
+ 'action=voteny&what=multi&type=stars&pageId=666&voteValue=4' => 'apihelp-voteny-example-5'
+ );
+ }
+}
diff --git a/Vote.js b/Vote.js
index 09444da..859bf76 100644
--- a/Vote.js
+++ b/Vote.js
@@ -25,14 +25,14 @@ var VoteNY = function VoteNY() {
* @param PageID Integer: internal ID number of the current article
*/
this.clickVote = function( TheVote, PageID ) {
- $.post(
- mw.util.wikiScript(), {
- action: 'ajax',
- rs: 'wfVoteClick',
- rsargs: [ TheVote, PageID ]
- }
- ).done( function( data ) {
- $( '#PollVotes' ).html( ( data || '0' ) );
+ ( new mw.Api() ).postWithToken( 'csrf', {
+ action: 'voteny',
+ format: 'json',
+ what: 'vote',
+ pageId: PageID,
+ voteValue: TheVote
+ } ).done( function( data ) {
+ $( '#PollVotes' ).html( data.voteny.result );
$( '#Answer' ).html(
'' +
mediaWiki.msg( 'voteny-unvote-link' ) + ''
@@ -44,17 +44,15 @@ var VoteNY = function VoteNY() {
* Called when removing your vote through the green square voting box
*
* @param PageID Integer: internal ID number of the current article
- * @param mk Mixed: random token
*/
this.unVote = function( PageID ) {
- $.post(
- mw.util.wikiScript(), {
- action: 'ajax',
- rs: 'wfVoteDelete',
- rsargs: [ PageID ]
- }
- ).done( function( data ) {
- $( '#PollVotes' ).html( ( data || '0' ) );
+ ( new mw.Api() ).postWithToken( 'csrf', {
+ action: 'voteny',
+ format: 'json',
+ what: 'delete',
+ pageId: PageID
+ } ).done( function( data ) {
+ $( '#PollVotes' ).html( data.voteny.result );
$( '#Answer' ).html(
'' +
mediaWiki.msg( 'voteny-link' ) + ''
@@ -71,22 +69,22 @@ var VoteNY = function VoteNY() {
*/
this.clickVoteStars = function( TheVote, PageID, id, action ) {
this.voted_new[id] = TheVote;
- var rsfun;
+ var actionName;
if ( action == 3 ) {
- rsfun = 'wfVoteStars';
+ actionName = 'stars'; // all other values but 'multi' are ignored anyway
}
if ( action == 5 ) {
- rsfun = 'wfVoteStarsMulti';
+ actionName = 'multi';
}
- $.post(
- mw.util.wikiScript(), {
- action: 'ajax',
- rs: rsfun,
- rsargs: [ TheVote, PageID ]
- }
- ).done( function( data ) {
- $( '#rating_' + id ).html( data );
+ ( new mw.Api() ).postWithToken( 'csrf', {
+ action: 'voteny',
+ type: 'stars',
+ what: actionName,
+ voteValue: TheVote,
+ pageId: PageID
+ } ).done( function( data ) {
+ $( '#rating_' + id ).html( data.voteny.result );
} );
};
@@ -97,14 +95,13 @@ var VoteNY = function VoteNY() {
* @param id Integer: ID of the current rating star
*/
this.unVoteStars = function( PageID, id ) {
- $.post(
- mw.util.wikiScript(), {
- action: 'ajax',
- rs: 'wfVoteStarsDelete',
- rsargs: [ PageID ]
- }
- ).done( function( data ) {
- $( '#rating_' + id ).html( data );
+ ( new mw.Api() ).postWithToken( 'csrf', {
+ action: 'voteny',
+ what: 'delete',
+ type: 'stars',
+ pageId: PageID
+ } ).done( function( data ) {
+ $( '#rating_' + id ).html( data.voteny.result );
} );
};
diff --git a/Vote.php b/Vote.php
deleted file mode 100644
index 8aa3279..0000000
--- a/Vote.php
+++ /dev/null
@@ -1,4 +0,0 @@
-display();
}
- wfProfileOut( __METHOD__ );
-
return $output;
}
@@ -174,7 +170,7 @@ class VoteHooks {
* @param string $pagename Page name
* @return int Amount of votes for the given page
*/
- static function getNumberOfVotesPageParser( $parser, $pagename ) {
+ public static function getNumberOfVotesPageParser( $parser, $pagename ) {
$title = Title::newFromText( $pagename );
if ( !$title instanceof Title ) {
@@ -202,7 +198,7 @@ class VoteHooks {
* @param Parser $parser
* @return bool
*/
- static function setupNumberOfVotesPageParser( &$parser ) {
+ public static function setupNumberOfVotesPageParser( &$parser ) {
$parser->setFunctionHook( 'NUMBEROFVOTESPAGE', 'VoteHooks::getNumberOfVotesPageParser', Parser::SFH_NO_HASH );
return true;
}
diff --git a/VoteNY.php b/VoteNY.php
deleted file mode 100644
index f5c0f45..0000000
--- a/VoteNY.php
+++ /dev/null
@@ -1,70 +0,0 @@
- tag
- *
- * @file
- * @ingroup Extensions
- * @author Aaron Wright
- * @author David Pean
- * @author Jack Phoenix
- * @link https://www.mediawiki.org/wiki/Extension:VoteNY Documentation
- * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License 2.0 or later
- */
-
-// Extension credits that show up on Special:Version
-$wgExtensionCredits['parserhook'][] = array(
- 'name' => 'Vote',
- 'version' => '2.7',
- 'author' => array( 'Aaron Wright', 'David Pean', 'Jack Phoenix' ),
- 'descriptionmsg' => 'voteny-desc',
- 'url' => 'https://www.mediawiki.org/wiki/Extension:VoteNY'
-);
-
-// Path to Vote extension files
-$wgVoteDirectory = "$IP/extensions/VoteNY";
-
-// New user right
-$wgAvailableRights[] = 'voteny';
-$wgGroupPermissions['*']['voteny'] = false; // Anonymous users cannot vote
-$wgGroupPermissions['user']['voteny'] = true; // Registered users can vote
-
-// AJAX functions needed by this extension
-require_once 'Vote_AjaxFunctions.php';
-
-// Autoload classes and set up i18n
-$wgMessagesDirs['VoteNY'] = __DIR__ . '/i18n';
-$wgExtensionMessagesFiles['VoteNYAlias'] = __DIR__ . '/VoteNY.alias.php';
-$wgExtensionMessagesFiles['VoteNYMagic'] = __DIR__ . '/VoteNY.i18n.magic.php';
-
-$wgAutoloadClasses['Vote'] = __DIR__ . '/VoteClass.php';
-$wgAutoloadClasses['VoteStars'] = __DIR__ . '/VoteClass.php';
-
-// Set up the new special page, Special:TopRatings, which shows top rated pages
-// based on given criteria
-$wgAutoloadClasses['SpecialTopRatings'] = __DIR__ . '/SpecialTopRatings.php';
-$wgSpecialPages['TopRatings'] = 'SpecialTopRatings';
-
-// Hooked functions
-$wgAutoloadClasses['VoteHooks'] = __DIR__ . '/VoteHooks.php';
-
-$wgHooks['ParserFirstCallInit'][] = 'VoteHooks::registerParserHook';
-$wgHooks['RenameUserSQL'][] = 'VoteHooks::onUserRename';
-$wgHooks['ParserGetVariableValueSwitch'][] = 'VoteHooks::assignValueToMagicWord';
-$wgHooks['MagicWordwgVariableIDs'][] = 'VoteHooks::registerVariableId';
-$wgHooks['ParserFirstCallInit'][] = 'VoteHooks::setupNumberOfVotesPageParser';
-$wgHooks['LoadExtensionSchemaUpdates'][] = 'VoteHooks::addTable';
-
-// ResourceLoader support for MediaWiki 1.17+
-$wgResourceModules['ext.voteNY.styles'] = array(
- 'styles' => 'Vote.css',
- 'localBasePath' => __DIR__,
- 'remoteExtPath' => 'VoteNY',
- 'position' => 'top' // available since r85616
-);
-
-$wgResourceModules['ext.voteNY.scripts'] = array(
- 'scripts' => 'Vote.js',
- 'messages' => array( 'voteny-link', 'voteny-unvote-link' ),
- 'localBasePath' => __DIR__,
- 'remoteExtPath' => 'VoteNY'
-);
diff --git a/Vote_AjaxFunctions.php b/Vote_AjaxFunctions.php
deleted file mode 100644
index f838b18..0000000
--- a/Vote_AjaxFunctions.php
+++ /dev/null
@@ -1,88 +0,0 @@
-isAllowed( 'voteny' ) ) {
- return '';
- }
-
- if ( is_numeric( $pageId ) && ( is_numeric( $voteValue ) ) ) {
- $vote = new Vote( $pageId );
- $vote->insert( $voteValue );
-
- return $vote->count( 1 );
- } else {
- return 'error';
- }
-}
-
-$wgAjaxExportList[] = 'wfVoteDelete';
-function wfVoteDelete( $pageId ) {
- global $wgUser;
-
- if ( !$wgUser->isAllowed( 'voteny' ) ) {
- return '';
- }
-
- if ( is_numeric( $pageId ) ) {
- $vote = new Vote( $pageId );
- $vote->delete();
-
- return $vote->count( 1 );
- } else {
- return 'error';
- }
-}
-
-$wgAjaxExportList[] = 'wfVoteStars';
-function wfVoteStars( $voteValue, $pageId ) {
- global $wgUser;
-
- if ( !$wgUser->isAllowed( 'voteny' ) ) {
- return '';
- }
-
- $vote = new VoteStars( $pageId );
- if ( $vote->UserAlreadyVoted() ) {
- $vote->delete();
- }
- $vote->insert( $voteValue );
-
- return $vote->display( $voteValue );
-}
-
-$wgAjaxExportList[] = 'wfVoteStarsMulti';
-function wfVoteStarsMulti( $voteValue, $pageId ) {
- global $wgUser;
-
- if ( !$wgUser->isAllowed( 'voteny' ) ) {
- return '';
- }
-
- $vote = new VoteStars( $pageId );
- if ( $vote->UserAlreadyVoted() ) {
- $vote->delete();
- }
- $vote->insert( $voteValue );
-
- return $vote->displayScore();
-}
-
-$wgAjaxExportList[] = 'wfVoteStarsDelete';
-function wfVoteStarsDelete( $pageId ) {
- global $wgUser;
-
- if ( !$wgUser->isAllowed( 'voteny' ) ) {
- return '';
- }
-
- $vote = new VoteStars( $pageId );
- $vote->delete();
-
- return $vote->display();
-}
diff --git a/extension.json b/extension.json
new file mode 100644
index 0000000..82ed752
--- /dev/null
+++ b/extension.json
@@ -0,0 +1,84 @@
+{
+ "name": "VoteNY",
+ "version": "2.8",
+ "author": [
+ "Aaron Wright",
+ "David Pean",
+ "Jack Phoenix"
+ ],
+ "license-name": "GPL-2.0+",
+ "url": "https://www.mediawiki.org/wiki/Extension:VoteNY",
+ "descriptionmsg": "voteny-desc",
+ "type": "parserhook",
+ "SpecialPages": {
+ "TopRatings": "SpecialTopRatings"
+ },
+ "MessagesDirs": {
+ "VoteNY": [
+ "i18n"
+ ]
+ },
+ "APIModules": {
+ "voteny": "ApiVoteNY"
+ },
+ "ExtensionMessagesFiles": {
+ "VoteNYAlias": "VoteNY.alias.php",
+ "VoteNYMagic": "VoteNY.i18n.magic.php"
+ },
+ "AutoloadClasses": {
+ "ApiVoteNY": "ApiVoteNY.php",
+ "Vote": "VoteClass.php",
+ "VoteStars": "VoteClass.php",
+ "SpecialTopRatings": "SpecialTopRatings.php",
+ "VoteHooks": "VoteHooks.php"
+ },
+ "Hooks": {
+ "ParserFirstCallInit": [
+ "VoteHooks::registerParserHook",
+ "VoteHooks::setupNumberOfVotesPageParser"
+ ],
+ "RenameUserSQL": [
+ "VoteHooks::onUserRename"
+ ],
+ "ParserGetVariableValueSwitch": [
+ "VoteHooks::assignValueToMagicWord"
+ ],
+ "MagicWordwgVariableIDs": [
+ "VoteHooks::registerVariableId"
+ ],
+ "LoadExtensionSchemaUpdates": [
+ "VoteHooks::addTable"
+ ]
+ },
+ "ResourceFileModulePaths": {
+ "localBasePath": "",
+ "remoteExtPath": "VoteNY"
+ },
+ "ResourceModules": {
+ "ext.voteNY.scripts": {
+ "scripts": "Vote.js",
+ "messages": [
+ "voteny-link",
+ "voteny-unvote-link"
+ ],
+ "dependencies": [ "mediawiki.api" ],
+ "position": "bottom"
+ },
+ "ext.voteNY.styles": {
+ "styles": "Vote.css",
+ "position": "top"
+ }
+ },
+ "AvailableRights": [
+ "voteny"
+ ],
+ "GroupPermissions": {
+ "*": {
+ "voteny": false
+ },
+ "user": {
+ "voteny": true
+ }
+ },
+ "manifest_version": 1
+}
diff --git a/i18n/en.json b/i18n/en.json
index a2d4ce0..7f9110f 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -5,6 +5,16 @@
"David Pean "
]
},
+ "apihelp-voteny-description": "VoteNY API module",
+ "apihelp-voteny-param-what": "Action to take; valid values are 'vote' (green voting box), 'multi' (voting stars) or 'delete' (delete a previously given vote)",
+ "apihelp-voteny-param-pageId": "Page ID of the page where the voting box/stars is/are",
+ "apihelp-voteny-param-voteValue": "Numerical vote value between 1 and 5",
+ "apihelp-voteny-param-type": "Set this to 'stars' to call the voting stars (VoteStars PHP class), otherwise the green vote box (Vote PHP class) is used",
+ "apihelp-voteny-example-1": "Cast a vote for the page which has the ID number 666",
+ "apihelp-voteny-example-2": "Delete your vote from the page which has the ID number 666",
+ "apihelp-voteny-example-3": "Cast a vote (3 stars out of 5) for the page which has the ID number 666",
+ "apihelp-voteny-example-4": "Delete your vote from the page which has the ID number 666 which is using the star rating",
+ "apihelp-voteny-example-5": "Cast a vote (4 stars out of 5) for the page which has the ID number 666, deleting your previous vote, if any",
"voteny-desc": "JavaScript-based voting with the <vote> tag",
"voteny-link": "Vote",
"voteny-unvote-link": "unvote",