diff --git a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestStartup.cs b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestStartup.cs index f038112b0b..200d7653f9 100644 --- a/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestStartup.cs +++ b/src/Umbraco.Tests/TestHelpers/ControllerTesting/TestStartup.cs @@ -30,9 +30,9 @@ namespace Umbraco.Tests.TestHelpers.ControllerTesting var httpConfig = new HttpConfiguration(); // TODO: Enable this if you can't see the errors produced - //var traceWriter = httpConfig.EnableSystemDiagnosticsTracing(); - //traceWriter.IsVerbose = true; - //traceWriter.MinimumLevel = TraceLevel.Debug; + // var traceWriter = httpConfig.EnableSystemDiagnosticsTracing(); + // traceWriter.IsVerbose = true; + // traceWriter.MinimumLevel = TraceLevel.Debug; httpConfig.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 38b90513eb..00338f2bd9 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -367,7 +367,7 @@ namespace Umbraco.Tests.Testing Composition .ComposeCoreMappingProfiles() - //.ComposeWebMappingProfiles() + .ComposeWebMappingProfiles() ; } diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 1ed4cb880d..b0820db329 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -93,6 +93,7 @@ + diff --git a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs index 3c429376fa..55629fde62 100644 --- a/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/ContentControllerTests.cs @@ -115,7 +115,7 @@ namespace Umbraco.Tests.Web.Controllers Composition.RegisterUnique(f => langService.Object); Composition.RegisterUnique(f => textService.Object); Composition.RegisterUnique(f => Mock.Of()); - // Composition.RegisterUnique(f => new UmbracoApiControllerTypeCollection(new[] { typeof(ContentTreeController) })); + Composition.RegisterUnique(f => new UmbracoApiControllerTypeCollection(new Type[] { })); } private MultipartFormDataContent GetMultiPartRequestContent(string json) diff --git a/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs b/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs index b15561bbc8..bd03ef9a88 100644 --- a/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs +++ b/src/Umbraco.Web.BackOffice/Mapping/CommonTreeNodeMapper.cs @@ -11,13 +11,11 @@ namespace Umbraco.Web.Models.Mapping { public class CommonTreeNodeMapper { - private readonly IHttpContextAccessor _httpContextAccessor; private readonly LinkGenerator _linkGenerator; - public CommonTreeNodeMapper(IHttpContextAccessor httpContextAccessor, LinkGenerator linkGenerator) + public CommonTreeNodeMapper( LinkGenerator linkGenerator) { - _httpContextAccessor = httpContextAccessor; _linkGenerator = linkGenerator; } @@ -25,10 +23,6 @@ namespace Umbraco.Web.Models.Mapping public string GetTreeNodeUrl(IContentBase source) where TController : UmbracoApiController, ITreeNodeController { - var httpContext = _httpContextAccessor.HttpContext; - if (httpContext == null) return null; - - return _linkGenerator.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); } diff --git a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs index 282890a9af..c1520f367c 100644 --- a/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs +++ b/src/Umbraco.Web/Composing/CompositionExtensions/WebMappingProfiles.cs @@ -14,28 +14,13 @@ namespace Umbraco.Web.Composing.CompositionExtensions // definitions to be moved to core composition.WithCollectionBuilder() - .Add() - .Add() - //.Add() - .Add() - .Add() - .Add() - .Add() - .Add() - .Add() - //.Add() - //.Add() - .Add() - .Add() - .Add() - .Add() - .Add() - .Add() - .Add() - .Add(); + .Add() + .Add() + .Add() + ; composition.Register(); - //.Register(); + composition.Register(); composition.Register(); return composition; diff --git a/src/Umbraco.Web/Models/Mapping/CommonTreeNodeMapper.cs b/src/Umbraco.Web/Models/Mapping/CommonTreeNodeMapper.cs new file mode 100644 index 0000000000..dedf1b3664 --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/CommonTreeNodeMapper.cs @@ -0,0 +1,30 @@ +using System.Web.Mvc; +using Umbraco.Core.Models; +using Umbraco.Web.Trees; +using Umbraco.Web.WebApi; +//Migrated to .NET CORE +namespace Umbraco.Web.Models.Mapping +{ + public class CommonTreeNodeMapper + { + private readonly IHttpContextAccessor _httpContextAccessor; + + + public CommonTreeNodeMapper(IHttpContextAccessor httpContextAccessor) + { + _httpContextAccessor = httpContextAccessor; + } + + + public string GetTreeNodeUrl(IContentBase source) + where TController : UmbracoApiController, ITreeNodeController + { + var httpContext = _httpContextAccessor.HttpContext; + if (httpContext == null) return null; + + var urlHelper = new UrlHelper(httpContext.Request.RequestContext); + return urlHelper.GetUmbracoApiService(controller => controller.GetTreeNode(source.Key.ToString("N"), null)); + } + + } +} diff --git a/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs new file mode 100644 index 0000000000..ec7fd4ae59 --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/ContentMapDefinition.cs @@ -0,0 +1,326 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core; +using Umbraco.Core.Dictionary; +using Umbraco.Core.Logging; +using Umbraco.Core.Mapping; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Routing; +using Umbraco.Web.Trees; + +//Migrated to .NET CORE +namespace Umbraco.Web.Models.Mapping +{ + /// + /// Declares how model mappings for content + /// + internal class ContentMapDefinition : IMapDefinition + { + private readonly CommonMapper _commonMapper; + private readonly CommonTreeNodeMapper _commonTreeNodeMapper; + private readonly ICultureDictionary _cultureDictionary; + private readonly ILocalizedTextService _localizedTextService; + private readonly IContentService _contentService; + private readonly IContentTypeService _contentTypeService; + private readonly IFileService _fileService; + private readonly IUmbracoContextAccessor _umbracoContextAccessor; + private readonly IPublishedRouter _publishedRouter; + private readonly ILocalizationService _localizationService; + private readonly ILogger _logger; + private readonly IUserService _userService; + private readonly IEntityService _entityService; + private readonly IVariationContextAccessor _variationContextAccessor; + private readonly IPublishedUrlProvider _publishedUrlProvider; + private readonly UriUtility _uriUtility; + private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; + private readonly ContentSavedStateMapper _stateMapper; + private readonly ContentBasicSavedStateMapper _basicStateMapper; + private readonly ContentVariantMapper _contentVariantMapper; + + + public ContentMapDefinition(CommonMapper commonMapper, CommonTreeNodeMapper commonTreeNodeMapper, ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService, IContentService contentService, IContentTypeService contentTypeService, + IFileService fileService, IUmbracoContextAccessor umbracoContextAccessor, IPublishedRouter publishedRouter, ILocalizationService localizationService, ILogger logger, + IUserService userService, IVariationContextAccessor variationContextAccessor, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, UriUtility uriUtility, IPublishedUrlProvider publishedUrlProvider, IEntityService entityService) + { + _commonMapper = commonMapper; + _commonTreeNodeMapper = commonTreeNodeMapper; + _cultureDictionary = cultureDictionary; + _localizedTextService = localizedTextService; + _contentService = contentService; + _contentTypeService = contentTypeService; + _fileService = fileService; + _umbracoContextAccessor = umbracoContextAccessor; + _publishedRouter = publishedRouter; + _localizationService = localizationService; + _logger = logger; + _userService = userService; + _entityService = entityService; + _variationContextAccessor = variationContextAccessor; + _uriUtility = uriUtility; + _publishedUrlProvider = publishedUrlProvider; + + _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider); + _stateMapper = new ContentSavedStateMapper(); + _basicStateMapper = new ContentBasicSavedStateMapper(); + _contentVariantMapper = new ContentVariantMapper(_localizationService, localizedTextService); + } + + public void DefineMaps(UmbracoMapper mapper) + { + mapper.Define((source, context) => new ContentPropertyCollectionDto(), Map); + mapper.Define((source, context) => new ContentItemDisplay(), Map); + mapper.Define((source, context) => new ContentVariantDisplay(), Map); + mapper.Define>((source, context) => new ContentItemBasic(), Map); + } + + // Umbraco.Code.MapAll + private static void Map(IContent source, ContentPropertyCollectionDto target, MapperContext context) + { + target.Properties = context.MapEnumerable(source.Properties); + } + + // Umbraco.Code.MapAll -AllowPreview -Errors -PersistedContent -TreeNodeUrl + private void Map(IContent source, ContentItemDisplay target, MapperContext context) + { + target.AllowedActions = GetActions(source); + target.AllowedTemplates = GetAllowedTemplates(source); + target.ContentApps = _commonMapper.GetContentApps(source); + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.ContentTypeName = _localizedTextService.UmbracoDictionaryTranslate(_cultureDictionary, source.ContentType.Name); + target.DocumentType = _commonMapper.GetContentType(source, context); + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.IsBlueprint = source.Blueprint; + target.IsChildOfListView = DetermineIsChildOfListView(source, context); + target.IsContainer = source.ContentType.IsContainer; + target.IsElement = source.ContentType.IsElement; + target.Key = source.Key; + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.SortOrder = source.SortOrder; + target.TemplateAlias = GetDefaultTemplate(source); + target.TemplateId = source.TemplateId ?? default; + target.Trashed = source.Trashed; + // target.TreeNodeUrl = _commonTreeNodeMapper.GetTreeNodeUrl(source); + target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key); + target.UpdateDate = source.UpdateDate; + target.Updater = _commonMapper.GetCreator(source, context); + target.Urls = GetUrls(source); + target.Variants = _contentVariantMapper.Map(source, context); + + target.ContentDto = new ContentPropertyCollectionDto(); + target.ContentDto.Properties = context.MapEnumerable(source.Properties); + } + + // Umbraco.Code.MapAll -Segment -Language -DisplayName + private void Map(IContent source, ContentVariantDisplay target, MapperContext context) + { + target.CreateDate = source.CreateDate; + target.ExpireDate = GetScheduledDate(source, ContentScheduleAction.Expire, context); + target.Name = source.Name; + target.PublishDate = source.PublishDate; + target.ReleaseDate = GetScheduledDate(source, ContentScheduleAction.Release, context); + target.State = _stateMapper.Map(source, context); + target.Tabs = _tabsAndPropertiesMapper.Map(source, context); + target.UpdateDate = source.UpdateDate; + } + + // Umbraco.Code.MapAll -Alias + private void Map(IContent source, ContentItemBasic target, MapperContext context) + { + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.CreateDate = source.CreateDate; + target.Edited = source.Edited; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.Key = source.Key; + target.Name = GetName(source, context); + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Properties = context.MapEnumerable(source.Properties); + target.SortOrder = source.SortOrder; + target.State = _basicStateMapper.Map(source, context); + target.Trashed = source.Trashed; + target.Udi = Udi.Create(source.Blueprint ? Constants.UdiEntityType.DocumentBlueprint : Constants.UdiEntityType.Document, source.Key); + target.UpdateDate = GetUpdateDate(source, context); + target.Updater = _commonMapper.GetCreator(source, context); + target.VariesByCulture = source.ContentType.VariesByCulture(); + } + + private IEnumerable GetActions(IContent source) + { + var umbracoContext = _umbracoContextAccessor.UmbracoContext; + + //cannot check permissions without a context + if (umbracoContext == null) + return Enumerable.Empty(); + + string path; + if (source.HasIdentity) + path = source.Path; + else + { + var parent = _contentService.GetById(source.ParentId); + path = parent == null ? "-1" : parent.Path; + } + + // TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is + // with the IUmbracoContextAccessor. In the meantime, if used outside of a web app this will throw a null + // reference exception :( + return _userService.GetPermissionsForPath(umbracoContext.Security.CurrentUser, path).GetAllPermissions(); + } + + private UrlInfo[] GetUrls(IContent source) + { + if (source.ContentType.IsElement) + return Array.Empty(); + + var umbracoContext = _umbracoContextAccessor.UmbracoContext; + + var urls = umbracoContext == null + ? new[] { UrlInfo.Message("Cannot generate urls without a current Umbraco Context") } + : source.GetContentUrls(_publishedRouter, umbracoContext, _localizationService, _localizedTextService, _contentService, _variationContextAccessor, _logger, _uriUtility, _publishedUrlProvider).ToArray(); + + return urls; + } + + private DateTime GetUpdateDate(IContent source, MapperContext context) + { + // invariant = global date + if (!source.ContentType.VariesByCulture()) return source.UpdateDate; + + // variant = depends on culture + var culture = context.GetCulture(); + + // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! + if (culture == null) + throw new InvalidOperationException("Missing culture in mapping options."); + + // if we don't have a date for a culture, it means the culture is not available, and + // hey we should probably not be mapping it, but it's too late, return a fallback date + var date = source.GetUpdateDate(culture); + return date ?? source.UpdateDate; + } + + private string GetName(IContent source, MapperContext context) + { + // invariant = only 1 name + if (!source.ContentType.VariesByCulture()) return source.Name; + + // variant = depends on culture + var culture = context.GetCulture(); + + // if there's no culture here, the issue is somewhere else (UI, whatever) - throw! + if (culture == null) + throw new InvalidOperationException("Missing culture in mapping options."); + + // if we don't have a name for a culture, it means the culture is not available, and + // hey we should probably not be mapping it, but it's too late, return a fallback name + return source.CultureInfos.TryGetValue(culture, out var name) && !name.Name.IsNullOrWhiteSpace() ? name.Name : $"({source.Name})"; + } + + /// + /// Checks if the content item is a descendant of a list view + /// + /// + /// + /// + /// Returns true if the content item is a descendant of a list view and where the content is + /// not a current user's start node. + /// + /// + /// We must check if it's the current user's start node because in that case we will actually be + /// rendering the tree node underneath the list view to visually show context. In this case we return + /// false because the item is technically not being rendered as part of a list view but instead as a + /// real tree node. If we didn't perform this check then tree syncing wouldn't work correctly. + /// + private bool DetermineIsChildOfListView(IContent source, MapperContext context) + { + var userStartNodes = Array.Empty(); + + // In cases where a user's start node is below a list view, we will actually render + // out the tree to that start node and in that case for that start node, we want to return + // false here. + if (context.HasItems && context.Items.TryGetValue("CurrentUser", out var usr) && usr is IUser currentUser) + { + userStartNodes = currentUser.CalculateContentStartNodeIds(_entityService); + if (!userStartNodes.Contains(Constants.System.Root)) + { + // return false if this is the user's actual start node, the node will be rendered in the tree + // regardless of if it's a list view or not + if (userStartNodes.Contains(source.Id)) + return false; + } + } + + var parent = _contentService.GetParent(source); + + if (parent == null) + return false; + + var pathParts = parent.Path.Split(',').Select(x => int.TryParse(x, out var i) ? i : 0).ToList(); + + // reduce the path parts so we exclude top level content items that + // are higher up than a user's start nodes + foreach (var n in userStartNodes) + { + var index = pathParts.IndexOf(n); + if (index != -1) + { + // now trim all top level start nodes to the found index + for (var i = 0; i < index; i++) + { + pathParts.RemoveAt(0); + } + } + } + + return parent.ContentType.IsContainer || _contentTypeService.HasContainerInPath(pathParts.ToArray()); + } + + + private DateTime? GetScheduledDate(IContent source, ContentScheduleAction action, MapperContext context) + { + var culture = context.GetCulture() ?? string.Empty; + var schedule = source.ContentSchedule.GetSchedule(culture, action); + return schedule.FirstOrDefault()?.Date; // take the first, it's ordered by date + } + + private IDictionary GetAllowedTemplates(IContent source) + { + var contentType = _contentTypeService.Get(source.ContentTypeId); + + return contentType.AllowedTemplates + .Where(t => t.Alias.IsNullOrWhiteSpace() == false && t.Name.IsNullOrWhiteSpace() == false) + .ToDictionary(t => t.Alias, t => _localizedTextService.UmbracoDictionaryTranslate(_cultureDictionary, t.Name)); + } + + private string GetDefaultTemplate(IContent source) + { + if (source == null) + return null; + + // If no template id was set... + if (!source.TemplateId.HasValue) + { + // ... and no default template is set, return null... + // ... otherwise return the content type default template alias. + return string.IsNullOrWhiteSpace(source.ContentType.DefaultTemplate?.Alias) + ? null + : source.ContentType.DefaultTemplate?.Alias; + } + + var template = _fileService.GetTemplate(source.TemplateId.Value); + return template.Alias; + } + } +} diff --git a/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs new file mode 100644 index 0000000000..b39c2f7f30 --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/MediaMapDefinition.cs @@ -0,0 +1,111 @@ +using Umbraco.Core; +using Umbraco.Core.Dictionary; +using Umbraco.Core.Logging; +using Umbraco.Core.Mapping; +using Umbraco.Core.Models; +using Umbraco.Core.PropertyEditors; +using Umbraco.Core.Services; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Trees; +using Umbraco.Core.Configuration.UmbracoSettings; +using System; +//Migrated to .NET CORE +namespace Umbraco.Web.Models.Mapping +{ + /// + /// Declares model mappings for media. + /// + public class MediaMapDefinition : IMapDefinition + { + private readonly CommonMapper _commonMapper; + private readonly CommonTreeNodeMapper _commonTreeNodeMapper; + private readonly IMediaService _mediaService; + private readonly IMediaTypeService _mediaTypeService; + private readonly MediaUrlGeneratorCollection _mediaUrlGenerators; + private readonly TabsAndPropertiesMapper _tabsAndPropertiesMapper; + private readonly IContentSettings _contentSettings; + + public MediaMapDefinition(ICultureDictionary cultureDictionary, CommonMapper commonMapper, CommonTreeNodeMapper commonTreeNodeMapper, IMediaService mediaService, IMediaTypeService mediaTypeService, + ILocalizedTextService localizedTextService, MediaUrlGeneratorCollection mediaUrlGenerators, IContentSettings contentSettings, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider) + { + _commonMapper = commonMapper; + _commonTreeNodeMapper = commonTreeNodeMapper; + _mediaService = mediaService; + _mediaTypeService = mediaTypeService; + _mediaUrlGenerators = mediaUrlGenerators; + _contentSettings = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings)); + + _tabsAndPropertiesMapper = new TabsAndPropertiesMapper(cultureDictionary, localizedTextService, contentTypeBaseServiceProvider); + } + + public void DefineMaps(UmbracoMapper mapper) + { + mapper.Define((source, context) => new ContentPropertyCollectionDto(), Map); + mapper.Define((source, context) => new MediaItemDisplay(), Map); + mapper.Define>((source, context) => new ContentItemBasic(), Map); + } + + // Umbraco.Code.MapAll + private static void Map(IMedia source, ContentPropertyCollectionDto target, MapperContext context) + { + target.Properties = context.MapEnumerable(source.Properties); + } + + // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsContainer -TreeNodeUrl + private void Map(IMedia source, MediaItemDisplay target, MapperContext context) + { + target.ContentApps = _commonMapper.GetContentApps(source); + target.ContentType = _commonMapper.GetContentType(source, context); + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.ContentTypeName = source.ContentType.Name; + target.CreateDate = source.CreateDate; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.IsChildOfListView = DetermineIsChildOfListView(source); + target.Key = source.Key; + target.MediaLink = string.Join(",", source.GetUrls(_contentSettings, _mediaUrlGenerators)); + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.SortOrder = source.SortOrder; + target.State = null; + target.Tabs = _tabsAndPropertiesMapper.Map(source, context); + target.Trashed = source.Trashed; + //target.TreeNodeUrl = _commonTreeNodeMapper.GetTreeNodeUrl(source); + target.Udi = Udi.Create(Constants.UdiEntityType.Media, source.Key); + target.UpdateDate = source.UpdateDate; + target.VariesByCulture = source.ContentType.VariesByCulture(); + } + + // Umbraco.Code.MapAll -Edited -Updater -Alias + private void Map(IMedia source, ContentItemBasic target, MapperContext context) + { + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.CreateDate = source.CreateDate; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Properties = context.MapEnumerable(source.Properties); + target.SortOrder = source.SortOrder; + target.State = null; + target.Trashed = source.Trashed; + target.Udi = Udi.Create(Constants.UdiEntityType.Media, source.Key); + target.UpdateDate = source.UpdateDate; + target.VariesByCulture = source.ContentType.VariesByCulture(); + } + + private bool DetermineIsChildOfListView(IMedia source) + { + // map the IsChildOfListView (this is actually if it is a descendant of a list view!) + var parent = _mediaService.GetParent(source); + return parent != null && (parent.ContentType.IsContainer || _mediaTypeService.HasContainerInPath(parent.Path)); + } + } +} diff --git a/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs new file mode 100644 index 0000000000..02bea9479c --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/MemberMapDefinition.cs @@ -0,0 +1,103 @@ +using Umbraco.Core; +using Umbraco.Core.Mapping; +using Umbraco.Core.Models; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.Trees; +//Migrated to .NET CORE +namespace Umbraco.Web.Models.Mapping +{ + /// + /// Declares model mappings for members. + /// + public class MemberMapDefinition : IMapDefinition + { + private readonly CommonMapper _commonMapper; + private readonly CommonTreeNodeMapper _commonTreeNodeMapper; + private readonly MemberTabsAndPropertiesMapper _tabsAndPropertiesMapper; + private readonly IHttpContextAccessor _httpContextAccessor; + + public MemberMapDefinition(CommonMapper commonMapper, CommonTreeNodeMapper commonTreeNodeMapper, MemberTabsAndPropertiesMapper tabsAndPropertiesMapper, IHttpContextAccessor httpContextAccessor) + { + _commonMapper = commonMapper; + _commonTreeNodeMapper = commonTreeNodeMapper; + + _tabsAndPropertiesMapper = tabsAndPropertiesMapper; + _httpContextAccessor = httpContextAccessor; + } + + public void DefineMaps(UmbracoMapper mapper) + { + mapper.Define((source, context) => new MemberDisplay(), Map); + mapper.Define((source, context) => new MemberBasic(), Map); + mapper.Define((source, context) => new MemberGroupDisplay(), Map); + mapper.Define((source, context) => new ContentPropertyCollectionDto(), Map); + } + + // Umbraco.Code.MapAll -Properties -Errors -Edited -Updater -Alias -IsChildOfListView + // Umbraco.Code.MapAll -Trashed -IsContainer -VariesByCulture -TreeNodeUrl + private void Map(IMember source, MemberDisplay target, MapperContext context) + { + target.ContentApps = _commonMapper.GetContentApps(source); + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.ContentTypeName = source.ContentType.Name; + target.CreateDate = source.CreateDate; + target.Email = source.Email; + target.Icon = source.ContentType.Icon; + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.SortOrder = source.SortOrder; + target.State = null; + target.Tabs = _tabsAndPropertiesMapper.Map(source, context); + //target.TreeNodeUrl = _commonTreeNodeMapper.GetTreeNodeUrl(source); + target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); + target.UpdateDate = source.UpdateDate; + target.Username = source.Username; + } + + // Umbraco.Code.MapAll -Trashed -Edited -Updater -Alias -VariesByCulture + private void Map(IMember source, MemberBasic target, MapperContext context) + { + target.ContentTypeId = source.ContentType.Id; + target.ContentTypeAlias = source.ContentType.Alias; + target.CreateDate = source.CreateDate; + target.Email = source.Email; + target.Icon = source.ContentType.Icon; + target.Id = int.MaxValue; + target.Key = source.Key; + target.Name = source.Name; + target.Owner = _commonMapper.GetOwner(source, context); + target.ParentId = source.ParentId; + target.Path = source.Path; + target.Properties = context.MapEnumerable(source.Properties); + target.SortOrder = source.SortOrder; + target.State = null; + target.Udi = Udi.Create(Constants.UdiEntityType.Member, source.Key); + target.UpdateDate = source.UpdateDate; + target.Username = source.Username; + } + + // Umbraco.Code.MapAll -Icon -Trashed -ParentId -Alias + private void Map(IMemberGroup source, MemberGroupDisplay target, MapperContext context) + { + target.Id = source.Id; + target.Key = source.Key; + target.Name = source.Name; + target.Path = $"-1,{source.Id}"; + target.Udi = Udi.Create(Constants.UdiEntityType.MemberGroup, source.Key); + } + + // Umbraco.Code.MapAll + private static void Map(IMember source, ContentPropertyCollectionDto target, MapperContext context) + { + target.Properties = context.MapEnumerable(source.Properties); + } + + + + } +} diff --git a/src/Umbraco.Web/Trees/ITreeNodeController.cs b/src/Umbraco.Web/Trees/ITreeNodeController.cs new file mode 100644 index 0000000000..8def2f19c4 --- /dev/null +++ b/src/Umbraco.Web/Trees/ITreeNodeController.cs @@ -0,0 +1,23 @@ +using System.Net.Http.Formatting; +using Umbraco.Web.Models.Trees; +using Umbraco.Web.WebApi.Filters; +using System.Web.Http.ModelBinding; + +//Migrated to .NET CORE +namespace Umbraco.Web.Trees +{ + /// + /// Represents an TreeNodeController + /// + public interface ITreeNodeController + { + /// + /// Gets an individual tree node + /// + /// + /// + /// + TreeNode GetTreeNode(string id, [ModelBinder(typeof(HttpQueryStringModelBinder))] + FormDataCollection queryStrings); + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 29c9e326e6..fb93ca5435 100755 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -151,9 +151,14 @@ + + + + + @@ -465,8 +470,5 @@ Mvc\web.config - - - \ No newline at end of file