Broadcasting and Interceptors in Coldbox
There was a little discussion in the comments of my Analyzing Coldbox post. It related to Coldbox’s abilities to use message-style broadcasts, like MG uses. I’d like to show an example of how Coldbox CAN indeed broadcast to a listener when an event is called.
We’ll use the same code from the previous examples, and expand them. This is the simplest example that came to mind. I’m not going to explain what the docs already explain. It’s just to show you that you can actually do it with a concrete example.
Our Goal: When the user tries to add himself using the add employee form, we’re going to check to see if his name is “Will”. If it is, we’ll route him to a different view, and show him a special message. If it isn’t Will, his data will be logged as usual, and he’ll follow the normal flow of the application – to the dspAddEmployee view. .
Step 1: Create a new cfc in your Interceptors directory
<cfcomponent name=”myInterceptor”
hint=”This is a simple interceptor”
output=”false”
extends=”coldbox.system.interceptor”>
<cffunction name=”Configure” access=”public” returntype=”void” hint=”This is the configuration method for your interceptors” output=”false” >
<!— I set up myself —>
<cfset setProperty(‘ConfigurationTime’, now() )>
</cffunction>
<cffunction name=”afterConfigurationLoad” access=”public” returntype=”void” hint=”Executes after the framework and application configuration loads, but before the aspects get configured. ” output=”false” >
<!— ************************************************************* —>
<cfargument name=”event” required=”true” type=”coldbox.system.beans.requestContext” hint=”The event object.”>
<cfargument name=”interceptData” required=”true” type=”struct” hint=”interceptData of intercepted info.”>
<!— ************************************************************* —>
<!— Set the tracing setting —>
<cfset setSetting(“ExecutionTracerStartTime”,now())>
</cffunction>
</cfcomponent>
I believe that’s pretty much from the example Luis has on the Coldbox site.
Step 2: Let’s go ahead and create our custom interceptor inside our new component. Add this method:
<cffunction name=”onSubmitData” access=”public” returntype=”void” hint=”My custom convention interceptor” output=”false” >
<!— ************************************************************* —>
<cfargument name=”event” required=”true” type=”coldbox.system.beans.requestContext” hint=”The event object.”>
<cfargument name=”interceptData” required=”true” type=”struct” hint=”interceptData of intercepted info.”>
<!— ************************************************************* —>
<cfset var rc = event.getCollection()>
<!— Do whatever I want here —>
<cfscript>
if(arguments.interceptData.emp_fname EQ “Will”){
setNextRoute(“Employee/dspThisIsWill”);
}
</cfscript>
</cffunction>
I think this is pretty much self-explanatory. We’ll have an argument named interceptedData from which we’ll check the emp_fname variable. If it’s Will, change his route.
Step 3: Define a new interceptor in your coldspring.xml.cfm config file. Notice I named the interception point the same as my method. The class is obviously our new cfc in the interceptors directory.
<CustomInterceptionPoints>onSubmitData</CustomInterceptionPoints>
<Interceptor class=”interceptors.MyInterceptor” />
Step 4: Setup Will’s custom display view.
<cfoutput>
Wow! This is really Will??
</cfoutput>
The Last Step: Add the new “broadcast” to your processAddEmployee event.
<cffunction name=”processAddEmployee” access=”public” returntype=”void” output=”false”>
<cfargument name=”Event” type=”coldbox.system.beans.requestContext”>
<cfscript>
var data = structnew();
var rc = event.getCollection();
var aryErrors = “”;
var empService = getColdboxOCM().get(‘empService’);
data.timeIntercepted = now();
data.event = event.getCurrentEvent();
announceInterception(‘onSubmitData’, data);
//The regular process is from this point down
aryErrors = arrayNew(1);
if(not len(rc.emp_fname)){
arrayAppend(aryErrors, “No First Name Entered”);
}
if(not len(rc.emp_lname)){
arrayAppend(aryErrors, “No Last Name Entered”);
}
if(not len(rc.emp_age) or not isNumeric(rc.emp_age)){
arrayAppend(aryErrors, “Enter a numeric for your age”);
}
if(not arrayLen(aryErrors)){
empService.addEmployee(rc.emp_fname, rc.emp_lname, rc.emp_age);
setNextEvent(“Employee.dspAddEmployee”);
}
else{
//dump(aryErrors);
//abort();
arguments.event.setValue(“emp_fname”, rc.emp_fname);
arguments.event.setValue(“emp_lname”, rc.emp_lname);
arguments.event.setValue(“emp_age”, rc.emp_age);
getPlugin(“messageBox”).setMessage(“Warning”, “”, aryErrors);
setNextEvent(“Employee.AddEmployee”,”emp_fname=#rc.emp_fname#&emp_lname=#rc.emp_lname#&emp_age=#emp_age#”);
}
</cfscript>
</cffunction>
I’m setting up a data struct so we can store a bunch of goodies if we want. This line actually broadcasts to our interceptor:
announceInterception(‘onSubmitData’, data);
You can give it a whirl here.
Enter your info. If you use “Will” for the first name, it should display a totally different page. If you enter yours, you’ll land on the usual display page detailing what happened (I haven’t updated that info yet to reflect the changes).
Hope this helps!
3 comments so far
Leave a reply
Simple, and to the point. I like it! Thanks, Will.
Thanks Matt! I had to contact Luis about persisting some data across these requests. My mind was having a hard time visualizing some of it. He was most helpful, as usual!
Yet another thing I love about this framework – Luis. He’s great!
[...] my last Coldbox entry, I wanted to simply pass that fname variable over to the dspThisIsWill view. I tried with my [...]