Introduction to ColdFusion Markup Language, concluded
If you want to get a good start on learning ColdFusion, look no further. This article covers a whole bunch of CFML tags and some basic functions. It is the second of two parts, and excerpted from chapter three of the book ColdFusion Web Development with Dreamweaver MX 2004, written by Jen and Peter deHaan et al. (Apress; ISBN: 1590592379).
Introduction to ColdFusion Markup Language, concluded - The cfdirectory tag (Page 4 of 6 )
Before we begin discussing the<cfdirectory>tag, it is important to understand a few of the risks involved with using the tag, along with a few other concerns. It is possible to use this tag to create, rename, and delete folders on the server, which can cause some problems in applications or lead to some destructive behavior. Very often, if you are hosting on a shared server, this tag will be disabled to prevent people from looking through system folders or doing anything malicious to other directories. If this tag hasn't been disabled, you should always exercise extreme care so you don't delete or modify the wrong directory.
The<cfdirectory>tag has four different actions:list,create,delete, andrename. You can use this tag to make ColdFusion create new directories on the server on the fly, which can be useful if you want to upload images and keep them in separate folders based on which galleries they belong to. We can also use this tag to list the contents of directories on the server, which makes it easy to have ColdFusion display a list of files in a particular folder that users can download via their web browser instead of FTP.
Let's go through each of the four actions in turn and look at them in more detail.
The listaction is responsible for listing the contents of a directory, and it returns a Recordset of the files and directories. The Recordset contains six columns as follows:
Name: The file or directory's name. In ColdFusion MX and above, it does not include "." or "..".
Size: Size of the file in bytes. Directories return 0.
Type: Either File or Dir.
DateLastModified: Date and time the file/directory was last modified.
Attributes: Tells you whether the directory is read-only (R) or hidden (H), if applicable.
Mode: Tells you the file permissions of the file/directory (UNIX and Linux only).
There is one new function in the following example that we havent seen yet called#ExpandPath()#:it takes a single parameter, a relative path (for example, .), and returns an absolute path.<cfdirectory action="list">requires an absolute path, such as"C:\CFusionMX\wwwroot\cfbook\", and a name, which ColdFusion assigns to the Recordset it creates.
Type the following code into a new ColdFusion file (listdirectory.cfm):
When you test the page, you will see a browser output similar to that shown in Figure 3-16.
Figure 3-16. Using the list action of <cfdirectory> to output the current directory contents
As you can see, this code outputs a list of all the files and subfolders of the current working directory. If you wanted ColdFusion to display recursively all files and the content of each folder as well, you would need to create your own function or custom tag to handle it. Read more about custom functions and tags in Chapter 10.
Thecreateaction simply creates a new directory. The syntax for this action is as follows:
Again, use the#ExpandPath()#function to expand the path of the current directory. Then append the name of the new folder that you want to create onto the path, which in this case is NewFolder. If the directory already exists, ColdFusion will throw an error.
We can programmatically check to see if a directory exists by using a ColdFusion function named#DirectoryExists()#. The #DirectoryExists()#function takes a single parameter, which is the fully qualified path of the directory that we want to check for.
If we save this file in ourcfbook directory and test it in a browser, a NewFolder folder will be created in ourcfbookfolder, and we will see the following message in the browser window:
Directory was created.
The first thing you'll notice in the preceding code is the#DirectoryExists()#function call. However, there are a couple other new things you haven't seen yet. Inside the#DirectoryExists()#function, the current directory path is expanded and appended with"\NewFolder\". If the directory already exists, the#DirectoryExists()#function returnsTrue, and the<cfif>statement block executes. If the directory doesnt exist yet, then the<cfelse>block executes, and the desired folder is created.
You could modify the preceding snippet as follows (createdirectory2.cfm):
<cfif NOT DirectoryExists( ExpandPath( ".\NewFolder\" ) )> <cfdirectory directory="#ExpandPath( '.\NewFolder\' )#" action="create"> Directory was created. </cfif>
In this case, if the directory doesn't already exist, ColdFusion will create the new directory and output a message saying that the directory was created successfully. If it does exist, then nothing happens, which is more pleasant than having a nasty error message returned to the user.
Notice the use of theNOT keyword. Because the#DirectoryExists()#function returnsTrueif the directory exists, adding theNOTkeyword to the<cfif>tag causes it to trigger only when the directory does not already exist. This is because if the directory doesnt exist, the#DirectoryExists()#function call returnsFalse. Therefore, by addingNOTto the statement, you are sayingNOT False, which evaluates toTrue, causing the<cfif>block to be executed.
Thedeleteaction deletes an existing directory. It is called in much the same way you call thecreateaction. However, there is one important thing to note: you cannot delete a directory if it contains any files or subfolders. An example of thedeleteaction syntax is shown here:
As with theCreateexample we presented previously, make sure that the directory exists (and that it is empty) before trying to delete it.
Open Dreamweaver, create a new file nameddeletedirectory.cfmin yourcfbookdirectory, and enter the following code into it:
<cfset targetFolder = ExpandPath( ".\NewFolder\" )> <cfif DirectoryExists( targetFolder )> <cfdirectory directory="#targetFolder#" action="list" name="CheckEmpty"> <cfif CheckEmpty.RecordCount EQ 0> <cfdirectory directory="#targetFolder#" action="delete"> Directory deleted. <cfelse> Directory was not empty. </cfif> <cfelse> Directory was not found. </cfif>
Delete the NewFolder folder we created in the previous example. Now test ourdeletedirectory.cfmfile in a web browser or in Live Data View. You should see a message on the screen saying "Directory was not found. "
Recreate the NewFolder folder under the current working directory. Within this folder create a new file or subfolder. Now rerun thedeletedirectory.cfm file, and you should see the message "Directory was not empty" as output.
Now delete all files and subfolders within the NewFolder directory (but do not delete the directory itself ) and run thedeletedirectory.cfmcode one last time. Now you should see the message "Directory deleted" on your screen, and the folder should have been deleted from insidecfbook.
Now lets look at how this code works.
In this code, you begin by creating a variable to hold the complete path of the directory that you want to delete. Next check to see if the directory exists on the server. If it does, proceed to check if the directory is empty. Call<cfdirectory action="list">, which in turn returns a Recordset of any files or subfolders that may be in the folder you are trying to delete.
For any Recordset created by ColdFusion, a few other variables are created automatically. The three main variables created areRecordCount,CurrentRow, andColumnList. These three variables work in the following way:
RecordCounttells you how many records are in the Recordset.
CurrentRowtells you which record you are currently on within the Recordset.
ColumnListtells you the name of the columns in the Recordset.
So, when you check the value of#CheckEmpty.RecordCount#, you are checking if any records are present in the Recordset. If therecordcountis equal to 0, then you can be sure that no files or subfolders are in the folder you are trying to delete. Therefore, it is safe to go ahead and delete the target directory.
The final action,rename, simply renames a folder. It is used as follows:
Unlike the delete action, a folder does not have to be empty to use therenameaction. You can safely rename a directory with files and subfolders inside. One important point to remember is that you must make sure that the new directory name, specified in thenewdirectoryattribute, is not already in use as a directory name in the current directory; ColdFusion will throw errors if this is the case. Because of this, it is advisable to use the#DirectoryExists()#function to verify that you dont already have a folder with that particular name.