coldfusion ignore undefined variables - coldfusion

if I use
<cfoutput>#somevariable#</cfoutput>
and somevariable is not defined I get an error, how can I prevent the error from occourring?
is there a simple way of implementing a conditional that doesn't require a bunch of extra lines?

<cfparam name="somevariable" default="" />
If you're on cf 9 you can use a ternary operation, but cfparam is more 'best practicey'.
#isDefined("somevariable") ? somevariable : 'default string'#

You can test for the variable
<cfoutput>
<cfif isDefined("somevariable")>
#somevariable#
<cfelse>
handle default scenario here
</cfif>
</cfoutput>
or you could use inline conditional
<cfoutput>
#IIF(isDefined("somevariable"),de(somevariable),de(""))#
</cfoutput>

Related

Custom CFInclude for file customization

Our code base has quite a bit of the following example as we allow a lot of our base pages to be customized to our customers' individual needs.
<cfif fileExists("/custom/someFile.cfm")>
<cfinclude template="/custom/someFile.cfm" />
<cfelse>
<cfinclude template="someFile.cfm" />
</cfif>
I wanted to create a custom CF tag to boilerplate this as a simple <cf_custominclude template="someFile.cfm" />, however I ran into the fact that custom tags are effectively blackboxes, so they aren't pulling in local variables that exist prior to the start of the tag, and I can't reference any variable that was created as a result of the tag from importing the file.
E.G.
<!--- This is able to use someVar --->
<!--- Pulls in some variable named "steve" --->
<cfinclude template="someFile.cfm" />
<cfdump var="#steve#" /> <!--- This is valid, however... --->
<!--- someVar is undefined for this --->
<!--- Pulls in steve2 --->
<cf_custominclude template="someFile.cfm" />
<cfdump var="#steve2#" /> <!--- This isn't valid as steve2 is undefined. --->
Is there a means around this, or should I utilize some other language feature to accomplish my goal?
Well, I question doing this at all but I know we all get handed code at times we have to deal with and the struggle it is to get people to refactor.
This should do what you are wanting. One important thing to note is that you will need to ensure your custom tag has a closing or it won't work! Just use the simplified closing, so like you had it above:
<cf_custominclude template="someFile.cfm" />
This should do the trick, called it has you had it : custominclude.cfm
<!--- executes at start of tag --->
<cfif thisTag.executionMode eq 'Start'>
<!--- store a list of keys we don't want to copy, prior to including template --->
<cfset thisTag.currentKeys = structKeyList(variables)>
<!--- control var to see if we even should bother copying scopes --->
<cfset thisTag.includedTemplate = false>
<!--- standard include here --->
<cfif fileExists(expandPath(attributes.template))>
<cfinclude template="#attributes.template#">
<!--- set control var / flag to copy scopes at close of tag --->
<cfset thisTag.includedTemplate = true>
</cfif>
</cfif>
<!--- executes at closing of tag --->
<cfif thisTag.executionMode eq 'End'>
<!--- if control var / flag set to copy scopes --->
<cfif thisTag.includedTemplate>
<!--- only copy vars created in the included page --->
<cfloop list="#structKeyList(variables)#" index="var">
<cfif not listFindNoCase(thisTag.currentKeys, var)>
<!--- copy from include into caller scope --->
<cfset caller[var] = variables[var]>
</cfif>
</cfloop>
</cfif>
</cfif>
I tested it and it works fine, should work fine being nested as well. Good luck!
<!--- Pulls in steve2 var from include --->
<cf_custominclude template="someFile.cfm" />
<cfdump var="#steve2#" /> <!--- works! --->

Cfparam for a struct

<cfparam name="instance.params.sel_isCriteriaChanged" default="false">
Here instance is a global structure but "sel_isCriteriaChanged" inside that is created using form variable. But in certain form i dont have that variable. It'll be undefined in that case.
So in that case how to set the variable to false as default value.
I am using this variable inside CFC file
If I understand the question correctly you have something like this:
<cfparam name="instance.params.sel_isCriteriaChanged" default="false">
<cfset instance.params = {}>
<cfloop collection="#FORM#" item="key">
<cfset instance.params[key] = FORM[key]>
</cfloop>
but the cfparam gets overwriten here. Just make sure the form value is always defined:
<cfparam name="FORM.sel_isCriteriaChanged" default="false">
If I understand your problem correctly, you might do something like the following:
<cfset instance.params.sel_isCriteriaChanged = structKeyExists(form, "sel_isCriteriaChanged") ? form.sel_isCriteriaChanged : false />
This is shorthand for:
<cfif structKeyExists(form, "sel_isCriteriaChanged")>
<cfset instance.params.sel_isCriteriaChanged = form.sel_isCriteriaChanged />
<cfelse>
<cfset instance.params.sel_isCriteriaChanged = false />
</cfif>
I like the terseness of the ternary operator ? : and I try to avoid using <cfparam> if possible. Hope this helps.

