explorers’ club


Tutorial: AppCoreLib’s XMLDataBroker, mock XML data & Cairngorm
Monday, May 12, 2008, 6:46 pm
Filed under: actionScript, appCoreLib, cairngorm, client side, development, flex, projects, server side, tutorial, xml

The potential of Flex for rapid prototyping and general application development is amazingly fast. With some mock data and a basic user-experience (UX) scenario, a developer can create a functioning sample application in a matter of minutes.

If you are developing either a full blown RIA or a prototype application then you have probably at least heard of Cairngorm. If not, familiarize yourself with the basics here – link. I use a stripped down version of it for almost every project I have worked on. It works beautifully

I plan to show you an example of using AppCoreLib’s XMLDataBroker to fill in some mock XML data for your commands. This is helpful when you have a basic idea of an API/services but they are not returning anything or not ready to be tapped or you wanna test out a service’s result format before the server developers implement it.

Before I continue, let’s set one or two rules about this tutorial.

  • the expected format for the returned data is XML
  • the mock XML data format will reflect the same format of the actual service’s result

Firstly let’s take a look at a basic Cairngorm command. This is a stripped down version so you won’t see any delegate-type references in here.

package com.foo.controller.commands
{
    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;
    import com.foo.business.Services;

    import mx.rpc.AsyncToken;
    import mx.rpc.IResponder;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.http.HTTPService;

    public class SampleCairngormCommand implements ICommand, IResponder
    {
        private var _vo:Object = {};

        public function execute (event:CairngormEvent):void
        {
            var call:HTTPService = Services.getInstance().httpService;
            call.url = "http://www.foo.com/someService";

            var param:Object = {};

            var token:AsyncToken = call.send(param);
            token.addResponder(this);
        }

        public function result (data:Object):void
        {
            var xmlResult:XML = ResultEvent(data).result as XML;
        }

        public function fault (info:Object):void
        {
        }

    }
}

So now with about 5 lines of code, I will show you how to inject mock XML data for creating a response that fits within the Cairngorm command structure:

package com.foo.controller.commands
{
    import appCoreLib.business.XMLDataBroker;
    import appCoreLib.events.XMLLoadEvent;

    import com.adobe.cairngorm.commands.ICommand;
    import com.adobe.cairngorm.control.CairngormEvent;

    import mx.rpc.IResponder;

    public class SampleCairngormCommand implements ICommand, IResponder
    {
        public function execute (event:CairngormEvent):void
        {
            var x:XMLDataBroker = new XMLDataBroker();
            x.addEventListener(XMLLoadEvent.XML_LOAD_SUCCESS, result);
            x.addEventListener(XMLLoadEvent.XML_LOAD_FAILURE, fault);
            x.loadXML("assets/xml/someMockXMLData.xml");

            /* var call:HTTPService = Services.getInstance().httpService;
            call.url = "http://www.foo.com/someService";

            var param:Object = {};

            var token:AsyncToken = call.send(param);
            token.addResponder(this); */
        }

        public function result (data:Object):void
        {
            var xmlResult:XML = XMLLoadEvent(data).xml;
            //var xmlResult:XML = ResultEvent(data).result as XML;
        }

        public function fault (info:Object):void
        {
        }
    }
}

That’s it! Simple, effective and most importantly, easy to remove once an actual service response is available.



tutorial: Flex + AMFPHP + POG
Wednesday, March 12, 2008, 5:30 pm
Filed under: actionScript, amf, amfphp, cairngorm, development, flash, flex, mysql, orm, php, pog, remoting, tutorial, xml

Preface

If you are no stranger to the concept of a Rich Internet Application (aka. RIA) and the different constituents that make up a RIA, you can skip this introduction. This tutorial will help developers to setup a Flex application to a database using PHP while minimizing manual database queries. Let’s familiarize ourselves with a few basic RIA concepts. Generally a RIA is comprised of 3 main components:

  • the client – no, not your client that sends the checks, but rather the Graphical (User) Interface that a user of a RIA interacts with. In our case, this the flex client that is deployed to a particular URL.
  • the service layer -this component is the hidden part of the application that interprets client events, requests information stored on a database, and then sends the requested data back to the client. In our case AMFPHP, PHP and POG will be in this category. I will explain what these mean in a bit.
  • the database – this is where our data is stored. In my case this is MySQL. Depending on your local setup, you may be using a different database.

