Accessibility

Retrieving Drupal nodes with Flex 2

Justin Girard

www.furiousnerd.com

The use of PHP and MySQL as a back end for Adobe Flex applications can be a powerful combination for web developers dealing with clients who do not require enterprise-level solutions. Drupal—a modular, PHP-based content management system—can further enhance this marriage of technologies by providing a nearly instant, structured environment for managing data and content. With the introduction of the Services module for Drupal 5.x written by Scott Nelson, Drupal provides an optional integrated API for creating Flex or Flash applications driven by the Drupal framework. In this tutorial, I'll show you a basic operation for such an application: retrieving a node from Drupal.

Note: This tutorial is based on an example by Alexander Crugnola, in the example, Flex with AMFPHP. Please note that Alexander Crugnola's example is not specific to Drupal.

Requirements

In order to make the most of this article, you need the following software and files:

Software components:


Flex Builder 2

Web server components:

Sample code for this tutorial

Prerequisites:

Getting Drupal up and running

Before building your application, you'll need to install the Drupal content management system. As of Drupal Version 5.0, the installation process has been vastly simplified. An automated process has been added that installs the Drupal package, including the database. Follow the steps below to perform a base installation:

  1. Download the newest stable release of Drupal from http://www.drupal.org/download.
  2. Create a MySQL or PostgreSQL database for use with your Drupal install:

    mysql create database your_db_name

  3. Unpack the Drupal tarball in the HTML document root of your web server or another HTTP-accessible directory:

    On Unix: Unpack the archive using the command: tar -zxvf drupal-5.x.tar.gz

    On Windows: Unpack the archive using WinZip or WinRAR

  4. Modify permissions on the default settings.php file in your_drupal_install/sites/default/settings.php to allow the install script to modify it:

    On Unix: Use the command: chmod 777 your_drupal_install/sites/default/settings.php

    On Windows: Use the Windows command CACLS or XACLS, or use the Windows context-sensitive menu Properties (Security tab) to modify the permissions.

  5. Run the install script. To do so, navigate your browser to the base URL of your Drupal install. When browsing index.php in your Drupal install directory, you will see a "Database Configuration" page.

Once the installation is complete, the install will direct you to a "Welcome" page. Should you have trouble with your install, see the Drupal Troubleshooting FAQ. For Windows-specific installation guidelines, see Drupal's Windows-specific guidelines page. For further information regarding the installation of Drupal, see the Drupal Installation and configuration page.

Installing the required Drupal modules

Next, install the required Drupal modules, including AMFPHP, which is an RPC stack for PHP that enables Drupal to communicate with Flex.

  1. Download the latest stable release of the Drupal Services module from http://www.drupal.org/project/services.
  2. Download the newest stable release of the Drupal AMFPHP module at http://www.drupal.org/project/amfphp.
  3. Unpack the Services and AMFPHP tarballs in the modules directory of your Drupal install.
  4. Enable both the Services and AMFPHP modules within the Drupal administrator's interface at:

    http://your_drupal_install/admin/build/modules

  5. Make sure to also enable the AMFPHP server on the same page.
  6. For this example, I have disabled the "Use keys" and "Use sessid" options for the Services module. This is done in an effort to present the simplest possible example. To disable these options, do the following:

    1. Navigate your browser to http://your_drupal_install/admin/build/services/settings.
    2. Uncheck both the "Use keys" and "Use sessid" options.
    3. Click "Save configuration."

Installing AMFPHP

  1. Download the AMFPHP 1.9 Beta from http://www.5etdemi.com/uploads/amfphp-1.9.beta.zip.
  2. Unzip amfphp-1.9.beta.zip within the amfphp directory in your_drupal_install/modules/amfphp.
  3. Once step 2 is complete, test AFMPHP by navigating your browser to http://your_drupal_install/admin/build/services and clicking on the AMFPHP - /services/amfphp link under the "Services" heading.

    If AMFPHP is working properly, the output of that URL should look something like the following:

    amfphp and this gateway are installed correctly. You may now connect to this gateway from Flash.

    Note: If you're reading an old tutorial, it will tell you that you should see a download window instead of this message. This confused people so this is the new behaviour starting from amfphp 1.2.

    View the amfphp documentation

