Learning ColdBox: Coldbox Proxy How Cool is This!

I had some CFGRID code I needed to implement into an existing ColdBox application. The grid run out of the box without any intervention from the ColdBox Framework. However it would be necessary for the CFGRID to access my service layer and properties injected from ColdSpring if I wanted it to take full advantage of the CB Framework. I assumed this would be a nightmare, I mean how to I get my AJAX grid to use the same reusable ColdBox and model code?

With ColdBox Proxy of course! The ColdBox proxy enables remote calls like AJAX to communicate with ColdBox and take advantage of all the goodies it has to offer, thanks ColdBox!

So how easy was it to get working? Very, it only took a few extra lines of code to work, really!

First I told my CFGRID to access the proxy directly and not the CFC.

view plain print about
1bind="cfc:admin.coldboxproxy.getAllproducts({cfgridpage},
2 {cfgridpagesize},
3 {cfgridsortcolumn},
4 {cfgridsortdirection})"

Next using the ColdBox proxy template already provided (which extends coldbox.system.extras.ColdboxProxy) I created a new function that works the same was as handlers in ColdBox.

view plain print about
1<cffunction name="getAllproducts" output="false" access="remote" returntype="any" hint="Process a remote call and return data/objects back.">
2 <cfargument name="page" type="numeric" required="yes">
3 <cfargument name="pageSize" type="numeric" required="yes">
4 <cfargument name="gridsortcolumn" type="string" required="no" default="">
5 <cfargument name="gridsortdir" type="string" required="no" default="">
6
7 <cfset var results = "">
8 <cfset results = getBean("storeService").getAJAXProducts(page=#arguments.page#,                     pageSize=#arguments.pageSize#,
9            gridsortcolumn=#arguments.gridsortcolumn#,
10            gridsortdir=#arguments.gridsortdir#) /
>

11
12 <!--- Convert Query for Paging --->
13 <cfreturn QueryConvertForGrid(results,page,pageSize)>
14</cffunction>

getBean("storeService") interact directly with the service layer. Once this was done I could then take advantage of my dependency injection framework and ColdBox features. How cool is that!

Learning ColdBox: Multiple Updates uisng a Object

My venture in ColdBox has been so far very enjoyable. It has really changed the way I plan my applications. My stumble in to using objects (correctly) has also brought with it some challenges and changed my approach to building maintainable and reusable applications.

So far my blog entries on ColdBox have mainly been on objects, validation and persistent, all straight forward when doing simple updating/creating/deleting actions.

Anyway, going back to challenges and objects, my first real stumbling block came a few weeks ago. How do I insert multiple records from data that comes from a form using a object?

I asked this question on both the ColdBox forums and CFTALK list. They all make it sound so simple, not sure they had this in mind.

My problem was as follows: when creating/updating a product I need to insert/update or delete multiple records for the product options based on what the user ticked or not ticked. So my first attempt worked that's a start right? here goes....

[More]

Persisting Values in ColdBox

I have never found a way to validate data I feel is 100% right for me, but I think I am getting close, let me explain.

I have a simple ColdBox 'view' containing my user form. This form is used to both create and update user's credentials.

view plain print about
1user view
2
3<cfoutput>
4 <fieldset>
5 <div class="fm-req">
6 <label for="firstname">First Name</label>
7 <input id="firstname" name="firstname" type="text" class="text" value="#rc.bean.getfirstname()#" maxlength="15">
8 </div>
9 <div class="fm-req">
10 <label for="surname">Last Name</label>
11 <input id="surname" name="surname" type="text" class="text" maxlength="15" value="#rc.bean.getsurname()#">
12 </div>
13 <div class="fm-req">
14 <label for="email">Email Address</label>
15 <input id="email" name="email" type="text" class="text" maxlength="100" value="#rc.bean.getemail()#">
16 </div>
17 <div class="fm-req">
18 <label for="username">Username</label>
19 <input id="username" name="username" type="text" class="text" maxlength="12" value="#rc.bean.getusername()#">
20 </div>
21 <div class="fm-req">
22 <label for="password">Password</label>
23 <input id="password" name="password" type="password" class="text" maxlength="20" value="#variables.PasswordEncrypt#">
24 </div>
25 </fieldset>
26</cfoutput>
view plain print about
1example handler
2
3<!--- Edit User --->
4<cffunction name="editUser" access="public" returntype="void" output="false">
5<cfargument name="Event" type="coldbox.system.beans.requestContext">
6 <cfscript>
7     var rc = event.getCollection();// RC Reference
8
var userBean = variables.adminUsersService.createAdminUserBean(); //Create adminUserBean
9
     getPlugin('beanFactory').populateBean(userBean);//the magic bean machine
10
     variables.adminUsersService.getUserByID(userBean);
11     rc.bean = userBean;
12     event.setValue("pageTitle","Edit System User");//Form H1 Title
13
     event.setValue("formURL","/users/updateUser?adminId=#rc.adminId#");
14     event.setValue("buttonValue1","Update User");//H1 Title
15
     runEvent(event='users.createUserTabs',private=true); // Create User Tabs
16
     Event.setView("user/edit"); // Set the View To Display, after Logic
17
</cfscript>
18</cffunction>

I use one handler to create a new user and another to update, the only difference is the update handler pre populates the object from the database. So far simple stuff. Next I needed to validate my input. Again simple, I would submit to an intermediate handler that would validate my data against the object. However my dilemma is what to do if validation fails!

view plain print about
1<!--- Validation --->
2<cffunction name="validation" access="public" returntype="void" output="false">
3<cfargument name="Event" type="coldbox.system.beans.requestContext">
4 <cfscript>
5     var rc = event.getCollection();// RC Reference
6
var userBean = variables.adminUsersService.createAdminUserBean(); //Create adminUserBean
7
getPlugin('beanFactory').populateBean(userBean);//the magic bean machine
8
    
9     errors = userBean.validateUserALL();//Check For Validation Errors
10
    
11     if NOTT ArrayLen(errors)){//No Validation Errors
12
    
13         if ( variables.adminUsersService.updateUser(userBean)) {//Update Was OK
14
             getPlugin("messagebox").setMessage("info", "User was successfully updated.");
15         }
16         else {//Could Not Update User Show Error Message
17
             getPlugin("messagebox").setMessage("error", "Sorry, for some reason this user was not updated!");
18         }
19        
20     setNextEvent('users.overView'); // Set the Event To Run, After Logic
21
     }//End Of No Validation Errors
