http://www.mediawiki.org/wiki/Special:Code/MediaWiki/95185
Revision: 95185
Author: akshay
Date: 2011-08-22 00:34:04 +0000 (Mon, 22 Aug 2011)
Log Message:
-----------
Added resources for AJAX-ifying the signup form
Made AJAX & source tracking user configurable
Added extension specific messages to i18n file
Modified Paths:
--------------
trunk/extensions/SignupAPI/SignupAPI.i18n.php
trunk/extensions/SignupAPI/SignupAPI.php
trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
Added Paths:
-----------
trunk/extensions/SignupAPI/includes/images/
trunk/extensions/SignupAPI/includes/images/MW-Icon-AlertMark.png
trunk/extensions/SignupAPI/includes/images/MW-Icon-CheckMark.png
trunk/extensions/SignupAPI/includes/images/MW-Icon-NoMark.png
trunk/extensions/SignupAPI/includes/images/MW-Icon-Warning.png
trunk/extensions/SignupAPI/includes/validateSignup.php
trunk/extensions/SignupAPI/includes/verification.js
Modified: trunk/extensions/SignupAPI/SignupAPI.i18n.php
===================================================================
--- trunk/extensions/SignupAPI/SignupAPI.i18n.php 2011-08-22 00:11:49 UTC
(rev 95184)
+++ trunk/extensions/SignupAPI/SignupAPI.i18n.php 2011-08-22 00:34:04 UTC
(rev 95185)
@@ -10,6 +10,11 @@
$messages['en'] = array(
'signupapi-desc' => 'Cleans up the [[Special:UserLogin|login page]]
from signup related stuff and adds an API for signup',
+ 'signupapi-enterpassword' => 'You must enter a password',
+ 'signupapi-weak' => 'Weak',
+ 'signupapi-medium' => 'Medium',
+ 'signupapi-strong' => 'Strong',
+ 'signupapi-passwordsmatch' => 'Passwords Match',
);
/** Belarusian (Taraškievica orthography) (Беларуская (тарашкевіца))
Modified: trunk/extensions/SignupAPI/SignupAPI.php
===================================================================
--- trunk/extensions/SignupAPI/SignupAPI.php 2011-08-22 00:11:49 UTC (rev
95184)
+++ trunk/extensions/SignupAPI/SignupAPI.php 2011-08-22 00:34:04 UTC (rev
95185)
@@ -1,7 +1,8 @@
<?php
/**
* Setup for SignupAPI extension, a special page that cleans up
SpecialUserLogin
- * from signup related stuff & adds an API for signup
+ * from signup related stuff, adds an API for signup, adds sourcetracking for
+ *account creation & AJAX-ifies the signup form
*
* @file
* @ingroup Extensions
@@ -24,6 +25,9 @@
'descriptionmsg' => 'signupapi-desc',
);
+$wgSignupAPIUseAjax = true;
+$wgSignupAPISourceTracking = true;
+
$dir = dirname(__FILE__);
$wgExtensionMessagesFiles['SignupAPI'] = $dir . '/SignupAPI.i18n.php';
$wgMyExtensionIncludes = $dir . '/includes';
@@ -36,95 +40,117 @@
= $wgMyExtensionIncludes . '/APISignup.php';
$wgSpecialPages['UserSignup'] = 'SignupForm';
-$wgAPIModules['signup'] = 'ApiSignup';
+if ( $wgSignupAPIUseAjax ) {
+ $wgAutoloadClasses['validateSignup']
+ = $wgMyExtensionIncludes . '/validateSignup.php';
-# Schema updates for update.php
-$wgHooks['LoadExtensionSchemaUpdates'][] = 'fnMyHook';
-function fnMyHook() {
- global $wgExtNewTables;
- $wgExtNewTables[] = array(
- 'sourcetracking',
- dirname( __FILE__ ) . '/sourcetracking.sql' );
- return true;
-}
+ $wgAPIModules['signup'] = 'ApiSignup';
+ $wgAPIModules['validatesignup'] = 'validateSignup';
-# Add source tracking to personal URL's
-$wgHooks['PersonalUrls'][] = 'addSourceTracking';
+ # Requires jquery.ui.progressbar for password strength validation
+ $wgResourceModules['ext.SignupAPI'] = array(
-function addSourceTracking( &$personal_urls, &$title )
-{
- global $wgRequest,$wgUser;
-
- #generate source tracking parameters
- $sourceAction = $wgRequest->getVal( 'action' );
- $sourceNS = $title->getNamespace();
- $sourceArticle = $title->getArticleID();
- $loggedin = $wgUser->isLoggedIn();
- $thispage = $title->getPrefixedDBkey();
- $thisurl = $title->getPrefixedURL();
- $query = array();
- if ( !$wgRequest->wasPosted() ) {
- $query = $wgRequest->getValues();
- unset( $query['title'] );
- unset( $query['returnto'] );
- unset( $query['returntoquery'] );
- }
- $thisquery = wfUrlencode( wfArrayToCGI( $query ) );
+ 'scripts' => array( 'includes/verification.js' ),
+ 'messages' => array( 'ok', 'signupapi-enterpassword',
'passwordtooshort', 'signupapi-weak', 'signupapi-medium', 'signupapi-strong',
'badretype', 'signupapi-passwordsmatch' ),
+ 'dependencies' => array( 'jquery.ui.progressbar' ),
+ 'localBasePath' => dirname( __FILE__ ),
+ 'remoteExtPath' => 'SignupAPI'
+ );
- // Get the returnto and returntoquery parameters from the query string
- // or fall back on $this->thisurl or $this->thisquery
- // We can't use getVal()'s default value feature here because
- // stuff from $wgRequest needs to be escaped, but thisurl and thisquery
- // are already escaped.
- $page = $wgRequest->getVal( 'returnto' );
- if ( !is_null( $page ) ) {
- $page = wfUrlencode( $page );
- } else {
- $page = $thisurl;
- }
- $query = $wgRequest->getVal( 'returntoquery' );
- if ( !is_null( $query ) ) {
- $query = wfUrlencode( $query );
- } else {
- $query = $thisquery;
- }
- $returnto = "returnto=$page";
- if ( $query != '' ) {
- $returnto .= "&returntoquery=$query";
- }
+}
- if (isset ( $personal_urls['login'] ) ) {
- $login_url = $personal_urls['login'];
- $login_url['href'] =
$login_url['href']."&source_action=$sourceAction&source_ns=$sourceNS&source_article=$sourceArticle";
- $personal_urls['login'] = $login_url;
+if ( $wgSignupAPISourceTracking ) {
+ # Schema updates for update.php
+ $wgHooks['LoadExtensionSchemaUpdates'][] = 'onSourceTracking';
+ function onSourceTracking() {
+ global $wgExtNewTables;
+ $wgExtNewTables[] = array(
+ 'sourcetracking',
+ dirname( __FILE__ ) . '/sourcetracking.sql' );
+ return true;
}
- if ( isset ( $personal_urls['anonlogin'] ) ) {
- $login_url = $personal_urls['anonlogin'];
- $login_url['href'] =
$login_url['href']."&source_action=$sourceAction&source_ns=$sourceNS&source_article=$sourceArticle";
- $personal_urls['anonlogin'] = $login_url;
- }
+ # Add source tracking to personal URL's
+ $wgHooks['PersonalUrls'][] = 'addSourceTracking';
- if ( isset ( $personal_urls['createaccount'] ) ) {
- global $wgServer, $wgSecureLogin;
+ function addSourceTracking( &$personal_urls, &$title )
+ {
+ global $wgRequest,$wgUser;
+
+ #generate source tracking parameters
+ $sourceAction = $wgRequest->getVal( 'action' );
+ $sourceNS = $title->getNamespace();
+ $sourceArticle = $title->getArticleID();
+ $loggedin = $wgUser->isLoggedIn();
+ $thispage = $title->getPrefixedDBkey();
+ $thisurl = $title->getPrefixedURL();
+ $query = array();
+ if ( !$wgRequest->wasPosted() ) {
+ $query = $wgRequest->getValues();
+ unset( $query['title'] );
+ unset( $query['returnto'] );
+ unset( $query['returntoquery'] );
+ }
+ $thisquery = wfUrlencode( wfArrayToCGI( $query ) );
+
+ // Get the returnto and returntoquery parameters from the query string
+ // or fall back on $this->thisurl or $this->thisquery
+ // We can't use getVal()'s default value feature here because
+ // stuff from $wgRequest needs to be escaped, but thisurl and thisquery
+ // are already escaped.
$page = $wgRequest->getVal( 'returnto' );
- $is_signup = $wgRequest->getText( 'type' ) == "signup";
- $createaccount_url = array(
- 'text' => wfMsg( 'createaccount' ),
- 'href' => SkinTemplate::makeSpecialUrl( 'Usersignup',
"$returnto&type=signup&wpSourceAction=$sourceAction&wpSourceNS=$sourceNS&wpSourceArticle=$sourceArticle"
),
- 'active' => $title->isSpecial( 'Userlogin' ) && $is_signup
- );
+ if ( !is_null( $page ) ) {
+ $page = wfUrlencode( $page );
+ } else {
+ $page = $thisurl;
+ }
+ $query = $wgRequest->getVal( 'returntoquery' );
+ if ( !is_null( $query ) ) {
+ $query = wfUrlencode( $query );
+ } else {
+ $query = $thisquery;
+ }
+ $returnto = "returnto=$page";
+ if ( $query != '' ) {
+ $returnto .= "&returntoquery=$query";
+ }
- if ( substr( $wgServer, 0, 5 ) === 'http:' && $wgSecureLogin ) {
- $title = SpecialPage::getTitleFor( 'Usersignup' );
- $https_url = preg_replace( '/^http:/', 'https:',
$title->getFullURL( "type=signup" ) );
- $createaccount_url['href'] = $https_url;
- $createaccount_url['class'] = 'link-https';
- }
- $personal_urls['createaccount'] = $createaccount_url;
+ if (isset ( $personal_urls['login'] ) ) {
+ $login_url = $personal_urls['login'];
+ $login_url['href'] =
$login_url['href']."&source_action=$sourceAction&source_ns=$sourceNS&source_article=$sourceArticle";
+ $personal_urls['login'] = $login_url;
+ }
+
+ if ( isset ( $personal_urls['anonlogin'] ) ) {
+ $login_url = $personal_urls['anonlogin'];
+ $login_url['href'] =
$login_url['href']."&source_action=$sourceAction&source_ns=$sourceNS&source_article=$sourceArticle";
+ $personal_urls['anonlogin'] = $login_url;
+ }
+
+ if ( isset ( $personal_urls['createaccount'] ) ) {
+ global $wgServer, $wgSecureLogin;
+ $page = $wgRequest->getVal( 'returnto' );
+ $is_signup = $wgRequest->getText( 'type' ) == "signup";
+ $createaccount_url = array(
+ 'text' => wfMsg( 'createaccount' ),
+ 'href' => SkinTemplate::makeSpecialUrl( 'Usersignup',
"$returnto&type=signup&wpSourceAction=$sourceAction&wpSourceNS=$sourceNS&wpSourceArticle=$sourceArticle"
),
+ 'active' => $title->isSpecial( 'Userlogin' ) && $is_signup
+ );
+
+ if ( substr( $wgServer, 0, 5 ) === 'http:' && $wgSecureLogin ) {
+ $title = SpecialPage::getTitleFor( 'Usersignup' );
+ $https_url = preg_replace( '/^http:/', 'https:',
$title->getFullURL( "type=signup" ) );
+ $createaccount_url['href'] = $https_url;
+ $createaccount_url['class'] = 'link-https';
+ }
+ $personal_urls['createaccount'] = $createaccount_url;
+ }
+
+ return true;
}
- return true;
}
+
+
Modified: trunk/extensions/SignupAPI/includes/SpecialUserSignup.php
===================================================================
--- trunk/extensions/SignupAPI/includes/SpecialUserSignup.php 2011-08-22
00:11:49 UTC (rev 95184)
+++ trunk/extensions/SignupAPI/includes/SpecialUserSignup.php 2011-08-22
00:34:04 UTC (rev 95185)
@@ -129,6 +129,9 @@
public function execute( $par ) {
+ global $wgOut;
+ $wgOut->addModules( 'mediawiki.special.usersignup' );
+
if ( session_id() == '' ) {
wfSetupSession();
}
@@ -737,6 +740,7 @@
$wgOut->disallowUserJs(); // just in case...
$wgOut->addTemplate( $template );
+ $wgOut->addModules( 'ext.SignupAPI' );
}
/**
Added: trunk/extensions/SignupAPI/includes/images/MW-Icon-AlertMark.png
===================================================================
(Binary files differ)
Property changes on:
trunk/extensions/SignupAPI/includes/images/MW-Icon-AlertMark.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/extensions/SignupAPI/includes/images/MW-Icon-CheckMark.png
===================================================================
(Binary files differ)
Property changes on:
trunk/extensions/SignupAPI/includes/images/MW-Icon-CheckMark.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/extensions/SignupAPI/includes/images/MW-Icon-NoMark.png
===================================================================
(Binary files differ)
Property changes on:
trunk/extensions/SignupAPI/includes/images/MW-Icon-NoMark.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/extensions/SignupAPI/includes/images/MW-Icon-Warning.png
===================================================================
(Binary files differ)
Property changes on:
trunk/extensions/SignupAPI/includes/images/MW-Icon-Warning.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: trunk/extensions/SignupAPI/includes/validateSignup.php
===================================================================
--- trunk/extensions/SignupAPI/includes/validateSignup.php
(rev 0)
+++ trunk/extensions/SignupAPI/includes/validateSignup.php 2011-08-22
00:34:04 UTC (rev 95185)
@@ -0,0 +1,132 @@
+<?php
+
+if ( !defined( 'MEDIAWIKI' ) ) {
+ // Eclipse helper - will be ignored in production
+ require_once( 'ApiBase.php' );
+}
+
+/**
+ * Unit to create accounts in the current wiki
+ *
+ * @ingroup API
+ */
+class validateSignup extends ApiBase {
+
+ public function __construct( $main, $action ) {
+ parent::__construct( $main, $action );
+ }
+
+ public function execute() {
+ $params = $this->extractRequestParams();
+
+ $result = array();
+
+ switch ( $params['field'] ) {
+ case "username":
+ $mUser = User::newFromName( $params['inputVal'],
'creatable' );
+ if ( !is_object( $mUser ) ) {
+ $result['result'] = wfMsg( 'noname' );
+ $result['icon'] = 'MW-Icon-AlertMark.png';
+ }
+
+ if ( 0 != $mUser->idForName() ) {
+ $result['result'] = wfMsg( 'userexists' );
+ $result['icon'] = "MW-Icon-NoMark.png";
+ }
+
+ else {
+ $result['result'] = wfMsg( 'ok' );
+ $result['icon'] = "MW-Icon-CheckMark.png";
+ }
+ break;
+
+ case "email" :
+ if ( $valid = User::isValidEmailAddr(
$params['inputVal'] ) ) {
+ $result['result']= wfMsg( 'ok' );
+ $result['icon'] = "MW-Icon-CheckMark.png";
+ }
+ else {
+ $result['result']= wfMsg( 'invalidemailaddress' );
+ $result['icon'] = "MW-Icon-NoMark.png";
+ }
+ break;
+
+ case "passwordlength" :
+ global $wgMinimalPasswordLength;
+ $result['result'] = $wgMinimalPasswordLength;
+ break;
+
+ default :
+ ApiBase::dieDebug( __METHOD__, "Unhandled case value:
{$params['field']}" );
+ }
+
+ $this->getResult()->addValue( null, 'signup', $result );
+ }
+
+ public function mustBePosted() {
+ return false;
+ }
+
+ public function isReadMode() {
+ return false;
+ }
+
+ public function getAllowedParams() {
+ return array(
+ 'field' => null,
+ 'inputVal' => null,
+ 'password' => null,
+ 'retype' => null,
+ 'email' => null,
+ );
+ }
+
+ public function getParamDescription() {
+ return array(
+ 'name' => 'Desired Username',
+ 'password' => 'Password',
+ 'retype' => 'Re-typed Password',
+ 'email' => 'Email ID(optional)',
+ );
+ }
+
+ public function getDescription() {
+ return array(
+ 'This module validates the parameters posted by the
signup form.'
+ );
+ }
+
+ public function getPossibleErrors() {
+ return array_merge( parent::getPossibleErrors(), array(
+ array( 'code' => 'WrongPassword', 'info' => 'Incorrect
password entered. Please try again.' ),
+ array( 'code' => 'ReadOnlyPage', 'info' => 'Accounts
cannot be created with read-only permissions' ),
+ array( 'code' => 'NoCookies', 'info' => 'The user
account was not created, as we could not confirm its source.
+ Ensure you
have cookies enabled, reload this page and try again.' ),
+ array( 'code' => 'NeedToken', 'info' => 'You need to
resubmit your signup with the specified token' ),
+ array( 'code' => 'WrongToken', 'info' => 'You specified
an invalid token' ),
+ array( 'code' => 'InsufficientPermission', 'info' =>
'You do not have sufficient permissions to create account' ),
+ array( 'code' => 'CreateBlocked', 'info' => 'You have
been blocked from creating accounts' ),
+ array( 'code' => 'IPBlocked', 'info' => 'Your IP is
blocked from creating accounts' ),
+ array( 'code' => 'NoName', 'info' => 'You have not set
a valid name for the username parameter' ),
+ array( 'code' => 'UserExists', 'info' => 'Username
entered already in use. Please choose a different name.' ),
+ array( 'code' => 'WrongRetype', 'info' => 'The
passwords you entered do not match.' ),
+ array( 'code' => 'InvalidPass', 'info' => 'You
specified an invalid password' ),
+ array( 'code' => 'NoEmail', 'info' => 'No e-mail
address specified' ),
+ array( 'code' => 'InvalidEmail', 'info' => 'You
specified an invalid email address' ),
+ array( 'code' => 'BlockedByHook', 'info' => 'A hook
blocked account creation' ),
+ array( 'code' => 'ExternalDBError', 'info' => 'There
was either an authentication database error or you are not allowed to update
your external account.' ),
+ array( 'code' => 'Throttled', 'info' => 'You have tried
creating accounts too many times in a short period' ),
+ ) );
+ }
+
+ protected function getExamples() {
+ return array(
+
'api.php?action=validatesignup&field=username&name=username'
+ );
+ }
+
+ public function getVersion() {
+ return __CLASS__ . ': $Id: validateSignup.php 91472 2011-07-05
18:43:51Z akshay $';
+ }
+
+}
Property changes on: trunk/extensions/SignupAPI/includes/validateSignup.php
___________________________________________________________________
Added: svn:eol-style
+ native
Added: trunk/extensions/SignupAPI/includes/verification.js
===================================================================
--- trunk/extensions/SignupAPI/includes/verification.js
(rev 0)
+++ trunk/extensions/SignupAPI/includes/verification.js 2011-08-22 00:34:04 UTC
(rev 95185)
@@ -0,0 +1,84 @@
+//setup verification fields on the form
+
+function validateInput( fieldtype,fieldid ) {
+ var inputVal = document.getElementById(fieldid).value;
+ var valresult = document.getElementById(fieldid+'val');
+ $.ajax({
+ type: "POST",
+ url: mw.util.wikiScript('api'),
+ data:
"action=validatesignup&format=json&field="+fieldtype+"&inputVal="+inputVal,
+ dataType: 'json',
+ success: function( jsondata ){
+ var image = "<img src='"+ imagePath + jsondata.signup.icon
+"'>";
+ var message = jsondata.signup.result;
+ valresult.innerHTML = image+message;
+ }
+ });
+}
+
+function passwordStrength() {
+
+ var strength = document.getElementById('wpPassword2val');
+ var strongRegex = new
RegExp("^(?=.{8,})(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*\\W).*$", "g");
+ var mediumRegex = new
RegExp("^(?=.{7,})(((?=.*[A-Z])(?=.*[a-z]))|((?=.*[A-Z])(?=.*[0-9]))|((?=.*[a-z])(?=.*[0-9]))).*$",
"g");
+ var enoughRegex = new RegExp("(?=.{6,}).*", "g");
+ var pwd = document.getElementById("wpPassword2");
+
+ if (pwd.value.length==0) {
+ strength.innerHTML = mw.message( 'signupapi-enterpassword' );
+ } else if (pwd.value.length<minlength) {
+ strength.innerHTML = mw.message( 'passwordtooshort', minlength );
+ $("#progress").progressbar({value: 10});
+ $("div.ui-progressbar-value").css("background","red");
+ } else if (strongRegex.test(pwd.value)) {
+ strength.innerHTML = '<span style="color:green">'+mw.message(
'signupapi-strong' )+'</span>';
+ $("#progress").progressbar({value: 100});
+ $("div.ui-progressbar-value").css("background","green");
+ } else if (mediumRegex.test(pwd.value)) {
+ strength.innerHTML = '<span style="color:orange">'+mw.message(
'signupapi-medium' )+'</span>';
+ $("#progress").progressbar({value: 60});
+ $("div.ui-progressbar-value").css("background","orange");
+ } else {
+ strength.innerHTML = '<span style="color:red">'+mw.message(
'signupapi-weak' )+'</span>';
+ $("#progress").progressbar({value: 30});
+ $("div.ui-progressbar-value").css("background","red");
+ }
+}
+
+
+function checkRetype( pass,retype ) {
+ var valresult = document.getElementById('wpRetypeval');
+ var image = "";
+ var message = "";
+ if ( pass==retype ) {
+ image = "<img src='"+ imagePath +"MW-Icon-CheckMark.png'>";
+ message = mw.message( 'signupapi-passwordsmatch' );
+ }
+ else {
+ image = "<img src='"+ imagePath +"MW-Icon-NoMark.png'>";
+ message = mw.message( 'badretype' );
+ }
+ valresult.innerHTML = image+message;
+}
+
+$('#wpName2').change(function() {validateInput("username","wpName2");});
+$('#wpPassword2').keyup(function() {passwordStrength();});
+$('#wpRetype').change(function()
{checkRetype(document.getElementById("wpPassword2").value,document.getElementById("wpRetype").value);});
+$('#wpEmail').change(function() {validateInput( "email","wpEmail" );});
+
+$('#wpName2').after('<span id="wpName2val" class="wpName2val"></span>');
+$('#wpPassword2').after('<span id="wpPassword2val"></span><div id="progress"
class="progress" style="width:30%; float: right;"></div>');
+$('#wpRetype').after('<span id="wpRetypeval" class="wpRetypeval"></span>');
+$('#wpEmail').after('<span id="wpEmailval" class="wpEmailval"></span>');
+
+mw.loader.using( 'ext.SignupAPI', function() {
+ $("#progress").progressbar();
+ } );
+
+console.log();
+$('div.ui-progressbar').css('background','#F2F5F7');
+
+var imagePath = window.wgServer+window.wgExtensionAssetsPath +
"/SignupAPI/includes/images/";
+var minlength = window.wgMinimalPasswordLength;
+
+
Property changes on: trunk/extensions/SignupAPI/includes/verification.js
___________________________________________________________________
Added: svn:eol-style
+ native
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs