How to call a ColdFusion function from a .cfc file? - coldfusion

I have a .cfc file with all my functions in it (wrapped in a <cfcomponent> tag), including this one:
<cffunction name="getFooter" output="false" access="public" returnType="string">
<cfargument name="showFooter" type="string" required="false" default="" />
<cfreturn footer />
<cfset application.lib.getFooter(arguments.footer)>
</cffunction>
<cfset footer = getFooter(footer="<footer class="text-center">I am a footer.</footer>") />
And in my .cfm file, I put:
<cfoutput>#footer#</cfoutput>
It is not displaying the footer.
When I have all of this in a single .cfm file, it works fine.
I need to be able to store the function in my .cfc file and call it from anywhere in the application.
What am I missing?

Yet another way to cut it:
Application.cfc
<cfcomponent displayname="Application" output="false" hint="Handle the application.">
<!--- Set up the application. --->
<cfset this.Name = "AppCFC" />
<cfset this.ApplicationTimeout = createTimeSpan( 1, 0, 0, 0 ) />
<cfset this.sessionTimeout = createTimeSpan( 0, 0, 30, 0 ) />
<cfset this.sessionManagement = true />
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<!--- These variables are available to every CFM page in the application --->
<cfset application.lib = new path_to_Lib_CFC()>
<cfset application.footer=application.lib.getFooter()>
<cfreturn true />
</cffunction>
</cfcomponent>
Lib.cfc
<cfcomponent displayname="Lib" hint="Library of application CFCs">
<cffunction
name="getFooter"
output="false"
access="public"
returnType="string">
<cfset var footer = "<footer class=""text-center"">I am a footer.</footer>" />
<cfreturn footer />
</cffunction>
</cfcomponent>
Then, in any CFM file in the application:
<cfoutput>#application.footer#</cfoutput>

You explain your requirement clearly:
I need to be able to...call it from anywhere in the application.
So, don't do this:
"have a .cfc file with all my functions in it (wrapped in a
tag), including this one:"
The requirement, "call it from anywhere in the application", implies just one thing in ColdFusion: an application-scoped variable.
So, do the following instead: transfer the footer functionality from that CFC to your Application.cfc.
Let's assume the following is an excerpt of your Application.cfc.
Then, do something like:
<cfcomponent displayname="Application" output="true" hint="Handle the application.">
<!--- Set up the application. --->
<cfset this.Name = "AppCFC" />
<cfset this.ApplicationTimeout = createTimeSpan( 1, 0, 0, 0 ) />
<cfset this.sessionTimeout = createTimeSpan( 0, 0, 30, 0 ) />
<cfset this.sessionManagement = true />
<cffunction
name="OnApplicationStart"
access="public"
returntype="boolean"
output="false"
hint="Fires when the application is first created.">
<!--- This variable is available to every CFM page in the application --->
<cfset application.footer=getFooter()>
<cfreturn true />
</cffunction>
<cffunction
name="getFooter"
output="false"
access="public"
returnType="string">
<cfset var footer = "<footer class=""text-center"">I am a footer.</footer>" />
<cfreturn footer />
</cffunction>
</cfcomponent>
Then, in any CFM file in the application:
<cfoutput>#application.footer#</cfoutput>

You stated, we store all of our functions in a lib.cfc file.. So, in that file, write your function.
<cffunction name = "writeAppABCFooter" <!---descriptive name in case there is another footer --->
access = "public"
output = "yes" <!--- this is important --->
returntype = "void">
html code for footer
</cffunction>
To call your function, first create an object of lib.cfc.
<cfobject name = "FooterObject" component = "lib">
Then call the function.
<cfset FooterObject.writeAppABCFooter()>
This assumes that lib.cfc exists in a location that enables it to be called by any application.

I am going to ask and answer what I think you want.
Question
I have an application and it needs to have common footers. My footers are going to need the ability to have some sort of business logic. Right now it is Just static text. I think my footers need to be a function.
How can I do that? Oh, and I need to do this with tags, not script
Answer
First, we need a function with a very wide scope. I am going to put it in application.cfc. It is true that application.cfc is a .cfc, but it is highly special.
<!--- application.cfc --->
<cfcomponent>
...
<cffunction name="getFooter">
<cfsavecontent variable="local.result">
</cfsavecontent>
<cfreturn local.result>
</cffunction>
<cfset application.getFooter = getFooter>
...
</cfcomponent>
Now inside of each of the .cfm files, you can
<cfoutput>#application.getFooter()#</cfoutput>

