ColdFusion Thoughts from a Longtime PHP developer

Serge Jespers is a colleague of mine on the Platform Evangelism team. He’s a longtime PHP developer and has recently dipped his toes into the ColdFusion waters. He recently developed the MAX widget that’s been going around. In fact, he used ColdFusion to power it. Here are his thoughts on the matter:

…I’m fairly new to ColdFusion. I actually first touched CF about a year a go on the On AIR Train Tour through Europe. That was the first time I played around with CF after oh… some 10 years of working with PHP. I looked at CF a few years ago and never really took another serious look at it. I’m sure there are many of you out there in the same situation and I would like to invite you to take another look at ColdFusion. CF has changed and matured a lot since the early days and is just a breeze to work with. With a minimum amount of code, I was able to rapidly code my database calls for the widget. Another cool thing about ColdFusion is that once you write your database code, you can use it in a number of different ways. You can directly call the methods using Flash Remoting in your Flex application, call it as a webservice from a mobile Flash application and/or call it from an HTML page without changing anything in the original code. I surely was pretty impressed when I saw that the first time. If you’re a long time PHP user and want to know more about ColdFusion, I’d like to invite you to my session at MAX. I’m going to talk about the difference and similarities between PHP and CF and also talk about what CF can do right out of the box….

If you want to find out more about his experience with the widget, check out the rest of the article.

ColdFusion Builder Extension Test Creator

When I build or debug ColdFusion Builder Extensions I typically do the following:

  • Alter the extension code to write IDE post contents to file
  • Call extension in IDE
  • Alter the extension code to read IDE post contents from file
  • Debug through the browser

I found my self frustrated with this workflow. Instead, what if I created an extension that could capture the IDE content and write it to the disk for me?

That’s what I did.

I still have to adjust my extensions to read in the file, but I can make that conditional:

So now much less work for me, and if you’re interested, much less work for you. The extension is now up on RIAForge.com: ColdFusion Builder Extension Test Creator.

MAX 2009 Unconference – ColdFusion for the Masses: PHP, Java, Ruby, and ASP Developers

Wow, that’s a long title.

I’m doing a session at the ColdFusion Unconference at Max 2009 on promoting ColdFusion to non-ColdFusion developers. It’s about going into other communities and focusing on the correct arguments for ColdFusion. I want to both share what I’ve learned in terms of winning arguments, and hear what you guys think resonate. So I’ll be presenting a bit, but I’ll also be listening to your experience (if you care to share.)

So sign up for MAX 2009, and check out the Unconference.

This session will be Tuesday October 6th from 1:30 – 2:30.

Also check out my main conference sessions:

Leveraging Exposed Services in ColdFusion Centaur
October 5 at 11:30AM
This session is about the new exposed services or CFaaS we have included in ColdFusion 9. I’ll be talking about how to leverage them in Flex and other languages, and even how to enhance previous versions of ColdFusion with them.

ColdFusion with Microsoft Office, SharePoint, and Exchange
October 5 at 05:00PM
I’ll be talking about how nice ColdFusion plays with Microsoft technologies. While Exchange integration has been around since ColdFusion 8, with 9 we’ve added the ability to interact with SharePoint and Office documents.

 

ColdFusion AIR Synchronization

First, let me just cop to the fact that this post draws a lot from Jayesh Viradiya’s post on this ColdFusion/AIR Offline support. I had to simplify his stuff to wrap my mind around it enough to talk about it. So hats off to Jayesh, he’s done some awesome work here.

I was doing a demo on ColdFusion and AIR integration at the keynote for CFUnited, and I figured I would go into a little more detail here.

First off, to call it “ColdFusion and AIR integration” is to do it a bit of a disservice. What our engineers have accomplished is nothing short of “ORM for AIR.” It handles:

  • Creating and maintaining the SQLite database
  • Saving objects to SQLite without SQL statements
  • Handling relationships:
    • one-to-one
    • one-to-many
    • many-to-one
    • many-to-many
  • Syncing those records back to ColdFusion

So I have a sample application that shows a basic demo of this, without the relationships. Jayesh’s demo has the relationships. I’ve attached the code here, so if you want to look at it, just download the whole thing. Otherwise, let me take you through it. One little note, this stuff was written for ColdFusion 9 Beta. There are some bugs. I’ll point them out where I can, and assure you that the bugs are being worked on.

So let’s start in the ColdFusion. First I define an ORM cfc:


component persistent="true"{
property name="personID" fieldtype="id";
property name="firstName";
property name="lastName";
property name="twitter";

public string function serial(){
return "#This.getFirstName()#|#This.getLastName()#|#This.getTwitter()#|#This.getpersonID()#";
}
}

Pretty straightforward; then I define a corresponding ActionScript class:


package airdemo
{
[Bindable]
[RemoteClass(alias="AIRDemo.person")]
[Entity]
public class Person
{
[Id]
public var personID:int;
public var firstName:String;
public var lastName:String;
public var twitter:String;
}
}

