* Fixed issue with Paths-integers being converted using local culture. * Align with the old implementation * Use int.TryParse insteaad of TryConvertTo when we do not want culture specific parsing * More fixes for cultures and fixed wrong test. Users should be part of all groups to have access * Fix casing for requested file * Force tests to not use NLS * try force tests to not use NLS * try force tests to not use NLS * Force tests on windows to run ICU * More fixes for invariant int parsing * Change key on actions/emptyRecycleBin, so the casing aligns with the view file, that is named emptyrecyclebin.html * Fixed casing issue * use Attempt to align with other code
652 lines
28 KiB
C#
652 lines
28 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Net;
|
|
using System.Xml.Linq;
|
|
using Umbraco.Cms.Core.Models;
|
|
using Umbraco.Cms.Core.PropertyEditors;
|
|
using Umbraco.Cms.Core.Serialization;
|
|
using Umbraco.Cms.Core.Strings;
|
|
using Umbraco.Extensions;
|
|
|
|
namespace Umbraco.Cms.Core.Services.Implement
|
|
{
|
|
/// <summary>
|
|
/// Serializes entities to XML
|
|
/// </summary>
|
|
internal class EntityXmlSerializer : IEntityXmlSerializer
|
|
{
|
|
private readonly IContentTypeService _contentTypeService;
|
|
private readonly IMediaService _mediaService;
|
|
private readonly IContentService _contentService;
|
|
private readonly IDataTypeService _dataTypeService;
|
|
private readonly IUserService _userService;
|
|
private readonly ILocalizationService _localizationService;
|
|
private readonly UrlSegmentProviderCollection _urlSegmentProviders;
|
|
private readonly IShortStringHelper _shortStringHelper;
|
|
private readonly PropertyEditorCollection _propertyEditors;
|
|
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
|
|
|
|
public EntityXmlSerializer(
|
|
IContentService contentService,
|
|
IMediaService mediaService,
|
|
IDataTypeService dataTypeService,
|
|
IUserService userService,
|
|
ILocalizationService localizationService,
|
|
IContentTypeService contentTypeService,
|
|
UrlSegmentProviderCollection urlSegmentProviders,
|
|
IShortStringHelper shortStringHelper,
|
|
PropertyEditorCollection propertyEditors,
|
|
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer)
|
|
{
|
|
_contentTypeService = contentTypeService;
|
|
_mediaService = mediaService;
|
|
_contentService = contentService;
|
|
_dataTypeService = dataTypeService;
|
|
_userService = userService;
|
|
_localizationService = localizationService;
|
|
_urlSegmentProviders = urlSegmentProviders;
|
|
_shortStringHelper = shortStringHelper;
|
|
_propertyEditors = propertyEditors;
|
|
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an IContent item as an XElement.
|
|
/// </summary>
|
|
public XElement Serialize(IContent content,
|
|
bool published,
|
|
bool withDescendants = false) // TODO: take care of usage! only used for the packager
|
|
{
|
|
if (content == null) throw new ArgumentNullException(nameof(content));
|
|
|
|
var nodeName = content.ContentType.Alias.ToSafeAlias(_shortStringHelper);
|
|
|
|
var xml = SerializeContentBase(content, content.GetUrlSegment(_shortStringHelper, _urlSegmentProviders), nodeName, published);
|
|
|
|
xml.Add(new XAttribute("nodeType", content.ContentType.Id));
|
|
xml.Add(new XAttribute("nodeTypeAlias", content.ContentType.Alias));
|
|
|
|
xml.Add(new XAttribute("creatorName", content.GetCreatorProfile(_userService)?.Name ?? "??"));
|
|
//xml.Add(new XAttribute("creatorID", content.CreatorId));
|
|
xml.Add(new XAttribute("writerName", content.GetWriterProfile(_userService)?.Name ?? "??"));
|
|
xml.Add(new XAttribute("writerID", content.WriterId));
|
|
|
|
xml.Add(new XAttribute("template", content.TemplateId?.ToString(CultureInfo.InvariantCulture) ?? ""));
|
|
|
|
xml.Add(new XAttribute("isPublished", content.Published));
|
|
|
|
if (withDescendants)
|
|
{
|
|
const int pageSize = 500;
|
|
var page = 0;
|
|
var total = long.MaxValue;
|
|
while(page * pageSize < total)
|
|
{
|
|
var children = _contentService.GetPagedChildren(content.Id, page++, pageSize, out total);
|
|
SerializeChildren(children, xml, published);
|
|
}
|
|
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an IMedia item as an XElement.
|
|
/// </summary>
|
|
public XElement Serialize(
|
|
IMedia media,
|
|
bool withDescendants = false,
|
|
Action<IMedia, XElement> onMediaItemSerialized = null)
|
|
{
|
|
if (_mediaService == null) throw new ArgumentNullException(nameof(_mediaService));
|
|
if (_dataTypeService == null) throw new ArgumentNullException(nameof(_dataTypeService));
|
|
if (_userService == null) throw new ArgumentNullException(nameof(_userService));
|
|
if (_localizationService == null) throw new ArgumentNullException(nameof(_localizationService));
|
|
if (media == null) throw new ArgumentNullException(nameof(media));
|
|
if (_urlSegmentProviders == null) throw new ArgumentNullException(nameof(_urlSegmentProviders));
|
|
|
|
var nodeName = media.ContentType.Alias.ToSafeAlias(_shortStringHelper);
|
|
|
|
const bool published = false; // always false for media
|
|
string urlValue = media.GetUrlSegment(_shortStringHelper, _urlSegmentProviders);
|
|
XElement xml = SerializeContentBase(media, urlValue, nodeName, published);
|
|
|
|
|
|
xml.Add(new XAttribute("nodeType", media.ContentType.Id));
|
|
xml.Add(new XAttribute("nodeTypeAlias", media.ContentType.Alias));
|
|
|
|
//xml.Add(new XAttribute("creatorName", media.GetCreatorProfile(userService).Name));
|
|
//xml.Add(new XAttribute("creatorID", media.CreatorId));
|
|
xml.Add(new XAttribute("writerName", media.GetWriterProfile(_userService)?.Name ?? string.Empty));
|
|
xml.Add(new XAttribute("writerID", media.WriterId));
|
|
xml.Add(new XAttribute("udi", media.GetUdi()));
|
|
|
|
//xml.Add(new XAttribute("template", 0)); // no template for media
|
|
|
|
onMediaItemSerialized?.Invoke(media, xml);
|
|
|
|
if (withDescendants)
|
|
{
|
|
const int pageSize = 500;
|
|
var page = 0;
|
|
var total = long.MaxValue;
|
|
while (page * pageSize < total)
|
|
{
|
|
var children = _mediaService.GetPagedChildren(media.Id, page++, pageSize, out total);
|
|
SerializeChildren(children, xml, onMediaItemSerialized);
|
|
}
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports an IMember item as an XElement.
|
|
/// </summary>
|
|
public XElement Serialize(IMember member)
|
|
{
|
|
var nodeName = member.ContentType.Alias.ToSafeAlias(_shortStringHelper);
|
|
|
|
const bool published = false; // always false for member
|
|
var xml = SerializeContentBase(member, "", nodeName, published);
|
|
|
|
xml.Add(new XAttribute("nodeType", member.ContentType.Id));
|
|
xml.Add(new XAttribute("nodeTypeAlias", member.ContentType.Alias));
|
|
|
|
// what about writer/creator/version?
|
|
|
|
xml.Add(new XAttribute("loginName", member.Username));
|
|
xml.Add(new XAttribute("email", member.Email));
|
|
xml.Add(new XAttribute("icon", member.ContentType.Icon));
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a list of Data Types
|
|
/// </summary>
|
|
/// <param name="dataTypeDefinitions">List of data types to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IDataTypeDefinition objects</returns>
|
|
public XElement Serialize(IEnumerable<IDataType> dataTypeDefinitions)
|
|
{
|
|
var container = new XElement("DataTypes");
|
|
foreach (var dataTypeDefinition in dataTypeDefinitions)
|
|
{
|
|
container.Add(Serialize(dataTypeDefinition));
|
|
}
|
|
return container;
|
|
}
|
|
|
|
public XElement Serialize(IDataType dataType)
|
|
{
|
|
var xml = new XElement("DataType");
|
|
xml.Add(new XAttribute("Name", dataType.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", dataType.EditorAlias));
|
|
xml.Add(new XAttribute("Definition", dataType.Key));
|
|
xml.Add(new XAttribute("DatabaseType", dataType.DatabaseType.ToString()));
|
|
xml.Add(new XAttribute("Configuration", _configurationEditorJsonSerializer.Serialize(dataType.Configuration)));
|
|
|
|
var folderNames = string.Empty;
|
|
var folderKeys = string.Empty;
|
|
if (dataType.Level != 1)
|
|
{
|
|
//get URL encoded folder names
|
|
var folders = _dataTypeService.GetContainers(dataType)
|
|
.OrderBy(x => x.Level);
|
|
|
|
folderNames = string.Join("/", folders.Select(x => WebUtility.UrlEncode(x.Name)).ToArray());
|
|
folderKeys = string.Join("/", folders.Select(x => x.Key).ToArray());
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(folderNames) == false)
|
|
{
|
|
xml.Add(new XAttribute("Folders", folderNames));
|
|
xml.Add(new XAttribute("FolderKeys", folderKeys));
|
|
}
|
|
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a list of <see cref="IDictionaryItem"/> items to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="dictionaryItem">List of dictionary items to export</param>
|
|
/// <param name="includeChildren">Optional boolean indicating whether or not to include children</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IDictionaryItem objects</returns>
|
|
public XElement Serialize(IEnumerable<IDictionaryItem> dictionaryItem, bool includeChildren = true)
|
|
{
|
|
var xml = new XElement("DictionaryItems");
|
|
foreach (var item in dictionaryItem)
|
|
{
|
|
xml.Add(Serialize(item, includeChildren));
|
|
}
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a single <see cref="IDictionaryItem"/> item to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="dictionaryItem">Dictionary Item to export</param>
|
|
/// <param name="includeChildren">Optional boolean indicating whether or not to include children</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IDictionaryItem object</returns>
|
|
public XElement Serialize(IDictionaryItem dictionaryItem, bool includeChildren)
|
|
{
|
|
var xml = Serialize(dictionaryItem);
|
|
|
|
if (includeChildren)
|
|
{
|
|
var children = _localizationService.GetDictionaryItemChildren(dictionaryItem.Key);
|
|
foreach (var child in children)
|
|
{
|
|
xml.Add(Serialize(child, true));
|
|
}
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
private XElement Serialize(IDictionaryItem dictionaryItem)
|
|
{
|
|
var xml = new XElement("DictionaryItem",
|
|
new XAttribute("Key", dictionaryItem.Key),
|
|
new XAttribute("Name", dictionaryItem.ItemKey));
|
|
|
|
foreach (IDictionaryTranslation 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(IStylesheet stylesheet, bool includeProperties)
|
|
{
|
|
var xml = new XElement("Stylesheet",
|
|
new XElement("Name", stylesheet.Alias),
|
|
new XElement("FileName", stylesheet.Path),
|
|
new XElement("Content", new XCData(stylesheet.Content)));
|
|
|
|
if (!includeProperties)
|
|
{
|
|
return xml;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a list of <see cref="ILanguage"/> items to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="languages">List of Languages to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the ILanguage objects</returns>
|
|
public XElement Serialize(IEnumerable<ILanguage> languages)
|
|
{
|
|
var xml = new XElement("Languages");
|
|
foreach (var language in languages)
|
|
{
|
|
xml.Add(Serialize(language));
|
|
}
|
|
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("Key", template.Key));
|
|
xml.Add(new XElement("Alias", template.Alias));
|
|
xml.Add(new XElement("Design", new XCData(template.Content)));
|
|
|
|
if (template is Template concreteTemplate && concreteTemplate.MasterTemplateId != null)
|
|
{
|
|
if (concreteTemplate.MasterTemplateId.IsValueCreated &&
|
|
concreteTemplate.MasterTemplateId.Value != default)
|
|
{
|
|
xml.Add(new XElement("Master", concreteTemplate.MasterTemplateId.ToString()));
|
|
xml.Add(new XElement("MasterAlias", concreteTemplate.MasterTemplateAlias));
|
|
}
|
|
}
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a list of <see cref="ITemplate"/> items to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="templates"></param>
|
|
/// <returns></returns>
|
|
public XElement Serialize(IEnumerable<ITemplate> templates)
|
|
{
|
|
var xml = new XElement("Templates");
|
|
foreach (var item in templates)
|
|
{
|
|
xml.Add(Serialize(item));
|
|
}
|
|
return xml;
|
|
}
|
|
|
|
|
|
public XElement Serialize(IMediaType mediaType)
|
|
{
|
|
var info = new XElement("Info",
|
|
new XElement("Name", mediaType.Name),
|
|
new XElement("Alias", mediaType.Alias),
|
|
new XElement("Key", mediaType.Key),
|
|
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", SerializePropertyTypes(mediaType.PropertyTypes, mediaType.PropertyGroups)); // actually, all of them
|
|
|
|
var tabs = new XElement("Tabs", SerializePropertyGroups(mediaType.PropertyGroups)); // TODO Rename to PropertyGroups
|
|
|
|
var xml = new XElement("MediaType",
|
|
info,
|
|
structure,
|
|
genericProperties,
|
|
tabs);
|
|
|
|
return xml;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Exports a list of <see cref="IMacro"/> items to xml as an <see cref="XElement"/>
|
|
/// </summary>
|
|
/// <param name="macros">Macros to export</param>
|
|
/// <returns><see cref="XElement"/> containing the xml representation of the IMacro objects</returns>
|
|
public XElement Serialize(IEnumerable<IMacro> macros)
|
|
{
|
|
var xml = new XElement("Macros");
|
|
foreach (var item in macros)
|
|
{
|
|
xml.Add(Serialize(item));
|
|
}
|
|
return xml;
|
|
}
|
|
|
|
public XElement Serialize(IMacro macro)
|
|
{
|
|
var xml = new XElement("macro");
|
|
xml.Add(new XElement("name", macro.Name));
|
|
xml.Add(new XElement("key", macro.Key));
|
|
xml.Add(new XElement("alias", macro.Alias));
|
|
xml.Add(new XElement("macroSource", macro.MacroSource));
|
|
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("key", property.Key),
|
|
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;
|
|
}
|
|
|
|
public XElement Serialize(IContentType contentType)
|
|
{
|
|
var info = new XElement("Info",
|
|
new XElement("Name", contentType.Name),
|
|
new XElement("Alias", contentType.Alias),
|
|
new XElement("Key", contentType.Key),
|
|
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()),
|
|
new XElement("IsElement", contentType.IsElement.ToString()),
|
|
new XElement("Variations", contentType.Variations.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", SerializePropertyTypes(contentType.PropertyTypes, contentType.PropertyGroups)); // actually, all of them
|
|
|
|
var tabs = new XElement("Tabs", SerializePropertyGroups(contentType.PropertyGroups)); // TODO Rename to PropertyGroups
|
|
|
|
var xml = new XElement("DocumentType",
|
|
info,
|
|
structure,
|
|
genericProperties,
|
|
tabs);
|
|
|
|
var folderNames = string.Empty;
|
|
var folderKeys = 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);
|
|
|
|
folderNames = string.Join("/", folders.Select(x => WebUtility.UrlEncode(x.Name)).ToArray());
|
|
folderKeys = string.Join("/", folders.Select(x => x.Key).ToArray());
|
|
}
|
|
|
|
if (string.IsNullOrWhiteSpace(folderNames) == false)
|
|
{
|
|
xml.Add(new XAttribute("Folders", folderNames));
|
|
xml.Add(new XAttribute("FolderKeys", folderKeys));
|
|
}
|
|
|
|
|
|
return xml;
|
|
}
|
|
|
|
private IEnumerable<XElement> SerializePropertyTypes(IEnumerable<IPropertyType> propertyTypes, IEnumerable<PropertyGroup> propertyGroups)
|
|
{
|
|
foreach (var propertyType in propertyTypes)
|
|
{
|
|
var definition = _dataTypeService.GetDataType(propertyType.DataTypeId);
|
|
|
|
var propertyGroup = propertyType.PropertyGroupId == null // true generic property
|
|
? null
|
|
: propertyGroups.FirstOrDefault(x => x.Id == propertyType.PropertyGroupId.Value);
|
|
|
|
XElement genericProperty = SerializePropertyType(propertyType, definition, propertyGroup);
|
|
genericProperty.Add(new XElement("Variations", propertyType.Variations.ToString()));
|
|
|
|
yield return genericProperty;
|
|
}
|
|
}
|
|
|
|
private IEnumerable<XElement> SerializePropertyGroups(IEnumerable<PropertyGroup> propertyGroups)
|
|
{
|
|
foreach (var propertyGroup in propertyGroups)
|
|
{
|
|
yield return new XElement("Tab", // TODO Rename to PropertyGroup
|
|
new XElement("Id", propertyGroup.Id),
|
|
new XElement("Key", propertyGroup.Key),
|
|
new XElement("Type", propertyGroup.Type.ToString()),
|
|
new XElement("Caption", propertyGroup.Name), // TODO Rename to Name (same in PackageDataInstallation)
|
|
new XElement("Alias", propertyGroup.Alias),
|
|
new XElement("SortOrder", propertyGroup.SortOrder));
|
|
}
|
|
}
|
|
|
|
private XElement SerializePropertyType(IPropertyType propertyType, IDataType definition, PropertyGroup propertyGroup)
|
|
=> new XElement("GenericProperty",
|
|
new XElement("Name", propertyType.Name),
|
|
new XElement("Alias", propertyType.Alias),
|
|
new XElement("Key", propertyType.Key),
|
|
new XElement("Type", propertyType.PropertyEditorAlias),
|
|
new XElement("Definition", definition.Key),
|
|
propertyGroup != null ? new XElement("Tab", propertyGroup.Name, new XAttribute("Alias", propertyGroup.Alias)) : null, // TODO Replace with PropertyGroupAlias
|
|
new XElement("SortOrder", propertyType.SortOrder),
|
|
new XElement("Mandatory", propertyType.Mandatory.ToString()),
|
|
new XElement("LabelOnTop", propertyType.LabelOnTop.ToString()),
|
|
propertyType.MandatoryMessage != null ? new XElement("MandatoryMessage", propertyType.MandatoryMessage) : null,
|
|
propertyType.ValidationRegExp != null ? new XElement("Validation", propertyType.ValidationRegExp) : null,
|
|
propertyType.ValidationRegExpMessage != null ? new XElement("ValidationRegExpMessage", propertyType.ValidationRegExpMessage) : null,
|
|
propertyType.Description != null ? new XElement("Description", new XCData(propertyType.Description)) : null);
|
|
|
|
// exports an IContentBase (IContent, IMedia or IMember) as an XElement.
|
|
private XElement SerializeContentBase(IContentBase contentBase, string urlValue, string nodeName, bool published)
|
|
{
|
|
var xml = new XElement(nodeName,
|
|
new XAttribute("id", contentBase.Id.ToInvariantString()),
|
|
new XAttribute("key", contentBase.Key),
|
|
new XAttribute("parentID", (contentBase.Level > 1 ? contentBase.ParentId : -1).ToInvariantString()),
|
|
new XAttribute("level", contentBase.Level),
|
|
new XAttribute("creatorID", contentBase.CreatorId.ToInvariantString()),
|
|
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", ""));
|
|
|
|
|
|
// Add culture specific node names
|
|
foreach (var culture in contentBase.AvailableCultures)
|
|
{
|
|
xml.Add(new XAttribute("nodeName-" + culture, contentBase.GetCultureName(culture)));
|
|
}
|
|
|
|
foreach (var property in contentBase.Properties)
|
|
xml.Add(SerializeProperty(property, published));
|
|
|
|
return xml;
|
|
}
|
|
|
|
// exports a property as XElements.
|
|
private IEnumerable<XElement> SerializeProperty(IProperty property, bool published)
|
|
{
|
|
var propertyType = property.PropertyType;
|
|
|
|
// get the property editor for this property and let it convert it to the xml structure
|
|
var propertyEditor = _propertyEditors[propertyType.PropertyEditorAlias];
|
|
return propertyEditor == null
|
|
? Array.Empty<XElement>()
|
|
: propertyEditor.GetValueEditor().ConvertDbToXml(property, published);
|
|
}
|
|
|
|
// exports an IContent item descendants.
|
|
private void SerializeChildren(IEnumerable<IContent> children, XElement xml, bool published)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
// add the child xml
|
|
var childXml = Serialize(child, published);
|
|
xml.Add(childXml);
|
|
|
|
const int pageSize = 500;
|
|
var page = 0;
|
|
var total = long.MaxValue;
|
|
while(page * pageSize < total)
|
|
{
|
|
var grandChildren = _contentService.GetPagedChildren(child.Id, page++, pageSize, out total);
|
|
// recurse
|
|
SerializeChildren(grandChildren, childXml, published);
|
|
}
|
|
}
|
|
}
|
|
|
|
// exports an IMedia item descendants.
|
|
private void SerializeChildren(IEnumerable<IMedia> children, XElement xml, Action<IMedia, XElement> onMediaItemSerialized)
|
|
{
|
|
foreach (var child in children)
|
|
{
|
|
// add the child xml
|
|
var childXml = Serialize(child, onMediaItemSerialized: onMediaItemSerialized);
|
|
xml.Add(childXml);
|
|
|
|
const int pageSize = 500;
|
|
var page = 0;
|
|
var total = long.MaxValue;
|
|
while (page * pageSize < total)
|
|
{
|
|
var grandChildren = _mediaService.GetPagedChildren(child.Id, page++, pageSize, out total);
|
|
// recurse
|
|
SerializeChildren(grandChildren, childXml, onMediaItemSerialized);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|