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 the endpoint 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 and LoginPanel.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 a Login.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 called GenericDestination.
 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 named loginService.
 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 its RemoteClass 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.

Any feedback?

comments powered by Disqus