* U4-4748 - refactor Content-, Media- and MemberTypeRepository * Cleanup Attempt * Cleanup OperationStatus * U4-4748 - refactor Content-, Media- and MemberTypeService * U4-4748 - cleanup locking * U4-4748 - refactor Content-, Media- and MemberRepository * U4-4748 - refactor ContentService (in progress) * U4-4748 - all unit of work must be completed * U4-4748 - refactor locks, fix tests * U4-4748 - deal with fixmes * U4-4748 - lock table migration * Update UmbracoVersion * Fix AuthorizeUpgrade * U4-4748 - cleanup+bugfix lock objects * U4-4748 - bugfix * updates a string interpolation
546 lines
27 KiB
C#
546 lines
27 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Web;
|
|
using System.Xml;
|
|
using System.Xml.Linq;
|
|
using Umbraco.Core.Configuration;
|
|
using Umbraco.Core.Models;
|
|
using Umbraco.Core.Persistence.Repositories;
|
|
using Umbraco.Core.PropertyEditors;
|
|
using Umbraco.Core.Strings;
|
|
|
|
namespace Umbraco.Core.Services
|
|
{
|
|
//TODO: Move the rest of the logic for the PackageService.Export methods to here!
|
|
|
|
/// <summary>
|
|
/// A helper class to serialize entities to XML
|
|
/// </summary>
|
|
internal class EntityXmlSerializer
|
|
{
|
|
/// <summary>
|
|
/// Exports an <see cref="IContent"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="contentService"></param>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="userService"></param>
|
|
/// <param name="content">Content to export</param>
|
|
/// <param name="urlSegmentProviders"></param>
|
|
/// <param name="deep">Optional parameter indicating whether to include descendents</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the Content object</returns>
|
|
public XElement Serialize(
|
|
IContentService contentService,
|
|
IDataTypeService dataTypeService,
|
|
IUserService userService,
|
|
IEnumerable<IUrlSegmentProvider> urlSegmentProviders,
|
|
IContent content,
|
|
bool deep = false)
|
|
{
|
|
if (contentService == null) throw new ArgumentNullException("contentService");
|
|
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
|
if (userService == null) throw new ArgumentNullException("userService");
|
|
if (content == null) throw new ArgumentNullException("content");
|
|
if (urlSegmentProviders == null) throw new ArgumentNullException("urlSegmentProviders");
|
|
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
|
var nodeName = content.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
|
|
|
var xml = Serialize(dataTypeService, content, content.GetUrlSegment(urlSegmentProviders), nodeName);
|
|
xml.Add(new XAttribute("nodeType", content.ContentType.Id));
|
|
xml.Add(new XAttribute("creatorName", content.GetCreatorProfile(userService).Name));
|
|
xml.Add(new XAttribute("writerName", content.GetWriterProfile(userService).Name));
|
|
xml.Add(new XAttribute("writerID", content.WriterId));
|
|
xml.Add(new XAttribute("template", content.Template == null ? "0" : content.Template.Id.ToString(CultureInfo.InvariantCulture)));
|
|
xml.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias));
|
|
|
|
if (deep)
|
|
{
|
|
var descendants = contentService.GetDescendants(content).ToArray();
|
|
var currentChildren = descendants.Where(x => x.ParentId == content.Id);
|
|
AddChildXml(contentService, dataTypeService, userService, urlSegmentProviders, descendants, currentChildren, xml);
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an <see cref="IMedia"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="mediaService"></param>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="userService"></param>
|
|
/// <param name="media">Media to export</param>
|
|
/// <param name="urlSegmentProviders"></param>
|
|
/// <param name="deep">Optional parameter indicating whether to include descendents</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the Media object</returns>
|
|
public XElement Serialize(
|
|
IMediaService mediaService,
|
|
IDataTypeService dataTypeService,
|
|
IUserService userService,
|
|
IEnumerable<IUrlSegmentProvider> urlSegmentProviders,
|
|
IMedia media,
|
|
bool deep = false)
|
|
{
|
|
if (mediaService == null) throw new ArgumentNullException("mediaService");
|
|
if (dataTypeService == null) throw new ArgumentNullException("dataTypeService");
|
|
if (userService == null) throw new ArgumentNullException("userService");
|
|
if (media == null) throw new ArgumentNullException("media");
|
|
if (urlSegmentProviders == null) throw new ArgumentNullException("urlSegmentProviders");
|
|
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
|
var nodeName = media.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
|
|
|
var xml = Serialize(dataTypeService, media, media.GetUrlSegment(urlSegmentProviders), nodeName);
|
|
xml.Add(new XAttribute("nodeType", media.ContentType.Id));
|
|
xml.Add(new XAttribute("writerName", media.GetCreatorProfile(userService).Name));
|
|
xml.Add(new XAttribute("writerID", media.CreatorId));
|
|
xml.Add(new XAttribute("version", media.Version));
|
|
xml.Add(new XAttribute("template", 0));
|
|
xml.Add(new XAttribute("nodeTypeAlias", media.ContentType.Alias));
|
|
|
|
if (deep)
|
|
{
|
|
var descendants = mediaService.GetDescendants(media).ToArray();
|
|
var currentChildren = descendants.Where(x => x.ParentId == media.Id);
|
|
AddChildXml(mediaService, dataTypeService, userService, urlSegmentProviders, descendants, currentChildren, xml);
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an <see cref="IMember"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="member">Member to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the Member object</returns>
|
|
public XElement Serialize(IDataTypeService dataTypeService, IMember member)
|
|
{
|
|
//nodeName should match Casing.SafeAliasWithForcingCheck(content.ContentType.Alias);
|
|
var nodeName = member.ContentType.Alias.ToSafeAliasWithForcingCheck();
|
|
|
|
var xml = Serialize(dataTypeService, member, "", nodeName);
|
|
xml.Add(new XAttribute("nodeType", member.ContentType.Id));
|
|
xml.Add(new XAttribute("nodeTypeAlias", member.ContentType.Alias));
|
|
|
|
xml.Add(new XAttribute("loginName", member.Username));
|
|
xml.Add(new XAttribute("email", member.Email));
|
|
|
|
xml.Add(new XAttribute("icon", member.ContentType.Icon));
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(IDataTypeService dataTypeService, Property property)
|
|
{
|
|
var propertyType = property.PropertyType;
|
|
var nodeName = property.Alias.ToSafeAlias();
|
|
|
|
var xElement = new XElement(nodeName);
|
|
|
|
|
|
//Get the property editor for thsi property and let it convert it to the xml structure
|
|
var propertyEditor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);
|
|
if (propertyEditor != null)
|
|
{
|
|
var xmlValue = propertyEditor.ValueEditor.ConvertDbToXml(property, propertyType, dataTypeService);
|
|
xElement.Add(xmlValue);
|
|
}
|
|
|
|
return xElement;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an <see cref="IDataTypeDefinition"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="dataTypeDefinition">IDataTypeDefinition type to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IDataTypeDefinition object</returns>
|
|
public XElement Serialize(IDataTypeService dataTypeService, IDataTypeDefinition dataTypeDefinition)
|
|
{
|
|
var prevalues = new XElement("PreValues");
|
|
var prevalueList = dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeDefinition.Id)
|
|
.FormatAsDictionary();
|
|
|
|
var sort = 0;
|
|
foreach (var pv in prevalueList)
|
|
{
|
|
var prevalue = new XElement("PreValue");
|
|
prevalue.Add(new XAttribute("Id", pv.Value.Id));
|
|
prevalue.Add(new XAttribute("Value", pv.Value.Value ?? ""));
|
|
prevalue.Add(new XAttribute("Alias", pv.Key));
|
|
prevalue.Add(new XAttribute("SortOrder", sort));
|
|
prevalues.Add(prevalue);
|
|
sort++;
|
|
}
|
|
|
|
var xml = new XElement("DataType", prevalues);
|
|
xml.Add(new XAttribute("Name", dataTypeDefinition.Name));
|
|
//The 'ID' when exporting is actually the property editor alias (in pre v7 it was the IDataType GUID id)
|
|
xml.Add(new XAttribute("Id", dataTypeDefinition.PropertyEditorAlias));
|
|
xml.Add(new XAttribute("Definition", dataTypeDefinition.Key));
|
|
xml.Add(new XAttribute("DatabaseType", dataTypeDefinition.DatabaseType.ToString()));
|
|
|
|
var folderNames = string.Empty;
|
|
if (dataTypeDefinition.Level != 1)
|
|
{
|
|
//get url encoded folder names
|
|
var folders = dataTypeService.GetContainers(dataTypeDefinition)
|
|
.OrderBy(x => x.Level)
|
|
.Select(x => HttpUtility.UrlEncode(x.Name));
|
|
|
|
folderNames = string.Join("/", folders.ToArray());
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(folderNames) == false)
|
|
xml.Add(new XAttribute("Folders", folderNames));
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(IDictionaryItem dictionaryItem)
|
|
{
|
|
var xml = new XElement("DictionaryItem", new XAttribute("Key", dictionaryItem.ItemKey));
|
|
foreach (var translation in dictionaryItem.Translations)
|
|
{
|
|
xml.Add(new XElement("Value",
|
|
new XAttribute("LanguageId", translation.Language.Id),
|
|
new XAttribute("LanguageCultureAlias", translation.Language.IsoCode),
|
|
new XCData(translation.Value)));
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(Stylesheet stylesheet)
|
|
{
|
|
var xml = new XElement("Stylesheet",
|
|
new XElement("Name", stylesheet.Alias),
|
|
new XElement("FileName", stylesheet.Path),
|
|
new XElement("Content", new XCData(stylesheet.Content)));
|
|
|
|
var props = new XElement("Properties");
|
|
xml.Add(props);
|
|
|
|
foreach (var prop in stylesheet.Properties)
|
|
{
|
|
props.Add(new XElement("Property",
|
|
new XElement("Name", prop.Name),
|
|
new XElement("Alias", prop.Alias),
|
|
new XElement("Value", prop.Value)));
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(ILanguage language)
|
|
{
|
|
var xml = new XElement("Language",
|
|
new XAttribute("Id", language.Id),
|
|
new XAttribute("CultureAlias", language.IsoCode),
|
|
new XAttribute("FriendlyName", language.CultureName));
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(ITemplate template)
|
|
{
|
|
var xml = new XElement("Template");
|
|
xml.Add(new XElement("Name", template.Name));
|
|
xml.Add(new XElement("Alias", template.Alias));
|
|
xml.Add(new XElement("Design", new XCData(template.Content)));
|
|
|
|
var concreteTemplate = template as Template;
|
|
if (concreteTemplate != null && concreteTemplate.MasterTemplateId != null)
|
|
{
|
|
if (concreteTemplate.MasterTemplateId.IsValueCreated &&
|
|
concreteTemplate.MasterTemplateId.Value != default(int))
|
|
{
|
|
xml.Add(new XElement("Master", concreteTemplate.MasterTemplateId.ToString()));
|
|
xml.Add(new XElement("MasterAlias", concreteTemplate.MasterTemplateAlias));
|
|
}
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(IDataTypeService dataTypeService, IMediaType mediaType)
|
|
{
|
|
var info = new XElement("Info",
|
|
new XElement("Name", mediaType.Name),
|
|
new XElement("Alias", mediaType.Alias),
|
|
new XElement("Icon", mediaType.Icon),
|
|
new XElement("Thumbnail", mediaType.Thumbnail),
|
|
new XElement("Description", mediaType.Description),
|
|
new XElement("AllowAtRoot", mediaType.AllowedAsRoot.ToString()));
|
|
|
|
var masterContentType = mediaType.CompositionAliases().FirstOrDefault();
|
|
if (masterContentType != null)
|
|
info.Add(new XElement("Master", masterContentType));
|
|
|
|
var structure = new XElement("Structure");
|
|
foreach (var allowedType in mediaType.AllowedContentTypes)
|
|
{
|
|
structure.Add(new XElement("MediaType", allowedType.Alias));
|
|
}
|
|
|
|
var genericProperties = new XElement("GenericProperties"); // actually, all of them
|
|
foreach (var propertyType in mediaType.PropertyTypes)
|
|
{
|
|
var definition = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId);
|
|
|
|
var propertyGroup = propertyType.PropertyGroupId == null // true generic property
|
|
? null
|
|
: mediaType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
|
|
|
|
var genericProperty = new XElement("GenericProperty",
|
|
new XElement("Name", propertyType.Name),
|
|
new XElement("Alias", propertyType.Alias),
|
|
new XElement("Type", propertyType.PropertyEditorAlias),
|
|
new XElement("Definition", definition.Key),
|
|
new XElement("Tab", propertyGroup == null ? "" : propertyGroup.Name),
|
|
new XElement("Mandatory", propertyType.Mandatory.ToString()),
|
|
new XElement("Validation", propertyType.ValidationRegExp),
|
|
new XElement("Description", new XCData(propertyType.Description)));
|
|
genericProperties.Add(genericProperty);
|
|
}
|
|
|
|
var tabs = new XElement("Tabs");
|
|
foreach (var propertyGroup in mediaType.PropertyGroups)
|
|
{
|
|
var tab = new XElement("Tab",
|
|
new XElement("Id", propertyGroup.Id.ToString(CultureInfo.InvariantCulture)),
|
|
new XElement("Caption", propertyGroup.Name),
|
|
new XElement("SortOrder", propertyGroup.SortOrder));
|
|
|
|
tabs.Add(tab);
|
|
}
|
|
|
|
var xml = new XElement("MediaType",
|
|
info,
|
|
structure,
|
|
genericProperties,
|
|
tabs);
|
|
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(IMacro macro)
|
|
{
|
|
var xml = new XElement("macro");
|
|
xml.Add(new XElement("name", macro.Name));
|
|
xml.Add(new XElement("alias", macro.Alias));
|
|
xml.Add(new XElement("scriptType", macro.ControlType));
|
|
xml.Add(new XElement("scriptAssembly", macro.ControlAssembly));
|
|
xml.Add(new XElement("scriptingFile", macro.ScriptPath));
|
|
xml.Add(new XElement("xslt", macro.XsltPath));
|
|
xml.Add(new XElement("useInEditor", macro.UseInEditor.ToString()));
|
|
xml.Add(new XElement("dontRender", macro.DontRender.ToString()));
|
|
xml.Add(new XElement("refreshRate", macro.CacheDuration.ToString(CultureInfo.InvariantCulture)));
|
|
xml.Add(new XElement("cacheByMember", macro.CacheByMember.ToString()));
|
|
xml.Add(new XElement("cacheByPage", macro.CacheByPage.ToString()));
|
|
|
|
var properties = new XElement("properties");
|
|
foreach (var property in macro.Properties)
|
|
{
|
|
properties.Add(new XElement("property",
|
|
new XAttribute("name", property.Name),
|
|
new XAttribute("alias", property.Alias),
|
|
new XAttribute("sortOrder", property.SortOrder),
|
|
new XAttribute("propertyType", property.EditorAlias)));
|
|
}
|
|
xml.Add(properties);
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an <see cref="IContentType"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="contentTypeService"></param>
|
|
/// <param name="contentType">Content type to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IContentType object</returns>
|
|
public XElement Serialize(IDataTypeService dataTypeService, IContentTypeService contentTypeService, IContentType contentType)
|
|
{
|
|
var info = new XElement("Info",
|
|
new XElement("Name", contentType.Name),
|
|
new XElement("Alias", contentType.Alias),
|
|
new XElement("Icon", contentType.Icon),
|
|
new XElement("Thumbnail", contentType.Thumbnail),
|
|
new XElement("Description", contentType.Description),
|
|
new XElement("AllowAtRoot", contentType.AllowedAsRoot.ToString()),
|
|
new XElement("IsListView", contentType.IsContainer.ToString()));
|
|
|
|
var masterContentType = contentType.ContentTypeComposition.FirstOrDefault(x => x.Id == contentType.ParentId);
|
|
if(masterContentType != null)
|
|
info.Add(new XElement("Master", masterContentType.Alias));
|
|
|
|
var compositionsElement = new XElement("Compositions");
|
|
var compositions = contentType.ContentTypeComposition;
|
|
foreach (var composition in compositions)
|
|
{
|
|
compositionsElement.Add(new XElement("Composition", composition.Alias));
|
|
}
|
|
info.Add(compositionsElement);
|
|
|
|
var allowedTemplates = new XElement("AllowedTemplates");
|
|
foreach (var template in contentType.AllowedTemplates)
|
|
{
|
|
allowedTemplates.Add(new XElement("Template", template.Alias));
|
|
}
|
|
info.Add(allowedTemplates);
|
|
|
|
if (contentType.DefaultTemplate != null && contentType.DefaultTemplate.Id != 0)
|
|
info.Add(new XElement("DefaultTemplate", contentType.DefaultTemplate.Alias));
|
|
else
|
|
info.Add(new XElement("DefaultTemplate", ""));
|
|
|
|
var structure = new XElement("Structure");
|
|
foreach (var allowedType in contentType.AllowedContentTypes)
|
|
{
|
|
structure.Add(new XElement("DocumentType", allowedType.Alias));
|
|
}
|
|
|
|
var genericProperties = new XElement("GenericProperties"); // actually, all of them
|
|
foreach (var propertyType in contentType.PropertyTypes)
|
|
{
|
|
var definition = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId);
|
|
|
|
var propertyGroup = propertyType.PropertyGroupId == null // true generic property
|
|
? null
|
|
: contentType.PropertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
|
|
|
|
var genericProperty = new XElement("GenericProperty",
|
|
new XElement("Name", propertyType.Name),
|
|
new XElement("Alias", propertyType.Alias),
|
|
new XElement("Type", propertyType.PropertyEditorAlias),
|
|
new XElement("Definition", definition.Key),
|
|
new XElement("Tab", propertyGroup == null ? "" : propertyGroup.Name),
|
|
new XElement("SortOrder", propertyType.SortOrder),
|
|
new XElement("Mandatory", propertyType.Mandatory.ToString()),
|
|
propertyType.ValidationRegExp != null ? new XElement("Validation", propertyType.ValidationRegExp) : null,
|
|
propertyType.Description != null ? new XElement("Description", new XCData(propertyType.Description)) : null);
|
|
|
|
genericProperties.Add(genericProperty);
|
|
}
|
|
|
|
var tabs = new XElement("Tabs");
|
|
foreach (var propertyGroup in contentType.PropertyGroups)
|
|
{
|
|
var tab = new XElement("Tab",
|
|
new XElement("Id", propertyGroup.Id.ToString(CultureInfo.InvariantCulture)),
|
|
new XElement("Caption", propertyGroup.Name),
|
|
new XElement("SortOrder", propertyGroup.SortOrder));
|
|
tabs.Add(tab);
|
|
}
|
|
|
|
var xml = new XElement("DocumentType",
|
|
info,
|
|
structure,
|
|
genericProperties,
|
|
tabs);
|
|
|
|
var folderNames = string.Empty;
|
|
//don't add folders if this is a child doc type
|
|
if (contentType.Level != 1 && masterContentType == null)
|
|
{
|
|
//get url encoded folder names
|
|
var folders = contentTypeService.GetContainers(contentType)
|
|
.OrderBy(x => x.Level)
|
|
.Select(x => HttpUtility.UrlEncode(x.Name));
|
|
|
|
folderNames = string.Join("/", folders.ToArray());
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(folderNames) == false)
|
|
xml.Add(new XAttribute("Folders", folderNames));
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used by Media Export to recursively add children
|
|
/// </summary>
|
|
/// <param name="mediaService"></param>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="userService"></param>
|
|
/// <param name="urlSegmentProviders"></param>
|
|
/// <param name="originalDescendants"></param>
|
|
/// <param name="currentChildren"></param>
|
|
/// <param name="currentXml"></param>
|
|
private void AddChildXml(IMediaService mediaService, IDataTypeService dataTypeService, IUserService userService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IMedia[] originalDescendants, IEnumerable<IMedia> currentChildren, XElement currentXml)
|
|
{
|
|
foreach (var child in currentChildren)
|
|
{
|
|
//add the child's xml
|
|
var childXml = Serialize(mediaService, dataTypeService, userService, urlSegmentProviders, child);
|
|
currentXml.Add(childXml);
|
|
//copy local (out of closure)
|
|
var c = child;
|
|
//get this item's children
|
|
var children = originalDescendants.Where(x => x.ParentId == c.Id);
|
|
//recurse and add it's children to the child xml element
|
|
AddChildXml(mediaService, dataTypeService, userService, urlSegmentProviders, originalDescendants, children, childXml);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Part of the export of IContent and IMedia and IMember which is shared
|
|
/// </summary>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="contentBase">Base Content or Media to export</param>
|
|
/// <param name="urlValue"></param>
|
|
/// <param name="nodeName">Name of the node</param>
|
|
/// <returns><see cref="XElement"/></returns>
|
|
private XElement Serialize(IDataTypeService dataTypeService, IContentBase contentBase, string urlValue, string nodeName)
|
|
{
|
|
var xml = new XElement(nodeName,
|
|
new XAttribute("id", contentBase.Id),
|
|
new XAttribute("key", contentBase.Key),
|
|
new XAttribute("parentID", contentBase.Level > 1 ? contentBase.ParentId : -1),
|
|
new XAttribute("level", contentBase.Level),
|
|
new XAttribute("creatorID", contentBase.CreatorId),
|
|
new XAttribute("sortOrder", contentBase.SortOrder),
|
|
new XAttribute("createDate", contentBase.CreateDate.ToString("s")),
|
|
new XAttribute("updateDate", contentBase.UpdateDate.ToString("s")),
|
|
new XAttribute("nodeName", contentBase.Name),
|
|
new XAttribute("urlName", urlValue),
|
|
new XAttribute("path", contentBase.Path),
|
|
new XAttribute("isDoc", ""));
|
|
|
|
foreach (var property in contentBase.Properties.Where(p => p != null && p.Value != null && p.Value.ToString().IsNullOrWhiteSpace() == false))
|
|
{
|
|
xml.Add(Serialize(dataTypeService, property));
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Used by Content Export to recursively add children
|
|
/// </summary>
|
|
/// <param name="contentService"></param>
|
|
/// <param name="dataTypeService"></param>
|
|
/// <param name="userService"></param>
|
|
/// <param name="urlSegmentProviders"></param>
|
|
/// <param name="originalDescendants"></param>
|
|
/// <param name="currentChildren"></param>
|
|
/// <param name="currentXml"></param>
|
|
private void AddChildXml(IContentService contentService, IDataTypeService dataTypeService, IUserService userService, IEnumerable<IUrlSegmentProvider> urlSegmentProviders, IContent[] originalDescendants, IEnumerable<IContent> currentChildren, XElement currentXml)
|
|
{
|
|
foreach (var child in currentChildren)
|
|
{
|
|
//add the child's xml
|
|
var childXml = Serialize(contentService, dataTypeService, userService, urlSegmentProviders, child);
|
|
currentXml.Add(childXml);
|
|
//copy local (out of closure)
|
|
var c = child;
|
|
//get this item's children
|
|
var children = originalDescendants.Where(x => x.ParentId == c.Id);
|
|
//recurse and add it's children to the child xml element
|
|
AddChildXml(contentService, dataTypeService, userService, urlSegmentProviders, originalDescendants, children, childXml);
|
|
}
|
|
}
|
|
}
|
|
} |