coldfusion weird extra space - coldfusion

I have a function to convert string to number
<cffunction name="convertToNumber" returntype="numeric">
<cfargument name="separator" required="Yes" type="string" />
<cfargument name="number" required="Yes" type="string" />
<cfset LOCAL.arrSeparator = ["comma", "period", "lakh_crore"] />
<cfif ARGUMENTS.separator eq "comma" or ARGUMENTS.separator eq "lakh_crore">
<cfif ListLen(ARGUMENTS.number, ".") eq 2>
<cfset LOCAL.integral = ListFirst(ARGUMENTS.number, ".") />
<cfset LOCAL.fractional = ListLast(ARGUMENTS.number, ".") />
<cfelse>
<cfset LOCAL.integral = ARGUMENTS.number />
<cfset LOCAL.fractional = "" />
</cfif>
<cfset LOCAL.integral = Replace(LOCAL.integral, ",", "", "ALL") />
<cfset LOCAL.returnValue = LOCAL.integral />
<cfif Len(Trim(LOCAL.fractional))>
<cfset LOCAL.returnValue &= "." & LOCAL.fractional />
</cfif>
</cfif>
<cfif ARGUMENTS.separator eq "period">
<cfif ListLen(ARGUMENTS.number, ",") eq 2>
<cfset LOCAL.integral = ListFirst(ARGUMENTS.number, ",") />
<cfset LOCAL.fractional = ListLast(ARGUMENTS.number, ",") />
<cfelse>
<cfset LOCAL.integral = ARGUMENTS.number />
<cfset LOCAL.fractional = "" />
</cfif>
<cfset LOCAL.integral = Replace(LOCAL.integral, ".", "", "ALL") />
<cfset LOCAL.returnValue = LOCAL.integral />
<cfif Len(Trim(LOCAL.fractional))>
<cfset LOCAL.returnValue &= "." & LOCAL.fractional />
</cfif>
</cfif>
<cfreturn LOCAL.returnValue />
</cffunction>
<cfset separatorNumber = StructNew() />
<cfset separatorNumber.comma = "1,234,567,890.123456">
<cfset separatorNumber.period = "1.234.567.890,123456">
<cfset separatorNumber.lakh_crore = "1,23,45,67,890.123456">
<cfloop collection="#separatorNumber#" item="separator">
<p>
#separator# :
<input type="Text" value="#convertToNumber(separator, separatorNumber[separator])#">
Length : #Len(convertToNumber(separator, separatorNumber[separator]))#
</p>
</cfloop>
the length is 17, but in the input text it add extra white space at first char. I really don't know how to remove the extra white space, and when I add ToString(Trim())
<input type="Text" value="#ToString(Trim(convertToNumber(separator, separatorNumber[separator])))#">
it still have extra white space
thank you

Have you tried to added output="false" to your function tag?
<cffunction name="convertToNumber" returntype="numeric" output="false">...</cffunction>
Hope that helps.

I ran into a similar problem, and what worked for me was putting the value returned from the method into a variable and then outputting the variable instead of the return from the method. I didn't format it at all, but somehow that helped.

It's very simple. Put <cfsilent> in your <cffunction>. Need to put <cfsilent> after <cfargument>.
I've wrote about extra space within cffunction in my blog.
<cffunction name="convertToNumber" returntype="numeric">
<cfargument name="separator" required="Yes" type="string" />
<cfargument name="number" required="Yes" type="string" />
<cfsilent>
<cfset LOCAL.arrSeparator = ["comma", "period", "lakh_crore"] />
<cfif ARGUMENTS.separator eq "comma" or ARGUMENTS.separator eq "lakh_crore">
<cfif ListLen(ARGUMENTS.number, ".") eq 2>
<cfset LOCAL.integral = ListFirst(ARGUMENTS.number, ".") />
<cfset LOCAL.fractional = ListLast(ARGUMENTS.number, ".") />
<cfelse>
<cfset LOCAL.integral = ARGUMENTS.number />
<cfset LOCAL.fractional = "" />
</cfif>
<cfset LOCAL.integral = Replace(LOCAL.integral, ",", "", "ALL") />
<cfset LOCAL.returnValue = LOCAL.integral />
<cfif Len(Trim(LOCAL.fractional))>
<cfset LOCAL.returnValue &= "." & LOCAL.fractional />
</cfif>
</cfif>
<cfif ARGUMENTS.separator eq "period">
<cfif ListLen(ARGUMENTS.number, ",") eq 2>
<cfset LOCAL.integral = ListFirst(ARGUMENTS.number, ",") />
<cfset LOCAL.fractional = ListLast(ARGUMENTS.number, ",") />
<cfelse>
<cfset LOCAL.integral = ARGUMENTS.number />
<cfset LOCAL.fractional = "" />
</cfif>
<cfset LOCAL.integral = Replace(LOCAL.integral, ".", "", "ALL") />
<cfset LOCAL.returnValue = LOCAL.integral />
<cfif Len(Trim(LOCAL.fractional))>
<cfset LOCAL.returnValue &= "." & LOCAL.fractional />
</cfif>
</cfif>
<cfreturn LOCAL.returnValue />
</cfsilent>
</cffunction>
<cfset separatorNumber = StructNew() />
<cfset separatorNumber.comma = "1,234,567,890.123456" />
<cfset separatorNumber.period = "1.234.567.890,123456" />
<cfset separatorNumber.lakh_crore = "1,23,45,67,890.123456" />
<cfoutput>
<cfloop collection="#separatorNumber#" item="separator">
<p>
#separator# :
<input type="Text" value="#convertToNumber(separator, separatorNumber[separator])#">
Length : #Len(convertToNumber(separator, separatorNumber[separator]))#
</p>
</cfloop>
</cfoutput>

