Netcore: Migration of Model classes from Umbraco.Infrastructure to Core (#9404)
* Migrating more model, mapping and tree classes * Migrating files from Mapping dir without Newtonsoft dependency * Migrating files from PublishedContent and Editors dirs without Newtonsoft dependency + some more of the same kind * Migrating DataType class without the usage of Newtonsoft.Json and making the corresponding changes to all classes affected * Combining 3 ContentExtensions files into 1 * Refactoring from migrating ContentExtensions * Migrating more classes * Migrating ContentRepositoryExtensions - combining it with existing file in Umbraco.Core * removing Newtonsoft json dependency & migrating file. Adding partial migration of ConfigurationEditor, so PropertyTagsExtensions can be migrated * Migrating ContentTagsExtensions, and refactoring from changes in PropertyTagsExtensions * Changes that should be reverted once ConfigurationEditor class is fully migrated * VS couldn't find Composing, so build was failing. Removing the using solves the problem * Handling a single case for deserializing a subset of an input * Small changes and added tests to JsonNetSerializer Signed-off-by: Bjarke Berg <mail@bergmania.dk> * Migrated ConfigurationEditor Signed-off-by: Bjarke Berg <mail@bergmania.dk> Co-authored-by: Bjarke Berg <mail@bergmania.dk>
This commit is contained in:
committed by
GitHub
parent
d498c1a2cd
commit
dd5f400cf3
183
src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs
Normal file
183
src/Umbraco.Core/Models/Mapping/TabsAndPropertiesMapper.cs
Normal file
@@ -0,0 +1,183 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Web.Models.ContentEditing;
|
||||
|
||||
namespace Umbraco.Web.Models.Mapping
|
||||
{
|
||||
public abstract class TabsAndPropertiesMapper
|
||||
{
|
||||
protected ICultureDictionary CultureDictionary { get; }
|
||||
protected ILocalizedTextService LocalizedTextService { get; }
|
||||
protected IEnumerable<string> IgnoreProperties { get; set; }
|
||||
|
||||
protected TabsAndPropertiesMapper(ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService)
|
||||
{
|
||||
CultureDictionary = cultureDictionary ?? throw new ArgumentNullException(nameof(cultureDictionary));
|
||||
LocalizedTextService = localizedTextService ?? throw new ArgumentNullException(nameof(localizedTextService));
|
||||
IgnoreProperties = new List<string>();
|
||||
}
|
||||
|
||||
protected TabsAndPropertiesMapper(ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService, IEnumerable<string> ignoreProperties)
|
||||
: this(cultureDictionary, localizedTextService)
|
||||
{
|
||||
IgnoreProperties = ignoreProperties ?? throw new ArgumentNullException(nameof(ignoreProperties));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a collection of custom generic properties that exist on the generic properties tab
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected virtual IEnumerable<ContentPropertyDisplay> GetCustomGenericProperties(IContentBase content)
|
||||
{
|
||||
return Enumerable.Empty<ContentPropertyDisplay>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps properties on to the generic properties tab
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="tabs"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <remarks>
|
||||
/// The generic properties tab is responsible for
|
||||
/// setting up the properties such as Created date, updated date, template selected, etc...
|
||||
/// </remarks>
|
||||
protected virtual void MapGenericProperties(IContentBase content, List<Tab<ContentPropertyDisplay>> tabs, MapperContext context)
|
||||
{
|
||||
// add the generic properties tab, for properties that don't belong to a tab
|
||||
// get the properties, map and translate them, then add the tab
|
||||
var noGroupProperties = content.GetNonGroupedProperties()
|
||||
.Where(x => IgnoreProperties.Contains(x.Alias) == false) // skip ignored
|
||||
.ToList();
|
||||
var genericproperties = MapProperties(content, noGroupProperties, context);
|
||||
|
||||
tabs.Add(new Tab<ContentPropertyDisplay>
|
||||
{
|
||||
Id = 0,
|
||||
Label = LocalizedTextService.Localize("general/properties"),
|
||||
Alias = "Generic properties",
|
||||
Properties = genericproperties
|
||||
});
|
||||
|
||||
var genericProps = tabs.Single(x => x.Id == 0);
|
||||
|
||||
//store the current props to append to the newly inserted ones
|
||||
var currProps = genericProps.Properties.ToArray();
|
||||
|
||||
var contentProps = new List<ContentPropertyDisplay>();
|
||||
|
||||
var customProperties = GetCustomGenericProperties(content);
|
||||
if (customProperties != null)
|
||||
{
|
||||
//add the custom ones
|
||||
contentProps.AddRange(customProperties);
|
||||
}
|
||||
|
||||
//now add the user props
|
||||
contentProps.AddRange(currProps);
|
||||
|
||||
//re-assign
|
||||
genericProps.Properties = contentProps;
|
||||
|
||||
//Show or hide properties tab based on whether it has or not any properties
|
||||
if (genericProps.Properties.Any() == false)
|
||||
{
|
||||
//loop through the tabs, remove the one with the id of zero and exit the loop
|
||||
for (var i = 0; i < tabs.Count; i++)
|
||||
{
|
||||
if (tabs[i].Id != 0) continue;
|
||||
tabs.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a list of <see cref="Property"/> to a list of <see cref="ContentPropertyDisplay"/>
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="properties"></param>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
protected virtual List<ContentPropertyDisplay> MapProperties(IContentBase content, List<IProperty> properties, MapperContext context)
|
||||
{
|
||||
return context.MapEnumerable<IProperty, ContentPropertyDisplay>(properties.OrderBy(x => x.PropertyType.SortOrder));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the tabs collection with properties assigned for display models
|
||||
/// </summary>
|
||||
public class TabsAndPropertiesMapper<TSource> : TabsAndPropertiesMapper
|
||||
where TSource : IContentBase
|
||||
{
|
||||
private readonly IContentTypeBaseServiceProvider _contentTypeBaseServiceProvider;
|
||||
|
||||
public TabsAndPropertiesMapper(ICultureDictionary cultureDictionary, ILocalizedTextService localizedTextService, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider)
|
||||
: base(cultureDictionary, localizedTextService)
|
||||
{
|
||||
_contentTypeBaseServiceProvider = contentTypeBaseServiceProvider ?? throw new ArgumentNullException(nameof(contentTypeBaseServiceProvider));
|
||||
}
|
||||
|
||||
public virtual IEnumerable<Tab<ContentPropertyDisplay>> Map(TSource source, MapperContext context)
|
||||
{
|
||||
var tabs = new List<Tab<ContentPropertyDisplay>>();
|
||||
|
||||
var contentType = _contentTypeBaseServiceProvider.GetContentTypeOf(source);
|
||||
|
||||
// add the tabs, for properties that belong to a tab
|
||||
// need to aggregate the tabs, as content.PropertyGroups contains all the composition tabs,
|
||||
// and there might be duplicates (content does not work like contentType and there is no
|
||||
// content.CompositionPropertyGroups).
|
||||
var groupsGroupsByName = contentType.CompositionPropertyGroups.OrderBy(x => x.SortOrder).GroupBy(x => x.Name);
|
||||
foreach (var groupsByName in groupsGroupsByName)
|
||||
{
|
||||
var properties = new List<IProperty>();
|
||||
|
||||
// merge properties for groups with the same name
|
||||
foreach (var group in groupsByName)
|
||||
{
|
||||
var groupProperties = source.GetPropertiesForGroup(group)
|
||||
.Where(x => IgnoreProperties.Contains(x.Alias) == false); // skip ignored
|
||||
|
||||
properties.AddRange(groupProperties);
|
||||
}
|
||||
|
||||
if (properties.Count == 0)
|
||||
continue;
|
||||
|
||||
//map the properties
|
||||
var mappedProperties = MapProperties(source, properties, context);
|
||||
|
||||
// add the tab
|
||||
// we need to pick an identifier... there is no "right" way...
|
||||
var g = groupsByName.FirstOrDefault(x => x.Id == source.ContentTypeId) // try local
|
||||
?? groupsByName.First(); // else pick one randomly
|
||||
var groupId = g.Id;
|
||||
var groupName = groupsByName.Key;
|
||||
tabs.Add(new Tab<ContentPropertyDisplay>
|
||||
{
|
||||
Id = groupId,
|
||||
Alias = groupName,
|
||||
Label = LocalizedTextService.UmbracoDictionaryTranslate(CultureDictionary, groupName),
|
||||
Properties = mappedProperties,
|
||||
IsActive = false
|
||||
});
|
||||
}
|
||||
|
||||
MapGenericProperties(source, tabs, context);
|
||||
|
||||
// activate the first tab, if any
|
||||
if (tabs.Count > 0)
|
||||
tabs[0].IsActive = true;
|
||||
|
||||
return tabs;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user