Tracking who opened a document for reporting purposes
I have a need to keep track of who opened a document in the website. For example, I have built a module (called Projects) in which a 'project' can be associated with a document (document is a custom field of type 'Media').
I've looked at this posting http://www.sitefinity.com/developer-network/forums/developing-with-sitefinity-/how-do-i-track-who-is-accessing-documents and see how I can get the user information for who's accessing the files...My question is what would be the best approach to take in order to store this information so that it can be viewed/accessed later on (in a report). I'm not interested in storing this information in a log file as that's not an appropriate place to store this type of information. This information needs to be retained indefinetly.
What are my options? Create a custom table in the sitefinity database? Create a custom database to store this? Create some other type of module to associate this with?
I'd appreciate any input you might have.
I guess depends on your requirements :)
1) Like it might be neat to create a longtext field on the document itself, and everytime the event fires append the username to that longtext...
2) Or create a new table and map it in using OpenAccess, then just update that
3) Create a new Module builder type to store the data, on download run some code to add a new entry. Downside here is the download "log" is separate from the document in the UI.
So option 1&2 mean you don't have to create a UI to show the data...
I would defiantly not create a new DB though...just no need.
Thanks for your input. I've gone down a few different paths. Currently have leaned more towards your 3) and using custom fields to link information together. It's 'sorta' working -- however not as good as I'd like it. The two major links I'd like to include are the 'user' who is downloading the information, as well as the 'Project' that the document is associated with. I've created two custom fields to try to do this. A normal field control that binds the user information (got it working), and a dynamic field control that links to a seperate module (built with module builder). Unfortunately this isn't working as expected (and I thought it would be). I have a seperate thread on this, but sadly nobody's come to my rescue :(
What about this?
Yup, I've looked at that, and have all of that working. The problem I'm having is with saving the 'custom control field' value into the linked module. My scenario (dumbed down). I have a custom module called Projects. I have a custom module called TrackedDocuments. I created a custom control field in TrackedDocuments that binds to the content item 'Project' (of the Projects module) (so that there's a picker in the UI for people to use). It stores an array of Guids (the ProjectID). Everything works fine in the UI for when you create a new content item for TrackedDocuments.
What isn't working is when I try to create a new content item for TrackedDocuments in the codebehind of the LibrariesEventHandler (using the API referenced in the 'code reference' for the module)... I need to create items via the UI as well as through code (I create the item when the MediaContentDownloadedEvent event is fired)...
Guid opportunityId = Guid.NewGuid();
DynamicContent trackedDocumentItem = dynamicModuleManager.CreateDataItem(trackedDocumentType);
trackedDocumentItem.SetValue("Opp", new Guid opportunityId ); //Not saved, or doesn't appear to be saved because it's not being pre-populated when you go into edit the item after it's been created
I'm not sure how I can debug this -- perhaps the value is actually being saved properly, but in the UI of the content item (edit mode) the control responsible for rendering the items is not picking it up properly to display it as an item ? I'm perhaps starting to lean more on that as opposed to the value not being saved... maybe... is there a way to query the database directly to see if the value's been saved? I'm not sure which table this information is stored in...
Appreciate your suggestions
If you view the actual JSON for the dataItem coming down to populate that edit form, do you see your linked Guids?
...I'm wondering if you're just running into the same issue I'm dealing with at this moment (well I'm trying to "FIX" it right now)
In your thunder .js is it getting\saving the "OriginalContentId" or just the "Id" of the item?...and in the ".cs" for the field control, does the URL for the service path have "/Live" on the end of it?
I believe it's saving (and getting) the 'OriginalContentId'... this is straight boilerplate Thunder generated code (I haven't modified anything)... Is this possibly the issue? When I'm using the API to store in the GUID of my content Item, do I actually need to pass in the originalContentId of it? Not sure I'm doing that currently...I'm just passing in the ID of it... hrmmm
get_value: function ()
/*on publish if we have items in the kendo observable array
we get their ids in a aray of Guids so that they can be persisted*/
var selectedKeysArray = new Array();
var data = this._selectedItems.toJSON();
for (var i = 0; i < data.items.length; i++)
if (selectedKeysArray.length > 0)
set_value: function (value)
/*clears the observable array*/
/*if there are related items get them through the dynamic modules' data service*/
if (value != null && value != "")
var filterExpression = "";
for (var i = 0; i < value.length; i++)
if (i > 0)
filterExpression = filterExpression + ' OR ';
filterExpression = filterExpression + 'OriginalContentId == ' + value[i].toString();
var data =
headers: "SF_UI_CULTURE" : this.get_uiCulture() ,
contentType: "application/json; charset=utf-8",
/*on success add them to the kendo observable array*/
and yes, "/Live" is on the end of the service path:
private const string DynamicModulesDataServicePath = "~/Sitefinity/Services/DynamicModules/Data.svc/live/";
Per my other posting (not sure why I created two related to the same issue)... http://www.sitefinity.com/developer-network/forums/bugs-issues-/field-control-with-selector-for-dynamic-items-not-saving
I believe I've resolved my problem by referencing the Master ID of the dynamic content item (and not just by it's ID)... Hope this helps others
Hate to beat a dead horse.... but do you happen to know how to trap an event for when users only 'open' an item (like a .pdf). These events only seem to apply if the user actually downloads the file (chooses 'save as' in the dialog, as opposed to simply 'open')...
just as an FYI..i resolved this with a REST webservice and json call on the onclick event of the pdf link. Seems to do the job.