In this part of the series, we’re not so much focusing on the login part of the component we’ve been building, but rather the registration form. More specifically, we want to check the database prior to adding a new user record to make sure we’re not about to get a duplicate user record in the database. This is going to utilize a combination of PHP and Flex. When the user clicks the “Save” button from the registration form, it will send both the username and email address to PHP, which will run a query against the database. PHP will then send back a “true” or “false” response based on whether the username and/or email address already exists. Once Flex receives the answer, it will then either allow registration to continue with adding the record, or it will send an Alert notifying the user that there is a problem with either the username or email address or both.
Lets start by adding the needed PHP file.
duplicates.php
<?php
$host="localhost"; // Host name
$username="root"; // Mysql username
$password="root"; // Mysql password
$db_name="example12"; // Database name
//Connect to server and select databse.
mysql_connect("$host", "$username", "$password")or die("cannot connect to server");
mysql_select_db("$db_name")or die("cannot select DB");
// table name
$tbl_name=users;
//assign the data passed from Flex to variables
$username = mysql_real_escape_string($_POST["usernameTextInput2"]);
$email = mysql_real_escape_string($_POST["emailTextInput2"]);
//check if email id is already present
$chk1=mysql_query("Select * FROM $tbl_name WHERE email='$email'");
$num1=mysql_num_rows($chk1);
$dupemail .= "<dupemailchk>";
if($num1 > 0)
{
$dupemail .= "true";
}
else
{
$dupemail .= "false";
}
$dupemail .= "</dupemailchk>";
//check if email id is already present
$chk2=mysql_query("Select * FROM $tbl_name WHERE username='$username'");
$num2=mysql_num_rows($chk2);
$dupuser .= "<dupusernamechk>";
if($num2 > 0)
{
$dupuser .= "true";
}
else
{
$dupuser .= "false";
}
$dupuser .= "</dupusernamechk>";
//output the XML
print ($dupemail);
print ($dupuser);
?>
What this is saying is: Take the user’s desired username (“usernameTextInput2″) and email address (“emailTextInput2″) and check against the database’s users table to see if there is a match in the respective column. If there is, send back true, otherwise send back false. There will be two separate answers returned, one for username and one for email address. This allows the application to know which Alert to give the user.
Creating the Function
This function first checks to see if there is a duplicate username, and if there is a duplicate email address, and if there is not for either of them, it will call saveBtn_clickHandler.
private function dupCheck(event:ResultEvent):void
{
if(event.result.dupusernamechk == true)
{
mx.controls.Alert.show('Please choose another username, this one is already taken.');
}
else if(event.result.dupemailchk == true)
{
mx.controls.Alert.show('This email address has already been registered.');
}
else
{
saveBtn_clickHandler();
}
}
Creating the Service Call
<mx:HTTPService id="duplicate_check" result="dupCheck(event)" showBusyCursor="true" method="POST" url="duplicates.php" useProxy="false">
<mx:request xmlns="">
<usernameTextInput2>
{usernameTextInput2.text}
</usernameTextInput2>
<emailTextInput2>
{emailTextInput2.text}
</emailTextInput2>
</mx:request>
</mx:HTTPService>
The above code is telling PHP the names of the variables that we are sending over and telling Flex where to get that information, what function we are calling, how we are communicating with PHP, and where the file is located.
Component Changes
First we need to make sure that we are calling duplicate_check HTTPService rather than saveBtn_clickHandler. This allows us to check for duplicates, and then if there are none, then the dupCheck function will callsaveBtn_clickHandler.
Change From:
<s:Button x="10" y="118" label="Save" id="saveBtn" click="saveBtn_clickHandler(event)" enabled="false" includeIn="register"/>
.
Change To:
<s:Button x="10" y="118" label="Save" id="saveBtn" click="duplicate_check.send()" enabled="false" includeIn="register"/>
Secondly, we need to remove the argument being passed by saveBtn_clickHandler which was created automatically for us by FB4.
Change From:
protected function saveBtn_clickHandler(event:MouseEvent):void
Change To:
protected function saveBtn_clickHandler():void
That’s it. Go ahead and run the application and try to create a duplicate entry. You will find that you will be alerted when doing so.
Application should now look like:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
applicationComplete="init()"
minWidth="955" minHeight="600" xmlns:valueObjects="valueObjects.*"
xmlns:usersservice="services.usersservice.*">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.ValidationResultEvent;
import mx.rpc.events.ResultEvent;
import mx.validators.EmailValidator;
import mx.validators.StringValidator;
import spark.events.TextOperationEvent;
private var userid:int;
private var usertype:String;
private var usernameVal:StringValidator = new StringValidator();
private var passwordVal:StringValidator = new StringValidator();
private var emailVal:EmailValidator = new EmailValidator();
private var usernameVal2:StringValidator = new StringValidator();
private var emailVal2:EmailValidator = new EmailValidator();
private var passwordVal2:StringValidator = new StringValidator();
[Bindable]
private var cookieAction:Boolean;
protected function saveBtn_clickHandler():void
{
var users2:Users = new Users();
users2.username = usernameTextInput2.text;
users2.email = emailTextInput2.text;
users2.password = passwordTextInput2.text;
users2.user_type = "user";
createUsersResult.token = usersService.createUsers(users2);
createUsersResult.token = usersService.commit();
currentState = 'loggedOut';
}
private function checkLogin(event:ResultEvent):void
{
userid = event.result.loginsuccess;
trace (userid);
usertype = event.result.usertype;
trace (usertype);
cookieAction = event.result.usertype;
trace (cookieAction);
if (userid != 0)
{
currentState = usertype;
}
else
{
mx.controls.Alert.show('Invalid username/password');
}
}
protected function createUsersResult_resultHandler(event:ResultEvent):void
{
mx.controls.Alert.show('Thank you for registering. You may login now!');
currentState = "loggedOut";
}
private function init():void
{
getCookie.send();
}
protected function getCookie_resultHandler(event:ResultEvent):void
{
if(event.result.storedCookie == true)
{
cookieAction = true;
username.text = event.result.creds.username;
password.text = event.result.creds.password;
loginBtn.enabled = true;
}
else
{
cookieAction == false;
}
}
private function getPassword(event:ResultEvent):void
{
if(event.result.getPassword == "yes")
{
mx.controls.Alert.show('Your password has been emailed to you.');
currentState = "loggedOut";
}
else
{
mx.controls.Alert.show('Invalid email, please try again.');
}
}
protected function loggedOutVal_changeHandler(event:TextOperationEvent):void
{
if (username.text)
{
var valUsername:ValidationResultEvent;
usernameVal.source = username;
usernameVal.property = "text";
usernameVal.minLength=6;
}
if (password.text)
{
var valPassword:ValidationResultEvent;
passwordVal.source = password;
passwordVal.property = "text";
passwordVal.minLength=6;
}
valUsername = usernameVal.validate();
valPassword = passwordVal.validate();
if(valUsername.type == "valid" && valPassword.type == "valid")
loginBtn.enabled = true;
else
loginBtn.enabled = false;
}
protected function email_toVal_changeHandler(event:TextOperationEvent):void
{
if (email_to.text)
{
var valEmail:ValidationResultEvent;
emailVal.source = email_to;
emailVal.property = "text";
}
valEmail = emailVal.validate();
if(valEmail.type == "valid")
emailBtn.enabled = true;
else
emailBtn.enabled = false;
}
protected function registerVal_changeHandler(event:TextOperationEvent):void
{
if (usernameTextInput2.text)
{
var valUsername2:ValidationResultEvent;
usernameVal2.source = usernameTextInput2;
usernameVal2.property = "text";
usernameVal2.minLength=6;
}
if (emailTextInput2.text)
{
var valEmail2:ValidationResultEvent;
emailVal2.source = emailTextInput2;
emailVal2.property = "text";
}
if (passwordTextInput2.text)
{
var valPassword2:ValidationResultEvent;
passwordVal2.source = passwordTextInput2;
passwordVal2.property = "text";
passwordVal2.minLength=6;
}
valUsername2 = usernameVal2.validate();
valEmail2 = emailVal2.validate();
valPassword2 = passwordVal2.validate();
if(valUsername2.type == "valid" && valPassword2.type == "valid" && valEmail2.type == "valid")
saveBtn.enabled = true;
else
saveBtn.enabled = false;
}
private function dupCheck(event:ResultEvent):void
{
if(event.result.dupusernamechk == true)
{
mx.controls.Alert.show('Please choose another username, this one is already taken.');
}
else if(event.result.dupemailchk == true)
{
mx.controls.Alert.show('This email address has already been registered.');
}
else
{
saveBtn_clickHandler();
}
}
]]>
</fx:Script>
<s:states>
<s:State name="loggedOut"/>
<s:State name="forgotPW"/>
<s:State name="register"/>
<s:State name="user"/>
<s:State name="admin"/>
</s:states>
<fx:Declarations>
<s:HTTPService id="login_user" result="checkLogin(event)" showBusyCursor="true" method="POST"
url="login.php" useProxy="false">
<s:request xmlns="">
<username>
{username.text}
</username>
<password>
{password.text}
</password>
<logincookie>
{setCookie.selected}
</logincookie>
</s:request>
</s:HTTPService>
<s:HTTPService id="getCookie" result="getCookie_resultHandler(event)" method="POST" url="getCookie.php"/>
<mx:HTTPService id="get_password" result="getPassword(event)" showBusyCursor="true" method="POST"
url="forgotPW.php" useProxy="false">
<mx:request xmlns="">
<email_to>
{email_to.text}
</email_to>
</mx:request>
</mx:HTTPService>
<mx:HTTPService id="duplicate_check" result="dupCheck(event)" showBusyCursor="true" method="POST"
url="duplicates.php" useProxy="false">
<mx:request xmlns="">
<usernameTextInput2>
{usernameTextInput2.text}
</usernameTextInput2>
<emailTextInput2>
{emailTextInput2.text}
</emailTextInput2>
</mx:request>
</mx:HTTPService>
<valueObjects:Users id="users"/>
<usersservice:UsersService id="usersService" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
<s:CallResponder id="createUsersResult" result="createUsersResult_resultHandler(event)"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Panel width="250" height="200" title="Flex 4 Login Box" horizontalCenter="0" verticalCenter="0">
<s:Label x="10" y="18" text="Username" includeIn="loggedOut"/>
<s:TextInput x="110" y="10" id="username" change="loggedOutVal_changeHandler(event)" includeIn="loggedOut"/>
<s:Label x="12" y="47" text="Password" includeIn="loggedOut"/>
<s:TextInput x="110" y="40" id="password" change="loggedOutVal_changeHandler(event)" displayAsPassword="true" includeIn="loggedOut"/>
<s:Button x="10" y="72" id="loginBtn" label="Login" click="login_user.send();" enabled="false" includeIn="loggedOut"/>
<s:Button x="120" y="72" label="Forgot Login Info?" click="currentState='forgotPW'" includeIn="loggedOut"/>
<s:CheckBox x="10" y="101" label="Remember Me" id="setCookie" selected="{cookieAction}" includeIn="loggedOut"/>
<s:Label x="195" y="103" text="Sign Up" click="currentState='register'" includeIn="loggedOut"/>
<s:Label x="10" y="46" text="Email:" includeIn="forgotPW"/>
<s:TextInput x="110" y="39" id="email_to" change="email_toVal_changeHandler(event)" includeIn="forgotPW"/>
<s:Button x="8" y="72" id="emailBtn" label="Get Login Info" click="get_password.send();" enabled="false" includeIn="forgotPW"/>
<s:Button x="168" y="72" label="<< Login" click="currentState='loggedOut'" includeIn="forgotPW"/>
<s:Label x="10" y="31" text="Username:" includeIn="register"/>
<s:TextInput x="110" y="24" id="usernameTextInput2" text="{users.username}" change="registerVal_changeHandler(event)" includeIn="register"/>
<s:Label x="10" y="61" text="Email:" includeIn="register"/>
<s:TextInput x="110" y="54" id="emailTextInput2" text="{users.email}" change="registerVal_changeHandler(event)" includeIn="register"/>
<s:Label x="10" y="91" text="Password:" includeIn="register"/>
<s:TextInput x="110" y="84" id="passwordTextInput2" text="{users.password}" change="registerVal_changeHandler(event)" displayAsPassword="true" includeIn="register"/>
<s:Button x="10" y="118" label="Save" id="saveBtn" click="duplicate_check.send()" enabled="false" includeIn="register"/>
<s:Button x="168" y="118" label="<< click="currentState='loggedOut'" Login" includeIn="register"/>
<s:Label x="10" y="10" text="Welcome User" includeIn="user"/>
<s:Button x="10" y="30" label="Log Out" click="currentState='loggedOut'" includeIn="user"/>
<s:Label x="10" y="10" text="Welcome Admin" includeIn="admin"/>
<s:Button x="10" y="30" label="Admin Log Out" click="currentState='loggedOut'" includeIn="admin"/>
</s:Panel>
</s:Application>
