WebORB for PHP Login Example using Flex 3 and Cairngorm 2.2.1
Posted on August 8, 2007
I've been playing around with WebORB for PHP for developing Flex remoting services and it's just awesome. WebORB gives you well documented product information including a service browser, tons of examples, code generator etc.
However, one thing I've missed is a WebORB for PHP example using Flex and Cairngorm... So I decided to write it down on my blog. It based on Alex Uhlmann's CairngormLogin Sample modified by Neil Webb.
Example
To see this content latest Flash Player Plugin is required.
Instruction
You'll need the following sources:
- WebORB for PHP (v2.0.2)
- Cairngorm (2.2.1)
- Alex Uhlmann's CairngormLogin Sample
- Install WebORB as described in "GETTING STARTED - WEBORB INSTALLATION".
- Open Flex Builder and create a new Flex Project called "CairngormLogin". As Mike Potter pointed out you don't need to select Flex Data Service as server type which mentioned by the WebORB documentation, just "Other/None" using a
services-config.xml
as described in step 5. - Don't forget to add the
Cairngorm.swc
to your library path. - Create
services-config.xml
and modify the value of theendpoint uri
to{yourWebORBInstallationFolder}/Weborb/index.php
. Save it into the root of your project folder. UPDATE (10/06/07): Flex Builder 3 Beta 2 needs a valid port as well. For more information about it read this thread on Adobes Flex Builder 3 forum.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <services-config>
3 <services>
4 <service id="amfphp-flashremoting-service"
5 class="flex.messaging.services.RemotingService"
6 messageTypes="flex.messaging.messages.RemotingMessage">
7 <destination id="GenericDestination">
8 <channels>
9 <channel ref="my-amf"/>
10 </channels>
11 <properties>
12 <source>*</source>
13 </properties>
14 </destination>
15 </service>
16 </services>
17
18 <channels>
19 <channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel">
20 <endpoint uri="http://localhost:80/weborb/Weborb/index.php" class="flex.messaging.endpoints.AMFEndpoint"/>
21 </channel-definition>
22 </channels>
23 </services-config>
- Open your project properties window with a right mouse click on your project folder within Flex Builder to add the
services-config.xml
as a-services
argument to the Flex compiler - Copy all files of Alex Uhlmann's CairngormLogin Sample into your project folder.
*Update the
LoginDelegate.as
,LoginCommand.as
andLoginPanel.mxml
to the latest Cairngorm package (v. 2.2.1 beta) as Neil Webb described. At the end you can check your work with my files as well. - Now you have to create the remoting service called
getUser
adding aLogin.php
to{yourWebORBInstallationFolder}/Services/com/adobe/cairngorm/samples/login/
.
1 <?php
2
3 require_once("vo/LoginVO.php");
4
5 class Login
6 {
7
8 public function getUser(LoginVO $loginVO)
9 {
10 if ($loginVO->username == "admin" && $loginVO->password == "admin")
11 {
12 $adminVO = new LoginVO();
13 $adminVO->username = $loginVO->username;
14 $adminVO->password = $loginVO->password;
15 return $adminVO;
16 }
17 else
18 {
19 throw new Exception("Invalid username or password, please try it again.");
20 }
21
22 }
23 }
24
25 ?>
- The remoting service needs a Value Object (VO) to transfer the data between the application tier. Therefore create a VO named
LoginVO.php
and put it into{yourWebORBInstallationFolder}/Services/com/adobe/cairngorm/samples/login/vo/
1 <?php
2 class LoginVO
3 {
4 var $username;
5 var $password;
6 var $loginDate;
7 }
8 ?>
- Modify the ServiceLocator named
Services.mxml
for adding the remoting service created in step 9. Note: The destination for WebORB is calledGenericDestination
.
1 <?xml version="1.0" encoding="utf-8"?>
2 <cairngorm:ServiceLocator
3 xmlns:mx="http://www.adobe.com/2006/mxml"
4 xmlns:cairngorm="com.adobe.cairngorm.business.*">
5 <mx:RemoteObject
6 id="loginService"
7 destination="GenericDestination"
8 source="com.adobe.cairngorm.samples.login.Login"
9 showBusyCursor="true"
10 result="event.token.resultHandler(event);"
11 fault="event.token.faultHandler(event);">
12 </mx:RemoteObject>
13 </cairngorm:ServiceLocator>
- Modify the
LoginDelegate.as
to call the remoting service namedloginService
.
1 package com.adobe.cairngorm.samples.login.business
2 {
3 import com.adobe.cairngorm.business.ServiceLocator;
4 import com.adobe.cairngorm.samples.login.vo.LoginVO;
5
6 import mx.rpc.AsyncToken;
7 import mx.rpc.IResponder;
8
9 public class LoginDelegate
10 {
11 private var responder : IResponder;
12 private var service : Object;
13
14 public function LoginDelegate( responder : IResponder )
15 {
16 this.service = ServiceLocator.getInstance().getService( "loginService" );
17 this.responder = responder;
18 }
19
20 public function login( loginVO : LoginVO ): void
21 {
22 var token : AsyncToken = service.getUser(loginVO);
23 token.resultHandler = responder.result;
24 token.faultHandler = responder.fault;
25 }
26
27 }
28 }
- Modify the
LoginCommand.as
to respond the service call.
1 package com.adobe.cairngorm.samples.login.commands
2 {
3 import com.adobe.cairngorm.commands.Command;
4 import com.adobe.cairngorm.control.CairngormEvent;
5 import com.adobe.cairngorm.samples.login.business.LoginDelegate;
6 import com.adobe.cairngorm.samples.login.control.LoginEvent;
7 import com.adobe.cairngorm.samples.login.model.ModelLocator;
8
9 import mx.rpc.IResponder;
10
11 public class LoginCommand implements Command, IResponder
12 {
13 private var model : ModelLocator = ModelLocator.getInstance();
14
15 public function execute( event : CairngormEvent ) : void
16 {
17 model.login.isPending = true;
18
19 var delegate : LoginDelegate = new LoginDelegate( this );
20 var loginEvent : LoginEvent = event as LoginEvent;
21 delegate.login( loginEvent.loginVO );
22 }
23
24 public function result( event : Object ) : void
25 {
26 model.login.loginVO = event.result;
27 model.login.loginDate = new Date();
28 model.login.isPending = false;
29
30 model.workflowState = ModelLocator.VIEWING_LOGGED_IN_SCREEN;
31 }
32
33 public function fault( event : Object ) : void
34 {
35 model.login.statusMessage = event.fault.faultString;
36 model.login.isPending = false;
37
38 model.workflowState = ModelLocator.VIEWING_ERROR_SCREEN;
39 }
40 }
41 }
- One of the big advantage using remoting services is providing well-typed objects over the application tier called "client-server-class mapping". For ensure this you have to correspond your client-side Value Object called
LoginVO.as
to itsRemoteClass
using[RemoteClass(alias="com.adobe.cairngorm.samples.login.vo.LoginVO")]
1 package com.adobe.cairngorm.samples.login.vo
2 {
3 import com.adobe.cairngorm.vo.ValueObject;
4
5 [RemoteClass(alias="com.adobe.cairngorm.samples.login.vo.LoginVO")]
6
7 [Bindable]
8 public class LoginVO implements ValueObject
9 {
10 public var username : String;
11 public var password : String;
12 public var loginDate : Date;
13 }
14 }
That's all ;-)
Download
Note: In the following *.zip-file I've changed some more code lines for customizing the appearance of the example which I don't described above. Anyway, have fun ;-)
Source: CairngormLoginExampleWebORB.zip
UPDATE (23/12/07)
The tutorial and source code have been updated using Flex Builder 3 Beta 3.