Using ColdFusion to Zip Individual Files

I ran into an interesting situation this morning that didn't have an obvious answer. I needed to create a zip with a few specific files out of a directory with lots of possible files. The problem is that <cfzip /> is designed to work against whole directories, so at first I kept thinking that I'd have to make a temporary directory, move the files to it, and then zip the directory, but a little more persistence found the right answer.

 

Utility Functions: ListIsValid() and ListRemoveInvalid()

A gear One technique I often use is to create gateway objects to my database that allow the user to pass in multiple IDs, rather then a single one. I've run into a problem though; what if the user passes through something that is a valid list, but is not a valid list of the type I need? Read more to see ListIsValid() abd ListRemoveInvalid().

 

Utility Functions: CreateMapping() and RemoveMapping()

Some more "stolen" code for today's pair of utility functions. Thanks to FusionGrokker's post on controlling mappings in CF7. As FusionGrokker points out, these functions work in CF7, but its actually hacking global mapping values, so you could have problems.

<cffunction name="CreateMapping" output="false" returntype="void">
    <cfargument name="mapping" type="string" required="true" />
    <cfargument name="path" type="string" required="true" />
    
    <cfset var factory = CreateObject("java", "coldfusion.server.ServiceFactory") />
    <cfset var mappings = factory.runtimeService.getMappings() />
    
    <cfset mappings[arguments.mapping] = arguments.path />
    
    <cfreturn />
</cffunction>

<cffunction name="RemoveMapping" output="false" returntype="void">
    <cfargument name="mapping" type="string" required="true" />
    
    <cfset var factory = CreateObject("java", "coldfusion.server.ServiceFactory") />
    <cfset var mappings = factory.runtimeService.getMappings() />
    
    <cfset StructDelete(mappings, arguments.mapping) />
    
    <cfreturn />
</cffunction>

 

Utility Function: StructDeleteKeys()

A gear I often need to delete struct keys based on a list of items. Its not that I can't just loop the list and call StructDelete(), but it gets old, and this function makes it a little easier.

<cffunction name="StructDeleteKeys" returntype="void">
    <cfargument name="struct" type="struct" requried="true" />
    <cfargument name="keyList" type="string" requried="true" />
    <cfargument name="delimiters" type="string" required="false" default="," />
    
    <cfloop list="#arguments.keyList#" delimiters="#arguments.delimiters#" index="key">
        <cfset StructDelete(arguments.struct, key) />
    </cfloop>
    
    <cfreturn />
</cffunction>

 

Utility Functions: StructToListPairs() and ListPairsToStruct()

Today we have a pair of functions designed to convert structures into list pairs and back again. They serve as the back bone of another pair of functions that I'll release soon. StructToListPairs() is also useful when constructing long links (such as creating "sort" links for tables).

<cffunction name="StructToListPairs" returntype="string">
    <cfargument name="struct" type="struct" requried="true" />
    <cfargument name="delimiter1" type="string" required="false" default="&" />
    <cfargument name="delimiter2" type="string" required="false" default="=" />
    
    <cfset var buffer = CreateObject("java", "java.lang.StringBuffer").init() />
    
    <cfloop collection="#arguments.struct#" item="key">
        <cfset buffer.append(key) />
        <cfset buffer.append(delimiter2) />
        <cfset buffer.append(arguments.struct[key]) />
        <cfset buffer.append(delimiter1) />
    </cfloop>
    
    <cfif buffer.length() gt 1>
        <cfset buffer.setLength(buffer.length()-1) />
    </cfif>
    
    <cfreturn buffer.toString() />
</cffunction>

<cffunction name="ListPairsToStruct" returntype="struct">
    <cfargument name="list" type="string" requried="true" />
    <cfargument name="delimiter1" type="string" required="false" default="&" />
    <cfargument name="delimiter2" type="string" required="false" default="=" />
    
    <cfset var returnValue = StructNew() />
    
    <cfloop list="#arguments.list#" index="pair" delimiters="#arguments.delimiter1#">
        <cfset returnValue[ListFirst(pair, arguments.delimiter2)] = ListLast(pair, arguments.delimiter2) />
    </cfloop>
    
    <cfreturn returnValue />
</cffunction>

 

Utility Functions: Three String Functions

Here is a trio of functions based on a question from Hal Helm's "Are you OO Ready" quiz, in which he mentions that you can do the following:

<cfset x = "something" />
<cfset y = x />
<cfoutput>#y.equals(x)#</cfoutput>

So I came up with these:

<cffunction name="StringToChars" access="public" output="false" returntype="array">
    <cfargument name="string" type="string" required="true" />
    
    <cfreturn arguments.string.toCharArray() />
</cffunction>

<cffunction name="StringEndsWith" access="public" output="false" returntype="boolean">
    <cfargument name="string" type="string" required="true" />
    <cfargument name="suffix" type="string" required="true" />
    
    <cfreturn arguments.string.endsWith(arguments.suffix) />
</cffunction>

<cffunction name="StringBeginsWith" access="public" output="false" returntype="boolean">
    <cfargument name="string" type="string" required="true" />
    <cfargument name="prefix" type="string" required="true" />
    
    <cfreturn arguments.string.startsWith(arguments.prefix) />
</cffunction>

 

More Entries

Jon Hartmann, July 2011

I'm Jon Hartmann and I'm a Javascript fanatic, UX/UI evangelist and former ColdFusion master. I blog about mysterious error messages, user interface design questions, and all things baffling and irksome about programming for the web.

Learn more about me on LinkedIn.