This post was imported from FARMCode.org which has been discontinued. These posts now exist here as an archive. They may contain broken links and images.
Something I’ve heard a number of people say is that they want a way in which they can store the DocumentType in their source control system.

This is obviously a bit of a problem since they are actually stored in the database, not on the file system. Hmmm…

Then yesterday I was talking to Tatham Oddie about it and how you could go about CI with Umbraco. Then after bouncing a few ideas of Shannon we had a great idea, that when you say a DocumentType it would just dump it to the file system. You can then check this file into your source control system and you have a backup.

Sounds pretty simple, and in fact, Umbraco has all the stuff you’d need for this, it’s just a matter of doing it. So while waiting for a rather large project to check out of source control I decided to just write it.

Please note, the following code is not tested, it’s just a POC, when I get some time I do plan on actually testing it :P

How do go about it

It’s actually quite simple, you just need to tie into the Umbraco event model for a DocumentType and use the built in XML export feature.

I’ve also done the code so you can either dump to a single file or to multiple files (depending which is easiest in your solution.

It doesn’t check the files out for you, so if you’re using something like TFS you’ll have a problem, but I have put in handlers for read-only files.

Also, there’s no error checking, like I said, this is POC code :P.

Code baby!

using System.Linq;
using System.IO;
using System.Web;
using System.Xml.Linq;
using umbraco;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.web;

namespace AaronPowell.Umbraco
{
    public class DocumentTypeSerializer : ApplicationBase
    {
        public DocumentTypeSerializer()
        {
            DocumentType.AfterSave += new DocumentType.SaveEventHandler(DocumentType_AfterSave);
            DocumentType.AfterDelete += new DocumentType.DeleteEventHandler(DocumentType_AfterDelete);
        }

        void DocumentType_AfterDelete(DocumentType sender, umbraco.cms.businesslogic.DeleteEventArgs e)
        {
            DumpDocumentTypes(false);
        }

        void DocumentType_AfterSave(DocumentType sender, umbraco.cms.businesslogic.SaveEventArgs e)
        {
            DumpDocumentTypes(false);
        }

        private static void DumpDocumentTypes(bool useSingleFile)
        {
            var allDocTypes = DocumentType.GetAllAsList();
			var storageFolder = GlobalSettings.StorageDirectory + "/";
			System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument();
			
			if(useSingleFile)
			{
				var xdoc = new XDocument(new XElement("DocumentTypes"));

				foreach (var dt in allDocTypes)
					xdoc.Root.Add(XElement.Parse(dt.ToXml(xmlDoc).InnerXml));

				var file = storageFolder + "DocumentTypes.config";
				var fileOnFileSystem = new FileInfo(HttpContext.Current.Server.MapPath(file));
				if (fileOnFileSystem.Exists)
				{
					if (fileOnFileSystem.Attributes == FileAttributes.ReadOnly)
						fileOnFileSystem.Attributes &= ~FileAttributes.ReadOnly;
						
					fileOnFileSystem.Delete();
				}

				xdoc.Save(fileOnFileSystem.FullName);
			}
			else
			{
				storageFolder += "DocumentTypes/";
				if(!Directory.Exists(storageFolder))
				{
					Directory.Create(storageFolder);
				}
				else
				{
					var di = new DirectoryInfo(storageFolder);
					var files = di.GetFiles();
					foreach(var file in files) 
					{
						if (file.Exists)
						{
							if (file.Attributes == FileAttributes.ReadOnly)
								file.Attributes &= ~FileAttributes.ReadOnly;
								
							file.Delete();
						}
					}
				}				
				
				foreach(var dt in allDocTypes) 
				{
					var xdoc = XDocument.Parse(dt.ToXml(xmlDoc).ToString());
					
					var file = storageFolder + dt.Alias + ".config";
					
					var fileOnFileSystem = new FileInfo(HttpContext.Current.Server.MapPath(file));
					if (fileOnFileSystem.Exists)
					{
						if (fileOnFileSystem.Attributes == FileAttributes.ReadOnly)
							fileOnFileSystem.Attributes &= ~FileAttributes.ReadOnly;
							
						fileOnFileSystem.Delete();
					}

					xdoc.Save(fileOnFileSystem.FullName);
				}
			}
        }
    }
}

I'll look at cleaning this up and testing it soon and releasing it as an actual Umbraco package, but in the mean time feel free to have a play around with it.