HJCotton.net

July 26, 2010

Attachment filenames containing special characters and cfmailparam

by @ 7:30 pm. Filed under Coldfusion.

When you use cfmailparam to attach a file to an email being sent within cfmail, you may get an error that the file cannot be found (even when it actually exists). I noticed this particular condition when the attachment filename contained a plus sign ‘+’, but it probably occurs for other special characters as well. It doesn’t appear that cfmailparam can handle these well, and they get replaced with spaces. Based on the blog posts I’ve read, there doesn’t seem to be a quick workaround.

<cfmail from="#fromEmail#" to="#toEmail#" subject="Email w/ Attachment" type="html">
    I attached this file for your review. I <strong>swear</strong>, it's not a virus!
    <cfmailparam file="#ExpandPath('FileC+D.doc')">
</cfmail>

The solution I ended up using? Use ReReplace to replace invalid characters. This means that the attachment’s filename will have to change, but it is the only workaround I could find.

In ColdFusion 7, you’ll have to do this when the file is uploaded or just prior to it being attached. In 8 and beyond, you may be able to skip that intermediary step of using cffile to copy and save the file in order to get the filename you want. Instead, you may be able to use the content attribute of cfmailparam to feed in the contents of the file and give the content the filename to use, as per Ben Nadel’s excellent post here.

December 12, 2009

CF9 Ternary Operator

by @ 11:22 pm. Filed under Coldfusion.

Coldfusion 9 finally has a ternary operator. It’s certainly a lot prettier to use than an IIF(), and you won’t have to deal with those odd occasions where you need to use DE() to get things to work. Here’s an example of how it works in CF9 and the equivalent using an IIF() and a standard “if” (keep in mind that the loops are to demonstrate performance only – they are otherwise quite out-of-place):

<cfparam name="URL.name">
<cfparam name="URL.isLight">
 
<cfset startTernary = GetTickCount()>
<cfloop from="1" to="10000" index="i">
	<cfset beerName = !URL.isLight? URL.name & " is a good beer" : "No light beers in this list!">
</cfloop>
<cfset endTernary = GetTickCount()>
 
<cfset startIIF = GetTickCount()>
<cfloop from="1" to="10000" index="i">
	<cfset beerName = IIF(!URL.isLight, "'#URL.name# is a good beer'", "'No light beers in this list!'")>
</cfloop>
<cfset endIIF = GetTickCount()>
 
<cfset startIf = GetTickCount()>
<cfloop from="1" to="10000" index="i">
	<cfif URL.isLight>
		<cfset beerName = "No light beers in this list!">
	<cfelse>
		<cfset beerName = "#URL.name# is a good beer">
	</cfif>
</cfloop>
<cfset endIf = GetTickCount()>
 
<cfoutput>
	Ternary: #endTernary - startTernary#ms<br />
	IIF: #endIIF - startIIF#ms<br />
	If: #endIf - startIf#ms<br />
</cfoutput>

Even over 10,000 iterations, the ternary option is head-to-head with a standard if statement, and only slightly faster than an IIF:
Ternary: 62ms
IIF: 77ms
If: 62ms

I’ve always heard that IIFs were slow, but I’ve always found them so handy that I overlooked whatever the performance consequences might be. While noticeable in these tests, it’s not something that would affect most projects at all. These results are also backed up in this post by Ben Nadel.

I won’t be using CF9 in a production setting in the immediate future, so until then it’ll still be IIFs for me. Still, some of these new language improvements and features are definitely worth looking into (even if they should have been added long ago!).

September 9, 2009

CF in NC

by @ 5:34 am. Filed under Coldfusion.

I was not able to attend CFUnited this year, simply due to the high cost of the event. This was unfortunate as it is supposedly an awesome conference. Fortunately enough for me, a new CF conference is taking place in Raleigh, NC on October 17th and 18th. Best of all? It’s a free event! I can afford free, even if it is 6 hours away.

The list of speakers and topics isn’t finalized, but the preliminary list is pretty promising. Sounds like it should be a good time and I’m sure to learn a lot! Unfortunately, though, it is the same weekend as another low-cost conference of equal awesomeness (CPOSC), which I will not be able to attend.

CFinNC - Carolina ColdFusion / Flex / Air Conference - Oct 17-18, 2009

July 13, 2009

cfcatch was born a struct, then it wasn’t but now it’s back

by @ 9:19 pm. Filed under Coldfusion.

Recently, I came across an interesting “catch” when passing around a cfcatch structure. I created a function that would take a cfcatch struct and send out an email with the results formatted as I wanted them to be:

<cfcomponent output="false">
  <cffunction name="sendCFCatchEmail" access="public" output="false" returntype="void">
    <cfargument name="cfcatchStruct" type="struct" required="yes">
    <cfargument name="emailAddress" type="email" required="yes">
 
    <cfmail from="email@email.com" subject="Error" to="#arguments.emailAddress#" type="html">
      <table>
        <tr>
          <cfoutput>
            <td>#cfcatch.type#</td>
            <td>#cfcatch.message#</td>
            <td>#cfcatch.detail#</td>
          </cfoutput>
        </tr>
      </table>
    </cfmail>
 
  </cffunction>
</cfcomponent>

What threw me was that I kept getting the following error when passing a cfcatch struct to the function:

“The CFCATCHSTRUCT argument passed to the sendCFCatchEmail function is not of type struct.”

Huh?

The difficulty I was having was that when you dump a cfcatch, it identifies itself as a struct.

cfcatch

It took me a little while (and maybe some googling) to figure out what was going on. Doing an “isStruct(cfcatch)” shows that for some reason, cfcatch is not a structure. What is it then? Well, an “isObject(cfcatch)” shows that it’s an object… of some kind. The particularly odd part is that “Duplicate(cfcatch)” will return a structure, not an object. Weird, huh?

<cftry>
  <cfset answer = 3 / "t">
 
  <cfcatch>
    <cfoutput>
      <h2>Standard cfcatch</h2>
      Is Struct: #isStruct(cfcatch)#<br />
      Is Object: #isObject(cfcatch)#<br />
 
      <h2>Duplicated cfcatch</h2>
      Is Struct: #isStruct(Duplicate(cfcatch))#<br />
      Is Object: #isObject(Duplicate(cfcatch))#<br />
 
    </cfoutput>
  </cfcatch>
</cftry>

cfcatch Output

In short, I just ended up changing the expected type for the cfcatchStruct argument to be “any”. I could duplicate cfcatches before sending to the function, but that’s not optimal in the least, so I just let cfcatch pretend that it’s an object if that’s what it wants to be.

HJCotton.net

pages:

categories:

search:

archives:

September 2010
S M T W T F S
« Aug    
 1234
567891011
12131415161718
19202122232425
2627282930  

So it goes.
— Kurt Vonnegut

general links:

IMG_0340.jpg

IMG_0340.jpg

01-23-2010

01-23-2010

other:

Page 1 of 1First

19 queries. 0.922 seconds