Related

ColdFusion zip an entire folder

I moved some files from one directory to another in my server. I would like to zip the destination folder after moving the files.
<cfoutput>
<cfset destination = expandPath("./TenantFiles/tempEmail/11/") />
<cfif not directoryExists(destination)>
<cfdirectory action="create" directory="#destination#">
<cfelse>
<cfdirectory action="delete" directory="#destination#" recurse="true">
<cfdirectory action="create" directory="#destination#">
</cfif>
<cfloop query="myQuery">
<cfset sourcefile = expandPath("./TenantFiles/11/#myQuery.TenantID#/#myQuery.DocumentName#") />
<cfif FileExists(sourcefile)>
<cfscript>
FileMove(#sourcefile#, #destination#);
</cfscript>
</cfif>
</cfloop>
<cfzip action="zip" file="#destination#\ZipFile.zip" source="#destination#" filter="*.pdf" />
</cfoutput>
It is returning the error:
Can not create a zip file with no entries.
Make sure that there is at least one entry in the zip file.
However the #destination# folder has a lot of pdf files.
Thanks
Instead of going back and forth on possible issues I created a function that can be used to test if there is something else going on in your environment. I eliminated movement of files and other possible sources of problems.
Try just setting up a test folder matching this example and see if that works before using your real query and files. I set it to not store path of files in zip as that was the result of your file movement and adding but it may not be what you want in the end.
<cfset myQuery = queryNew("") />
<cfset TenantIDs = [1,2,3,4] />
<cfset DocumentNames = ['one.pdf','two.pdf','three.txt','four.doc'] />
<cfset queryAddColumn(myQuery, 'TenantID', "integer", TenantIDs) />
<cfset queryAddColumn(myQuery, 'DocumentName', "varchar", DocumentNames) />
<cfset zipPdfFiles(expandPath('./testfiles'), myQuery, "TenantID", "DocumentName", expandPath('./testfiles/zipFile.zip'), "pdf") />
<cffunction name="zipPdfFiles" output="true">
<cfargument name="baseFilePath" required="true" />
<cfargument name="fileQuery" required="true" />
<cfargument name="folderColumn" required="true" />
<cfargument name="fileNameColumn" required="true" />
<cfargument name="zipFilePath" required="true" />
<cfargument name="allowExtensions" default="" hint="comma separated list of extensions or blank for all" />
<cfzip action="zip" file="#arguments.zipFilePath#" storePath="false">
<cfloop query="arguments.fileQuery">
<cfif not len(arguments.allowExtensions) or listFindNoCase(arguments.allowExtensions, listLast(myQuery.DocumentName, "."))>
<cfzipparam source="#arguments.baseFilePath#/#arguments.fileQuery[arguments.folderColumn][currentRow]#/#arguments.fileQuery[arguments.fileNameColumn][currentRow]#" />
</cfif>
</cfloop>
</cfzip>
</cffunction>

Variable CFUSION_ENCRYPT is undefined

0 experience with ColdFusion over here.
Got this project dropped off at my desk which was written by somebody 4 years ago, the person doesn't work with my company any more.
Got the logs from the live hosted website, and the error seems to exist on this line.
Line 196:
<p>Click here to activate your account</p>
I believe it might have something to do with the fact that the URL exists in quotes and the parameters are not correctly being passed? But I am not certain by any means.
I do not have the code base to test it or debug it, just the live deployed website.
Happy to get any suggestions on how to proceed with this.
Thanks!
If your CFML code is hosted on both new and pre-CF11 ColdFusion servers, you may need to use a user-defined function (UDF) to fill the gap. We used the following code while slowly testing & migrating older applications from CF7 to 2016. (Just add these functions to your codebase and rename existing "CFusion_" tags to "Fusion_".)
Published 10/20/2005 by Barney Boisvert:
http://www.barneyb.com/barneyblog/2005/10/28/cfusion_encryptcfusion_decrypt-udfs/
<cffunction name="fusion_encrypt" output="false" returntype="string">
<cfargument name="string" type="string" required="true" />
<cfargument name="key" type="string" required="true" />
<cfset var i = "" />
<cfset var result = "" />
<cfset key = repeatString(key, ceiling(len(string) / len(key))) />
<cfloop from="1" to="#len(string)#" index="i">
<cfset result = result & rJustify(formatBaseN(binaryXOR(asc(mid(string, i, 1)), asc(mid(key, i, 1))), 16), 2) />
</cfloop>
<cfreturn ucase(replace(result, " ", "0", "all")) />
</cffunction>
<cffunction name="fusion_decrypt" output="false" returntype="string">
<cfargument name="string" type="string" required="true" />
<cfargument name="key" type="string" required="true" />
<cfset var i = "" />
<cfset var result = "" />
<cfset key = repeatString(key, ceiling(len(string) / 2 / len(key))) />
<cfloop from="2" to="#len(string)#" index="i" step="2">
<cfset result = result & chr(binaryXOR(inputBaseN(mid(string, i - 1, 2), 16), asc(mid(key, i / 2, 1)))) />
</cfloop>
<cfreturn result />
</cffunction>
<cffunction name="binaryXOR" output="false" returntype="numeric">
<cfargument name="n1" type="numeric" required="true" />
<cfargument name="n2" type="numeric" required="true" />
<cfset n1 = formatBaseN(n1, 2) />
<cfset n2 = formatBaseN(n2, 2) />
<cfreturn inputBaseN(replace(n1 + n2, 2, 0, "all"), 2) />
</cffunction>
<h2>cfusion_encrypt Test</h2>
<cfset key = "test" />
<cfoutput>
<table>
<cfloop list="barney,is,damn cool!" index="i">
<tr>
<td>#i#</td>
<td>#cfusion_encrypt(i, key)#</td>
<td>#fusion_encrypt(i, key)#</td>
<td>#cfusion_decrypt(cfusion_encrypt(i, key), key)#</td>
<td>#fusion_decrypt(fusion_encrypt(i, key), key)#</td>
</tr>
</cfloop>
</table>
</cfoutput>
Sounds like you're using now a version of ColdFusion server that does not have the built in cfusion_encrypt() function.
Try this, change
cfusion_encrypt(uu.username, application.encKey)
to
encrypt(uu.username, application.encKey,'CFMX_COMPAT','HEX')
I hope it helps.

Amazon Seller Central API Error - Request signature we calculated does not match the signature you provided

I have been trying to implement the Amazon Seller Central API for getting the order details, using ColdFusion.The API response is an error stating that the
"
The request signature we calculated does not match the signature you
provided. Check your AWS Secret Access Key and signing method. Consult
the service documentation for details.
"
Code:
<cfcomponent displayname="AmazonOrderDetails">
<cfoutput>
<cfset variables.timeStamp = getIsoTimeString(now())>
<cffunction name="getOrderDetails" access="remote" returntype="any">
<cfhttp url="https://mws.amazonservices.com/Orders/2013-09-01" method="POST">
<cfhttpparam name="AWSAccessKeyId" type="url" value="XXXXXXXXXXXXX">
<cfhttpparam name="Action" type="url" value="ListOrders">
<cfhttpparam name="Marketplace" type="url" value="XXXXXXXXXXXXXX">
<cfhttpparam name="Merchant" type="url" value="XXXXXXXXXXXXX">
<cfhttpparam name="SignatureMethod" type="url" value="HmacSHA256">
<cfhttpparam name="SignatureVersion" type="url" value="2">
<cfhttpparam name="Signature" type="url" value="#generateSignature()#">
<cfhttpparam name="Timestamp" type="url" value="#variables.timeStamp#">
<cfhttpparam name="Version" type="url" value="2013-09-01">
<cfhttpparam name="CreatedAfter" type="url" value="#getIsoTimeString(dateAdd("m", -1, now()))#">
</cfhttp>
<cfdump var="#cfhttp.Filecontent#">
</cffunction>
<cffunction name="HMAC_SHA256" returntype="string" access="private" output="false">
<cfargument name="Data" type="string" required="true" />
<cfargument name="Key" type="string" required="true" />
<cfargument name="Bits" type="numeric" required="false" default="256" />
<cfset local.i = 0 />
<cfset local.HexData = "" />
<cfset local.HexKey = "" />
<cfset local.KeyLen = 0 />
<cfset local.KeyI = "" />
<cfset local.KeyO = "" />
<cfset local.HexData = BinaryEncode(CharsetDecode(Arguments.data, "iso-8859-1"), "hex") />
<cfset local.HexKey = BinaryEncode(CharsetDecode(Arguments.key, "iso-8859-1"), "hex") />
<cfset local.KeyLen = Len(local.HexKey)/2 />
<cfif local.KeyLen gt 64>
<cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />
<cfset local.KeyLen = Len(local.HexKey)/2 />
</cfif>
<cfloop index="i" from="1" to="#KeyLen#">
<cfset local.KeyI = local.KeyI & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(local.HexKey,2*i-
1,2),16),InputBaseN("36",16)),16),2) />
<cfset local.KeyO = local.KeyO & Right("0"&FormatBaseN(BitXor(InputBaseN(Mid(local.HexKey,2*i-
1,2),16),InputBaseN("5c",16)),16),2) />
</cfloop>
<cfset local.KeyI = local.KeyI & RepeatString("36",64-local.KeyLen) />
<cfset local.KeyO = local.KeyO & RepeatString("5c",64-local.KeyLen) />
<cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.KeyI&local.HexData, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1")
/>
<cfset local.HexKey = Hash(CharsetEncode(BinaryDecode(local.KeyO&local.HexKey, "hex"), "iso-8859-1"), "SHA-256", "iso-8859-1") />
<cfreturn Left(local.HexKey,arguments.Bits/4) />
</cffunction>
<cffunction name="getIsoTimeString" returntype="Any" access="private">
<cfargument name="datetime" type="date" required="true">
<cfset local.convertToUTC = true>
<cfif local.convertToUTC >
<cfset local.datetime = dateConvert( "local2utc", arguments.datetime )>
<cfreturn(
dateFormat( local.datetime, "yyyy-mm-dd" )&"T"&timeFormat( local.datetime, "HH:mm:ss" )&"Z"
)>
</cfif>
</cffunction>
<cffunction name="generateSignature" returntype="String" access="private">
<cfset local.secret_key="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx">
<cfset parameters = structNew() >
<cfset parameters["xxxxxxxxxxxxxxxxxxxx"] = "UserID">
<cfset parameters["1.0"] = "Version">
<cfset parameters["ListOrders"] = "Action">
<cfset parameters["#variables.timeStamp#"] = "Timestamp">
<cfset local.strtohash = "" >
<cfloop list="#ArrayToList(StructSort(parameters, "text", "asc"))#" index="key" >
<cfset local.strtohash = local.strtohash & #parameters[key]# & "=" & #URLEncodedFormat(key)# & "&" >
</cfloop>
<cfset local.strtohash = RemoveChars(local.strtohash, len(local.strtohash), 1)>
<cfset local.strtohash = Replace(local.strtohash, "%2D", "-", "All")>
<cfset local.strtohash = Replace(local.strtohash, "%2E", ".", "All")>
<cfset local.signature="#LCase(toBase64(HMAC_SHA256(local.strtohash, local.secret_key)))#">
<cfreturn local.signature>
</cffunction>
</cfoutput>
</cfcomponent>

