Wednesday, March 20, 2013

Content approval for folders

Due to unfortunate necessity, I'm having to take our SP2010 branding apart bit-by-bit, redo the solution, and get dragged screaming and kicking into the 21st century of SP2010 development (IE - VS2010 on a server, no more STSDEV). I've certainly had my share of frustrations learning what everyone already knows here, but I discovered a new item that I'd only seen one other person mention anything about. I'm adding masterpages to the site's Master Page Gallery in the solution. Nothing big there. As someone with branding experience might already know, sometimes the masterpages won't be content-approved when you upload them, meaning that your event handler needs to be able to check them in on-the-fly. Nothing big there.
                using (SPSite site = (SPSite)properties.Feature.Parent)
                {
                    SPList masterPageGallery = site.GetCatalog(SPListTemplateType.MasterPageCatalog);
                    SPFolder masterPageTargetFolder = masterPageGallery.RootFolder.SubFolders[themeName];

                    foreach (SPFile file in masterPageTargetFolder.Files)
                    {
                        SPListItem listItem = file.Item;

                        if (!listItem.HasPublishedVersion)
                        {
                            listItem.File.CheckIn("Automatically added by installation feature.", SPCheckinType.MajorCheckIn);
                            listItem.File.Update();
                            listItem.File.Approve("Automatically added by installation feature.");
                            listItem.File.Update();
                        }
                    }
                }
Now, it turns out that since I'm putting the masterpages for this theme in their own folder, the folder also is subject to content type approval (not that this is relevant to the masterpages being accessible). So, let's say we want to be good citizens and have that folder automatically checked in when the code runs. Well, how do you do that? There's no .CheckIn() method on SPFolder or SPListItem...and if you think you'll be clever and try masterPageTargetFolder.Item.File.CheckIn(), the File member is null, so you'll find yourself quickly dashed. I found this post by Jay Noirfalise that got me part of the way there (using SPModerationInformation), but it didn't quite work.
                    SPList masterPageGallery = site.GetCatalog(SPListTemplateType.MasterPageCatalog);

                    SPFolder masterPageTargetFolder = masterPageGallery.RootFolder.SubFolders[themeName];
                    SPListItem masterPageTargetFolderItem = masterPageTargetFolder.Item;
                    SPModerationInformation moderationInformation = masterPageTargetFolderItem.ModerationInformation;
                    moderationInformation.Comment = "Automatically added by installation feature.";
                    moderationInformation.Status = SPModerationStatusType.Approved;
                    masterPageTargetFolderItem.Update();
For starters, it looked a little off to me. If I'm instantiating a SPModerationInformation object and then setting properties there, don't I need to save that object back to the SPListItem to effect the change? I tried to verify this in PowerShell and my suspicions were confirmed - nothing changed when I did this. Maybe it worked like that in WSS/MOSS? I dunno. Further, the SPListItem.ModerationInformation member is read-only. So, you just need to drill into the properties and set them inside the ModerationInformation member, like so:
                    SPList masterPageGallery = site.GetCatalog(SPListTemplateType.MasterPageCatalog);

                    SPFolder masterPageTargetFolder = masterPageGallery.RootFolder.SubFolders[themeName];
                    SPListItem masterPageTargetFolderItem = masterPageTargetFolder.Item;
                    masterPageTargetFolderItem.ModerationInformation.Comment = "Automatically added by installation feature.";
                    masterPageTargetFolderItem.ModerationInformation.Status = SPModerationStatusType.Approved;
                    masterPageTargetFolderItem.SystemUpdate(false);
But it still doesn't work. After running the matching code in PowerShell, my folder is still "Pending". You might notice one change I made which breaks this whole thing. It makes a little sense if you think about it - the approval's supposed to be done by a human, so we can't use SystemUpdate(false) to effect the change, because then there's no record of who did the change.
                    SPList masterPageGallery = site.GetCatalog(SPListTemplateType.MasterPageCatalog);

                    SPFolder masterPageTargetFolder = masterPageGallery.RootFolder.SubFolders[themeName];
                    SPListItem masterPageTargetFolderItem = masterPageTargetFolder.Item;
                    masterPageTargetFolderItem.ModerationInformation.Comment = "Automatically added by installation feature.";
                    masterPageTargetFolderItem.ModerationInformation.Status = SPModerationStatusType.Approved;
                    masterPageTargetFolderItem.Update(true);
Use Update() or SystemUpdate(true), and you're all set.

No comments:

Post a Comment