Menu Close

CKEditor’s file manager and deleting files

FCKEditor's file manager with deleting filesFCKEditor is retired, but still widely used in many web applications. One of its great features is file manager that can be both invoked from editor or be used by itself. One of most painful limitations that this built-in file manager has is inability to delete files. But, as it turned out, it’s not a hard task to implement this functionality on Your own. In this post I’ll demonstrate how to do it in asp.net application(client-part is applicable for any other server-side framework).

I assume you already have your application witch uses FCKEditor, I’ll not show how to built one, it’s beyond this tutorial scope. I also assume that you have used FredCK control, but if you haven’t it shouldn’t be difficult to apply this tutorial anyway.

So lets start by downloading source of FredCK from here(sourceforge), and add project to solution that contains your project (if you are using VS newer than 2005 you’ll have to migrate project). Next replace reference to dll file with reference to the project you just added. If you prefer change name of FredCK project to mark that it’s not a standard version.

First of all we need to understand how it works. Files manager’s web page consists of frames, each frame displays a specific page, there’s one with files and folders list, one with file uploader etc. When pages are loaded they communicate with connectors using AJAX. Connectors are server-side programs responsible for performing actions on files at the server as well as sending informations about files and folders to client-side aplication.

We need to add buttons to delete files on listing. To do that open \FckEditor\editor\filemanager\browser\default\frmresourceslist.html (assuming that your FCKEditor resides in \FckEditor) and locate these function’s definitions:

  • oListManager.GetFolderRowHtml
  • oListManager.GetFileRowHtml

As names indicates they are used to form HTML representing, accordingly, folders and files in listing. Change them so they look like this:

oListManager.GetFolderRowHtml = function (folderName, folderPath) {
 // Build the link to view the folder.
 var sLink = '<a href="#">';
 var deleteLink = '<a href="#">Delete<\/a>';
 return '<tr>' +
 '<td width="16">' +
 sLink +
 '<img alt="" src="images/Folder.gif" width="16" height="16" border="0"><\/a>' +
 '<\/td><td>&nbsp;' +
 sLink +
 folderName +
 '<\/a>' +
 '<\/td>' + "<td>" + deleteLink + "<\/td>" + "<td><\/td>" + '<\/tr>';
}

oListManager.GetFileRowHtml = function (fileName, fileUrl, fileSize) {
 // Build the link to view the folder.
 var sLink = '<a href="#">' ;
 var deleteLink = '<a href="#">Delete<\/a>';
 // Get the file icon.
 var sIcon = oIcons.GetIcon( fileName ) ;

 return '<tr>' +
 '<td width="16">' +
 sLink +
 '<img alt="" src="images/icons/' + sIcon + '.gif" width="16" height="16" border="0"><\/a>' +
 '<\/td><td>&nbsp;' +
 sLink +
 fileName +
 '<\/a>' +
 '<\/td>'+"<td>"+deleteLink+"<\/td>"+'<td align="right" nowrap>&nbsp;' +
 fileSize +
 ' KB' +
 '<\/td><\/tr>' ;
}

Now you can preview changes by invoking your file browser, be sure that your browser cache is disabled thought(quick way to do this is to use firebug, and in net panel menu check “disable browser cache”). As you can see in code above we added links, that will be used to invoke functions, that will order server-side code to delete nodes. These functions looks like this:

function DeleteFile(fileUrl) {
 var name = fileUrl.split("/");
 name = name[name.length - 1];
 if(confirm("Delete "+name+"?"))
 oConnector.SendCommand('DeleteFile', "nodeToDelete=" + fileUrl, Refresh);
}

function DeleteDirectory(dirName) {
 if (confirm("Delete " + name + "?"))
 oConnector.SendCommand('DeleteDirectory', "nodeToDelete=" + dirName, Refresh);
}

I’ve used two different functions, because, for some reason, file manager handles files and folders paths in a different manner, files names are prefixed with user files folder, while directories names aren’t. Most important parts of functions above are lines with SendCommand method call. First argument is command – what we wont to tell server to do, second one is custom query string parameters, witch we use to pass our file url or directory name, third one is function that will get invoked after command will be completed. Refresh function is defined few lines below, name is quite self-explanatory.

Ok. That’s it for client part. Lets dig in into connector’s code. Open /FileBrowser/Connector.cs file from FredCK project. In OnLoad method find the part, where parameters are extracted form query string and add this:

string sPathOrName = Request.QueryString["nodeToDelete"];

Now scroll down a little bit, till you find switch statement, modify it by adding two new cases (corresponding to deleting file or deleting folder). After that case statement should look somehow like this:

			// Execute the required command.
			switch( sCommand )
			{
				case "GetFolders" :
					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
					break ;
				case "GetFoldersAndFiles" :
					this.GetFolders( oConnectorNode, sResourceType, sCurrentFolder ) ;
					this.GetFiles( oConnectorNode, sResourceType, sCurrentFolder ) ;
					break ;
				case "CreateFolder" :
					this.CreateFolder( oConnectorNode, sResourceType, sCurrentFolder ) ;
					break ;
				case "DeleteFile":
					this.DeleteFile(sPathOrName);
				break;
				case "DeleteDirectory":
					 this.DeleteDirectory(sPathOrName, sResourceType, sCurrentFolder);
					break;
				default :
					XmlResponseHandler.SendError( Response, 1, "Command is not allowed" ) ;
					break;
			}

And now, add methods to handle commands:

private void DeleteFile(string path)
{
	string sServerPath = Server.MapPath(path);

	if (File.Exists(sServerPath))
		File.Delete(sServerPath);
	else throw new ArgumentException("no such file: "+path);
}

private void DeleteDirectory(string directoryName, string resourceType, string currentFolder)
{
	var parts = directoryName.Replace('/', '\\\').Trim('\\\').Split('\\\');
	string path = ServerMapFolder(resourceType, currentFolder, false) + parts[parts.Length-1];

	if (Directory.Exists(path))
		Directory.Delete(path, true);
	else throw new ArgumentException("no such diretory: " + path);
}

And that’s quite it. Rebuild application, and enjoy deleting your files :-).

Disclaimer: Be careful when granting delete permissions to users of your application. Presented mechanism did not provide any way to control/limit access to other’s users files, perhaps you should thing of implementing that in your app.

Leave a Reply

Your email address will not be published. Required fields are marked *

*