Ask Ben: Creating An Archive Folder / File List

<!--- Kill extra output. --->
<cfsilent>
 
	<!---
		This is the name of the archive folder for which we
		want to list out the archive documents.
	--->
	<cfparam
		name="URL.folder"
		type="string"
		default=""
		/>
 
	<!--- Decode the folder value. --->
	<cfset URL.folder = UrlDecode( URL.folder ) />
 
	<!---
		For security reasons, we want to get rid of any suspect
		values in the folder variable. These include "../"
		which would go to a parent directory or "/" which will
		go to the root perhaps.
	--->
	<cfset URL.folder = URL.folder.ReplaceAll(
		"(\.\.[\\/])+", ""
		).ReplaceAll(
			"[\\/]+", ""
			) />
 
	<!---
		Set the directory path of the root archive
		directory (this one).
	--->
	<cfset strRoot = ExpandPath( "./" ) />
 
 
	<!---
		Check to see if we have an archive folder selected.
		If we do, then we want to query that one. If not,
		then we want to get the list of all the archive folders.
		Furthermore, if we have an archive folder, just
		check to make sure the folder exists.
	--->
	<cfif (
		Len( URL.folder ) AND
		DirectoryExists( strRoot & "\" & URL.folder )
		)>
 
		<!--- Set the query path to be the archive folder. --->
		<cfset strQueryPath = (strRoot & "\" & URL.folder) />
 
	<cfelse>
 
		<!---
			We have no archive folder selected (or it did not
			exist). Query the root directory.
		--->
		<cfset strQueryPath = strRoot />
 
		<!---
			Reset the folder variable so we don't get confused
			later on.
		--->
		<cfset URL.folder = "" />
 
	</cfif>
 
 
	<!---
		Query for the files / folders in the selected
		directory (might be root OR an archive folder). When
		sorting the directory list, we want to sort by name
		DESC if we are listing the archive folders, but sort
		by name ASC if we are listing out the documents.
	--->
	<cfdirectory
		action="LIST"
		directory="#strQueryPath#"
		recurse="false"
		sort="name #IIF( Len( URL.folder ), DE( 'ASC' ), DE( 'DESC' ) )#"
		name="qDirectoryList"
		/>
 
</cfsilent>
 
<cfoutput>
<html>
<head>
	<title>Document Archive</title>
</head>
<body>
 
	<h1>
		Document Archive
	</h1>
 
	<!---
		Check to see if we have a folder value. If we do then
		we are outputting the contents of that folder. If we do
		not, then we are outputting the archive folder list.
	--->
	<cfif Len( URL.folder )>
 
		<!--- We are listing out the archive documents. --->
		<h2>
			#URL.folder#
		</h2>
 
		<cfloop query="qDirectoryList">
 
			<!---
				Output the link to the file from the root
				directory (since that is where we will are).
				Include the name of the sub folder in the path.
			--->
			<p>
				<a href="./#UrlEncodedFormat( URL.folder )#/#UrlEncodedFormat( qDirectoryList.name )#">#qDirectoryList.name#</a>
			</p>
 
		</cfloop>
 
 
		<!--- Provide a link back to parent directory. --->
		<p>
			&laquo; <a href="#CGI.script_name#">Back To Archive</a>
		</p>
 
	<cfelse>
 
		<!--- We are viewing the archive folder list. --->
		<p>
			Please select an archive folder to view documents:
		</p>
 
		<cfloop query="qDirectoryList">
 
			<!---
				When outputting, we only want to display
				directories, not files (otherwise we might
				output the index.cfm file.
			--->
			<cfif (qDirectoryList.Type EQ "Dir")>
 
				<!---
					For each link, submit the page back to
					itself but pass in the requested folder
					name.
				--->
				<p>
					<a href="#CGI.script_name#?folder=#UrlEncodedFormat( qDirectoryList.name )#">#qDirectoryList.name#</a> &raquo;
				</p>
 
			</cfif>
 
		</cfloop>
 
	</cfif>
 
</body>
</html>
</cfoutput>

For Cut-and-Paste