What conditional logic to use for numbers with leading zeros?

I am running ColdFusion Enterprise 9.0.1.274733 on Windows Server 2008 R2 with Java 1.6.0_22.
I am calling a SOAP web service that returns various data to me. One of the data elements contains a code consisting of numbers with leading zeros. I am trying to convert that code into a text description but am having problems with the leading zeros. I have tried using the cfswitch tag as well as various things with the cfif tag. They are behaving a bit differently. I am looking for some suggestions on how to best handle these codes.
Here is an example of the code to description lookup:
Code Description
01 Automobile
010 Personal Automobile
011 Commercial Automobile
02 Home
03 Boat
10 Life
11 Umbrella
I initially attempted to use a cfswitch block to handle this but found that it treats the code as an integer. So as far as cfswitch is concerned; 010 is equal to 10. I have also tried using cfif. It also appears to be converting the value during the comparison. So as far as cfif is concerned the opposite is true; 10 is equal to 010.
How do you guys handle this issue?
Here is some example code that shows what is happening:
<html>
<head><title>Test</title></head>
<body>
<h3>Test</h3>
<cfset testvals = "01,010,011,10,11,12" />
<cfoutput>
<div>
<cfloop list="#testvals#" index="testval">
<p>testval = [#testval#]
<cfswitch expression="#testval#">
<cfcase value="01"> <cfset desc="matches 01" /> </cfcase>
<!---<cfcase value="010"> <cfset desc="matches 010" /></cfcase> --->
<!---<cfcase value="011"> <cfset desc="matches 011" /></cfcase> --->
<cfcase value="02"> <cfset desc="matches 02" /> </cfcase>
<cfcase value="03"> <cfset desc="matches 03" /> </cfcase>
<cfcase value="04"> <cfset desc="matches 04" /> </cfcase>
<cfcase value="08"> <cfset desc="matches 08" /> </cfcase>
<cfcase value="09"> <cfset desc="matches 09" /> </cfcase>
<cfcase value="10"> <cfset desc="matches 10" /> </cfcase>
<cfcase value="11"> <cfset desc="matches 11" /> </cfcase>
<cfcase value="12"> <cfset desc="matches 12" /> </cfcase>
<cfdefaultcase> <cfset desc="no match" /> </cfdefaultcase>
</cfswitch>
<br />cfswitch: #desc#
<cfif testval EQ "01">
<cfset desc="matches 01" />
<cfelseif testval EQ "010">
<cfset desc="matches 010" />
<cfelseif testval EQ "011">
<cfset desc="matches 011" />
<cfelseif testval EQ "02">
<cfset desc="matches 02" />
<cfelseif testval EQ "03">
<cfset desc="matches 03" />
<cfelseif testval EQ "04">
<cfset desc="matches 04" />
<cfelseif testval EQ "08">
<cfset desc="matches 08" />
<cfelseif testval EQ "09">
<cfset desc="matches 09" />
<cfelseif testval EQ "10">
<cfset desc="matches 10" />
<cfelseif testval EQ "11">
<cfset desc="matches 11" />
<cfelseif testval EQ "12">
<cfset desc="matches 12" />
<cfelse>
<cfset desc="no match" />
</cfif>
<br />cfif: #desc#
<cfif toString(testval) EQ "01">
<cfset desc="matches 01" />
<cfelseif toString(testval) EQ "010">
<cfset desc="matches 010" />
<cfelseif toString(testval) EQ "011">
<cfset desc="matches 011" />
<cfelseif toString(testval) EQ "02">
<cfset desc="matches 02" />
<cfelseif toString(testval) EQ "03">
<cfset desc="matches 03" />
<cfelseif toString(testval) EQ "04">
<cfset desc="matches 04" />
<cfelseif toString(testval) EQ "08">
<cfset desc="matches 08" />
<cfelseif toString(testval) EQ "09">
<cfset desc="matches 09" />
<cfelseif toString(testval) EQ "10">
<cfset desc="matches 10" />
<cfelseif toString(testval) EQ "11">
<cfset desc="matches 11" />
<cfelseif toString(testval) EQ "12">
<cfset desc="matches 12" />
<cfelse>
<cfset desc="no match" />
</cfif>
<br />tostring: #desc#
</p>
</cfloop>
</div>
</cfoutput>
</body>
</html>
Note that I had to comment out the cfcase tags for the values of 010 and 011 to avoid an error. If those are in the cfswitch then I get this error: Context validation error for the cfcase tag. The cfswitch tag has a duplicate cfcase tag for value 10.0. The error occurred on line -1.
Here is the output from the example code:
Test
testval = [01]
cfswitch: matches 01
cfif: matches 01
tostring: matches 01
testval = [010]
cfswitch: matches 10 // trying to avoid this
cfif: matches 010
tostring: matches 010
testval = [011]
cfswitch: matches 11 // trying to avoid this
cfif: matches 011
tostring: matches 011
testval = [10]
cfswitch: matches 10
cfif: matches 010 // trying to avoid this
tostring: matches 010 // trying to avoid this
testval = [11]
cfswitch: matches 11
cfif: matches 011 // trying to avoid this
tostring: matches 011 // trying to avoid this
testval = [12]
cfswitch: matches 12
cfif: matches 12
tostring: matches 12
I often use compare() to avoid undesired implicit conversion problems:
<cfif compare("010", testVal) EQ 0>
matches 010
</cfif>
But if you are just returning a single value, have you considered using a structure to do a simple look-up instead?
<cfset lookup = { "010"="matches 010", ...} >
<cfif structKeyExists(lookup, testVal)>
do something with #lookup[ testVal ]# ...
</cfif>
So as far as cfswitch is concerned; 010 is equal to 10
Edit: That sounds a little buggy IMO. The documentation mentions a similar issue with 0 versus 00 and states that it was fixed. But the error still occurs in CF 9. So you may want to submit a bug report.
The value "00" was also evaluated to the value 0. This caused the
exception “Context validation error for tag CFCASE. The CFSWITCH has a
duplicate CFCASE for value "0.0".” The tag now returns the
expected result.
why not just use val() and then do the cfswitch??? Val() will strip all leading zeroes from the value:
<cfset a = "010">
<cfset b = val(a)>
<cfdump var="#a#">
<cfdump var="#b#">
<cfdump var="#b eq 10#">

How to reference a returned structure from a cfc?

I'm using the validation CFC by Ryan J. Heldt http://validation.riaforge.org/
My form submits to processSignup.cfc
<cfscript>
objValidation = createObject("component","cfcs.validation").init();
objValidation.setFields(form);
objValidation.validate();
</cfscript>
<!--- clear the error/success message --->
<cfset msg="">
<cfif objValidation.getErrorCount() is not 0>
<cfsavecontent variable="msg">
<H2>Error in form submission</H2>
<P>There were <cfoutput>#objValidation.getErrorCount()#</cfoutput> errors in your submission:</P>
<ul>
<cfloop collection="#variables.objValidation.getMessages()#" item="rr">
<li><cfoutput>#variables.objValidation.getMessage(rr)#</cfoutput></li>
</cfloop>
</ul>
<p>Please use the back button on your browser to correct your submission.</p>
</cfsavecontent>
</cfif>
<cfdump var="#objvalidation#">
<cfoutput>
#msg#
</cfoutput>
Which gives me this output
What I'm trying figure out is the name of the structure and how to to get to "confirm password", "password", "username" but I'm being dense and I can't figure out how to.
<!---
<fusedoc fuse="Validation.cfc" language="ColdFusion" specification="2.0">
<responsibilities>
I am a ColdFusion Component that performs server-side form validation.
Copyright 2006-2008 Ryan J. Heldt. All rights reserved.
Validation.cfc is licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain
a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
If you use this component in a live site, I would love to know where! Please end
me a quick note at rheldt#ryanheldt.com with the name of the site the URL.
</responsibilities>
<property name="version" value="1.00" />
<property name="copyright" value="Copyright 2006-2008 Ryan J. Heldt." />
</properties>
</fusedoc>
--->
<cfcomponent displayname="Validation" hint="ColdFusion component that performs server-side form validation." output="false">
<!--- ---------- Properties ---------- --->
<cfproperty name="fields" type="struct" />
<cfproperty name="directories" type="struct" />
<cfproperty name="files" type="struct" />
<cfproperty name="errors" type="numeric" />
<cfproperty name="messages" type="struct" />
<cfproperty name="mimeTypes" type="array" />
<!--- ---------- Constructors ---------- --->
<cffunction name="init" access="public" output="false" returntype="Validation">
<cfscript>
_fields = structNew();
_directories = structNew();
_files = structNew();
_uploadedFiles = structNew();
_errors = 0;
_messages = structNew();
_cardTypes = structNew();
_mimeTypes = arrayNew(1);
</cfscript>
<cfreturn this />
</cffunction>
<!--- ---------- Accessors and Mutators ---------- --->
<cffunction name="getFields" access="public" output="false" returntype="struct">
<cfreturn _fields />
</cffunction>
<cffunction name="setFields" access="public" output="false" returntype="void">
<cfargument name="fields" type="struct" required="true" />
<cfset _fields = arguments.fields />
<cfreturn />
</cffunction>
<cffunction name="getDirectories" access="public" output="false" returntype="struct">
<cfreturn _directories />
</cffunction>
<cffunction name="setDirectories" access="public" output="false" returntype="void">
<cfargument name="directories" type="struct" required="true" />
<cfset _directories = arguments.directories />
<cfreturn />
</cffunction>
<cffunction name="getFiles" access="public" output="false" returntype="struct">
<cfreturn _files />
</cffunction>
<cffunction name="getErrorCount" access="public" output="false" returntype="numeric">
<cfreturn _errors />
</cffunction>
<cffunction name="getMessages" access="public" output="false" returntype="struct">
<cfreturn _messages />
</cffunction>
<cffunction name="getMessage" access="public" output="false" returntype="string">
<cfargument name="field" type="string" required="true" />
<cfif structKeyExists(_messages,field)>
<cfreturn _messages[field] />
<cfelse>
<cfreturn "" />
</cfif>
</cffunction>
<cffunction name="getCardType" access="public" output="false" returntype="string">
<cfargument name="field" type="string" required="true" />
<cfif structKeyExists(_cardTypes,field)>
<cfreturn _cardTypes[field] />
<cfelse>
<cfreturn "" />
</cfif>
</cffunction>
<cffunction name="getMimeTypes" access="public" output="false" returntype="array">
<cfreturn _mimeTypes />
</cffunction>
<!--- ---------- Public Methods ---------- --->
<cffunction name="validate" access="public" output="true" returntype="void">
<cfset var rr = 0 />
<cfloop list="#structKeyList(_fields)#" index="rr">
<cfif lCase(left(rr,9)) is "validate_">
<cfswitch expression="#lCase(rr)#">
<cfcase value="validate_require">
<!--- Required Fields --->
<cfset validateRequired(_fields[rr]) />
</cfcase>
<cfcase value="validate_integer">
<!--- Validate Integers --->
<cfset validateInteger(_fields[rr]) />
</cfcase>
<cfcase value="validate_numeric">
<!--- Validate Numeric --->
<cfset validateNumeric(_fields[rr]) />
</cfcase>
<cfcase value="validate_email">
<!--- Validate E-mail Addresses --->
<cfset validateEmail(_fields[rr]) />
</cfcase>
<cfcase value="validate_url">
<!--- Validate URLs --->
<cfset validateURL(_fields[rr]) />
</cfcase>
<cfcase value="validate_ip">
<!--- Validate IP Addresses --->
<cfset validateIP(_fields[rr]) />
</cfcase>
<cfcase value="validate_ssn">
<!--- Validate Socical Security Number (United States) nnn-nn-nnnn --->
<cfset validateSSN(_fields[rr]) />
</cfcase>
<cfcase value="validate_postal">
<!--- Validate Postal Code (United States and Canada) nnnnn or nnnnn-nnnn or ana-nan --->
<cfset validatePostal(_fields[rr]) />
</cfcase>
<cfcase value="validate_dateus">
<!--- Validate Date (United States) mm/dd/yyyy --->
<cfset validateDateUS(_fields[rr]) />
</cfcase>
<cfcase value="validate_dateeu">
<!--- Validate Date (Europe) dd/mm/yyyy --->
<cfset validateDateEU(_fields[rr]) />
</cfcase>
<cfcase value="validate_time">
<!--- Validate Time hh:mm:ss tt --->
<cfset validateDateEU(_fields[rr]) />
</cfcase>
<cfcase value="validate_phoneus">
<!--- Validate Phone Number (United States) nnn-nnn-nnnn --->
<cfset validatePhoneUS(_fields[rr]) />
</cfcase>
<cfcase value="validate_currencyus">
<!--- Validate Currency (United States) Allows optional "$", optional "-" or "()" but not both, optional cents, and optional commas separating thousands --->
<cfset validateCurrencyUS(_fields[rr]) />
</cfcase>
<cfcase value="validate_creditcard">
<!--- Validate Credit Card using Luhn Algorithm --->
<cfset validateCreditCard(_fields[rr]) />
</cfcase>
<cfcase value="validate_password">
<!--- Validate two fields to make sure they match. Comparison is case-sensitive --->
<cfset validatePassword(_fields[rr]) />
</cfcase>
<cfcase value="validate_file">
<!--- Upload files and validate their MIME types --->
<cfset loadMimeTypes() />
<cfset validateFile(_fields[rr]) />
</cfcase>
</cfswitch>
</cfif>
</cfloop>
<cfif val(_errors)>
<!--- If there were any validation errors, delete all the upload files --->
<cfset cleanupFiles() />
</cfif>
<cfreturn />
</cffunction>
<!--- ---------- Package Methods ---------- --->
<cffunction name="validateRequired" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif not (isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]))>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateInteger" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^-?\d+$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateNumeric" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not isNumeric(_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateEmail" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^[a-zA-Z][\w\.-]*[a-zA-Z0-9]#[a-zA-Z0-9][\w\.-]*[a-zA-Z0-9]\.[a-zA-Z][a-zA-Z\.]*[a-zA-Z]$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateURL" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("https?://([-\w\.]+)+(:\d+)?(/([\w/_\.]*(\?\S+)?)?)?",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateIP" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateSSN" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^\d{3}-\d{2}-\d{4}$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validatePostal" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^((\d{5}-\d{4})|(\d{5})|([A-Z]\d[A-Z]\s\d[A-Z]\d))$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateDateUS" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not (reFind("(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)\d\d",_fields[listGetAt(rr,1,"|")]) and isDate(_fields[listGetAt(rr,1,"|")]))>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateDateEU" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not (reFind("(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)\d\d",_fields[listGetAt(rr,1,"|")]) and isDate(_fields[listGetAt(rr,1,"|")]))>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateTime" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not (reFind("^((0?[1-9]|1[012])(:[0-5]\d){0,2}(\ [AP]M))$|^([01]\d|2[0-3])",uCase(_fields[listGetAt(rr,1,"|")])) and isDate(_fields[listGetAt(rr,1,"|")]))>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validatePhoneUS" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^[2-9]\d{2}-\d{3}-\d{4}$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateCurrencyUS" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and len(_fields[listGetAt(rr,1,"|")]) and not reFind("^\$?\-?([1-9]{1}[0-9]{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\-?\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))$|^\(\$?([1-9]{1}\d{0,2}(\,\d{3})*(\.\d{0,2})?|[1-9]{1}\d{0,}(\.\d{0,2})?|0(\.\d{0,2})?|(\.\d{1,2}))\)$",_fields[listGetAt(rr,1,"|")])>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateCreditCard" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<!--- Based on isCreditCard() by Nick de Voil (cflib.org/udf.cfm?id=49) --->
<cfset var strCardNumber = "" />
<cfset var strProcessedNumber = "" />
<cfset var intCalculatedNumber = 0 />
<cfset var isValid = false />
<cfset var rr = 0 />
<cfset var i = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfscript>
// Take out spaces and dashes. Flip card number around for processing
strCardNumber = replace(_fields[listGetAt(rr,1,"|")]," ","","all");
strCardNumber = replace(strCardNumber,"-","","all");
strCardNumber = reverse(strCardNumber);
_cardTypes[listGetAt(rr,1,"|")] = "Unknown";
// Double every other digit
if (isNumeric(strCardNumber) and len(strCardNumber) gt 12) {
for(i = 1; i lte len(strCardNumber); i = i + 1) {
if(i mod 2 is 0) {
strProcessedNumber = strProcessedNumber & mid(strCardNumber,i,1) * 2;
} else {
strProcessedNumber = strProcessedNumber & mid(strCardNumber,i,1);
}
}
// Sum processed digits
for(i = 1; i lte len(strProcessedNumber); i = i + 1) {
intCalculatedNumber = intCalculatedNumber + val(mid(strProcessedNumber,i,1));
}
// See if calculated number passed mod 10 test and attempt to determine card type
if(intCalculatedNumber neq 0 and intCalculatedNumber mod 10 is 0) {
isValid = true;
strCardNumber = reverse(strCardNumber);
if ((len(strCardNumber) eq 15) and (((left(strCardNumber,2) is "34")) or ((left(strCardNumber,2) is "37")))) {
_cardTypes[listGetAt(rr,1,"|")] = "Amex";
}
if ((len(strCardNumber) eq 14) and (((left(strCardNumber,3) gte 300) and (left(strCardNumber,3) lte 305)) or (left(strCardNumber,2) is "36") or (left(strCardNumber, 2) is "38"))){
_cardTypes[listGetAt(rr,1,"|")] = "Diners";
}
if ((len(strCardNumber) eq 16) and (left(strCardNumber,4) is "6011")) {
_cardTypes[listGetAt(rr,1,"|")] = "Discover";
}
if ((len(strCardNumber) eq 16) and (left(strCardNumber,2) gte 51) and (left(strCardNumber,2) lte 55)) {
_cardTypes[listGetAt(rr,1,"|")] = "MasterCard";
}
if (((len(strCardNumber) eq 13) or (len(strCardNumber) eq 16)) and (Left(strCardNumber,1) is "4")) {
_cardTypes[listGetAt(rr,1,"|")] = "Visa";
}
}
}
// Not a valid card number
if (not isValid) {
registerError(listGetAt(rr,1,"|"),listGetAt(rr,2,"|"));
}
</cfscript>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validatePassword" returntype="void" access="private" output="false">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cfif isDefined("#listGetAt(rr,1,"|")#") and isDefined("#listGetAt(rr,2,"|")#") and compare(_fields[listGetAt(rr,1,"|")],_fields[listGetAt(rr,2,"|")]) neq 0>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,3,"|")) />
</cfif>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="validateFile" returntype="void" access="private" output="true">
<cfargument name="parameters" type="string" required="true" />
<cfset var rr = 0 />
<cfset var strCurrentMimeType = "" />
<cfset var strCurrentFileExt = "" />
<cfset var aryValidFileExts = arrayNew(1) />
<cfset var strFilename = "" />
<cfset var blnValidFile = false />
<cfloop index="rr" list="#arguments.parameters#" delimiters=";">
<cftry>
<!--- Perform the upload --->
<cfif structKeyExists(_directories,"#listGetAt(rr,1,"|")#")>
<cfif len(evaluate("#listGetAt(rr,1,"|")#"))>
<cffile action="upload" filefield="#listGetAt(rr,1,"|")#" destination="#_directories[listGetAt(rr,1,"|")]#" nameconflict="makeunique" />
<cfset strCurrentMimeType = "#cffile.contentType#/#cffile.contentSubType#" />
<cfset strCurrentFileExt = "" />
<cfset aryValidFileExts = arrayNew(1) />
<cfset blnValidFile = false />
<!--- Determine file ext from MIME type --->
<cfloop from="1" to="#arrayLen(_mimeTypes)#" index="i">
<cfparam name="_mimeTypes[i]" default="0,0" />
<cfif listGetAt(_mimeTypes[i],2) is strCurrentMimeType>
<cfset strCurrentFileExt = "." & listGetAt(_mimeTypes[i],1) />
</cfif>
</cfloop>
<!--- Look what the server returned if unable to determine from MIME type --->
<cfif not len(strCurrentFileExt)>
<cfset strCurrentFileExt = "." & cffile.serverFileExt />
</cfif>
<!--- Rename the file and register in case we have to clean house--->
<cfset strFilename = "#generateFilename(cffile.clientFilename)##strCurrentFileExt#" />
<cffile action="rename" source="#cffile.serverDirectory#/#cffile.serverFile#" destination="#strFilename#" />
<cfset structInsert(_files,listGetAt(rr,1,"|"),strFilename)>
<cfset structInsert(_uploadedFiles,listGetAt(rr,1,"|"),#cffile.serverDirectory#&"/"&strFilename)>
<!--- Validate file type --->
<cfif listGetAt(rr,2,"|") neq "*">
<cfset aryValidFileExts = listToArray(listGetAt(rr,2,"|")) />
<cfloop from="1" to="#arrayLen(aryValidFileExts)#" index="i">
<cfif replaceNoCase(strCurrentFileExt,".","","all") is aryValidFileExts[i]>
<cfset blnValidFile = true />
</cfif>
</cfloop>
</cfif>
<cfif not blnValidFile>
<cfset registerError(listGetAt(rr,1,"|"),listGetAt(rr,3,"|")) />
</cfif>
</cfif>
<cfelse>
<!--- Developer didn't tell us the upload directory --->
<cfset registerError(listGetAt(rr,1,"|"),"There was no upload directory specified.") />
</cfif>
<cfcatch>
<cfset registerError(listGetAt(rr,1,"|"),"There was as problem uploading a file. Please contact the web site administrator. [#cfcatch.message# #cfcatch.detail#]") />
</cfcatch>
</cftry>
</cfloop>
<cfreturn />
</cffunction>
<cffunction name="registerError" returntype="void" access="private" output="false">
<cfargument name="field" type="string" required="true" />
<cfargument name="message" type="string" required="true" />
<cfset _errors = _errors + 1 />
<cfset _messages[field] = message />
<cfreturn />
</cffunction>
<cffunction name="generateFilename" returntype="string" access="private" output="false">
<cfargument name="originalFilename" type="string" required="true" />
<cfset var rr = 0 />
<cfset var strReturn="" />
<cfset var intCurrentCharacter=0 />
<cfset arguments.originalFilename=trim(lCase(arguments.originalFilename)) />
<cfloop index="rr" from="1" to="#len(arguments.originalFilename)#">
<cfset intCurrentCharacter=asc(mid(arguments.originalFilename,rr,1)) />
<cfif intCurrentCharacter is 32>
<!--- Space --->
<cfset strReturn=strReturn&"_" />
<cfelseif intCurrentCharacter gte 48 and intCurrentCharacter lte 57>
<!--- Numbers 0-9 --->
<cfset strReturn=strReturn&chr(intCurrentCharacter) />
<cfelseif (intCurrentCharacter gte 97 and intCurrentCharacter lte 122)>
<!--- Letters a-z --->
<cfset strReturn=strReturn&chr(intCurrentCharacter) />
<cfelse>
<!--- Skip Everything Else--->
</cfif>
</cfloop>
<cfif len(strReturn)>
<cfset strReturn = lCase(left(strReturn,35)) & "_" />
<cfelse>
<cfset strReturn = "untitled_" />
</cfif>
<cfreturn strReturn & dateFormat(now(),"yyyymmdd") & timeFormat(now(),"HHmmss") />
</cffunction>
<cffunction name="cleanupFiles" returntype="void" access="private" output="false">
<cfset var rr = "" />
<cfloop collection="#_uploadedFiles#" item="rr">
<cfif fileExists(structFind(_uploadedFiles,rr))>
<cffile action="delete" file="#structFind(_uploadedFiles,rr)#" />
</cfif>
</cfloop>
</cffunction>
<cffunction name="loadMimeTypes" returntype="void" access="private" output="false">
<cfscript>
// Microsoft Office Formats (Office 2003 and Prior)
_mimeTypes[1]="doc,application/msword";
_mimeTypes[2]="doc,application/vnd.ms-word";
_mimeTypes[3]="mdb,application/msaccess";
_mimeTypes[4]="mdb,application/vnd.ms-access";
_mimeTypes[5]="mpp,application/msproject";
_mimeTypes[6]="mpp,application/vnd.ms-project";
_mimeTypes[7]="one,application/msonenote";
_mimeTypes[8]="one,application/vnd.ms-onenote";
_mimeTypes[9]="ppt,application/mspowerpoint";
_mimeTypes[10]="ppt,application/vnd.ms-powerpoint";
_mimeTypes[11]="pub,application/mspublisher";
_mimeTypes[12]="pub,application/vnd.ms-publisher";
_mimeTypes[13]="xls,application/msexcel";
_mimeTypes[14]="xls,application/vnd.ms-excel";
// Microsoft Office Formats (Office 2007)
_mimeTypes[15]="docx,application/vnd.openxmlformats-officedocument.wordprocessingml.document";
_mimeTypes[16]="pptx,application/vnd.openxmlformats-officedocument.presentationml.presentation";
_mimeTypes[17]="xlsx,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
// Other Document Formats
_mimeTypes[18]="csv,text/csv";
_mimeTypes[19]="csv,text/comma-seperated-values";
_mimeTypes[20]="htm,text/html";
_mimeTypes[21]="pdf,application/pdf";
_mimeTypes[22]="rtf,application/rtf";
_mimeTypes[23]="rtf,text/rtf";
_mimeTypes[24]="txt,text/plain";
_mimeTypes[25]="xml,text/xml";
// Bitmap Image Formats
_mimeTypes[26]="bmp,image/bmp";
_mimeTypes[27]="gif,image/gif";
_mimeTypes[28]="jpg,image/jpeg";
_mimeTypes[29]="jpg,image/pjpeg";
_mimeTypes[30]="png,image/png";
_mimeTypes[31]="png,image/x-png";
_mimeTypes[32]="tif,image/tiff";
// Vector Image Formats
_mimeTypes[33]="ai,application/postscript";
_mimeTypes[34]="swf,application/x-shockwave-flash";
_mimeTypes[35]="svg,image/svg+xml";
// Video Formats
_mimeTypes[36]="avi,video/x-msvideo";
_mimeTypes[37]="mov,video/quicktime";
_mimeTypes[38]="mpg,video/mpeg";
_mimeTypes[39]="wmv,video/x-ms-wmv";
// Audio Formats
_mimeTypes[40]="au,audio/basic";
_mimeTypes[41]="mid,audio/midi";
_mimeTypes[42]="mp3,audio/mpeg";
_mimeTypes[43]="ogg,application/ogg";
_mimeTypes[44]="wav,audio/x-wav";
// Other Formats
_mimeTypes[45]="zip,application/zip";
</cfscript>
<cfreturn />
</cffunction>
</cfcomponent>
I'd think that since <cfdump var="#objvalidation#"> shows you the struct, you'd reference it via objValidation, no?
objValidation.messages should then show you the struct of the messages. Because "Confirm password" is a key with a space in it, you'll need to use array notation to reference it.
So...
#objValidation.messages[ 'Confirm password' ]#
#objValidation.messages[ 'password' ]#
#objValidation.messages[ 'username' ]#
...should work. In theory :)
EDIT: disregard the info above. You're dumping an actual object, not just a struct... so try:
<cfdump var="#objValidation.getMessages()#" />
Look at the code for the CFC and you'll see a getMessage() method which returns a struct. So once you have that, you can get at the individual messages. Since you won't necessarily know what keys exist in the struct (as I assume it will vary depending on the validation failures), I'd just loop over the struct returned from #objValidation.getMessages()# via a standard struct-based <cfloop>
EDIT AGAIN:
<cfloop collection="#objValidation.getMessages()#" item="error">
#error#: #objValidation.getMessages[ error ]#<br />
</cfloop>
If you're trying to get the values, it looks like they're in objValidation.fields:
objValidation.getField('Confirm password')
objValidation.getField('password')
objValidation.getField('username')
I'd recommend making your life easier and taking the space out of the "Confirm password" field.