Turns out this was a lot simpler than most us made it out to be. The <cfsavecontent> tag wasn't necessary. Storing the HTML in a variable wasn't required. I don't know if it was me or not, but this got way over complicated.
Ultimately, this is where I ended up going.
lib.cfc file
<cffunction name="getFooter" output="true" access="public" returntype="string">
<footer>I am a footer.</footer>
</cffunction>
index.cfm file
<cfoutput>
#application.lib.getFooter()#
</cfoutput>

I find it useful to just put simple reuseable things in their own CFM and just include them when needed.
/app/includes/footer.cfm
<p>I am the footer</p>
index.html
<cfinclude template="app/includes/footer.cfm">

Related

How to handle a request in ColdFusion

I am a newbie to ColdFusion, I created a result.cfm page, now I just want to do some actions in Application.cfc when the user calls /result.cfm. Something like below:
<cfif 'if the request is for result.cfm'>
<!-- do some action -->
</cfif>
Is there any way to handle the request?
A CFC is what Coldfusion calls a component, but it's essentially an object with methods. When any page on your site is requested coldfusion sends the name of your page to the onRequest method of your Application.cfc. By default that method looks something like this...
<cffunction name="OnRequest" access="public" returntype="void" output="true">
<cfargument name="TargetPage" type="string" required="true" />
<cfinclude template = "#arguments.targetPage#" />
</cffunction>
The TargetPage is the relative path to the page that has been requested.
I'm not sure what you're trying to do do, but you can either just create the page result.cfm and do your coding in there, or if you need to you can intercept the call by creating your own onRequest method and putting it in your application.cfc
<cffunction name="OnRequest" access="public" returntype="void" output="true">
<cfargument name="TargetPage" type="string" required="true" />
<cfif arguments.targetPage is "requestresult.cfm">
<!--- Do something else --->
<cfelse>
<cfinclude template = "#arguments.targetPage#" />
</cfif>
</cffunction>
Note that onRequest isn't the only method in Application.cfc, so that's worth looking up.
Also note you might want to output arguments.targetPage when you try this to just double check if the slash comes with the request or not (can't remember)
<cfif REFindNoCase("^/result.cfm", CGI.SCRIPT_NAME)>
<!--- do some action --->
</cfif>
or if you want to match more pages and subfolders you could do:
<cfset patterns = [
"^/foo/",
"^/bar/",
"^/etc/",
"^/login.cfm",
"^/baz.cfm"
] />
<cfif REFindNoCase("(" & ArrayToList(patterns, ")|(") & ")", CGI.SCRIPT_NAME)>
<!--- do some action --->
</cfif>

Best way for implementing webservice in CF

I have to create a web service in ColdFusion. I have tried the below 2 ways. Can anyone help me to find which one is the best way (Both Performance and security enhancement basis)
First Way
Created a cfm page like below;
<cfset result = StructNew() />
<cfset resultStruct = StructNew() />
<cfset validStruct = StructNew() />
<cfset VARIABLES.Sample = CreateObject("component","main.webservice.Sample")>
<cfif NOT isDefined("URL.method")>
<cfset result['status'] = false >
<cfset result['message'] = 'method is missing' />
<cfoutput>#SerializeJSON(result)#</cfoutput>
<cfabort>
</cfif>
<cfswitch expression="#URL.method#">
<cfcase value="get">
<cfset fieldList = "name">
<cfset validStruct = validate(fieldList) />
<cfif validStruct['status']>
<cfset resultStruct = VARIABLES.Sample.get(argumentCollection=URL) />
</cfif>
<cfoutput>#SerializeJSON(resultStruct)#</cfoutput>
<cfbreak>
</cfcase>
<cfcase value="put">
<cfset fieldList = "name,value">
<cfset validStruct = validate(fieldList) />
<cfif validStruct['status']>
<cfset resultStruct = VARIABLES.Sample.put(argumentCollection=URL) />
</cfif>
<cfoutput>#SerializeJSON(resultStruct)#</cfoutput>
<cfbreak>
</cfcase>
<cfdefaultcase>
<cfset result['status'] = false >
<cfset result['message'] = 'Not a valid method' />
<cfoutput>#SerializeJSON(result)#</cfoutput>
<cfbreak>
</cfdefaultcase>
</cfswitch>
And Created a cfc named 'Sample' under webservice folder and called like above.
WebService URL
http://test.com/webservice/Sample.cfm?method=get&name=test
Second Way
Called directly from the CFC Sample
Sample.CFC
<cfcomponent displayname="Sample" hint="Sample WebService" output="false">
<cffunction name="get" access="remote" returntype="struct" returnformat="json">
<cfargument name="name" required="true" type="string" >
<cfreturn StructNew() />
</cffunction>
<cffunction name="put" access="remote" returntype="struct" returnformat="json">
<cfargument name="name" required="true" type="string" >
<cfargument name="value" required="true" type="string" >
<cfreturn StructNew() />
</cffunction>
</cfcomponent>
WebService URL
http://test.com/webservice/Sample.CFC?method=get&name=test
The second method is the standard way to do WebServices in CFML. Along with the functionality, you are seeking you get standards based WSDL returns and definitions. It's a case of rebuilding the wheel. I'm sure the underlying CF code for ws could be optimized, but it's pretty good as is and has been field-tested by millions.
I would suggest setting up RESTful web services in ColdFusion. Here is an excellent article to get you started.
There's also Taffy which claims to make it simpler, although I have not used it.

apllication.cfc does not fire any default cffunction? Coldfusion

Can anyone tell me what the problem is? I tried to run some .cfm files but it does not trigger any effect of cffunction except cfcomponent? Am I missing something? Can anyone explain to me?
<cfcomponent>
<cfset THIS.Name = "formdemo">
<cfset THIS.SessionManagement = true>
<cfset This.Sessiontimeout="#createtimespan(0,0,20,0)#">
<cfset This.applicationtimeout="#createtimespan(5,0,0,0)#">
--Entered cfcomponent--
<cffunction name="onApplicationStart" returnType="boolean" output="false">
--Entered Application Start--
<cfset application.portfolioUploadRoot = "ram:///portfoliouploads">
<cfif not directoryExists(application.portfolioUploadRoot)>
<cfdirectory action="create" directory="#application.portfolioUploadRoot#">
</cfif>
<cfreturn true>
</cffunction>
<cffunction name="onSessionStart" returnType="void" output="false">
--Entered Session Start--
<cfset session.myuploadroot = application.portfolioUploadRoot & "/" & replace(createUUID(), "-", "_", "all")>
<cfif not directoryExists(session.myuploadroot)>
<cfdirectory action="create" directory="#session.myuploadroot#">
</cfif>
</cffunction>
<cffunction name="onApplicationEnd" returnType="void" output="false">
--Entered Application End--
<cfargument name="applicationScope" required="true">
<cfif directoryExists(arguments.applicationScope.portfolioUploadRoot)>
<cfdirectory action="delete" recurse="true" directory="#arguments.applicationScope.portfolioUploadRoot#">
</cfif>
</cffunction>
<cffunction name="onSessionEnd" returnType="void" output="false">
--Entered Session End--
<cfargument name="sessionScope" type="struct" required="true">
<cfargument name="appScope" type="struct" required="false">
<cfif directoryExists(arguments.sessionScope.myuploadroot)>
<cfdirectory action="delete" recurse="true" directory="#arguments.sessionScope.myuploadroot#">
</cfif>
</cffunction>
</cfcomponent>
The result only shows "--Entered cfcomponent--" on the beginning of cfmpage.cfm.
cfmpage.cfm:
<cfparam name="form.textname" default="">
<cfparam name="form.textemail" default="">
<cfparam name="form.docattach" default="">
<cfif structKeyExists(form, "Submit")>
<cfset form.textname = trim(htmlEditFormat(form.textname))>
<cfset form.textemail = trim(htmlEditFormat(form.textemail))>
<cflocation url="formcomplete.cfm" addToken="false">
</cfif>
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
<form method="post" enctype="multipart/form-data">
<cfoutput>
<input id="textname" name="textname" type="text" class="input-large" required="" value="#form.textname#">
<input id="textemail" name="textemail" type="text" class="input-large" required="" value="#form.textemail#">
</cfoutput>
</form>
</body>
</html>
It is doing as it should.
onApplicationStart -- Runs when ColdFusion receives the first request for a page in the application.
For this, to easily see this, you can try changing the name of the application, then
visit a page within.
onSessionStart -- Only run upon the first visit within the session. If you wait til after the
timeout and then come back, you'll see this. Changing the application name will should also
retrigger this.
onSessionEnd -- Run when the session ends. It will trigger after the timeout, it's used so that
you can clean up activity. For instance, if you're using something like Application.NumberOnline.
OnSessionEnd can substract one (where onSessionStart) can add one.
onApplicationEnd -- Runs when the application timeout occurs or the server is shutting down.
Neither of the latter two will ever show any text on screen because you can't see that event while visiting the page. You can however call them manually to trigger their effects. You can, however, log these actions however you choose. You may use cflog, for instance, in this fashion:
<cffunction name="onApplicationEnd">
<cfargument name="ApplicationScope" required=true/>
<cflog file="#This.Name#" type="Information"
text="Application #Arguments.ApplicationScope.applicationname# Ended" >
</cffunction>
In other words:
<cfscript>
ap = createObject("component","Application");
ap.onSessionEnd(session,application);
</cfscript>
Will display the text because it is firing the event.
Finally, if you're wanting something to happen on each page, onRequestStart and onRequestEnd or onRequest are great options. OnRequest is a method that wraps around the page, so you can do header and footer actions in the same request, but you must explicitly include the file, wheras onRequestStart / onRequestEnd execute at the start and end of the request.
The order of action methods invoked is
onApplicationStart (runs on first application activity)
onSessionStart (runs on first session activity)
onRequestStart
onRequest
onRequestEnd
Lastly, functions don't fire unless they're called. This applies to functions you write yourself as well.
<cfscript>
function foo() {
writeoutput("bar");
}
</cfscript>
Won't do anything until you actually try something like <cfoutput>#foo()#</cfoutput>.
In the case of "default functions", these are just special functions/methods that CF calls at certain points if they're present.

Looking for Struct Keys in Session

I am trying to write a session helper and facing to problem to test if a Struct key in session exists?
I am trying like
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="Any" />
<cfreturn Evaluate( "StructKeyExists( Session, #Arguments.Key# )" ) />
</cffunction>
Where I am calling the function like
<cfif Exists("data.fromdate") >
...
</cfif>
How should I write it?
Thanks
if you are checking to see if key "Test" exists in the session struct, try something like this:
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="String" />
<cfreturn StructKeyExists(session, arguments.Key) />
</cffunction>
<cfif Exists("Test") >
....
</cfif>
Another concept, or two, since you are looking for a struct within the session would be:
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="Key" required="true" type="String" />
<cfreturn (structKeyExists(session, listFirst(arguments.Key,"."))
AND structKeyExists(session[listFirst(arguments.Key,".")], listLast(arguments.Key, "."))) />
</cffunction>
<cfif Exists("data.Test") >
....
</cfif>
and
<cffunction name="Exists" access="public" output="false" returntype="boolean" >
<cfargument name="struct" required="true" type="String" />
<cfargument name="Key" required="true" type="String" />
<cfreturn (structKeyExists(session, arguments.struct)
AND structKeyExists(session[arguments.struct], arguments.key)) />
</cffunction>
<cfif Exists("data", "Test") >
....
</cfif>
Hope all this helps point you in the right direction, good luck!
The following code will check any depth struct, and also correctly locks the Session scope.
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cfset local.mainKeyList = ListChangeDelims(ListDeleteAt(Arguments.Key, ListLen(Arguments.Key, "."), "."), ",", ".")>
<cfset local.StructChain = "Session">
<cfloop list="#local.mainKeyList#" index="local.CurrentKey">
<cfset local.StructChain &= '["#local.CurrentKey#"]'>
</cfloop>
<cflock scope="session" type="readonly" timeout="3">
<cftry>
<cfset local.Exists = StructKeyExists(Evaluate(local.StructChain), ListLast(Arguments.Key, "."))>
<cfcatch>
<cfset local.Exists = false>
</cfcatch>
</cftry>
</cflock>
<cfreturn local.Exists>
</cffunction>
<cflock scope="session" type="exclusive" timeout="3">
<cfset Session.data.log.deep = "I'm here!">
</cflock>
<cfoutput>#Exists("data.log.deep")#</cfoutput>
Hopefully the amount of code in this function will justify why a helper function would be useful, to those pondering your reasons. This doesn't currently, but could be enhanced to, deal with Structs inside of Arrays as well. This also doesn't deal with an empty Arguments.Key, or fail gracefully on a cflock timeout, but should get you started.
Additionally, those that want to comment that cflock isn't required, please read the ColdFusion cflock docs first.
Simplified, but may provide inaccurate results in extremely rare conditions
Doing an IsDefined inline in your code will provide the opportunity for false positives, however having the IsDefined inside a udf or cfc method reduces this risk greatly to the point it may not need be a consideration. If you're happy to take that chance then you can simplify the function using IsDefined as Peter Boughton suggests.
<cffunction name="Exists" access="public" output="false" returntype="boolean">
<cfargument name="Key" required="true" type="string">
<cflock scope="session" type="readonly" timeout="3">
<cfset local.Exists = IsDefined("Session." & Arguments.Key)>
</cflock>
<cfreturn local.Exists>
</cffunction>
As Al Everett mentioned above, I don't remember the last time I had an app that didn't have session enabled. I guess if you can't be sure of that, then it makes sense to see if Session exists. My code for this would include:
<!--- in the application.cfc --->
<cffunction name="onSessionStart" output="false">
<!--- default session structure, you can also add default values to the data
structure here to ensure they exist later --->
<cfset session.data = {} />
</cffunction>
<!--- then in code use structKeyExists instead of a whole new function --->
<cfif structKeyExists(session.data, myKey)>
<!--- if you really wanted the "exists" function --->
<cffunction name="dataKeyExists" returntype="boolean" output="false">
<cfargument name="key" required="true" />
<cfreturn structKeyExists(session.data, arguments.key) />
</cffunction>
Depending on what's going on, I might choose to pass in the session to maintain encapsulation. But it doesn't always make sense to be a slave to OO and introduce complexity just for the sake of maintaining a pattern. Passing in the session structure and evaluating the key is really just a big workaround to using the "structKeyExists" function.
I also dislike having a function called "exists" because it tells me nothing about what it's really evaluating. I'd assume a function like that was like "isDefined" and more generic than just testing for a key in a specific structure.
<cfif structkeyexists(session, "data") and structkeyexists(session["data"], key)>
...
</cfif>
Why not just call <cfif isNull(session.data.fromdate)>
If the key data does not exist in session it will not throw, just returns false.

returning multiple stored procedure result sets from a cfc

I am trying to convert some pages from my app to use cfc's, and one page uses a stored procedure to retrieve a couple sets of data.
Now when I access the results, they act just like a if I used a <cfquery> tag, and all of the functionality that gives. So now I am trying to use this same stored procedure in a cfc that I am building, and I would like to be able access the results in the same manner, and there in lies my problem. I'm not sure how to return multiple queries from the function, without creating an array, which I have started. By the way, the function is incomplete. I was just trying to get something to work. In the below setup I get an array of query objects, but I feel there is a better way to do it.
Here is the <cffuntion>:
<cffunction name="getProfileData"
access="public"
output="false"
returntype="string">
<cfargument name="cusip" type="string" required="true">
<cfargument name="report_date" type="date" required="true">
<cfset var errorMessage = "everything is good">
<cftry>
<cfstoredproc datasource="#dsn#" procedure="prc_asset_profile_retrieve">
<cfprocparam type="in" cfsqltype="cf_sql_varchar" value="#cusip#" dbvarname="#cusip">
<cfprocparam type="in" cfsqltype="cf_sql_varchar" value="#report_date#" dbvarname="#reportDate">
<cfprocresult name="profile_head" resultset="1">
<cfprocresult name="attribution" resultset="2">
<cfprocresult name="characteristics" resultset="3">
<cfprocresult name="exposure" resultset="4">
<cfprocresult name="weights" resultset="5">
<cfprocresult name="holdings" resultset="6">
</cfstoredproc>
<cfset var profileArray = []>
<cfset #ArrayAppend(profileArray,profile_head)#>
<cfcatch type="any">
<cfset errorMessage = "something happened">
</cfcatch>
</cftry>
<cfreturn profileArray>
</cffunction>
When I output some test data, it matches up
<cfset count = fund_profile.getProfileData("#cusip#","#report_date#")>
<cfdump var="#count[1]#">
<cfoutput>
From cfc (##count[1].recordCount##): #count[1].recordCount#<br>
From stored proc (##profile_head.recordCount##): #profile_head.recordCount#
</cfoutput>
I get:
From cfc (#count[1].recordCount#): 1
From stored proc (#profile_head.recordCount#): 1
But the second way looks so much cleaner.
-----------------------------WORKING SOLUTION------------------------------
So after working with the answer from #leigh, I came up with this.
Here is the full cfc:
<cfcomponent displayname="Fund Profile" hint="This is the cfc that will do the processing of all fund profile information" output="false">
<cfproperty name = "result1"> <!--- PROFILE HEAD --->
<cfproperty name = "result2"> <!--- ATTRIBUTION --->
<cfproperty name = "result3"> <!--- CHARACTERISTICS --->
<cfproperty name = "result4"> <!--- EXPOSURE --->
<cfproperty name = "result5"> <!--- WEIGHTS --->
<cfproperty name = "result6"> <!--- HOLDINGS --->
<cffunction name="init"
displayname="init"
hint="This will initialize the object"
access="public"
output="false"
returnType="Any">
<cfargument name="dsn" type="string" required="true" />
<cfargument name="cusip" type="string" required="true" />
<cfargument name="report_date" type="date" required="true" />
<cfset variables.dsn = #arguments.dsn#>
<cfset variables.cusip = #arguments.cusip#>
<cfset variables.report_date = #arguments.report_date#>
<cfscript>
getProfiledata(cusip,report_date);
</cfscript>
<cfreturn this>
</cffunction>
<cffunction name="getProfileData"
access="private"
output="false"
returntype="void">
<cfargument name="cusip" type="string" required="true">
<cfargument name="report_date" type="date" required="true">
<cfstoredproc datasource="#dsn#" procedure="prc_asset_profile_retrieve">
<!--- STORED PROCEDURE HASN'T CHANGED. SEE ABOVE FOR CODE --->
</cfstoredproc>
<cfscript>
setProfilehead(profile_head);
setAttribution(attribution);
setCharacteristics(characteristics);
setExposure(exposure);
setWeights(weights);
setHoldings(holdings);
</cfscript>
<cfreturn>
</cffunction>
<!--- NOT GOING TO INCLUDE ALL SETTERS AND GETTERS, --->
<!--- BECAUSE THEY ARE ALL THE SAME OTHER THAN THE NAMES --->
<cffunction name="setProfileHead" access="private">
<cfargument name="ProfileHead">
<cfset variables.result1 = arguments.ProfileHead>
</cffunction>
<cffunction name="getProfileHead" access="public" returntype="query">
<cfreturn variables.result1>
</cffunction>
</cfcomponent>
Here is the code from the calling page:
<cfset fund_profile = CreateObject("component", "CFCs.fund_profile").init("#dsn#","#cusip#","#report_date#")>
<cfset profile_head = fund_profile.getProfileHead()>
Sorry for all the code, but I wanted to make the code available. So does anyone see any problems with what I came up with?
A function can only return a single value. If you wish to return multiple values, you will need to use some type of complex object (an array, structure, ...) If arrays are not intuitive enough, you could place the queries in a structure and return that instead. Then the calling page could access the queries by name, rather than index.
(Side note, be sure to properly var scope/localize all function variables.)
<cfset var data = {}>
...
<!--- store query results in structure --->
<cfset data.profile_head = profile_head>
<cfset data.attribution = attribution>
...
<cfset data.holdings = holdings>
<!--- return structure --->
<cfreturn data>
I would create other methods in the CFC that would each be responsible for returning a result from the stored proc. In the main method , call setters
setProfileHead(profilehead:profileHead)
<cffunction name=ProfileHead>
<cfarguments name=ProfileHead />
<cfset variables.profilehead = arguments.profilehead>
</cffunction>
Then...
<cffunction name=GetProfileHead>
<cfreturn variables.profileHead />
</cffuction>