22
    
23     else {//We Have Validation Errors Show The User A Message
24
getPlugin("messagebox").setMessage("error", "<b>The Following Validation Errors Occurred:</b><br />",errors);
25        
26 ///what to do here?
27
        
28 }
29
</cfscript>
30</cffunction>

[More]

ColdBox and ColdSpring Hard Lessons

It has been a few weeks now of me getting to grips with ColdBox and ColdSpring. My question has been mainly on why I would use ColdSpring at all. Some will be glad to hear I am starting to see how ColdSpring helps with managing CFC's. I also just wanted to recommend Jason Dean's Blog. He has provided a very insightful step by step guide to using ColdBox and ColdSpring which has really helped me. I got it late, I know but if for some strange reason you have not read his series, do it, do it now!

The Hard Lesson

When I was creating my object i.e "userservice().init()" CF was throwing an error. It seemed ColdSpring knew nothing about my injected properties to the CFC, can you spot why? Well either ColdSpring or ColdBox (not sure which) handles the .init() it calls the constructor and passes in the correct argument without my help. So because I was trying to call the init() myself it was not being managed by ColdSpring. Simple, but it held me up for a long time. Because I always try and follow the best practice it never occurred to me this could be the culprit. A quick post on the ColdSpring user group and Brian Kotek quickly put me on the right track, thanks again.

[More]

ColdBox using ColdSpring

The more I work in ColdBox the more I want to learn, so pardon my ramblings but yesterday ColdBox and ColdSpring took my fancy. I have never worked with ColdSpring nor any other AOP for CFC's.

So ColdSpring, what's all that about then? To be honest I am still not sure why I would use it. I started by playing around, I wanted to inject my ColdBox DNS setting into my common.cfc (database gateway).

view plain print about
1<beans default-autowire="byName">
2<bean id="coldboxFactory" class="coldbox.system.extras.ColdboxFactory" />
3<bean id="ConfigBean" factory-bean="ColdboxFactory" factory-method="getConfigBean" />
4<bean id="dsnBean" factory-bean="ColdboxFactory" factory-method="getDatasource">
5    <constructor-arg name="alias">
6    <value>DBDetails</value>
7    </constructor-arg>
8</bean>    
9    <bean id="userService" class="model.UserService" />
10    
11    <bean id="userGateway" class="model.common" >
12     <property name="dsnBean">
13 <ref bean="dsnBean" />
14 </property>
15 </bean>
16
17</beans>

I then created a UserService.cfc. The idea I think behind this is that I access the userService.cfc to get to common.cfc (gateway) and common.cfc gets the DNS setting injected.