For most of this tutorial we will be dealing with the client and the service layer. The service layer will be comprised of AMFPHP which is a very small framework which facilitates remoting between Flex and PHP. Remoting is simply a means to send and receive native ActionScript objects to a service layer. POG is another small framework for taking PHP objects and allowing CRUD methods for their database counterparts. CRUD stands for Create, Read, Update and Delete and POG simply stands for PHP Object Generator. In our case, we are setting up a RIA so that the objects sent to and from Flex will easily be able to be manipulated via CRUD methods. To sum this up we are establishing a seamless means of having Flex and a database to communicate with a minimum amount of manual data manipulation. If that confused the hell out of you, I apologize as I am kinda new to making tutorials.

Resources

POGTestApp client & server – link
AMFPHP v1.9 20070513 – link
POG – link

The Quest

Anyone who frequents this blog know that I have been on a mission for some time to get some sort of ORM setup for my pet-project. I didn’t want to be encumbered by a heavy framework with a complex API or inheritance structure. I’d looked at CakePHP, Doctrine, Propel, Junction and a few others. As a non-PHP guy, I found all of those to be overwhelming. I’d rather spend my time coding than having to read config documentation or learn a new API. That is not to say that I don’t want to learn something new, I do. I just felt enough of my time had been spent trying to find the right solution. The right solution had to be ultra-simple and intuitive.

Enter POG

POG stands for PHP Object Generator. I’ll spare you my praises of it for now (you can read up on their site if you like). Suffice it to say it is an ORM framework that is simple, intuitive and light weight. And it works for me. This looks like a long read, and it is, but it will go rather quickly. Lot’s of pictures too!!!

Your first Flex + AMFPHP + POG RIA

Server setup

I have my project setup in two places. One location is where my deployable flex content, AMFPHP and POG code goes. The other is simply where I house my Flex project source. Here is a pic of the deploy location:

picture-2.png

I use MAMP (Mac + Apache + MySQL + PHP) which is a turnkey PHP server. It works well for me because I really didn’t like doing all the Terminal setup to get my Mac’s built in PHP setup for this. If my project makes it to the big time, then all this server side setup will be delegated to a more knowledgeable person who can set it up better than I have.

AMFPHP

Firstly I want to tackle the AMFPHP part since its probably the most straight forward part of the process. Go and download AMFPHP 1.9. I am using the 20070513 release. Once downloaded, unzip it and place it in the aforementioned deploy location. The only things you need to do for AMFPHP is:

  • make note of you services folder (I put a symlink to the whole AMF folder in my flex project so I could have direct access to it from within Eclipse without having to use the bin folder).
  • adjust the following information on the globals.php
    • $servicesPath – in my case “services/”
    • $voPath – this will point to your POG objects folder once we get it setup, in my case “../pog/objects/”

That is all on the AMFPHP aside from constructing your services.

[EDIT 2008.03.21]

Since initially this tutorial only happened to touch upon the setup of these technologies there hadn’t been any issues encountered. Obviously this tutorial didn’t reflect a real implementation of such a setup beyond the simple Get method. Further development has turned up an interesting find about sending AS3 objects out from Flex to be mapped to a POG object. As it is now, it can’t. That is because the naming convention chosen by the POG framework doesn’t get picked up by the AMFPHP deserializer. My gunslinger buddy Renaun Erickson has found a simple solution for this that doesn’t break the POG naming convention. You can read more about it on his blog – link.

You need to open the AMFBaseDeserializer.php and insert the following code at line 384:

elseif(file_exists($GLOBALS['amfphp']['customMappingsPath'] . 'class.' . strtolower($mappedClass) . '.php'))
{
        $include = $GLOBALS['amfphp']['customMappingsPath'] . 'class.' . strtolower($mappedClass) . '.php';
}

POG

