Question

I thought this would be a lot easier, however I'm unable to find a way to determine in my event handler if it is the FIRST check-in of the file..

You see, I'm breaking role inheritance, and selectively inheriting permissions for files in doc libs, yet I wish to do it only once, during the first check-in of the file.

I've tried adding an entry to 'SPListItem.Properties' in the ItemAdded event in order to indicate if the file is new, however the moment I do 'SPListItem.Update()' it vanishes..

I've played with the ItemCheckingIn and ItemCheckedIn events with no success...

My only hope at the moment is adding a SPField to the ContentType to indicate if new file or not, but I really wish to avoid it..

ANY IDEAS????

PLEASE HELP ME!

Was it helpful?

Solution 2

So I got a solution for this. I'm sorry I can't post code here, I do not have access to internet on my dev machine. It should be good enough for everyone.

Solution: During the CheckingIn event I try to access the file using the SHAREPOINT\system("SPSecurity.RunWithElevatedPrivileges()"). During the first check-in the file is new and not accessible to other users besides the uploader.

So if I fail getting the file with SHAREPOINT\system it means its new, and I save its Guid in a dictionary in my EventHandlers class.

Then in the CheckedIn event I simply check if the dictionary contains the Guid of the current item, if it does - FIRST CHECK-IN, if it does not - NOT FIRST CHECK-IN.

Of course after I'm finished with the file I remove the entry from the dictionary.

Hope it helps, if you got any questions you are welcome to ask :)

OTHER TIPS

I would recommend considering not only whether the system account has access, but also if the checked out date of the file is identical to the file's creation date.

public bool IsFirstCheckIn(SPListItem item)
{
    // Item not null!
    if (item != null)
    {
        SPSecurity.RunWithElevatedPrivileges(delegate
        {
            // Open privileged Site
            using (SPSite pSite = new SPSite(site.ID))
            {
                // Open privileged Web
                using (SPWeb pWeb = pSite.OpenWeb(web.ID))
                {
                    // Create privileged SharePoint-Objects
                    SPList pList = GetList(pWeb, list.ID);
                    SPListItem pItem = GetListItem(pList, item.UniqueId);

                    // Check the Item
                    if (pItem == null)
                    {
                        // Can't access
                        return true;
                    }
                    else if (pItem.File != null && pItem.File.CheckedOutByUser != null)
                    {
                        // If the Item's File and checked out User is set, check if checked out date is equal creation date
                        return (pItem.File.CheckedOutDate.ToLocalTime() == pItem.File.TimeCreated.ToLocalTime());
                    }
                }
            }            
        });    
    }

    return false;
}

To use the system account, is definitely a good idea, otherwise authorization settings would cause problems. Use the "local time" instead of the "UTC-Time", SharePoint handled the Time Zone while storing!

Seems like, SharePoint used the UTF-FileTime to store the file's creation time but used the Time Zone defined for the SPWeb or for the SPUser to store the file checked out date based on the "local time".

Fortunately the DateTime value does know what it is and can convert it to the same "local time" while calling ToLocalTime(). Strangely it will be still a File-Time while calling ToUniversalTime();

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top