ColdFusion isDefined getting Not Defined error

I have:
<cfif not isDefined(activity)>
<cfset activity="">
</cfif>
And I'm getting the error: :"Variable ACTIVITY is undefined."
Huh?
Oh, and the error is with isDefined, not with the cfset.
isDefined takes the name of a variable, not the variable itself:
<cfif not isDefined("activity")>
<cfset activity="">
</cfif>
Try:
<cfif structKeyExists(VARIABLES, 'Activity')>
<cfset Activity = "Something" />
</cfif>

ColdFusion = OnRequest Error

Looking through the logs, we're getting hundreds of the following
"Error","jrpp-185","08/21/12","10:05:43","PATH","www.domain.com
Agent:Mozilla/4.0 (compatible; Synapse)
Error: An exception occurred when invoking a event handler method from Application.cfc.
The method name is: onRequest.
They seem to be mostly search bots. The on place on APplication.cfc that I can see reference to the function is below
<cffunction name="onRequest" returnType="void">
<cfargument name="targetPage" type="String" required=true/>
<cfsetting enablecfoutputonly="yes" requesttimeout="20">
<cfparam name="url.refresh" default="0">
<cfset request.strMember = Duplicate(session.strMember)/>
<cfset request.tNow = GetTickCount()>
<cfif url.refresh EQ 0>
<cfset request.iCacheHr = 12/>
<cfelse>
<cfset request.iCacheHr = 0/>
</cfif>
<cflogin>
<cfif IsDefined("session.strMember.sRoles")>
<cfloginuser name="#session.strMember.sFirstName##session.strMember.sLastName#"
password="12345"
roles="#session.strMember.sRoles#"/>
</cfif>
</cflogin>
<cfinclude template="core/incl/SessionLogger.cfm">
<cfinclude template="core/incl/LinkTranslator.cfm">
<cfinclude template="core/incl/udf.cfm">
<cfinclude template="urlcheck.cfm"/>
<cfinclude template="#Arguments.targetPage#">
</cffunction>
From that, can anyone please advise on what's wrong and how to fix it? I'm fairly new to CF and this is making me pull out what little hair I have left
1) You use two different coding styles
<cfparam name="url.refresh" default="0">
<cfset request.strMember = Duplicate(session.strMember)/>
Invalid/left open XML tags in first line and valid (closed) XML tags in the second line.
Try to stick to one (preferably the last one).
2) You are using old way of checking variable being defined
IsDefined("session.strMember.sRoles")
read about newer (and better and faster)
StructKeyExists(session.strMember, "sRoles")
3) Most likely your code is calling
<cfloginuser ... >
at every page request
4) Make sure that paths for all includes are correct and they themselves don't have any errors.
Simplify your method until you stop getting an error and then investigate what exactly is causing it
Are the bots hitting a page that doesn't exist?
Maybe try changing the last line to:
<cfif fileExists(expandPath(Arguments.targetPage))>
<cfinclude template="#Arguments.targetPage#">
<cfelse>
<cfabort>
</cfif>
Maybe you could detect if they are a bot and server them something else? depends on how search friendly you want your site to be:
http://www.bennadel.com/blog/1083-ColdFusion-Session-Management-And-Spiders-Bots.htm

In ColdFusion, how do I determine if a query string variable exists?

In ColdFusion, how can I determine if a variable exists within the querystring without throwing an error attempting to check it?
There are two options.
The first is to use cfparam to define a default value eg:
<cfparam name="url.varname" type="string" default="" />
This ensures that you can always refer to url.varname
The second is to use isDefined or structKeyExists to test for the presence of the variable:
<cfif isDefined("url.varname") and url.varname eq 42> do something </cfif>
or
<cfif structKeyExists(url, "varname") and url.varname eq 42> do something </cfif>
I have used this approach in many places.
At the top of the page:
<cfparam name="request.someVal" default="request.defaultVal">
Later in the page or custom tag, check for the value of the request.someVal variable, without fear of it crashing, since it has a default value.
<cfif ("request.someVal" eq "something")>
...
</cfif>
.
.
.
In <cfscript>, you can
param url.varname; // throws error if it does not exist
param url.varname = ""; // sets value it was not already set