now.. we go to flash. The first class is the DataConnector which establishes the connection to the AMF/PHP connector and calls the function
we declare a variable called callTitle which is assigned based on which function we’re calling. this variable is then used to decide what action to do in the event listener.
package data
{
import events.Communicator;
import flash.events.*;
import flash.net.NetConnection;
import flash.net.Responder;
public class DataConnector extends EventDispatcher
{
private var gateway :String ;
private var callTitle :String = "";
private var connection :NetConnection;
private var responder :Responder;
public function DataConnector()
{
gateway = "./connectors/gateway.php";
responder = new Responder(onResult, onFault);
connection = new NetConnection;
connection.connect(gateway);
}
public function getCategoryList(parentCatName:String = ""):void
{
callTitle = "getCategoryList";
parentCategory = parentCatName;
connection.call("functions.getCategoryList", responder , parentCatName);
}
public function getCategoryPosts(_catName:String = ""):void
{
callTitle = "getCategoryPosts";
catName = _catName;
connection.call("functions.getCategoryPosts", responder , catName);
}
public function getPostList():void
{
callTitle = "getPostList";
connection.call("functions.getPostList", responder);
}
public function getPost(id:String):void
{
callTitle = "getPost";
postID = id;
connection.call("functions.getPost", responder , postID);
}
private function onResult(result:Object):void
{
switch (callTitle)
{
case "getCategoryList":
result = result as Array;
var _cat:Array = new Array();
for (var i:int=0; i <result.length; i++)
{
var _obj:Object = new Object();
_obj.id = result[i].id ;
_obj.title = result[i].title ;
_obj.desc = result[i].description;
cat.push(obj)
}
// now do something with that array
break;
case "getPostList":
result = result as Array;
var _cat:Array = new Array();
for (var i:int=0; i<result.length; i++)
{
var _obj:Object = new Object();
_obj.id = result[i].id ;
_obj.title = result[i].title ;
cat.push(obj)
}
// now do something with that array
break;
case "getCategoryPosts":
result = result as Array;
var _cat:Array = new Array();
for (var i:int=0; i<result.length; i++)
{
var _obj:Object = new Object();
_obj.index= result[i].index ;
_obj.id = result[i].id ;
_obj.title = result[i].title ;
cat.push(obj)
}
// now do something with that array
break;
case "getPost":
result = result as Object;
// do something with the object
// like trace(result.post.title) , trace(result.post.content) , trace(result.post.date)
// and:
// for (var i:int=0; i< result.meta.length; i++)
// {
// trace(result.meta[i].index , " : " , result.meta[i].value);
// }
break;
}
}
private function onFault(fault:Object):void
{
trace(String(fault.description));
}
}
}
This class can now be called from the parent class (Main for example) in the following fashion:
package
{
import data.DataConnector;
import flash.display.Sprite;
import flash.events.*;
public class Main extends Sprite
{
private var _dataConnector
ataConnector;
public function Main()
{
_dataConnector = new DataConnector();
_dataConnector.getCategoryList("cat1");
}
}
}
the way I usually do its is follow this sequence:
Main -> DataConnector -> call Function
DataConnector ->receive Call result and handle Data
DataConnector -> Dispatch Event with the handled Data
Main -> receive the event in an event listener -> use the data.
but again, this sequence is very dependant on the structure of your classes and projects.. so now you’re on your own…
hope this was helpful enough
]]>a big credit is due to Tim Wilson on his library which was the basis of all the work I have done in here. I only changed the return types of the functions to be of custom data types instead of XML.
steps of reproduction:
1- download the AMFPHP package from http://sourceforge.net/project/showfiles.php?group_id=72483#files
2- unzip the package in your flash export folder (WWW for example, or DEPLOY, or whatever you call it).. put all the AMF files inside a folder and name it as you wish (I am going to call it connectors for example
3- in services/DatabaseRequest.php fill in your appropriate username/password/db name and hostname
4-go to services/functions.php and write your functions there.. I am using these functions:
function getPostList()
{
$dbc = new DatabaseRequest();
$db_query = $dbc->call("SELECT * FROM wp_posts WHERE post_status='publish' AND post_type !='page' ORDER BY ID DESC");
$posts = array();
$i =0;
while ($fields = mysql_fetch_array($db_query))
{
$posts[$i] = array(id=>$fields['ID'] , title => $fields['post_title']);
$i ++;
}
return $posts;
}
and
function getCategoryList($parentCategorySlug)
{
$dbc = new DatabaseRequest();
$query = "SELECT wp_terms.slug, wp_terms.name, wp_term_taxonomy.description FROM wp_terms, wp_term_taxonomy WHERE wp_terms.term_id = wp_term_taxonomy.term_id AND wp_term_taxonomy.taxonomy = 'category'".
(($parentCategorySlug != "") ? "AND wp_term_taxonomy.parent IN ( SELECT term_id FROM wp_terms WHERE wp_terms.slug LIKE '".$parentCategorySlug."')" : "") ;
$db_query = $dbc->call($query);
$arr = array();
$i=0;
while ($fields = mysql_fetch_array($db_query))
{
$arr[$i] = array(title =>$fields['name'] , id => $fields['slug'] , description=>$fields['description']);
$i ++;
}
return $arr;
}
and
function getCategoryPosts($categorySlug)
{
$dbc = new DatabaseRequest();
$db_query = $dbc->call("SELECT * FROM wp_posts
LEFT JOIN wp_term_relationships ON ( wp_posts.ID = wp_term_relationships.object_id )
LEFT JOIN wp_term_taxonomy ON ( wp_term_relationships.term_taxonomy_id = wp_term_taxonomy.term_taxonomy_id )
WHERE wp_posts.post_status = 'publish' AND wp_term_taxonomy.taxonomy = 'category' AND wp_term_taxonomy.term_id in
(SELECT term_id FROM wp_terms WHERE wp_terms.slug LIKE '".$categorySlug."')" );
$posts = array();
$i =0;
while ($fields = mysql_fetch_array($db_query))
{
$indexQuery = "SELECT meta_value FROM wp_postmeta WHERE post_id =".$fields['ID']." AND meta_key LIKE 'index'";
$db_query1 = $dbc->call($indexQuery );
$index = mysql_fetch_array($db_query1);
$posts[$i] = array(index => $index[0] , id => $fields['ID'] , title =>$fields['post_title']);
$i++;
}
return $posts;
}
and
function getPost($postID)
{
$dbc = new DatabaseRequest();
$query ="
SELECT * FROM wp_posts WHERE wp_posts.ID=".$postID." AND wp_posts.post_status = 'publish'";
$db_query = $dbc->call($query);
$fields = mysql_fetch_array($db_query);
$post = $fields[0];
$arr=array();
if(count($fields) == 1)
{
createFailMessage('Post Not Found');
}
else
{
$post = array( id=> $fields['ID'] ,
title=>$fields['post_title'] ,
content => $fields['post_content'] ,
date=> $fields['post_modified_gmt']
);
// Get any Custom Fields for this Post.
$additionalFields = $dbc->call("SELECT * FROM wp_postmeta WHERE post_id='".$fields['ID']."';");
$extrFields = array();
$j=0;
while ($customField = mysql_fetch_array($additionalFields))
{
$extrFields[$j] = array(
index => $customField['meta_key'],
value => $customField['meta_value']
);
$j++;
}
$result = array(post => $post , meta =>$extrFields);
return $result;
}
the beauty of AMF/PHP is that you can get returns in the form of objects, arrays, multidimensional arrays, and objects that has properties that are a mix of arrays and regular data types..
so now, we have all the PHP functions that need to be called in order to get data from the Database… notice that in the getPost function, I am also returning the meta fields associated with the post, based on that post ID.
the flash part of that communication will be in part 2 of this post
]]>as any other flash programmer would do, we try to use everything we know in remaking our website, which eventually leaves us stuck not doing anything cos we try to integrate everything at the same time
so I decided to go with the Backend CMS option (not that I have regularly updated content or anything) but more for the search engine optimisation reasons. so I decided to go with the natural solution of using wordpress as a backend, and connecto to its database using something…. and that “something” became a whole week work of research..
turns out that, as popular wordpress is, there is no out-of-the-box solution (open source of course) that you can use to connect to it.
the closest found was Tim Wilson‘s Press Connect . which provides a very nice connection, only the only way I found to use it was through AS2 with the XML.sendAndLoad() interface.. and that of course does not work if you are planning to use AS3
so I decided to take the plunge and write my own connectors, basing my self on Tim Wilson’s code, and use AMFPHP to be the middle man. production started officially last thursday, and I am hoping that by the end of the weekend I will have most of my connectors ready for use.. and will probably share it on my blog for those who need some help doing what I am trying to do..
so, stay tuned…
]]>