XMLRPC for Actionscript 3.0 - Free Library

I just finished porting Matt Shaw's XML-RPC for Actionscript 2.0 code to AS3. This is a really easy way to get Flash to transfer data with an XML-RPC endpoint. Matt did a great job and the conversion wasn't too difficult.

Here's some sample code to show you how to use it.

import flash.events.Event;
import flash.events.ErrorEvent;
 
import com.mattism.http.xmlrpc.*;
import com.mattism.http.xmlrpc.util.*;
 
function rpcCompleteHandler(evt:Event):void
{
	var response:Object = rpc.getResponse();
}
 
function rpcErrorHandler(evt:ErrorEvent):void
{
	var fault:MethodFault = rpc.getFault();
}
 
var rpc:Connection = new ConnectionImpl('http://localhost/xmlrpc.php');
rpc.addEventListener(Event.COMPLETE, rpcCompleteHandler);
rpc.addEventListener(ErrorEvent.ERROR, rpcErrorHandler);
 
rpc.addParam(4, XMLRPCDataTypes.INT);
rpc.call('mypackage.myfunction');

Download XMLRPC for AS3

And without further ado, here are the source files:

Some notes:

If you have any questions or problems leave a comment here. Enjoy!

Comments

episoem says, "Great work."
episoem's picture

Great work.
tks;

Matt Shaw says, "I was just wondering "Do I"
Matt Shaw's picture

I was just wondering "Do I need to port my AS2 XML-RPC classes?" - I guess not! Looking forward to trying this out... Thanks!! (and thanks Google!)

Any chance you fixed some of the bugs :)

Daniel says, "Hey, thanks for the original"
Daniel's picture

Hey, thanks for the original code, Matt! Made my life a lot easier, too.

Rodrigo says, "Hello, "
Rodrigo's picture

Hello,

good work. However I made an update to allow to use structures of structures inside:

File MethodCallImpl.as, update line 143:

MemberNode.appendChild(this.createParamsNode(parameter.value[x]));

then use

var struct:Object = new Object();
struct.id = {type: XMLRPCDataTypes.INT, value:99};
struct.age = {type: XMLRPCDataTypes.INT, value:32};
struct.name = {type: XMLRPCDataTypes.STRING, value:'Homer Simpson'};
 
var addr:Object = new Object();
addr.street = {type: XMLRPCDataTypes.STRING, value:'Green'};
addr.number = {type: XMLRPCDataTypes.INT, value:56};
addr.city = {type: XMLRPCDataTypes.STRING, value:'Springfield'};
 
struct.address = {type: XMLRPCDataTypes.STRUCT, value:addr};
Andy says, "Hmm, how do I pass an array"
Andy's picture

Hmm, how do I pass an array to addParam with this? I keep getting ReferenceError: Error #1069 when I try do it like:

var myArray = [1,2]
rpc.addParam(myArray, XMLRPCDataTypes.ARRAY)

I used Peter Parente's XMLRPC library in AS2 and this was valid with:

var myArray = [1,2]
server.Call("add", myArray, listener)

Don't suppose you could port his lib could you Daniel? ;) (the interface seems tighter)

Justin says, "Andy.... I create my array"
Justin's picture

Andy....

I create my array as follows, and works cool...
var arr:Array = new Array({type: XMLRPCDataTypes.STRING, value:"test string"},{type: XMLRPCDataTypes.INT, value:5})
rpc.addParam(arr, XMLRPCDataTypes.ARRAY);

I like it because it keeps the standards nice 'n tight, the fact that you have to conform to XMLRPC standard, by casting your array elements datatypes.

Andy says, "Thank you so much Justin! I"
Andy's picture

Thank you so much Justin! I was totally missing the concept of adding type and value.

Thank you also to Matt for the original library, and Daniel for the AS3 port, great work.

Andy says, "ack, both the AS2 and AS3"
Andy's picture

ack, both the AS2 and AS3 versions wont accept zero or negative values as int parameters?

At the server end I'm getting:
{'type': 'int', 'value': '0'}

