Ask a Jedi:Using cfdirectory and a form to delete files

This post is more than 2 years old.

This was a simple request, but I thought I'd share the code in case any other beginners would find it interesting. Joe asks:

I was after a method of being able to select results from a cfdirectory query using a form check box, then once a "delete selected" button is pressed it will then go on to delete them from the directory.

I currently have a page displaying all the files and folders now I just need a way so delete the selected records could you please help?

So as Joe pointed out, it's rather simple to use cfdirectory to create a list of files. Joe mentioned checkboxes and a simple form, so let's look at that part of the script first: <cfset directory="#expandPath('.')#">

<cfdirectory action="list" directory="#directory#" name="entries" type="file">

<cfoutput><form action="#cgi.script_name#" method="post"></cfoutput> <table> <cfoutput query="entries"> <tr> <td><input type="checkbox" name="files" value="#name#" /></td> <td>#name#</td> </tr> </cfoutput> </table> <input type="submit" value="DELETE" /> </form>

Normally the directory variable would point to some other folder instead of the current folder. This script would actually let you delete the script itself, which is probably not a good idea. Notice that I filtered by files. You can actually perform a recursive delete on a directory, but since Joe mentioned files I figured I'd keep it at that.

Notice next to each file we use a checkbox with the name files. When the form is submitted, each and every file will exist in the form value, files. If the user selects multiple files, then the values will be a list. Here is how I processed the form submission:

<cfif structKeyExists(form, "files") and len(form.files)> <cfloop index="f" list="#form.files#"> <cfif fileExists(directory & "/" & getFileFromPath(f))> <cffile action="delete" file="#directory#/#getFileFromPath(f)#"> </cfif> </cfloop> </cfif>

Nothing crazy here. Note though that I go the extra step to ensure the file exists before I delete it. In theory it is possible someone else could have deleted the file. (And to be real anal, I should use a cflock as well.)

As I said - easy stuff, but hopefully this example will help Joe. I'll print the entire sample below. Before doing so, don't forget that any web based application that lets you delete files is a risky. Please be sure you know what your doing before deploy code like this.

<cfset directory="#expandPath('.')#">

<cfif structKeyExists(form, "files") and len(form.files)> <cfloop index="f" list="#form.files#"> <cfif fileExists(directory & "/" & getFileFromPath(f))> <cffile action="delete" file="#directory#/#getFileFromPath(f)#"> </cfif> </cfloop> </cfif>

<cfdirectory action="list" directory="#directory#" name="entries" type="file">

<cfoutput><form action="#cgi.script_name#" method="post"></cfoutput> <table> <cfoutput query="entries"> <tr> <td><input type="checkbox" name="files" value="#name#" /></td> <td>#name#</td> </tr> </cfoutput> </table> <input type="submit" value="DELETE" /> </form>

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Elliott Sprehn posted on 10/23/2008 at 9:31 AM

Bad bad bad!!!

You should be using getFileFromPath() on the file in the fileExists() and <cffile action="delete">.

With what you have there I can pass a random path that contains ../../ and delete all the .cfm/.cfc files on your entire server! (Also probably everything else that the JRun user has permissions on)

Comment 2 by Joe Smith posted on 10/23/2008 at 11:37 AM

Thanks Muchly this has helped alot! I've managed to recreate this perfectly. As for Elliott's comment, this is only a school project and wont be accessible externally but i appreciate the concern.

Thanks Again Raymond =)

Comment 3 by John Whish posted on 10/23/2008 at 2:08 PM

@Joe, great to see ColdFusion being used for a school project! Good luck :)

Comment 4 by Raymond Camden posted on 10/23/2008 at 3:15 PM

Elliot, ok, ok ok! (Does saying it 3 times make it more true? ;)

Good point - here is the modified cfif block Joe.

<cfif fileExists(directory & "/" & getFileFromPath(f))>
<cffile action="delete" file="#directory#/#getFileFromPath(f)#">
</cfif>

Comment 5 by Elliott Sprehn posted on 10/23/2008 at 7:18 PM

@Ray

Hah, sorry about that ;)

It would be great if you'd fix the actual post though. For the same reasons posting sample code without cfqueryparam is dangerous, posting this is dangerous.

People copy and paste code and model code on well known, respected blogs, from respected developers... like you! And if that code has security flaws they get propagated all over the place.

Comment 6 by Raymond Camden posted on 10/23/2008 at 7:22 PM

Agreed and updated.

Comment 7 by Elliott Sprehn posted on 10/24/2008 at 1:18 AM

Thanks!