Note the RemoteClass mapping to the CFC on the back end. Now let’s go to the application. I have a simple data grid and form designed to show and edit the details of these person objects. I’ll skip that and go right to the part where I hook up AIR to the ColdFusion server:


private function init():void
{
// Provide Credentials for Server side Connection and CFC
syncmanager = new SyncManager();
syncmanager.cfPort = 80;
syncmanager.cfServer = "centaur.dev";
syncmanager.syncCFC = "AirDemo.personManager";

// THis handler will be called when any COnflict
// occurs while writing back changes on serverside
syncmanager.addEventListener(ConflictEvent.CONFLICT, conflictHandler);

//Kick off the application.
getRemote();

}

This connects this application to the ColdFusion server centaur.dev on port 80 and wires the syncmanager to AIRDemo.personmanager. More on that later. But it also kicks off getRemote which takes care of populating this application with data from the server. So getRemote() fires:


//GET records from BACKEND SERVER
private function getRemote():void{
var token:AsyncToken= syncmanager.fetch("fetch");
token.addResponder(new mx.rpc.Responder(fetchSuccess, fetchFault));
}

Syncmanager.fetch calls the fetch method of the ColdFusion CFC we set as syncmanager.syncCFC above. That method just retrieves the records using ColdFusion ORM.


remote Array function fetch(){
return EntityLoad('person');;
}

In most cases it is successful, in which case fetchSuccess calls createLocalDB:


//CREATE the actual SQLite DB
private function createLocalDB():void{
//Create a pointer to actual SQLite db file
dbFile = File.userDirectory.resolvePath("AirDemo.db");

var sessiontoken:SessionToken =syncmanager.openSession(dbFile,017916);
sessiontoken.addResponder(new mx.rpc.Responder(connectSuccess,connectFault));
}

In most cases that is successful and connectSuccess calls createLocalCacheFromRemote


//PUT records from BACKEND SERVER in SQLite DB
private function createLocalCacheFromRemote():void{
var savetoken:SessionToken = session.saveUpdateCache(pc);
savetoken.addResponder(new mx.rpc.Responder(saveCacheSuccess, savefault));
}

Those three ActionScript functions in concert with the ColdFusion one:

  • Got the data from the ColdFusion server
  • Created a local SQLite database for the data
  • Populated the local SQLite data with that data

Okay, so now I go through the application, update some data, and want to save it back to the SQLite database:


//SAVE to SQLite DB
private function saveLocal():void
{
//Generate person object from form.
var person:Person = convertFormToObject();

//session.saveUpdate saves record to SQLite Database
var savetoken:SessionToken = session.saveUpdate(person);
savetoken.addResponder(new mx.rpc.Responder(saveSuccess, savefault));
}

ConvertFormToObject does exactly what it sounds like, converting values from a form into a Person object, then session.saveUpdate() handles saving the record back to the SQLite store. No SQL required. Then we need to send it off to the ColdFusion server:


//SAVE to BACKEND SERVER
private function saveRemote():void
{
var committoken:SessionToken = session.commit();
committoken.addResponder(new mx.rpc.Responder(commitSuccess, commitFault));
}

That’s it. That transmits all of that changes made in this session to the ColdFusion server, where it is processed:


remote any function sync(required array operations,
required array clientobjects,
array originalobjects = ArrayNew(1)){

var i= 0;
var conflicts = ArrayNew(1);
var conflictcount = 1;

for (i=1; i <= ArrayLen(operations); i++ ){

var operation = operations[i];
var clientobject = clientobjects[i];
var originalobject = originalobjects[i];

if (operation eq "INSERT" ){
var obj = ORMGetSession().merge(clientobject);
EntitySave(obj);
}
else{

if (isinstanceOf(originalobject,"person")){
var serverobject = EntityLoadByPK("person",originalobject.getpersonID());
}
else{
throw "Invalid Object";
}

if (not isdefined('serverobject')){
var text="CONFLICT::SERVER OBJECT NOT FOUND, RECORD MAY BE DELETED ALREADY";
var conflict = New CFIDE.AIR.conflict();
conflict.clientobject = clientobject;
conflict.originalobject = originalobject;
conflict.operation = operation;
conflicts[conflictcount++] = conflict;
continue;
}

var isNotConflict = (originalobject.serial() eq serverobject.serial());
if (isNotConflict){
if (operation eq "UPDATE"){
obj = ORMGetSession().merge(clientobject);
EntitySave(obj);
}
else if (operation eq "DELETE"){
obj = ORMGetSession().merge(originalobject);
EntityDelete(obj);
}
}
else{
var text="is a conflict";
var conflict = New CFIDE.AIR.conflict();
conflict.clientobject = clientobject;
conflict.originalobject = originalobject;
conflict.operation = operation;
conflicts[conflictcount++] = conflict;
continue;
}
}
}
if (conflictcount gt 1){
return conflicts;
}
}
}

So this is a lot of code, but basically it performs the following steps:

  • Check to see if the record is new
    • If so insert it
  • Then check to see if the update is in conflict
    • If not, delete or update accordingly
    • If so, send a conflict back to the AIR client

