Merge remote-tracking branch 'origin/6.2.0' into 6.2.0-pubcontent
Conflicts: src/Umbraco.Tests/TestHelpers/BaseWebTest.cs
This commit is contained in:
@@ -35,12 +35,9 @@ namespace Umbraco.Core
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache)
|
||||
public ApplicationContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache)
|
||||
: this(enableCache)
|
||||
{
|
||||
if (dbContext == null) throw new ArgumentNullException("dbContext");
|
||||
if (serviceContext == null) throw new ArgumentNullException("serviceContext");
|
||||
|
||||
_databaseContext = dbContext;
|
||||
_services = serviceContext;
|
||||
}
|
||||
@@ -57,7 +54,7 @@ namespace Umbraco.Core
|
||||
/// Constructor used to specify if we will enable application cache or not
|
||||
/// </summary>
|
||||
/// <param name="enableCache"></param>
|
||||
internal ApplicationContext(bool enableCache)
|
||||
public ApplicationContext(bool enableCache)
|
||||
{
|
||||
//create a new application cache from the HttpRuntime.Cache
|
||||
ApplicationCache = HttpRuntime.Cache == null
|
||||
@@ -65,7 +62,55 @@ namespace Umbraco.Core
|
||||
: new CacheHelper(HttpRuntime.Cache, enableCache);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <summary>
|
||||
/// A method used to set and/or ensure that a global ApplicationContext singleton is created.
|
||||
/// </summary>
|
||||
/// <param name="appContext">
|
||||
/// The instance to set on the global application singleton
|
||||
/// </param>
|
||||
/// <param name="replaceContext">If set to true and the singleton is already set, it will be replaced</param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(ApplicationContext appContext, bool replaceContext)
|
||||
{
|
||||
if (ApplicationContext.Current != null)
|
||||
{
|
||||
if (!replaceContext)
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
ApplicationContext.Current = appContext;
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A method used to create and ensure that a global ApplicationContext singleton is created.
|
||||
/// </summary>
|
||||
/// <param name="enableCache"></param>
|
||||
/// <param name="replaceContext">
|
||||
/// If set to true will replace the current singleton instance - This should only be used for unit tests or on app
|
||||
/// startup if for some reason the boot manager is not the umbraco boot manager.
|
||||
/// </param>
|
||||
/// <param name="dbContext"></param>
|
||||
/// <param name="serviceContext"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is NOT thread safe
|
||||
/// </remarks>
|
||||
public static ApplicationContext EnsureContext(DatabaseContext dbContext, ServiceContext serviceContext, bool enableCache, bool replaceContext)
|
||||
{
|
||||
if (ApplicationContext.Current != null)
|
||||
{
|
||||
if (!replaceContext)
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
var ctx = new ApplicationContext(dbContext, serviceContext, enableCache);
|
||||
ApplicationContext.Current = ctx;
|
||||
return ApplicationContext.Current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Singleton accessor
|
||||
/// </summary>
|
||||
public static ApplicationContext Current { get; internal set; }
|
||||
|
||||
@@ -99,6 +99,10 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
public static class Member
|
||||
{
|
||||
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
|
||||
|
||||
public static readonly string UmbracoRoleProviderName = "UmbracoRoleProvider";
|
||||
|
||||
/// <summary>
|
||||
/// Property alias for a Members Password Question
|
||||
/// </summary>
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Umbraco.Core
|
||||
private string _providerName;
|
||||
private DatabaseSchemaResult _result;
|
||||
|
||||
internal DatabaseContext(IDatabaseFactory factory)
|
||||
public DatabaseContext(IDatabaseFactory factory)
|
||||
{
|
||||
_factory = factory;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
@@ -50,6 +51,7 @@ namespace Umbraco.Core.Models
|
||||
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
|
||||
_properties = properties;
|
||||
_properties.EnsurePropertyTypes(PropertyTypes);
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -73,6 +75,7 @@ namespace Umbraco.Core.Models
|
||||
_contentTypeId = int.Parse(contentType.Id.ToString(CultureInfo.InvariantCulture));
|
||||
_properties = properties;
|
||||
_properties.EnsurePropertyTypes(PropertyTypes);
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentBase, string>(x => x.Name);
|
||||
@@ -253,6 +256,16 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IDictionary<string, object> _additionalData;
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
IDictionary<string, object> IUmbracoEntity.AdditionalData
|
||||
{
|
||||
get { return _additionalData; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of PropertyGroups available on this Content object
|
||||
/// </summary>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
@@ -42,6 +43,7 @@ namespace Umbraco.Core.Models
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
protected ContentTypeBase(IContentTypeBase parent)
|
||||
@@ -52,6 +54,7 @@ namespace Umbraco.Core.Models
|
||||
_allowedContentTypes = new List<ContentTypeSort>();
|
||||
_propertyGroups = new PropertyGroupCollection();
|
||||
_propertyTypes = new PropertyTypeCollection();
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<ContentTypeBase, string>(x => x.Name);
|
||||
@@ -314,6 +317,16 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IDictionary<string, object> _additionalData;
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
IDictionary<string, object> IUmbracoEntity.AdditionalData
|
||||
{
|
||||
get { return _additionalData; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a list of integer Ids for allowed ContentTypes
|
||||
/// </summary>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
@@ -31,6 +33,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_parentId = parentId;
|
||||
_controlId = controlId;
|
||||
_additionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<DataTypeDefinition, string>(x => x.Name);
|
||||
@@ -160,9 +163,11 @@ namespace Umbraco.Core.Models
|
||||
_trashed = value;
|
||||
return _trashed;
|
||||
}, _trashed, TrashedSelector);
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
_additionalData["Trashed"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Id of the DataType control
|
||||
/// </summary>
|
||||
@@ -177,6 +182,8 @@ namespace Umbraco.Core.Models
|
||||
_controlId = value;
|
||||
return _controlId;
|
||||
}, _controlId, ControlIdSelector);
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
_additionalData["ControlId"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,9 +201,22 @@ namespace Umbraco.Core.Models
|
||||
_databaseType = value;
|
||||
return _databaseType;
|
||||
}, _databaseType, DatabaseTypeSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
_additionalData["DatabaseType"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly IDictionary<string, object> _additionalData;
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
IDictionary<string, object> IUmbracoEntity.AdditionalData
|
||||
{
|
||||
get { return _additionalData; }
|
||||
}
|
||||
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Umbraco.Core.Models.EntityBase
|
||||
{
|
||||
public interface IUmbracoEntity : IAggregateRoot
|
||||
{
|
||||
@@ -41,5 +43,10 @@
|
||||
/// Not all entities support being trashed, they'll always return false.
|
||||
/// </remarks>
|
||||
bool Trashed { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
IDictionary<string, object> AdditionalData { get; }
|
||||
}
|
||||
}
|
||||
@@ -427,7 +427,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public override void ChangeTrashedState(bool isTrashed, int parentId = -20)
|
||||
{
|
||||
throw new NotImplementedException("Members can't be trashed as no Recycle Bin exists, so use of this method is invalid");
|
||||
throw new NotSupportedException("Members can't be trashed as no Recycle Bin exists, so use of this method is invalid");
|
||||
}
|
||||
|
||||
/* Internal experiment - only used for mapping queries.
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
//TODO: THere's still a bunch of properties that don't exist in this use that need to be mapped somehow.
|
||||
|
||||
internal class UmbracoMembershipMember : MembershipUser
|
||||
{
|
||||
private readonly IMember _member;
|
||||
@@ -21,5 +23,44 @@ namespace Umbraco.Core.Models.Membership
|
||||
get { return _member.Email; }
|
||||
set { _member.Email = value; }
|
||||
}
|
||||
|
||||
public override object ProviderUserKey
|
||||
{
|
||||
get { return _member.Key; }
|
||||
}
|
||||
|
||||
public override System.DateTime CreationDate
|
||||
{
|
||||
get { return _member.CreateDate; }
|
||||
}
|
||||
|
||||
public override string UserName
|
||||
{
|
||||
get { return _member.Username; }
|
||||
}
|
||||
|
||||
public override string Comment
|
||||
{
|
||||
get { return _member.Comments; }
|
||||
set { _member.Comments = value; }
|
||||
}
|
||||
|
||||
public override bool IsApproved
|
||||
{
|
||||
get { return _member.IsApproved; }
|
||||
set { _member.IsApproved = value; }
|
||||
}
|
||||
|
||||
public override bool IsLockedOut
|
||||
{
|
||||
get { return _member.IsLockedOut; }
|
||||
}
|
||||
|
||||
public override System.DateTime LastLoginDate
|
||||
{
|
||||
get { return _member.LastLoginDate; }
|
||||
set { _member.LastLoginDate = value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a paged result for a model collection
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
[DataContract(Name = "pagedCollection", Namespace = "")]
|
||||
public class PagedResult<T>
|
||||
{
|
||||
public PagedResult(long totalItems, long pageNumber, long pageSize)
|
||||
{
|
||||
TotalItems = totalItems;
|
||||
PageNumber = pageNumber;
|
||||
PageSize = pageSize;
|
||||
|
||||
if (pageSize > 0)
|
||||
{
|
||||
TotalPages = (long) Math.Ceiling(totalItems/(Decimal) pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
TotalPages = 1;
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember(Name = "pageNumber")]
|
||||
public long PageNumber { get; private set; }
|
||||
|
||||
[DataMember(Name = "pageSize")]
|
||||
public long PageSize { get; private set; }
|
||||
|
||||
[DataMember(Name = "totalPages")]
|
||||
public long TotalPages { get; private set; }
|
||||
|
||||
[DataMember(Name = "totalItems")]
|
||||
public long TotalItems { get; private set; }
|
||||
|
||||
[DataMember(Name = "items")]
|
||||
public IEnumerable<T> Items { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the skip size based on the paged parameters specified
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Returns 0 if the page number or page size is zero
|
||||
/// </remarks>
|
||||
internal int SkipSize
|
||||
{
|
||||
get
|
||||
{
|
||||
if (PageNumber > 0 && PageSize > 0)
|
||||
{
|
||||
return Convert.ToInt32((PageNumber - 1)*PageSize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,10 +44,12 @@ namespace Umbraco.Core.Models
|
||||
|
||||
public UmbracoEntity()
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
public UmbracoEntity(bool trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
@@ -142,6 +144,9 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> AdditionalData { get; private set; }
|
||||
|
||||
|
||||
public bool HasChildren
|
||||
{
|
||||
get { return _hasChildren; }
|
||||
@@ -152,6 +157,9 @@ namespace Umbraco.Core.Models
|
||||
_hasChildren = value;
|
||||
return _hasChildren;
|
||||
}, _hasChildren, HasChildrenSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["HasChildren"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +172,10 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_isPublished = value;
|
||||
return _isPublished;
|
||||
}, _isPublished, IsPublishedSelector);
|
||||
}, _isPublished, IsPublishedSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["IsPublished"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,6 +189,9 @@ namespace Umbraco.Core.Models
|
||||
_isDraft = value;
|
||||
return _isDraft;
|
||||
}, _isDraft, IsDraftSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["IsDraft"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,6 +205,9 @@ namespace Umbraco.Core.Models
|
||||
_hasPendingChanges = value;
|
||||
return _hasPendingChanges;
|
||||
}, _hasPendingChanges, HasPendingChangesSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["HasPendingChanges"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,6 +221,9 @@ namespace Umbraco.Core.Models
|
||||
_contentTypeAlias = value;
|
||||
return _contentTypeAlias;
|
||||
}, _contentTypeAlias, ContentTypeAliasSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["ContentTypeAlias"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +237,9 @@ namespace Umbraco.Core.Models
|
||||
_contentTypeIcon = value;
|
||||
return _contentTypeIcon;
|
||||
}, _contentTypeIcon, ContentTypeIconSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["ContentTypeIcon"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,6 +253,9 @@ namespace Umbraco.Core.Models
|
||||
_contentTypeThumbnail = value;
|
||||
return _contentTypeThumbnail;
|
||||
}, _contentTypeThumbnail, ContentTypeThumbnailSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["ContentTypeThumbnail"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,10 +268,16 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
_nodeObjectTypeId = value;
|
||||
return _nodeObjectTypeId;
|
||||
}, _nodeObjectTypeId, NodeObjectTypeIdSelector);
|
||||
}, _nodeObjectTypeId, NodeObjectTypeIdSelector);
|
||||
|
||||
//This is a custom property that is not exposed in IUmbracoEntity so add it to the additional data
|
||||
AdditionalData["NodeObjectTypeId"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Some entities may expose additional data that other's might not, this custom data will be available in this collection
|
||||
/// </summary>
|
||||
public IList<UmbracoProperty> UmbracoProperties { get; set; }
|
||||
|
||||
internal class UmbracoProperty
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//TODO: Not sure why we need this interface as it's never referenced in code.
|
||||
|
||||
internal interface IEntityFactory<TEntity, TDto>
|
||||
where TEntity : class
|
||||
where TDto : class
|
||||
|
||||
@@ -8,6 +8,45 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class UmbracoEntityFactory : IEntityFactory<UmbracoEntity, EntityRepository.UmbracoEntityDto>
|
||||
{
|
||||
internal UmbracoEntity BuildEntityFromDynamic(dynamic d)
|
||||
{
|
||||
var entity = new UmbracoEntity(d.trashed)
|
||||
{
|
||||
CreateDate = d.createDate,
|
||||
CreatorId = d.nodeUser,
|
||||
Id = d.id,
|
||||
Key = d.uniqueID,
|
||||
Level = d.level,
|
||||
Name = d.text,
|
||||
NodeObjectTypeId = d.nodeObjectType,
|
||||
ParentId = d.parentID,
|
||||
Path = d.path,
|
||||
SortOrder = d.sortOrder,
|
||||
HasChildren = d.children > 0,
|
||||
ContentTypeAlias = d.alias ?? string.Empty,
|
||||
ContentTypeIcon = d.icon ?? string.Empty,
|
||||
ContentTypeThumbnail = d.thumbnail ?? string.Empty,
|
||||
UmbracoProperties = new List<UmbracoEntity.UmbracoProperty>()
|
||||
};
|
||||
|
||||
var asDictionary = (IDictionary<string, object>)d;
|
||||
|
||||
var publishedVersion = default(Guid);
|
||||
//some content items don't have a published version
|
||||
if (asDictionary.ContainsKey("publishedVersion") && asDictionary["publishedVersion"] != null)
|
||||
{
|
||||
Guid.TryParse(d.publishedVersion.ToString(), out publishedVersion);
|
||||
}
|
||||
var newestVersion = default(Guid);
|
||||
Guid.TryParse(d.newestVersion.ToString(), out newestVersion);
|
||||
|
||||
entity.IsPublished = publishedVersion != default(Guid) || (newestVersion != default(Guid) && publishedVersion == newestVersion);
|
||||
entity.IsDraft = newestVersion != default(Guid) && (publishedVersion == default(Guid) || publishedVersion != newestVersion);
|
||||
entity.HasPendingChanges = (publishedVersion != default(Guid) && newestVersion != default(Guid)) && publishedVersion != newestVersion;
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
public UmbracoEntity BuildEntity(EntityRepository.UmbracoEntityDto dto)
|
||||
{
|
||||
var entity = new UmbracoEntity(dto.Trashed)
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Umbraco.Core.Persistence
|
||||
/// <summary>
|
||||
/// Used to create the UmbracoDatabase for use in the DatabaseContext
|
||||
/// </summary>
|
||||
internal interface IDatabaseFactory : IDisposable
|
||||
public interface IDatabaseFactory : IDisposable
|
||||
{
|
||||
UmbracoDatabase CreateDatabase();
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
@@ -17,6 +18,19 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
internal static event CreateTableEventHandler NewTable;
|
||||
|
||||
/// <summary>
|
||||
/// This will escape single @ symbols for peta poco values so it doesn't think it's a parameter
|
||||
/// </summary>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static string EscapeAtSymbols(this Database db, string value)
|
||||
{
|
||||
//this fancy regex will only match a single @ not a double, etc...
|
||||
var regex = new Regex("(?<!@)@(?!@)");
|
||||
return regex.Replace(value, "@@");
|
||||
}
|
||||
|
||||
public static void CreateTable<T>(this Database db)
|
||||
where T : new()
|
||||
{
|
||||
|
||||
@@ -38,7 +38,11 @@ namespace Umbraco.Core.Persistence.Relators
|
||||
// Setup the new current MemberTypeReadOnlyDto
|
||||
Current = a;
|
||||
Current.PropertyTypes = new List<PropertyTypeReadOnlyDto>();
|
||||
Current.PropertyTypes.Add(p);
|
||||
//this can be null since we are doing a left join
|
||||
if (p.Id.HasValue)
|
||||
{
|
||||
Current.PropertyTypes.Add(p);
|
||||
}
|
||||
|
||||
Current.PropertyTypeGroups = new List<PropertyTypeGroupReadOnlyDto>();
|
||||
if (g.Id.HasValue)
|
||||
|
||||
@@ -1,12 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Strings;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
@@ -124,15 +130,43 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var translator = new SqlTranslator<IUmbracoEntity>(sqlClause, query);
|
||||
var sql = translator.Translate().Append(GetGroupBy(isContent, isMedia));
|
||||
|
||||
var dtos = isMedia
|
||||
? _work.Database.Fetch<UmbracoEntityDto, UmbracoPropertyDto, UmbracoEntityDto>(
|
||||
new UmbracoEntityRelator().Map, sql)
|
||||
: _work.Database.Fetch<UmbracoEntityDto>(sql);
|
||||
|
||||
var factory = new UmbracoEntityFactory();
|
||||
var list = dtos.Select(factory.BuildEntity).Cast<IUmbracoEntity>().ToList();
|
||||
|
||||
return list;
|
||||
if (isMedia)
|
||||
{
|
||||
//treat media differently for now
|
||||
var dtos = _work.Database.Fetch<UmbracoEntityDto, UmbracoPropertyDto, UmbracoEntityDto>(
|
||||
new UmbracoEntityRelator().Map, sql);
|
||||
return dtos.Select(factory.BuildEntity).Cast<IUmbracoEntity>().ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
//use dynamic so that we can get ALL properties from the SQL
|
||||
//we'll have to stitch stuff together manually but we can get our
|
||||
//additional data to put in the dictionary.
|
||||
var dtos = _work.Database.Fetch<dynamic>(sql);
|
||||
var entityProps = TypeHelper.GetPublicProperties(typeof (IUmbracoEntity)).Select(x => x.Name).ToArray();
|
||||
var result = new List<IUmbracoEntity>();
|
||||
foreach (var d in dtos)
|
||||
{
|
||||
//build the initial entity
|
||||
IUmbracoEntity entity = factory.BuildEntityFromDynamic(d);
|
||||
|
||||
//convert the dynamic row to dictionary
|
||||
var asDictionary = (IDictionary<string, object>) d;
|
||||
|
||||
//figure out what extra properties we have that are not on the IUmbracoEntity and add them to additional data
|
||||
foreach (var k in asDictionary.Keys
|
||||
.Select(x => new {orig = x, title = x.ConvertCase(StringAliasCaseType.PascalCase)})
|
||||
.Where(x => entityProps.InvariantContains(x.title) == false))
|
||||
{
|
||||
entity.AdditionalData[k.title] = asDictionary[k.orig];
|
||||
}
|
||||
|
||||
result.Add(entity);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -159,11 +193,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
if (isContent || isMedia)
|
||||
{
|
||||
columns.Add("published.versionId as publishedVerison");
|
||||
columns.Add("published.versionId as publishedVersion");
|
||||
columns.Add("latest.versionId as newestVersion");
|
||||
columns.Add("contenttype.alias");
|
||||
columns.Add("contenttype.icon");
|
||||
columns.Add("contenttype.thumbnail");
|
||||
columns.Add("contenttype.isContainer");
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
@@ -251,6 +286,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
columns.Add("contenttype.alias");
|
||||
columns.Add("contenttype.icon");
|
||||
columns.Add("contenttype.thumbnail");
|
||||
columns.Add("contenttype.isContainer");
|
||||
}
|
||||
|
||||
if (isMedia)
|
||||
@@ -287,7 +323,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
[Column("children")]
|
||||
public int Children { get; set; }
|
||||
|
||||
[Column("publishedVerison")]
|
||||
[Column("publishedVersion")]
|
||||
public Guid PublishedVersion { get; set; }
|
||||
|
||||
[Column("newestVersion")]
|
||||
|
||||
@@ -11,5 +11,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="groupName"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMember> GetByMemberGroup(string groupName);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -298,11 +298,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//TODO ContentType for the Member entity
|
||||
|
||||
//Create the PropertyData for this version - cmsPropertyData
|
||||
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
|
||||
var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties);
|
||||
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
|
||||
var keyDictionary = new Dictionary<int, int>();
|
||||
|
||||
//Add Properties
|
||||
// - don't try to save the property if it doesn't exist (or doesn't have an ID) on the content type
|
||||
// - this can occur if the member type doesn't contain the built-in properties that the
|
||||
// - member object contains.
|
||||
var existingProperties = entity.Properties
|
||||
.Where(property => entity.ContentType.PropertyTypes.Any(x => x.Alias == property.Alias && x.HasIdentity))
|
||||
.ToList();
|
||||
|
||||
var propertyDataDtos = propertyFactory.BuildDto(existingProperties);
|
||||
|
||||
foreach (var propertyDataDto in propertyDataDtos)
|
||||
{
|
||||
if (propertyDataDto.Id > 0)
|
||||
|
||||
@@ -108,7 +108,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<ContentTypeDto>().On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.LeftJoin<PropertyTypeDto>().On<PropertyTypeDto, NodeDto>(left => left.ContentTypeId, right => right.NodeId)
|
||||
.InnerJoin<MemberTypeDto>().On<MemberTypeDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.LeftJoin<MemberTypeDto>().On<MemberTypeDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.LeftJoin<DataTypeDto>().On<DataTypeDto, PropertyTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.LeftJoin<PropertyTypeGroupDto>().On<PropertyTypeGroupDto, NodeDto>(left => left.ContentTypeNodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
@@ -122,7 +122,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<ContentTypeDto>().On<ContentTypeDto, NodeDto>(left => left.NodeId, right => right.NodeId)
|
||||
.LeftJoin<PropertyTypeDto>().On<PropertyTypeDto, NodeDto>(left => left.ContentTypeId, right => right.NodeId)
|
||||
.InnerJoin<MemberTypeDto>().On<MemberTypeDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.LeftJoin<MemberTypeDto>().On<MemberTypeDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.LeftJoin<DataTypeDto>().On<DataTypeDto, PropertyTypeDto>(left => left.DataTypeId, right => right.DataTypeId)
|
||||
.LeftJoin<PropertyTypeGroupDto>().On<PropertyTypeGroupDto, NodeDto>(left => left.ContentTypeNodeId, right => right.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
}
|
||||
|
||||
internal RepositoryFactory(bool disableAllCache)
|
||||
public RepositoryFactory(bool disableAllCache)
|
||||
{
|
||||
_disableAllCache = disableAllCache;
|
||||
}
|
||||
|
||||
@@ -43,4 +43,5 @@ using System.Security.Permissions;
|
||||
|
||||
[assembly: InternalsVisibleTo("Concorde.Sync")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.Belle")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
||||
[assembly: InternalsVisibleTo("Umbraco.VisualStudio")]
|
||||
[assembly: InternalsVisibleTo("umbraco.providers")]
|
||||
@@ -10,7 +10,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public class EntityService : IService
|
||||
public class EntityService : IService, IEntityService
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public interface IEntityService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets an UmbracoEntity by its Id, and optionally loads the complete object graph.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// By default this will load the base type <see cref="IUmbracoEntity"/> with a minimum set of properties.
|
||||
/// </returns>
|
||||
/// <param name="id">Id of the object to retrieve</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c>.</param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
IUmbracoEntity Get(int id, bool loadBaseType = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an UmbracoEntity by its Id and UmbracoObjectType, and optionally loads the complete object graph.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// By default this will load the base type <see cref="IUmbracoEntity"/> with a minimum set of properties.
|
||||
/// </returns>
|
||||
/// <param name="id">Id of the object to retrieve</param>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the entity to retrieve</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c>.</param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
IUmbracoEntity Get(int id, UmbracoObjectTypes umbracoObjectType, bool loadBaseType = true);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an UmbracoEntity by its Id and specified Type. Optionally loads the complete object graph.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// By default this will load the base type <see cref="IUmbracoEntity"/> with a minimum set of properties.
|
||||
/// </returns>
|
||||
/// <typeparam name="T">Type of the model to retrieve. Must be based on an <see cref="IUmbracoEntity"/></typeparam>
|
||||
/// <param name="id">Id of the object to retrieve</param>
|
||||
/// <param name="loadBaseType">Optional bool to load the complete object graph when set to <c>False</c>.</param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
IUmbracoEntity Get<T>(int id, bool loadBaseType = true) where T : IUmbracoEntity;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of entity by its id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the entity to retrieve the Parent for</param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
IUmbracoEntity GetParent(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the parent of entity by its id and UmbracoObjectType
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the entity to retrieve the Parent for</param>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the parent to retrieve</param>
|
||||
/// <returns>An <see cref="IUmbracoEntity"/></returns>
|
||||
IUmbracoEntity GetParent(int id, UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of children by the parents Id
|
||||
/// </summary>
|
||||
/// <param name="parentId">Id of the parent to retrieve children for</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetChildren(int parentId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of children by the parents Id and UmbracoObjectType
|
||||
/// </summary>
|
||||
/// <param name="parentId">Id of the parent to retrieve children for</param>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the children to retrieve</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetChildren(int parentId, UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of descendents by the parents Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of entity to retrieve descendents for</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetDescendents(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of descendents by the parents Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of entity to retrieve descendents for</param>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the descendents to retrieve</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetDescendents(int id, UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of the entities at the root, which corresponds to the entities with a Parent Id of -1.
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the root entities to retrieve</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetRootEntities(UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all <see cref="IUmbracoEntity"/> of a given type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type of the entities to retrieve</typeparam>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetAll<T>() where T : IUmbracoEntity;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of all <see cref="IUmbracoEntity"/> of a given type.
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType">UmbracoObjectType of the entities to return</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetAll(UmbracoObjectTypes umbracoObjectType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a collection of <see cref="IUmbracoEntity"/>
|
||||
/// </summary>
|
||||
/// <param name="objectTypeId">Guid id of the UmbracoObjectType</param>
|
||||
/// <returns>An enumerable list of <see cref="IUmbracoEntity"/> objects</returns>
|
||||
IEnumerable<IUmbracoEntity> GetAll(Guid objectTypeId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the UmbracoObjectType from the integer id of an IUmbracoEntity.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the entity</param>
|
||||
/// <returns><see cref="UmbracoObjectTypes"/></returns>
|
||||
UmbracoObjectTypes GetObjectType(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the UmbracoObjectType from an IUmbracoEntity.
|
||||
/// </summary>
|
||||
/// <param name="entity"><see cref="IUmbracoEntity"/></param>
|
||||
/// <returns><see cref="UmbracoObjectTypes"/></returns>
|
||||
UmbracoObjectTypes GetObjectType(IUmbracoEntity entity);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Type of an entity by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the entity</param>
|
||||
/// <returns>Type of the entity</returns>
|
||||
Type GetEntityType(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Type of an entity by its <see cref="UmbracoObjectTypes"/>
|
||||
/// </summary>
|
||||
/// <param name="umbracoObjectType"><see cref="UmbracoObjectTypes"/></param>
|
||||
/// <returns>Type of the entity</returns>
|
||||
Type GetEntityType(UmbracoObjectTypes umbracoObjectType);
|
||||
}
|
||||
}
|
||||
@@ -35,5 +35,7 @@ namespace Umbraco.Core.Services
|
||||
void Delete(IMember membershipUser);
|
||||
|
||||
void Save(IMember membershipUser);
|
||||
|
||||
IEnumerable<IMember> FindMembersByEmail(string emailStringToMatch);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal interface IMemberTypeService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a list of all available <see cref="IContentType"/> objects
|
||||
/// </summary>
|
||||
/// <param name="ids">Optional list of ids</param>
|
||||
/// <returns>An Enumerable list of <see cref="IContentType"/> objects</returns>
|
||||
IEnumerable<IMemberType> GetAllMemberTypes(params int[] ids);
|
||||
}
|
||||
}
|
||||
@@ -108,6 +108,25 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does a search for members that contain the specified string in their email address
|
||||
/// </summary>
|
||||
/// <param name="emailStringToMatch"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMember> FindMembersByEmail(string emailStringToMatch)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
var query = new Query<IMember>();
|
||||
|
||||
|
||||
query.Where(member => member.Email.Contains(emailStringToMatch));
|
||||
|
||||
return repository.GetByQuery(query);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of Members with a certain string property value
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal class MemberTypeService : IMemberTypeService
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
|
||||
public MemberTypeService()
|
||||
: this(new PetaPocoUnitOfWorkProvider(), new RepositoryFactory())
|
||||
{}
|
||||
|
||||
public MemberTypeService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
{ }
|
||||
|
||||
public MemberTypeService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
{
|
||||
if (provider == null) throw new ArgumentNullException("provider");
|
||||
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
|
||||
_uowProvider = provider;
|
||||
_repositoryFactory = repositoryFactory;
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberType> GetAllMemberTypes(params int[] ids)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,10 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly EntityService _entityService;
|
||||
private readonly IEntityService _entityService;
|
||||
|
||||
public RelationService(IDatabaseUnitOfWorkProvider uowProvider, RepositoryFactory repositoryFactory,
|
||||
EntityService entityService)
|
||||
IEntityService entityService)
|
||||
{
|
||||
_uowProvider = uowProvider;
|
||||
_repositoryFactory = repositoryFactory;
|
||||
|
||||
@@ -12,41 +12,67 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public class ServiceContext
|
||||
{
|
||||
private Lazy<ContentService> _contentService;
|
||||
private Lazy<UserService> _userService;
|
||||
private Lazy<MemberService> _memberService;
|
||||
private Lazy<MediaService> _mediaService;
|
||||
private Lazy<ContentTypeService> _contentTypeService;
|
||||
private Lazy<DataTypeService> _dataTypeService;
|
||||
private Lazy<FileService> _fileService;
|
||||
private Lazy<LocalizationService> _localizationService;
|
||||
private Lazy<IContentService> _contentService;
|
||||
private Lazy<IUserService> _userService;
|
||||
private Lazy<IMemberService> _memberService;
|
||||
private Lazy<IMediaService> _mediaService;
|
||||
private Lazy<IContentTypeService> _contentTypeService;
|
||||
private Lazy<IDataTypeService> _dataTypeService;
|
||||
private Lazy<IFileService> _fileService;
|
||||
private Lazy<ILocalizationService> _localizationService;
|
||||
private Lazy<PackagingService> _packagingService;
|
||||
private Lazy<ServerRegistrationService> _serverRegistrationService;
|
||||
private Lazy<EntityService> _entityService;
|
||||
private Lazy<IEntityService> _entityService;
|
||||
private Lazy<RelationService> _relationService;
|
||||
private Lazy<IMemberTypeService> _memberTypeService;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="dbUnitOfWorkProvider"></param>
|
||||
/// <param name="fileUnitOfWorkProvider"></param>
|
||||
/// <param name="publishingStrategy"></param>
|
||||
internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy)
|
||||
{
|
||||
BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy,
|
||||
//this needs to be lazy because when we create the service context it's generally before the
|
||||
//resolvers have been initialized!
|
||||
new Lazy<RepositoryFactory>(() => RepositoryResolver.Current.Factory));
|
||||
}
|
||||
/// <summary>
|
||||
/// public ctor - will generally just be used for unit testing
|
||||
/// </summary>
|
||||
/// <param name="contentService"></param>
|
||||
/// <param name="mediaService"></param>
|
||||
/// <param name="contentTypeService"></param>
|
||||
/// <param name="dataTypeService"></param>
|
||||
/// <param name="fileService"></param>
|
||||
/// <param name="localizationService"></param>
|
||||
/// <param name="packagingService"></param>
|
||||
/// <param name="entityService"></param>
|
||||
/// <param name="relationService"></param>
|
||||
public ServiceContext(IContentService contentService, IMediaService mediaService, IContentTypeService contentTypeService, IDataTypeService dataTypeService, IFileService fileService, ILocalizationService localizationService, PackagingService packagingService, IEntityService entityService, RelationService relationService)
|
||||
{
|
||||
_contentService = new Lazy<IContentService>(() => contentService);
|
||||
_mediaService = new Lazy<IMediaService>(() => mediaService);
|
||||
_contentTypeService = new Lazy<IContentTypeService>(() => contentTypeService);
|
||||
_dataTypeService = new Lazy<IDataTypeService>(() => dataTypeService);
|
||||
_fileService = new Lazy<IFileService>(() => fileService);
|
||||
_localizationService = new Lazy<ILocalizationService>(() => localizationService);
|
||||
_packagingService = new Lazy<PackagingService>(() => packagingService);
|
||||
_entityService = new Lazy<IEntityService>(() => entityService);
|
||||
_relationService = new Lazy<RelationService>(() => relationService);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor used to instantiate the core services
|
||||
/// </summary>
|
||||
/// <param name="dbUnitOfWorkProvider"></param>
|
||||
/// <param name="fileUnitOfWorkProvider"></param>
|
||||
/// <param name="publishingStrategy"></param>
|
||||
internal ServiceContext(IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider, IUnitOfWorkProvider fileUnitOfWorkProvider, BasePublishingStrategy publishingStrategy)
|
||||
{
|
||||
BuildServiceCache(dbUnitOfWorkProvider, fileUnitOfWorkProvider, publishingStrategy,
|
||||
//this needs to be lazy because when we create the service context it's generally before the
|
||||
//resolvers have been initialized!
|
||||
new Lazy<RepositoryFactory>(() => RepositoryResolver.Current.Factory));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the various services
|
||||
/// </summary>
|
||||
private void BuildServiceCache(
|
||||
IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider,
|
||||
IUnitOfWorkProvider fileUnitOfWorkProvider,
|
||||
BasePublishingStrategy publishingStrategy,
|
||||
Lazy<RepositoryFactory> repositoryFactory)
|
||||
private void BuildServiceCache(
|
||||
IDatabaseUnitOfWorkProvider dbUnitOfWorkProvider,
|
||||
IUnitOfWorkProvider fileUnitOfWorkProvider,
|
||||
BasePublishingStrategy publishingStrategy,
|
||||
Lazy<RepositoryFactory> repositoryFactory)
|
||||
{
|
||||
var provider = dbUnitOfWorkProvider;
|
||||
var fileProvider = fileUnitOfWorkProvider;
|
||||
@@ -54,38 +80,41 @@ namespace Umbraco.Core.Services
|
||||
if (_serverRegistrationService == null)
|
||||
_serverRegistrationService = new Lazy<ServerRegistrationService>(() => new ServerRegistrationService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_userService == null)
|
||||
_userService = new Lazy<UserService>(() => new UserService(provider, repositoryFactory.Value));
|
||||
if (_userService == null)
|
||||
_userService = new Lazy<IUserService>(() => new UserService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_memberService == null)
|
||||
_memberService = new Lazy<MemberService>(() => new MemberService(provider, repositoryFactory.Value));
|
||||
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_contentService == null)
|
||||
_contentService = new Lazy<ContentService>(() => new ContentService(provider, repositoryFactory.Value, publishingStrategy));
|
||||
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory.Value, publishingStrategy));
|
||||
|
||||
if(_mediaService == null)
|
||||
_mediaService = new Lazy<MediaService>(() => new MediaService(provider, repositoryFactory.Value));
|
||||
if (_mediaService == null)
|
||||
_mediaService = new Lazy<IMediaService>(() => new MediaService(provider, repositoryFactory.Value));
|
||||
|
||||
if(_contentTypeService == null)
|
||||
_contentTypeService = new Lazy<ContentTypeService>(() => new ContentTypeService(provider, repositoryFactory.Value, _contentService.Value, _mediaService.Value));
|
||||
if (_contentTypeService == null)
|
||||
_contentTypeService = new Lazy<IContentTypeService>(() => new ContentTypeService(provider, repositoryFactory.Value, _contentService.Value, _mediaService.Value));
|
||||
|
||||
if(_dataTypeService == null)
|
||||
_dataTypeService = new Lazy<DataTypeService>(() => new DataTypeService(provider, repositoryFactory.Value));
|
||||
if (_dataTypeService == null)
|
||||
_dataTypeService = new Lazy<IDataTypeService>(() => new DataTypeService(provider, repositoryFactory.Value));
|
||||
|
||||
if(_fileService == null)
|
||||
_fileService = new Lazy<FileService>(() => new FileService(fileProvider, provider, repositoryFactory.Value));
|
||||
if (_fileService == null)
|
||||
_fileService = new Lazy<IFileService>(() => new FileService(fileProvider, provider, repositoryFactory.Value));
|
||||
|
||||
if(_localizationService == null)
|
||||
_localizationService = new Lazy<LocalizationService>(() => new LocalizationService(provider, repositoryFactory.Value));
|
||||
if (_localizationService == null)
|
||||
_localizationService = new Lazy<ILocalizationService>(() => new LocalizationService(provider, repositoryFactory.Value));
|
||||
|
||||
if(_packagingService == null)
|
||||
if (_packagingService == null)
|
||||
_packagingService = new Lazy<PackagingService>(() => new PackagingService(_contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value, _fileService.Value, _localizationService.Value, repositoryFactory.Value, provider));
|
||||
|
||||
if (_entityService == null)
|
||||
_entityService = new Lazy<EntityService>(() => new EntityService(provider, repositoryFactory.Value, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value));
|
||||
_entityService = new Lazy<IEntityService>(() => new EntityService(provider, repositoryFactory.Value, _contentService.Value, _contentTypeService.Value, _mediaService.Value, _dataTypeService.Value));
|
||||
|
||||
if(_relationService == null)
|
||||
if (_relationService == null)
|
||||
_relationService = new Lazy<RelationService>(() => new RelationService(provider, repositoryFactory.Value, _entityService.Value));
|
||||
|
||||
if (_memberTypeService == null)
|
||||
_memberTypeService = new Lazy<IMemberTypeService>(() => new MemberTypeService(provider, repositoryFactory.Value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -99,7 +128,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets the <see cref="EntityService"/>
|
||||
/// </summary>
|
||||
public EntityService EntityService
|
||||
public IEntityService EntityService
|
||||
{
|
||||
get { return _entityService.Value; }
|
||||
}
|
||||
@@ -125,7 +154,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public IContentTypeService ContentTypeService
|
||||
{
|
||||
get { return _contentTypeService.Value; }
|
||||
get { return _contentTypeService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -133,7 +162,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public IDataTypeService DataTypeService
|
||||
{
|
||||
get { return _dataTypeService.Value; }
|
||||
get { return _dataTypeService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -141,7 +170,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public IFileService FileService
|
||||
{
|
||||
get { return _fileService.Value; }
|
||||
get { return _fileService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,7 +178,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public ILocalizationService LocalizationService
|
||||
{
|
||||
get { return _localizationService.Value; }
|
||||
get { return _localizationService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -157,7 +186,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public IMediaService MediaService
|
||||
{
|
||||
get { return _mediaService.Value; }
|
||||
get { return _mediaService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -173,7 +202,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
internal IUserService UserService
|
||||
{
|
||||
get { return _userService.Value; }
|
||||
get { return _userService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -183,5 +212,14 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
get { return _memberService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the MemberTypeService
|
||||
/// </summary>
|
||||
internal IMemberTypeService MemberTypeService
|
||||
{
|
||||
get { return _memberTypeService.Value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -203,6 +203,53 @@ namespace Umbraco.Core
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all public properties including inherited properties even for interfaces
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// taken from http://stackoverflow.com/questions/358835/getproperties-to-return-all-properties-for-an-interface-inheritance-hierarchy
|
||||
/// </remarks>
|
||||
public static PropertyInfo[] GetPublicProperties(Type type)
|
||||
{
|
||||
if (type.IsInterface)
|
||||
{
|
||||
var propertyInfos = new List<PropertyInfo>();
|
||||
|
||||
var considered = new List<Type>();
|
||||
var queue = new Queue<Type>();
|
||||
considered.Add(type);
|
||||
queue.Enqueue(type);
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var subType = queue.Dequeue();
|
||||
foreach (var subInterface in subType.GetInterfaces())
|
||||
{
|
||||
if (considered.Contains(subInterface)) continue;
|
||||
|
||||
considered.Add(subInterface);
|
||||
queue.Enqueue(subInterface);
|
||||
}
|
||||
|
||||
var typeProperties = subType.GetProperties(
|
||||
BindingFlags.FlattenHierarchy
|
||||
| BindingFlags.Public
|
||||
| BindingFlags.Instance);
|
||||
|
||||
var newPropertyInfos = typeProperties
|
||||
.Where(x => !propertyInfos.Contains(x));
|
||||
|
||||
propertyInfos.InsertRange(0, newPropertyInfos);
|
||||
}
|
||||
|
||||
return propertyInfos.ToArray();
|
||||
}
|
||||
|
||||
return type.GetProperties(BindingFlags.FlattenHierarchy
|
||||
| BindingFlags.Public | BindingFlags.Instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets (and caches) <see cref="FieldInfo"/> discoverable in the current <see cref="AppDomain"/> for a given <paramref name="type"/>.
|
||||
/// </summary>
|
||||
|
||||
@@ -235,6 +235,7 @@
|
||||
<Compile Include="Models\Membership\UmbracoMembershipMember.cs" />
|
||||
<Compile Include="Models\Membership\UmbracoMembershipUser.cs" />
|
||||
<Compile Include="Models\MemberType.cs" />
|
||||
<Compile Include="Models\PagedResult.cs" />
|
||||
<Compile Include="Models\Rdbms\MemberReadOnlyDto.cs" />
|
||||
<Compile Include="Models\Rdbms\MemberTypeReadOnlyDto.cs" />
|
||||
<Compile Include="Models\Rdbms\PropertyDataReadOnlyDto.cs" />
|
||||
@@ -737,16 +738,19 @@
|
||||
<Compile Include="Services\IContentService.cs" />
|
||||
<Compile Include="Services\IContentTypeService.cs" />
|
||||
<Compile Include="Services\IDataTypeService.cs" />
|
||||
<Compile Include="Services\IEntityService.cs" />
|
||||
<Compile Include="Services\IFileService.cs" />
|
||||
<Compile Include="Services\ILocalizationService.cs" />
|
||||
<Compile Include="Services\IMediaService.cs" />
|
||||
<Compile Include="Services\IMemberService.cs" />
|
||||
<Compile Include="Services\IMembershipUserService.cs" />
|
||||
<Compile Include="Services\IMemberTypeService.cs" />
|
||||
<Compile Include="Services\IService.cs" />
|
||||
<Compile Include="Services\IUserService.cs" />
|
||||
<Compile Include="Services\LocalizationService.cs" />
|
||||
<Compile Include="Services\MediaService.cs" />
|
||||
<Compile Include="Services\MemberService.cs" />
|
||||
<Compile Include="Services\MemberTypeService.cs" />
|
||||
<Compile Include="Services\RelationService.cs" />
|
||||
<Compile Include="Services\ServerRegistrationService.cs" />
|
||||
<Compile Include="Services\PackagingService.cs" />
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using Moq;
|
||||
using Umbraco.Web;
|
||||
|
||||
namespace Umbraco.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class MockTests
|
||||
{
|
||||
|
||||
[Test]
|
||||
public void Can_Create_Empty_App_Context()
|
||||
{
|
||||
var appCtx = new ApplicationContext(false);
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Create_Service_Context()
|
||||
{
|
||||
var svcCtx = new ServiceContext(
|
||||
new Mock<IContentService>().Object,
|
||||
new Mock<IMediaService>().Object,
|
||||
new Mock<IContentTypeService>().Object,
|
||||
new Mock<IDataTypeService>().Object,
|
||||
new Mock<IFileService>().Object,
|
||||
new Mock<ILocalizationService>().Object,
|
||||
new PackagingService(
|
||||
new Mock<IContentService>().Object,
|
||||
new Mock<IContentTypeService>().Object,
|
||||
new Mock<IMediaService>().Object,
|
||||
new Mock<IDataTypeService>().Object,
|
||||
new Mock<IFileService>().Object,
|
||||
new Mock<ILocalizationService>().Object,
|
||||
new RepositoryFactory(true),
|
||||
new Mock<IDatabaseUnitOfWorkProvider>().Object),
|
||||
new Mock<IEntityService>().Object,
|
||||
new RelationService(
|
||||
new Mock<IDatabaseUnitOfWorkProvider>().Object,
|
||||
new RepositoryFactory(true),
|
||||
new Mock<IEntityService>().Object));
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Create_Db_Context()
|
||||
{
|
||||
var dbCtx = new DatabaseContext(new Mock<IDatabaseFactory>().Object);
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Create_App_Context_With_Services()
|
||||
{
|
||||
var appCtx = new ApplicationContext(
|
||||
new DatabaseContext(new Mock<IDatabaseFactory>().Object),
|
||||
new ServiceContext(
|
||||
new Mock<IContentService>().Object,
|
||||
new Mock<IMediaService>().Object,
|
||||
new Mock<IContentTypeService>().Object,
|
||||
new Mock<IDataTypeService>().Object,
|
||||
new Mock<IFileService>().Object,
|
||||
new Mock<ILocalizationService>().Object,
|
||||
new PackagingService(
|
||||
new Mock<IContentService>().Object,
|
||||
new Mock<IContentTypeService>().Object,
|
||||
new Mock<IMediaService>().Object,
|
||||
new Mock<IDataTypeService>().Object,
|
||||
new Mock<IFileService>().Object,
|
||||
new Mock<ILocalizationService>().Object,
|
||||
new RepositoryFactory(true),
|
||||
new Mock<IDatabaseUnitOfWorkProvider>().Object),
|
||||
new Mock<IEntityService>().Object,
|
||||
new RelationService(
|
||||
new Mock<IDatabaseUnitOfWorkProvider>().Object,
|
||||
new RepositoryFactory(true),
|
||||
new Mock<IEntityService>().Object)),
|
||||
false);
|
||||
Assert.Pass();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Assign_App_Context_Singleton()
|
||||
{
|
||||
var appCtx = new ApplicationContext(false);
|
||||
var result = ApplicationContext.EnsureContext(appCtx, true);
|
||||
Assert.AreEqual(appCtx, result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Does_Not_Overwrite_App_Context_Singleton()
|
||||
{
|
||||
ApplicationContext.EnsureContext(new ApplicationContext(false), true);
|
||||
var appCtx = new ApplicationContext(false);
|
||||
var result = ApplicationContext.EnsureContext(appCtx, false);
|
||||
Assert.AreNotEqual(appCtx, result);
|
||||
}
|
||||
|
||||
[NUnit.Framework.Ignore("Need to fix more stuff up, this is ignore because an exception occurs because it wants to ensure we have a resolver initialized - need to make that process better for testability")]
|
||||
[Test]
|
||||
public void Can_Get_Umbraco_Context()
|
||||
{
|
||||
var appCtx = new ApplicationContext(false);
|
||||
ApplicationContext.EnsureContext(appCtx, true);
|
||||
|
||||
var umbCtx = UmbracoContext.EnsureContext(
|
||||
new Mock<HttpContextBase>().Object,
|
||||
appCtx,
|
||||
true);
|
||||
|
||||
Assert.AreEqual(umbCtx, UmbracoContext.Current);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+34
-34
@@ -1,35 +1,35 @@
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Auditing
|
||||
{
|
||||
[TestFixture]
|
||||
public class AuditTests : BaseDatabaseFactoryTest
|
||||
{
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Add_Audit_Entry()
|
||||
{
|
||||
Audit.Add(AuditTypes.System, "This is a System audit trail", 0, -1);
|
||||
|
||||
var dtos = DatabaseContext.Database.Fetch<LogDto>("WHERE id > -1");
|
||||
|
||||
Assert.That(dtos.Any(), Is.True);
|
||||
Assert.That(dtos.First().Comment, Is.EqualTo("This is a System audit trail"));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
}
|
||||
}
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Persistence.Auditing
|
||||
{
|
||||
[TestFixture]
|
||||
public class AuditTests : BaseDatabaseFactoryTest
|
||||
{
|
||||
[SetUp]
|
||||
public override void Initialize()
|
||||
{
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Add_Audit_Entry()
|
||||
{
|
||||
Audit.Add(AuditTypes.System, "This is a System audit trail", 0, -1);
|
||||
|
||||
var dtos = DatabaseContext.Database.Fetch<LogDto>("WHERE id > -1");
|
||||
|
||||
Assert.That(dtos.Any(), Is.True);
|
||||
Assert.That(dtos.First().Comment, Is.EqualTo("This is a System audit trail"));
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public override void TearDown()
|
||||
{
|
||||
base.TearDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MemberRepository_Can_Persist_Member()
|
||||
public void MemberRepository_Can_Persist_Member_Type()
|
||||
{
|
||||
IMemberType sut;
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
@@ -67,6 +67,56 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MemberRepository_Can_Get_All_Member_Types()
|
||||
{
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
using (var repository = CreateRepository(unitOfWork))
|
||||
{
|
||||
var memberType1 = MockedContentTypes.CreateSimpleMemberType();
|
||||
repository.AddOrUpdate(memberType1);
|
||||
unitOfWork.Commit();
|
||||
|
||||
var memberType2 = MockedContentTypes.CreateSimpleMemberType();
|
||||
memberType2.Name = "AnotherType";
|
||||
memberType2.Alias = "anotherType";
|
||||
repository.AddOrUpdate(memberType2);
|
||||
unitOfWork.Commit();
|
||||
|
||||
var result = repository.GetAll();
|
||||
|
||||
//there are 3 because of the Member type created for init data
|
||||
Assert.AreEqual(3, result.Count());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MemberRepository_Can_Get_All_Member_When_No_Properties()
|
||||
{
|
||||
var provider = new PetaPocoUnitOfWorkProvider();
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
using (var repository = CreateRepository(unitOfWork))
|
||||
{
|
||||
var memberType1 = MockedContentTypes.CreateSimpleMemberType();
|
||||
memberType1.PropertyTypeCollection.Clear();
|
||||
repository.AddOrUpdate(memberType1);
|
||||
unitOfWork.Commit();
|
||||
|
||||
var memberType2 = MockedContentTypes.CreateSimpleMemberType();
|
||||
memberType2.PropertyTypeCollection.Clear();
|
||||
memberType2.Name = "AnotherType";
|
||||
memberType2.Alias = "anotherType";
|
||||
repository.AddOrUpdate(memberType2);
|
||||
unitOfWork.Commit();
|
||||
|
||||
var result = repository.GetAll();
|
||||
|
||||
//there are 3 because of the Member type created for init data
|
||||
Assert.AreEqual(3, result.Count());
|
||||
}
|
||||
}
|
||||
|
||||
[Test, NUnit.Framework.Ignore]
|
||||
public void MemberTypeRepository_Can_Get_MemberType_By_Id()
|
||||
{
|
||||
|
||||
@@ -3,8 +3,8 @@ using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Stubs;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Tests.TestHelpers.Stubs;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Models;
|
||||
using Umbraco.Web.Mvc;
|
||||
|
||||
@@ -3,9 +3,9 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Tests.Stubs;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using System.Configuration;
|
||||
using Umbraco.Tests.TestHelpers.Stubs;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache.XmlPublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -21,7 +21,6 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.PropertyEditors;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.Stubs;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache;
|
||||
using Umbraco.Web.PublishedCache.XmlPublishedCache;
|
||||
|
||||
@@ -4,7 +4,7 @@ using System.Web.Routing;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Tests.Stubs;
|
||||
using Umbraco.Tests.TestHelpers.Stubs;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.PublishedCache.XmlPublishedCache;
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
@@ -14,7 +14,6 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Publishing;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Tests.PublishedContent;
|
||||
using Umbraco.Tests.Stubs;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Routing;
|
||||
using umbraco.BusinessLogic;
|
||||
|
||||
+11
-11
@@ -1,12 +1,12 @@
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Tests.Stubs
|
||||
{
|
||||
internal class FakeLastChanceFinder : IContentFinder
|
||||
{
|
||||
public bool TryFindContent(PublishedContentRequest docRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
using Umbraco.Web.Routing;
|
||||
|
||||
namespace Umbraco.Tests.TestHelpers.Stubs
|
||||
{
|
||||
internal class FakeLastChanceFinder : IContentFinder
|
||||
{
|
||||
public bool TryFindContent(PublishedContentRequest docRequest)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
+39
-39
@@ -1,40 +1,40 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.Stubs
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in place of the UmbracoControllerFactory which relies on BuildManager which throws exceptions in a unit test context
|
||||
/// </summary>
|
||||
internal class TestControllerFactory : IControllerFactory
|
||||
{
|
||||
|
||||
public IController CreateController(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
var types = TypeFinder.FindClassesOfType<ControllerBase>(new[] { Assembly.GetExecutingAssembly() });
|
||||
|
||||
var controllerTypes = types.Where(x => x.Name.Equals(controllerName + "Controller", StringComparison.InvariantCultureIgnoreCase));
|
||||
var t = controllerTypes.SingleOrDefault();
|
||||
|
||||
if (t == null)
|
||||
return null;
|
||||
|
||||
return Activator.CreateInstance(t) as IController;
|
||||
}
|
||||
|
||||
public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return SessionStateBehavior.Disabled;
|
||||
}
|
||||
|
||||
public void ReleaseController(IController controller)
|
||||
{
|
||||
controller.DisposeIfDisposable();
|
||||
}
|
||||
}
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using System.Web.SessionState;
|
||||
using Umbraco.Core;
|
||||
|
||||
namespace Umbraco.Tests.TestHelpers.Stubs
|
||||
{
|
||||
/// <summary>
|
||||
/// Used in place of the UmbracoControllerFactory which relies on BuildManager which throws exceptions in a unit test context
|
||||
/// </summary>
|
||||
internal class TestControllerFactory : IControllerFactory
|
||||
{
|
||||
|
||||
public IController CreateController(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
var types = TypeFinder.FindClassesOfType<ControllerBase>(new[] { Assembly.GetExecutingAssembly() });
|
||||
|
||||
var controllerTypes = types.Where(x => x.Name.Equals(controllerName + "Controller", StringComparison.InvariantCultureIgnoreCase));
|
||||
var t = controllerTypes.SingleOrDefault();
|
||||
|
||||
if (t == null)
|
||||
return null;
|
||||
|
||||
return Activator.CreateInstance(t) as IController;
|
||||
}
|
||||
|
||||
public System.Web.SessionState.SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
|
||||
{
|
||||
return SessionStateBehavior.Disabled;
|
||||
}
|
||||
|
||||
public void ReleaseController(IController controller)
|
||||
{
|
||||
controller.DisposeIfDisposable();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,8 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="AttemptTests.cs" />
|
||||
<Compile Include="Auditing\AuditTests.cs" />
|
||||
<Compile Include="MockTests.cs" />
|
||||
<Compile Include="Persistence\Auditing\AuditTests.cs" />
|
||||
<Compile Include="BootManagers\CoreBootManagerTests.cs" />
|
||||
<Compile Include="BusinessLogic\DictionaryTest.cs" />
|
||||
<Compile Include="Cache\CacheHelperTests.cs" />
|
||||
@@ -359,7 +360,7 @@
|
||||
<Compile Include="Routing\NiceUrlProviderTests.cs" />
|
||||
<Compile Include="Routing\RenderRouteHandlerTests.cs" />
|
||||
<Compile Include="Routing\RouteTestExtensions.cs" />
|
||||
<Compile Include="Stubs\TestControllerFactory.cs" />
|
||||
<Compile Include="TestHelpers\Stubs\TestControllerFactory.cs" />
|
||||
<Compile Include="TestHelpers\BaseUsingSqlCeSyntax.cs" />
|
||||
<Compile Include="TestHelpers\BaseWebTest.cs" />
|
||||
<Compile Include="TestHelpers\BaseDatabaseTest.cs" />
|
||||
@@ -395,7 +396,7 @@
|
||||
<Compile Include="Resolvers\PackageActionsResolverTests.cs" />
|
||||
<Compile Include="PluginManagerExtensions.cs" />
|
||||
<Compile Include="PluginManagerTests.cs" />
|
||||
<Compile Include="Stubs\FakeLastChanceFinder.cs" />
|
||||
<Compile Include="TestHelpers\Stubs\FakeLastChanceFinder.cs" />
|
||||
<Compile Include="TestHelpers\TestHelper.cs" />
|
||||
<Compile Include="EnumerableExtensionsTests.cs" />
|
||||
<Compile Include="IO\AbstractFileSystemTests.cs" />
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Configuration.Provider;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
@@ -8,6 +10,7 @@ using System.Web.Hosting;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
@@ -254,8 +257,9 @@ namespace Umbraco.Web.Security.Providers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new membership user to the data source.
|
||||
/// Adds a new membership user to the data source with the specified member type
|
||||
/// </summary>
|
||||
/// <param name="memberType">A specific member type to create the member for</param>
|
||||
/// <param name="username">The user name for the new user.</param>
|
||||
/// <param name="password">The password for the new user.</param>
|
||||
/// <param name="email">The e-mail address for the new user.</param>
|
||||
@@ -267,16 +271,16 @@ namespace Umbraco.Web.Security.Providers
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Web.Security.MembershipUser"></see> object populated with the information for the newly created user.
|
||||
/// </returns>
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer,
|
||||
public MembershipUser CreateUser(string memberType, string username, string password, string email, string passwordQuestion, string passwordAnswer,
|
||||
bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
LogHelper.Debug<MembersMembershipProvider>("Member signup requested: username -> " + username + ". email -> " +email);
|
||||
LogHelper.Debug<MembersMembershipProvider>("Member signup requested: username -> " + username + ". email -> " + email);
|
||||
|
||||
// Validate password
|
||||
if (IsPasswordValid(password) == false)
|
||||
{
|
||||
status = MembershipCreateStatus.InvalidPassword;
|
||||
return null;
|
||||
status = MembershipCreateStatus.InvalidPassword;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Validate email
|
||||
@@ -324,18 +328,41 @@ namespace Umbraco.Web.Security.Providers
|
||||
return null;
|
||||
}
|
||||
|
||||
var member = MemberService.CreateMember(email, username, password, DefaultMemberTypeAlias);
|
||||
var member = MemberService.CreateMember(email, username, password, memberType);
|
||||
|
||||
member.IsApproved = isApproved;
|
||||
member.PasswordQuestion = passwordQuestion;
|
||||
member.PasswordAnswer = passwordAnswer;
|
||||
|
||||
|
||||
//encrypts/hashes the password depending on the settings
|
||||
member.Password = EncryptOrHashPassword(member.Password);
|
||||
|
||||
MemberService.Save(member);
|
||||
|
||||
|
||||
status = MembershipCreateStatus.Success;
|
||||
return member.AsConcreteMembershipUser();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new membership user to the data source.
|
||||
/// </summary>
|
||||
/// <param name="username">The user name for the new user.</param>
|
||||
/// <param name="password">The password for the new user.</param>
|
||||
/// <param name="email">The e-mail address for the new user.</param>
|
||||
/// <param name="passwordQuestion">The password question for the new user.</param>
|
||||
/// <param name="passwordAnswer">The password answer for the new user</param>
|
||||
/// <param name="isApproved">Whether or not the new user is approved to be validated.</param>
|
||||
/// <param name="providerUserKey">The unique identifier from the membership data source for the user.</param>
|
||||
/// <param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus"></see> enumeration value indicating whether the user was created successfully.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Web.Security.MembershipUser"></see> object populated with the information for the newly created user.
|
||||
/// </returns>
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer,
|
||||
bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
return CreateUser(DefaultMemberTypeAlias, username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes a request to update the password question and answer for a membership user.
|
||||
/// </summary>
|
||||
@@ -360,7 +387,7 @@ namespace Umbraco.Web.Security.Providers
|
||||
}
|
||||
|
||||
var member = MemberService.GetByUsername(username);
|
||||
var encodedPassword = EncodePassword(password);
|
||||
var encodedPassword = EncryptOrHashPassword(password);
|
||||
|
||||
if (member.Password == encodedPassword)
|
||||
{
|
||||
@@ -427,12 +454,12 @@ namespace Umbraco.Web.Security.Providers
|
||||
var member = MemberService.GetByUsername(username);
|
||||
if (member == null) return false;
|
||||
|
||||
var encodedPassword = EncodePassword(oldPassword);
|
||||
var encodedPassword = EncryptOrHashPassword(oldPassword);
|
||||
|
||||
if (member.Password == encodedPassword)
|
||||
{
|
||||
|
||||
member.Password = EncodePassword(newPassword);
|
||||
member.Password = EncryptOrHashPassword(newPassword);
|
||||
MemberService.Save(member);
|
||||
|
||||
return true;
|
||||
@@ -464,7 +491,7 @@ namespace Umbraco.Web.Security.Providers
|
||||
if (_requiresQuestionAndAnswer == false || (_requiresQuestionAndAnswer && answer == member.PasswordAnswer))
|
||||
{
|
||||
member.Password =
|
||||
EncodePassword(Membership.GeneratePassword(_minRequiredPasswordLength,
|
||||
EncryptOrHashPassword(Membership.GeneratePassword(_minRequiredPasswordLength,
|
||||
_minRequiredNonAlphanumericCharacters));
|
||||
MemberService.Save(member);
|
||||
}
|
||||
@@ -505,7 +532,7 @@ namespace Umbraco.Web.Security.Providers
|
||||
if (member.IsLockedOut)
|
||||
throw new ProviderException("The member is locked out.");
|
||||
|
||||
var encodedPassword = EncodePassword(password);
|
||||
var encodedPassword = EncryptOrHashPassword(password);
|
||||
|
||||
var authenticated = (encodedPassword == member.Password);
|
||||
|
||||
@@ -687,7 +714,16 @@ namespace Umbraco.Web.Security.Providers
|
||||
/// </returns>
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
var byEmail = MemberService.FindMembersByEmail(emailToMatch).ToArray();
|
||||
totalRecords = byEmail.Length;
|
||||
var pagedResult = new PagedResult<IMember>(totalRecords, pageIndex, pageSize);
|
||||
|
||||
var collection = new MembershipUserCollection();
|
||||
foreach (var m in byEmail.Skip(pagedResult.SkipSize).Take(pageSize))
|
||||
{
|
||||
collection.Add(m.AsConcreteMembershipUser());
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
#region Private methods
|
||||
@@ -714,11 +750,9 @@ namespace Umbraco.Web.Security.Providers
|
||||
|
||||
private bool IsEmaiValid(string email)
|
||||
{
|
||||
const string pattern = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|"
|
||||
+ @"([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)"
|
||||
+ @"@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$";
|
||||
var validator = new EmailAddressAttribute();
|
||||
|
||||
return Regex.IsMatch(email, pattern, RegexOptions.IgnoreCase | RegexOptions.Compiled);
|
||||
return validator.IsValid(email);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -726,7 +760,7 @@ namespace Umbraco.Web.Security.Providers
|
||||
/// </summary>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>The encoded password.</returns>
|
||||
private string EncodePassword(string password)
|
||||
private string EncryptOrHashPassword(string password)
|
||||
{
|
||||
var encodedPassword = password;
|
||||
switch (PasswordFormat)
|
||||
|
||||
@@ -2,8 +2,10 @@ using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using umbraco.cms.businesslogic.language;
|
||||
using umbraco.DataLayer;
|
||||
using umbraco.BusinessLogic;
|
||||
@@ -19,7 +21,7 @@ namespace umbraco.cms.businesslogic
|
||||
public class Dictionary
|
||||
{
|
||||
private static volatile bool _cacheIsEnsured = false;
|
||||
private static readonly object Locker = new object();
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
private static readonly ConcurrentDictionary<string, DictionaryItem> DictionaryItems = new ConcurrentDictionary<string, DictionaryItem>();
|
||||
private static readonly Guid TopLevelParent = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
|
||||
|
||||
@@ -33,30 +35,28 @@ namespace umbraco.cms.businesslogic
|
||||
/// </summary>
|
||||
private static void EnsureCache()
|
||||
{
|
||||
if (!_cacheIsEnsured)
|
||||
using (var lck = new UpgradeableReadLock(Locker))
|
||||
{
|
||||
lock (Locker)
|
||||
if (_cacheIsEnsured) return;
|
||||
|
||||
lck.UpgradeToWriteLock();
|
||||
|
||||
using (var dr = SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary"))
|
||||
{
|
||||
if (!_cacheIsEnsured)
|
||||
while (dr.Read())
|
||||
{
|
||||
using (IRecordsReader dr = SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary"))
|
||||
{
|
||||
while (dr.Read())
|
||||
{
|
||||
//create new dictionaryitem object and put in cache
|
||||
var item = new DictionaryItem(dr.GetInt("pk"),
|
||||
dr.GetString("key"),
|
||||
dr.GetGuid("id"),
|
||||
dr.GetGuid("parent"));
|
||||
//create new dictionaryitem object and put in cache
|
||||
var item = new DictionaryItem(dr.GetInt("pk"),
|
||||
dr.GetString("key"),
|
||||
dr.GetGuid("id"),
|
||||
dr.GetGuid("parent"));
|
||||
|
||||
DictionaryItems.TryAdd(item.key, item);
|
||||
}
|
||||
}
|
||||
|
||||
_cacheIsEnsured = true;
|
||||
DictionaryItems.TryAdd(item.key, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_cacheIsEnsured = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,9 +64,12 @@ namespace umbraco.cms.businesslogic
|
||||
/// </summary>
|
||||
internal static void ClearCache()
|
||||
{
|
||||
DictionaryItems.Clear();
|
||||
//ensure the flag is reset so that EnsureCache will re-cache everything
|
||||
_cacheIsEnsured = false;
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
DictionaryItems.Clear();
|
||||
//ensure the flag is reset so that EnsureCache will re-cache everything
|
||||
_cacheIsEnsured = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -30,8 +30,8 @@ namespace umbraco.cms.businesslogic.member
|
||||
public class Member : Content
|
||||
{
|
||||
#region Constants and static members
|
||||
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
|
||||
public static readonly string UmbracoRoleProviderName = "UmbracoRoleProvider";
|
||||
public static readonly string UmbracoMemberProviderName = Constants.Conventions.Member.UmbracoMemberProviderName;
|
||||
public static readonly string UmbracoRoleProviderName = Constants.Conventions.Member.UmbracoRoleProviderName;
|
||||
public static readonly Guid _objectType = new Guid(Constants.ObjectTypes.Member);
|
||||
|
||||
private static readonly object m_Locker = new object();
|
||||
@@ -211,6 +211,8 @@ namespace umbraco.cms.businesslogic.member
|
||||
/// <returns>The new member</returns>
|
||||
public static Member MakeNew(string Name, string LoginName, string Email, MemberType mbt, User u)
|
||||
{
|
||||
if (mbt == null) throw new ArgumentNullException("mbt");
|
||||
|
||||
var loginName = (!String.IsNullOrEmpty(LoginName)) ? LoginName : Name;
|
||||
|
||||
if (String.IsNullOrEmpty(loginName))
|
||||
|
||||
@@ -1,20 +1,26 @@
|
||||
#region namespace
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Security;
|
||||
using System.Configuration;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using umbraco.BusinessLogic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Web.Util;
|
||||
using System.Collections.Specialized;
|
||||
using System.Configuration.Provider;
|
||||
using umbraco.cms.businesslogic;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
|
||||
using System.Security;
|
||||
using System.Security.Permissions;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Member = umbraco.cms.businesslogic.member.Member;
|
||||
using MemberType = umbraco.cms.businesslogic.member.MemberType;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using User = umbraco.BusinessLogic.User;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace umbraco.providers.members
|
||||
@@ -354,6 +360,68 @@ namespace umbraco.providers.members
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new membership user to the data source.
|
||||
/// </summary>
|
||||
/// <param name="memberTypeAlias"></param>
|
||||
/// <param name="username">The user name for the new user.</param>
|
||||
/// <param name="password">The password for the new user.</param>
|
||||
/// <param name="email">The e-mail address for the new user.</param>
|
||||
/// <param name="passwordQuestion">The password question for the new user.</param>
|
||||
/// <param name="passwordAnswer">The password answer for the new user</param>
|
||||
/// <param name="isApproved">Whether or not the new user is approved to be validated.</param>
|
||||
/// <param name="providerUserKey">The unique identifier from the membership data source for the user.</param>
|
||||
/// <param name="status">A <see cref="T:System.Web.Security.MembershipCreateStatus"></see> enumeration value indicating whether the user was created successfully.</param>
|
||||
/// <returns>
|
||||
/// A <see cref="T:System.Web.Security.MembershipUser"></see> object populated with the information for the newly created user.
|
||||
/// </returns>
|
||||
public MembershipUser CreateUser(string memberTypeAlias, string username, string password, string email, string passwordQuestion,
|
||||
string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
if (Member.GetMemberFromLoginName(username) != null)
|
||||
status = MembershipCreateStatus.DuplicateUserName;
|
||||
else if (Member.GetMemberFromEmail(email) != null && RequiresUniqueEmail)
|
||||
status = MembershipCreateStatus.DuplicateEmail;
|
||||
else
|
||||
{
|
||||
var memberType = MemberType.GetByAlias(memberTypeAlias);
|
||||
if (memberType == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not find a member type with alias " + memberTypeAlias + ". Ensure your membership provider configuration is up to date and that the default member type exists.");
|
||||
}
|
||||
|
||||
Member m = Member.MakeNew(username, email, memberType, User.GetUser(0));
|
||||
m.Password = password;
|
||||
|
||||
MembershipUser mUser =
|
||||
ConvertToMembershipUser(m);
|
||||
|
||||
// custom fields
|
||||
if (!String.IsNullOrEmpty(m_PasswordRetrievalQuestionPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, passwordQuestion);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_PasswordRetrievalAnswerPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, passwordAnswer);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_ApprovedPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_ApprovedPropertyTypeAlias, isApproved);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_LastLoginPropertyTypeAlias))
|
||||
{
|
||||
mUser.LastActivityDate = DateTime.Now;
|
||||
UpdateMemberProperty(m, m_LastLoginPropertyTypeAlias, mUser.LastActivityDate);
|
||||
}
|
||||
|
||||
// save
|
||||
m.Save();
|
||||
|
||||
status = MembershipCreateStatus.Success;
|
||||
|
||||
return mUser;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new membership user to the data source.
|
||||
/// </summary>
|
||||
@@ -371,41 +439,7 @@ namespace umbraco.providers.members
|
||||
public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion,
|
||||
string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
|
||||
{
|
||||
if (Member.GetMemberFromLoginName(username) != null)
|
||||
status = MembershipCreateStatus.DuplicateUserName;
|
||||
else if (Member.GetMemberFromEmail(email) != null && RequiresUniqueEmail)
|
||||
status = MembershipCreateStatus.DuplicateEmail;
|
||||
else
|
||||
{
|
||||
Member m = Member.MakeNew(username, email, MemberType.GetByAlias(m_DefaultMemberTypeAlias), User.GetUser(0));
|
||||
m.Password = password;
|
||||
|
||||
MembershipUser mUser =
|
||||
ConvertToMembershipUser(m);
|
||||
|
||||
// custom fields
|
||||
if (!String.IsNullOrEmpty(m_PasswordRetrievalQuestionPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_PasswordRetrievalQuestionPropertyTypeAlias, passwordQuestion);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_PasswordRetrievalAnswerPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_PasswordRetrievalAnswerPropertyTypeAlias, passwordAnswer);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_ApprovedPropertyTypeAlias))
|
||||
UpdateMemberProperty(m, m_ApprovedPropertyTypeAlias, isApproved);
|
||||
|
||||
if (!String.IsNullOrEmpty(m_LastLoginPropertyTypeAlias)) {
|
||||
mUser.LastActivityDate = DateTime.Now;
|
||||
UpdateMemberProperty(m, m_LastLoginPropertyTypeAlias, mUser.LastActivityDate);
|
||||
}
|
||||
|
||||
// save
|
||||
m.Save();
|
||||
|
||||
status = MembershipCreateStatus.Success;
|
||||
|
||||
return mUser;
|
||||
}
|
||||
return null;
|
||||
return CreateUser(m_DefaultMemberTypeAlias, username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -439,7 +473,16 @@ namespace umbraco.providers.members
|
||||
/// </returns>
|
||||
public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
var byEmail = ApplicationContext.Current.Services.MemberService.FindMembersByEmail(emailToMatch).ToArray();
|
||||
totalRecords = byEmail.Length;
|
||||
var pagedResult = new PagedResult<IMember>(totalRecords, pageIndex, pageSize);
|
||||
|
||||
var collection = new MembershipUserCollection();
|
||||
foreach (var m in byEmail.Skip(pagedResult.SkipSize).Take(pageSize))
|
||||
{
|
||||
collection.Add(m.AsConcreteMembershipUser());
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -751,7 +794,7 @@ namespace umbraco.providers.members
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the specified user name and password exist in the data source.
|
||||
/// </summary>
|
||||
@@ -973,6 +1016,7 @@ namespace umbraco.providers.members
|
||||
DateTime.Now, DateTime.Now, DateTime.Now);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,6 +97,10 @@
|
||||
<Project>{ccd75ec3-63db-4184-b49d-51c1dd337230}</Project>
|
||||
<Name>umbraco.cms</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Umbraco.Core\Umbraco.Core.csproj">
|
||||
<Project>{31785bc3-256c-4613-b2f5-a1b0bdded8c1}</Project>
|
||||
<Name>Umbraco.Core</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\umbraco.datalayer\umbraco.datalayer.csproj">
|
||||
<Project>{C7CB79F0-1C97-4B33-BFA7-00731B579AE2}</Project>
|
||||
<Name>umbraco.datalayer</Name>
|
||||
|
||||
+4
-3
@@ -1,7 +1,5 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.20827.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
# Visual Studio 2012
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{2849E9D4-3B4E-40A3-A309-F3CB4F0E125F}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
..\build\Build.bat = ..\build\Build.bat
|
||||
@@ -159,4 +157,7 @@ Global
|
||||
{73529637-28F5-419C-A6BB-D094E39DE614} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}
|
||||
{B555AAE6-0F56-442F-AC9F-EF497DB38DE7} = {DD32977B-EF54-475B-9A1B-B97A502C6E58}
|
||||
EndGlobalSection
|
||||
GlobalSection(Performance) = preSolution
|
||||
HasPerformanceSessions = true
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
||||
Reference in New Issue
Block a user