Instead of just a zero :(

Andy says, "Sorry, negatives work, zero"
Andy's picture

Sorry, negatives work, zero not.

daniel says, "About those negatives"
daniel's picture

"Sorry, negatives work, zero not."

Hey Andy. I haven't been able to address your comment because I've been out of town on business. Were you able to resolve the issue with zero values?

Andy says, "Hi Daniel, I'm afraid not,"
Andy's picture

Hi Daniel,

I'm afraid not, I've had to resort to converting all instances of 0 to 1 then converting them back on the server side :/

rpc.addParam(0, XMLRPCDataTypes.INT);
rpc.call('sendInt');

Returns at the server end: {'type': 'int', 'value': '0'}

rpc.addParam(1, XMLRPCDataTypes.INT);
rpc.call('sendInt');

Returns at the server end: 1

I've tested the xmlrpc server with a python client and it works fine with 0s from python.

Any help would be much appreciated.

Ricardo says, "I found the bug related to o and """
Ricardo's picture

I have found 2 bugs in MethodCallImp.as

private function createParamsNode( parameter:Object ):XML {
			this.debug("CreateParameterNode()");
			var Node:XML = ;
			var TypeNode:XML;
 
	// Here is the first bug
        //if the param values is 0 or "" then
			if (!parameter.value && parameter){
				parameter = {value:parameter};
			}
 
 
			if ( typeof parameter == "object") {
 
 
				// Default to 
				if (!parameter.type){
					var v:Object = parameter.value;
					if ( v is Array )
						parameter.type=XMLRPCDataTypes.ARRAY;
					else if ( v is Object )
						parameter.type=XMLRPCDataTypes.STRUCT;
					else
//Bug 2 V is an object so this is					
//unreachable code
						parameter.type=XMLRPCDataTypes.STRING;
				}

anyone knows what its the purpose of this code?
because i´m not very familiar with xmlrpc

but this is what i did to fix it

* @author	Matt Shaw 
* @url		http://sf.net/projects/xmlrpcflash
* 			http://www.osflash.org/doku.php?id=xmlrpcflash		
*
* @author   Daniel Mclaren (http://danielmclaren.net)
* @note     Updated to Actionscript 3.0
*/
 
package com.mattism.http.xmlrpc
{
	import com.mattism.http.xmlrpc.util.XMLRPCUtils;
	import com.mattism.http.xmlrpc.util.XMLRPCDataTypes;
	import com.mattism.http.xmlrpc.MethodCall;
 
	public class MethodCallImpl
	implements MethodCall
	{
 
		private var _VERSION:String = "1.0";
		private var _PRODUCT:String = "MethodCallImpl";
		private var _TRACE_LEVEL:Number = 3;	
		private var _parameters:Array;
		private var _name:String;
		private var _xml:XML;
 
		public function MethodCallImpl(){
			this.removeParams();
 
			this.debug("MethodCallImpl instance created. (v" + _VERSION + ")");
		}
 
 
		public function setName( name:String ):void {
			this._name=name;
		}
 
		public function addParam(param_value:Object,param_type:String):void {
			this.debug("MethodCallImpl.addParam("+arguments+")");
			this._parameters.push({type:param_type,value:param_value});
		}
 
		public function removeParams():void {
			this._parameters=new Array();
		}
 
		public function getXml():XML {
			this.debug("getXml()");
 
			var ParentNode:XML;
			var ChildNode:XML;
 
			// Create the ... root node
			ParentNode = ;
			this._xml = ParentNode;
 
			// Create the ... node
			ChildNode = {this._name};
			ParentNode.appendChild(ChildNode);
 
			// Create the ... node
			ChildNode = ;
			ParentNode.appendChild(ChildNode);
			ParentNode = ChildNode;
 
			// build nodes that hold all the params
			this.debug("Render(): Creating the params node.");
 
			var i:Number;		
			for (i=0; i;
				this.debug(this._parameters[i]);
				ChildNode.appendChild( this.createParamsNode(this._parameters[i]) );
				ParentNode.appendChild(ChildNode);
			}
 
			this._parameters.length=0;//to call again with a clean array
			this.debug("Render(): Resulting XML document:");
			this.debug("Render(): " + this._xml.toXMLString());
 
			return this._xml;
		}
 
 
		private function createParamsNode( parameter:Object ):XML {
			this.debug("CreateParameterNode()");
			var Node:XML = ;
			var TypeNode:XML;
 
//for the bug related to 0 numbers, false, booleans and empty strings ""
			if (!parameter.value && parameter && (!parameter.type||parameter.type==XMLRPCDataTypes.ARRAY||parameter.type==XMLRPCDataTypes.STRUCT)){
				parameter = {value:parameter};
				// Default to 
				if (!parameter.type){
					var v:Object = parameter.value;
					if ( v is String )
						parameter.type=XMLRPCDataTypes.STRING;
					else if ( v is Array )
						parameter.type=XMLRPCDataTypes.ARRAY;
					else
						parameter.type=XMLRPCDataTypes.STRUCT;
				}
			}
 
 
			if ( typeof parameter == "object") {
 
 
 
 
				// Handle Explicit Simple Objects
				if ( XMLRPCUtils.isSimpleType(parameter.type) ) {
					//cdata is really a string type with a cdata wrapper, so don't really make a 'cdata' tag
					parameter = this.fixCDATAParameter(parameter);
 
					this.debug("CreateParameterNode(): Creating object '"+parameter.value+"' as type "+parameter.type);
					TypeNode = <{parameter.type}>{parameter.value};
					Node.appendChild(TypeNode);
					return Node;
				}
				// Handle Array Objects
				if (parameter.type == XMLRPCDataTypes.ARRAY) {
					var DataNode:XML;
					this.debug("CreateParameterNode(): >> Begin Array");
					TypeNode = ;
					DataNode = ;
					//for (var i:String in parameter.value) {
					//	DataNode.appendChild(this.createParamsNode(parameter.value[i]));
					//}
					for (var i:int=0; i Begin struct");
					TypeNode = ;
					for (var x:String in parameter.value) {
						var MemberNode:XML = ;
 
						// add name node
						MemberNode.appendChild({x});
 
						// add value node
						MemberNode.appendChild({parameter.value[x]});
 
						TypeNode.appendChild(MemberNode);
					}
					this.debug("CreateParameterNode(): << End struct");
					Node.appendChild(TypeNode);
					return Node;
				}
			}
 
			return Node;
		}
 
 
		/*///////////////////////////////////////////////////////
		fixCDATAParameter()
		?:      Turns a cdata parameter into a string parameter with 
				CDATA wrapper
		IN:	    Possible CDATA parameter
		OUT:	Same parameter, CDATA'ed is necessary
		///////////////////////////////////////////////////////*/
		private function fixCDATAParameter(parameter:Object):Object{
			if (parameter.type==XMLRPCDataTypes.CDATA){
				parameter.type=XMLRPCDataTypes.STRING;
				parameter.value='';  
			}
			return parameter;
		}
 
 
		public function cleanUp():void {
			//this.removeParams();
			//this.parseXML(null);
		}
 
		private function debug(a:Object):void {
			trace(a);
		}
	}
}
daniel says, "Ricardo's bug fixes"
daniel's picture

Ricardo, thanks very much for sharing the code for the bug fixes! When I get a chance I'll test it out and add it to the download above.

Andy says, "Great news, thank you"
Andy's picture

Great news, thank you Ricardo!

Magdalena says, "Unhandled ioError"
Magdalena's picture

Hi there,

Would someone explain what the following error means?


Error #2044: Unhandled ioError:. text=Error #2032: Stream Error. URL: https://
at com.mattism.http.xmlrpc::ConnectionImpl()[\src\com\mattism\http\xmlrpc\ConnectionImpl.as:57

The code seems to be creating the raw XML request correctly, but when it tries to send the XML-RPC request, that error is spitted out.

Help anyone? :(

daniel says, "Help with ioError"
daniel's picture

Hi Magdalena,

That error occurs when there is a bad response (or no response) from the server. Looking at your error message, it seems that the URL is missing. When you call the constructor, ConnectionImpl(url:String), make sure the full URL is being passed through.

Hope that helps!

Magdalena says, "Unhandled ioError"
Magdalena's picture

Hi danielgm! :)

I've passed the full URL to the ConnectionImp constructor.

Requesting the same XML-RPC from the same domain to the same target URL works though.
So I figure it's something to do with cross-domain policy restriction.
But even after placing a cross-domain file under the target domain root directory, it still issues the same error :(

The error seems to happen when URLLoader is loading the request (I placed another event listener for IOErrorEvent.IO_ERROR)

So when "this._response.load(request);" is being executed in ConnectionImpl.as, this is the full error came out:


[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: https://[ROOT_DOMAIN]/~[USER_NAME]/cgi-bin/xmlrpc/v1/" errorID=2032]

daniel says, "Unhandled ioError"
daniel's picture

I can't say I've had this issue before but there seems to be a lot of info following the link below. Maybe that will help if you haven't found it already. (-:

http://www.judahfrangipane.com/blog/?p=87

Bruce says, "I'm currently working on a"
Bruce's picture

I'm currently working on a homework assignment that involves Flash using XML-RPC to interface with our professor's web service (So thanks to Matt and Dan so I didn't have to do this assignment in Java!) But I'm curious if the same security restrictions still apply from the AS2 to AS3 conversion.

I've everything setup the way it should be, but when I send my request I only ever receive error 'XMLRPC Fault (0):' and I'm unsure as to what's going on. Do I have to ask my prof to configure his server to allow Flash to interact with it like back in AS2?

Thanks for any help!

daniel says, "XMLRPC Fault"
daniel's picture

Hi Bruce,

I'm not sure what the error is without digging into it, but it could be the Flash player security. Might be a good idea to try the cross-domain policy file.

Good luck!

Bruce says, "Yeah, it was the lack of a policy file..."
Bruce's picture

Dan,

Yeah, it was the lack of a policy file that was causing my problem and I can now receive a response.

My new problem, however, is that the responses are all empty!

For example, when I send out a request to my prof's server to get back an Array of Strings, which succeeds, but when I try to trace the data I get empty values:

trace( response ); -> ,,,
trace( response.length ); -> 4

The length is correct, but I cannot discern why the values are all empty.

I do not know if the fact that the webService was written in Java has any bearing on the matter. Classmates have been successful with other languages (Java, Python, Javascript).

Sorry again for being a nuisance and thank you!

daniel says, "Fixing those empty responses"
daniel's picture

To figure out what's going wrong, I'd start by opening up ParserImpl.as and adding a trace statement to the parse method to make sure all the values are actually in the XML:

public function parse( xml:XML ):Object {
	trace(xml);
	if ( xml.toString().toLowerCase().indexOf('<html') >= 0 ){
		trace("WARNING: XML-RPC Response " +
			"looks like an html page.");
		return xml.toString();
	}
 
	return this._parse( xml );
}

If the response looks good, try setting the debug variable to true and see if any of the output from that helps.

Mark says, "Is this correct?"
Mark's picture

In ParserImpl:

if (node.nodeKind() == 'text') {
    return node.*;
}

Why "node.*"? The text node doesnt have children does it???

I had a problem where the _parse method was being called with the node:

<value>& lt;hello/& gt;</value>

(but without those spaces!)

So, thats an element with a single child text node.

The response object was then empty (could this be related to the problem Bruce was having?).

My desired result was:

<hello/>

So I changed the above code (I know its a hack) to:

if (node.toXMLString().indexOf("<") >= 0) {
    var textParent:Object = node.parent();
    var textString:String = textParent.toString();
    return new XML(textString);
}
else {
    return node.*;
}

}
The textParent.toString() does all the decoding for me!!!

Mark says, "Problem with the formatting"
Mark's picture

Problem with the formatting there:

if (node.toXMLString().indexOf("<") >= 0) {

The "<" should be the encoded form (i.e. [ampersand]lt;)

daniel says, "node.*"
daniel's picture

Hi Mark,

I think you're right that node.* can be replaced with node.

As for decoding the XML entities, I did some poking around and ended up writing an entire blog post on it, so check it out. It turns out that using node instead of node.* will fix the decoding problem.

Dan

daniel says, "Library Updated"
daniel's picture

The library download link above has been updated. Enjoi.

Anonymous says, "Superb! Tremendous stuff,"
Anonymous's picture

Superb! Tremendous stuff, all works a treat. Thanks very much.

One other thing - is there any way to specify a timeout?

I'm calling the eXist XML-RPC but if eXist is not running then none of the listeners are ever called after a RPC call is made.

Mark says, "I didnt need to specify a"
Mark's picture

I didnt need to specify a timeout. Instead I just listen for an IO error by adding this line:

this._response.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

to just after you instantiate the URLLoader.

Hope this helps someone.

Dee Volume says, "wordpress basic?"
Dee Volume's picture

Hi I dont suppose you would have an idiot proof usage example that refers to wordpress blogs?

I thought it would be like,
_rpc = new ConnectionImpl('http://domain/blog/xmlrpc.php');
_rpc.addEventListener(Event.COMPLETE, rpcCompleteHandler);
_rpc.addEventListener(ErrorEvent.ERROR, rpcErrorHandler);

var arr:Array = new Array({type: XMLRPCDataTypes.STRING, value:"my blog id"},{type: XMLRPCDataTypes.STRING, value:"my user name"},{type: XMLRPCDataTypes.STRING, value:"my password"},{type: XMLRPCDataTypes.INT, value:10)})
_rpc.addParam(arr, XMLRPCDataTypes.ARRAY);
_rpc.call("metaWeblog.getRecentPosts");

but a trace of the response objects reveals every single property to be undefined - something must be going right here to even have these properties, right? but im not sure what it is that's wrong - i guess it could be wordpress and not flash specific and i may be asking the wrong people, but...

eg
for(var i in response)
{
trace(i + ' : ' + response[i]);
for(var j in response[i])
{
trace(' ' + j + ' : ' + response[j]);
}
}

reveals

0 : [object Object]
link : undefined
wp_password : undefined
post_status : undefined
mt_excerpt : undefined
wp_slug : undefined
userid : undefined
postid : undefined
dateCreated : undefined
mt_keywords : undefined
title : undefined
mt_allow_comments : undefined
date_created_gmt : undefined
categories : undefined
custom_fields : undefined
mt_text_more : undefined
description : undefined
permaLink : undefined
mt_allow_pings : undefined
wp_author_id : undefined
wp_author_display_name : undefined

if you have any ideas i'd be super grateful.

d

Bannakaffalatta says, "Security sandbox violation"
Bannakaffalatta's picture

Using your code, which seemed to work beautifully for a few hours, however I came upon a security sandbox violation error. Any ideas on how I can get around this?

Steve Good says, "Error being thrown when running rpc.call()"
Steve Good's picture

Here's the error I'm getting after passing rpc.call('metaWeblog.getRecentPosts'); Error actually occurs no matter what I pass through rpc.call.

Here's the error.

TypeError: Error #1009: Cannot access a property or method of a null object reference.
at ParserImpl/parse()[\src\com\mattism\http\xmlrpc\ParserImpl.as:39]
at com.mattism.http.xmlrpc::ConnectionImpl/parseResponse()[\src\com\mattism\http\xmlrpc\ConnectionImpl.as:115]
at com.mattism.http.xmlrpc::ConnectionImpl/_onLoad()[\src\com\mattism\http\xmlrpc\ConnectionImpl.as:103]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

Any ideas?

Ray says, "Great"
Ray's picture

Thankyou very much for the port of this library to AS3.

I am successfully using it to communicate back and forth between a Drupal CMS.

Ray says, "Just to let you know"
Ray's picture

I just received this error when posting my last comment:

* warning: pg_query() [function.pg-query]: Query failed: ERROR: column "notify" of relation "dm_comments" does not exist at character 24 in /home/dmclaren/http/danielmclaren.net/includes/database.pgsql.inc on line 125.
* user warning: query: update dm_comments set notify = 1 where cid = 1223 in /home/dmclaren/http/danielmclaren.net/includes/database.pgsql.inc on line 144.

danielgm says, "Thanks!"
danielgm's picture

Thanks for the feedback, Ray. Should be fixed now...

daniel says, "Might be a bad response"
daniel's picture

Hi Steve,

My first guess would be a malformed response (combined with fairly rigid parsing). It looks like parseResponse is being called with a null value. You might try tracing the responseXML variable in ConnectionImpl at line 91 and check to see that the two following statements actually refer to an XML element.

responseXML.fault.value.*[0];
responseXML.params.param.value[0];

Good luck!

Maré says, "Works perfectly running locally but stops working when online"
Maré's picture

When running locally i connect successfully to my XML-RPC server running on mydomain.com:8080. But when i upload the movie and run it from anotherdomain.com it's stops working.

It seems to be connecting to the server. However, the servers log output is:

INFO   | jvm 1    | 2008/05/30 09:55:51 | 2008-05-30 09:55:51,360 ERROR WebServer - GET
INFO   | jvm 1    | 2008/05/30 09:55:51 | org.apache.xmlrpc.webserver.Connection$BadRequestException: GET
INFO   | jvm 1    | 2008/05/30 09:55:51 |       at org.apache.xmlrpc.webserver.Connection.getRequestConfig(Connection.java:139)
INFO   | jvm 1    | 2008/05/30 09:55:51 |       at org.apache.xmlrpc.webserver.Connection.run(Connection.java:171)
INFO   | jvm 1    | 2008/05/30 09:55:51 |       at org.apache.xmlrpc.util.ThreadPool$MyThread.runTask(ThreadPool.java:71)
INFO   | jvm 1    | 2008/05/30 09:55:51 |       at org.apache.xmlrpc.util.ThreadPool$MyThread.run(ThreadPool.java:87

This doenst happen when i run the same movie from my pc or if i run an html file with the movie embedded from my pc, any help will be much appreciated.

daniel says, "Crossdomain Files?"
daniel's picture

Not sure if a bad get request exception would result from it, but first thing that comes to mind is crossdomain policy files. Do you have these in place?

RiC says, "Http Auth"
RiC's picture

I wonder, is there any way to use xmlrpc calls to protected area ?
My weba pplication use Basic Auth, when I try to pass l/p via http string it fails. (e.g. https://login:pass@some.u.rl/

Thanks in advance.

Herberth Amaral says, "Where is the documentation?"
Herberth Amaral's picture

I couldn't find the documentation of this project, even in the author's page.
Do anyone can post a link with useful information about this lib?
[I'am sorry for any english mistake =]

pugans says, "as 2 file upload"
pugans's picture

hello i am using as2 and the not new classes. how do i add a parameter whose datatype is file? im using the file reference class and i would like to send it via addParam function.

Herberth says, "An example"
Herberth's picture

I need only an example showing how I can get information from the returned object. I am a newbie in AS and I don't have any idea how the library works (XML-RPC is not problem for me. I have coded a XML-RPC server and client in PHP without problems). I tried to read the source code, without sucess.

Can you post only a example of that involves interpretation of the returned data?

Hawk says, "Does the zip file contain"
Hawk's picture

Does the zip file contain the latest code, Flash is giving me a lot of errors (99) such as...

A type identifier is expected after the ':'.

Rommel Delima says, "Hi, Just wondering if"
Rommel Delima's picture

Hi,

Just wondering if Ricardo's bug fixes are implemented with the current download of the xml-rpc for AS3.

Thanks,
Rommel

sondod says, "Some struct stuff"
sondod's picture

So I was having passing struct's as they were getting sent as objects instead of xml nodes. So I changed line 164 in MethodCallImpl to the following:

var MemTypeNode:XML = <{parameter.value[x].type}>{parameter.value[x].value};
MemberNode.appendChild(MemTypeNode)
Twanneman says, "Wordpress Class Files"
Twanneman's picture

I've ported the three wordpress files found in the original library.
Still testing, but seems to work :)

1) Wordpress.as

/**
 * @author		Matt Shaw <matt AT mattism. DOT com>
 * @description	WordPress.as
 * @see			http://www.xmlrpc.com/metaWeblogApi
 * 				http://www.sixapart.com/movabletype/docs/mtmanual_programmatic.html
 *  
 *  metaWeblog.newPost (blogid, username, password, struct, publish) returns string
 *  metaWeblog.editPost (postid, username, password, struct, publish) returns true
 *	metaWeblog.getPost (postid, username, password) returns struct
 *	metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts)
 * 
 *	@requires	http://xmlrpcflash.mattism.com
 */
package com.mattism.http.wordpress
{
	import flash.events.Event;
	import flash.events.ErrorEvent;
	import com.mattism.http.xmlrpc.*;
	import com.mattism.http.xmlrpc.util.*;
 
	public class WordPress {
		public var rpc:Connection;
		public var SERVICE_URL:String;
 
		public var blog_id:String;
		public var username:String;
		public var password:String;
 
		public var response:Object;
		public var fault:MethodFault;
 
		private var METHOD_NEW_POST:String = "metaWeblog.newPost";
		private var METHOD_GET_POST:String = "metaWeblog.getPost";
		private var METHOD_EDIT_POST:String = "metaWeblog.editPost";
		private var METHOD_GET_RECENT_POSTS:String = "metaWeblog.getRecentPosts";	
		private var METHOD_GET_CATEGORIES:String = "metaWeblog.getCategories";	
 
		// Return post ID
		public function newPost(title:String, content:String):void { 
			var args:Array = [
								[blog_id, XMLRPCDataTypes.STRING],
								[username, XMLRPCDataTypes.STRING],
								[password, XMLRPCDataTypes.STRING],
								[{ title:title, description: content }, XMLRPCDataTypes.STRUCT],
								[true,XMLRPCDataTypes.BOOLEAN]
							];
			_wpCall(METHOD_NEW_POST,args);
		}
 
		public function editPost(post_id:Number,title:String, content:String):void {
			var args:Array = [
								//[blog_id, XMLRPCDataTypes.STRING],
								[post_id, XMLRPCDataTypes.STRING],
								[username, XMLRPCDataTypes.STRING],
								[password, XMLRPCDataTypes.STRING],
								[{ title:title, description: content }, XMLRPCDataTypes.STRUCT],
								[true,XMLRPCDataTypes.BOOLEAN]
							];
			_wpCall(METHOD_EDIT_POST,args);
		}
 
		public function getPost(post_id:Number):void {
			var args:Array = [
								[blog_id, XMLRPCDataTypes.STRING],
								[post_id, XMLRPCDataTypes.STRING],
								[username, XMLRPCDataTypes.STRING],
								[password, XMLRPCDataTypes.STRING]
							];
			_wpCall(METHOD_GET_POST,args);
		}
 
		public function getRecentPosts( post_count:Number ):void {
			var args:Array =  [
								[blog_id, XMLRPCDataTypes.STRING],
								[username, XMLRPCDataTypes.STRING],
								[password, XMLRPCDataTypes.STRING],
								[post_count, XMLRPCDataTypes.INT]
							];
			_wpCall(METHOD_GET_RECENT_POSTS,args);		
		}
 
		public function getCategories( category_count:Number ):void {
			var args:Array =  [
								[blog_id, XMLRPCDataTypes.STRING],
								[username, XMLRPCDataTypes.STRING],
								[password, XMLRPCDataTypes.STRING],
								[category_count, XMLRPCDataTypes.INT]
							];
			_wpCall(METHOD_GET_CATEGORIES,args);		
		}
 
		private function _wpCall(method:String, args:Array):void {
			rpc = new ConnectionImpl(SERVICE_URL);
			rpc.addEventListener(Event.COMPLETE, rpcCompleteHandler);
			rpc.addEventListener(ErrorEvent.ERROR, rpcErrorHandler);
 
			var i:Number; 
			for (i=0; i<args.length; i++) {
				rpc.addParam(args[i][0], args[i][1]);
			}
			rpc.call(method);
		} 
		private function rpcCompleteHandler(evt:Event):void { response = rpc.getResponse();}
		private function rpcErrorHandler(evt:ErrorEvent):void { fault = rpc.getFault(); }
	}
}
Twanneman says, "Wordpress Class Files"
Twanneman's picture

2) WordPressPost.as

/**
 * @author		Matt Shaw 
 * @description	WpPost.as
 * 				
 * Quick and dirty for now
 */
package com.mattism.http.wordpress 
{
	public class WordPressPost
	{
		public var mt_allow_pings:Number;
		public var mt_allow_comments:Number;
		public var mt_text_more:String;
		public var mt_excerpt:String;
		public var categories:Array;
		public var permaLink:String;
		public var link:String;
		public var title:String;
		public var description:String;
		public var postid:Number;
		public var userid:Number;
		public var dateCreated:Date;
 
		public function WordPressPost( data:Object ) {
			for (var key:String in data ){
				trace(key + " = " + data[key]);
				this[key]=data[key];
			}
		}
	}
}
Twanneman says, "Wordpress Class Files"
Twanneman's picture

WordpressCategories.as

/**
 * @author		Matt Shaw 
 * @description	WpCats.as
 * 				
 * Quick and dirty for now
 */
package com.mattism.http.wordpress
{
	public class WordPressCategories 
	{
		public var categoryId:Number;
		public var parentId:Number;
		public var description:String;
		public var categoryName:String;
		public var htmlUrl:String;
		public var rssUrl:String;
 
		public function WordPressCategories( data:Object ) {
			for (var key:String in data ){
				trace(key + " = " + data[key]);
				this[key]=data[key];
			}
		}
	}
}
daniel says, "Wordpress Class Files... Thanks!"
daniel's picture

Hi Twanneman,

Thanks for the wordpress class file code-listings. Much-appreciated!

Daniel

Mário Santos says, "Wordpress XML-RPC API"
Mário Santos's picture

Hi Daniel!!

Thanks for the AS3 update version.

I was making that ("dirty") job also a few months ago, but because i did not have much free time i stopped.

I've been developping a simple API for Wordpress XML-RPC methods, i'm just finished to make all the codding work! :)

Sonner will be availiable for download.

The current methods supported are:

catLister.as -> Lists all categories in the blog.
insertCat.as -> Inserts a new category
deleteCat.as -> Deletes a category
insertPage.as -> Insert a new page.
deletePage.as -> Delete a page from blog
editPage.as -> Update a page with new changes
insertPost.as -> Inserts a new post
deletePost.as -> Deletes a post
editPost.as -> Update a post with new changes
getRecentPosts.as -> Get last posts (defined "how many posts")
getPages.as -> Get all blog pages
getAuthors.as -> Get authors/user in blog
getOptions.as -> Get blog seetings
uploadFile.as -> Send binary / image file to blog

That's it, gave me a few days to figure out some output from xml-rpc but the work is done! Probably the API will work also on other blogs platforms that use XML-RPC.

The API uses your classes, so the credits will be granted to you also!

When i release the API i'll notify you! For the moment i'm testing a smal AIR app to make sure all works.

Best Regards from Portugal! :)

Anonymous says, "ricardos fix"
Anonymous's picture

i tried to copy and paste ricardo's bug fix from above, but the browser is processing the markup and the code is all worng. How can i get that fix in properly and does it address the original mishandling of '"' when sending over a String?
Thanks very much

Post new comment

The content of this field is kept private and will not be shown publicly.
If you have a Gravatar account, used to display your avatar.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • You can enable syntax highlighting of source code with the following tags: <code>. Beside the tag style "<foo>" it is also possible to use "[foo]".
  • Lines and paragraphs break automatically.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options

About

Daniel McLaren

Daniel is a Flash and Flex developer specializing in the art of information visualization.

Latest from SketchyD

Latest Drawing from SketchyD

This is the most recent drawing from my mobile sketch blog, SketchyD.com.

Recent comments