Here is the code I used to add a password strength meter to the user edit form. First, I added a menu item that will be used by AJAX to process the user’s password. The path will be used like this: http://MYWEBSITE/passwordStrength/USERPASSWORD. As you can see in the callback arguments, the remainder of the query string after the first “/” is passed into the callback function.
Drupal hook_menu:
<?php
function MYMODULE_menu () {
$items = array ();
// ...code...
$items [] = array (
'path' => 'passwordStrength' ,
'callback' => 'MYMODULE_passwordStrength' ,
'type' => MENU_CALLBACK ,
'access' => TRUE ,
'callback arguments' => array ( array_pop ( explode ( "/" , $_REQUEST [ 'q' ], 2 ))),
);
// ...code...
return $items ;
}
?>
Here’s the callback function. It returns an integer to the screen with no theming.
<?php
function patient_portal_callback_passwordStrength ( $password ) {
// NOTE: "SSL: Fatal Protocol Error" occurring
// echo file_get_contents('https://www.google.com/accounts/RatePassword?Passwd=' . $password);
// NOTE: google will return 1-4
// check for invalid password
if ( strlen ( $password ) == 0 || ! $password ) {
echo 1 ;
die ;
}
// using CURL to fetch website result
$ch = curl_init ();
curl_setopt ( $ch , CURLOPT_URL , 'https://www.google.com/accounts/RatePassword?Passwd=' . urlencode ( $password ));
curl_exec ( $ch );
curl_closE ( $ch );
die ;
}
?>
The next part is modifying the user edit form using the form_alter hook.
<?php
function MYMODULE_form_alter ( $form_id , & $form ) {
// ...code...
if ( $form_id == 'user_edit' ) {
// add weights to current account form elements
if ( isset ( $form [ 'account' ][ 'name' ])) $form [ 'account' ][ 'name' ][ '#weight' ] = 1 ;
if ( isset ( $form [ 'account' ][ 'mail' ])) $form [ 'account' ][ 'mail' ][ '#weight' ] = 2 ;
if ( isset ( $form [ 'account' ][ 'pass' ])) $form [ 'account' ][ 'pass' ][ '#weight' ] = 3 ;
if ( isset ( $form [ 'account' ][ 'status' ])) $form [ 'account' ][ 'status' ][ '#weight' ] = 5 ;
if ( isset ( $form [ 'account' ][ 'roles' ])) $form [ 'account' ][ 'roles' ][ '#weight' ] = 6 ;
// create html for password meter
$passwordMeterHtml = "
<div id='passwordMeterFormItem' class='form-item'>
<label>
<span id='passwordStrengthLabel'>Password Strength:</span>
<span id='passwordStrengthDescription'></span>
</label>
<table id='passwordMeter'>
<tr>
<td id='barLeft'></td>
<td id='barRight'></td>
</tr>
</table>
</div>
" ;
// add form "element"
$form [ 'account' ][ 'passwordMeter' ] = array (
'#value' => $passwordMeterHtml ,
'#weight' => 4 ,
);
// add js to password input
$js = "
$(document).ready(function(){
$('form#user-edit #edit-pass-pass1').keyup(function(e){
if (this.value.length) {
$.ajax({
type: 'GET',
url: '/passwordStrength/' + this.value,
success: function(passwordCode){
switch (passwordCode) {
case '1':
word = 'Weak';
break;
case '2':
word = 'Fair';
break;
case '3':
word = 'Good';
break;
case '4':
word = 'Strong';
break;
}
// remove td classes
$('table#passwordMeter td#barLeft').removeClass();
$('table#passwordMeter td#barRight').removeClass();
// add td classes
$('table#passwordMeter td#barLeft').addClass(word);
$('table#passwordMeter td#barRight').addClass(word);
// set description
$('span#passwordStrengthDescription').html(word);
$('span#passwordStrengthDescription').removeClass();
$('span#passwordStrengthDescription').addClass(word);
}
});
} else {
// remove td classes
$('table#passwordMeter td#barLeft').removeClass();
$('table#passwordMeter td#barRight').removeClass();
// set description
$('span#passwordStrengthDescription').html('');
$('span#passwordStrengthDescription').removeClass();
}
});
});
" ;
drupal_add_js ( $js , 'inline' );
}
// ...code...
}
?>
Lastly, I added some CSS:
div #passwordMeterFormItem {
width : 210px ;
}
table #passwordMeter {
width : 100% ;
height : 10px ;
margin : 0 ;
clear : both ;
}
span #passwordStrengthLabel {
float : left ;
}
table #passwordMeter tbody , table #passwordMeter tr {
border : none ;
}
table #passwordMeter td {
padding : 0 ;
height : 10px ;
}
table #passwordMeter td #barLeft {
background-color : #e0e0e0 ;
width : 0% ;
}
table #passwordMeter td #barRight {
background-color : #e0e0e0 ;
width : 100% ;
}
table #passwordMeter td #barLeft .Weak {
width : 25% ;
background-color : #AA0033 ;
}
table #passwordMeter td #barRight .Weak {
width : 75% ;
}
table #passwordMeter td #barLeft .Fair {
width : 50% ;
background-color : #FFCC33 ;
}
table #passwordMeter td #barRight .Fair {
width : 50% ;
}
table #passwordMeter td #barLeft .Good {
width : 75% ;
background-color : #6699CC ;
}
table #passwordMeter td #barRight .Good {
width : 25% ;
}
table #passwordMeter td #barLeft .Strong {
width : 100% ;
background-color : #008000 ;
}
table #passwordMeter td #barRight .Strong {
width : 0% ;
}
span #passwordStrengthDescription {
display : block ;
float : right ;
}
span #passwordStrengthDescription .Weak {
color : #AA0033 ;
}
span #passwordStrengthDescription .Fair {
color : #FFCC33 ;
}
span #passwordStrengthDescription .Good {
color : #6699CC ;
}
span #passwordStrengthDescription .Strong {
color : #008000 ;
}
Here’s a screen shot: