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

Reply via email to