De volledige flash source code van de drupal tutorials uit wdm 34 en wdm 36 zijn hier te downloaden.
Voor meer informatie over de dpdk actionscript library en drupal kun je terecht op www.dpdk.nl/opensource.
een eerdere presentatie van dpdk over drupal en flash op het adobe user group xl event is te vinden op augxl.dpdk.nl
You are missing some Flash content that should appear here! Perhaps your browser cannot display it, or maybe it did not initialize correctly.
package nl.webdesignermagazine {
import flash.events.MouseEvent;
import fl.controls.TextInput;
import fl.controls.Button;
import fl.controls.DataGrid;
import nl.dpdk.utils.ColorCalculations;
import nl.dpdk.utils.URLUtils;
import fl.controls.TextArea;
import fl.events.ListEvent;
import nl.dpdk.services.gephyr.DrupalData;
import nl.dpdk.services.gephyr.DrupalProxy;
import nl.dpdk.services.gephyr.DrupalUtils;
import flash.display.MovieClip;
/** * authenticatie, custom modules, cck, views * login, node.save, extra parameters voor nodes ophalen met minder data * */public class DrupalAdvancedDemo extends MovieClip {
private var proxy : DrupalProxy;
// alle assets die op de flash stage staan / de main timelinepublic var output_txt : TextArea;
public var data_grid : DataGrid;
public var save_btn : Button;
public var title_txt : TextInput;
public var body_txt : TextInput;
public var url_txt : TextInput;
public function DrupalAdvancedDemo() {
trace("DrupalAdvancedDemo.DrupalAdvancedDemo()");
// maak een instantie aan van de DrupalProxy en configureer deze met de url naar de drupal services voor amfphpproxy = new DrupalProxy("http://webdesignermagazine.dpdk.nl/services/amfphp", DrupalProxy.VERSION_6);
// we hebben de sessies en authenticatie niet aangezet, dit kun je zelf uitproberen op je eigen site. // proxy = new DrupalProxy("http://webdesignermagazine.dpdk.nl/services/amfphp", DrupalProxy.VERSION_6 true, "67021648cdcc96b7a40557381b927ef2", "webdesignermagazine.dpdk.nl"); // zet de globale error handler. De functie onDrupalError wordt aangeroepen als er errors op treden die niet op remote functie aanroep niveau plaatsvinden.proxy.setErrorHandler(onDrupalError);
/* * maak voor iedere methode die we op de drupal installatie aanroepen een functie die het resultaat afhandelt en een functie die een fout afhandelt * omdat we met sessies werken moeten we eerst een anonieme sessie Id krijgen en moeten we system.connect als eerste aanroepen. * */proxy.setHandler("node", "get", onNodeGetResult, onNodeGetStatus);
proxy.setHandler("node", "save", onNodeSaveResult, onNodeSaveStatus);
proxy.setHandler("views", "get", onViewsGetResult, onViewsGetStatus);
proxy.setHandler("system", "connect", onSystemConnectResult, onSystemConnectStatus);
proxy.setHandler("wdm", "test", onWdmTestResult, onWdmTestStatus);
/* * we configureren de dataGrid flash component hieronder. Dit is een van de standaard flash as3 componenten, meer info kun je vinden in de flash help * We detecteren de klik op een rij uit de lijst van de datagrid * We detecteren de rollover op een rij uit de lijst van de datagrid * We definieren ook de kolomnamen, deze namen gebruiken we ook om data op de juiste plek te krijgen */data_grid.addEventListener(ListEvent.ITEM_CLICK, onDataGridItemClicked);
data_grid.addEventListener(ListEvent.ITEM_ROLL_OVER, onDataGridItemOver);
data_grid.columns = ["nid", "title", "url"];
data_grid.getColumnAt(0).width = 30;
data_grid.getColumnAt(1).width = 200;
save_btn.addEventListener(MouseEvent.CLICK, onSave);
// roep system.connect aan om een sessie Id te krijgen en laat het de gebruiker weten dat we data ophalenproxy.invoke("system", "connect");
output("system.connect, ophalen session ID...");
} /** * de functie die uitgevoerd wordt als we succesvol 'system.connect' hebben aangeroepen. * Vanuit hier gaat ook de sequentie van het ophalen van data door, aangezien dit de eerste "verplichte" call is. */private function onSystemConnectResult(data : DrupalData) : void {
// we hebben nu een geldig sessie ID, deze is bij een gelukte call naar system.connect automatisch opgeslagen op de proxy. // en zal automatisch gebruikt worden bij de verdere communicatie met drupal.output("onSystemConnectResult() session ID: " + proxy.getSessionId());
// we gaan door met het ophalen van data van een view. De view heet 'downloads' en we roepen 'views.get' aan.proxy.invoke("views", "get", "downloads");
// we roepen ook meteen de wdm.test methode aan, die uit onze custom module komtproxy.invoke("wdm", "test", "dit is de tekst uit flash om de wdm service te testen");
// geef wat informatie aan de eindgebruiker over wat hem te wachten staat.output("ga over de rijen in het grid om meer informatie te verkrijgen over het item. Alle informatie komt uit de view 'downloads' vanuit drupal.");
} /** * de functie die uitgevoerd wordt als we niet succesvol 'system.connect' hebben aangeroepen */private function onSystemConnectStatus(data : DrupalData) : void {
// er is iets mis, laat het de gebruiker weten. Tevens zal er hierna dan niets meer gebeuren aangezien we geen verdere calls naar drupal doenoutput("onSystemConnectStatus(): " + data.getMessage(), "#ff0000");
} /** * de functie die uitgevoerd wordt als we succesvol 'wdm.test' hebben aangeroepen. */private function onWdmTestResult(data : DrupalData) : void {
output("onWdmTestResult(): " + data.getData(), "#0000ff");
} /** * de functie die uitgevoerd wordt als we niet succesvol 'wdm.test' hebben aangeroepen */private function onWdmTestStatus(data : DrupalData) : void {
output("onWdmTestStatus(): " + data.getMessage(), "#ff0000");
} /** * de functie die uitgevoerd wordt als we succesvol 'views.get' hebben aangeroepen */private function onViewsGetResult(data : DrupalData) : void {
output("onViewsGetResult()");
// het resultaat van de call gaan we manipuleren om in de datagrid te zetten // haal de specifieke data op uit het drupaldata objectvar result : * = data.getData();
//de variabele die we alvast declareren voor het gebruik in de loop zometeen om de data van een rij uit het resultaat op te slaan.var row : Object;
// als er al data in het grid stond, haal het dan wegdata_grid.removeAll();
// loop over alle rijen van het resultaat heen, de view geeft een array van data terug met node data (in een ander formaat dan wanneer je een enkele node ophaalt)for (var i : int = 0;i < result.length;++i) {
row = result[i];
// voeg aan het datagrid nu een object toe met data. // alle object properties die dezelfde naam hebben als de kolomnamen die we eerder hebben gemaakt, kunnen we zien in de desbetreffende kolommen. // alle object props die niet dezelfde naam hebben, zien we niet. Deze kunnen we straks wel gebruiken als we de data weer ophalen/nodig hebben //let vooral even op de benaming die de view heeft gegeven aan de url. deze geeft de oorsprong aan van het veld via een naamgevingsconventievar item : Object = {nid:row.nid, title:row.node_title, url:row.node_data_field_url_field_url_value, body:row.node_revisions_body};
data_grid.addItem(item);
} } /** * de functie die uitgevoerd wordt als we niet succesvol 'views.get' hebben aangeroepen */private function onViewsGetStatus(data : DrupalData) : void {
output("onViewsGetStatus(): " + data.getMessage(), "#ff0000");
} /** * de event listener voor het drukken op de 'save' knop. * We gaan hier proberen een node van het type 'download' op te slaan */private function onSave(event : MouseEvent) : void {
// eerst kijken we of alle data min of meer goed ingevuld is...if (title_txt.text == "" || body_txt.text == "" || url_txt.text == "" || title_txt.text == "title" || body_txt.text == "body" || url_txt.text == "url") {
output("Een van de velden is niet goed ingevuld", "#ff0000");
return;
} // ja, goed ingevuld, maak een nieuwe node aan // een nieuwe node is een standaard object, met minimaal de properties 'type', 'title', 'body', 'created' en 'nid'. // we gebruiken hiervoor een makkelijke functie uit de DrupalUtils class. nid 0 betekent dat we een nieuwe node aanmakenvar node : * = DrupalUtils.createNode("download", title_txt.text, body_txt.text, 0);
// omdat we met de content construction kit (cck) een nieuwe type node hebben gemaakt ('download'), // heeft de cck voor ons een nieuwe property aangemaakt, namelijk een array met de naam field_url (cck property naam). // cck maakt hier altijd arrays van, en we zullen ons voor het opslaan van de node hieraan moeten conformeren. // hoe de datastructuur van de node met type download eruit ziet kun je zien bij de services tester van drupal door enkel de node op te halen (views geeft namelijk een andere 'kijk' op de data)node.field_url = new Array();
node.field_url[0] = new Array();
node.field_url[0].value = url_txt.text;
// roep de service method aan, met als argument het node object dat we zojuist hebben gemaakt. // als nid 0 is dan sla je een nieuwe node op en anders overschrijf je een bestaande node (als je de permissies daarvoor hebt)proxy.invoke("node", "save", node);
} /** * de functie die uitgevoerd wordt als we succesvol 'node.save' hebben aangeroepen */private function onNodeSaveResult(data : DrupalData) : void {
// succes, de node van type 'download' is opgeslagen // haal dan nu de view data opnieuw op zodat we de grid kunnen vullen met de nieuwe node erbij.proxy.invoke("views", "get", "downloads");
// de velden maken we weer even leeg.title_txt.text = body_txt.text = url_txt.text = "";
} /** * de functie die uitgevoerd wordt als we een fout bij 'node.save' hebben aangeroepen */private function onNodeSaveStatus(data : DrupalData) : void {
output("onNodeSaveStatus(): " + data.getMessage(), "#ff0000");
} /** * event handler voor als we over een kolom uit het datagrid gaan */private function onDataGridItemOver(event : ListEvent) : void {
// dit is het data item dat hoort bij de specifieke rij waar we overheen gaan met onze muisvar item : * = event.item;
// maak een random kleur aan voor de displayvar textColor : String = "#" + ColorCalculations.getHexValue(Math.random() * 0xffffff);
// geef de tekst weer die behoort bij de beschrijving van de rij waar we overheen rollen // dit is de body tekst van de Drupal Node met type "Download" // 'body' is de naam die we zelf gegeven hebben aan de body data toen het binnenkwam bij views.getoutput(item.body, textColor);
} /** * event handler voor als we op een kolom uit het datagrid klikken */private function onDataGridItemClicked(event : ListEvent) : void {
// dit is het data item dat hoort bij de specifieke rij waar we op klikken gaan met onze muisvar item : * = event.item;
// alle properties die wij in het datagrid hebben gezet kunnen we weer uitlezentrace(item.nid);
trace(item.title);
trace(item.url);
trace(item.body);
// we gaan naar de url (download url)URLUtils.getURL(item.url);
} /** * Methode die het resultaat afhandelt van succesvolle calls naar "node.get" * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onNodeGetResult(data : DrupalData) : void {
// het DrupalData object heeft een methode die de resultaat data ophaalt uit het object.var result : * = data.getData();
// output de volledige node, geformatteerd met print_routput(DrupalUtils.print_r(result, "nodeGetResult"), "#ff9900");
/* * het interessante aan node data is dat we ieder veld van het node object apart kunnen benaderen (ook van nodes gemaakt met de cck, content construction kit) * Deze data kunnen we op allerlei manieren gebruiken in onze flash file * afhankelijk van het type van de node en de opbouw hiervan kunnen nodes andere velden hebben. */output("body: " + result.body, "#027acc");
output("node id: " + result.nid, "#000000");
output("type: " + result.type, "#027acc");
output("title: " + result.title, "#000000");
if (result.type == "download") {
output("download: " + result.field_url[0].value, "#027acc");
} } /** * Methode die de status/error afvangt in het geval deze optreedt bij het aanroepen van "node.get" * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onNodeGetStatus(data : DrupalData) : void {
// het DrupalData object heeft een methode die in geval van een error de boodschap van deze error teruggeeftoutput(data.getMessage(), "ff9900");
} /** * de methode die generieke errors afvangt * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onDrupalError(data : DrupalData) : void {
output(data.getMessage(), "#ff0000");
} /** * een helper methode die een boodschap aan de gebruiker toont * @param message de boodschap die we willen tonen aan de gebruiker * @param color de html kleur (formaat #rrggbb) die we aan de boodschap willen geven */private function output(message : String, color : String = "#11111") : void {
// strip de \r uit de boodschap, zodat we geen dubbele line breaks (\r\n) krijgenmessage = message.replace(/\r/g, "");
// vervang html karakters, zodat deze niet geinterpreteerd worden door het html tekst veld in flashmessage = message.replace(/\</g, "<");
message = message.replace(/\>/g, ">");
output_txt.htmlText = '<font color="' + color + '">' + message + '</font><br />' + output_txt.htmlText;
} }}</actionscript>
You are missing some Flash content that should appear here! Perhaps your browser cannot display it, or maybe it did not initialize correctly.
package nl.webdesignermagazine {
import nl.dpdk.services.gephyr.DrupalData;
import nl.dpdk.services.gephyr.DrupalProxy;
import nl.dpdk.services.gephyr.DrupalUtils;
import flash.display.MovieClip;
/** * Deze "document class", gekoppeld aan de flash movie, bevat de code voor de basic drupal demo voor webdesignermagazine.nl * zie de .fla file drupal_basic_demo.fla * Ten tijde van schrijven (februari 2011) is er nog geen goed werkende module voor Drupal 7 en services/amf integratie. * Deze demo is dan ook enkel geschikt voor Drupal 6. * * * * @author Rolf Vreijdenberger <rolf@dpdk.nl> */public class DrupalBasicDemo extends MovieClip {
// een referentie naar de DrupalProxyprivate var proxy : DrupalProxy;
// we declareren deze variabele hier om het mogelijk te maken om het tekstveld van de fl package toegangkelijk te maken door eclipse/fdt (flash programmeer tool/IDE)public var output_txt : *;
public function DrupalBasicDemo() {
trace("DrupalBasicDemo.DrupalBasicDemo()");
// maak een instantie aan van de DrupalProxy en configureer deze met de url naar de drupal services voor amfphpproxy = new DrupalProxy("http://webdesignermagazine.dpdk.nl/services/amfphp");
// zet de globale error handler. De functie onDrupalError wordt aangeroepen als er errors op treden die niet op remote functie aanroep niveau plaatsvinden.proxy.setErrorHandler(onDrupalError);
/* * maak voor iedere methode die we op de drupal installatie aanroepen een functie die het resultaat afhandelt en een functie die een fout afhandelt * In dit geval doen we dit om de data van een drupal node op te halen via "node.get" * */proxy.setHandler("node", "get", onNodeGetResult, onNodeGetStatus);
// roep via de DrupalProxy een methode aan op het drupal cms. de "node.get" aanroep krijgt een extra argument mee met het id van de node die we willen hebben.proxy.invoke("node", "get", 1);
// de node met id 2 is de node waarin deze flash file staat. //proxy.invoke("node", "get", 2);output("data wordt opgehaald...");
} /** * Methode die het resultaat afhandelt van succesvolle calls naar "node.get" * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onNodeGetResult(data : DrupalData) : void {
// het DrupalData object heeft een methode die de resultaat data ophaalt uit het object.var result : * = data.getData();
// output de volledige node, geformatteerd met print_routput(DrupalUtils.print_r(result, "nodeGetResult"), "#ff9900");
/* * het interessante aan node data is dat we ieder veld van het node object apart kunnen benaderen (ook van nodes gemaakt met de cck, content construction kit) * Deze data kunnen we op allerlei manieren gebruiken in onze flash file * afhankelijk van het type van de node en de opbouw hiervan kunnen nodes andere velden hebben. */output("body: " + result.body, "#027acc");
output("node id: " + result.nid, "#000000");
output("type: " + result.type, "#027acc");
output("title: " + result.title, "#000000");
} /** * Methode die de status/error afvangt in het geval deze optreedt bij het aanroepen van "node.get" * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onNodeGetStatus(data : DrupalData) : void {
// het DrupalData object heeft een methode die in geval van een error de boodschap van deze error teruggeeftoutput(data.getMessage(), "ff9900");
} /** * de methode die generieke errors afvangt * @param data DrupalData een DrupalData object dat automatisch wordt meegegeven door de DrupalProxy */private function onDrupalError(data : DrupalData) : void {
output(data.getMessage(), "#ff0000");
} /** * een helper methode die een boodschap aan de gebruiker toont * @param message de boodschap die we willen tonen aan de gebruiker * @param color de html kleur (formaat #rrggbb) die we aan de boodschap willen geven */private function output(message : String, color : String = "#11111") : void {
// strip de \r uit de boodschap, zodat we geen dubbele line breaks (\r\n) krijgenmessage = message.replace(/\r/g, "");
// vervang html karakters, zodat deze niet geinterpreteerd worden door het html tekst veld in flashmessage = message.replace(/\</g, "<");
message = message.replace(/\>/g, ">");
output_txt.htmlText = '<font color="' + color + '">' + message + '</font><br />' + output_txt.htmlText;
} }}