using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { internal class ContentModelMapper { private readonly ApplicationContext _applicationContext; private readonly ProfileModelMapper _profileMapper; public ContentModelMapper(ApplicationContext applicationContext, ProfileModelMapper profileMapper) { _applicationContext = applicationContext; _profileMapper = profileMapper; } private ContentPropertyDisplay ToContentPropertyDisplay(Property property) { return CreateProperty(property, (display, originalProp, propEditor) => { //set the display properties after mapping display.Alias = originalProp.Alias; display.Description = originalProp.PropertyType.Description; display.Label = property.PropertyType.Name; display.Config = _applicationContext.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId); display.View = propEditor.ValueEditor.View; }); } public ContentItemDisplay ToContentItemDisplay(IContent content) { //create the list of tabs for properties assigned to tabs. var tabs = content.PropertyGroups.Select(propertyGroup => { //get the properties for the current tab var propertiesForTab = content.GetPropertiesForGroup(propertyGroup).ToArray(); //convert the properties to ContentPropertyDisplay objects var displayProperties = propertiesForTab .Select(ToContentPropertyDisplay); //return the tab with the tab properties return new Tab { Id = propertyGroup.Id, Alias = propertyGroup.Name, Label = propertyGroup.Name, Properties = displayProperties }; }).ToList(); //now add the generic properties tab for any properties that don't belong to a tab var orphanProperties = content.GetNonGroupedProperties(); //now add the generic properties tab tabs.Add(new Tab { Id = 0, Label = "Generic properties", Alias = "Generic properties", Properties = orphanProperties.Select(ToContentPropertyDisplay).ToArray() }); var result = CreateContent(content, (display, originalContent) => { //set display props after the normal properties are alraedy mapped display.Name = originalContent.Name; display.Tabs = tabs; display.Icon = originalContent.ContentType.Icon; //look up the published version of this item if it is not published if (content.Published) { display.PublishDate = content.UpdateDate; } else if (content.HasPublishedVersion()) { var published = _applicationContext.Services.ContentService.GetPublishedVersion(content.Id); display.PublishDate = published.UpdateDate; } else { display.PublishDate = null; } }, null, false); return result; } internal ContentItemDto ToContentItemDto(IContent content) { return CreateContent(content, null, (propertyDto, originalProperty, propEditor) => { propertyDto.Alias = originalProperty.Alias; propertyDto.Description = originalProperty.PropertyType.Description; propertyDto.Label = originalProperty.PropertyType.Name; propertyDto.DataType = _applicationContext.Services.DataTypeService.GetDataTypeDefinitionById(originalProperty.PropertyType.DataTypeDefinitionId); propertyDto.PropertyEditor = PropertyEditorResolver.Current.GetById(originalProperty.PropertyType.DataTypeId); }); } internal ContentItemBasic ToContentItemSimple(IContent content) { return CreateContent, ContentPropertyBasic>(content, null, null); } /// /// Creates a new content item /// /// /// /// /// /// /// /// private TContent CreateContent(IContent content, Action contentCreatedCallback = null, Action propertyCreatedCallback = null, bool createProperties = true) where TContent : ContentItemBasic, new() where TContentProperty : ContentPropertyBasic, new() { var result = new TContent { Id = content.Id, Owner = _profileMapper.ToBasicUser(content.GetCreatorProfile()), Updator = _profileMapper.ToBasicUser(content.GetWriterProfile()), ParentId = content.ParentId, UpdateDate = content.UpdateDate, CreateDate = content.CreateDate, ContentTypeAlias = content.ContentType.Alias }; if (createProperties) result.Properties = content.Properties.Select(p => CreateProperty(p, propertyCreatedCallback)).ToArray(); if (contentCreatedCallback != null) contentCreatedCallback(result, content); return result; } /// /// Creates the property with the basic property values mapped /// /// /// /// /// private static TContentProperty CreateProperty( Property property, Action callback = null) where TContentProperty : ContentPropertyBasic, new() { var editor = PropertyEditorResolver.Current.GetById(property.PropertyType.DataTypeId); if (editor == null) { //TODO: Remove this check as we shouldn't support this at all! var legacyEditor = DataTypesResolver.Current.GetById(property.PropertyType.DataTypeId); if (legacyEditor == null) { throw new NullReferenceException("The property editor with id " + property.PropertyType.DataTypeId + " does not exist"); } var legacyResult = new TContentProperty { Id = property.Id, Value = property.Value.ToString() }; if (callback != null) callback(legacyResult, property, null); return legacyResult; } var result = new TContentProperty { Id = property.Id, Value = editor.ValueEditor.SerializeValue(property.Value) }; if (callback != null) callback(result, property, editor); return result; } } }