Now back in the client you have to handle the conflict, in this version of the application, I just replace the client details with the server details:


//OVERWRITE from BACKEND SERVER
public function conflictOverwrite(conflicts:ArrayCollection):void{
var token:SessionToken = session.keepAllServerObjects(conflicts);
token.addResponder(new mx.rpc.Responder(conflictSuccess, conflictFault));
}

Again, one function, session.keepAllServerObjects, handles overwriting everything on the client.

So that is the gist of what I was going to show at CFUnited. The code is attached, (Down at the bottom there is a “download” link) feel free to give it a try and see what you can do with it.

DZone Refcard on ColdFusion

DZone released my Refcard on ColdFusion 9 today.

As you may or may not know, DZone Refcardz is a collection of cheat sheets that are designed to give developers a quick jumpstart into a new topic. They’re pretty great – no fluff and lots of content squeezed into a little bit of space.

I’m particularly excited about this as the audience for the DZone is pretty expansive, and cuts over many technology interests, including Flash Platform developers, Java developers, .Net Developers and other web developers. As an evangelist, it’s important for me to show off ColdFusion to people who aren’t already fans. The Refcard and my interview with DZone over the release of the public beta of ColdFusion 9 are part of that ongoing effort.

I’m committed to expanding the ColdFusion community by bringing in .NET, Java, PHP and other web developers who are willing to give ColdFusion a new look. We’re not going to do that by only talking to the ColdFusion community, and this is what reaching out to them looks like. More things in this space are coming down the pike, but I wanted to let all of you know that we’re committed to growing the community, and taking steps to do so.

Introspecting Application.cfc

I’ve gotten this question a bunch of times. How do you get information about what’s enabled in your application scope? How do I know if ORM is enabled, or what the datasource is?

Pretty easy – Instantiate the Application scope, and then get that information from the This scope.

CFUnited 2009 New Session

Due to some last minute CFUnited speaker withdrawals (unfortunate ones at that) I have picked up another session. So my sessions are as follows:

Thursday

Friday

I’m excited about all of the topics, but I’d like to point out two of them to you.

For Working with MS Office, SharePoint, and Exchange I’m teaming up with Dipanwita Sarkar from the Indian team. It should be great to see the SharePoint features in more detail.

Dipanwita has been working hard on this and on her other session: ColdFusion Builder: Getting Started (Bring Your Laptop). She’d like everyone who’s going to that to try and have ColdFusion 9 Beta and ColdFusion Builder Beta installed ahead of time if you can. They’re going to have a special pre-session workshop to help with that.

The second session I’d like to highlight is new one that got added, Selling Professional Development Techniques at a Resistant Shop. I’ve added a few things to it over the past few months, so if you have seen it before, it’s still much the same content but updated. If you haven’t seen it before, it basically is designed to help you sell all the things you learn at CFUnited to your co-workers when you get back to the office.

I can’t wait to see all of you down at the resort. There will be cigars if anyone is up for them.

 

Scotch on the Road Part Deux

The mainland Europe leg of Scotch on the Road is a go. Adam Lehman, ColdFusion Product Manager, and I are splitting up the dates. We’ll be teaming up with Andy Allan and Kevin McCabe of Fuzzy Orange, Claude Englebert ColdFusion EMEA Specialist, and Serge Jespers Platform Evangelist from Adobe to bring some ColdFusion goodness to the continent.

  • October 19: Munich
  • October 21: Zurich
  • October 23: Milan
  • October 26: Amsterdam
  • October 27: Brussels
  • October 29: London

The best part is it’s free. Yep, no cost, one day sessions in various cities in Europe, completely free. Now you have no excuse to stay at work.

I can’t wait to team back up with Fuzzy Orange, Serge, and Claude for this. I’ll be taking the first week of events in Munich, Zurich, and Milan.

ColdFusion Trivia Friday

In honor of CFUnited next week, I’m running a little Friday giveaway contest.

I will be asking 1 ColdFusion trivia question every 30 minutes on Twitter (@tpryan) starting Friday August 7th from 12:00PM to 2:00PM EDT. Use the Twitter hash tag #CFTFri. This will total 5 questions, and therefore 5 chances at a prize. The first person who gets a particular question right, as determined by my twitter client, gets the question’s prize. Prizes are limited to one prize per person. So if you win one, you cannot win another.

Prizes will be:

  • 4 ColdFusion Rocks t shirts – 12:00, 12:30, 1:00, 1:30
  • 1 set ColdFusion 8 Scotch Glasses (4 glasses in set) – 2:00

After you win, we’ll get in touch with each other via direct message. Then I’ll get your shipping details (not limited to USA), and shirt size.

I’d like to give special thanks to a recent re-addition to the Evangelism team, Ted Patrick. This is a blatant rip off of his contest idea. (But he said I could.)

If for some reason, Twitter is not playing well tomorrow (as it appears to be today), I’ll reschedule for Monday.