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.
The problem is that the <cfzip /> tag requires a source directory attribute, even if you want a single file, so you have to break the file path up and pass in the directory, and then pass the file name into the filter attribute, so that it only matches that specific file.
Handling multiple files in the same folder is easy too, because you can pass in a comma-delimited list to the filter attribute.
If you have multiple files from different directories though, you have to go over each of them and break up the path yourself. If that sounds a little tedious, I went ahead and made a Utility Function that wraps up the implimentation nicely.
<cfargument name="zippath" type="string" required="true" />
<cfargument name="filePath" type="string" required="true" />
<cfargument name="overwrite" type="boolean" required="false" default="false" />
<cfzip action="zip" file="#arguments.zipPath#" source="#GetDirectoryFromPath(arguments.filePath)#" filter="#GetFileFromPath(arguments.filePath)#" overwrite="#YesNoFormat(arguments.overwrite)#" />
And it can be used like this:
<cfset ZipFile(zip, "#ExpandPath(".")#\utilities.cfc") />
<cfset ZipFile(zip, "#ExpandPath("./new")#\utilities2.cfc") />