AMFPHP is now installed.

Note: For Flex to retrieve a node from your Drupal database, you must first create one. Make sure you create at least one story, page, or other node type to retrieve by clicking the "Create content" link in your Drupal administrator's interface, selecting a node type, and submitting it. Since it is the first node in the system, it will have a node ID of 1. If the node you decide to use has a different ID, adjust the MXML Application code accordingly. You will use this node later in this tutorial.

Creating the Flex application

Use the following steps to create the Flex application.

  1. Open Flex Builder 2 and create a new Flex project of type Basic. I named my Flex project AMFPHPDrupal.
  2. Create a services-config.xml file to describe your service. Create this file anywhere in your project and give it the name services-config.xml. I created a folder in my project called "services" and placed it there.
  3. In this file, you'll want the following code. You will need to specify the <endpoint uri="" to reflect the location of your own installation of the AMFPHP module:

    <?xml version="1.0" encoding="UTF-8"?>
    <services-config>
        <services>
            <service id="amfphp-flashremoting-service"
            class="flex.messaging.services.RemotingService"
            messageTypes="flex.messaging.messages.RemotingMessage">
                <destination id="amfphp">
                <channels>
                    <channel ref="my-amfphp"/>
                </channels>
                <properties>
                    <source>*</source>
                </properties>
                </destination>
            </service>
        </services>
    
        <channels>
            <channel-definition id="my-amfphp" class="mx.messaging.channels.AMFChannel">
                <endpoint uri="http://your_drupal_install/services/amfphp" class="flex.messaging.endpoints.AMFEndpoint"/>
            </channel-definition>
        </channels>
    </services-config>
    
  4. Add a compiler directive for the services-config.xml file you just created by using the following steps:

    • Right-click your project in Flex Builder and select Properties.
    • In the Properties dialog box, select Flex Compiler.
    • In the "Additional compiler arguments" text field, you must add a directive that specifies to Flex the location of your services-config.xml file on your machine.

      In my case this file is in my default Flex Project location, and my directive looks like the block below. You will add something that starts with "-services":

      -locale en_US -services "/Users/your-user-name/Documents/Flex Builder 2/your-project-name/services/services-config.xml".

      Note: In my case it was necessary to provide the full path to the file, and this path reflects the Apple file system structure. This may not be necessary in your case. If you are using a different OS, specify the appropriate path.

    • Click OK in the Properties dialog box.
    • If you experience errors from Flex Builder that say that the services-config.xml file can't be found, then the path is wrong. If the path is wrong, an error will show up immediately in the Problems pane of Flex Builder. If no error messages appear, your services-config.xml file is being compiled into your project when you click Debug or Run.
  5. Add the code for the MXML application file. The code is provided below in bulk and commented, and detailed descriptions are provided afterward:

    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="430" height="270">
    
        <!-- set up a RemoteObject with which to access the services api -->
        <mx:RemoteObject id="node" fault="faultHandler(event)" showBusyCursor="true" source="node" destination="amfphp">
            <mx:method name="load" result="resultHandler(event)" />
        </mx:RemoteObject>
    
        <mx:Script>
            <![CDATA[
            //import the required packages and classes
            import mx.rpc.remoting.RemoteObject;
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
    
            //declare an object to store the data we retrieve
            [Bindable]
            public var resObject:Object;
    
            //declare an event handler to deal with the result
            public function resultHandler(event:ResultEvent):void {
    
                //set the bindable object to the value of the result
                resObject = event.result;
    
                //set the value of the TextArea to the title of the loaded node
                result_text.text = "Success! The title of your node is: " + event.result.title;
            }
    
    
            //declare an event handler to deal with a potential fault
            public function faultHandler (event:FaultEvent):void {
                //set the value of the TextArea to the fault in the event of failure
                result_text.text = "fault: " + String(event.fault);
            }
            ]]>
        </mx:Script>
    
    <!-- note that by naming a RemoteObject the same as the Drupal service, we get a relative mirror of the Services and Drupal api;
        "node" - the service
        "load" - the method
        "node.load" - clear & concise -->
    
    <!-- set up simple ui elements to invoke the service & display the result -->
    <mx:Button id="btn" label="Load that node!" click="node.load(1);" width="115" bottom="5" right="15"/>
    <mx:TextArea width="400" height="200" id="result_text" horizontalCenter="0" verticalCenter="0"/>
    <mx:Label text="Result:" left="15" top="10"/>
    </mx:Application>
    

