Merge branch 'v8/dev' into v8-fix-media-picker-create-folder
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using Umbraco.Core;
|
||||
|
||||
[assembly: PreApplicationStartMethod(typeof(BindingRedirects), "Initialize")]
|
||||
// no binding redirect for now = de-activate
|
||||
//[assembly: PreApplicationStartMethod(typeof(BindingRedirects), "Initialize")]
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
@@ -18,7 +18,7 @@ namespace Umbraco.Core
|
||||
// this only gets called when an assembly can't be resolved
|
||||
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This is used to do an assembly binding redirect via code - normally required due to signature changes in assemblies
|
||||
/// </summary>
|
||||
@@ -27,14 +27,19 @@ namespace Umbraco.Core
|
||||
/// <returns></returns>
|
||||
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
|
||||
{
|
||||
// When an assembly can't be resolved. In here we can do magic with the assembly name and try loading another.
|
||||
|
||||
// keep here for reference - we don't use AutoMapper
|
||||
/*
|
||||
//AutoMapper:
|
||||
// this is used for loading a signed assembly of AutoMapper (v. 3.1+) without having to recompile old code.
|
||||
// ensure the assembly is indeed AutoMapper and that the PublicKeyToken is null before trying to Load again
|
||||
// do NOT just replace this with 'return Assembly', as it will cause an infinite loop -> stackoverflow
|
||||
if (args.Name.StartsWith("AutoMapper") && args.Name.EndsWith("PublicKeyToken=null"))
|
||||
return Assembly.Load(args.Name.Replace(", PublicKeyToken=null", ", PublicKeyToken=be96cd2c38ef1005"));
|
||||
*/
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Scoping;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
@@ -13,11 +12,6 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public static NoCacheRepositoryCachePolicy<TEntity, TId> Instance { get; } = new NoCacheRepositoryCachePolicy<TEntity, TId>();
|
||||
|
||||
public IRepositoryCachePolicy<TEntity, TId> Scoped(IAppPolicyCache runtimeCache, IScope scope)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public TEntity Get(TId id, Func<TId, TEntity> performGet, Func<TId[], IEnumerable<TEntity>> performGetAll)
|
||||
{
|
||||
return performGet(id);
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Umbraco.Core.Compose
|
||||
|
||||
private static void ContentService_Moved(IContentService sender, MoveEventArgs<IContent> e)
|
||||
{
|
||||
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinContent.ToInvariantString())))
|
||||
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinContentString)))
|
||||
{
|
||||
var relationService = Current.Services.RelationService;
|
||||
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;
|
||||
@@ -37,7 +37,7 @@ namespace Umbraco.Core.Compose
|
||||
|
||||
private static void MediaService_Moved(IMediaService sender, MoveEventArgs<IMedia> e)
|
||||
{
|
||||
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinMedia.ToInvariantString())))
|
||||
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinMediaString)))
|
||||
{
|
||||
var relationService = Current.Services.RelationService;
|
||||
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias;
|
||||
|
||||
@@ -70,7 +70,23 @@ namespace Umbraco.Core.Composing
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<Type> PrepareComposerTypes()
|
||||
internal IEnumerable<Type> PrepareComposerTypes()
|
||||
{
|
||||
var requirements = GetRequirements();
|
||||
|
||||
// only for debugging, this is verbose
|
||||
//_logger.Debug<Composers>(GetComposersReport(requirements));
|
||||
|
||||
var sortedComposerTypes = SortComposers(requirements);
|
||||
|
||||
// bit verbose but should help for troubleshooting
|
||||
//var text = "Ordered Composers: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComposerTypes) + Environment.NewLine;
|
||||
_logger.Debug<Composers>("Ordered Composers: {SortedComposerTypes}", sortedComposerTypes);
|
||||
|
||||
return sortedComposerTypes;
|
||||
}
|
||||
|
||||
internal Dictionary<Type, List<Type>> GetRequirements(bool throwOnMissing = true)
|
||||
{
|
||||
// create a list, remove those that cannot be enabled due to runtime level
|
||||
var composerTypeList = _composerTypes
|
||||
@@ -89,25 +105,69 @@ namespace Umbraco.Core.Composing
|
||||
// enable or disable composers
|
||||
EnableDisableComposers(composerTypeList);
|
||||
|
||||
// sort the composers according to their dependencies
|
||||
var requirements = new Dictionary<Type, List<Type>>();
|
||||
foreach (var type in composerTypeList) requirements[type] = null;
|
||||
foreach (var type in composerTypeList)
|
||||
void GatherInterfaces<TAttribute>(Type type, Func<TAttribute, Type> getTypeInAttribute, HashSet<Type> iset, List<Type> set2)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
GatherRequirementsFromRequireAttribute(type, composerTypeList, requirements);
|
||||
GatherRequirementsFromRequiredByAttribute(type, composerTypeList, requirements);
|
||||
foreach (var attribute in type.GetCustomAttributes<TAttribute>())
|
||||
{
|
||||
var typeInAttribute = getTypeInAttribute(attribute);
|
||||
if (typeInAttribute != null && // if the attribute references a type ...
|
||||
typeInAttribute.IsInterface && // ... which is an interface ...
|
||||
typeof(IComposer).IsAssignableFrom(typeInAttribute) && // ... which implements IComposer ...
|
||||
!iset.Contains(typeInAttribute)) // ... which is not already in the list
|
||||
{
|
||||
// add it to the new list
|
||||
iset.Add(typeInAttribute);
|
||||
set2.Add(typeInAttribute);
|
||||
|
||||
// add all its interfaces implementing IComposer
|
||||
foreach (var i in typeInAttribute.GetInterfaces().Where(x => typeof(IComposer).IsAssignableFrom(x)))
|
||||
{
|
||||
iset.Add(i);
|
||||
set2.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// only for debugging, this is verbose
|
||||
//_logger.Debug<Composers>(GetComposersReport(requirements));
|
||||
// gather interfaces too
|
||||
var interfaces = new HashSet<Type>(composerTypeList.SelectMany(x => x.GetInterfaces().Where(y => typeof(IComposer).IsAssignableFrom(y))));
|
||||
composerTypeList.AddRange(interfaces);
|
||||
var list1 = composerTypeList;
|
||||
while (list1.Count > 0)
|
||||
{
|
||||
var list2 = new List<Type>();
|
||||
foreach (var t in list1)
|
||||
{
|
||||
GatherInterfaces<ComposeAfterAttribute>(t, a => a.RequiredType, interfaces, list2);
|
||||
GatherInterfaces<ComposeBeforeAttribute>(t, a => a.RequiringType, interfaces, list2);
|
||||
}
|
||||
composerTypeList.AddRange(list2);
|
||||
list1 = list2;
|
||||
}
|
||||
|
||||
// sort the composers according to their dependencies
|
||||
var requirements = new Dictionary<Type, List<Type>>();
|
||||
foreach (var type in composerTypeList)
|
||||
requirements[type] = null;
|
||||
foreach (var type in composerTypeList)
|
||||
{
|
||||
GatherRequirementsFromAfterAttribute(type, composerTypeList, requirements, throwOnMissing);
|
||||
GatherRequirementsFromBeforeAttribute(type, composerTypeList, requirements);
|
||||
}
|
||||
|
||||
return requirements;
|
||||
}
|
||||
|
||||
internal IEnumerable<Type> SortComposers(Dictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
// sort composers
|
||||
var graph = new TopoGraph<Type, KeyValuePair<Type, List<Type>>>(kvp => kvp.Key, kvp => kvp.Value);
|
||||
graph.AddItems(requirements);
|
||||
List<Type> sortedComposerTypes;
|
||||
try
|
||||
{
|
||||
sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).ToList();
|
||||
sortedComposerTypes = graph.GetSortedItems().Select(x => x.Key).Where(x => !x.IsInterface).ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -117,40 +177,37 @@ namespace Umbraco.Core.Composing
|
||||
throw;
|
||||
}
|
||||
|
||||
// bit verbose but should help for troubleshooting
|
||||
//var text = "Ordered Composers: " + Environment.NewLine + string.Join(Environment.NewLine, sortedComposerTypes) + Environment.NewLine;
|
||||
_logger.Debug<Composers>("Ordered Composers: {SortedComposerTypes}", sortedComposerTypes);
|
||||
|
||||
return sortedComposerTypes;
|
||||
}
|
||||
|
||||
private static string GetComposersReport(Dictionary<Type, List<Type>> requirements)
|
||||
internal static string GetComposersReport(Dictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
var text = new StringBuilder();
|
||||
text.AppendLine("Composers & Dependencies:");
|
||||
text.AppendLine(" < compose before");
|
||||
text.AppendLine(" > compose after");
|
||||
text.AppendLine(" : implements");
|
||||
text.AppendLine(" = depends");
|
||||
text.AppendLine();
|
||||
|
||||
bool HasReq(IEnumerable<Type> types, Type type)
|
||||
=> types.Any(x => type.IsAssignableFrom(x) && !x.IsInterface);
|
||||
|
||||
foreach (var kvp in requirements)
|
||||
{
|
||||
var type = kvp.Key;
|
||||
|
||||
text.AppendLine(type.FullName);
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeAfterAttribute>())
|
||||
text.AppendLine(" -> " + attribute.RequiredType + (attribute.Weak.HasValue
|
||||
? (attribute.Weak.Value ? " (weak)" : (" (strong" + (requirements.ContainsKey(attribute.RequiredType) ? ", missing" : "") + ")"))
|
||||
: ""));
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" -< " + attribute.RequiringType);
|
||||
foreach (var i in type.GetInterfaces())
|
||||
{
|
||||
text.AppendLine(" : " + i.FullName);
|
||||
foreach (var attribute in i.GetCustomAttributes<ComposeAfterAttribute>())
|
||||
text.AppendLine(" -> " + attribute.RequiredType + (attribute.Weak.HasValue
|
||||
? (attribute.Weak.Value ? " (weak)" : (" (strong" + (requirements.ContainsKey(attribute.RequiredType) ? ", missing" : "") + ")"))
|
||||
: ""));
|
||||
foreach (var attribute in i.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" -< " + attribute.RequiringType);
|
||||
var weak = !(attribute.RequiredType.IsInterface ? attribute.Weak == false : attribute.Weak != true);
|
||||
text.AppendLine(" > " + attribute.RequiredType +
|
||||
(weak ? " (weak" : " (strong") + (HasReq(requirements.Keys, attribute.RequiredType) ? ", found" : ", missing") + ")");
|
||||
}
|
||||
foreach (var attribute in type.GetCustomAttributes<ComposeBeforeAttribute>())
|
||||
text.AppendLine(" < " + attribute.RequiringType);
|
||||
foreach (var i in type.GetInterfaces())
|
||||
text.AppendLine(" : " + i.FullName);
|
||||
if (kvp.Value != null)
|
||||
foreach (var t in kvp.Value)
|
||||
text.AppendLine(" = " + t);
|
||||
@@ -221,16 +278,16 @@ namespace Umbraco.Core.Composing
|
||||
types.Remove(kvp.Key);
|
||||
}
|
||||
|
||||
private static void GatherRequirementsFromRequireAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
private static void GatherRequirementsFromAfterAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements, bool throwOnMissing = true)
|
||||
{
|
||||
// get 'require' attributes
|
||||
// these attributes are *not* inherited because we want to "custom-inherit" for interfaces only
|
||||
var requireAttributes = type
|
||||
var afterAttributes = type
|
||||
.GetInterfaces().SelectMany(x => x.GetCustomAttributes<ComposeAfterAttribute>()) // those marking interfaces
|
||||
.Concat(type.GetCustomAttributes<ComposeAfterAttribute>()); // those marking the composer
|
||||
|
||||
// what happens in case of conflicting attributes (different strong/weak for same type) is not specified.
|
||||
foreach (var attr in requireAttributes)
|
||||
foreach (var attr in afterAttributes)
|
||||
{
|
||||
if (attr.RequiredType == type) continue; // ignore self-requirements (+ exclude in implems, below)
|
||||
|
||||
@@ -238,13 +295,13 @@ namespace Umbraco.Core.Composing
|
||||
// unless strong, and then require at least one enabled composer implementing that interface
|
||||
if (attr.RequiredType.IsInterface)
|
||||
{
|
||||
var implems = types.Where(x => x != type && attr.RequiredType.IsAssignableFrom(x)).ToList();
|
||||
var implems = types.Where(x => x != type && attr.RequiredType.IsAssignableFrom(x) && !x.IsInterface).ToList();
|
||||
if (implems.Count > 0)
|
||||
{
|
||||
if (requirements[type] == null) requirements[type] = new List<Type>();
|
||||
requirements[type].AddRange(implems);
|
||||
}
|
||||
else if (attr.Weak == false) // if explicitly set to !weak, is strong, else is weak
|
||||
else if (attr.Weak == false && throwOnMissing) // if explicitly set to !weak, is strong, else is weak
|
||||
throw new Exception($"Broken composer dependency: {type.FullName} -> {attr.RequiredType.FullName}.");
|
||||
}
|
||||
// requiring a class = require that the composer is enabled
|
||||
@@ -256,28 +313,28 @@ namespace Umbraco.Core.Composing
|
||||
if (requirements[type] == null) requirements[type] = new List<Type>();
|
||||
requirements[type].Add(attr.RequiredType);
|
||||
}
|
||||
else if (attr.Weak != true) // if not explicitly set to weak, is strong
|
||||
else if (attr.Weak != true && throwOnMissing) // if not explicitly set to weak, is strong
|
||||
throw new Exception($"Broken composer dependency: {type.FullName} -> {attr.RequiredType.FullName}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void GatherRequirementsFromRequiredByAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
private static void GatherRequirementsFromBeforeAttribute(Type type, ICollection<Type> types, IDictionary<Type, List<Type>> requirements)
|
||||
{
|
||||
// get 'required' attributes
|
||||
// these attributes are *not* inherited because we want to "custom-inherit" for interfaces only
|
||||
var requiredAttributes = type
|
||||
var beforeAttributes = type
|
||||
.GetInterfaces().SelectMany(x => x.GetCustomAttributes<ComposeBeforeAttribute>()) // those marking interfaces
|
||||
.Concat(type.GetCustomAttributes<ComposeBeforeAttribute>()); // those marking the composer
|
||||
|
||||
foreach (var attr in requiredAttributes)
|
||||
foreach (var attr in beforeAttributes)
|
||||
{
|
||||
if (attr.RequiringType == type) continue; // ignore self-requirements (+ exclude in implems, below)
|
||||
|
||||
// required by an interface = by any enabled composer implementing this that interface
|
||||
if (attr.RequiringType.IsInterface)
|
||||
{
|
||||
var implems = types.Where(x => x != type && attr.RequiringType.IsAssignableFrom(x)).ToList();
|
||||
var implems = types.Where(x => x != type && attr.RequiringType.IsAssignableFrom(x) && !x.IsInterface).ToList();
|
||||
foreach (var implem in implems)
|
||||
{
|
||||
if (requirements[implem] == null) requirements[implem] = new List<Type>();
|
||||
|
||||
@@ -133,7 +133,11 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
Configs.RegisterWith(_register);
|
||||
|
||||
return _register.CreateFactory();
|
||||
IFactory factory = null;
|
||||
// ReSharper disable once AccessToModifiedClosure -- on purpose
|
||||
_register.Register(_ => factory, Lifetime.Singleton);
|
||||
factory = _register.CreateFactory();
|
||||
return factory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
|
||||
namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
@@ -8,7 +8,9 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
{
|
||||
public static Composition ComposeCoreMappingProfiles(this Composition composition)
|
||||
{
|
||||
composition.Register<Profile, IdentityMapperProfile>();
|
||||
composition.RegisterUnique<UmbracoMapper>();
|
||||
composition.WithCollectionBuilder<MapDefinitionCollectionBuilder>()
|
||||
.Add<IdentityMapDefinition>();
|
||||
return composition;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
composition.RegisterUnique<IPartialViewRepository, PartialViewRepository>();
|
||||
composition.RegisterUnique<IScriptRepository, ScriptRepository>();
|
||||
composition.RegisterUnique<IStylesheetRepository, StylesheetRepository>();
|
||||
composition.RegisterUnique<IContentTypeCommonRepository, ContentTypeCommonRepository>();
|
||||
|
||||
return composition;
|
||||
}
|
||||
|
||||
@@ -98,7 +98,6 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
: appPlugins.GetDirectories()
|
||||
.SelectMany(x => x.GetDirectories("Lang"))
|
||||
.SelectMany(x => x.GetFiles("*.xml", SearchOption.TopDirectoryOnly))
|
||||
.Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 5)
|
||||
.Select(x => new LocalizedTextServiceSupplementaryFileSource(x, false));
|
||||
|
||||
//user defined langs that overwrite the default, these should not be used by plugin creators
|
||||
@@ -106,7 +105,6 @@ namespace Umbraco.Core.Composing.CompositionExtensions
|
||||
? Enumerable.Empty<LocalizedTextServiceSupplementaryFileSource>()
|
||||
: configLangFolder
|
||||
.GetFiles("*.user.xml", SearchOption.TopDirectoryOnly)
|
||||
.Where(x => Path.GetFileNameWithoutExtension(x.FullName).Length == 10)
|
||||
.Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true));
|
||||
|
||||
return new LocalizedTextServiceFileSources(
|
||||
|
||||
@@ -4,6 +4,7 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Dictionary;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Core.PackageActions;
|
||||
using Umbraco.Core.Packaging;
|
||||
@@ -103,6 +104,9 @@ namespace Umbraco.Core.Composing
|
||||
|
||||
#region Getters
|
||||
|
||||
public static UmbracoMapper Mapper
|
||||
=> _factory.GetInstance<UmbracoMapper>();
|
||||
|
||||
public static IShortStringHelper ShortStringHelper
|
||||
=> _shortStringHelper ?? (_shortStringHelper = _factory?.TryGetInstance<IShortStringHelper>()
|
||||
?? new DefaultShortStringHelper(new DefaultShortStringHelperConfig().WithDefault(Configs.Settings())));
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
/// <summary>
|
||||
/// Compose.
|
||||
/// </summary>
|
||||
/// <param name="composition"></param>
|
||||
void Compose(Composition composition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@
|
||||
/// Represents a core <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All core composers are required by (compose before) all user composers,
|
||||
/// and require (compose after) all runtime composers.</para>
|
||||
/// <para>Core composers compose after the initial composer, and before user composers.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(IRuntimeComposer))]
|
||||
public interface ICoreComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a runtime <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All runtime composers are required by (compose before) all core composers</para>
|
||||
/// </remarks>
|
||||
public interface IRuntimeComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
@@ -4,9 +4,9 @@
|
||||
/// Represents a user <see cref="IComposer"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>All user composers require (compose after) all core composers.</para>
|
||||
/// <para>User composers compose after core composers, and before the final composer.</para>
|
||||
/// </remarks>
|
||||
[ComposeAfter(typeof(ICoreComposer))]
|
||||
public interface IUserComposer : IComposer
|
||||
{ }
|
||||
}
|
||||
}
|
||||
|
||||
171
src/Umbraco.Core/Composing/SetCollectionBuilderBase.cs
Normal file
171
src/Umbraco.Core/Composing/SetCollectionBuilderBase.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Implements an un-ordered collection builder.
|
||||
/// </summary>
|
||||
/// <typeparam name="TBuilder">The type of the builder.</typeparam>
|
||||
/// <typeparam name="TCollection">The type of the collection.</typeparam>
|
||||
/// <typeparam name="TItem">The type of the items.</typeparam>
|
||||
/// <remarks>
|
||||
/// <para>A set collection builder is the most basic collection builder,
|
||||
/// where items are not ordered.</para>
|
||||
/// </remarks>
|
||||
public abstract class SetCollectionBuilderBase<TBuilder, TCollection, TItem> : CollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TBuilder : SetCollectionBuilderBase<TBuilder, TCollection, TItem>
|
||||
where TCollection : class, IBuilderCollection<TItem>
|
||||
{
|
||||
protected abstract TBuilder This { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Clears all types in the collection.
|
||||
/// </summary>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Clear()
|
||||
{
|
||||
Configure(types => types.Clear());
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a type to the collection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to append.</typeparam>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Add<T>()
|
||||
where T : TItem
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
types.Add(type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a type to the collection.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to append.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Add(Type type)
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
EnsureType(type, "register");
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
types.Add(type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds types to the collections.
|
||||
/// </summary>
|
||||
/// <param name="types">The types to append.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Add(IEnumerable<Type> types)
|
||||
{
|
||||
Configure(list =>
|
||||
{
|
||||
foreach (var type in types)
|
||||
{
|
||||
// would be detected by CollectionBuilderBase when registering, anyways, but let's fail fast
|
||||
EnsureType(type, "register");
|
||||
if (list.Contains(type)) list.Remove(type);
|
||||
list.Add(type);
|
||||
}
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a type from the collection.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type to remove.</typeparam>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Remove<T>()
|
||||
where T : TItem
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
var type = typeof(T);
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a type from the collection.
|
||||
/// </summary>
|
||||
/// <param name="type">The type to remove.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
public TBuilder Remove(Type type)
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
EnsureType(type, "remove");
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces a type in the collection.
|
||||
/// </summary>
|
||||
/// <typeparam name="TReplaced">The type to replace.</typeparam>
|
||||
/// <typeparam name="T">The type to insert.</typeparam>
|
||||
/// <returns>The builder.</returns>
|
||||
/// <remarks>Throws if the type to replace does not already belong to the collection.</remarks>
|
||||
public TBuilder Replace<TReplaced, T>()
|
||||
where TReplaced : TItem
|
||||
where T : TItem
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
var typeReplaced = typeof(TReplaced);
|
||||
var type = typeof(T);
|
||||
if (typeReplaced == type) return;
|
||||
|
||||
var index = types.IndexOf(typeReplaced);
|
||||
if (index < 0) throw new InvalidOperationException();
|
||||
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
index = types.IndexOf(typeReplaced); // in case removing type changed index
|
||||
types.Insert(index, type);
|
||||
types.Remove(typeReplaced);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces a type in the collection.
|
||||
/// </summary>
|
||||
/// <param name="typeReplaced">The type to replace.</param>
|
||||
/// <param name="type">The type to insert.</param>
|
||||
/// <returns>The builder.</returns>
|
||||
/// <remarks>Throws if the type to replace does not already belong to the collection.</remarks>
|
||||
public TBuilder Replace(Type typeReplaced, Type type)
|
||||
{
|
||||
Configure(types =>
|
||||
{
|
||||
EnsureType(typeReplaced, "find");
|
||||
EnsureType(type, "register");
|
||||
|
||||
if (typeReplaced == type) return;
|
||||
|
||||
var index = types.IndexOf(typeReplaced);
|
||||
if (index < 0) throw new InvalidOperationException();
|
||||
|
||||
if (types.Contains(type)) types.Remove(type);
|
||||
index = types.IndexOf(typeReplaced); // in case removing type changed index
|
||||
types.Insert(index, type);
|
||||
types.Remove(typeReplaced);
|
||||
});
|
||||
return This;
|
||||
}
|
||||
}
|
||||
}
|
||||
44
src/Umbraco.Core/Composing/TypeCollectionBuilderBase.cs
Normal file
44
src/Umbraco.Core/Composing/TypeCollectionBuilderBase.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Composing
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a base class for collections of types.
|
||||
/// </summary>
|
||||
public abstract class TypeCollectionBuilderBase<TCollection, TConstraint> : ICollectionBuilder<TCollection, Type>
|
||||
where TCollection : class, IBuilderCollection<Type>
|
||||
{
|
||||
private readonly HashSet<Type> _types = new HashSet<Type>();
|
||||
|
||||
private Type Validate(Type type, string action)
|
||||
{
|
||||
if (!typeof(TConstraint).IsAssignableFrom(type))
|
||||
throw new InvalidOperationException($"Cannot {action} type {type.FullName} as it does not inherit from/implement {typeof(TConstraint).FullName}.");
|
||||
return type;
|
||||
}
|
||||
|
||||
public void Add(Type type) => _types.Add(Validate(type, "add"));
|
||||
|
||||
public void Add<T>() => Add(typeof(T));
|
||||
|
||||
public void Add(IEnumerable<Type> types)
|
||||
{
|
||||
foreach (var type in types) Add(type);
|
||||
}
|
||||
|
||||
public void Remove(Type type) => _types.Remove(Validate(type, "remove"));
|
||||
|
||||
public void Remove<T>() => Remove(typeof(T));
|
||||
|
||||
public TCollection CreateCollection(IFactory factory)
|
||||
{
|
||||
return factory.CreateInstance<TCollection>(_types);
|
||||
}
|
||||
|
||||
public void RegisterWith(IRegister register)
|
||||
{
|
||||
register.Register(CreateCollection, Lifetime.Singleton);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -203,6 +203,28 @@ namespace Umbraco.Core
|
||||
composition.RegisterUnique(_ => registrar);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the database server messenger options.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="factory">A function creating the options.</param>
|
||||
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
|
||||
public static void SetDatabaseServerMessengerOptions(this Composition composition, Func<IFactory, DatabaseServerMessengerOptions> factory)
|
||||
{
|
||||
composition.RegisterUnique(factory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the database server messenger options.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition.</param>
|
||||
/// <param name="options">Options.</param>
|
||||
/// <remarks>Use DatabaseServerRegistrarAndMessengerComposer.GetDefaultOptions to get the options that Umbraco would use by default.</remarks>
|
||||
public static void SetDatabaseServerMessengerOptions(this Composition composition, DatabaseServerMessengerOptions options)
|
||||
{
|
||||
composition.RegisterUnique(_ => options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the short string helper.
|
||||
/// </summary>
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Net.Configuration;
|
||||
using System.Web;
|
||||
using System.Web.Configuration;
|
||||
using System.Web.Hosting;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
@@ -17,16 +18,15 @@ namespace Umbraco.Core.Configuration
|
||||
/// </summary>
|
||||
public class GlobalSettings : IGlobalSettings
|
||||
{
|
||||
private string _localTempPath;
|
||||
|
||||
#region Private static fields
|
||||
|
||||
|
||||
// TODO these should not be static
|
||||
private static string _reservedPaths;
|
||||
private static string _reservedUrls;
|
||||
|
||||
//ensure the built on (non-changeable) reserved paths are there at all times
|
||||
internal const string StaticReservedPaths = "~/app_plugins/,~/install/,~/mini-profiler-resources/,"; //must end with a comma!
|
||||
internal const string StaticReservedUrls = "~/config/splashes/noNodes.aspx,~/.well-known,"; //must end with a comma!
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config)
|
||||
@@ -131,7 +131,7 @@ namespace Umbraco.Core.Configuration
|
||||
: "~/App_Data/umbraco.config";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to umbraco's root directory (/umbraco by default).
|
||||
/// </summary>
|
||||
@@ -163,7 +163,7 @@ namespace Umbraco.Core.Configuration
|
||||
SaveSetting(Constants.AppSettings.ConfigurationStatus, value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves a setting into the configuration file.
|
||||
/// </summary>
|
||||
@@ -206,7 +206,7 @@ namespace Umbraco.Core.Configuration
|
||||
ConfigurationManager.RefreshSection("appSettings");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether umbraco is running in [debug mode].
|
||||
/// </summary>
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of days that should take place between version checks.
|
||||
/// </summary>
|
||||
@@ -269,7 +269,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc />
|
||||
public LocalTempStorage LocalTempStorageLocation
|
||||
{
|
||||
@@ -288,25 +288,43 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_localTempPath != null)
|
||||
return _localTempPath;
|
||||
|
||||
switch (LocalTempStorageLocation)
|
||||
{
|
||||
case LocalTempStorage.AspNetTemp:
|
||||
return System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData");
|
||||
return _localTempPath = System.IO.Path.Combine(HttpRuntime.CodegenDir, "UmbracoData");
|
||||
|
||||
case LocalTempStorage.EnvironmentTemp:
|
||||
// include the appdomain hash is just a safety check, for example if a website is moved from worker A to worker B and then back
|
||||
// to worker A again, in theory the %temp% folder should already be empty but we really want to make sure that its not
|
||||
// utilizing an old path - assuming we cannot have SHA1 collisions on AppDomainAppId
|
||||
var appDomainHash = HttpRuntime.AppDomainAppId.GenerateHash();
|
||||
return System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", appDomainHash);
|
||||
|
||||
// environment temp is unique, we need a folder per site
|
||||
|
||||
// use a hash
|
||||
// combine site name and application id
|
||||
// site name is a Guid on Cloud
|
||||
// application id is eg /LM/W3SVC/123456/ROOT
|
||||
// the combination is unique on one server
|
||||
// and, if a site moves from worker A to B and then back to A...
|
||||
// hopefully it gets a new Guid or new application id?
|
||||
|
||||
var siteName = HostingEnvironment.SiteName;
|
||||
var applicationId = HostingEnvironment.ApplicationID; // ie HttpRuntime.AppDomainAppId
|
||||
|
||||
var hashString = siteName + "::" + applicationId;
|
||||
var hash = hashString.GenerateHash();
|
||||
var siteTemp = System.IO.Path.Combine(Environment.ExpandEnvironmentVariables("%temp%"), "UmbracoData", hash);
|
||||
|
||||
return _localTempPath = siteTemp;
|
||||
|
||||
//case LocalTempStorage.Default:
|
||||
//case LocalTempStorage.Unknown:
|
||||
default:
|
||||
return IOHelper.MapPath("~/App_Data/TEMP");
|
||||
return _localTempPath = IOHelper.MapPath("~/App_Data/TEMP");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default UI language.
|
||||
/// </summary>
|
||||
|
||||
@@ -93,7 +93,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string DisableElectionForSingleServer = "Umbraco.Core.DisableElectionForSingleServer";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Debug specific web.config AppSetting keys for Umbraco
|
||||
/// </summary>
|
||||
|
||||
@@ -145,11 +145,11 @@
|
||||
|
||||
public const string PartialViewMacros = "partialViewMacros";
|
||||
|
||||
public const string LogViewer = "logViewer";
|
||||
public const string LogViewer = "logViewer";
|
||||
|
||||
public static class Groups
|
||||
{
|
||||
public const string Settings = "settingsGroup";
|
||||
public const string Settings = "settingsGroup";
|
||||
|
||||
public const string Templating = "templatingGroup";
|
||||
|
||||
|
||||
@@ -92,10 +92,10 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string Extension = "umbracoExtension";
|
||||
|
||||
/// <summary>
|
||||
/// The default height/width of an image file if the size can't be determined from the metadata
|
||||
/// </summary>
|
||||
public const int DefaultSize = 200;
|
||||
/// <summary>
|
||||
/// The default height/width of an image file if the size can't be determined from the metadata
|
||||
/// </summary>
|
||||
public const int DefaultSize = 200;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -209,71 +209,71 @@ namespace Umbraco.Core
|
||||
public static Dictionary<string, PropertyType> GetStandardPropertyTypeStubs()
|
||||
{
|
||||
return new Dictionary<string, PropertyType>
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(PropertyEditors.Aliases.TextArea, ValueStorageType.Ntext, true, Comments)
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(PropertyEditors.Aliases.TextArea, ValueStorageType.Ntext, true, Comments)
|
||||
{
|
||||
Name = CommentsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts)
|
||||
{
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, true, IsApproved)
|
||||
{
|
||||
Name = IsApprovedLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, true, IsLockedOut)
|
||||
{
|
||||
Name = IsLockedOutLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate)
|
||||
{
|
||||
Name = LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate)
|
||||
{
|
||||
Name = LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate)
|
||||
{
|
||||
Name = LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer)
|
||||
{
|
||||
Name = PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion)
|
||||
{
|
||||
Name = PasswordQuestionLabel
|
||||
}
|
||||
Name = CommentsLabel
|
||||
}
|
||||
};
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Integer, true, FailedPasswordAttempts)
|
||||
{
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, true, IsApproved)
|
||||
{
|
||||
Name = IsApprovedLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(PropertyEditors.Aliases.Boolean, ValueStorageType.Integer, true, IsLockedOut)
|
||||
{
|
||||
Name = IsLockedOutLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLockoutDate)
|
||||
{
|
||||
Name = LastLockoutDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastLoginDate)
|
||||
{
|
||||
Name = LastLoginDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Date, true, LastPasswordChangeDate)
|
||||
{
|
||||
Name = LastPasswordChangeDateLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordAnswer)
|
||||
{
|
||||
Name = PasswordAnswerLabel
|
||||
}
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(PropertyEditors.Aliases.Label, ValueStorageType.Nvarchar, true, PasswordQuestion)
|
||||
{
|
||||
Name = PasswordQuestionLabel
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
public static class Icons
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// System contenttype icon
|
||||
/// </summary>
|
||||
@@ -42,12 +34,10 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string MemberType = "icon-users";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// System member icon
|
||||
/// </summary>
|
||||
public const string Template = "icon-layout";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
|
||||
@@ -123,7 +123,6 @@ namespace Umbraco.Core
|
||||
public static readonly Guid Template = new Guid(Strings.Template);
|
||||
|
||||
public static readonly Guid ContentItem = new Guid(Strings.ContentItem);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
public static partial class Constants
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the constants used for the Umbraco package repository
|
||||
/// Defines the constants used for the Umbraco package repository
|
||||
/// </summary>
|
||||
public static class PackageRepository
|
||||
{
|
||||
|
||||
@@ -34,7 +34,6 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public const string ContentPicker = "Umbraco.ContentPicker";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// DateTime.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Umbraco.Core
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
public static partial class Constants
|
||||
{
|
||||
@@ -22,7 +19,6 @@ namespace Umbraco.Core
|
||||
public const string PreviewCookieName = "UMB_PREVIEW";
|
||||
|
||||
public const string InstallerCookieName = "umb_installId";
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Web;
|
||||
using System.Xml.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NPoco.Expressions;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Models;
|
||||
@@ -52,8 +53,8 @@ namespace Umbraco.Core
|
||||
return ContentStatus.Unpublished;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
@@ -134,9 +135,14 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Sets the posted file value of a property.
|
||||
/// </summary>
|
||||
/// <remarks>This really is for FileUpload fields only, and should be obsoleted. For anything else,
|
||||
/// you need to store the file by yourself using Store and then figure out
|
||||
/// how to deal with auto-fill properties (if any) and thumbnails (if any) by yourself.</remarks>
|
||||
public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, HttpPostedFileBase postedFile, string culture = null, string segment = null)
|
||||
{
|
||||
content.SetValue(contentTypeBaseServiceProvider, propertyTypeAlias, postedFile.FileName, postedFile.InputStream, culture, segment);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the posted file value of a property.
|
||||
/// </summary>
|
||||
public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
|
||||
{
|
||||
if (filename == null || filestream == null) return;
|
||||
|
||||
@@ -10,6 +10,18 @@ namespace Umbraco.Core
|
||||
///</summary>
|
||||
public static class EnumerableExtensions
|
||||
{
|
||||
internal static bool HasDuplicates<T>(this IEnumerable<T> items, bool includeNull)
|
||||
{
|
||||
var hs = new HashSet<T>();
|
||||
foreach (var item in items)
|
||||
{
|
||||
if ((item != null || includeNull) && !hs.Add(item))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Wraps this object instance into an IEnumerable{T} consisting of a single item.
|
||||
/// </summary>
|
||||
@@ -100,7 +112,7 @@ namespace Umbraco.Core
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if all items in the other collection exist in this collection
|
||||
/// </summary>
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog.Events;
|
||||
using Serilog.Formatting.Compact.Reader;
|
||||
|
||||
@@ -10,13 +11,15 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
internal class JsonLogViewer : LogViewerSourceBase
|
||||
{
|
||||
private readonly string _logsPath;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public JsonLogViewer(string logsPath = "", string searchPath = "") : base(searchPath)
|
||||
public JsonLogViewer(ILogger logger, string logsPath = "", string searchPath = "") : base(searchPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(logsPath))
|
||||
logsPath = $@"{AppDomain.CurrentDomain.BaseDirectory}\App_Data\Logs\";
|
||||
|
||||
_logsPath = logsPath;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
private const int FileSizeCap = 100;
|
||||
@@ -77,8 +80,14 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
using (var stream = new StreamReader(fs))
|
||||
{
|
||||
var reader = new LogEventReader(stream);
|
||||
while (reader.TryRead(out var evt))
|
||||
while (TryRead(reader, out var evt))
|
||||
{
|
||||
//We may get a null if log line is malformed
|
||||
if (evt == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (count > skip + take)
|
||||
{
|
||||
break;
|
||||
@@ -105,5 +114,21 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
return logs;
|
||||
}
|
||||
|
||||
private bool TryRead(LogEventReader reader, out LogEvent evt)
|
||||
{
|
||||
try
|
||||
{
|
||||
return reader.TryRead(out evt);
|
||||
}
|
||||
catch (JsonReaderException ex)
|
||||
{
|
||||
// As we are reading/streaming one line at a time in the JSON file
|
||||
// Thus we can not report the line number, as it will always be 1
|
||||
_logger.Error<JsonLogViewer>(ex, "Unable to parse a line in the JSON log file");
|
||||
|
||||
evt = null;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Umbraco.Core.Logging.Viewer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
composition.SetLogViewer(_ => new JsonLogViewer());
|
||||
composition.SetLogViewer(_ => new JsonLogViewer(composition.Logger));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
src/Umbraco.Core/Mapping/IMapDefinition.cs
Normal file
13
src/Umbraco.Core/Mapping/IMapDefinition.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines maps for <see cref="UmbracoMapper"/>.
|
||||
/// </summary>
|
||||
public interface IMapDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines maps.
|
||||
/// </summary>
|
||||
void DefineMaps(UmbracoMapper mapper);
|
||||
}
|
||||
}
|
||||
12
src/Umbraco.Core/Mapping/MapDefinitionCollection.cs
Normal file
12
src/Umbraco.Core/Mapping/MapDefinitionCollection.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
public class MapDefinitionCollection : BuilderCollectionBase<IMapDefinition>
|
||||
{
|
||||
public MapDefinitionCollection(IEnumerable<IMapDefinition> items)
|
||||
: base(items)
|
||||
{ }
|
||||
}
|
||||
}
|
||||
11
src/Umbraco.Core/Mapping/MapDefinitionCollectionBuilder.cs
Normal file
11
src/Umbraco.Core/Mapping/MapDefinitionCollectionBuilder.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
public class MapDefinitionCollectionBuilder : SetCollectionBuilderBase<MapDefinitionCollectionBuilder, MapDefinitionCollection, IMapDefinition>
|
||||
{
|
||||
protected override MapDefinitionCollectionBuilder This => this;
|
||||
|
||||
protected override Lifetime CollectionLifetime => Lifetime.Transient;
|
||||
}
|
||||
}
|
||||
130
src/Umbraco.Core/Mapping/MapperContext.cs
Normal file
130
src/Umbraco.Core/Mapping/MapperContext.cs
Normal file
@@ -0,0 +1,130 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a mapper context.
|
||||
/// </summary>
|
||||
public class MapperContext
|
||||
{
|
||||
private readonly UmbracoMapper _mapper;
|
||||
private IDictionary<string, object> _items;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MapperContext"/> class.
|
||||
/// </summary>
|
||||
public MapperContext(UmbracoMapper mapper)
|
||||
{
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the context has items.
|
||||
/// </summary>
|
||||
public bool HasItems => _items != null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the context items.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Items => _items ?? (_items = new Dictionary<string, object>());
|
||||
|
||||
#region Map
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TTarget>(object source)
|
||||
=> _mapper.Map<TTarget>(source, this);
|
||||
|
||||
// let's say this is a bad (dangerous) idea, and leave it out for now
|
||||
/*
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TTarget>(object source, Action<MapperContext> f)
|
||||
{
|
||||
f(this);
|
||||
return _mapper.Map<TTarget>(source, this);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source)
|
||||
=> _mapper.Map<TSource, TTarget>(source, this);
|
||||
|
||||
// let's say this is a bad (dangerous) idea, and leave it out for now
|
||||
/*
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, Action<MapperContext> f)
|
||||
{
|
||||
f(this);
|
||||
return _mapper.Map<TSource, TTarget>(source, this);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to an existing target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target)
|
||||
=> _mapper.Map(source, target, this);
|
||||
|
||||
// let's say this is a bad (dangerous) idea, and leave it out for now
|
||||
/*
|
||||
/// <summary>
|
||||
/// Maps a source object to an existing target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target, Action<MapperContext> f)
|
||||
{
|
||||
f(this);
|
||||
return _mapper.Map(source, target, this);
|
||||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Maps an enumerable of source objects to a new list of target objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSourceElement">The type of the source objects.</typeparam>
|
||||
/// <typeparam name="TTargetElement">The type of the target objects.</typeparam>
|
||||
/// <param name="source">The source objects.</param>
|
||||
/// <returns>A list containing the target objects.</returns>
|
||||
public List<TTargetElement> MapEnumerable<TSourceElement, TTargetElement>(IEnumerable<TSourceElement> source)
|
||||
{
|
||||
return source.Select(Map<TSourceElement, TTargetElement>).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
424
src/Umbraco.Core/Mapping/UmbracoMapper.cs
Normal file
424
src/Umbraco.Core/Mapping/UmbracoMapper.cs
Normal file
@@ -0,0 +1,424 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Mapping
|
||||
{
|
||||
// notes:
|
||||
// AutoMapper maps null to empty arrays, lists, etc
|
||||
|
||||
// TODO:
|
||||
// when mapping from TSource, and no map is found, consider the actual source.GetType()?
|
||||
// when mapping to TTarget, and no map is found, consider the actual target.GetType()?
|
||||
// not sure we want to add magic to this simple mapper class, though
|
||||
|
||||
/// <summary>
|
||||
/// Umbraco Mapper.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>When a map is defined from TSource to TTarget, the mapper automatically knows how to map
|
||||
/// from IEnumerable{TSource} to IEnumerable{TTarget} (using a List{TTarget}) and to TTarget[].</para>
|
||||
/// <para>When a map is defined from TSource to TTarget, the mapper automatically uses that map
|
||||
/// for any source type that inherits from, or implements, TSource.</para>
|
||||
/// <para>When a map is defined from TSource to TTarget, the mapper can map to TTarget exclusively
|
||||
/// and cannot re-use that map for types that would inherit from, or implement, TTarget.</para>
|
||||
/// <para>When using the Map{TSource, TTarget}(TSource source, ...) overloads, TSource is explicit. When
|
||||
/// using the Map{TTarget}(object source, ...) TSource is defined as source.GetType().</para>
|
||||
/// <para>In both cases, TTarget is explicit and not typeof(target).</para>
|
||||
/// </remarks>
|
||||
public class UmbracoMapper
|
||||
{
|
||||
private readonly Dictionary<Type, Dictionary<Type, Func<object, MapperContext, object>>> _ctors
|
||||
= new Dictionary<Type, Dictionary<Type, Func<object, MapperContext, object>>>();
|
||||
|
||||
private readonly Dictionary<Type, Dictionary<Type, Action<object, object, MapperContext>>> _maps
|
||||
= new Dictionary<Type, Dictionary<Type, Action<object, object, MapperContext>>>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UmbracoMapper"/> class.
|
||||
/// </summary>
|
||||
/// <param name="profiles"></param>
|
||||
public UmbracoMapper(MapDefinitionCollection profiles)
|
||||
{
|
||||
foreach (var profile in profiles)
|
||||
profile.DefineMaps(this);
|
||||
}
|
||||
|
||||
#region Define
|
||||
|
||||
private static TTarget ThrowCtor<TSource, TTarget>(TSource source, MapperContext context)
|
||||
=> throw new InvalidOperationException($"Don't know how to create {typeof(TTarget).FullName} instances.");
|
||||
|
||||
private static void Identity<TSource, TTarget>(TSource source, TTarget target, MapperContext context)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Defines a mapping.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
public void Define<TSource, TTarget>()
|
||||
=> Define<TSource, TTarget>(ThrowCtor<TSource, TTarget>, Identity);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a mapping.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="map">A mapping method.</param>
|
||||
public void Define<TSource, TTarget>(Action<TSource, TTarget, MapperContext> map)
|
||||
=> Define(ThrowCtor<TSource, TTarget>, map);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a mapping.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="ctor">A constructor method.</param>
|
||||
public void Define<TSource, TTarget>(Func<TSource, MapperContext, TTarget> ctor)
|
||||
=> Define(ctor, Identity);
|
||||
|
||||
/// <summary>
|
||||
/// Defines a mapping.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="ctor">A constructor method.</param>
|
||||
/// <param name="map">A mapping method.</param>
|
||||
public void Define<TSource, TTarget>(Func<TSource, MapperContext, TTarget> ctor, Action<TSource, TTarget, MapperContext> map)
|
||||
{
|
||||
var sourceType = typeof(TSource);
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var sourceCtors = DefineCtors(sourceType);
|
||||
if (ctor != null)
|
||||
sourceCtors[targetType] = (source, context) => ctor((TSource)source, context);
|
||||
|
||||
var sourceMaps = DefineMaps(sourceType);
|
||||
sourceMaps[targetType] = (source, target, context) => map((TSource)source, (TTarget)target, context);
|
||||
}
|
||||
|
||||
private Dictionary<Type, Func<object, MapperContext, object>> DefineCtors(Type sourceType)
|
||||
{
|
||||
if (!_ctors.TryGetValue(sourceType, out var sourceCtor))
|
||||
sourceCtor = _ctors[sourceType] = new Dictionary<Type, Func<object, MapperContext, object>>();
|
||||
return sourceCtor;
|
||||
}
|
||||
|
||||
private Dictionary<Type, Action<object, object, MapperContext>> DefineMaps(Type sourceType)
|
||||
{
|
||||
if (!_maps.TryGetValue(sourceType, out var sourceMap))
|
||||
sourceMap = _maps[sourceType] = new Dictionary<Type, Action<object, object, MapperContext>>();
|
||||
return sourceMap;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Map
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TTarget>(object source)
|
||||
=> Map<TTarget>(source, new MapperContext(this));
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TTarget>(object source, Action<MapperContext> f)
|
||||
{
|
||||
var context = new MapperContext(this);
|
||||
f(context);
|
||||
return Map<TTarget>(source, context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="context">A mapper context.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TTarget>(object source, MapperContext context)
|
||||
=> Map<TTarget>(source, source?.GetType(), context);
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source)
|
||||
=> Map<TSource, TTarget>(source, new MapperContext(this));
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, Action<MapperContext> f)
|
||||
{
|
||||
var context = new MapperContext(this);
|
||||
f(context);
|
||||
return Map<TSource, TTarget>(source, context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to a new target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="context">A mapper context.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, MapperContext context)
|
||||
=> Map<TTarget>(source, typeof(TSource), context);
|
||||
|
||||
private TTarget Map<TTarget>(object source, Type sourceType, MapperContext context)
|
||||
{
|
||||
if (source == null)
|
||||
throw new ArgumentNullException(nameof(source));
|
||||
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var ctor = GetCtor(sourceType, targetType);
|
||||
var map = GetMap(sourceType, targetType);
|
||||
|
||||
// if there is a direct constructor, map
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
var target = ctor(source, context);
|
||||
map(source, target, context);
|
||||
return (TTarget)target;
|
||||
}
|
||||
|
||||
// otherwise, see if we can deal with enumerable
|
||||
|
||||
var ienumerableOfT = typeof(IEnumerable<>);
|
||||
|
||||
bool IsIEnumerableOfT(Type type) =>
|
||||
type.IsGenericType &&
|
||||
type.GenericTypeArguments.Length == 1 &&
|
||||
type.GetGenericTypeDefinition() == ienumerableOfT;
|
||||
|
||||
// try to get source as an IEnumerable<T>
|
||||
var sourceIEnumerable = IsIEnumerableOfT(sourceType) ? sourceType : sourceType.GetInterfaces().FirstOrDefault(IsIEnumerableOfT);
|
||||
|
||||
// if source is an IEnumerable<T> and target is T[] or IEnumerable<T>, we can create a map
|
||||
if (sourceIEnumerable != null && IsEnumerableOrArrayOfType(targetType))
|
||||
{
|
||||
var sourceGenericArg = sourceIEnumerable.GenericTypeArguments[0];
|
||||
var targetGenericArg = GetEnumerableOrArrayTypeArgument(targetType);
|
||||
|
||||
ctor = GetCtor(sourceGenericArg, targetGenericArg);
|
||||
map = GetMap(sourceGenericArg, targetGenericArg);
|
||||
|
||||
// if there is a constructor for the underlying type, create & invoke the map
|
||||
if (ctor != null && map != null)
|
||||
{
|
||||
// register (for next time) and do it now (for this time)
|
||||
object NCtor(object s, MapperContext c) => MapEnumerableInternal<TTarget>((IEnumerable) s, targetGenericArg, ctor, map, c);
|
||||
DefineCtors(sourceType)[targetType] = NCtor;
|
||||
DefineMaps(sourceType)[targetType] = Identity;
|
||||
return (TTarget) NCtor(source, context);
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Don't know how to map {sourceGenericArg.FullName} to {targetGenericArg.FullName}, so don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Don't know how to map {sourceType.FullName} to {targetType.FullName}.");
|
||||
}
|
||||
|
||||
private TTarget MapEnumerableInternal<TTarget>(IEnumerable source, Type targetGenericArg, Func<object, MapperContext, object> ctor, Action<object, object, MapperContext> map, MapperContext context)
|
||||
{
|
||||
var targetList = (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(targetGenericArg));
|
||||
|
||||
foreach (var sourceItem in source)
|
||||
{
|
||||
var targetItem = ctor(sourceItem, context);
|
||||
map(sourceItem, targetItem, context);
|
||||
targetList.Add(targetItem);
|
||||
}
|
||||
|
||||
object target = targetList;
|
||||
|
||||
if (typeof(TTarget).IsArray)
|
||||
{
|
||||
var elementType = typeof(TTarget).GetElementType();
|
||||
if (elementType == null) throw new Exception("panic");
|
||||
var targetArray = Array.CreateInstance(elementType, targetList.Count);
|
||||
targetList.CopyTo(targetArray, 0);
|
||||
target = targetArray;
|
||||
}
|
||||
|
||||
return (TTarget) target;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to an existing target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target)
|
||||
=> Map(source, target, new MapperContext(this));
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to an existing target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target, Action<MapperContext> f)
|
||||
{
|
||||
var context = new MapperContext(this);
|
||||
f(context);
|
||||
return Map(source, target, context);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps a source object to an existing target object.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource">The source type.</typeparam>
|
||||
/// <typeparam name="TTarget">The target type.</typeparam>
|
||||
/// <param name="source">The source object.</param>
|
||||
/// <param name="target">The target object.</param>
|
||||
/// <param name="context">A mapper context.</param>
|
||||
/// <returns>The target object.</returns>
|
||||
public TTarget Map<TSource, TTarget>(TSource source, TTarget target, MapperContext context)
|
||||
{
|
||||
var sourceType = typeof(TSource);
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
var map = GetMap(sourceType, targetType);
|
||||
|
||||
// if there is a direct map, map
|
||||
if (map != null)
|
||||
{
|
||||
map(source, target, context);
|
||||
return target;
|
||||
}
|
||||
|
||||
// we cannot really map to an existing enumerable - give up
|
||||
|
||||
throw new InvalidOperationException($"Don't know how to map {typeof(TSource).FullName} to {typeof(TTarget).FullName}.");
|
||||
}
|
||||
|
||||
private Func<object, MapperContext, object> GetCtor(Type sourceType, Type targetType)
|
||||
{
|
||||
if (_ctors.TryGetValue(sourceType, out var sourceCtor) && sourceCtor.TryGetValue(targetType, out var ctor))
|
||||
return ctor;
|
||||
|
||||
ctor = null;
|
||||
foreach (var (stype, sctors) in _ctors)
|
||||
{
|
||||
if (!stype.IsAssignableFrom(sourceType)) continue;
|
||||
if (!sctors.TryGetValue(targetType, out ctor)) continue;
|
||||
|
||||
sourceCtor = sctors;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctor == null) return null;
|
||||
|
||||
_ctors[sourceType] = sourceCtor;
|
||||
return ctor;
|
||||
}
|
||||
|
||||
private Action<object, object, MapperContext> GetMap(Type sourceType, Type targetType)
|
||||
{
|
||||
if (_maps.TryGetValue(sourceType, out var sourceMap) && sourceMap.TryGetValue(targetType, out var map))
|
||||
return map;
|
||||
|
||||
map = null;
|
||||
foreach (var (stype, smap) in _maps)
|
||||
{
|
||||
if (!stype.IsAssignableFrom(sourceType)) continue;
|
||||
|
||||
// TODO: consider looking for assignable types for target too?
|
||||
if (!smap.TryGetValue(targetType, out map)) continue;
|
||||
|
||||
sourceMap = smap;
|
||||
break;
|
||||
}
|
||||
|
||||
if (map == null) return null;
|
||||
|
||||
_maps[sourceType] = sourceMap;
|
||||
return map;
|
||||
}
|
||||
|
||||
private static bool IsEnumerableOrArrayOfType(Type type)
|
||||
{
|
||||
if (type.IsArray && type.GetArrayRank() == 1) return true;
|
||||
if (type.IsGenericType && type.GenericTypeArguments.Length == 1) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Type GetEnumerableOrArrayTypeArgument(Type type)
|
||||
{
|
||||
if (type.IsArray) return type.GetElementType();
|
||||
if (type.IsGenericType) return type.GenericTypeArguments[0];
|
||||
throw new Exception("panic");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps an enumerable of source objects to a new list of target objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSourceElement">The type of the source objects.</typeparam>
|
||||
/// <typeparam name="TTargetElement">The type of the target objects.</typeparam>
|
||||
/// <param name="source">The source objects.</param>
|
||||
/// <returns>A list containing the target objects.</returns>
|
||||
public List<TTargetElement> MapEnumerable<TSourceElement, TTargetElement>(IEnumerable<TSourceElement> source)
|
||||
{
|
||||
return source.Select(Map<TSourceElement, TTargetElement>).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps an enumerable of source objects to a new list of target objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSourceElement">The type of the source objects.</typeparam>
|
||||
/// <typeparam name="TTargetElement">The type of the target objects.</typeparam>
|
||||
/// <param name="source">The source objects.</param>
|
||||
/// <param name="f">A mapper context preparation method.</param>
|
||||
/// <returns>A list containing the target objects.</returns>
|
||||
public List<TTargetElement> MapEnumerable<TSourceElement, TTargetElement>(IEnumerable<TSourceElement> source, Action<MapperContext> f)
|
||||
{
|
||||
var context = new MapperContext(this);
|
||||
f(context);
|
||||
return source.Select(x => Map<TSourceElement, TTargetElement>(x, context)).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Maps an enumerable of source objects to a new list of target objects.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSourceElement">The type of the source objects.</typeparam>
|
||||
/// <typeparam name="TTargetElement">The type of the target objects.</typeparam>
|
||||
/// <param name="source">The source objects.</param>
|
||||
/// <param name="context">A mapper context.</param>
|
||||
/// <returns>A list containing the target objects.</returns>
|
||||
public List<TTargetElement> MapEnumerable<TSourceElement, TTargetElement>(IEnumerable<TSourceElement> source, MapperContext context)
|
||||
{
|
||||
return source.Select(x => Map<TSourceElement, TTargetElement>(x, context)).ToList();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -83,17 +83,25 @@ namespace Umbraco.Core.Migrations.Expressions.Create
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey()
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey() => PrimaryKey(true);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey(bool clustered)
|
||||
{
|
||||
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey);
|
||||
expression.Constraint.IsPrimaryKeyClustered = clustered;
|
||||
return new CreateConstraintBuilder(expression);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey(string primaryKeyName)
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey(string primaryKeyName) => PrimaryKey(primaryKeyName, true);
|
||||
|
||||
/// <inheritdoc />
|
||||
public ICreateConstraintOnTableBuilder PrimaryKey(string primaryKeyName, bool clustered)
|
||||
{
|
||||
var expression = new CreateConstraintExpression(_context, ConstraintType.PrimaryKey);
|
||||
expression.Constraint.ConstraintName = primaryKeyName;
|
||||
expression.Constraint.IsPrimaryKeyClustered = clustered;
|
||||
return new CreateConstraintBuilder(expression);
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Core.Migrations.Expressions.Create.Expressions
|
||||
var constraintType = (Constraint.IsPrimaryKeyConstraint) ? "PRIMARY KEY" : "UNIQUE";
|
||||
|
||||
if (Constraint.IsPrimaryKeyConstraint && SqlSyntax.SupportsClustered())
|
||||
constraintType += " CLUSTERED";
|
||||
constraintType += Constraint.IsPrimaryKeyClustered ? " CLUSTERED" : " NONCLUSTERED";
|
||||
|
||||
if (Constraint.IsNonUniqueConstraint)
|
||||
constraintType = string.Empty;
|
||||
|
||||
@@ -68,6 +68,16 @@ namespace Umbraco.Core.Migrations.Expressions.Create
|
||||
/// </summary>
|
||||
ICreateConstraintOnTableBuilder PrimaryKey(string primaryKeyName);
|
||||
|
||||
/// <summary>
|
||||
/// Builds a Create Primary Key expression.
|
||||
/// </summary>
|
||||
ICreateConstraintOnTableBuilder PrimaryKey(bool clustered);
|
||||
|
||||
/// <summary>
|
||||
/// Builds a Create Primary Key expression.
|
||||
/// </summary>
|
||||
ICreateConstraintOnTableBuilder PrimaryKey(string primaryKeyName, bool clustered);
|
||||
|
||||
/// <summary>
|
||||
/// Builds a Create Unique Constraint expression.
|
||||
/// </summary>
|
||||
|
||||
@@ -226,6 +226,8 @@ namespace Umbraco.Core.Migrations.Install
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 32, UniqueId = 32.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLockoutDate, Name = Constants.Conventions.Member.LastLockoutDateLabel, SortOrder = 4, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 33, UniqueId = 33.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastLoginDate, Name = Constants.Conventions.Member.LastLoginDateLabel, SortOrder = 5, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 34, UniqueId = 34.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = 11, Alias = Constants.Conventions.Member.LastPasswordChangeDate, Name = Constants.Conventions.Member.LastPasswordChangeDateLabel, SortOrder = 6, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte) ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 35, UniqueId = 35.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = null, Alias = Constants.Conventions.Member.PasswordQuestion, Name = Constants.Conventions.Member.PasswordQuestionLabel, SortOrder = 7, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte)ContentVariation.Nothing });
|
||||
_database.Insert(Constants.DatabaseSchema.Tables.PropertyType, "id", false, new PropertyTypeDto { Id = 36, UniqueId = 36.ToGuid(), DataTypeId = Constants.DataTypes.LabelDateTime, ContentTypeId = 1044, PropertyTypeGroupId = null, Alias = Constants.Conventions.Member.PasswordAnswer, Name = Constants.Conventions.Member.PasswordAnswerLabel, SortOrder = 8, Mandatory = false, ValidationRegExp = null, Description = null, Variations = (byte)ContentVariation.Nothing });
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Core.Migrations.Install
|
||||
typeof (LogDto),
|
||||
typeof (MacroDto),
|
||||
typeof (MacroPropertyDto),
|
||||
typeof (MemberTypeDto),
|
||||
typeof (MemberPropertyTypeDto),
|
||||
typeof (MemberDto),
|
||||
typeof (Member2MemberGroupDto),
|
||||
typeof (PropertyTypeGroupDto),
|
||||
|
||||
@@ -5,6 +5,7 @@ using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_12_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_7_14_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_0;
|
||||
using Umbraco.Core.Migrations.Upgrade.V_8_0_1;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade
|
||||
{
|
||||
@@ -137,6 +138,8 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
|
||||
To<RenameLabelAndRichTextPropertyEditorAliases>("{E0CBE54D-A84F-4A8F-9B13-900945FD7ED9}");
|
||||
To<MergeDateAndDateTimePropertyEditor>("{78BAF571-90D0-4D28-8175-EF96316DA789}");
|
||||
To<ChangeNuCacheJsonFormat>("{80C0A0CB-0DD5-4573-B000-C4B7C313C70D}");
|
||||
|
||||
//FINAL
|
||||
|
||||
|
||||
@@ -167,7 +170,7 @@ namespace Umbraco.Core.Migrations.Upgrade
|
||||
From("{init-7.12.4}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.0}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
From("{init-7.13.1}").To("{init-7.10.0}"); // same as 7.12.0
|
||||
|
||||
|
||||
// 7.14.0 has migrations, handle it...
|
||||
// clone going from 7.10 to 1350617A (the last one before we started to merge 7.12 migrations), then
|
||||
// clone going from CF51B39B (after 7.12 migrations) to 0009109C (the last one before we started to merge 7.12 migrations),
|
||||
|
||||
@@ -13,8 +13,8 @@ namespace Umbraco.Core.Migrations.Upgrade.V_7_9_0
|
||||
{
|
||||
var columns = SqlSyntax.GetColumnsInSchema(Context.Database).ToArray();
|
||||
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberType) && x.ColumnName.InvariantEquals("isSensitive")) == false)
|
||||
AddColumn<MemberTypeDto>("isSensitive");
|
||||
if (columns.Any(x => x.TableName.InvariantEquals(Constants.DatabaseSchema.Tables.MemberPropertyType) && x.ColumnName.InvariantEquals("isSensitive")) == false)
|
||||
AddColumn<MemberPropertyTypeDto>("isSensitive");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_0_1
|
||||
{
|
||||
public class ChangeNuCacheJsonFormat : MigrationBase
|
||||
{
|
||||
public ChangeNuCacheJsonFormat(IMigrationContext context) : base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// nothing - just adding the post-migration
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Umbraco.Core.Migrations.PostMigrations;
|
||||
|
||||
namespace Umbraco.Core.Migrations.Upgrade.V_8_1_0
|
||||
{
|
||||
public class ChangeNuCacheJsonFormat : MigrationBase
|
||||
{
|
||||
public ChangeNuCacheJsonFormat(IMigrationContext context) : base(context)
|
||||
{ }
|
||||
|
||||
public override void Migrate()
|
||||
{
|
||||
// nothing - just adding the post-migration
|
||||
Context.AddPostMigration<RebuildPublishedSnapshot>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Collections;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Core.Exceptions;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -170,23 +166,23 @@ namespace Umbraco.Core.Models
|
||||
/// Sets the publishing values for names and properties.
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="culture"></param>
|
||||
/// <param name="impact"></param>
|
||||
/// <returns>A value indicating whether it was possible to publish the names and values for the specified
|
||||
/// culture(s). The method may fail if required names are not set, but it does NOT validate property data</returns>
|
||||
public static bool PublishCulture(this IContent content, string culture = "*")
|
||||
public static bool PublishCulture(this IContent content, CultureImpact impact)
|
||||
{
|
||||
culture = culture.NullOrWhiteSpaceAsNull();
|
||||
if (impact == null) throw new ArgumentNullException(nameof(impact));
|
||||
|
||||
// the variation should be supported by the content type properties
|
||||
// if the content type is invariant, only '*' and 'null' is ok
|
||||
// if the content type varies, everything is ok because some properties may be invariant
|
||||
if (!content.ContentType.SupportsPropertyVariation(culture, "*", true))
|
||||
throw new NotSupportedException($"Culture \"{culture}\" is not supported by content type \"{content.ContentType.Alias}\" with variation \"{content.ContentType.Variations}\".");
|
||||
if (!content.ContentType.SupportsPropertyVariation(impact.Culture, "*", true))
|
||||
throw new NotSupportedException($"Culture \"{impact.Culture}\" is not supported by content type \"{content.ContentType.Alias}\" with variation \"{content.ContentType.Variations}\".");
|
||||
|
||||
var alsoInvariant = false;
|
||||
if (culture == "*") // all cultures
|
||||
// set names
|
||||
if (impact.ImpactsAllCultures)
|
||||
{
|
||||
foreach (var c in content.AvailableCultures)
|
||||
foreach (var c in content.AvailableCultures) // does NOT contain the invariant culture
|
||||
{
|
||||
var name = content.GetCultureName(c);
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
@@ -194,26 +190,31 @@ namespace Umbraco.Core.Models
|
||||
content.SetPublishInfo(c, name, DateTime.Now);
|
||||
}
|
||||
}
|
||||
else if (culture == null) // invariant culture
|
||||
else if (impact.ImpactsOnlyInvariantCulture)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content.Name))
|
||||
return false;
|
||||
// PublishName set by repository - nothing to do here
|
||||
}
|
||||
else // one single culture
|
||||
else if (impact.ImpactsExplicitCulture)
|
||||
{
|
||||
var name = content.GetCultureName(culture);
|
||||
var name = content.GetCultureName(impact.Culture);
|
||||
if (string.IsNullOrWhiteSpace(name))
|
||||
return false;
|
||||
content.SetPublishInfo(culture, name, DateTime.Now);
|
||||
alsoInvariant = true; // we also want to publish invariant values
|
||||
content.SetPublishInfo(impact.Culture, name, DateTime.Now);
|
||||
}
|
||||
|
||||
// property.PublishValues only publishes what is valid, variation-wise
|
||||
// set values
|
||||
// property.PublishValues only publishes what is valid, variation-wise,
|
||||
// but accepts any culture arg: null, all, specific
|
||||
foreach (var property in content.Properties)
|
||||
{
|
||||
property.PublishValues(culture);
|
||||
if (alsoInvariant)
|
||||
// for the specified culture (null or all or specific)
|
||||
property.PublishValues(impact.Culture);
|
||||
|
||||
// maybe the specified culture did not impact the invariant culture, so PublishValues
|
||||
// above would skip it, yet it *also* impacts invariant properties
|
||||
if (impact.ImpactsAlsoInvariantProperties)
|
||||
property.PublishValues(null);
|
||||
}
|
||||
|
||||
|
||||
@@ -95,6 +95,21 @@ namespace Umbraco.Core.Models
|
||||
|
||||
protected void PropertyTypesChanged(object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
//enable this to detect duplicate property aliases. We do want this, however making this change in a
|
||||
//patch release might be a little dangerous
|
||||
|
||||
////detect if there are any duplicate aliases - this cannot be allowed
|
||||
//if (e.Action == NotifyCollectionChangedAction.Add
|
||||
// || e.Action == NotifyCollectionChangedAction.Replace)
|
||||
//{
|
||||
// var allAliases = _noGroupPropertyTypes.Concat(PropertyGroups.SelectMany(x => x.PropertyTypes)).Select(x => x.Alias);
|
||||
// if (allAliases.HasDuplicates(false))
|
||||
// {
|
||||
// var newAliases = string.Join(", ", e.NewItems.Cast<PropertyType>().Select(x => x.Alias));
|
||||
// throw new InvalidOperationException($"Other property types already exist with the aliases: {newAliases}");
|
||||
// }
|
||||
//}
|
||||
|
||||
OnPropertyChanged(nameof(PropertyTypes));
|
||||
}
|
||||
|
||||
@@ -210,9 +225,7 @@ namespace Umbraco.Core.Models
|
||||
return Variations.ValidateVariation(culture, segment, false, true, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of PropertyGroups available on this ContentType
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// <para>A PropertyGroup corresponds to a Tab in the UI</para>
|
||||
/// <para>Marked DoNotClone because we will manually deal with cloning and the event handlers</para>
|
||||
@@ -230,9 +243,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all property types, across all property groups.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
[IgnoreDataMember]
|
||||
[DoNotClone]
|
||||
public IEnumerable<PropertyType> PropertyTypes
|
||||
@@ -243,12 +254,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property types that are not in a group.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Marked DoNotClone because we will manually deal with cloning and the event handlers
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
[DoNotClone]
|
||||
public IEnumerable<PropertyType> NoGroupPropertyTypes
|
||||
{
|
||||
@@ -397,15 +403,16 @@ namespace Umbraco.Core.Models
|
||||
var group = PropertyGroups[propertyGroupName];
|
||||
if (group == null) return;
|
||||
|
||||
// re-assign the group's properties to no group
|
||||
// first remove the group
|
||||
PropertyGroups.RemoveItem(propertyGroupName);
|
||||
|
||||
// Then re-assign the group's properties to no group
|
||||
foreach (var property in group.PropertyTypes)
|
||||
{
|
||||
property.PropertyGroupId = null;
|
||||
_noGroupPropertyTypes.Add(property);
|
||||
}
|
||||
|
||||
// actually remove the group
|
||||
PropertyGroups.RemoveItem(propertyGroupName);
|
||||
OnPropertyChanged(nameof(PropertyGroups));
|
||||
}
|
||||
|
||||
|
||||
@@ -43,9 +43,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property groups for the entire composition.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<PropertyGroup> CompositionPropertyGroups
|
||||
{
|
||||
@@ -76,9 +74,7 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property types for the entire composition.
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
[IgnoreDataMember]
|
||||
public IEnumerable<PropertyType> CompositionPropertyTypes
|
||||
{
|
||||
|
||||
257
src/Umbraco.Core/Models/CultureImpact.cs
Normal file
257
src/Umbraco.Core/Models/CultureImpact.cs
Normal file
@@ -0,0 +1,257 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the impact of a culture set.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>A set of cultures can be either all cultures (including the invariant culture), or
|
||||
/// the invariant culture, or a specific culture.</para>
|
||||
/// </remarks>
|
||||
internal class CultureImpact
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility method to return the culture used for invariant property errors based on what cultures are being actively saved,
|
||||
/// the default culture and the state of the current content item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <param name="savingCultures"></param>
|
||||
/// <param name="defaultCulture"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetCultureForInvariantErrors(IContent content, string[] savingCultures, string defaultCulture)
|
||||
{
|
||||
if (content == null) throw new ArgumentNullException(nameof(content));
|
||||
if (savingCultures == null) throw new ArgumentNullException(nameof(savingCultures));
|
||||
if (savingCultures.Length == 0) throw new ArgumentException(nameof(savingCultures));
|
||||
|
||||
var cultureForInvariantErrors = savingCultures.Any(x => x.InvariantEquals(defaultCulture))
|
||||
//the default culture is being flagged for saving so use it
|
||||
? defaultCulture
|
||||
//If the content has no published version, we need to affiliate validation with the first variant being saved.
|
||||
//If the content has a published version we will not affiliate the validation with any culture (null)
|
||||
: !content.Published ? savingCultures[0] : null;
|
||||
|
||||
return cultureForInvariantErrors;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="CultureImpact"/> class.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture code.</param>
|
||||
/// <param name="isDefault">A value indicating whether the culture is the default culture.</param>
|
||||
private CultureImpact(string culture, bool isDefault = false)
|
||||
{
|
||||
if (culture != null && culture.IsNullOrWhiteSpace())
|
||||
throw new ArgumentException("Culture \"\" is not valid here.");
|
||||
|
||||
Culture = culture;
|
||||
|
||||
if ((culture == null || culture == "*") && isDefault)
|
||||
throw new ArgumentException("The invariant or 'all' culture can not be the default culture.");
|
||||
|
||||
ImpactsOnlyDefaultCulture = isDefault;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the impact of 'all' cultures (including the invariant culture).
|
||||
/// </summary>
|
||||
public static CultureImpact All { get; } = new CultureImpact("*");
|
||||
|
||||
/// <summary>
|
||||
/// Gets the impact of the invariant culture.
|
||||
/// </summary>
|
||||
public static CultureImpact Invariant { get; } = new CultureImpact(null);
|
||||
|
||||
/// <summary>
|
||||
/// Creates an impact instance representing the impact of a specific culture.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture code.</param>
|
||||
/// <param name="isDefault">A value indicating whether the culture is the default culture.</param>
|
||||
public static CultureImpact Explicit(string culture, bool isDefault)
|
||||
{
|
||||
if (culture == null)
|
||||
throw new ArgumentException("Culture <null> is not explicit.");
|
||||
if (culture.IsNullOrWhiteSpace())
|
||||
throw new ArgumentException("Culture \"\" is not explicit.");
|
||||
if (culture == "*")
|
||||
throw new ArgumentException("Culture \"*\" is not explicit.");
|
||||
|
||||
return new CultureImpact(culture, isDefault);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an impact instance representing the impact of a culture set,
|
||||
/// in the context of a content item variation.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture code.</param>
|
||||
/// <param name="isDefault">A value indicating whether the culture is the default culture.</param>
|
||||
/// <param name="content">The content item.</param>
|
||||
/// <remarks>
|
||||
/// <para>Validates that the culture is compatible with the variation.</para>
|
||||
/// </remarks>
|
||||
public static CultureImpact Create(string culture, bool isDefault, IContent content)
|
||||
{
|
||||
// throws if not successful
|
||||
TryCreate(culture, isDefault, content.ContentType.Variations, true, out var impact);
|
||||
return impact;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to create an impact instance representing the impact of a culture set,
|
||||
/// in the context of a content item variation.
|
||||
/// </summary>
|
||||
/// <param name="culture">The culture code.</param>
|
||||
/// <param name="isDefault">A value indicating whether the culture is the default culture.</param>
|
||||
/// <param name="variation">A content variation.</param>
|
||||
/// <param name="throwOnFail">A value indicating whether to throw if the impact cannot be created.</param>
|
||||
/// <param name="impact">The impact if it could be created, otherwise null.</param>
|
||||
/// <returns>A value indicating whether the impact could be created.</returns>
|
||||
/// <remarks>
|
||||
/// <para>Validates that the culture is compatible with the variation.</para>
|
||||
/// </remarks>
|
||||
internal static bool TryCreate(string culture, bool isDefault, ContentVariation variation, bool throwOnFail, out CultureImpact impact)
|
||||
{
|
||||
impact = null;
|
||||
|
||||
// if culture is invariant...
|
||||
if (culture == null)
|
||||
{
|
||||
// ... then variation must not vary by culture ...
|
||||
if (variation.VariesByCulture())
|
||||
{
|
||||
if (throwOnFail)
|
||||
throw new InvalidOperationException("The invariant culture is not compatible with a varying variation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ... and it cannot be default
|
||||
if (isDefault)
|
||||
{
|
||||
if (throwOnFail)
|
||||
throw new InvalidOperationException("The invariant culture can not be the default culture.");
|
||||
return false;
|
||||
}
|
||||
|
||||
impact = Invariant;
|
||||
return true;
|
||||
}
|
||||
|
||||
// if culture is 'all'...
|
||||
if (culture == "*")
|
||||
{
|
||||
// ... it cannot be default
|
||||
if (isDefault)
|
||||
{
|
||||
if (throwOnFail)
|
||||
throw new InvalidOperationException("The 'all' culture can not be the default culture.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// if variation does not vary by culture, then impact is invariant
|
||||
impact = variation.VariesByCulture() ? All : Invariant;
|
||||
return true;
|
||||
}
|
||||
|
||||
// neither null nor "*" - cannot be the empty string
|
||||
if (culture.IsNullOrWhiteSpace())
|
||||
{
|
||||
if (throwOnFail)
|
||||
throw new ArgumentException("Cannot be the empty string.", nameof(culture));
|
||||
return false;
|
||||
}
|
||||
|
||||
// if culture is specific, then variation must vary
|
||||
if (!variation.VariesByCulture())
|
||||
{
|
||||
if (throwOnFail)
|
||||
throw new InvalidOperationException($"The variant culture {culture} is not compatible with an invariant variation.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// return specific impact
|
||||
impact = new CultureImpact(culture, isDefault);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the culture code.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>Can be null (invariant) or * (all cultures) or a specific culture code.</para>
|
||||
/// </remarks>
|
||||
public string Culture { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this impact impacts all cultures, including,
|
||||
/// indirectly, the invariant culture.
|
||||
/// </summary>
|
||||
public bool ImpactsAllCultures => Culture == "*";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this impact impacts only the invariant culture,
|
||||
/// directly, not because all cultures are impacted.
|
||||
/// </summary>
|
||||
public bool ImpactsOnlyInvariantCulture => Culture == null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this impact impacts an implicit culture.
|
||||
/// </summary>
|
||||
/// <remarks>And then it does not impact the invariant culture. The impacted
|
||||
/// explicit culture could be the default culture.</remarks>
|
||||
public bool ImpactsExplicitCulture => Culture != null && Culture != "*";
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this impact impacts the default culture, directly,
|
||||
/// not because all cultures are impacted.
|
||||
/// </summary>
|
||||
public bool ImpactsOnlyDefaultCulture {get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this impact impacts the invariant properties, either
|
||||
/// directly, or because all cultures are impacted, or because the default culture is impacted.
|
||||
/// </summary>
|
||||
public bool ImpactsInvariantProperties => Culture == null || Culture == "*" || ImpactsOnlyDefaultCulture;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this also impact impacts the invariant properties,
|
||||
/// even though it does not impact the invariant culture, neither directly (ImpactsInvariantCulture)
|
||||
/// nor indirectly (ImpactsAllCultures).
|
||||
/// </summary>
|
||||
public bool ImpactsAlsoInvariantProperties => !ImpactsOnlyInvariantCulture &&
|
||||
!ImpactsAllCultures &&
|
||||
ImpactsOnlyDefaultCulture;
|
||||
|
||||
public Behavior CultureBehavior
|
||||
{
|
||||
get
|
||||
{
|
||||
//null can only be invariant
|
||||
if (Culture == null) return Behavior.InvariantCulture | Behavior.InvariantProperties;
|
||||
|
||||
// * is All which means its also invariant properties since this will include the default language
|
||||
if (Culture == "*") return (Behavior.AllCultures | Behavior.InvariantProperties);
|
||||
|
||||
//else it's explicit
|
||||
var result = Behavior.ExplicitCulture;
|
||||
|
||||
//if the explicit culture is the default, then the behavior is also InvariantProperties
|
||||
if (ImpactsOnlyDefaultCulture)
|
||||
result |= Behavior.InvariantProperties;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Flags]
|
||||
public enum Behavior : byte
|
||||
{
|
||||
AllCultures = 1,
|
||||
InvariantCulture = 2,
|
||||
ExplicitCulture = 4,
|
||||
InvariantProperties = 8
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Models
|
||||
/// * when the setter performs additional required logic other than just setting the underlying field
|
||||
///
|
||||
/// </remarks>
|
||||
internal class DoNotCloneAttribute : Attribute
|
||||
public class DoNotCloneAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -96,17 +96,17 @@ namespace Umbraco.Core.Models
|
||||
IEnumerable<ContentTypeSort> AllowedContentTypes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a collection of Property Groups
|
||||
/// Gets or sets the local property groups.
|
||||
/// </summary>
|
||||
PropertyGroupCollection PropertyGroups { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets all property types, across all property groups.
|
||||
/// Gets all local property types belonging to a group, across all local property groups.
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> PropertyTypes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the property types that are not in a group.
|
||||
/// Gets or sets the local property types that do not belong to a group.
|
||||
/// </summary>
|
||||
IEnumerable<PropertyType> NoGroupPropertyTypes { get; set; }
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Core.Models.Identity
|
||||
if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(username));
|
||||
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(culture));
|
||||
|
||||
var user = new BackOfficeIdentityUser();
|
||||
var user = new BackOfficeIdentityUser(Array.Empty<IReadOnlyUserGroup>());
|
||||
user.DisableChangeTracking();
|
||||
user._userName = username;
|
||||
user._email = email;
|
||||
@@ -54,16 +54,19 @@ namespace Umbraco.Core.Models.Identity
|
||||
return user;
|
||||
}
|
||||
|
||||
private BackOfficeIdentityUser()
|
||||
private BackOfficeIdentityUser(IReadOnlyUserGroup[] groups)
|
||||
{
|
||||
_startMediaIds = new int[] { };
|
||||
_startContentIds = new int[] { };
|
||||
_groups = new IReadOnlyUserGroup[] { };
|
||||
_allowedSections = new string[] { };
|
||||
_startMediaIds = Array.Empty<int>();
|
||||
_startContentIds = Array.Empty<int>();
|
||||
_allowedSections = Array.Empty<string>();
|
||||
_culture = Current.Configs.Global().DefaultUILanguage; // TODO: inject
|
||||
_groups = new IReadOnlyUserGroup[0];
|
||||
|
||||
// must initialize before setting groups
|
||||
_roles = new ObservableCollection<IdentityUserRole<string>>();
|
||||
_roles.CollectionChanged += _roles_CollectionChanged;
|
||||
|
||||
// use the property setters - they do more than just setting a field
|
||||
Groups = groups;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,19 +75,10 @@ namespace Umbraco.Core.Models.Identity
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="groups"></param>
|
||||
public BackOfficeIdentityUser(int userId, IEnumerable<IReadOnlyUserGroup> groups)
|
||||
: this(groups.ToArray())
|
||||
{
|
||||
_startMediaIds = new int[] { };
|
||||
_startContentIds = new int[] { };
|
||||
_groups = new IReadOnlyUserGroup[] { };
|
||||
_allowedSections = new string[] { };
|
||||
_culture = Current.Configs.Global().DefaultUILanguage; // TODO: inject
|
||||
_groups = groups.ToArray();
|
||||
_roles = new ObservableCollection<IdentityUserRole<string>>(_groups.Select(x => new IdentityUserRole<string>
|
||||
{
|
||||
RoleId = x.Alias,
|
||||
UserId = userId.ToString()
|
||||
}));
|
||||
_roles.CollectionChanged += _roles_CollectionChanged;
|
||||
// use the property setters - they do more than just setting a field
|
||||
Id = userId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -226,6 +220,8 @@ namespace Umbraco.Core.Models.Identity
|
||||
//so they recalculate
|
||||
_allowedSections = null;
|
||||
|
||||
_groups = value;
|
||||
|
||||
//now clear all roles and re-add them
|
||||
_roles.CollectionChanged -= _roles_CollectionChanged;
|
||||
_roles.Clear();
|
||||
|
||||
80
src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs
Normal file
80
src/Umbraco.Core/Models/Identity/IdentityMapDefinition.cs
Normal file
@@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Mapping;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models.Identity
|
||||
{
|
||||
public class IdentityMapDefinition : IMapDefinition
|
||||
{
|
||||
private readonly ILocalizedTextService _textService;
|
||||
private readonly IEntityService _entityService;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
|
||||
public IdentityMapDefinition(ILocalizedTextService textService, IEntityService entityService, IGlobalSettings globalSettings)
|
||||
{
|
||||
_textService = textService;
|
||||
_entityService = entityService;
|
||||
_globalSettings = globalSettings;
|
||||
}
|
||||
|
||||
public void DefineMaps(UmbracoMapper mapper)
|
||||
{
|
||||
mapper.Define<IUser, BackOfficeIdentityUser>(
|
||||
(source, context) =>
|
||||
{
|
||||
var target = new BackOfficeIdentityUser(source.Id, source.Groups);
|
||||
target.DisableChangeTracking();
|
||||
return target;
|
||||
},
|
||||
(source, target, context) =>
|
||||
{
|
||||
Map(source, target);
|
||||
target.ResetDirtyProperties(true);
|
||||
target.EnableChangeTracking();
|
||||
});
|
||||
}
|
||||
|
||||
// Umbraco.Code.MapAll -Id -Groups -LockoutEnabled -PhoneNumber -PhoneNumberConfirmed -TwoFactorEnabled
|
||||
private void Map(IUser source, BackOfficeIdentityUser target)
|
||||
{
|
||||
// well, the ctor has been fixed
|
||||
/*
|
||||
// these two are already set in ctor but BackOfficeIdentityUser ctor is CompletelyBroken
|
||||
target.Id = source.Id;
|
||||
target.Groups = source.Groups.ToArray();
|
||||
*/
|
||||
|
||||
target.CalculatedMediaStartNodeIds = source.CalculateMediaStartNodeIds(_entityService);
|
||||
target.CalculatedContentStartNodeIds = source.CalculateContentStartNodeIds(_entityService);
|
||||
target.Email = source.Email;
|
||||
target.UserName = source.Username;
|
||||
target.LastPasswordChangeDateUtc = source.LastPasswordChangeDate.ToUniversalTime();
|
||||
target.LastLoginDateUtc = source.LastLoginDate.ToUniversalTime();
|
||||
target.EmailConfirmed = source.EmailConfirmedDate.HasValue;
|
||||
target.Name = source.Name;
|
||||
target.AccessFailedCount = source.FailedPasswordAttempts;
|
||||
target.PasswordHash = GetPasswordHash(source.RawPasswordValue);
|
||||
target.StartContentIds = source.StartContentIds;
|
||||
target.StartMediaIds = source.StartMediaIds;
|
||||
target.Culture = source.GetUserCulture(_textService, _globalSettings).ToString(); // project CultureInfo to string
|
||||
target.IsApproved = source.IsApproved;
|
||||
target.SecurityStamp = source.SecurityStamp;
|
||||
target.LockoutEndDateUtc = source.IsLockedOut ? DateTime.MaxValue.ToUniversalTime() : (DateTime?) null;
|
||||
|
||||
// this was in AutoMapper but does not have a setter anyways
|
||||
//target.AllowedSections = source.AllowedSections.ToArray(),
|
||||
|
||||
// these were marked as ignored for AutoMapper but don't have a setter anyways
|
||||
//target.Logins =;
|
||||
//target.Claims =;
|
||||
//target.Roles =;
|
||||
}
|
||||
|
||||
private static string GetPasswordHash(string storedPass)
|
||||
{
|
||||
return storedPass.StartsWith(Constants.Security.EmptyPasswordPrefix) ? null : storedPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using AutoMapper;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Security;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Core.Models.Identity
|
||||
{
|
||||
public class IdentityMapperProfile : Profile
|
||||
{
|
||||
public IdentityMapperProfile(ILocalizedTextService textService, IEntityService entityService, IGlobalSettings globalSettings)
|
||||
{
|
||||
CreateMap<IUser, BackOfficeIdentityUser>()
|
||||
.BeforeMap((src, dest) =>
|
||||
{
|
||||
dest.DisableChangeTracking();
|
||||
})
|
||||
.ConstructUsing(src => new BackOfficeIdentityUser(src.Id, src.Groups))
|
||||
.ForMember(dest => dest.LastLoginDateUtc, opt => opt.MapFrom(src => src.LastLoginDate.ToUniversalTime()))
|
||||
.ForMember(user => user.LastPasswordChangeDateUtc, expression => expression.MapFrom(user => user.LastPasswordChangeDate.ToUniversalTime()))
|
||||
.ForMember(dest => dest.Email, opt => opt.MapFrom(src => src.Email))
|
||||
.ForMember(dest => dest.EmailConfirmed, opt => opt.MapFrom(src => src.EmailConfirmedDate.HasValue))
|
||||
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.Id))
|
||||
.ForMember(dest => dest.LockoutEndDateUtc, opt => opt.MapFrom(src => src.IsLockedOut ? DateTime.MaxValue.ToUniversalTime() : (DateTime?) null))
|
||||
.ForMember(dest => dest.IsApproved, opt => opt.MapFrom(src => src.IsApproved))
|
||||
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.Username))
|
||||
.ForMember(dest => dest.PasswordHash, opt => opt.MapFrom(user => GetPasswordHash(user.RawPasswordValue)))
|
||||
.ForMember(dest => dest.Culture, opt => opt.MapFrom(src => src.GetUserCulture(textService, globalSettings)))
|
||||
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.Name))
|
||||
.ForMember(dest => dest.StartMediaIds, opt => opt.MapFrom(src => src.StartMediaIds))
|
||||
.ForMember(dest => dest.StartContentIds, opt => opt.MapFrom(src => src.StartContentIds))
|
||||
.ForMember(dest => dest.AccessFailedCount, opt => opt.MapFrom(src => src.FailedPasswordAttempts))
|
||||
.ForMember(dest => dest.CalculatedContentStartNodeIds, opt => opt.MapFrom(src => src.CalculateContentStartNodeIds(entityService)))
|
||||
.ForMember(dest => dest.CalculatedMediaStartNodeIds, opt => opt.MapFrom(src => src.CalculateMediaStartNodeIds(entityService)))
|
||||
.ForMember(dest => dest.AllowedSections, opt => opt.MapFrom(src => src.AllowedSections.ToArray()))
|
||||
.ForMember(dest => dest.LockoutEnabled, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Logins, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.EmailConfirmed, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.PhoneNumber, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.PhoneNumberConfirmed, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.TwoFactorEnabled, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Roles, opt => opt.Ignore())
|
||||
.ForMember(dest => dest.Claims, opt => opt.Ignore())
|
||||
.AfterMap((src, dest) =>
|
||||
{
|
||||
dest.ResetDirtyProperties(true);
|
||||
dest.EnableChangeTracking();
|
||||
});
|
||||
}
|
||||
|
||||
private static string GetPasswordHash(string storedPass)
|
||||
{
|
||||
return storedPass.StartsWith(Constants.Security.EmptyPasswordPrefix) ? null : storedPass;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Umbraco.Core.Models
|
||||
public class PropertyCollection : KeyedCollection<string, Property>, INotifyCollectionChanged, IDeepCloneable
|
||||
{
|
||||
private readonly object _addLocker = new object();
|
||||
internal Action OnAdd;
|
||||
|
||||
internal Func<Property, bool> AdditionValidator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -49,10 +49,12 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
internal void Reset(IEnumerable<Property> properties)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var property in properties)
|
||||
Add(property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,8 +62,9 @@ namespace Umbraco.Core.Models
|
||||
/// </summary>
|
||||
protected override void SetItem(int index, Property property)
|
||||
{
|
||||
var oldItem = index >= 0 ? this[index] : property;
|
||||
base.SetItem(index, property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property, index));
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, property, oldItem));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -120,10 +123,8 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem with Add
|
||||
base.Add(property);
|
||||
|
||||
OnAdd?.Invoke();
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, property));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
|
||||
|
||||
// TODO: this doesn't seem to be used anywhere
|
||||
internal Action OnAdd;
|
||||
|
||||
internal PropertyGroupCollection()
|
||||
{ }
|
||||
|
||||
@@ -37,16 +34,19 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks></remarks>
|
||||
internal void Reset(IEnumerable<PropertyGroup> groups)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var group in groups)
|
||||
Add(group);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, PropertyGroup item)
|
||||
{
|
||||
var oldItem = index >= 0 ? this[index] : item;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem));
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
@@ -84,6 +84,7 @@ namespace Umbraco.Core.Models
|
||||
if (keyExists)
|
||||
throw new Exception($"Naming conflict: Changing the name of PropertyGroup '{item.Name}' would result in duplicates");
|
||||
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(item.Id), item);
|
||||
return;
|
||||
}
|
||||
@@ -96,16 +97,14 @@ namespace Umbraco.Core.Models
|
||||
var exists = Contains(key);
|
||||
if (exists)
|
||||
{
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(key), item);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem
|
||||
base.Add(item);
|
||||
OnAdd?.Invoke();
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -19,9 +19,6 @@ namespace Umbraco.Core.Models
|
||||
[IgnoreDataMember]
|
||||
private readonly ReaderWriterLockSlim _addLocker = new ReaderWriterLockSlim();
|
||||
|
||||
// TODO: This doesn't seem to be used
|
||||
[IgnoreDataMember]
|
||||
internal Action OnAdd;
|
||||
|
||||
internal PropertyTypeCollection(bool supportsPublishing)
|
||||
{
|
||||
@@ -43,36 +40,44 @@ namespace Umbraco.Core.Models
|
||||
/// <remarks></remarks>
|
||||
internal void Reset(IEnumerable<PropertyType> properties)
|
||||
{
|
||||
//collection events will be raised in each of these calls
|
||||
Clear();
|
||||
|
||||
//collection events will be raised in each of these calls
|
||||
foreach (var property in properties)
|
||||
Add(property);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
Add(property);
|
||||
}
|
||||
|
||||
protected override void SetItem(int index, PropertyType item)
|
||||
{
|
||||
item.SupportsPublishing = SupportsPublishing;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item, index));
|
||||
var oldItem = index >= 0 ? this[index] : item;
|
||||
base.SetItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, item, oldItem));
|
||||
item.PropertyChanged += Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void RemoveItem(int index)
|
||||
{
|
||||
var removed = this[index];
|
||||
base.RemoveItem(index);
|
||||
removed.PropertyChanged -= Item_PropertyChanged;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, removed));
|
||||
}
|
||||
|
||||
protected override void InsertItem(int index, PropertyType item)
|
||||
{
|
||||
item.SupportsPublishing = SupportsPublishing;
|
||||
base.InsertItem(index, item);
|
||||
base.InsertItem(index, item);
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
item.PropertyChanged += Item_PropertyChanged;
|
||||
}
|
||||
|
||||
protected override void ClearItems()
|
||||
{
|
||||
base.ClearItems();
|
||||
foreach (var item in this)
|
||||
item.PropertyChanged -= Item_PropertyChanged;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
|
||||
}
|
||||
|
||||
@@ -91,6 +96,7 @@ namespace Umbraco.Core.Models
|
||||
var exists = Contains(key);
|
||||
if (exists)
|
||||
{
|
||||
//collection events will be raised in SetItem
|
||||
SetItem(IndexOfKey(key), item);
|
||||
return;
|
||||
}
|
||||
@@ -103,10 +109,8 @@ namespace Umbraco.Core.Models
|
||||
item.SortOrder = this.Max(x => x.SortOrder) + 1;
|
||||
}
|
||||
|
||||
//collection events will be raised in InsertItem
|
||||
base.Add(item);
|
||||
OnAdd?.Invoke();
|
||||
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, item));
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -115,6 +119,17 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when a property changes on a PropertyType that exists in this collection
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void Item_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
|
||||
{
|
||||
var propType = (PropertyType)sender;
|
||||
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, propType, propType));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this collection contains a <see cref="Property"/> whose alias matches the specified PropertyType.
|
||||
/// </summary>
|
||||
|
||||
@@ -11,14 +11,14 @@ namespace Umbraco.Core.Models.PublishedContent
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PublishedCultureInfo"/> class.
|
||||
/// </summary>
|
||||
public PublishedCultureInfo(string culture, string name, DateTime date)
|
||||
public PublishedCultureInfo(string culture, string name, string urlSegment, DateTime date)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(culture)) throw new ArgumentNullOrEmptyException(nameof(culture));
|
||||
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentNullOrEmptyException(nameof(name));
|
||||
|
||||
Culture = culture;
|
||||
Name = name;
|
||||
UrlSegment = name.ToUrlSegment(culture);
|
||||
UrlSegment = urlSegment;
|
||||
Date = date;
|
||||
}
|
||||
|
||||
|
||||
@@ -151,22 +151,22 @@ namespace Umbraco.Core.Models
|
||||
|
||||
internal static bool HasContentRootAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.Root.ToInvariantString(), user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasContentBinAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinContent.ToInvariantString(), user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinContentString, user.CalculateContentStartNodeIds(entityService), Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.Root.ToInvariantString(), user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RootString, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool HasMediaBinAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinMedia.ToInvariantString(), user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
|
||||
return ContentPermissionsHelper.HasPathAccess(Constants.System.RecycleBinMediaString, user.CalculateMediaStartNodeIds(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool HasPathAccess(this IUser user, IContent content, IEntityService entityService)
|
||||
@@ -327,7 +327,7 @@ namespace Umbraco.Core.Models
|
||||
? entityService.GetAllPaths(objectType, asn).ToDictionary(x => x.Id, x => x.Path)
|
||||
: new Dictionary<int, string>();
|
||||
|
||||
paths[Constants.System.Root] = Constants.System.Root.ToString(); // entityService does not get that one
|
||||
paths[Constants.System.Root] = Constants.System.RootString; // entityService does not get that one
|
||||
|
||||
var binPath = GetBinPath(objectType);
|
||||
|
||||
|
||||
@@ -57,7 +57,7 @@ namespace Umbraco.Core
|
||||
public const string MacroProperty = /*TableNamePrefix*/ "cms" + "MacroProperty";
|
||||
|
||||
public const string Member = /*TableNamePrefix*/ "cms" + "Member";
|
||||
public const string MemberType = /*TableNamePrefix*/ "cms" + "MemberType";
|
||||
public const string MemberPropertyType = /*TableNamePrefix*/ "cms" + "MemberType";
|
||||
public const string Member2MemberGroup = /*TableNamePrefix*/ "cms" + "Member2MemberGroup";
|
||||
|
||||
public const string Access = TableNamePrefix + "Access";
|
||||
@@ -69,7 +69,7 @@ namespace Umbraco.Core
|
||||
|
||||
public const string Tag = /*TableNamePrefix*/ "cms" + "Tags";
|
||||
public const string TagRelationship = /*TableNamePrefix*/ "cms" + "TagRelationship";
|
||||
|
||||
|
||||
public const string KeyValue = TableNamePrefix + "KeyValue";
|
||||
|
||||
public const string AuditEntry = TableNamePrefix + "Audit";
|
||||
|
||||
@@ -18,5 +18,6 @@ namespace Umbraco.Core.Persistence.DatabaseModelDefinitions
|
||||
public string ConstraintName { get; set; }
|
||||
public string TableName { get; set; }
|
||||
public ICollection<string> Columns = new HashSet<string>();
|
||||
public bool IsPrimaryKeyClustered { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
public byte Variations { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne, ColumnName = "NodeId")]
|
||||
public NodeDto NodeDto { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Umbraco.Core.Persistence.Dtos
|
||||
public string Configuration { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.OneToOne, ColumnName = "DataTypeId")]
|
||||
[Reference(ReferenceType.OneToOne, ColumnName = "NodeId")]
|
||||
public NodeDto NodeDto { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,10 @@ using Umbraco.Core.Persistence.DatabaseAnnotations;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Dtos
|
||||
{
|
||||
[TableName(Constants.DatabaseSchema.Tables.MemberType)]
|
||||
[TableName(Constants.DatabaseSchema.Tables.MemberPropertyType)]
|
||||
[PrimaryKey("pk")]
|
||||
[ExplicitColumns]
|
||||
internal class MemberTypeDto
|
||||
internal class MemberPropertyTypeDto
|
||||
{
|
||||
[Column("pk")]
|
||||
[PrimaryKeyColumn]
|
||||
@@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using NPoco;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Dtos
|
||||
{
|
||||
[TableName(Constants.DatabaseSchema.Tables.Node)]
|
||||
[PrimaryKey("id")]
|
||||
[ExplicitColumns]
|
||||
internal class MemberTypeReadOnlyDto
|
||||
{
|
||||
/* from umbracoNode */
|
||||
[Column("id")]
|
||||
public int NodeId { get; set; }
|
||||
|
||||
[Column("trashed")]
|
||||
public bool Trashed { get; set; }
|
||||
|
||||
[Column("parentID")]
|
||||
public int ParentId { get; set; }
|
||||
|
||||
[Column("nodeUser")]
|
||||
public int? UserId { get; set; }
|
||||
|
||||
[Column("level")]
|
||||
public short Level { get; set; }
|
||||
|
||||
[Column("path")]
|
||||
public string Path { get; set; }
|
||||
|
||||
[Column("sortOrder")]
|
||||
public int SortOrder { get; set; }
|
||||
|
||||
[Column("uniqueID")]
|
||||
public Guid? UniqueId { get; set; }
|
||||
|
||||
[Column("text")]
|
||||
public string Text { get; set; }
|
||||
|
||||
[Column("nodeObjectType")]
|
||||
public Guid? NodeObjectType { get; set; }
|
||||
|
||||
[Column("createDate")]
|
||||
public DateTime CreateDate { get; set; }
|
||||
|
||||
/* cmsContentType */
|
||||
[Column("pk")]
|
||||
public int PrimaryKey { get; set; }
|
||||
|
||||
[Column("alias")]
|
||||
public string Alias { get; set; }
|
||||
|
||||
[Column("icon")]
|
||||
public string Icon { get; set; }
|
||||
|
||||
[Column("thumbnail")]
|
||||
public string Thumbnail { get; set; }
|
||||
|
||||
[Column("description")]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Column("isContainer")]
|
||||
public bool IsContainer { get; set; }
|
||||
|
||||
[Column("allowAtRoot")]
|
||||
public bool AllowAtRoot { get; set; }
|
||||
|
||||
/* PropertyTypes */
|
||||
// TODO: Add PropertyTypeDto (+MemberTypeDto and DataTypeDto as one) ReadOnly list
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeId")]
|
||||
public List<PropertyTypeReadOnlyDto> PropertyTypes { get; set; }
|
||||
|
||||
/* PropertyTypeGroups */
|
||||
// TODO: Add PropertyTypeGroupDto ReadOnly list
|
||||
[ResultColumn]
|
||||
[Reference(ReferenceType.Many, ReferenceMemberName = "ContentTypeNodeId")]
|
||||
public List<PropertyTypeGroupReadOnlyDto> PropertyTypeGroups { get; set; }
|
||||
}
|
||||
}
|
||||
18
src/Umbraco.Core/Persistence/Dtos/PropertyTypeCommonDto.cs
Normal file
18
src/Umbraco.Core/Persistence/Dtos/PropertyTypeCommonDto.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using NPoco;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Dtos
|
||||
{
|
||||
// this is PropertyTypeDto + the special property type fields for members
|
||||
// it is used for querying everything needed for a property type, at once
|
||||
internal class PropertyTypeCommonDto : PropertyTypeDto
|
||||
{
|
||||
[Column("memberCanEdit")]
|
||||
public bool CanEdit { get; set; }
|
||||
|
||||
[Column("viewOnProfile")]
|
||||
public bool ViewOnProfile { get; set; }
|
||||
|
||||
[Column("isSensitive")]
|
||||
public bool IsSensitive { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -67,16 +67,28 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
public static IMemberType BuildMemberTypeEntity(ContentTypeDto dto)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var contentType = new MemberType(dto.NodeDto.ParentId);
|
||||
try
|
||||
{
|
||||
contentType.DisableChangeTracking();
|
||||
BuildCommonEntity(contentType, dto, false);
|
||||
contentType.ResetDirtyProperties(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
contentType.EnableChangeTracking();
|
||||
}
|
||||
|
||||
return contentType;
|
||||
}
|
||||
|
||||
public static IEnumerable<MemberTypeDto> BuildMemberTypeDtos(IMemberType entity)
|
||||
public static IEnumerable<MemberPropertyTypeDto> BuildMemberPropertyTypeDtos(IMemberType entity)
|
||||
{
|
||||
var memberType = entity as MemberType;
|
||||
if (memberType == null || memberType.PropertyTypes.Any() == false)
|
||||
return Enumerable.Empty<MemberTypeDto>();
|
||||
return Enumerable.Empty<MemberPropertyTypeDto>();
|
||||
|
||||
var dtos = memberType.PropertyTypes.Select(x => new MemberTypeDto
|
||||
var dtos = memberType.PropertyTypes.Select(x => new MemberPropertyTypeDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
PropertyTypeId = x.Id,
|
||||
@@ -91,7 +103,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
#region Common
|
||||
|
||||
private static void BuildCommonEntity(ContentTypeBase entity, ContentTypeDto dto)
|
||||
private static void BuildCommonEntity(ContentTypeBase entity, ContentTypeDto dto, bool setVariations = true)
|
||||
{
|
||||
entity.Id = dto.NodeDto.NodeId;
|
||||
entity.Key = dto.NodeDto.UniqueId;
|
||||
@@ -102,6 +114,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
entity.SortOrder = dto.NodeDto.SortOrder;
|
||||
entity.Description = dto.Description;
|
||||
entity.CreateDate = dto.NodeDto.CreateDate;
|
||||
entity.UpdateDate = dto.NodeDto.CreateDate;
|
||||
entity.Path = dto.NodeDto.Path;
|
||||
entity.Level = dto.NodeDto.Level;
|
||||
entity.CreatorId = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;
|
||||
@@ -109,7 +122,9 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
entity.IsContainer = dto.IsContainer;
|
||||
entity.IsElement = dto.IsElement;
|
||||
entity.Trashed = dto.NodeDto.Trashed;
|
||||
entity.Variations = (ContentVariation) dto.Variations;
|
||||
|
||||
if (setVariations)
|
||||
entity.Variations = (ContentVariation) dto.Variations;
|
||||
}
|
||||
|
||||
public static ContentTypeDto BuildContentTypeDto(IContentTypeBase entity)
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
using Umbraco.Core.Persistence.Repositories.Implement;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal static class MemberTypeReadOnlyFactory
|
||||
{
|
||||
public static IMemberType BuildEntity(MemberTypeReadOnlyDto dto, out bool needsSaving)
|
||||
{
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
needsSaving = false;
|
||||
|
||||
var memberType = new MemberType(dto.ParentId);
|
||||
|
||||
try
|
||||
{
|
||||
memberType.DisableChangeTracking();
|
||||
|
||||
memberType.Alias = dto.Alias;
|
||||
memberType.AllowedAsRoot = dto.AllowAtRoot;
|
||||
memberType.CreateDate = dto.CreateDate;
|
||||
memberType.CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0;
|
||||
memberType.Description = dto.Description;
|
||||
memberType.Icon = dto.Icon;
|
||||
memberType.Id = dto.NodeId;
|
||||
memberType.IsContainer = dto.IsContainer;
|
||||
memberType.Key = dto.UniqueId.Value;
|
||||
memberType.Level = dto.Level;
|
||||
memberType.Name = dto.Text;
|
||||
memberType.Path = dto.Path;
|
||||
memberType.SortOrder = dto.SortOrder;
|
||||
memberType.Thumbnail = dto.Thumbnail;
|
||||
memberType.Trashed = dto.Trashed;
|
||||
memberType.UpdateDate = dto.CreateDate;
|
||||
memberType.AllowedContentTypes = Enumerable.Empty<ContentTypeSort>();
|
||||
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes);
|
||||
memberType.PropertyGroups = propertyTypeGroupCollection;
|
||||
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
|
||||
//By Convention we add 9 standard PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
if (dto.PropertyTypes.Any(x => x.Alias.Equals(standardPropertyType.Key))) continue;
|
||||
|
||||
// beware!
|
||||
// means that we can return a memberType "from database" that has some property types
|
||||
// that do *not* come from the database and therefore are incomplete eg have no key,
|
||||
// no id, no dataTypeDefinitionId - ouch! - better notify caller of the situation
|
||||
needsSaving = true;
|
||||
|
||||
//Add the standard PropertyType to the current list
|
||||
propertyTypes.Add(standardPropertyType.Value);
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit", "VisibleOnProfile", "IsSensitive" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new MemberTypePropertyProfileAccess(false, false, false));
|
||||
}
|
||||
memberType.NoGroupPropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
finally
|
||||
{
|
||||
memberType.EnableChangeTracking();
|
||||
}
|
||||
}
|
||||
|
||||
private static PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
// see PropertyGroupFactory, repeating code here...
|
||||
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue))
|
||||
{
|
||||
var group = new PropertyGroup(MemberType.SupportsPublishingConst);
|
||||
|
||||
// if the group is defined on the current member type,
|
||||
// assign its identifier, else it will be zero
|
||||
if (groupDto.ContentTypeNodeId == memberType.Id)
|
||||
{
|
||||
// note: no idea why Id is nullable here, but better check
|
||||
if (groupDto.Id.HasValue == false)
|
||||
throw new Exception("GroupDto.Id has no value.");
|
||||
group.Id = groupDto.Id.Value;
|
||||
}
|
||||
|
||||
group.Key = groupDto.UniqueId;
|
||||
group.Name = groupDto.Text;
|
||||
group.SortOrder = groupDto.SortOrder;
|
||||
group.PropertyTypes = new PropertyTypeCollection(MemberType.SupportsPublishingConst);
|
||||
|
||||
//Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded
|
||||
var localGroupDto = groupDto;
|
||||
var typeDtos = dto.PropertyTypes.Where(x => x.Id.HasValue && x.Id > 0 && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value == localGroupDto.Id.Value);
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive));
|
||||
|
||||
var tempGroupDto = groupDto;
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<ValueStorageType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success,
|
||||
typeDto.Alias)
|
||||
{
|
||||
DataTypeId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id.Value,
|
||||
Name = typeDto.Name,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id.Value),
|
||||
CreateDate = memberType.CreateDate,
|
||||
UpdateDate = memberType.UpdateDate,
|
||||
Key = typeDto.UniqueId
|
||||
};
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
propertyType.ResetDirtyProperties(false);
|
||||
group.PropertyTypes.Add(propertyType);
|
||||
}
|
||||
|
||||
// reset dirty initial properties (U4-1946)
|
||||
group.ResetDirtyProperties(false);
|
||||
propertyGroups.Add(group);
|
||||
}
|
||||
|
||||
return propertyGroups;
|
||||
}
|
||||
|
||||
private static List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
//Find PropertyTypes that does not belong to a PropertyTypeGroup
|
||||
var propertyTypes = new List<PropertyType>();
|
||||
foreach (var typeDto in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit, typeDto.IsSensitive));
|
||||
|
||||
//ensures that any built-in membership properties have their correct dbtype assigned no matter
|
||||
//what the underlying data type is
|
||||
var propDbType = MemberTypeRepository.GetDbTypeForBuiltInProperty(
|
||||
typeDto.Alias,
|
||||
typeDto.DbType.EnumParse<ValueStorageType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.PropertyEditorAlias,
|
||||
propDbType.Result,
|
||||
//This flag tells the property type that it has an explicit dbtype and that it cannot be changed
|
||||
// which is what we want for the built-in properties.
|
||||
propDbType.Success,
|
||||
typeDto.Alias)
|
||||
{
|
||||
DataTypeId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id.Value,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
Name = typeDto.Name,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = null,
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate,
|
||||
Key = typeDto.UniqueId
|
||||
};
|
||||
|
||||
propertyTypes.Add(propertyType);
|
||||
}
|
||||
return propertyTypes;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -7,18 +8,18 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(PublicAccessEntry))]
|
||||
public sealed class AccessMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public AccessMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.Key, dto => dto.Id);
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.LoginNodeId, dto => dto.LoginNodeId);
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.NoAccessNodeId, dto => dto.NoAccessNodeId);
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.ProtectedNodeId, dto => dto.NodeId);
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<PublicAccessEntry, AccessDto>(src => src.UpdateDate, dto => dto.UpdateDate);
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.Key), nameof(AccessDto.Id));
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.LoginNodeId), nameof(AccessDto.LoginNodeId));
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.NoAccessNodeId), nameof(AccessDto.NoAccessNodeId));
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.ProtectedNodeId), nameof(AccessDto.NodeId));
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.CreateDate), nameof(AccessDto.CreateDate));
|
||||
DefineMap<PublicAccessEntry, AccessDto>(nameof(PublicAccessEntry.UpdateDate), nameof(AccessDto.UpdateDate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -11,21 +12,21 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(AuditEntry))]
|
||||
public sealed class AuditEntryMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public AuditEntryMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.Id, dto => dto.Id);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingUserId, dto => dto.PerformingUserId);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingDetails, dto => dto.PerformingDetails);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.PerformingIp, dto => dto.PerformingIp);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventDateUtc, dto => dto.EventDateUtc);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.AffectedUserId, dto => dto.AffectedUserId);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.AffectedDetails, dto => dto.AffectedDetails);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventType, dto => dto.EventType);
|
||||
CacheMap<AuditEntry, AuditEntryDto>(entity => entity.EventDetails, dto => dto.EventDetails);
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.Id), nameof(AuditEntryDto.Id));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.PerformingUserId), nameof(AuditEntryDto.PerformingUserId));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.PerformingDetails), nameof(AuditEntryDto.PerformingDetails));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.PerformingIp), nameof(AuditEntryDto.PerformingIp));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.EventDateUtc), nameof(AuditEntryDto.EventDateUtc));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.AffectedUserId), nameof(AuditEntryDto.AffectedUserId));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.AffectedDetails), nameof(AuditEntryDto.AffectedDetails));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.EventType), nameof(AuditEntryDto.EventType));
|
||||
DefineMap<AuditEntry, AuditEntryDto>(nameof(AuditEntry.EventDetails), nameof(AuditEntryDto.EventDetails));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,17 +9,17 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IAuditItem))]
|
||||
public sealed class AuditItemMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public AuditItemMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<AuditItem, LogDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<AuditItem, LogDto>(src => src.CreateDate, dto => dto.Datestamp);
|
||||
CacheMap<AuditItem, LogDto>(src => src.UserId, dto => dto.UserId);
|
||||
CacheMap<AuditItem, LogDto>(src => src.AuditType, dto => dto.Header);
|
||||
CacheMap<AuditItem, LogDto>(src => src.Comment, dto => dto.Comment);
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Id), nameof(LogDto.NodeId));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.CreateDate), nameof(LogDto.Datestamp));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.UserId), nameof(LogDto.UserId));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.AuditType), nameof(LogDto.Header));
|
||||
DefineMap<AuditItem, LogDto>(nameof(AuditItem.Comment), nameof(LogDto.Comment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +1,81 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using NPoco;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
public abstract class BaseMapper : IDiscoverable
|
||||
public abstract class BaseMapper
|
||||
{
|
||||
protected BaseMapper()
|
||||
// note: using a Lazy<ISqlContext> here because during installs, we are resolving the
|
||||
// mappers way before we have a configured IUmbracoDatabaseFactory, ie way before we
|
||||
// have an ISqlContext - this is some nasty temporal coupling which we might want to
|
||||
// cleanup eventually.
|
||||
|
||||
private readonly Lazy<ISqlContext> _sqlContext;
|
||||
private readonly object _definedLock = new object();
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> _maps;
|
||||
|
||||
private ISqlSyntaxProvider _sqlSyntax;
|
||||
private bool _defined;
|
||||
|
||||
protected BaseMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
{
|
||||
Build();
|
||||
_sqlContext = sqlContext;
|
||||
_maps = maps;
|
||||
}
|
||||
|
||||
internal abstract ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache { get; }
|
||||
protected abstract void DefineMaps();
|
||||
|
||||
private void Build()
|
||||
internal string Map(string propertyName)
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
protected abstract void BuildMap();
|
||||
|
||||
internal string Map(ISqlSyntaxProvider sqlSyntax, string propertyName, bool throws = false)
|
||||
{
|
||||
if (PropertyInfoCache.TryGetValue(propertyName, out var dtoTypeProperty))
|
||||
return GetColumnName(sqlSyntax, dtoTypeProperty.Type, dtoTypeProperty.PropertyInfo);
|
||||
|
||||
if (throws)
|
||||
throw new InvalidOperationException("Could not get the value with the key " + propertyName + " from the property info cache, keys available: " + string.Join(", ", PropertyInfoCache.Keys));
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
internal void CacheMap<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var property = ResolveMapping(sourceMember, destinationMember);
|
||||
PropertyInfoCache.AddOrUpdate(property.SourcePropertyName, property, (x, y) => property);
|
||||
}
|
||||
|
||||
internal DtoMapModel ResolveMapping<TSource, TDestination>(Expression<Func<TSource, object>> sourceMember, Expression<Func<TDestination, object>> destinationMember)
|
||||
{
|
||||
var source = ExpressionHelper.FindProperty(sourceMember);
|
||||
var destination = (PropertyInfo) ExpressionHelper.FindProperty(destinationMember).Item1;
|
||||
|
||||
if (destination == null)
|
||||
lock (_definedLock)
|
||||
{
|
||||
throw new InvalidOperationException("The 'destination' returned was null, cannot resolve the mapping");
|
||||
if (!_defined)
|
||||
{
|
||||
var sqlContext = _sqlContext.Value;
|
||||
if (sqlContext == null)
|
||||
throw new InvalidOperationException("Could not get an ISqlContext.");
|
||||
_sqlSyntax = sqlContext.SqlSyntax;
|
||||
|
||||
DefineMaps();
|
||||
|
||||
_defined = true;
|
||||
}
|
||||
}
|
||||
|
||||
return new DtoMapModel(typeof(TDestination), destination, source.Item1.Name);
|
||||
if (!_maps.TryGetValue(GetType(), out var mapperMaps))
|
||||
throw new InvalidOperationException($"No maps defined for mapper {GetType().FullName}.");
|
||||
if (!mapperMaps.TryGetValue(propertyName, out var mappedName))
|
||||
throw new InvalidOperationException($"No map defined by mapper {GetType().FullName} for property {propertyName}.");
|
||||
return mappedName;
|
||||
}
|
||||
|
||||
internal virtual string GetColumnName(ISqlSyntaxProvider sqlSyntax, Type dtoType, PropertyInfo dtoProperty)
|
||||
protected void DefineMap<TSource, TTarget>(string sourceName, string targetName)
|
||||
{
|
||||
var tableNameAttribute = dtoType.FirstAttribute<TableNameAttribute>();
|
||||
if (_sqlSyntax == null)
|
||||
throw new InvalidOperationException("Do not define maps outside of DefineMaps.");
|
||||
|
||||
var targetType = typeof(TTarget);
|
||||
|
||||
// TODO ensure that sourceName is a valid sourceType property (but, slow?)
|
||||
|
||||
var tableNameAttribute = targetType.FirstAttribute<TableNameAttribute>();
|
||||
if (tableNameAttribute == null) throw new InvalidOperationException($"Type {targetType.FullName} is not marked with a TableName attribute.");
|
||||
var tableName = tableNameAttribute.Value;
|
||||
|
||||
var columnAttribute = dtoProperty.FirstAttribute<ColumnAttribute>();
|
||||
var columnName = columnAttribute.Name;
|
||||
// TODO maybe get all properties once and then index them
|
||||
var targetProperty = targetType.GetProperty(targetName);
|
||||
if (targetProperty == null) throw new InvalidOperationException($"Type {targetType.FullName} does not have a property named {targetName}.");
|
||||
var columnAttribute = targetProperty.FirstAttribute<ColumnAttribute>();
|
||||
if (columnAttribute == null) throw new InvalidOperationException($"Property {targetType.FullName}.{targetName} is not marked with a Column attribute.");
|
||||
|
||||
var columnMap = sqlSyntax.GetQuotedTableName(tableName) + "." + sqlSyntax.GetQuotedColumnName(columnName);
|
||||
return columnMap;
|
||||
var columnName = columnAttribute.Name;
|
||||
var columnMap = _sqlSyntax.GetQuotedTableName(tableName) + "." + _sqlSyntax.GetQuotedColumnName(columnName);
|
||||
|
||||
var mapperMaps = _maps.GetOrAdd(GetType(), type => new ConcurrentDictionary<string, string>());
|
||||
mapperMaps[sourceName] = columnMap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -11,20 +12,20 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Consent))]
|
||||
public sealed class ConsentMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public ConsentMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Id, dto => dto.Id);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Current, dto => dto.Current);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Source, dto => dto.Source);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Context, dto => dto.Context);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Action, dto => dto.Action);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.State, dto => dto.State);
|
||||
CacheMap<Consent, ConsentDto>(entity => entity.Comment, dto => dto.Comment);
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Id), nameof(ConsentDto.Id));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Current), nameof(ConsentDto.Current));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.CreateDate), nameof(ConsentDto.CreateDate));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Source), nameof(ConsentDto.Source));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Context), nameof(ConsentDto.Context));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Action), nameof(ConsentDto.Action));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.State), nameof(ConsentDto.State));
|
||||
DefineMap<Consent, ConsentDto>(nameof(Consent.Comment), nameof(ConsentDto.Comment));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,36 +13,34 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IContent))]
|
||||
public sealed class ContentMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public ContentMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
DefineMap<Content, NodeDto>(nameof(Content.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.Key), nameof(NodeDto.UniqueId));
|
||||
|
||||
CacheMap<Content, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Content, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
DefineMap<Content, ContentVersionDto>(nameof(Content.VersionId), nameof(ContentVersionDto.Id));
|
||||
DefineMap<Content, ContentVersionDto>(nameof(Content.Name), nameof(ContentVersionDto.Text));
|
||||
|
||||
CacheMap<Content, ContentVersionDto>(src => src.VersionId, dto => dto.Id);
|
||||
CacheMap<Content, ContentVersionDto>(src => src.Name, dto => dto.Text);
|
||||
DefineMap<Content, NodeDto>(nameof(Content.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.Level), nameof(NodeDto.Level));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.Path), nameof(NodeDto.Path));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.Trashed), nameof(NodeDto.Trashed));
|
||||
|
||||
CacheMap<Content, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Content, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<Content, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<Content, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<Content, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
DefineMap<Content, NodeDto>(nameof(Content.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<Content, NodeDto>(nameof(Content.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<Content, ContentDto>(nameof(Content.ContentTypeId), nameof(ContentDto.ContentTypeId));
|
||||
|
||||
CacheMap<Content, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Content, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<Content, ContentDto>(src => src.ContentTypeId, dto => dto.ContentTypeId);
|
||||
DefineMap<Content, ContentVersionDto>(nameof(Content.UpdateDate), nameof(ContentVersionDto.VersionDate));
|
||||
DefineMap<Content, DocumentDto>(nameof(Content.Published), nameof(DocumentDto.Published));
|
||||
|
||||
CacheMap<Content, ContentVersionDto>(src => src.UpdateDate, dto => dto.VersionDate);
|
||||
CacheMap<Content, DocumentDto>(src => src.Published, dto => dto.Published);
|
||||
|
||||
//CacheMap<Content, DocumentDto>(src => src.Name, dto => dto.Alias);
|
||||
//DefineMap<Content, DocumentDto>(nameof(Content.Name), nameof(DocumentDto.Alias));
|
||||
//CacheMap<Content, DocumentDto>(src => src, dto => dto.Newest);
|
||||
//CacheMap<Content, DocumentDto>(src => src.Template, dto => dto.TemplateId);
|
||||
//DefineMap<Content, DocumentDto>(nameof(Content.Template), nameof(DocumentDto.TemplateId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,31 +13,29 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IContentType))]
|
||||
public sealed class ContentTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public ContentTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<ContentType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<ContentType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<ContentType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.AllowedAsRoot, dto => dto.AllowAtRoot);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.IsContainer, dto => dto.IsContainer);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.IsElement, dto => dto.IsElement);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Thumbnail, dto => dto.Thumbnail);
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Level), nameof(NodeDto.Level));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Path), nameof(NodeDto.Path));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Name), nameof(NodeDto.Text));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Alias), nameof(ContentTypeDto.Alias));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.AllowedAsRoot), nameof(ContentTypeDto.AllowAtRoot));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Description), nameof(ContentTypeDto.Description));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Icon), nameof(ContentTypeDto.Icon));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.IsContainer), nameof(ContentTypeDto.IsContainer));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.IsElement), nameof(ContentTypeDto.IsElement));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Thumbnail), nameof(ContentTypeDto.Thumbnail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,25 +13,24 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IDataType))]
|
||||
public sealed class DataTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public DataTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<DataType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<DataType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<DataType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<DataType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<DataType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<DataType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<DataType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<DataType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<DataType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<DataType, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<DataType, DataTypeDto>(src => src.EditorAlias, dto => dto.EditorAlias);
|
||||
CacheMap<DataType, DataTypeDto>(src => src.DatabaseType, dto => dto.DbType);
|
||||
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Level), nameof(NodeDto.Level));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Path), nameof(NodeDto.Path));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Name), nameof(NodeDto.Text));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<DataType, NodeDto>(nameof(DataType.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<DataType, DataTypeDto>(nameof(DataType.EditorAlias), nameof(DataTypeDto.EditorAlias));
|
||||
DefineMap<DataType, DataTypeDto>(nameof(DataType.DatabaseType), nameof(DataTypeDto.DbType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,16 +13,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IDictionaryItem))]
|
||||
public sealed class DictionaryMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public DictionaryMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.Id, dto => dto.PrimaryKey);
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.ItemKey, dto => dto.Key);
|
||||
CacheMap<DictionaryItem, DictionaryDto>(src => src.ParentId, dto => dto.Parent);
|
||||
DefineMap<DictionaryItem, DictionaryDto>(nameof(DictionaryItem.Id), nameof(DictionaryDto.PrimaryKey));
|
||||
DefineMap<DictionaryItem, DictionaryDto>(nameof(DictionaryItem.Key), nameof(DictionaryDto.UniqueId));
|
||||
DefineMap<DictionaryItem, DictionaryDto>(nameof(DictionaryItem.ItemKey), nameof(DictionaryDto.Key));
|
||||
DefineMap<DictionaryItem, DictionaryDto>(nameof(DictionaryItem.ParentId), nameof(DictionaryDto.Parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,16 +13,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IDictionaryTranslation))]
|
||||
public sealed class DictionaryTranslationMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public DictionaryTranslationMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Id, dto => dto.PrimaryKey);
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Language, dto => dto.LanguageId);
|
||||
CacheMap<DictionaryTranslation, LanguageTextDto>(src => src.Value, dto => dto.Value);
|
||||
DefineMap<DictionaryTranslation, LanguageTextDto>(nameof(DictionaryTranslation.Id), nameof(LanguageTextDto.PrimaryKey));
|
||||
DefineMap<DictionaryTranslation, LanguageTextDto>(nameof(DictionaryTranslation.Key), nameof(LanguageTextDto.UniqueId));
|
||||
DefineMap<DictionaryTranslation, LanguageTextDto>(nameof(DictionaryTranslation.Language), nameof(LanguageTextDto.LanguageId));
|
||||
DefineMap<DictionaryTranslation, LanguageTextDto>(nameof(DictionaryTranslation.Value), nameof(LanguageTextDto.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,16 +9,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(UmbracoDomain))]
|
||||
public sealed class DomainMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public DomainMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<UmbracoDomain, DomainDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<UmbracoDomain, DomainDto>(src => src.RootContentId, dto => dto.RootStructureId);
|
||||
CacheMap<UmbracoDomain, DomainDto>(src => src.LanguageId, dto => dto.DefaultLanguage);
|
||||
CacheMap<UmbracoDomain, DomainDto>(src => src.DomainName, dto => dto.DomainName);
|
||||
DefineMap<UmbracoDomain, DomainDto>(nameof(UmbracoDomain.Id), nameof(DomainDto.Id));
|
||||
DefineMap<UmbracoDomain, DomainDto>(nameof(UmbracoDomain.RootContentId), nameof(DomainDto.RootStructureId));
|
||||
DefineMap<UmbracoDomain, DomainDto>(nameof(UmbracoDomain.LanguageId), nameof(DomainDto.DefaultLanguage));
|
||||
DefineMap<UmbracoDomain, DomainDto>(nameof(UmbracoDomain.DomainName), nameof(DomainDto.DomainName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
internal class DtoMapModel
|
||||
{
|
||||
public DtoMapModel(Type type, PropertyInfo propertyInfo, string sourcePropertyName)
|
||||
{
|
||||
Type = type;
|
||||
PropertyInfo = propertyInfo;
|
||||
SourcePropertyName = sourcePropertyName;
|
||||
}
|
||||
|
||||
public string SourcePropertyName { get; private set; }
|
||||
public Type Type { get; private set; }
|
||||
public PropertyInfo PropertyInfo { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models.Identity;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,25 +9,17 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IdentityUserLogin))]
|
||||
public sealed class ExternalLoginMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public ExternalLoginMapper()
|
||||
public ExternalLoginMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
BuildMap();
|
||||
DefineMap<IdentityUserLogin, ExternalLoginDto>(nameof(IdentityUserLogin.Id), nameof(ExternalLoginDto.Id));
|
||||
DefineMap<IdentityUserLogin, ExternalLoginDto>(nameof(IdentityUserLogin.CreateDate), nameof(ExternalLoginDto.CreateDate));
|
||||
DefineMap<IdentityUserLogin, ExternalLoginDto>(nameof(IdentityUserLogin.LoginProvider), nameof(ExternalLoginDto.LoginProvider));
|
||||
DefineMap<IdentityUserLogin, ExternalLoginDto>(nameof(IdentityUserLogin.ProviderKey), nameof(ExternalLoginDto.ProviderKey));
|
||||
DefineMap<IdentityUserLogin, ExternalLoginDto>(nameof(IdentityUserLogin.UserId), nameof(ExternalLoginDto.UserId));
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
{
|
||||
CacheMap<IdentityUserLogin, ExternalLoginDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<IdentityUserLogin, ExternalLoginDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<IdentityUserLogin, ExternalLoginDto>(src => src.LoginProvider, dto => dto.LoginProvider);
|
||||
CacheMap<IdentityUserLogin, ExternalLoginDto>(src => src.ProviderKey, dto => dto.ProviderKey);
|
||||
CacheMap<IdentityUserLogin, ExternalLoginDto>(src => src.UserId, dto => dto.UserId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,15 +13,15 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Language))]
|
||||
public sealed class LanguageMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public LanguageMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Language, LanguageDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Language, LanguageDto>(src => src.IsoCode, dto => dto.IsoCode);
|
||||
CacheMap<Language, LanguageDto>(src => src.CultureName, dto => dto.CultureName);
|
||||
DefineMap<Language, LanguageDto>(nameof(Language.Id), nameof(LanguageDto.Id));
|
||||
DefineMap<Language, LanguageDto>(nameof(Language.IsoCode), nameof(LanguageDto.IsoCode));
|
||||
DefineMap<Language, LanguageDto>(nameof(Language.CultureName), nameof(LanguageDto.CultureName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,22 +9,22 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IMacro))]
|
||||
internal sealed class MacroMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MacroMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Macro, MacroDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Macro, MacroDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<Macro, MacroDto>(src => src.CacheByPage, dto => dto.CacheByPage);
|
||||
CacheMap<Macro, MacroDto>(src => src.CacheByMember, dto => dto.CachePersonalized);
|
||||
CacheMap<Macro, MacroDto>(src => src.MacroType, dto => dto.MacroType);
|
||||
CacheMap<Macro, MacroDto>(src => src.DontRender, dto => dto.DontRender);
|
||||
CacheMap<Macro, MacroDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<Macro, MacroDto>(src => src.CacheDuration, dto => dto.RefreshRate);
|
||||
CacheMap<Macro, MacroDto>(src => src.MacroSource, dto => dto.MacroSource);
|
||||
CacheMap<Macro, MacroDto>(src => src.UseInEditor, dto => dto.UseInEditor);
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.Id), nameof(MacroDto.Id));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.Alias), nameof(MacroDto.Alias));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.CacheByPage), nameof(MacroDto.CacheByPage));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.CacheByMember), nameof(MacroDto.CachePersonalized));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.MacroType), nameof(MacroDto.MacroType));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.DontRender), nameof(MacroDto.DontRender));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.Name), nameof(MacroDto.Name));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.CacheDuration), nameof(MacroDto.RefreshRate));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.MacroSource), nameof(MacroDto.MacroSource));
|
||||
DefineMap<Macro, MacroDto>(nameof(Macro.UseInEditor), nameof(MacroDto.UseInEditor));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
using Umbraco.Core.Composing;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
public class MapperCollectionBuilder : LazyCollectionBuilderBase<MapperCollectionBuilder, MapperCollection, BaseMapper>
|
||||
public class MapperCollectionBuilder : SetCollectionBuilderBase<MapperCollectionBuilder, MapperCollection, BaseMapper>
|
||||
{
|
||||
private readonly ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> _maps
|
||||
= new ConcurrentDictionary<Type, ConcurrentDictionary<string, string>>();
|
||||
|
||||
protected override MapperCollectionBuilder This => this;
|
||||
|
||||
public override void RegisterWith(IRegister register)
|
||||
@@ -19,6 +24,11 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
register.Register<IMapperCollection>(factory => factory.GetInstance<MapperCollection>());
|
||||
}
|
||||
|
||||
protected override BaseMapper CreateItem(IFactory factory, Type itemType)
|
||||
{
|
||||
return (BaseMapper) factory.CreateInstance(itemType, _maps);
|
||||
}
|
||||
|
||||
public MapperCollectionBuilder AddCoreMappers()
|
||||
{
|
||||
Add<AccessMapper>();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,29 +13,27 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Umbraco.Core.Models.Media))]
|
||||
public sealed class MediaMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MediaMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Key), nameof(NodeDto.UniqueId));
|
||||
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
DefineMap<Content, ContentVersionDto>(nameof(Content.VersionId), nameof(ContentVersionDto.Id));
|
||||
|
||||
CacheMap<Content, ContentVersionDto>(src => src.VersionId, dto => dto.Id);
|
||||
|
||||
CacheMap<Models.Media, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<Models.Media, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<Models.Media, ContentDto>(src => src.ContentTypeId, dto => dto.ContentTypeId);
|
||||
CacheMap<Models.Media, ContentVersionDto>(src => src.UpdateDate, dto => dto.VersionDate);
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Level), nameof(NodeDto.Level));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Path), nameof(NodeDto.Path));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Name), nameof(NodeDto.Text));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<Models.Media, NodeDto>(nameof(Models.Media.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<Models.Media, ContentDto>(nameof(Models.Media.ContentTypeId), nameof(ContentDto.ContentTypeId));
|
||||
DefineMap<Models.Media, ContentVersionDto>(nameof(Models.Media.UpdateDate), nameof(ContentVersionDto.VersionDate));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,31 +13,29 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(MediaType))]
|
||||
public sealed class MediaTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MediaTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<MediaType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<MediaType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<MediaType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<MediaType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<MediaType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<MediaType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<MediaType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<MediaType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<MediaType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<MediaType, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.AllowedAsRoot, dto => dto.AllowAtRoot);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.IsContainer, dto => dto.IsContainer);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.IsElement, dto => dto.IsElement);
|
||||
CacheMap<MediaType, ContentTypeDto>(src => src.Thumbnail, dto => dto.Thumbnail);
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Level), nameof(NodeDto.Level));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Path), nameof(NodeDto.Path));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Name), nameof(NodeDto.Text));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<MediaType, NodeDto>(nameof(MediaType.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.Alias), nameof(ContentTypeDto.Alias));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.AllowedAsRoot), nameof(ContentTypeDto.AllowAtRoot));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.Description), nameof(ContentTypeDto.Description));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.Icon), nameof(ContentTypeDto.Icon));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.IsContainer), nameof(ContentTypeDto.IsContainer));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.IsElement), nameof(ContentTypeDto.IsElement));
|
||||
DefineMap<MediaType, ContentTypeDto>(nameof(MediaType.Thumbnail), nameof(ContentTypeDto.Thumbnail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,17 +9,17 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof (MemberGroup))]
|
||||
public sealed class MemberGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MemberGroupMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<MemberGroup, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
DefineMap<MemberGroup, NodeDto>(nameof(MemberGroup.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<MemberGroup, NodeDto>(nameof(MemberGroup.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<MemberGroup, NodeDto>(nameof(MemberGroup.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<MemberGroup, NodeDto>(nameof(MemberGroup.Name), nameof(NodeDto.Text));
|
||||
DefineMap<MemberGroup, NodeDto>(nameof(MemberGroup.Key), nameof(NodeDto.UniqueId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
@@ -13,47 +14,47 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Member))]
|
||||
public sealed class MemberMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MemberMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Member, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Member, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<Member, NodeDto>(src => ((IUmbracoEntity)src).Level, dto => dto.Level);
|
||||
CacheMap<Member, NodeDto>(src => ((IUmbracoEntity)src).ParentId, dto => dto.ParentId);
|
||||
CacheMap<Member, NodeDto>(src => ((IUmbracoEntity)src).Path, dto => dto.Path);
|
||||
CacheMap<Member, NodeDto>(src => ((IUmbracoEntity)src).SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<Member, NodeDto>(src => ((IUmbracoEntity)src).CreatorId, dto => dto.UserId);
|
||||
CacheMap<Member, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<Member, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<Member, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<Member, ContentDto>(src => src.ContentTypeId, dto => dto.ContentTypeId);
|
||||
CacheMap<Member, ContentTypeDto>(src => src.ContentTypeAlias, dto => dto.Alias);
|
||||
CacheMap<Member, ContentVersionDto>(src => src.UpdateDate, dto => dto.VersionDate);
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Level), nameof(NodeDto.Level));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Path), nameof(NodeDto.Path));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Name), nameof(NodeDto.Text));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<Member, NodeDto>(nameof(Member.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<Member, ContentDto>(nameof(Member.ContentTypeId), nameof(ContentDto.ContentTypeId));
|
||||
DefineMap<Member, ContentTypeDto>(nameof(Member.ContentTypeAlias), nameof(ContentTypeDto.Alias));
|
||||
DefineMap<Member, ContentVersionDto>(nameof(Member.UpdateDate), nameof(ContentVersionDto.VersionDate));
|
||||
|
||||
CacheMap<Member, MemberDto>(src => src.Email, dto => dto.Email);
|
||||
CacheMap<Member, MemberDto>(src => src.Username, dto => dto.LoginName);
|
||||
CacheMap<Member, MemberDto>(src => src.RawPasswordValue, dto => dto.Password);
|
||||
DefineMap<Member, MemberDto>(nameof(Member.Email), nameof(MemberDto.Email));
|
||||
DefineMap<Member, MemberDto>(nameof(Member.Username), nameof(MemberDto.LoginName));
|
||||
DefineMap<Member, MemberDto>(nameof(Member.RawPasswordValue), nameof(MemberDto.Password));
|
||||
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IsApproved, dto => dto.IntegerValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IsLockedOut, dto => dto.IntegerValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.Comments, dto => dto.TextValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.RawPasswordAnswerValue, dto => dto.VarcharValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.PasswordQuestion, dto => dto.VarcharValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.FailedPasswordAttempts, dto => dto.IntegerValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastLockoutDate, dto => dto.DateValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastLoginDate, dto => dto.DateValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LastPasswordChangeDate, dto => dto.DateValue);
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.IsApproved), nameof(PropertyDataDto.IntegerValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.IsLockedOut), nameof(PropertyDataDto.IntegerValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.Comments), nameof(PropertyDataDto.TextValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.RawPasswordAnswerValue), nameof(PropertyDataDto.VarcharValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.PasswordQuestion), nameof(PropertyDataDto.VarcharValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.FailedPasswordAttempts), nameof(PropertyDataDto.IntegerValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.LastLockoutDate), nameof(PropertyDataDto.DateValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.LastLoginDate), nameof(PropertyDataDto.DateValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.LastPasswordChangeDate), nameof(PropertyDataDto.DateValue));
|
||||
|
||||
/* Internal experiment */
|
||||
CacheMap<Member, PropertyDataDto>(src => src.DateTimePropertyValue, dto => dto.DateValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.IntegerPropertyValue, dto => dto.IntegerValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.BoolPropertyValue, dto => dto.IntegerValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.LongStringPropertyValue, dto => dto.TextValue);
|
||||
CacheMap<Member, PropertyDataDto>(src => src.ShortStringPropertyValue, dto => dto.VarcharValue);
|
||||
CacheMap<Member, PropertyTypeDto>(src => src.PropertyTypeAlias, dto => dto.Alias);
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.DateTimePropertyValue), nameof(PropertyDataDto.DateValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.IntegerPropertyValue), nameof(PropertyDataDto.IntegerValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.BoolPropertyValue), nameof(PropertyDataDto.IntegerValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.LongStringPropertyValue), nameof(PropertyDataDto.TextValue));
|
||||
DefineMap<Member, PropertyDataDto>(nameof(Member.ShortStringPropertyValue), nameof(PropertyDataDto.VarcharValue));
|
||||
DefineMap<Member, PropertyTypeDto>(nameof(Member.PropertyTypeAlias), nameof(PropertyTypeDto.Alias));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,31 +13,29 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof (IMemberType))]
|
||||
public sealed class MemberTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public MemberTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<MemberType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<MemberType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<MemberType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<MemberType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<MemberType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<MemberType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<MemberType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<MemberType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<MemberType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<MemberType, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.AllowedAsRoot, dto => dto.AllowAtRoot);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.IsContainer, dto => dto.IsContainer);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.IsElement, dto => dto.IsElement);
|
||||
CacheMap<MemberType, ContentTypeDto>(src => src.Thumbnail, dto => dto.Thumbnail);
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Level), nameof(NodeDto.Level));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Path), nameof(NodeDto.Path));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Name), nameof(NodeDto.Text));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<MemberType, NodeDto>(nameof(MemberType.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.Alias), nameof(ContentTypeDto.Alias));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.AllowedAsRoot), nameof(ContentTypeDto.AllowAtRoot));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.Description), nameof(ContentTypeDto.Description));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.Icon), nameof(ContentTypeDto.Icon));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.IsContainer), nameof(ContentTypeDto.IsContainer));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.IsElement), nameof(ContentTypeDto.IsElement));
|
||||
DefineMap<MemberType, ContentTypeDto>(nameof(MemberType.Thumbnail), nameof(ContentTypeDto.Thumbnail));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -11,16 +12,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(PropertyGroup))]
|
||||
public sealed class PropertyGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public PropertyGroupMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<PropertyGroup, PropertyTypeGroupDto>(src => src.Name, dto => dto.Text);
|
||||
DefineMap<PropertyGroup, PropertyTypeGroupDto>(nameof(PropertyGroup.Id), nameof(PropertyTypeGroupDto.Id));
|
||||
DefineMap<PropertyGroup, PropertyTypeGroupDto>(nameof(PropertyGroup.Key), nameof(PropertyTypeGroupDto.UniqueId));
|
||||
DefineMap<PropertyGroup, PropertyTypeGroupDto>(nameof(PropertyGroup.SortOrder), nameof(PropertyTypeGroupDto.SortOrder));
|
||||
DefineMap<PropertyGroup, PropertyTypeGroupDto>(nameof(PropertyGroup.Name), nameof(PropertyTypeGroupDto.Text));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -7,14 +8,14 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Property))]
|
||||
public sealed class PropertyMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public PropertyMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Property, PropertyDataDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Property, PropertyDataDto>(src => src.PropertyTypeId, dto => dto.PropertyTypeId);
|
||||
DefineMap<Property, PropertyDataDto>(nameof(Property.Id), nameof(PropertyDataDto.Id));
|
||||
DefineMap<Property, PropertyDataDto>(nameof(Property.PropertyTypeId), nameof(PropertyDataDto.PropertyTypeId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -11,25 +12,23 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(PropertyType))]
|
||||
public sealed class PropertyTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public PropertyTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.DataTypeId, dto => dto.DataTypeId);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Mandatory, dto => dto.Mandatory);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<PropertyType, PropertyTypeDto>(src => src.ValidationRegExp, dto => dto.ValidationRegExp);
|
||||
CacheMap<PropertyType, DataTypeDto>(src => src.PropertyEditorAlias, dto => dto.EditorAlias);
|
||||
CacheMap<PropertyType, DataTypeDto>(src => src.ValueStorageType, dto => dto.DbType);
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Key), nameof(PropertyTypeDto.UniqueId));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Id), nameof(PropertyTypeDto.Id));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Alias), nameof(PropertyTypeDto.Alias));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.DataTypeId), nameof(PropertyTypeDto.DataTypeId));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Description), nameof(PropertyTypeDto.Description));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Mandatory), nameof(PropertyTypeDto.Mandatory));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.Name), nameof(PropertyTypeDto.Name));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.SortOrder), nameof(PropertyTypeDto.SortOrder));
|
||||
DefineMap<PropertyType, PropertyTypeDto>(nameof(PropertyType.ValidationRegExp), nameof(PropertyTypeDto.ValidationRegExp));
|
||||
DefineMap<PropertyType, DataTypeDto>(nameof(PropertyType.PropertyEditorAlias), nameof(DataTypeDto.EditorAlias));
|
||||
DefineMap<PropertyType, DataTypeDto>(nameof(PropertyType.ValueStorageType), nameof(DataTypeDto.DbType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,18 +13,18 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(Relation))]
|
||||
public sealed class RelationMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public RelationMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<Relation, RelationDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Relation, RelationDto>(src => src.ChildId, dto => dto.ChildId);
|
||||
CacheMap<Relation, RelationDto>(src => src.Comment, dto => dto.Comment);
|
||||
CacheMap<Relation, RelationDto>(src => src.CreateDate, dto => dto.Datetime);
|
||||
CacheMap<Relation, RelationDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<Relation, RelationDto>(src => src.RelationTypeId, dto => dto.RelationType);
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.Id), nameof(RelationDto.Id));
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.ChildId), nameof(RelationDto.ChildId));
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.Comment), nameof(RelationDto.Comment));
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.CreateDate), nameof(RelationDto.Datetime));
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.ParentId), nameof(RelationDto.ParentId));
|
||||
DefineMap<Relation, RelationDto>(nameof(Relation.RelationTypeId), nameof(RelationDto.RelationType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,18 +13,18 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IRelationType))]
|
||||
public sealed class RelationTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public RelationTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.ChildObjectType, dto => dto.ChildObjectType);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.IsBidirectional, dto => dto.Dual);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<RelationType, RelationTypeDto>(src => src.ParentObjectType, dto => dto.ParentObjectType);
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.Id), nameof(RelationTypeDto.Id));
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.Alias), nameof(RelationTypeDto.Alias));
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.ChildObjectType), nameof(RelationTypeDto.ChildObjectType));
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.IsBidirectional), nameof(RelationTypeDto.Dual));
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.Name), nameof(RelationTypeDto.Name));
|
||||
DefineMap<RelationType, RelationTypeDto>(nameof(RelationType.ParentObjectType), nameof(RelationTypeDto.ParentObjectType));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,19 +9,19 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(IServerRegistration))]
|
||||
internal sealed class ServerRegistrationMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public ServerRegistrationMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.IsActive, dto => dto.IsActive);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.IsMaster, dto => dto.IsMaster);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.ServerAddress, dto => dto.ServerAddress);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.CreateDate, dto => dto.DateRegistered);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.UpdateDate, dto => dto.DateAccessed);
|
||||
CacheMap<ServerRegistration, ServerRegistrationDto>(src => src.ServerIdentity, dto => dto.ServerIdentity);
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.Id), nameof(ServerRegistrationDto.Id));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.IsActive), nameof(ServerRegistrationDto.IsActive));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.IsMaster), nameof(ServerRegistrationDto.IsMaster));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.ServerAddress), nameof(ServerRegistrationDto.ServerAddress));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.CreateDate), nameof(ServerRegistrationDto.DateRegistered));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.UpdateDate), nameof(ServerRegistrationDto.DateAccessed));
|
||||
DefineMap<ServerRegistration, ServerRegistrationDto>(nameof(ServerRegistration.ServerIdentity), nameof(ServerRegistrationDto.ServerIdentity));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,31 +9,29 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(SimpleContentType))]
|
||||
public sealed class SimpleContentTypeMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public SimpleContentTypeMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<ContentType, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<ContentType, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<ContentType, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<ContentType, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<ContentType, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.AllowedAsRoot, dto => dto.AllowAtRoot);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Description, dto => dto.Description);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.IsContainer, dto => dto.IsContainer);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.IsElement, dto => dto.IsElement);
|
||||
CacheMap<ContentType, ContentTypeDto>(src => src.Thumbnail, dto => dto.Thumbnail);
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Level), nameof(NodeDto.Level));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Path), nameof(NodeDto.Path));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Name), nameof(NodeDto.Text));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<ContentType, NodeDto>(nameof(ContentType.CreatorId), nameof(NodeDto.UserId));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Alias), nameof(ContentTypeDto.Alias));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.AllowedAsRoot), nameof(ContentTypeDto.AllowAtRoot));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Description), nameof(ContentTypeDto.Description));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Icon), nameof(ContentTypeDto.Icon));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.IsContainer), nameof(ContentTypeDto.IsContainer));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.IsElement), nameof(ContentTypeDto.IsElement));
|
||||
DefineMap<ContentType, ContentTypeDto>(nameof(ContentType.Thumbnail), nameof(ContentTypeDto.Thumbnail));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,18 +13,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(ITag))]
|
||||
public sealed class TagMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public TagMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<Tag, TagDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<Tag, TagDto>(src => src.Text, dto => dto.Text);
|
||||
CacheMap<Tag, TagDto>(src => src.Group, dto => dto.Group);
|
||||
CacheMap<Tag, TagDto>(src => src.LanguageId, dto => dto.LanguageId);
|
||||
DefineMap<Tag, TagDto>(nameof(Tag.Id), nameof(TagDto.Id));
|
||||
DefineMap<Tag, TagDto>(nameof(Tag.Text), nameof(TagDto.Text));
|
||||
DefineMap<Tag, TagDto>(nameof(Tag.Group), nameof(TagDto.Group));
|
||||
DefineMap<Tag, TagDto>(nameof(Tag.LanguageId), nameof(TagDto.LanguageId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,18 +13,16 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(ITemplate))]
|
||||
public sealed class TemplateMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public TemplateMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
if (PropertyInfoCache.IsEmpty == false) return;
|
||||
|
||||
CacheMap<Template, TemplateDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<Template, NodeDto>(src => src.MasterTemplateId, dto => dto.ParentId);
|
||||
CacheMap<Template, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<Template, TemplateDto>(src => src.Alias, dto => dto.Alias);
|
||||
DefineMap<Template, TemplateDto>(nameof(Template.Id), nameof(TemplateDto.NodeId));
|
||||
DefineMap<Template, NodeDto>(nameof(Template.MasterTemplateId), nameof(NodeDto.ParentId));
|
||||
DefineMap<Template, NodeDto>(nameof(Template.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<Template, TemplateDto>(nameof(Template.Alias), nameof(TemplateDto.Alias));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models.Entities;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -7,22 +8,22 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof (IUmbracoEntity))]
|
||||
public sealed class UmbracoEntityMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public UmbracoEntityMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Id, dto => dto.NodeId);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Level, dto => dto.Level);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.ParentId, dto => dto.ParentId);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Path, dto => dto.Path);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.SortOrder, dto => dto.SortOrder);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Name, dto => dto.Text);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Trashed, dto => dto.Trashed);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.Key, dto => dto.UniqueId);
|
||||
CacheMap<IUmbracoEntity, NodeDto>(src => src.CreatorId, dto => dto.UserId);
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Id), nameof(NodeDto.NodeId));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.CreateDate), nameof(NodeDto.CreateDate));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Level), nameof(NodeDto.Level));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.ParentId), nameof(NodeDto.ParentId));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Path), nameof(NodeDto.Path));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.SortOrder), nameof(NodeDto.SortOrder));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Name), nameof(NodeDto.Text));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Trashed), nameof(NodeDto.Trashed));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.Key), nameof(NodeDto.UniqueId));
|
||||
DefineMap<IUmbracoEntity, NodeDto>(nameof(IUmbracoEntity.CreatorId), nameof(NodeDto.UserId));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -12,29 +13,18 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(UserGroup))]
|
||||
public sealed class UserGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public UserGroupMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
//NOTE: its an internal class but the ctor must be public since we're using Activator.CreateInstance to create it
|
||||
// otherwise that would fail because there is no public constructor.
|
||||
public UserGroupMapper()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
BuildMap();
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.Id), nameof(UserGroupDto.Id));
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.Alias), nameof(UserGroupDto.Alias));
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.Name), nameof(UserGroupDto.Name));
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.Icon), nameof(UserGroupDto.Icon));
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.StartContentId), nameof(UserGroupDto.StartContentId));
|
||||
DefineMap<UserGroup, UserGroupDto>(nameof(UserGroup.StartMediaId), nameof(UserGroupDto.StartMediaId));
|
||||
}
|
||||
|
||||
#region Overrides of BaseMapper
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
{
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.Alias, dto => dto.Alias);
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.Name, dto => dto.Name);
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.Icon, dto => dto.Icon);
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.StartContentId, dto => dto.StartContentId);
|
||||
CacheMap<UserGroup, UserGroupDto>(src => src.StartMediaId, dto => dto.StartMediaId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.Dtos;
|
||||
|
||||
@@ -8,28 +9,28 @@ namespace Umbraco.Core.Persistence.Mappers
|
||||
[MapperFor(typeof(User))]
|
||||
public sealed class UserMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
public UserMapper(Lazy<ISqlContext> sqlContext, ConcurrentDictionary<Type, ConcurrentDictionary<string, string>> maps)
|
||||
: base(sqlContext, maps)
|
||||
{ }
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache => PropertyInfoCacheInstance;
|
||||
|
||||
protected override void BuildMap()
|
||||
protected override void DefineMaps()
|
||||
{
|
||||
CacheMap<User, UserDto>(src => src.Id, dto => dto.Id);
|
||||
CacheMap<User, UserDto>(src => src.Email, dto => dto.Email);
|
||||
CacheMap<User, UserDto>(src => src.Username, dto => dto.Login);
|
||||
CacheMap<User, UserDto>(src => src.RawPasswordValue, dto => dto.Password);
|
||||
CacheMap<User, UserDto>(src => src.Name, dto => dto.UserName);
|
||||
DefineMap<User, UserDto>(nameof(User.Id), nameof(UserDto.Id));
|
||||
DefineMap<User, UserDto>(nameof(User.Email), nameof(UserDto.Email));
|
||||
DefineMap<User, UserDto>(nameof(User.Username), nameof(UserDto.Login));
|
||||
DefineMap<User, UserDto>(nameof(User.RawPasswordValue), nameof(UserDto.Password));
|
||||
DefineMap<User, UserDto>(nameof(User.Name), nameof(UserDto.UserName));
|
||||
//NOTE: This column in the db is *not* used!
|
||||
//CacheMap<User, UserDto>(src => src.DefaultPermissions, dto => dto.DefaultPermissions);
|
||||
CacheMap<User, UserDto>(src => src.IsApproved, dto => dto.Disabled);
|
||||
CacheMap<User, UserDto>(src => src.IsLockedOut, dto => dto.NoConsole);
|
||||
CacheMap<User, UserDto>(src => src.Language, dto => dto.UserLanguage);
|
||||
CacheMap<User, UserDto>(src => src.CreateDate, dto => dto.CreateDate);
|
||||
CacheMap<User, UserDto>(src => src.UpdateDate, dto => dto.UpdateDate);
|
||||
CacheMap<User, UserDto>(src => src.LastLockoutDate, dto => dto.LastLockoutDate);
|
||||
CacheMap<User, UserDto>(src => src.LastLoginDate, dto => dto.LastLoginDate);
|
||||
CacheMap<User, UserDto>(src => src.LastPasswordChangeDate, dto => dto.LastPasswordChangeDate);
|
||||
CacheMap<User, UserDto>(src => src.SecurityStamp, dto => dto.SecurityStampToken);
|
||||
//DefineMap<User, UserDto>(nameof(User.DefaultPermissions), nameof(UserDto.DefaultPermissions));
|
||||
DefineMap<User, UserDto>(nameof(User.IsApproved), nameof(UserDto.Disabled));
|
||||
DefineMap<User, UserDto>(nameof(User.IsLockedOut), nameof(UserDto.NoConsole));
|
||||
DefineMap<User, UserDto>(nameof(User.Language), nameof(UserDto.UserLanguage));
|
||||
DefineMap<User, UserDto>(nameof(User.CreateDate), nameof(UserDto.CreateDate));
|
||||
DefineMap<User, UserDto>(nameof(User.UpdateDate), nameof(UserDto.UpdateDate));
|
||||
DefineMap<User, UserDto>(nameof(User.LastLockoutDate), nameof(UserDto.LastLockoutDate));
|
||||
DefineMap<User, UserDto>(nameof(User.LastLoginDate), nameof(UserDto.LastLoginDate));
|
||||
DefineMap<User, UserDto>(nameof(User.LastPasswordChangeDate), nameof(UserDto.LastPasswordChangeDate));
|
||||
DefineMap<User, UserDto>(nameof(User.SecurityStamp), nameof(UserDto.SecurityStampToken));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user