POG is unique in that you don’t just go and download a framework (at least not yet). If you visit POG, you are greeted with a little RIA that takes some information about the object you want to create. I decided to use the name TestObject and give it two properties: userName and password both being varchar(255). Just to reiterate, I am using the PHP5.1+ along with the POG database wrapper:

picture-3.png

Notice that I am NOT using the PDO mysql wrapper. Reason being that AMFPHP has issues finding the mysql PDO driver and not everyone’s php environment contains those. So let’s stick to the POG database wrapper.

Since this is the first interaction with POG, we want to download the full framework in addition to you new object:

dlzip.png

Then unzip the file, rename it simple as “pog” and place it in your deployment location. Next locate the {yourMainDeploymentFolder}/pog/configuration.php and update the needed information so that POG can access your database. Here is a snap of mine:

configs.png

Notice that I have my mysql port set to 8889 rather than the default 3306? Also the plugin settings url is an absolute path. In your browser navigate to the following location: http://localhost{:yourPort}/{yourMainDeploymentFolder}/pog/setup/index.php. Go through the initial welcome/setup screen. POG will do some quick unit test, and if everything goes well, you are then presented with a portal to do basic CRUD methods on your new POG object. This is useful because we can setup a few test objects to use in setting up and testing the Flex application.

Now it would appear that POG is ready to go. And you’d be correct if you just want to use the local POG portal to play with it. In order to get it working with Flex and AMFPHP, you need to fix a few things with a few classes in POG. We will come back to that after we get the Flex project setup.

Flex

I am providing my POGTestApp source for you to download, but I also want you to see the steps necessary to do it yourself. First let’s create a new Flex project. I called mine POGTestApp. Now I also have mine located in a different place than the deployment location so I used some advanced options:

flexpath.png

In the provided flex project, I have the Cairngorm.swc in the libs folder. Make sure to add the libs folder to the library path. Also point it to the services-config.xml:

picture-5.png

Open the services-config.xml and make sure to modify the endpoint uri to point to your amfphp gateway.php:

services-config.png

Now at this point you should be able to modify your Services.mxml (ServiceLocator subclass) and add your php services there. If you downloaded the files I have provided, I suggest taking a look at Services.mxml. Since this is a testing application, I have a genericFaultHandler and a genericResultHandler in this file that you can add breakpoints to for debugging purposes. So even though I am making the calls from the application file without any responders, I am still listening for them in Services.mxml. Now if you decide to make some calls of you own, without using my files, you will notice that you get some errors or it just doesn’t seem to work. That is because POG needs some adjustments to work properly.

POG adjustments

Even though POG works inside the provided POG setup.php, it won’t want to play with Flex or AMFPHP unless you give it some help. Here are a few things to modify:

  • open the class.database.php and hardcode your configuration.php settings in there. For some reason the global vars are not making through to the Database class. Since I suck at php, I was advised to put it here until a better solution is found.
  • open the class.testobject.php (or whatever your POG object is named) and add the remoting string: var $_explicitType = YourRemotingClassNameHere.
  • also add include_once(‘class.database.php’);to class.testobject.php.

That should do it. Make your own or use the POGTestingServices and play with it. Keep in mind that even though my provided files work, you might get some PHP specific errors that appear to fail silently. If you experience this behavior you need to check your php.log to see what the issue is. Generally its due to the remoting code rather than the POG code.

Retrospective

I really like the idea of remoting for prototyping. It takes the hassle away from having to parse your responses in flex. POG is an ideal solution for developers not that familiar with PHP as the objects translate rather easily and since it is OO, its easy to do the mysql input without having to get involved with writing queries.

When time is of the essence, maybe you will consider this beautifully simple solution. Thanks goes out to Joel Wan (POG) and Renaun Erickson (the gunslinger) for help sorting this out. Let me know if you have any advice, suggestions, criticism and or corrections for this tutorial.



Better documentation for AS3’s XML class (e4x)
Wednesday, February 27, 2008, 4:25 pm
Filed under: actionScript, appCoreLib, development, e4x, flash, flex, regexp, xml

A powerful yet elegantly simple construct