Here's a quick piece-by-piece analysis of the really important pieces of the MXML application file:

  1. Declare the RemoteObject and method with which you will connect to the node service, which looks like the following code:

    <mx:RemoteObject id="node" fault="faultHandler(event)" showBusyCursor="true" source="node" destination="amfphp">
    	<mx:method name="load" result="resultHandler(event)" />
    </mx:RemoteObject>
    

    Where...

    • The id attribute of the RemoteObject is local to the Flex project, specific to the RemoteObject, and is not associated with the services-config.xml file.
    • The source attribute of the RemoteObject is the node service, identified by its name, "node."
    • The destination attribute of the RemoteObject matches the destination ID of the service declared in the services-config.xml file,
    • The single <mx:method name> is the method of the node service you wish to call. Additional methods would be added in the same fashion.
    • The remaining code refers primarily to event handlers and user feedback during retrieval.
  2. Import the classes and packages you need, which looks like this:

    import mx.rpc.remoting.RemoteObject;
    import mx.rpc.events.ResultEvent;
    import mx.rpc.events.FaultEvent;
    
  3. Declare the button used to invoke the call to the service, which looks like this:

    <mx:Button id="btn" label="Load that node!" click="node.load(1);" y="{result_text.y + result_text.height + 20}" x="{result_text.width - btn.width}"/>
    

    Where...

    • The click event uses the ID you gave your RemoteObject to send the request with a node ID of 1. In my case this is a Drupal page with a title of "TestPage." You can change the node ID to any node that you have published in Drupal.

Make sure you have saved the changes made to your MXML application file and click Debug in Flex Builder. Once the application has launched, click "Load that node!" and wait for a result. If you have assembled these pieces correctly, you will see output in the TextArea that looks something like the following:

Success! The title of your node is: Your node title

Troubleshooting

Here are some common problems you might encounter and their probable causes:

In this tutorial you've accomplished much more than the simple face value task of retrieving a node from Drupal. Rather, upon completion of this tutorial you've armed yourself with a stable, modular, extensive and entirely cost-free back end with which to build Flex and Flash applications for your clients or business. In conjunction with the power of the Flex SDK, the Flex Builder development environment, and the visualization capabilities of Flex components, you wield an impressive set of tool. For development of rich Internet applications and websites for use in low to medium bandwidth and traffic environments, this developer thinks this combination is just the ticket.

Where to go from here

As noted in my conclusion, the possibilities are myriad. For instance, you might leverage Drupal's contributed Flash Video module, Flash Media Server (or ffmpeg) and Flex to create a next-generation video website with the ease of use and the extensibility of Flex components. Or, perhaps you might create a video encoder/decoder for a production environment that could be used by a group of employees, online, concurrently. Drupal's community, networking, and content aggregation/syndication features could be leveraged in conjunction with Flex to create very usable and efficient corporate intranets or management applications. You could develop the next step in social networking websites with new and enticing features that Flex can facilitate at very low cost. The possibilities are exciting.

If you are not already, you take this opportunity to familiarize yourself more with the Drupal framework, node and theme systems, core and contributed modules, and APIs to get a good idea of exactly how powerful and viable this combination of technologies can be. Drupal includes a very solid core group of modules and content-types out of the box, and the list of contributed modules is growing at a pace that is effectively impossible to keep up with. The Drupal community is large, perpetually growing and, largely, very helpful to beginners. The Drupal forums are a great resource for tracking down specific solutions to issues or requesting help with a problem. You might also consider joining Drupal groups that pertain to your specific development needs or interests at groups.drupal.org. Understanding the Services module framework will also be important if you intend to develop your own services for use in your applications. Check out the beginnings of the Services module handbook.

I hope you've found this tutorial to be helpful and inspiring. Happy "Flupaling"!

About the author

Justin Girard began his career as a web developer and designer at The @Home Network developing rich interfaces for broadband cable television, prior to which he spent seven years designing for traditional media and skateboarding professionally. He currently lives and works in New York City.