Delete uploaded files upon node deletion for custom upload datatype properties
I have created a custom datatype for uploading multiple files. The imlpementation is done using an .ascx usercontrol that is wrapped for creating a new datatype. I would like to reproduce the behaviour of the current single-file upload datatype, so I have 3 questions:
1) How does the current Upload dataype creates the name for the folder where the file will be put? The folders are placed under the /media directory and their name is usually a number.
2) How does umbraco relates the uploaded file to the node and deletes the uploaded file when the node carrying the current upload datatype property gets deleted?
3) I have noticed that in the case of an image, the uploaded file gets deleted but its thumbnail does not, so there are left overs in the system from deleted nodes. Is this done on purpose?
My main concern is (2) because I want the uploaded files to be deleted by the system if the node get deleted. For doing this I need to know how the files and/or their container folder are related to the node carrying them.
1. Depends on settings (AllowUploadDirectories in umbracoSettings.config) and a id (which is retrieved from cmsPropertyData table)
2. Path to media node is stored in db, so on delete, it takes the path from the db and deletes the appropriate file on disk. You might be right on the node delete action (which doesn't delete the physical file). If so, create an event handler that registers for delete of media documents (nodes) and delete the uploaded file from disk.
3. Might be an issue, it should delete all files related to the image. I don't think that's on purpose. Once again, you could build an event handler that registers for delete of media items and remove all thumbnail files accordingly. Or, create a new work item on Codeplex and vote for it.
Thank you for your information and your help. Now that I know what how it is supposed to behave, I would like to ask a couple of things regarding the implementation. I'll keep the numbering for reference.
4) When inside the ascx control's code, how can I find the id of the row from the cmsPropertyData table where the files (property value) are stored? After postback, I collect the files that the user selected and upload them to the server. It is at that point where the id is needed in order to upload the physical files. I could find the id by selecting the row from the database if I knew the nodeID but it is not provided. I also tried "umbraco.presentation.nodeFactory.Node.GetCurrent()" for getting the current node, but it returns null. Is there any other way to discover the nodeID or the cmsPropertyData row id?
5) For deleteing the files upon node deletion I should create an event handler that registers for the BeforeDelete Document event, right? After building the necessary code, should I do something to "install" it in umbraco or simply subclassing the ApplicationBase and adding the event handling function does that automatically? In addition, should the event handling class be separate from the rest of the project or can it be compiled in the same .dll?
Finally I would like to ask regarding live editing.
6) For enabling live editing to edit my custom datatype should I implement the classes: xxxPrevalueEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor, fileUploadDataType and fileUploadDataEditor .presentation.LiveEditing.Modules.ItemEditing.ItemEditor.CreateFieldDataEditor(Item item), .presentation.LiveEditing.Modules.ItemEditing.ItemEditor.CreateChildControls()
6) For enabling live editing to edit my custom datatype should I implement the following classes? xxxDataEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor xxxDataType : umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType xxxPrevalueEditor : System.Web.UI.WebControls.PlaceHolder, umbraco.interfaces.IDataPrevalue And my main question about this is, after I complete the implementation, how are these "installed" in Umbraco? I assume that simply putting the .dll in the /bin directory will not suffice.
4. Really no idea atm, as i've done similar things but have not used a user control but instead used the 'other' approach (ie implementing IDataEditor, IDataPrevalue, ...)
5. Yes, register the BeforeDelete event (example below taken from a project of mine):
/// <summary>
/// Handles deletion of physical files (Only 'Protected Files')
/// </summary>
public class DeletePhysicalFile : ApplicationBase {
public DeletePhysicalFile(){
Media.BeforeDelete += OnMediaBeforeDelete;
}
/// <summary>
/// Handles the BeforeDelete event on media items
/// Deletes physical file from storage if type of media item is 'Protected File'
/// </summary>
/// <param name="sender">Media item that fires the event</param>
/// <param name="e">An instance of <see cref="DeleteEventArgs"/>DeleteEventArgs</param>
private static void OnMediaBeforeDelete(Media sender, DeleteEventArgs e) {
//umbraco framework takes care of firing events for child objects, so no need to check for folders, we just need to take care of actual deletion of the protected file.
if (string.Compare(sender.ContentType.Alias, Configuration.ProtectedMedia.Instance.Aliases.ProtectedFileAlias.UmbracoAlias, true) == 0)
FileStorageFactory.GetFileStorageImplementation().Delete(sender.Id);
}
}
6. No experience whatsoever with using Canvas, but the interfaces/classes you're mentioning are exactly the ones I've used for creating my own media upload datatype.
Installation is as easy as dropping the dll (doesn't matter where the code lives, it can be in any) into the /bin folder of the umbraco installation, restart the app to make sure your event gets registered on startup.
Thanks again Dirk for your help. With your inmformation I did some research and found the folowing:
4) For finding the node ID i used: "Request.QueryString["id"]". Then I accessed the row from [cmsPropertyData] and got the number for the directory name using:
SELECT TOP 1 [id] FROM [cmsPropertyData] NOLOCKWHERE [contentNodeId] = xxxx AND [propertytypeid] =(SELECT [id] FROM [cmsPropertyType] NOLOCKWHERE [Name] ='propertyName')ORDERBY [id] DESC
5) For deleting uploaded files upon node deletion I implemented & registered the umbraco.cms.businesslogic.web.Document.BeforeDelete event handler in the same .dll
The only thing that remains now is to make the datatype editable using the canvas. The functionality should be similar to the way the related links datatype works in the canvas, so:
7) In the admin section, when editing the node, the datatype renders fine and it is fully editable. But in the canvas I only get the interface for the uploadFile element (my datatype implements a multiple file uploade field using a single uploadFile element) and nothing else is shown, hence the rest functionality (add file, remove file) is not available. For achieving that, is there an interface related to LiveEdit I could implement?
As a summary, my datatype works fine now. The only thing that is missing is to make editable in the Canvas (7).
I did some more research today and I realised that when I click on it in the Canvas: a) Only the base controls that exist in the .ascx page get rendered b) The scripts (javascript) do not exist c) I do not receive the data from the property of the node being edited for displaying them.
Is there a way first to receive the data of the property? Can I make any scripts in the page to register or should I register them from the c-code behind? Mayby Tim that wrote the example for creating a datatype using usercontrol wrapping can help with this.
Delete uploaded files upon node deletion for custom upload datatype properties
I have created a custom datatype for uploading multiple files. The imlpementation is done using an .ascx usercontrol that is wrapped for creating a new datatype. I would like to reproduce the behaviour of the current single-file upload datatype, so I have 3 questions:
1) How does the current Upload dataype creates the name for the folder where the file will be put? The folders are placed under the /media directory and their name is usually a number.
2) How does umbraco relates the uploaded file to the node and deletes the uploaded file when the node carrying the current upload datatype property gets deleted?
3) I have noticed that in the case of an image, the uploaded file gets deleted but its thumbnail does not, so there are left overs in the system from deleted nodes. Is this done on purpose?
My main concern is (2) because I want the uploaded files to be deleted by the system if the node get deleted. For doing this I need to know how the files and/or their container folder are related to the node carrying them.
I am using umbraco 4.0.2.1 & .net framework 3.5
Manthos,
1. Depends on settings (AllowUploadDirectories in umbracoSettings.config) and a id (which is retrieved from cmsPropertyData table)
2. Path to media node is stored in db, so on delete, it takes the path from the db and deletes the appropriate file on disk. You might be right on the node delete action (which doesn't delete the physical file). If so, create an event handler that registers for delete of media documents (nodes) and delete the uploaded file from disk.
3. Might be an issue, it should delete all files related to the image. I don't think that's on purpose. Once again, you could build an event handler that registers for delete of media items and remove all thumbnail files accordingly. Or, create a new work item on Codeplex and vote for it.
Hope this helps.
Regards,
/Dirk
Thank you for your information and your help. Now that I know what how it is supposed to behave, I would like to ask a couple of things regarding the implementation. I'll keep the numbering for reference.
4) When inside the ascx control's code, how can I find the id of the row from the cmsPropertyData table where the files (property value) are stored? After postback, I collect the files that the user selected and upload them to the server. It is at that point where the id is needed in order to upload the physical files. I could find the id by selecting the row from the database if I knew the nodeID but it is not provided. I also tried "umbraco.presentation.nodeFactory.Node.GetCurrent()" for getting the current node, but it returns null. Is there any other way to discover the nodeID or the cmsPropertyData row id?
5) For deleteing the files upon node deletion I should create an event handler that registers for the BeforeDelete Document event, right? After building the necessary code, should I do something to "install" it in umbraco or simply subclassing the ApplicationBase and adding the event handling function does that automatically? In addition, should the event handling class be separate from the rest of the project or can it be compiled in the same .dll?
Finally I would like to ask regarding live editing.
6) For enabling live editing to edit my custom datatype should I implement the classes:
xxxPrevalueEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor, fileUploadDataType and fileUploadDataEditor
.presentation.LiveEditing.Modules.ItemEditing.ItemEditor.CreateFieldDataEditor(Item item),
.presentation.LiveEditing.Modules.ItemEditing.ItemEditor.CreateChildControls()
I'm rewriting (6) because it is incomplete:
6) For enabling live editing to edit my custom datatype should I implement the following classes?
xxxDataEditor : System.Web.UI.UpdatePanel, umbraco.interfaces.IDataEditor
xxxDataType : umbraco.cms.businesslogic.datatype.BaseDataType, umbraco.interfaces.IDataType
xxxPrevalueEditor : System.Web.UI.WebControls.PlaceHolder, umbraco.interfaces.IDataPrevalue
And my main question about this is, after I complete the implementation, how are these "installed" in Umbraco? I assume that simply putting the .dll in the /bin directory will not suffice.
Again thank you for your help and your time.
Manthos
Manthos,
4. Really no idea atm, as i've done similar things but have not used a user control but instead used the 'other' approach (ie implementing IDataEditor, IDataPrevalue, ...)
5. Yes, register the BeforeDelete event (example below taken from a project of mine):
6. No experience whatsoever with using Canvas, but the interfaces/classes you're mentioning are exactly the ones I've used for creating my own media upload datatype.
Installation is as easy as dropping the dll (doesn't matter where the code lives, it can be in any) into the /bin folder of the umbraco installation, restart the app to make sure your event gets registered on startup.
Cheers,
/Dirk
Thanks again Dirk for your help. With your inmformation I did some research and found the folowing:
4) For finding the node ID i used: "Request.QueryString["id"]". Then I accessed the row from [cmsPropertyData] and got the number for the directory name using:
SELECT TOP 1 [id] FROM [cmsPropertyData] NOLOCK WHERE [contentNodeId] = xxxx AND [propertytypeid] = (SELECT [id] FROM [cmsPropertyType] NOLOCK WHERE [Name] = 'propertyName') ORDER BY [id] DESC
5) For deleting uploaded files upon node deletion I implemented & registered the umbraco.cms.businesslogic.web.Document.BeforeDelete event handler in the same .dll
The only thing that remains now is to make the datatype editable using the canvas. The functionality should be similar to the way the related links datatype works in the canvas, so:
7) In the admin section, when editing the node, the datatype renders fine and it is fully editable. But in the canvas I only get the interface for the uploadFile element (my datatype implements a multiple file uploade field using a single uploadFile element) and nothing else is shown, hence the rest functionality (add file, remove file) is not available. For achieving that, is there an interface related to LiveEdit I could implement?
Thank you
Manthos
As a summary, my datatype works fine now. The only thing that is missing is to make editable in the Canvas (7).
I did some more research today and I realised that when I click on it in the Canvas:
a) Only the base controls that exist in the .ascx page get rendered
b) The scripts (javascript) do not exist
c) I do not receive the data from the property of the node being edited for displaying them.
Is there a way first to receive the data of the property? Can I make any scripts in the page to register or should I register them from the c-code behind? Mayby Tim that wrote the example for creating a datatype using usercontrol wrapping can help with this.
Again, thank you.
This is a very old topic but I am now trying to do the same thing Manthos did.
I didn't understand the answer for number 1 (and hence 4)
1) How does the current Upload dataype creates the name for the folder where the file will be put? (eg. /media/12345/)
4)
SELECT TOP 1 [id] FROM [cmsPropertyData] NOLOCKWHERE [contentNodeId] = xxxx AND [propertytypeid] =(SELECT [id] FROM [cmsPropertyType] NOLOCKWHERE [Name] ='propertyName')ORDERBY [id] DESC
How do you get the propertyName??
is working on a reply...