As a flex developer, I consider XML as a necessary and highly useful language for various aspects of RIA development. There is a myriad of uses including but not limited to:

  • external URL storage for links
  • non-embedded content loading of jpgs, gifs, pngs and other swfs
  • internal URL pointers for RESTful type services
  • incoming service response objects
  • application initialization data (e.g. dataProviders, default settings)
  • and the list goes on

That is all well and good. But the problem is that if you don’t fully understand how to traverse an XML object and understand what it does when using e4x to access, then you are not making the most of this simple yet powerful development structure. The next problem lies in that there is very poor documentation on e4x in respect with the ActionScript XML class.

Truly understanding what the XML Object & e4x does

Adobe did a decent job of showing you how to traverse an XML object via e4x and then seeing their simple little trace statements. But what they failed to do was to give you useful examples of how to use that output and turn it into ActionScript-friendly objects.

Grabbing an XML node’s attribute

We have all probably used the following to get a value from an attribute from an XML node:

var o:Object = someXMLObject.@someAttribute; //o is now an XMLList

The issue with this example is that o is an instance of an XMLList. In order to fully make use of the value inside that singular attribute (why it turns it to an XMLList when specifying that node’s attribute expecting a singular value, I have no idea) we have to cast that value to what we want. Here are a few examples:

var s:String = String(someXMLObject.@someAttribute);

var n:Number = Number(someXMLObject.@someAttribute);

Easy!

Constructing an XML object from within ActionScript

Most everyone has probably used the following to construct an XML variable in AS3:

var x:XML =

<node someAttribute="value">

   <subNode anotherAttribute="value"/>

   <subNode>value</subNode>

</node>

Doing a trace on that would yield the expected XML to output to an XML string, retaining the nested structure and brackets. But using the new XML() constructor can yield some different results, some unexpected and not entirely useful.

var x:XML = new XML("node"); //traces "node" and not <node/>

So how would one dynamically construct a new XML object when not knowing the node name?

var x:XML = new XML("<" + dynamicValueForNodeName + "/>");

I don’t like the above setup. Its a messy read. Certainly there is another option?

var x:XML = <genereicNodeNameToBeChanged/>;
x.setName("newNodeName"); //traces <newNodeName/>

While this is documented, they really don’t touch on it at all in their given examples.

Setting values to nodes

If you wanted to put a subNode inside a parentNode you’d probably use syntax such as:

var x:XML = <node/>;
var x2:XML = <subNode/>;
x.appendChild(x2); //which yields <node><subNode/></node>

That is probably the most common usage of appendChild(). But did you know you can append values as well? Not just subNodes but also non-nodal values:

var x:XML = <node/>;
x.appendChild("someValue"); //traces <node>someValue</node>

Again, this is very useful but not really touched upon by the documentation.

Finding values using the . syntax

One of the nicest features about e4x is that you can rapidly find value(s) nested deep within the XML by using the “dot” syntax. I will abstain from listing an example here as there are numerous examples on the documentation site. But did you know that you can make multiple inquiries on an XML structure within the same line of code?

arrayElementType = String(item.metadata.(@name == "ArrayElementType").arg.(@key == "" || @key == "type").@value);

This eliminates the need to make multiline inquiries by getting an XMLList from one e4x boolean operation, then repeating down the line until you have driven down into the specific node you are looking for.

Using this new-found knowledge

Though you may or may not have known about some of these little tricks, you might be wondering, “so where do I use this”. A few posts back I eluded to the fact that I was developing an XML-to-ActionScript translator for AppCoreLib. The translator would then be able to quickly take in an XML response from a web service and spit back a useful ActionScript object of a specified class with little work involved by the responder. In order to do this, I have to make major use of XML and specifically the XML spit out by the describeType method. It means that I not only have to traverse the XML object, I also have to dynamically construct XML objects to be sent back. After the first build, I was a little miffed that I had some hard to read, and plain ol’ ugly ass code. I wanted to fully immerse myself in what the XML object and e4x had to offer.

If you have some not-so-well-documented tips and tricks for XML and e4x, send them along and I will add it to the post.