view plain print about
1<cfcomponent name="User Service">
2
3<cffunction name="init" access="public" returntype="any" hint="Constructor.">
4 <cfreturn this />
5</cffunction>
6
7<cffunction name="getUserGateway" access="public" returntype="any" output="false" hint="Return the UserGateway.">
8 <cfreturn variables.instance['userGateway'] />
9</cffunction>
10
11<cffunction name="setUserGateway" access="public" returntype="void" output="false" hint="Set the UserGateway.">
12 <cfargument name="userGateway" type="any" required="true" hint="UserGateway" />
13 <cfset variables.instance['userGateway'] = arguments.userGateway />
14</cffunction>
15</cfcomponent>
view plain print about
1common.cfc
2<cffunction name="setdsnBean" access="public" returntype="void" output="false" hint="Set the dsnBean.">
3 <cfargument name="dsnBean" type="any" required="true" hint="dsnBean" />
4 <cfset variables.instance['dsnBean'] = arguments.dsnBean />
5</cffunction>

Why is this any better? I could have achieved this all in the init() method without ColdSpring, or I could have extended my CFC, or I could have even created a config CFC and injected that into the common.cfc.

Sorry, If these questions are just ignorant.

ColdBox - SagePay VSP Driect Plugin

Now I am getting more to grips with CB I have recreated an ecommerce site using the framework. I have also created a simple plugin for the Coldbox Framework that allows you to integrate SagePay VSP Direct payment system in your website. It seems to work very well the site I used it on has been running the new plugin for few days, taking transactions with no errors.

In case you don't know, SagePay VSP Direct is a method of processing a transaction through the Sage Pay gateway using server to server communication with the customer remaining on your website throughout the whole process.

This plugin will setup, send and handle the response from their gateway. You will need an understanding of Sagepay and a SSL cert to use this plugin. Sage Pay only support UK merchants at the moment!

I will be adding some example of the handler, checkout forms, and cart to a zip download soon at the moment all I have included the plugin CFC code below.

[More]

First Coldbox Plugin, HELP?

So, my first attempt at a ColdBox Plugin works, however I cannot help but feel I could have done it better/right. You see, I know the theory of OOP it's in my nightmares as student, but applying it practically in CF is still a learning experience.

I have posted my code below. Encapsulation is the key I think, you see I am coming outside of the CFC to put back in 'SagePayURLStruct'

So my question is, how to I setup the 'setEnvironment' function in the CFC so it accessible inside the CFC, only the CFC and without going outside the CFC? For example could this be done using the init(). Could it be called on create component, so its accessible in the CFC itself after creation?

I would really welcome any feedback here, rip it to pieces it's the only way I learn! :)

[More]

CFIMAGE WRITETOBROWSER no alt tag!

Just a quick post on using 'CFIMAGE' with the action 'WRITETOBROWSER'. I noticed something which is not documented in the livedocs. When using the above tag I viewed the sourced code it outputted to the browser and it gave a completely empty alt tag, not good for accessibility! So I looked in the livedocs to see it there was an attribute for missing 'alt', but nothing!

Just out of pure boredom I added alt="something" to the CFIMAGE tag and guess what? No errors, could it have worked? Yes it did! Infact any normal image attribute seemed to work on CFIMAGE such as border="0" etc.

OK, so this is weak attempt at a blog post but it has me thinking, do Adobe not document such things often or maybe just because its common sense. Well either way I like it when things just work.

ColdBox and Viewlets

The ColdBox Framework is fast becoming enjoyable to work with, which came as a surprise for me. Having now completed 4 projects in CB I have decided to start writing up on some of my experiences so far.

The first write-up starts at the beginning! By that I mean things I found useful when first starting a CB project. Its not a deep read into CB just some random stuff that helped me out when first starting with the Framework.

[More]

Sage Pay CFC

Below is a quick update on the old 'protx.cfc' now 'sagepay.cfc'. It's a little messy and there are a few things I would have done different if I had more time, but I didn't. I wanted to share will you my new CFC because as you may know Sage Pay don't seem to have a ColdFusion VSP Direct integration Kit anymore! Anyhow below will help jump start anyone wanting to integration the gatway using the VSP Direct service they offer.

First make sure you have read their integration guides @ sagepay.com and you will need have a test or simulation account to test first. If you don't have one you can sign up for a free simulation account here. You can get a live account by clicking here.

Download the sagepay.cfc (.rar file 3KB)

[More]

_UNKNOWNTRANSLATION_ / More Entries

 

About Me

Glyn Jackson, 28 years old, MD and senior developer of a development firm based in Staffordshire called Newebia Ltd. Academic background in BSc Information System & Internet Commerce. Online marketing expert (EE Ranked) and .NET developer. Has been developing with ColdFusion for 5 years and loves it. "I am not a veteran in ColdFusion but I do work on challenging projects which help me learn more about ColdFusion and if I can contribute to the community in anyway then, it's all good!"

Recommends

  • ColdFusion