Portal Engine
Version 3.x > Portal Engine > Upload Multiple Files and Overwrite existing View modes: 
User avatar
Member
Member
TC - 12/5/2008 4:39:09 AM
   
Upload Multiple Files and Overwrite existing
Hi,

I know we can upload multiple files using the File Import module, but is there a way to have the upload overwrite existing files with the same name?

I am thinking of maybe cloning the File Import Module and adding some logic to the "Start Import" event handler to check for file with the same name and deleting it before uploading the new file. But will there be an issue with the new uploaded file having a different GUID and thus causing problems with other controls that reference the file via the old GUID?

Thanks
TC

User avatar
Kentico Support
Kentico Support
kentico_zdenekc - 12/5/2008 7:40:49 AM
   
RE:Upload Multiple Files and Overwrite existing
Hi,

FileImport module unfortunatelly doesn't support files overwriting yet. You have a good point with the question, we will consider adding this ability for the future versions.

You could modify the module to be able to identify already existing files being uploaded. Then you could either get the GUIDs of these files and set them accordingly to newly uploaded files. However, this shouldn't be necessarry. As you probably know, the cms.File is document type with the binary data stored in 'Attachment' field (in DB, attachments are stored in CMS_Attachment table).

In the code, you could find the attachment using filename with the method FileManager.AttachmentManager.GetAttachments(string where,...); // Please check our API reference for details of the method.
Then you could update the attachment with new binary data so you won't need to manipulate with GUIDs etc., and the file will be simply overwritten.

The rest of files (uploaded for the first time) you could process the same way as before.

Hope this is clear enough...

Regards,
Zdenek Cetkovsky, Kentico

User avatar
Member
Member
TC - 12/10/2008 11:15:20 AM
   
RE:Upload Multiple Files and Overwrite existing
Hi Zdenek,

Thank you for the pointers. I have managed to extend the existing File Import Module to upload and overwrite existing files if present.

If anyone is interested, I have added a checkbox to the File Import Module called chkOverwriteExisting and I have the following code from line 293 in ~/CMSDesk/Tools/FileImport/Default.aspx.cs

if (chkOverwriteExisting.Checked)
{
FileInfo fi = new FileInfo(fileList[0]);

AttachmentManager attMan = new AttachmentManager();
DataSet existingFiles = attMan.GetAttachments("AttachmentName='" + fi.Name + "' AND AttachmentSiteID=" + CMSContext.CurrentSite.SiteID, "", true);

if (!DataHelper.DataSourceIsEmpty(existingFiles))
{
foreach (DataRow dr in existingFiles.Tables[0].Rows)
{
AttachmentInfo ai = new AttachmentInfo(dr, ConnectionHelper.GetConnection());

CMS.TreeEngine.TreeNode treeNode = TreeHelper.SelectSingleDocument(ai.AttachmentDocumentID);
if (treeNode.DocumentNamePath == targetAliasPath + "/" + fi.Name.Substring(0, fi.Name.LastIndexOf('.')))
{
if (ai.AttachmentMimeType.Contains("image"))
{
System.Drawing.Image img = System.Drawing.Image.FromFile(fileList[0]);
ai.AttachmentImageWidth = img.Width;
ai.AttachmentImageHeight = img.Height;
img.Dispose();
}

byte[] file = File.ReadAllBytes(fileList[0]);

ai.AttachmentSize = file.Length;
ai.AttachmentBinary = file;

attMan.SetAttachmentInfo(ai);
}
else
{
FileImport.ImportFiles(siteName, targetAliasPath, cultureCode, fileList, relativePathList, userId, chkDeleteImported.Checked);
}
}
}
else
{
FileImport.ImportFiles(siteName, targetAliasPath, cultureCode, fileList, relativePathList, userId, chkDeleteImported.Checked);
}
}
else
{
FileImport.ImportFiles(siteName, targetAliasPath, cultureCode, fileList, relativePathList, userId, chkDeleteImported.Checked);
}

if (!chkDeleteImported.Checked)
{
resultList.Add(ResHelper.GetString("Tools.FileImport.Imported"));
}

Thanks
TC

User avatar
Certified Developer 8
Certified Developer 8
bryan-bit-wizards - 10/14/2009 9:06:46 AM
   
RE:Upload Multiple Files and Overwrite existing
TC,

I was looking to do the exact thing and your code helped me a ton. However, I was dealing with versioned documents (Worklofw). Here is how I modified your code. Hope this helps anyone with the same issue.

- Added chkAutoPublish checkbox to the form

-Code Changes

//Determine the alias path
string strAliasPath = targetAliasPath + "/";
if (chkIncludeExtension.Checked)
{
strAliasPath += fileName.Replace(".", "-");
}
else
{
strAliasPath += fileName.Substring(0, fileName.LastIndexOf('.'));
}


//Check if files should be updated or added as new files
if (chkOverwriteExisting.Checked)
{
CMS.TreeEngine.TreeNode treeNode = tree.SelectSingleNode(CMSContext.CurrentSiteName, strAliasPath, CMSContext.CurrentUser.PreferredCultureCode, false, "cms.file", false);
//See if there is an existing doucment
if (treeNode != null)
{
//Update the existing document
// Get latest version of the document
treeNode = DocumentHelper.GetDocument(treeNode, tree);
// Check out the document
VersionManager vm = new VersionManager(tree);
vm.CheckOut(treeNode);
// Update the document
DocumentHelper.AddAttachment(treeNode, "FileAttachment", fileList[0], tree);
DocumentHelper.UpdateDocument(treeNode, tree);
// Check in the document
vm.CheckIn(treeNode, null, null);
}
else
{
//Add the new document
FileImport.ImportFiles(siteName, targetAliasPath, cultureCode, fileList, relativePathList, userId, chkDeleteImported.Checked);
}


//Check if imported file should be immediately published
if (chkAutoPublish.Checked)
{
CMS.TreeEngine.TreeNode newnode = tree.SelectSingleNode(CMSContext.CurrentSiteName, strAliasPath, CMSContext.CurrentUser.PreferredCultureCode,false,"cms.file",false);
// Move the document to the next step (approve)
WorkflowManager wm = new WorkflowManager(tree);
WorkflowStepInfo currentStep = wm.GetStepInfo(newnode);
while ((currentStep != null) && (currentStep.StepName.ToLower() != "published"))
{
currentStep = wm.MoveToNextStep(newnode, "");
}
}