Building a flash front-end for WordPress #1: logging into the admin area

Posted on Thursday 14 April 2005

Maybe the reason why few people are making RIAs is they think they will have to program everything from scratch. What if you want to use a Flash interface for content management, wikis, bulletin boards, blog software? You have two options right: stick with HTML or rebuild everything for Flash. Everyone is going to pick the HTML solution. But my point here is that in fact there is a viable third alternative, repurposing existing software for Flash use. Here I am not thinking of creating an XML layer, but rather creating wrapper services that will plug into the core of these content systems. In this way you not only enable Flash to plug in to these ready made systems but you will also provide an access point to the core functionality of that software package; you could reuse this to create a totally new interface for the software in HTML, Flash, SOAP, even PDF if you really wanted. So basically the point is to hack these systems to keep only a thin interface to the data access layer, and then use that thin interface as a Remoting service.

I chose to prove that it's possible to repurpose WordPress, the blogging software this site runs on, to make it run on a Flash interface. The interface to WordPress's admin area is already excellent, so the point is not in actually supplanting the HTML admin area, but proving it's possible. My hope is that sharing my experience will encourage people to do the same for other systems, like phpBB, Xoops, Nuke, osCommerce, and whatnot.

This, I'm hoping, will be an ongoing series, if anyone cares. It's exquisitely hacky, and a good hacker needs some good tools, namely:

  • AMFPHP 1.0 beta running on PHP5
  • xDebug compiled into PHP
  • WinCacheGrind to analyze xDebug files
  • Error logging to the Apache log file set to on

My first challenge was logging into the WordPress 1.3 admin area. Using xDebug and WinCacheGrind, I was able to see what files and functions were being called when I was logging to WordPress. The file wp-login.php was first loading a config file, then calling a function called wp_login(user, pass, usecookies). Marvellous! So as a first guess, I set up this PHP:


<?php
define('WP_BASE', 'e:/projets/5etdemi/v3/blog/');
require(WP_BASE . 'wp-config.php');
class WpAdmin
{
    function WpAdmin()
    {
        $this->methodTable = array(
            "attemptLogin" => array(
                "access" => "remote",
                "roles" => "admin"
            )
        );
    }
   
    function attemptLogin()
    {
        return true;
    }
   
    function _authenticate($user, $pass)
    {
        //Rig wordpress
        if(wp_login(addslashes($user), addslashes($pass), false))
        {
            return 'admin';
        }
        else
        {
            return false;
        }
    }
}
?>
 

And this very straightforward actionscript file:


import mx.remoting.Service;
import mx.rpc.RelayResponder;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
import mx.remoting.PendingCall;
import mx.remoting.RecordSet;
import mx.remoting.DataGlue;
import mx.utils.Delegate;
import mx.remoting.debug.NetDebug;

class WpAdmin
{
    //Change the gateway URL as needed
    var gatewayUrl:String = "http://localhost/iflashservices/gateway.php";
    var service:Service;
    var root;

    function WpAdmin(root)
    {
        this.root = root;
        init();
    }
   
    function init()
    {
        NetDebug.initialize();
        service = new Service(this.gatewayUrl, null, "WpAdmin", null, null);
       
        root.btnLogin.addEventListener("click", Delegate.create(this, handlePressLogin));
        root.btnLogin.addEventListener("enter", Delegate.create(this, handlePressLogin));
    }
   
    function handlePressLogin()
    {
        service.connection.setCredentials(root.txtUser.text, root.txtPass.text);
        attemptLogin();
    }

    //
    function attemptLogin()
    {
        var pc:PendingCall = this.service.attemptLogin();
        pc.responder = new RelayResponder(this, "handleAttemptLogin", "handleRemotingError");
    }

    function handleAttemptLogin(re:ResultEvent)
    {
        //Implement custom callback code
    }

    function handleRemotingError( fault:FaultEvent ):Void
    {
        NetDebug.trace({level:"None", message:"Error: " + fault.fault.faultstring });
    }
}
 

All very simple stuff. Ran it... Got some errors in the Apache log along the lines of 'calling function on a non-object'... After a lot of hunting around, the problem became clear: AMFPHP classes run in a sandbox. Thus if you include a file outside of the class, its variables are local, not global. But WordPress specifically uses globals for database handling, i10n, and settings. So the solution is to redeclare a bunch of variables as globals. For example, in wp-includes/wb-db.php, the last line should read:


global $wpdb;
$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);
 

The good news is this shouldn't break your regular HTML-based installation. The code as shown above works as is after taking care of globals. But what about logging out? Authenticate::logout(); ! And that's really all there is to it. Amazing! Hope the rest is just as easy (not likely).


WordPress database error: [Can't open file: 'wp_comments.MYD'. (errno: 145)]
SELECT * FROM wp_comments WHERE comment_post_ID = '77' AND comment_approved = '1' ORDER BY comment_date

No comments have been added to this post yet.

Leave a comment




Your e-mail address is never displayed. If you run into issues with SpamKarma blocking you, email me at $patrick->5etdemi(com)


RSS feed for comments on this post | TrackBack URI