Compare commits
171 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d3eef1124 | |||
| 3e6e6faf03 | |||
| b3f18bc677 | |||
| a48fe40675 | |||
| 1511ad58b2 | |||
| 2e9b751174 | |||
| d61ab97be3 | |||
| dd40d73b71 | |||
| 068bca84b7 | |||
| 0fda528b94 | |||
| 3552f63d87 | |||
| 01d04fde37 | |||
| 7f8c526136 | |||
| ea4be14f0c | |||
| 20df48e2f0 | |||
| 2c0f6f975c | |||
| fa7f91b39d | |||
| 72c5853fb1 | |||
| f03b1a22f9 | |||
| e7fb6e5beb | |||
| d0cc93d6a2 | |||
| 4adc2562b1 | |||
| ba6878666c | |||
| 792ab8d088 | |||
| 3d4409e52a | |||
| acd377956f | |||
| 3b6dcc3421 | |||
| cec4d41df7 | |||
| ff0bcffefa | |||
| 5dbc72897a | |||
| 83736bec01 | |||
| 2f953c3819 | |||
| 026d040a62 | |||
| 7747b8f64f | |||
| feb9f40237 | |||
| 651182f5de | |||
| 22b15a06f6 | |||
| cb09795280 | |||
| a5637af2d8 | |||
| ac59c5deb0 | |||
| 683ddf6d34 | |||
| eda33b1ac4 | |||
| ed0f884348 | |||
| b561351340 | |||
| 690ab29863 | |||
| 27cb1d5223 | |||
| c677f36f08 | |||
| 750f7a6b33 | |||
| dea804b402 | |||
| 3803d1d7da | |||
| 3e67b3034d | |||
| 1ada5210ad | |||
| 9a608674eb | |||
| 7dae412a29 | |||
| a1067e676f | |||
| ce649f54d7 | |||
| d159792256 | |||
| 606b5aa60a | |||
| a206652a0d | |||
| 545040fdf0 | |||
| 40d1a09609 | |||
| 2e25bc8fdb | |||
| 1618ac86b8 | |||
| a4adbca12c | |||
| 8728e2f918 | |||
| cd53682ddb | |||
| e2d5fbf545 | |||
| d339e7c814 | |||
| 078deb704b | |||
| 6858eb3330 | |||
| e267b7700a | |||
| 1e45abe71e | |||
| a556b4ed21 | |||
| 953c711ca4 | |||
| f06c9e8235 | |||
| f1a439e851 | |||
| a0e496e589 | |||
| e0dcc3afbc | |||
| 3634a77d61 | |||
| 846f4b5b6c | |||
| 2869f17eff | |||
| feefb052fd | |||
| 4d2d9156ba | |||
| 82ba1a24a3 | |||
| 357db9d0b6 | |||
| 61766287bc | |||
| ffbf8b2fd6 | |||
| f7a703195c | |||
| 509be9b431 | |||
| 10ef5eb7bc | |||
| 2849ecadb7 | |||
| 697f93c3ce | |||
| 18121e8726 | |||
| 81cdc71145 | |||
| 4069fc8d1f | |||
| 0a80c39962 | |||
| edee8134c2 | |||
| 30a73c0886 | |||
| f5ee02a3e9 | |||
| 9827b40bea | |||
| f9323c85e4 | |||
| 2677672e50 | |||
| a38e0dcf86 | |||
| fdd7227494 | |||
| 6b74e14cdd | |||
| 9d7b3b965a | |||
| 806008a7e9 | |||
| 45fa192c95 | |||
| 92235128f1 | |||
| 7622937cfd | |||
| bf41694572 | |||
| 7b897ce64c | |||
| 1ca950f721 | |||
| ffba271fd0 | |||
| ec08d3e910 | |||
| 0bfd032fad | |||
| 2bb58b6fca | |||
| 4d2d656b3d | |||
| fa625d72f9 | |||
| 1991380e02 | |||
| 3b8d6dc2c7 | |||
| 1faeb76c27 | |||
| 3a513668fd | |||
| 3ef51d7357 | |||
| 8b553dd067 | |||
| ccaf82d797 | |||
| f28ae52ae3 | |||
| cfd0973f00 | |||
| 1bfdd83ba7 | |||
| 6fefcacc61 | |||
| 3b639e61b2 | |||
| 9959ff667e | |||
| de1f86c7a1 | |||
| 28d8fd0531 | |||
| e4e76eb0bf | |||
| 677cc8c8fd | |||
| 3fa5c4e0b2 | |||
| 360393c464 | |||
| d3daf88a8d | |||
| 7a99ebd6d9 | |||
| a7298e2e5a | |||
| 15d7443c61 | |||
| f2b7e27b34 | |||
| 690d08aa8c | |||
| 6719d70cc0 | |||
| 3cdcf513ec | |||
| 43c426b46c | |||
| e2ac82abca | |||
| 64d1a484bd | |||
| 585b42af48 | |||
| 7c4412fc4b | |||
| 0be8039c8f | |||
| 668265f1ac | |||
| 4735f27a66 | |||
| 6377b9aa50 | |||
| 011be60205 | |||
| a272675ed8 | |||
| 80697cf9ca | |||
| f4534aa94c | |||
| 56dec485a5 | |||
| ffde0f48cf | |||
| 2956aee4e3 | |||
| 9bd8d729fa | |||
| fb9569d914 | |||
| 47974d49fe | |||
| 3f8b3031c2 | |||
| 7da41594fd | |||
| 9796b30bbb | |||
| c2c4763faa | |||
| c062d3b71b | |||
| ed83fb8216 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
@ECHO OFF
|
||||
SET release=6.2.0
|
||||
SET comment=
|
||||
SET comment=beta
|
||||
SET version=%release%
|
||||
|
||||
IF [%comment%] EQU [] (SET version=%release%) ELSE (SET version=%release%-%comment%)
|
||||
|
||||
@@ -160,5 +160,15 @@ namespace Umbraco.Core
|
||||
{
|
||||
return new Attempt<T>(condition, result, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Implicity operator to check if the attempt was successful without having to access the 'success' property
|
||||
/// </summary>
|
||||
/// <param name="a"></param>
|
||||
/// <returns></returns>
|
||||
public static implicit operator bool(Attempt<T> a)
|
||||
{
|
||||
return a.Success;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,5 @@
|
||||
using System;
|
||||
|
||||
namespace Umbraco.Core.Cache
|
||||
{
|
||||
|
||||
@@ -9,6 +11,7 @@ namespace Umbraco.Core.Cache
|
||||
public const string ApplicationTreeCacheKey = "ApplicationTreeCache";
|
||||
public const string ApplicationsCacheKey = "ApplicationCache";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserTypeCacheKey = "UserTypeCache";
|
||||
|
||||
public const string ContentItemCacheKey = "contentItem";
|
||||
@@ -24,13 +27,16 @@ namespace Umbraco.Core.Cache
|
||||
|
||||
public const string MemberLibraryCacheKey = "UL_GetMember";
|
||||
public const string MemberBusinessLogicCacheKey = "MemberCacheItem_";
|
||||
|
||||
|
||||
public const string TemplateFrontEndCacheKey = "template";
|
||||
public const string TemplateBusinessLogicCacheKey = "UmbracoTemplateCache";
|
||||
|
||||
public const string UserContextCacheKey = "UmbracoUserContext";
|
||||
public const string UserContextTimeoutCacheKey = "UmbracoUserContextTimeout";
|
||||
|
||||
[Obsolete("This is no longer used and will be removed from the codebase in the future")]
|
||||
public const string UserCacheKey = "UmbracoUser";
|
||||
|
||||
public const string UserPermissionsCacheKey = "UmbracoUserPermissions";
|
||||
|
||||
public const string ContentTypeCacheKey = "UmbracoContentType";
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace Umbraco.Core
|
||||
/// <summary>
|
||||
/// Gets the <see cref="ICacheRefresher"/> implementations.
|
||||
/// </summary>
|
||||
public IEnumerable<ICacheRefresher> CacheResolvers
|
||||
public IEnumerable<ICacheRefresher> CacheRefreshers
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace Umbraco.Core.Configuration
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Increases the version number in ClientDependency.config by 1
|
||||
/// Changes the version number in ClientDependency.config to a random value to avoid stale caches
|
||||
/// </summary>
|
||||
internal bool IncreaseVersionNumber()
|
||||
{
|
||||
@@ -28,9 +28,9 @@ namespace Umbraco.Core.Configuration
|
||||
|
||||
var versionAttribute = clientDependencyConfigXml.Root.Attribute("version");
|
||||
|
||||
int oldVersion;
|
||||
int.TryParse(versionAttribute.Value, out oldVersion);
|
||||
var newVersion = oldVersion + 1;
|
||||
//Set the new version to the hashcode of now
|
||||
var oldVersion = versionAttribute.Value;
|
||||
var newVersion = Math.Abs(DateTime.UtcNow.GetHashCode());
|
||||
|
||||
versionAttribute.SetValue(newVersion);
|
||||
clientDependencyConfigXml.Save(_fileName, SaveOptions.DisableFormatting);
|
||||
|
||||
@@ -7,6 +7,7 @@ using System.Web.Configuration;
|
||||
using System.Web.Routing;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using System.Xml.XPath;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
@@ -255,7 +256,38 @@ namespace Umbraco.Core.Configuration
|
||||
SaveSetting("umbracoConfigurationStatus", value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco members membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfiguredMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.Member.UmbracoMemberProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Umbraco users membership providers' useLegacyEncoding state. This will return a boolean
|
||||
/// </summary>
|
||||
/// <value>The useLegacyEncoding status.</value>
|
||||
public static bool UmbracoUsersMembershipProviderLegacyEncoding
|
||||
{
|
||||
get
|
||||
{
|
||||
return ConfiguredMembershipProvidersLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName);
|
||||
}
|
||||
set
|
||||
{
|
||||
SetMembershipProvidersLegacyEncoding(Constants.Conventions.User.UmbracoUsersProviderName, value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a setting into the configuration file.
|
||||
@@ -315,6 +347,43 @@ namespace Umbraco.Core.Configuration
|
||||
return fileName;
|
||||
}
|
||||
|
||||
private static void SetMembershipProvidersLegacyEncoding(string providerName, bool useLegacyEncoding)
|
||||
{
|
||||
var webConfigFilename = GetFullWebConfigFileName();
|
||||
var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace);
|
||||
|
||||
var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList();
|
||||
|
||||
if (membershipConfigs.Any() == false)
|
||||
return;
|
||||
|
||||
var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName);
|
||||
|
||||
if (provider == null)
|
||||
return;
|
||||
|
||||
provider.SetAttributeValue("useLegacyEncoding", useLegacyEncoding);
|
||||
|
||||
webConfigXml.Save(webConfigFilename, SaveOptions.DisableFormatting);
|
||||
}
|
||||
|
||||
private static bool ConfiguredMembershipProvidersLegacyEncoding(string providerName)
|
||||
{
|
||||
var webConfigFilename = GetFullWebConfigFileName();
|
||||
var webConfigXml = XDocument.Load(webConfigFilename, LoadOptions.PreserveWhitespace);
|
||||
|
||||
var membershipConfigs = webConfigXml.XPathSelectElements("configuration/system.web/membership/providers/add").ToList();
|
||||
|
||||
var provider = membershipConfigs.SingleOrDefault(c => c.Attribute("name") != null && c.Attribute("name").Value == providerName);
|
||||
|
||||
var useLegacyEncodingAttribute = provider.Attribute("useLegacyEncoding");
|
||||
|
||||
bool useLegacyEncoding;
|
||||
bool.TryParse(useLegacyEncodingAttribute.Value, out useLegacyEncoding);
|
||||
|
||||
return useLegacyEncoding;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the full path to root.
|
||||
/// </summary>
|
||||
|
||||
@@ -658,7 +658,7 @@ namespace Umbraco.Core.Configuration
|
||||
{
|
||||
string defaultProvider = GetKey("/settings/providers/users/DefaultBackofficeProvider");
|
||||
if (String.IsNullOrEmpty(defaultProvider))
|
||||
defaultProvider = "UsersMembershipProvider";
|
||||
defaultProvider = Constants.Conventions.User.UmbracoUsersProviderName;
|
||||
|
||||
return defaultProvider;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Core.Configuration
|
||||
/// Gets the version comment (like beta or RC).
|
||||
/// </summary>
|
||||
/// <value>The version comment.</value>
|
||||
public static string CurrentComment { get { return ""; } }
|
||||
public static string CurrentComment { get { return "beta"; } }
|
||||
|
||||
// Get the version of the umbraco.dll by looking at a class in that dll
|
||||
// Had to do it like this due to medium trust issues, see: http://haacked.com/archive/2010/11/04/assembly-location-and-medium-trust.aspx
|
||||
|
||||
@@ -85,7 +85,7 @@ namespace Umbraco.Core
|
||||
|
||||
/// <summary>
|
||||
/// MediaType alias for a folder.
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public const string Folder = "Folder";
|
||||
|
||||
/// <summary>
|
||||
@@ -94,9 +94,19 @@ namespace Umbraco.Core
|
||||
public const string Image = "Image";
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco user
|
||||
/// </summary>
|
||||
public static class User
|
||||
{
|
||||
public static readonly string UmbracoUsersProviderName = "UsersMembershipProvider";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constants for Umbraco Member property aliases.
|
||||
/// </summary>
|
||||
|
||||
public static class Member
|
||||
{
|
||||
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
|
||||
@@ -166,13 +176,18 @@ namespace Umbraco.Core
|
||||
|
||||
public const string FailedPasswordAttemptsLabel = "Failed Password Attempts";
|
||||
|
||||
/// <summary>
|
||||
/// Group name to put the membership properties on
|
||||
/// </summary>
|
||||
internal const string StandardPropertiesGroupName = "Membership";
|
||||
|
||||
internal static Dictionary<string, PropertyType> GetStandardPropertyTypeStubs()
|
||||
{
|
||||
return new Dictionary<string, PropertyType>
|
||||
{
|
||||
{
|
||||
Comments,
|
||||
new PropertyType(new Guid(PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext)
|
||||
new PropertyType(new Guid(PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext, true)
|
||||
{
|
||||
Alias = Comments,
|
||||
Name = CommentsLabel
|
||||
@@ -180,7 +195,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
FailedPasswordAttempts,
|
||||
new PropertyType(new Guid(PropertyEditors.Integer), DataTypeDatabaseType.Integer)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = FailedPasswordAttempts,
|
||||
Name = FailedPasswordAttemptsLabel
|
||||
@@ -188,7 +203,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsApproved,
|
||||
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer)
|
||||
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsApproved,
|
||||
Name = IsApprovedLabel
|
||||
@@ -196,7 +211,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
IsLockedOut,
|
||||
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer)
|
||||
new PropertyType(new Guid(PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer, true)
|
||||
{
|
||||
Alias = IsLockedOut,
|
||||
Name = IsLockedOutLabel
|
||||
@@ -204,7 +219,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLockoutDate,
|
||||
new PropertyType(new Guid(PropertyEditors.Date), DataTypeDatabaseType.Date)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLockoutDate,
|
||||
Name = LastLockoutDateLabel
|
||||
@@ -212,7 +227,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastLoginDate,
|
||||
new PropertyType(new Guid(PropertyEditors.Date), DataTypeDatabaseType.Date)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastLoginDate,
|
||||
Name = LastLoginDateLabel
|
||||
@@ -220,7 +235,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
LastPasswordChangeDate,
|
||||
new PropertyType(new Guid(PropertyEditors.Date), DataTypeDatabaseType.Date)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Date, true)
|
||||
{
|
||||
Alias = LastPasswordChangeDate,
|
||||
Name = LastPasswordChangeDateLabel
|
||||
@@ -228,7 +243,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordAnswer,
|
||||
new PropertyType(new Guid(PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordAnswer,
|
||||
Name = PasswordAnswerLabel
|
||||
@@ -236,7 +251,7 @@ namespace Umbraco.Core
|
||||
},
|
||||
{
|
||||
PasswordQuestion,
|
||||
new PropertyType(new Guid(PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar)
|
||||
new PropertyType(new Guid(PropertyEditors.NoEdit), DataTypeDatabaseType.Nvarchar, true)
|
||||
{
|
||||
Alias = PasswordQuestion,
|
||||
Name = PasswordQuestionLabel
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace Umbraco.Core
|
||||
{
|
||||
internal static class ControlExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Recursively finds a control with the specified identifier.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">
|
||||
/// The type of control to be found.
|
||||
/// </typeparam>
|
||||
/// <param name="parent">
|
||||
/// The parent control from which the search will start.
|
||||
/// </param>
|
||||
/// <param name="id">
|
||||
/// The identifier of the control to be found.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// The control with the specified identifier, otherwise <see langword="null"/> if the control
|
||||
/// is not found.
|
||||
/// </returns>
|
||||
public static T FindControlRecursive<T>(this Control parent, string id) where T : Control
|
||||
{
|
||||
if ((parent is T) && (parent.ID == id))
|
||||
{
|
||||
return (T)parent;
|
||||
}
|
||||
|
||||
foreach (Control control in parent.Controls)
|
||||
{
|
||||
var foundControl = FindControlRecursive<T>(control, id);
|
||||
if (foundControl != null)
|
||||
{
|
||||
return foundControl;
|
||||
}
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -250,7 +250,7 @@ namespace Umbraco.Core
|
||||
() => PluginManager.Current.ResolveAssignedMapperTypes());
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
new RepositoryFactory(ApplicationCache));
|
||||
|
||||
SqlSyntaxProvidersResolver.Current = new SqlSyntaxProvidersResolver(
|
||||
new[] { typeof(MySqlSyntaxProvider), typeof(SqlCeSyntaxProvider), typeof(SqlServerSyntaxProvider) })
|
||||
|
||||
@@ -18,5 +18,30 @@ namespace Umbraco.Core
|
||||
return dt.ToString("yyyy-MM-dd HH:mm:ss");
|
||||
}
|
||||
|
||||
public static DateTime TruncateTo(this DateTime dt, DateTruncate truncateTo)
|
||||
{
|
||||
if (truncateTo == DateTruncate.Year)
|
||||
return new DateTime(dt.Year, 0, 0);
|
||||
if (truncateTo == DateTruncate.Month)
|
||||
return new DateTime(dt.Year, dt.Month, 0);
|
||||
if (truncateTo == DateTruncate.Day)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day);
|
||||
if (truncateTo == DateTruncate.Hour)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, 0, 0);
|
||||
if (truncateTo == DateTruncate.Minute)
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, 0);
|
||||
return new DateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second);
|
||||
}
|
||||
|
||||
public enum DateTruncate
|
||||
{
|
||||
Year,
|
||||
Month,
|
||||
Day,
|
||||
Hour,
|
||||
Minute,
|
||||
Second
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,10 +306,8 @@ namespace Umbraco.Core.Models
|
||||
/// <returns><see cref="Property"/> Value as a <see cref="TPassType"/></returns>
|
||||
public virtual TPassType GetValue<TPassType>(string propertyTypeAlias)
|
||||
{
|
||||
if (Properties[propertyTypeAlias].Value is TPassType)
|
||||
return (TPassType)Properties[propertyTypeAlias].Value;
|
||||
|
||||
return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType));
|
||||
var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo<TPassType>();
|
||||
return convertAttempt.Success ? convertAttempt.Result : default(TPassType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -25,6 +25,20 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
#region IContent
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity was just published as part of a recent save operation (i.e. it wasn't previously published)
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is helpful for determining if the published event will execute during the saved event for a content item.
|
||||
/// </remarks>
|
||||
internal static bool JustPublished(this IContent entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Published") && entity.Published;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if a new version should be created
|
||||
/// </summary>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class EntityExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if this entity has just been created and persisted to the data store
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This is useful when handling events to determine if an entity is a brand new entity or was
|
||||
/// already existing.
|
||||
/// </remarks>
|
||||
public static bool IsNewEntity(this IEntity entity)
|
||||
{
|
||||
var dirty = (IRememberBeingDirty)entity;
|
||||
return dirty.WasPropertyDirty("Id");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
public interface IMemberGroup : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The name of the member group
|
||||
/// </summary>
|
||||
string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Profile of the user who created this Entity
|
||||
/// </summary>
|
||||
int CreatorId { get; set; }
|
||||
|
||||
/// <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; }
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,11 @@
|
||||
/// </summary>
|
||||
/// <returns><see cref="RenderingEngine"/></returns>
|
||||
RenderingEngine GetTypeOfRenderingEngine();
|
||||
|
||||
/// <summary>
|
||||
/// Set the mastertemplate
|
||||
/// </summary>
|
||||
/// <param name="masterTemplate"></param>
|
||||
void SetMasterTemplate(ITemplate masterTemplate);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
@@ -29,8 +31,10 @@ namespace Umbraco.Core.Models
|
||||
: base(name, -1, contentType, new PropertyCollection())
|
||||
{
|
||||
_contentType = contentType;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
//TODO: Should we just get rid of this one? no reason to have a level set.
|
||||
internal Member(string name, string email, string username, string password, int parentId, IMemberType contentType)
|
||||
: base(name, parentId, contentType, new PropertyCollection())
|
||||
{
|
||||
@@ -40,6 +44,7 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
public Member(string name, string email, string username, string password, IMemberType contentType)
|
||||
@@ -51,6 +56,7 @@ namespace Umbraco.Core.Models
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
IsApproved = true;
|
||||
}
|
||||
|
||||
//public Member(string name, string email, string username, string password, IContentBase parent, IMemberType contentType)
|
||||
@@ -140,12 +146,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordQuestion, "PasswordQuestion", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordQuestion].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordQuestion].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordQuestion,
|
||||
"PasswordQuestion") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordQuestion].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -162,12 +175,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.PasswordAnswer, "PasswordAnswer", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.PasswordAnswer].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.PasswordAnswer].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.PasswordAnswer,
|
||||
"PasswordAnswer") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.PasswordAnswer].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -184,12 +204,19 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.Comments, "Comments", default(string));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
return Properties[Constants.Conventions.Member.Comments].Value == null
|
||||
? string.Empty
|
||||
: Properties[Constants.Conventions.Member.Comments].Value.ToString();
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.Comments,
|
||||
"Comments") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.Comments].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -206,16 +233,25 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value == null)
|
||||
return default(bool);
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsApproved, "IsApproved",
|
||||
//This is the default value if the prop is not found
|
||||
true);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsApproved].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsApproved].Value;
|
||||
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsApproved].Value, typeof(bool));
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsApproved].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
//if the property exists but it cannot be converted, we will assume true
|
||||
return true;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsApproved,
|
||||
"IsApproved") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsApproved].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -232,16 +268,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value == null)
|
||||
return default(bool);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.IsLockedOut].Value is bool)
|
||||
return (bool)Properties[Constants.Conventions.Member.IsLockedOut].Value;
|
||||
|
||||
return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsLockedOut].Value, typeof(bool));
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.IsLockedOut, "IsLockedOut", false);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].Value.TryConvertTo<bool>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.IsLockedOut,
|
||||
"IsLockedOut") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.IsLockedOut].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -258,16 +300,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLoginDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLoginDate].Value;
|
||||
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLoginDate].Value, typeof(DateTime));
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLoginDate, "LastLoginDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLoginDate,
|
||||
"LastLoginDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLoginDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -284,16 +332,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value == null)
|
||||
return default(DateTime);
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastPasswordChangeDate, "LastPasswordChangeDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value;
|
||||
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value, typeof(DateTime));
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastPasswordChangeDate,
|
||||
"LastPasswordChangeDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -310,16 +364,22 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value == null)
|
||||
return default(DateTime);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.LastLockoutDate].Value is DateTime)
|
||||
return (DateTime)Properties[Constants.Conventions.Member.LastLockoutDate].Value;
|
||||
|
||||
return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLockoutDate].Value, typeof(DateTime));
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.LastLockoutDate, "LastLockoutDate", default(DateTime));
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].Value.TryConvertTo<DateTime>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(DateTime);
|
||||
}
|
||||
set
|
||||
{
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.LastLockoutDate,
|
||||
"LastLockoutDate") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
}
|
||||
}
|
||||
@@ -337,17 +397,23 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value == null)
|
||||
return default(int);
|
||||
|
||||
if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value is int)
|
||||
return (int)Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value;
|
||||
|
||||
return (int)Convert.ChangeType(Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value, typeof(int));
|
||||
var a = WarnIfPropertyTypeNotFoundOnGet(Constants.Conventions.Member.FailedPasswordAttempts, "FailedPasswordAttempts", 0);
|
||||
if (a.Success == false) return a.Result;
|
||||
|
||||
var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value.TryConvertTo<int>();
|
||||
if (tryConvert.Success)
|
||||
{
|
||||
return tryConvert.Result;
|
||||
}
|
||||
return default(int);
|
||||
}
|
||||
set
|
||||
{
|
||||
Properties[Constants.Conventions.Member.LastLockoutDate].Value = value;
|
||||
if (WarnIfPropertyTypeNotFoundOnSet(
|
||||
Constants.Conventions.Member.FailedPasswordAttempts,
|
||||
"FailedPasswordAttempts") == false) return;
|
||||
|
||||
Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value = value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,5 +527,73 @@ namespace Umbraco.Core.Models
|
||||
internal bool BoolPropertyValue { get; set; }
|
||||
internal DateTime DateTimePropertyValue { get; set; }
|
||||
internal string PropertyTypeAlias { get; set; }
|
||||
|
||||
private Attempt<T> WarnIfPropertyTypeNotFoundOnGet<T>(string propertyAlias, string propertyName, T defaultVal)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>(
|
||||
"Trying to access the '"
|
||||
+ propertyName
|
||||
+ "' property on "
|
||||
+ typeof(Member)
|
||||
+ " but the "
|
||||
+ propertyAlias
|
||||
+ " property does not exist on the member type so a default value is returned. Ensure that you have a property type with alias: "
|
||||
+ propertyAlias
|
||||
+ " configured on your member type in order to use the '"
|
||||
+ propertyName
|
||||
+ "' property on the model correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
//we'll put a warn in the log if this entity has been persisted
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return Attempt<T>.Fail(defaultVal);
|
||||
}
|
||||
|
||||
return Attempt<T>.Succeed();
|
||||
}
|
||||
|
||||
private bool WarnIfPropertyTypeNotFoundOnSet(string propertyAlias, string propertyname)
|
||||
{
|
||||
Action doLog = () => LogHelper.Warn<Member>("An attempt was made to set a value on the property '"
|
||||
+ propertyname
|
||||
+ "' on type "
|
||||
+ typeof(Member)
|
||||
+ " but the property type "
|
||||
+ propertyAlias
|
||||
+ " does not exist on the member type, ensure that this property type exists so that setting this property works correctly.");
|
||||
|
||||
//if the property doesn't exist, then do the logging and return a failure
|
||||
if (Properties.Contains(propertyAlias) == false)
|
||||
{
|
||||
if (HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//if the property doesn't have an identity but we do, then do logging and return failure
|
||||
var prop = Properties.Single(x => x.Alias == propertyAlias);
|
||||
if (prop.HasIdentity == false && HasIdentity)
|
||||
{
|
||||
doLog();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a member type
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
public class MemberGroup : Entity, IMemberGroup
|
||||
{
|
||||
public MemberGroup()
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
}
|
||||
|
||||
private string _name;
|
||||
private int _creatorId;
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, string>(x => x.Name);
|
||||
private static readonly PropertyInfo CreatorIdSelector = ExpressionHelper.GetPropertyInfo<MemberGroup, int>(x => x.CreatorId);
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
if (_name != value)
|
||||
{
|
||||
//if the name has changed, add the value to the additional data,
|
||||
//this is required purely for event handlers to know the previous name of the group
|
||||
//so we can keep the public access up to date.
|
||||
AdditionalData["previousName"] = _name;
|
||||
}
|
||||
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_creatorId = value;
|
||||
return _creatorId;
|
||||
}, _creatorId, CreatorIdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, object> AdditionalData { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Method to call when Entity is being saved
|
||||
/// </summary>
|
||||
/// <remarks>Created date is set and a Unique key is assigned</remarks>
|
||||
internal override void AddingEntity()
|
||||
{
|
||||
base.AddingEntity();
|
||||
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,20 +14,18 @@ namespace Umbraco.Core.Models
|
||||
public class MemberType : ContentTypeCompositionBase, IMemberType
|
||||
{
|
||||
//Dictionary is divided into string: PropertyTypeAlias, Tuple: MemberCanEdit, VisibleOnProfile, PropertyTypeId
|
||||
private IDictionary<string, Tuple<bool, bool, int>> _memberTypePropertyTypes;
|
||||
private string _alias;
|
||||
|
||||
public MemberType(int parentId) : base(parentId)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
public MemberType(IContentTypeComposition parent) : base(parent)
|
||||
{
|
||||
_memberTypePropertyTypes = new Dictionary<string, Tuple<bool, bool, int>>();
|
||||
MemberTypePropertyTypes = new Dictionary<string, MemberTypePropertyProfileAccess>();
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo MemberTypePropertyTypesSelector = ExpressionHelper.GetPropertyInfo<MemberType, IDictionary<string, Tuple<bool, bool, int>>>(x => x.MemberTypePropertyTypes);
|
||||
private static readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<MemberType, string>(x => x.Alias);
|
||||
|
||||
/// <summary>
|
||||
@@ -53,21 +51,10 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, PropertyTypeId) by the PropertyTypes' alias.
|
||||
/// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile) by the PropertyTypes' alias.
|
||||
/// </summary>
|
||||
[DataMember]
|
||||
internal IDictionary<string, Tuple<bool, bool, int>> MemberTypePropertyTypes
|
||||
{
|
||||
get { return _memberTypePropertyTypes; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_memberTypePropertyTypes = value;
|
||||
return _memberTypePropertyTypes;
|
||||
}, _memberTypePropertyTypes, MemberTypePropertyTypesSelector);
|
||||
}
|
||||
}
|
||||
internal IDictionary<string, MemberTypePropertyProfileAccess> MemberTypePropertyTypes { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether a Property is editable by the Member.
|
||||
@@ -78,7 +65,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item1;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsEditable;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -93,7 +80,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].Item2;
|
||||
return MemberTypePropertyTypes[propertyTypeAlias].IsVisible;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -108,13 +95,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(value, tuple.Item2, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsEditable = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(value, false, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(false, value);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
@@ -128,13 +113,11 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (MemberTypePropertyTypes.ContainsKey(propertyTypeAlias))
|
||||
{
|
||||
var tuple = MemberTypePropertyTypes[propertyTypeAlias];
|
||||
MemberTypePropertyTypes[propertyTypeAlias] = new Tuple<bool, bool, int>(tuple.Item1, value, tuple.Item3);
|
||||
MemberTypePropertyTypes[propertyTypeAlias].IsVisible = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
var propertyType = PropertyTypes.First(x => x.Alias.Equals(propertyTypeAlias));
|
||||
var tuple = new Tuple<bool, bool, int>(false, value, propertyType.Id);
|
||||
var tuple = new MemberTypePropertyProfileAccess(value, false);
|
||||
MemberTypePropertyTypes.Add(propertyTypeAlias, tuple);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to track the property types that are visible/editable on member profiles
|
||||
/// </summary>
|
||||
internal class MemberTypePropertyProfileAccess
|
||||
{
|
||||
public MemberTypePropertyProfileAccess(bool isVisible, bool isEditable)
|
||||
{
|
||||
IsVisible = isVisible;
|
||||
IsEditable = isEditable;
|
||||
}
|
||||
|
||||
public bool IsVisible { get; set; }
|
||||
public bool IsEditable { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -5,14 +5,14 @@
|
||||
/// </summary>
|
||||
public class EntityPermission
|
||||
{
|
||||
public EntityPermission(object userId, int entityId, string[] assignedPermissions)
|
||||
public EntityPermission(int userId, int entityId, string[] assignedPermissions)
|
||||
{
|
||||
UserId = userId;
|
||||
EntityId = entityId;
|
||||
AssignedPermissions = assignedPermissions;
|
||||
}
|
||||
|
||||
public object UserId { get; private set; }
|
||||
public int UserId { get; private set; }
|
||||
public int EntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
/// <summary>
|
||||
/// Defines the the Profile interface
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This interface is pretty useless but has been exposed publicly from 6.x so we're stuck with it. It would make more sense
|
||||
/// if the Id was an int but since it's not people have to cast it to int all of the time!
|
||||
/// </remarks>
|
||||
public interface IProfile
|
||||
{
|
||||
object Id { get; set; }
|
||||
|
||||
@@ -7,19 +7,18 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// Defines the interface for a <see cref="User"/>
|
||||
/// </summary>
|
||||
/// <remarks>Will be left internal until a proper Membership implementation is part of the roadmap</remarks>
|
||||
internal interface IUser : IMembershipUser, IProfile
|
||||
public interface IUser : IMembershipUser
|
||||
{
|
||||
new object Id { get; set; }
|
||||
|
||||
string Name { get; set; }
|
||||
int SessionTimeout { get; set; }
|
||||
int StartContentId { get; set; }
|
||||
int StartMediaId { get; set; }
|
||||
string Language { get; set; }
|
||||
|
||||
//NOTE: I have removed this because it is obsolete in v7 and we are basically removing live editing for now
|
||||
//bool DefaultToLiveEditing { get; set; }
|
||||
|
||||
IUserType UserType { get; }
|
||||
/// <summary>
|
||||
/// Gets/sets the user type for the user
|
||||
/// </summary>
|
||||
IUserType UserType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The default permission set for the user
|
||||
@@ -32,5 +31,10 @@ namespace Umbraco.Core.Models.Membership
|
||||
IEnumerable<string> AllowedSections { get; }
|
||||
void RemoveAllowedSection(string sectionAlias);
|
||||
void AddAllowedSection(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the basic profile data
|
||||
/// </summary>
|
||||
IProfile ProfileData { get; }
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Umbraco.Core.Persistence.Mappers;
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
|
||||
internal interface IUserType : IAggregateRoot
|
||||
public interface IUserType : IAggregateRoot
|
||||
{
|
||||
/// <summary>
|
||||
/// The user type alias
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Persistence.Mappers;
|
||||
|
||||
@@ -19,7 +20,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </remarks>
|
||||
[Serializable]
|
||||
[DataContract(IsReference = true)]
|
||||
internal class User : TracksChangesEntityBase, IUser
|
||||
public class User : TracksChangesEntityBase, IUser
|
||||
{
|
||||
public User(IUserType userType)
|
||||
{
|
||||
@@ -31,7 +32,12 @@ namespace Umbraco.Core.Models.Membership
|
||||
_sectionCollection = new ObservableCollection<string>();
|
||||
_addedSections = new List<string>();
|
||||
_removedSections = new List<string>();
|
||||
_language = GlobalSettings.DefaultUILanguage;
|
||||
_sectionCollection.CollectionChanged += SectionCollectionChanged;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
public User(string name, string email, string username, string password, IUserType userType)
|
||||
@@ -41,11 +47,15 @@ namespace Umbraco.Core.Models.Membership
|
||||
_email = email;
|
||||
_username = username;
|
||||
_password = password;
|
||||
_isApproved = true;
|
||||
_isLockedOut = false;
|
||||
_startContentId = -1;
|
||||
_startMediaId = -1;
|
||||
}
|
||||
|
||||
private readonly IUserType _userType;
|
||||
private IUserType _userType;
|
||||
private bool _hasIdentity;
|
||||
private object _id;
|
||||
private int _id;
|
||||
private string _name;
|
||||
private Type _userTypeKey;
|
||||
private readonly List<string> _addedSections;
|
||||
@@ -58,7 +68,6 @@ namespace Umbraco.Core.Models.Membership
|
||||
private string _username;
|
||||
private string _email;
|
||||
private string _password;
|
||||
private Guid _key;
|
||||
private bool _isApproved;
|
||||
private bool _isLockedOut;
|
||||
private string _language;
|
||||
@@ -81,23 +90,43 @@ namespace Umbraco.Core.Models.Membership
|
||||
private static readonly PropertyInfo LanguageSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Language);
|
||||
private static readonly PropertyInfo DefaultPermissionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.DefaultPermissions);
|
||||
private static readonly PropertyInfo DefaultToLiveEditingSelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.DefaultToLiveEditing);
|
||||
private static readonly PropertyInfo HasIdentitySelector = ExpressionHelper.GetPropertyInfo<User, bool>(x => x.HasIdentity);
|
||||
private static readonly PropertyInfo UserTypeSelector = ExpressionHelper.GetPropertyInfo<User, IUserType>(x => x.UserType);
|
||||
|
||||
#region Implementation of IEntity
|
||||
|
||||
[IgnoreDataMember]
|
||||
public bool HasIdentity { get { return Id != null || _hasIdentity; } }
|
||||
|
||||
[IgnoreDataMember]
|
||||
int IEntity.Id
|
||||
public bool HasIdentity
|
||||
{
|
||||
get
|
||||
{
|
||||
return int.Parse(Id.ToString());
|
||||
return _hasIdentity;
|
||||
}
|
||||
protected set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_hasIdentity = value;
|
||||
return _hasIdentity;
|
||||
}, _hasIdentity, HasIdentitySelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int Id
|
||||
{
|
||||
get
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
set
|
||||
{
|
||||
Id = value;
|
||||
_hasIdentity = true;
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
HasIdentity = true; //set the has Identity
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,8 +268,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
public int FailedPasswordAttempts { get; set; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IProfile
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
[DataMember]
|
||||
public string Name
|
||||
@@ -249,17 +278,13 @@ namespace Umbraco.Core.Models.Membership
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
{
|
||||
_name = value;
|
||||
return _name;
|
||||
}, _name, NameSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Implementation of IUser
|
||||
|
||||
public IEnumerable<string> AllowedSections
|
||||
{
|
||||
get { return _sectionCollection; }
|
||||
@@ -278,6 +303,11 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
public IProfile ProfileData
|
||||
{
|
||||
get { return new UserProfile(this); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to check if we need to add a section in the repository to the db
|
||||
/// </summary>
|
||||
@@ -354,20 +384,6 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public object Id
|
||||
{
|
||||
get { return _id; }
|
||||
set
|
||||
{
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_id = value;
|
||||
return _id;
|
||||
}, _id, IdSelector);
|
||||
}
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string Language
|
||||
{
|
||||
@@ -414,6 +430,19 @@ namespace Umbraco.Core.Models.Membership
|
||||
public IUserType UserType
|
||||
{
|
||||
get { return _userType; }
|
||||
set
|
||||
{
|
||||
if (value.HasIdentity == false)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot assign a User Type that has not been persisted");
|
||||
}
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_userType = value;
|
||||
return _userType;
|
||||
}, _userType, UserTypeSelector);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -459,5 +488,30 @@ namespace Umbraco.Core.Models.Membership
|
||||
_removedSections.Add(e.OldItems.Cast<string>().First());
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Internal class used to wrap the user in a profile
|
||||
/// </summary>
|
||||
private class UserProfile : IProfile
|
||||
{
|
||||
private readonly IUser _user;
|
||||
|
||||
public UserProfile(IUser user)
|
||||
{
|
||||
_user = user;
|
||||
}
|
||||
|
||||
public object Id
|
||||
{
|
||||
get { return _user.Id; }
|
||||
set { _user.Id = (int)value; }
|
||||
}
|
||||
|
||||
public string Name
|
||||
{
|
||||
get { return _user.Name; }
|
||||
set { _user.Name = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@ namespace Umbraco.Core.Models
|
||||
|
||||
private static readonly PropertyInfo ValueSelector = ExpressionHelper.GetPropertyInfo<Property, object>(x => x.Value);
|
||||
private static readonly PropertyInfo VersionSelector = ExpressionHelper.GetPropertyInfo<Property, Guid>(x => x.Version);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Returns the Alias of the PropertyType, which this Property is based on
|
||||
/// </summary>
|
||||
@@ -59,9 +59,14 @@ namespace Umbraco.Core.Models
|
||||
/// <summary>
|
||||
/// Returns the DatabaseType that the underlaying DataType is using to store its values
|
||||
/// </summary>
|
||||
/// <remarks>Only used internally when saving the property value</remarks>
|
||||
/// <remarks>
|
||||
/// Only used internally when saving the property value.
|
||||
/// </remarks>
|
||||
[IgnoreDataMember]
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType { get { return _propertyType.DataTypeDatabaseType; } }
|
||||
internal DataTypeDatabaseType DataTypeDatabaseType
|
||||
{
|
||||
get { return _propertyType.DataTypeDatabaseType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the PropertyType, which this Property is based on
|
||||
|
||||
@@ -14,6 +14,7 @@ namespace Umbraco.Core.Models
|
||||
[DataContract(IsReference = true)]
|
||||
public class PropertyType : Entity, IEquatable<PropertyType>
|
||||
{
|
||||
private readonly bool _isExplicitDbType;
|
||||
private string _name;
|
||||
private string _alias;
|
||||
private string _description;
|
||||
@@ -29,16 +30,28 @@ namespace Umbraco.Core.Models
|
||||
public PropertyType(IDataTypeDefinition dataTypeDefinition)
|
||||
{
|
||||
if(dataTypeDefinition.HasIdentity)
|
||||
DataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
_dataTypeDefinitionId = dataTypeDefinition.Id;
|
||||
|
||||
DataTypeId = dataTypeDefinition.ControlId;
|
||||
DataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
_dataTypeId = dataTypeDefinition.ControlId;
|
||||
_dataTypeDatabaseType = dataTypeDefinition.DatabaseType;
|
||||
}
|
||||
|
||||
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType)
|
||||
: this(dataTypeControlId, dataTypeDatabaseType, false)
|
||||
{
|
||||
DataTypeId = dataTypeControlId;
|
||||
DataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used internally to assign an explicity database type for this property type regardless of what the underlying data type/property editor is.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeControlId"></param>
|
||||
/// <param name="dataTypeDatabaseType"></param>
|
||||
/// <param name="isExplicitDbType"></param>
|
||||
internal PropertyType(Guid dataTypeControlId, DataTypeDatabaseType dataTypeDatabaseType, bool isExplicitDbType)
|
||||
{
|
||||
_isExplicitDbType = isExplicitDbType;
|
||||
_dataTypeId = dataTypeControlId;
|
||||
_dataTypeDatabaseType = dataTypeDatabaseType;
|
||||
}
|
||||
|
||||
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<PropertyType, string>(x => x.Name);
|
||||
@@ -149,6 +162,9 @@ namespace Umbraco.Core.Models
|
||||
get { return _dataTypeDatabaseType; }
|
||||
set
|
||||
{
|
||||
//don't allow setting this if an explicit declaration has been made in the ctor
|
||||
if (_isExplicitDbType) return;
|
||||
|
||||
SetPropertyValueAndDetectChanges(o =>
|
||||
{
|
||||
_dataTypeDatabaseType = value;
|
||||
|
||||
@@ -191,5 +191,11 @@ namespace Umbraco.Core.Models
|
||||
if (Key == Guid.Empty)
|
||||
Key = Guid.NewGuid();
|
||||
}
|
||||
|
||||
|
||||
public void SetMasterTemplate(ITemplate masterTemplate)
|
||||
{
|
||||
MasterTemplateId = new Lazy<int>(() => masterTemplate.Id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
@@ -53,6 +54,13 @@ namespace Umbraco.Core.Models
|
||||
Trashed = trashed;
|
||||
}
|
||||
|
||||
// for MySql
|
||||
public UmbracoEntity(UInt64 trashed)
|
||||
{
|
||||
AdditionalData = new Dictionary<string, object>();
|
||||
Trashed = trashed == 1;
|
||||
}
|
||||
|
||||
public int CreatorId
|
||||
{
|
||||
get { return _creatorId; }
|
||||
|
||||
@@ -237,12 +237,14 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Double))
|
||||
{
|
||||
Double value;
|
||||
return Double.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Double.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Single))
|
||||
{
|
||||
Single value;
|
||||
return Single.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Single.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Char))
|
||||
{
|
||||
@@ -283,7 +285,20 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(DateTime))
|
||||
{
|
||||
DateTime value;
|
||||
return DateTime.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
if (DateTime.TryParse(input, out value))
|
||||
{
|
||||
switch (value.Kind)
|
||||
{
|
||||
case DateTimeKind.Unspecified:
|
||||
case DateTimeKind.Utc:
|
||||
return Attempt<object>.Succeed(value);
|
||||
case DateTimeKind.Local:
|
||||
return Attempt<object>.Succeed(value.ToUniversalTime());
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
return Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(DateTimeOffset))
|
||||
{
|
||||
@@ -298,7 +313,8 @@ namespace Umbraco.Core
|
||||
else if (destinationType == typeof(Decimal))
|
||||
{
|
||||
Decimal value;
|
||||
return Decimal.TryParse(input, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
var input2 = NormalizeNumberDecimalSeparator(input);
|
||||
return Decimal.TryParse(input2, out value) ? Attempt<object>.Succeed(value) : Attempt<object>.Fail();
|
||||
}
|
||||
else if (destinationType == typeof(Version))
|
||||
{
|
||||
@@ -310,6 +326,14 @@ namespace Umbraco.Core
|
||||
return null; // we can't decide...
|
||||
}
|
||||
|
||||
private readonly static char[] NumberDecimalSeparatorsToNormalize = new[] {'.', ','};
|
||||
|
||||
private static string NormalizeNumberDecimalSeparator(string s)
|
||||
{
|
||||
var normalized = System.Threading.Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator[0];
|
||||
return s.ReplaceMany(NumberDecimalSeparatorsToNormalize, normalized);
|
||||
}
|
||||
|
||||
internal static void CheckThrowObjectDisposed(this IDisposable disposable, bool isDisposed, string objectname)
|
||||
{
|
||||
//TODO: Localise this exception
|
||||
@@ -516,7 +540,7 @@ namespace Umbraco.Core
|
||||
if (type == typeof(bool)) return XmlConvert.ToString((bool)value);
|
||||
if (type == typeof(byte)) return XmlConvert.ToString((byte)value);
|
||||
if (type == typeof(char)) return XmlConvert.ToString((char)value);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.RoundtripKind);
|
||||
if (type == typeof(DateTime)) return XmlConvert.ToString((DateTime)value, XmlDateTimeSerializationMode.Unspecified);
|
||||
if (type == typeof(DateTimeOffset)) return XmlConvert.ToString((DateTimeOffset)value);
|
||||
if (type == typeof(decimal)) return XmlConvert.ToString((decimal)value);
|
||||
if (type == typeof(double)) return XmlConvert.ToString((double)value);
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
internal class MemberGroupFactory : IEntityFactory<IMemberGroup, NodeDto>
|
||||
{
|
||||
|
||||
private readonly Guid _nodeObjectTypeId;
|
||||
|
||||
public MemberGroupFactory()
|
||||
{
|
||||
_nodeObjectTypeId = new Guid(Constants.ObjectTypes.MemberGroup);
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<ITemplate,TemplateDto>
|
||||
|
||||
public IMemberGroup BuildEntity(NodeDto dto)
|
||||
{
|
||||
var template = new MemberGroup
|
||||
{
|
||||
CreateDate = dto.CreateDate,
|
||||
Id = dto.NodeId,
|
||||
Key = dto.UniqueId.Value,
|
||||
Name = dto.Text
|
||||
};
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
template.ResetDirtyProperties(false);
|
||||
return template;
|
||||
}
|
||||
|
||||
public NodeDto BuildDto(IMemberGroup entity)
|
||||
{
|
||||
var dto = new NodeDto
|
||||
{
|
||||
CreateDate = entity.CreateDate,
|
||||
NodeId = entity.Id,
|
||||
Level = 0,
|
||||
NodeObjectType = _nodeObjectTypeId,
|
||||
ParentId = -1,
|
||||
Path = "",
|
||||
SortOrder = 0,
|
||||
Text = entity.Name,
|
||||
Trashed = false,
|
||||
UniqueId = entity.Key,
|
||||
UserId = entity.CreatorId
|
||||
};
|
||||
|
||||
if (entity.HasIdentity)
|
||||
{
|
||||
dto.NodeId = entity.Id;
|
||||
dto.Path = "-1," + entity.Id;
|
||||
}
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.UpdateDate,
|
||||
Name = dto.Text,
|
||||
ProviderUserKey = dto.UniqueId.Value,
|
||||
ProviderUserKey = dto.NodeId,
|
||||
Trashed = dto.Trashed,
|
||||
Key = dto.UniqueId.Value,
|
||||
CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0,
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
@@ -10,6 +11,8 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
public IMemberType BuildEntity(MemberTypeReadOnlyDto dto)
|
||||
{
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
|
||||
var memberType = new MemberType(dto.ParentId)
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
@@ -31,12 +34,12 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
AllowedContentTypes = Enumerable.Empty<ContentTypeSort>()
|
||||
};
|
||||
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType);
|
||||
var propertyTypeGroupCollection = GetPropertyTypeGroupCollection(dto, memberType, standardPropertyTypes);
|
||||
memberType.PropertyGroups = propertyTypeGroupCollection;
|
||||
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType);
|
||||
//By Convention we add 9 stnd PropertyTypes - This is only here to support loading of types that didn't have these conventions before.
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
var propertyTypes = GetPropertyTypes(dto, memberType, standardPropertyTypes);
|
||||
|
||||
//By Convention we add 9 stnd 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;
|
||||
@@ -46,16 +49,17 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(standardPropertyType.Key,
|
||||
new Tuple<bool, bool, int>(false, false, default(int)));
|
||||
new MemberTypePropertyProfileAccess(false, false));
|
||||
}
|
||||
memberType.PropertyTypes = propertyTypes;
|
||||
|
||||
return memberType;
|
||||
}
|
||||
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType, Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
var propertyGroups = new PropertyGroupCollection();
|
||||
|
||||
foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue))
|
||||
{
|
||||
var group = new PropertyGroup();
|
||||
@@ -84,11 +88,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
{
|
||||
//Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new Tuple<bool, bool, int>(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value));
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.ControlId,
|
||||
typeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
|
||||
//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<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.ControlId,
|
||||
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)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
@@ -117,32 +133,47 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
return propertyGroups;
|
||||
}
|
||||
|
||||
private List<PropertyType> GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType)
|
||||
|
||||
|
||||
private 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 propertyType in dto.PropertyTypes.Where(x => (x.PropertyTypeGroupId.HasValue == false || x.PropertyTypeGroupId.Value == 0) && x.Id.HasValue))
|
||||
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(propertyType.Alias,
|
||||
new Tuple<bool, bool, int>(propertyType.CanEdit, propertyType.ViewOnProfile, propertyType.Id.Value));
|
||||
//PropertyType Collection
|
||||
propertyTypes.Add(new PropertyType(propertyType.ControlId,
|
||||
propertyType.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = propertyType.Alias,
|
||||
DataTypeDefinitionId = propertyType.DataTypeId,
|
||||
Description = propertyType.Description,
|
||||
HelpText = propertyType.HelpText,
|
||||
Id = propertyType.Id.Value,
|
||||
Mandatory = propertyType.Mandatory,
|
||||
Name = propertyType.Name,
|
||||
SortOrder = propertyType.SortOrder,
|
||||
ValidationRegExp = propertyType.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
});
|
||||
memberType.MemberTypePropertyTypes.Add(typeDto.Alias,
|
||||
new MemberTypePropertyProfileAccess(typeDto.ViewOnProfile, typeDto.CanEdit));
|
||||
|
||||
//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<DataTypeDatabaseType>(true),
|
||||
standardProps);
|
||||
|
||||
var propertyType = new PropertyType(
|
||||
typeDto.ControlId,
|
||||
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)
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
HelpText = typeDto.HelpText,
|
||||
Id = typeDto.Id.Value,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
Name = typeDto.Name,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => default(int)),
|
||||
CreateDate = dto.CreateDate,
|
||||
UpdateDate = dto.CreateDate
|
||||
};
|
||||
|
||||
propertyTypes.Add(propertyType);
|
||||
}
|
||||
return propertyTypes;
|
||||
}
|
||||
|
||||
@@ -11,17 +11,21 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
private readonly int _id;
|
||||
private readonly DateTime _createDate;
|
||||
private readonly DateTime _updateDate;
|
||||
//a callback to create a property type which can be injected via a contructor
|
||||
private readonly Func<Guid, DataTypeDatabaseType, string, PropertyType> _propertyTypeCtor;
|
||||
|
||||
public PropertyGroupFactory(int id)
|
||||
{
|
||||
_id = id;
|
||||
_propertyTypeCtor = (guid, dbType, alias) => new PropertyType(guid, dbType);
|
||||
}
|
||||
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate)
|
||||
|
||||
public PropertyGroupFactory(int id, DateTime createDate, DateTime updateDate, Func<Guid, DataTypeDatabaseType, string, PropertyType> propertyTypeCtor)
|
||||
{
|
||||
_id = id;
|
||||
_createDate = createDate;
|
||||
_updateDate = updateDate;
|
||||
_propertyTypeCtor = propertyTypeCtor;
|
||||
}
|
||||
|
||||
#region Implementation of IEntityFactory<IEnumerable<PropertyGroup>,IEnumerable<TabDto>>
|
||||
@@ -55,22 +59,23 @@ namespace Umbraco.Core.Persistence.Factories
|
||||
foreach (var typeDto in typeDtos)
|
||||
{
|
||||
var tempGroupDto = groupDto;
|
||||
var propertyType = new PropertyType(typeDto.DataTypeDto.ControlId,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = typeDto.Alias,
|
||||
DataTypeDefinitionId = typeDto.DataTypeId,
|
||||
Description = typeDto.Description,
|
||||
Id = typeDto.Id,
|
||||
Name = typeDto.Name,
|
||||
HelpText = typeDto.HelpText,
|
||||
Mandatory = typeDto.Mandatory,
|
||||
SortOrder = typeDto.SortOrder,
|
||||
ValidationRegExp = typeDto.ValidationRegExp,
|
||||
PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id),
|
||||
CreateDate = _createDate,
|
||||
UpdateDate = _updateDate
|
||||
};
|
||||
var propertyType = _propertyTypeCtor(typeDto.DataTypeDto.ControlId,
|
||||
typeDto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true),
|
||||
typeDto.Alias);
|
||||
|
||||
propertyType.Alias = typeDto.Alias;
|
||||
propertyType.DataTypeDefinitionId = typeDto.DataTypeId;
|
||||
propertyType.Description = typeDto.Description;
|
||||
propertyType.Id = typeDto.Id;
|
||||
propertyType.Name = typeDto.Name;
|
||||
propertyType.HelpText = typeDto.HelpText;
|
||||
propertyType.Mandatory = typeDto.Mandatory;
|
||||
propertyType.SortOrder = typeDto.SortOrder;
|
||||
propertyType.ValidationRegExp = typeDto.ValidationRegExp;
|
||||
propertyType.PropertyGroupId = new Lazy<int>(() => tempGroupDto.Id);
|
||||
propertyType.CreateDate = _createDate;
|
||||
propertyType.UpdateDate = _updateDate;
|
||||
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
propertyType.ResetDirtyProperties(false);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Concurrent;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Mappers
|
||||
{
|
||||
[MapperFor(typeof (IMemberGroup))]
|
||||
[MapperFor(typeof (MemberGroup))]
|
||||
public sealed class MemberGroupMapper : BaseMapper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, DtoMapModel> PropertyInfoCacheInstance = new ConcurrentDictionary<string, DtoMapModel>();
|
||||
|
||||
//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 MemberGroupMapper()
|
||||
{
|
||||
BuildMap();
|
||||
}
|
||||
|
||||
internal override ConcurrentDictionary<string, DtoMapModel> PropertyInfoCache
|
||||
{
|
||||
get { return PropertyInfoCacheInstance; }
|
||||
}
|
||||
|
||||
internal override void BuildMap()
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +80,10 @@ namespace Umbraco.Core.Persistence.Migrations.Initial
|
||||
|
||||
try
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
if (_database.TableExist(tableName))
|
||||
{
|
||||
_database.DropTable(tableName);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
@@ -57,11 +57,20 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
using (var tr = db.GetTransaction())
|
||||
{
|
||||
db.BulkInsertRecords(collection, tr);
|
||||
db.BulkInsertRecords(collection, tr, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection, Transaction tr)
|
||||
/// <summary>
|
||||
/// Performs the bulk insertion in the context of a current transaction with an optional parameter to complete the transaction
|
||||
/// when finished
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="db"></param>
|
||||
/// <param name="collection"></param>
|
||||
/// <param name="tr"></param>
|
||||
/// <param name="commitTrans"></param>
|
||||
public static void BulkInsertRecords<T>(this Database db, IEnumerable<T> collection, Transaction tr, bool commitTrans = false)
|
||||
{
|
||||
//don't do anything if there are no records.
|
||||
if (collection.Any() == false)
|
||||
@@ -95,11 +104,17 @@ namespace Umbraco.Core.Persistence
|
||||
}
|
||||
}
|
||||
|
||||
tr.Complete();
|
||||
if (commitTrans)
|
||||
{
|
||||
tr.Complete();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
tr.Dispose();
|
||||
if (commitTrans)
|
||||
{
|
||||
tr.Dispose();
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
@@ -25,7 +26,7 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
//if (TypeSerializer.CanCreateFromString(fieldType))
|
||||
//{
|
||||
// return "'" + EscapeParam(TypeSerializer.SerializeToString(value)) + "'";
|
||||
// return "'" + escapeCallback(TypeSerializer.SerializeToString(value)) + "'";
|
||||
//}
|
||||
|
||||
throw new NotSupportedException(
|
||||
@@ -46,27 +47,24 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
|
||||
if (fieldType == typeof(DateTime))
|
||||
{
|
||||
return "'" + EscapeParam(((DateTime)value).ToIsoString()) + "'";
|
||||
return "'" + escapeCallback(((DateTime)value).ToIsoString()) + "'";
|
||||
}
|
||||
|
||||
if (fieldType == typeof(bool))
|
||||
return ((bool)value) ? Convert.ToString(1, CultureInfo.InvariantCulture) : Convert.ToString(0, CultureInfo.InvariantCulture);
|
||||
|
||||
return ShouldQuoteValue(fieldType)
|
||||
? "'" + EscapeParam(value) + "'"
|
||||
return shouldQuoteCallback(fieldType)
|
||||
? "'" + escapeCallback(value) + "'"
|
||||
: value.ToString();
|
||||
}
|
||||
|
||||
public virtual string EscapeParam(object paramValue)
|
||||
{
|
||||
return paramValue.ToString().Replace("'", "''");
|
||||
return paramValue == null
|
||||
? string.Empty
|
||||
: SqlSyntaxContext.SqlSyntaxProvider.EscapeString(paramValue.ToString());
|
||||
}
|
||||
|
||||
public virtual string EscapeAtArgument(string exp)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(exp);
|
||||
}
|
||||
|
||||
|
||||
public virtual bool ShouldQuoteValue(Type fieldType)
|
||||
{
|
||||
return true;
|
||||
|
||||
@@ -205,13 +205,12 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
{
|
||||
if (c.Value == null)
|
||||
return "null";
|
||||
else if (c.Value.GetType() == typeof(bool))
|
||||
if (c.Value is bool)
|
||||
{
|
||||
object o = GetQuotedValue(c.Value, c.Value.GetType());
|
||||
return string.Format("({0}={1})", GetQuotedTrueValue(), o);
|
||||
}
|
||||
else
|
||||
return GetQuotedValue(c.Value, c.Value.GetType());
|
||||
return GetQuotedValue(c.Value, c.Value.GetType());
|
||||
}
|
||||
|
||||
protected virtual string VisitUnary(UnaryExpression u)
|
||||
@@ -233,15 +232,15 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
switch (verb)
|
||||
{
|
||||
case "SqlWildcard":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnWildcardComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnWildcardComparison(col, RemoveQuote(val), columnType);
|
||||
case "Equals":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEqualComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEqualComparison(col, RemoveQuote(val), columnType);
|
||||
case "StartsWith":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnStartsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnStartsWithComparison(col, RemoveQuote(val), columnType);
|
||||
case "EndsWith":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEndsWithComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnEndsWithComparison(col, RemoveQuote(val), columnType);
|
||||
case "Contains":
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnContainsComparison(col, EscapeAtArgument(RemoveQuote(val)), columnType);
|
||||
return SqlSyntaxContext.SqlSyntaxProvider.GetStringColumnContainsComparison(col, RemoveQuote(val), columnType);
|
||||
case "InvariantEquals":
|
||||
case "SqlEquals":
|
||||
//recurse
|
||||
|
||||
@@ -243,6 +243,10 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
args.RemoveAt(0);
|
||||
}
|
||||
|
||||
//TODO: We should probably add the same logic we've done for ModelToSqlExpressionHelper with checking for:
|
||||
// InvariantStartsWith, InvariantEndsWith, SqlWildcard, etc...
|
||||
// since we should be able to easily handle that with the Poco objects too.
|
||||
|
||||
switch (m.Method.Name)
|
||||
{
|
||||
case "ToUpper":
|
||||
@@ -250,11 +254,11 @@ namespace Umbraco.Core.Persistence.Querying
|
||||
case "ToLower":
|
||||
return string.Format("lower({0})", r);
|
||||
case "StartsWith":
|
||||
return string.Format("upper({0}) like '{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString().ToUpper())));
|
||||
return string.Format("upper({0}) like '{1}%'", r, RemoveQuote(args[0].ToString().ToUpper()));
|
||||
case "EndsWith":
|
||||
return string.Format("upper({0}) like '%{1}'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper()));
|
||||
return string.Format("upper({0}) like '%{1}'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Contains":
|
||||
return string.Format("upper({0}) like '%{1}%'", r, EscapeAtArgument(RemoveQuote(args[0].ToString()).ToUpper()));
|
||||
return string.Format("upper({0}) like '%{1}%'", r, RemoveQuote(args[0].ToString()).ToUpper());
|
||||
case "Substring":
|
||||
var startIndex = Int32.Parse(args[0].ToString()) + 1;
|
||||
if (args.Count == 2)
|
||||
|
||||
@@ -22,23 +22,26 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
private readonly IContentTypeRepository _contentTypeRepository;
|
||||
private readonly ITemplateRepository _templateRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository)
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
|
||||
EnsureUniqueNaming = true;
|
||||
}
|
||||
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository)
|
||||
public ContentRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
|
||||
EnsureUniqueNaming = true;
|
||||
EnsureUniqueNaming = true;
|
||||
}
|
||||
|
||||
public bool EnsureUniqueNaming { get; set; }
|
||||
@@ -129,6 +132,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -264,7 +268,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Assign the same permissions to it as the parent node
|
||||
// http://issues.umbraco.org/issue/U4-2161
|
||||
var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
var parentPermissions = permissionsRepo.GetPermissionsForEntity(entity.ParentId).ToArray();
|
||||
//if there are parent permissions then assign them, otherwise leave null and permissions will become the
|
||||
// user's default permissions.
|
||||
@@ -273,9 +277,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var userPermissions = (
|
||||
from perm in parentPermissions
|
||||
from p in perm.AssignedPermissions
|
||||
select new Tuple<object, string>(perm.UserId, p)).ToList();
|
||||
select new Tuple<int, string>(perm.UserId, p)).ToList();
|
||||
|
||||
permissionsRepo.AssignEntityPermissions(entity, userPermissions);
|
||||
permissionsRepo.ReplaceEntityPermissions(entity, userPermissions);
|
||||
//flag the entity's permissions changed flag so we can track those changes.
|
||||
//Currently only used for the cache refreshers to detect if we should refresh all user permissions cache.
|
||||
((Content) entity).PermissionsChanged = true;
|
||||
@@ -527,15 +531,21 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return GetByVersion(dto.ContentVersionDto.VersionId);
|
||||
}
|
||||
|
||||
public void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds)
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
repo.AssignEntityPermissions(entity, permission, userIds);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
repo.AssignEntityPermission(entity, permission, userIds);
|
||||
}
|
||||
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
return repo.GetPermissionsForEntity(entityId);
|
||||
}
|
||||
|
||||
@@ -568,33 +578,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return content;
|
||||
}
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto{ NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
|
||||
private string EnsureUniqueNodeName(int parentId, string nodeName, int id = 0)
|
||||
{
|
||||
if (EnsureUniqueNaming == false)
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -54,19 +55,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
yield return dto.ContentTypeNodeId;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// We need to override this method to ensure that any content cache is cleared
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <remarks>
|
||||
/// see: http://issues.umbraco.org/issue/U4-1963
|
||||
/// </remarks>
|
||||
public override void PersistUpdatedItem(IEntity entity)
|
||||
|
||||
protected virtual PropertyType CreatePropertyType(Guid dataTypeId, DataTypeDatabaseType dbType, string propertyTypeAlias)
|
||||
{
|
||||
InMemoryCacheProvider.Current.Clear(typeof(IContent));
|
||||
RuntimeCacheProvider.Current.Clear(typeof(IContent));
|
||||
base.PersistUpdatedItem(entity);
|
||||
return new PropertyType(dataTypeId, dbType);
|
||||
}
|
||||
|
||||
protected void PersistNewBaseContentType(ContentTypeDto dto, IContentTypeComposition entity)
|
||||
@@ -158,8 +150,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//If the Id of the DataType is not set, we resolve it from the db by its ControlId
|
||||
if (propertyType.DataTypeDefinitionId == 0 || propertyType.DataTypeDefinitionId == default(int))
|
||||
{
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>("WHERE controlId = @Id", new { Id = propertyType.DataTypeId });
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
AssignDataTypeFromPropertyEditor(propertyType);
|
||||
}
|
||||
var propertyTypeDto = propertyFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = Convert.ToInt32(Database.Insert(propertyTypeDto));
|
||||
@@ -312,12 +303,16 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
foreach (var propertyType in entity.PropertyTypes)
|
||||
{
|
||||
var tabId = propertyType.PropertyGroupId != null ? propertyType.PropertyGroupId.Value : default(int);
|
||||
|
||||
//If the Id of the DataType is not set, we resolve it from the db by its ControlId
|
||||
if (propertyType.DataTypeDefinitionId == 0 || propertyType.DataTypeDefinitionId == default(int))
|
||||
{
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>("WHERE controlId = @Id", new { Id = propertyType.DataTypeId });
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
AssignDataTypeFromPropertyEditor(propertyType);
|
||||
}
|
||||
|
||||
//validate the alias!
|
||||
ValidateAlias(propertyType);
|
||||
|
||||
var propertyTypeDto = propertyGroupFactory.BuildPropertyTypeDto(tabId, propertyType);
|
||||
int typePrimaryKey = propertyType.HasIdentity
|
||||
? Database.Update(propertyTypeDto)
|
||||
@@ -354,7 +349,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
var dtos = Database.Fetch<PropertyTypeGroupDto, PropertyTypeDto, DataTypeDto, PropertyTypeGroupDto>(new GroupPropertyTypeRelator().Map, sql);
|
||||
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate);
|
||||
var propertyGroupFactory = new PropertyGroupFactory(id, createDate, updateDate, CreatePropertyType);
|
||||
var propertyGroups = propertyGroupFactory.BuildEntity(dtos);
|
||||
return new PropertyGroupCollection(propertyGroups);
|
||||
}
|
||||
@@ -371,29 +366,88 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var dtos = Database.Fetch<PropertyTypeDto, DataTypeDto>(sql);
|
||||
|
||||
//TODO Move this to a PropertyTypeFactory
|
||||
var list = (from dto in dtos
|
||||
where (dto.PropertyTypeGroupId > 0) == false
|
||||
select
|
||||
new PropertyType(dto.DataTypeDto.ControlId,
|
||||
dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true))
|
||||
{
|
||||
Alias = dto.Alias,
|
||||
DataTypeDefinitionId = dto.DataTypeId,
|
||||
Description = dto.Description,
|
||||
Id = dto.Id,
|
||||
Name = dto.Name,
|
||||
HelpText = dto.HelpText,
|
||||
Mandatory = dto.Mandatory,
|
||||
SortOrder = dto.SortOrder,
|
||||
ValidationRegExp = dto.ValidationRegExp,
|
||||
CreateDate = createDate,
|
||||
UpdateDate = updateDate
|
||||
}).ToList();
|
||||
|
||||
var list = new List<PropertyType>();
|
||||
foreach (var dto in dtos.Where(x => (x.PropertyTypeGroupId > 0) == false))
|
||||
{
|
||||
var propType = CreatePropertyType(dto.DataTypeDto.ControlId, dto.DataTypeDto.DbType.EnumParse<DataTypeDatabaseType>(true), dto.Alias);
|
||||
propType.Alias = dto.Alias;
|
||||
propType.DataTypeDefinitionId = dto.DataTypeId;
|
||||
propType.Description = dto.Description;
|
||||
propType.Id = dto.Id;
|
||||
propType.Name = dto.Name;
|
||||
propType.HelpText = dto.HelpText;
|
||||
propType.Mandatory = dto.Mandatory;
|
||||
propType.SortOrder = dto.SortOrder;
|
||||
propType.ValidationRegExp = dto.ValidationRegExp;
|
||||
propType.CreateDate = createDate;
|
||||
propType.UpdateDate = updateDate;
|
||||
list.Add(propType);
|
||||
}
|
||||
//Reset dirty properties
|
||||
Parallel.ForEach(list, currentFile => currentFile.ResetDirtyProperties(false));
|
||||
|
||||
return new PropertyTypeCollection(list);
|
||||
}
|
||||
|
||||
protected void ValidateAlias(PropertyType pt)
|
||||
{
|
||||
Mandate.That<InvalidOperationException>(string.IsNullOrEmpty(pt.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"{0} '{1}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
"Property Type",
|
||||
pt.Name);
|
||||
var exception = new InvalidOperationException(message);
|
||||
|
||||
LogHelper.Error<ContentTypeBaseRepository<TId, TEntity>>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
}
|
||||
|
||||
protected void ValidateAlias(TEntity entity)
|
||||
{
|
||||
Mandate.That<InvalidOperationException>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"{0} '{1}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
typeof(TEntity).Name,
|
||||
entity.Name);
|
||||
var exception = new InvalidOperationException(message);
|
||||
|
||||
LogHelper.Error<ContentTypeBaseRepository<TId, TEntity>>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Try to set the data type id based on its ControlId
|
||||
/// </summary>
|
||||
/// <param name="propertyType"></param>
|
||||
private void AssignDataTypeFromPropertyEditor(PropertyType propertyType)
|
||||
{
|
||||
//we cannot try to assign a data type of it's an empty guid
|
||||
if (propertyType.DataTypeId != Guid.Empty)
|
||||
{
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<DataTypeDto>()
|
||||
.Where("controlId = @Id", new { Id = propertyType.DataTypeId })
|
||||
.OrderBy<DataTypeDto>(typeDto => typeDto.DataTypeId);
|
||||
var datatype = Database.FirstOrDefault<DataTypeDto>(sql);
|
||||
//we cannot assign a data type if one was not found
|
||||
if (datatype != null)
|
||||
{
|
||||
propertyType.DataTypeDefinitionId = datatype.DataTypeId;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogHelper.Warn<ContentTypeBaseRepository<TId, TEntity>>("Could not assign a data type for the property type " + propertyType.Alias + " since no data type was found with a property editor " + propertyType.DataTypeId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,18 +208,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IContentType entity)
|
||||
{
|
||||
Mandate.That<Exception>(string.IsNullOrEmpty(entity.Alias) == false,
|
||||
() =>
|
||||
{
|
||||
var message =
|
||||
string.Format(
|
||||
"ContentType '{0}' cannot have an empty Alias. This is most likely due to invalid characters stripped from the Alias.",
|
||||
entity.Name);
|
||||
var exception = new Exception(message);
|
||||
|
||||
LogHelper.Error<ContentTypeRepository>(message, exception);
|
||||
throw exception;
|
||||
});
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((ContentType)entity).UpdatingEntity();
|
||||
|
||||
@@ -23,8 +23,19 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns>An enumerable list of <see cref="IContent"/></returns>
|
||||
IEnumerable<IContent> GetByPublishedVersion(IQuery<IContent> query);
|
||||
|
||||
void AssignEntityPermissions(IContent entity, char permission, IEnumerable<object> userIds);
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> userIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public interface IMemberGroupRepository : IRepositoryQueryable<int, IMemberGroup>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a member group by it's name
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
IMemberGroup GetByName(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the new member group if it doesn't already exist
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
IMemberGroup CreateIfNotExists(string roleName);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the member groups for a given member
|
||||
/// </summary>
|
||||
/// <param name="memberId"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMemberGroup> GetMemberGroupsForMember(int memberId);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the member groups for a given member
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username);
|
||||
|
||||
void AssignRoles(string[] usernames, string[] roleNames);
|
||||
|
||||
void DissociateRoles(string[] usernames, string[] roleNames);
|
||||
|
||||
void AssignRoles(int[] memberIds, string[] roleNames);
|
||||
|
||||
void DissociateRoles(int[] memberIds, string[] roleNames);
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,17 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IMemberRepository : IRepositoryVersionable<int, IMember>
|
||||
public interface IMemberRepository : IRepositoryVersionable<int, IMember>
|
||||
{
|
||||
/// <summary>
|
||||
/// Finds members in a given role
|
||||
/// </summary>
|
||||
/// <param name="roleName"></param>
|
||||
/// <param name="usernameToMatch"></param>
|
||||
/// <param name="matchType"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Get all members in a specific group
|
||||
/// </summary>
|
||||
|
||||
@@ -6,7 +6,7 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IUserRepository : IRepositoryQueryable<int, IUser>
|
||||
public interface IUserRepository : IRepositoryQueryable<int, IUser>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the count of items based on a complex query
|
||||
@@ -38,14 +38,21 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="orderBy"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IUser> GetPagedResultsByQuery(IQuery<IUser> query, int pageIndex, int pageSize, out int totalRecords, Expression<Func<IUser, string>> orderBy);
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user permissions for the specified entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds);
|
||||
IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds);
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
internal interface IUserTypeRepository : IRepositoryQueryable<int, IUserType>
|
||||
public interface IUserTypeRepository : IRepositoryQueryable<int, IUserType>
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@@ -124,6 +124,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -358,34 +359,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos);
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
|
||||
|
||||
private string EnsureUniqueNodeName(int parentId, string nodeName, int id = 0)
|
||||
{
|
||||
if (EnsureUniqueNaming == false)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -162,6 +163,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IMediaType entity)
|
||||
{
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((MediaType)entity).UpdatingEntity();
|
||||
|
||||
|
||||
@@ -1,7 +1,383 @@
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
public class MemberGroupRepository
|
||||
|
||||
|
||||
internal class MemberGroupRepository : PetaPocoRepositoryBase<int, IMemberGroup>, IMemberGroupRepository
|
||||
{
|
||||
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public MemberGroupRepository(IDatabaseUnitOfWork work, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public MemberGroupRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
private readonly MemberGroupFactory _modelFactory = new MemberGroupFactory();
|
||||
|
||||
protected override IMemberGroup PerformGet(int id)
|
||||
{
|
||||
var sql = GetBaseQuery(false);
|
||||
sql.Where(GetBaseWhereClause(), new { Id = id });
|
||||
|
||||
var dto = Database.Fetch<NodeDto>(sql).FirstOrDefault();
|
||||
|
||||
return dto == null ? null : _modelFactory.BuildEntity(dto);
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberGroup> PerformGetAll(params int[] ids)
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
var sql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode.id in (@ids)", new { ids = ids });
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
else
|
||||
{
|
||||
var sql = new Sql()
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId);
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberGroup> PerformGetByQuery(IQuery<IMemberGroup> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<IMemberGroup>(sqlClause, query);
|
||||
var sql = translator.Translate();
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select(isCount ? "COUNT(*)" : "*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId);
|
||||
return sql;
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
return "umbracoNode.id = @Id";
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
var list = new[]
|
||||
{
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE childId = @Id",
|
||||
"DELETE FROM cmsTagRelationship WHERE nodeId = @Id",
|
||||
"DELETE FROM cmsMember2MemberGroup WHERE MemberGroup = @Id",
|
||||
"DELETE FROM umbracoNode WHERE id = @Id"
|
||||
};
|
||||
return list;
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { return new Guid(Constants.ObjectTypes.MemberGroup); }
|
||||
}
|
||||
|
||||
protected override void PersistNewItem(IMemberGroup entity)
|
||||
{
|
||||
//Save to db
|
||||
var group = (MemberGroup)entity;
|
||||
group.AddingEntity();
|
||||
var dto = _modelFactory.BuildDto(group);
|
||||
var o = Database.IsNew(dto) ? Convert.ToInt32(Database.Insert(dto)) : Database.Update(dto);
|
||||
|
||||
//Update with new correct path
|
||||
dto.Path = string.Concat("-1,", dto.NodeId);
|
||||
Database.Update(dto);
|
||||
|
||||
group.ResetDirtyProperties();
|
||||
}
|
||||
|
||||
protected override void PersistUpdatedItem(IMemberGroup entity)
|
||||
{
|
||||
var dto = _modelFactory.BuildDto(entity);
|
||||
|
||||
Database.Update(dto);
|
||||
|
||||
((ICanBeDirty)entity).ResetDirtyProperties();
|
||||
}
|
||||
|
||||
public IMemberGroup GetByName(string name)
|
||||
{
|
||||
return _cacheHelper.RuntimeCache.GetCacheItem<IMemberGroup>(
|
||||
string.Format("{0}.{1}", typeof (IMemberGroup).FullName, name),
|
||||
() =>
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(group => group.Name.Equals(name));
|
||||
var result = GetByQuery(qry);
|
||||
return result.FirstOrDefault();
|
||||
},
|
||||
//cache for 5 mins since that is the default in the RuntimeCacheProvider
|
||||
TimeSpan.FromMinutes(5),
|
||||
//sliding is true
|
||||
true);
|
||||
}
|
||||
|
||||
public IMemberGroup CreateIfNotExists(string roleName)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(group => group.Name.Equals(roleName));
|
||||
var result = GetByQuery(qry);
|
||||
|
||||
if (result.Any()) return null;
|
||||
|
||||
var grp = new MemberGroup
|
||||
{
|
||||
Name = roleName
|
||||
};
|
||||
PersistNewItem(grp);
|
||||
|
||||
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(grp), this))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
transaction.Complete();
|
||||
|
||||
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(grp), this);
|
||||
|
||||
return grp;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(int memberId)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<Member2MemberGroupDto>(x => x.Member == memberId);
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.DistinctBy(dto => dto.NodeId)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberGroup> GetMemberGroupsForMember(string username)
|
||||
{
|
||||
//find the member by username
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
var escapedUsername = PetaPocoExtensions.EscapeAtSymbols(username);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where<MemberDto>(x => x.LoginName == escapedUsername);
|
||||
var memberIdUsername = Database.Fetch<int?>(memberSql).FirstOrDefault();
|
||||
if (memberIdUsername.HasValue == false)
|
||||
{
|
||||
return Enumerable.Empty<IMemberGroup>();
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("umbracoNode.*")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where<Member2MemberGroupDto>(x => x.Member == memberIdUsername.Value);
|
||||
|
||||
return Database.Fetch<NodeDto>(sql)
|
||||
.DistinctBy(dto => dto.NodeId)
|
||||
.Select(x => _modelFactory.BuildEntity(x));
|
||||
}
|
||||
|
||||
public void AssignRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
//first get the member ids based on the usernames
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames });
|
||||
var memberIds = Database.Fetch<int>(memberSql).ToArray();
|
||||
|
||||
AssignRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
//first get the member ids based on the usernames
|
||||
var memberSql = new Sql();
|
||||
var memberObjectType = new Guid(Constants.ObjectTypes.Member);
|
||||
memberSql.Select("umbracoNode.id")
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<MemberDto>()
|
||||
.On<NodeDto, MemberDto>(dto => dto.NodeId, dto => dto.NodeId)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == memberObjectType)
|
||||
.Where("cmsMember.LoginName in (@usernames)", new { usernames = usernames });
|
||||
var memberIds = Database.Fetch<int>(memberSql).ToArray();
|
||||
|
||||
DissociateRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
AssignRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRolesInternal(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
//create the missing roles first
|
||||
|
||||
var existingSql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames });
|
||||
var existingRoles = Database.Fetch<NodeDto>(existingSql).Select(x => x.Text);
|
||||
var missingRoles = roleNames.Except(existingRoles);
|
||||
var missingGroups = missingRoles.Select(x => new MemberGroup {Name = x}).ToArray();
|
||||
|
||||
if (SavingMemberGroup.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(missingGroups), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (var m in missingGroups)
|
||||
{
|
||||
PersistNewItem(m);
|
||||
}
|
||||
SavedMemberGroup.RaiseEvent(new SaveEventArgs<IMemberGroup>(missingGroups), this);
|
||||
|
||||
//now go get all the dto's for roles with these role names
|
||||
var rolesForNames = Database.Fetch<NodeDto>(existingSql).ToArray();
|
||||
|
||||
//get the groups that are currently assigned to any of these members
|
||||
|
||||
var assignedSql = new Sql();
|
||||
assignedSql.Select(string.Format(
|
||||
"{0},{1},{2}",
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("Member"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("MemberGroup")))
|
||||
.From<NodeDto>()
|
||||
.InnerJoin<Member2MemberGroupDto>()
|
||||
.On<NodeDto, Member2MemberGroupDto>(dto => dto.NodeId, dto => dto.MemberGroup)
|
||||
.Where<NodeDto>(x => x.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("cmsMember2MemberGroup.Member in (@ids)", new { ids = memberIds });
|
||||
|
||||
var currentlyAssigned = Database.Fetch<AssignedRolesDto>(assignedSql).ToArray();
|
||||
|
||||
//assign the roles for each member id
|
||||
|
||||
foreach (var memberId in memberIds)
|
||||
{
|
||||
//find any roles for the current member that are currently assigned that
|
||||
//exist in the roleNames list, then determine which ones are not currently assigned.
|
||||
var mId = memberId;
|
||||
var found = currentlyAssigned.Where(x => x.MemberId == mId).ToArray();
|
||||
var assignedRoles = found.Where(x => roleNames.Contains(x.RoleName)).Select(x => x.RoleName);
|
||||
var nonAssignedRoles = roleNames.Except(assignedRoles);
|
||||
foreach (var toAssign in nonAssignedRoles)
|
||||
{
|
||||
var groupId = rolesForNames.First(x => x.Text == toAssign).NodeId;
|
||||
Database.Insert(new Member2MemberGroupDto { Member = mId, MemberGroup = groupId });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
using (var transaction = Database.GetTransaction())
|
||||
{
|
||||
DissociateRolesInternal(memberIds, roleNames);
|
||||
transaction.Complete();
|
||||
}
|
||||
}
|
||||
|
||||
private void DissociateRolesInternal(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var existingSql = new Sql()
|
||||
.Select("*")
|
||||
.From<NodeDto>()
|
||||
.Where<NodeDto>(dto => dto.NodeObjectType == NodeObjectTypeId)
|
||||
.Where("umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + " in (@names)", new { names = roleNames });
|
||||
var existingRolesIds = Database.Fetch<NodeDto>(existingSql).Select(x => x.NodeId).ToArray();
|
||||
|
||||
Database.Execute("DELETE FROM cmsMember2MemberGroup WHERE Member IN (@memberIds) AND MemberGroup IN (@memberGroups)",
|
||||
new { memberIds = memberIds, memberGroups = existingRolesIds });
|
||||
}
|
||||
|
||||
private class AssignedRolesDto
|
||||
{
|
||||
[Column("text")]
|
||||
public string RoleName { get; set; }
|
||||
|
||||
[Column("Member")]
|
||||
public int MemberId { get; set; }
|
||||
|
||||
[Column("MemberGroup")]
|
||||
public int MemberGroupId { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IMemberGroupRepository, SaveEventArgs<IMemberGroup>> SavingMemberGroup;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
internal static event TypedEventHandler<IMemberGroupRepository, SaveEventArgs<IMemberGroup>> SavedMemberGroup;
|
||||
}
|
||||
}
|
||||
@@ -23,19 +23,22 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
internal class MemberRepository : VersionableRepositoryBase<int, IMember>, IMemberRepository
|
||||
{
|
||||
private readonly IMemberTypeRepository _memberTypeRepository;
|
||||
private readonly IMemberGroupRepository _memberGroupRepository;
|
||||
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository)
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository)
|
||||
: base(work)
|
||||
{
|
||||
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
|
||||
_memberTypeRepository = memberTypeRepository;
|
||||
_memberGroupRepository = memberGroupRepository;
|
||||
}
|
||||
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository)
|
||||
public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository, IMemberGroupRepository memberGroupRepository)
|
||||
: base(work, cache)
|
||||
{
|
||||
if (memberTypeRepository == null) throw new ArgumentNullException("memberTypeRepository");
|
||||
_memberTypeRepository = memberTypeRepository;
|
||||
_memberGroupRepository = memberGroupRepository;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int, IMembershipUser>
|
||||
@@ -164,6 +167,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE nodeId = @Id",
|
||||
"DELETE FROM umbracoRelation WHERE parentId = @Id",
|
||||
@@ -237,7 +241,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
//Create the PropertyData for this version - cmsPropertyData
|
||||
var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id);
|
||||
var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties);
|
||||
//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 propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray();
|
||||
var propertyDataDtos = propertyFactory.BuildDto(propsToPersist);
|
||||
var keyDictionary = new Dictionary<int, int>();
|
||||
|
||||
//Add Properties
|
||||
@@ -248,7 +257,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
|
||||
//Update Properties with its newly set Id
|
||||
foreach (var property in ((Member)entity).Properties)
|
||||
foreach (var property in propsToPersist)
|
||||
{
|
||||
property.Id = keyDictionary[property.PropertyTypeId];
|
||||
}
|
||||
@@ -331,12 +340,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
//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();
|
||||
// - member object contains.
|
||||
var propsToPersist = entity.Properties.Where(x => x.PropertyType.HasIdentity).ToArray();
|
||||
|
||||
var propertyDataDtos = propertyFactory.BuildDto(existingProperties);
|
||||
var propertyDataDtos = propertyFactory.BuildDto(propsToPersist);
|
||||
|
||||
foreach (var propertyDataDto in propertyDataDtos)
|
||||
{
|
||||
@@ -419,6 +426,57 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
public IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
//get the group id
|
||||
var grpQry = new Query<IMemberGroup>().Where(group => group.Name.Equals(roleName));
|
||||
var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault();
|
||||
if (memberGroup == null) return Enumerable.Empty<IMember>();
|
||||
|
||||
// get the members by username
|
||||
var query = new Query<IMember>();
|
||||
switch (matchType)
|
||||
{
|
||||
case StringPropertyMatchType.Exact:
|
||||
query.Where(member => member.Username.Equals(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Contains:
|
||||
query.Where(member => member.Username.Contains(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.StartsWith:
|
||||
query.Where(member => member.Username.StartsWith(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.EndsWith:
|
||||
query.Where(member => member.Username.EndsWith(usernameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Wildcard:
|
||||
query.Where(member => member.Username.SqlWildcard(usernameToMatch, TextColumnType.NVarchar));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("matchType");
|
||||
}
|
||||
var matchedMembers = GetByQuery(query).ToArray();
|
||||
|
||||
var membersInGroup = new List<IMember>();
|
||||
//then we need to filter the matched members that are in the role
|
||||
//since the max sql params are 2100 on sql server, we'll reduce that to be safe for potentially other servers and run the queries in batches
|
||||
var inGroups = matchedMembers.InGroupsOf(1000);
|
||||
foreach (var batch in inGroups)
|
||||
{
|
||||
var memberIdBatch = batch.Select(x => x.Id);
|
||||
var sql = new Sql().Select("*").From<Member2MemberGroupDto>()
|
||||
.Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id)
|
||||
.Where("Member IN (@memberIds)", new { memberIds = memberIdBatch });
|
||||
var memberIdsInGroup = Database.Fetch<Member2MemberGroupDto>(sql)
|
||||
.Select(x => x.Member).ToArray();
|
||||
|
||||
membersInGroup.AddRange(matchedMembers.Where(x => memberIdsInGroup.Contains(x.Id)));
|
||||
}
|
||||
|
||||
return membersInGroup;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get all members in a specific group
|
||||
/// </summary>
|
||||
@@ -426,9 +484,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMember> GetByMemberGroup(string groupName)
|
||||
{
|
||||
var subquery = GetSubquery().Where<NodeDto>(x => x.Text == groupName);
|
||||
var grpQry = new Query<IMemberGroup>().Where(group => group.Name.Equals(groupName));
|
||||
var memberGroup = _memberGroupRepository.GetByQuery(grpQry).FirstOrDefault();
|
||||
if (memberGroup == null) return Enumerable.Empty<IMember>();
|
||||
var subQuery = new Sql().Select("Member").From<Member2MemberGroupDto>().Where<Member2MemberGroupDto>(dto => dto.MemberGroup == memberGroup.Id);
|
||||
|
||||
var sql = GetBaseQuery(false)
|
||||
.Append(new Sql("WHERE umbracoNode.id IN (" + subquery.SQL + ")", subquery.Arguments))
|
||||
.Append(new Sql("WHERE umbracoNode.id IN (" + subQuery.SQL + ")", subQuery.Arguments))
|
||||
.OrderByDescending<ContentVersionDto>(x => x.VersionDate)
|
||||
.OrderBy<NodeDto>(x => x.SortOrder);
|
||||
|
||||
@@ -539,6 +601,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberReadOnlyFactory(memberTypes);
|
||||
var member = factory.BuildEntity(dto);
|
||||
|
||||
member.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, member.ContentType, dto.CreateDate, dto.UpdateDate);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
@@ -552,8 +616,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var memberTypeList = _memberTypeRepository.GetAll();
|
||||
memberTypeList.ForEach(x => memberTypes.Add(x.Alias, x));
|
||||
|
||||
var entities = new List<IMember>();
|
||||
var factory = new MemberReadOnlyFactory(memberTypes);
|
||||
return dtos.Select(factory.BuildEntity);
|
||||
foreach (var dto in dtos)
|
||||
{
|
||||
var entity = factory.BuildEntity(dto);
|
||||
entity.Properties = GetPropertyCollection(dto.NodeId, dto.VersionId, entity.ContentType, dto.CreateDate, dto.UpdateDate);
|
||||
entities.Add(entity);
|
||||
}
|
||||
return entities;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
@@ -17,17 +18,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
internal class MemberTypeRepository : ContentTypeBaseRepository<int, IMemberType>, IMemberTypeRepository
|
||||
{
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work)
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work)
|
||||
: base(work)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
public MemberTypeRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache)
|
||||
: base(work, cache)
|
||||
{
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int, IMemberType>
|
||||
#region Overrides of RepositoryBase<int, IMemberType>
|
||||
|
||||
protected override IMemberType PerformGet(int id)
|
||||
{
|
||||
@@ -39,13 +40,13 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
Database.Fetch<MemberTypeReadOnlyDto, PropertyTypeReadOnlyDto, PropertyTypeGroupReadOnlyDto, MemberTypeReadOnlyDto>(
|
||||
new PropertyTypePropertyGroupRelator().Map, sql);
|
||||
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return null;
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return null;
|
||||
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dtos.First());
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
var member = factory.BuildEntity(dtos.First());
|
||||
|
||||
return member;
|
||||
return member;
|
||||
}
|
||||
|
||||
protected override IEnumerable<IMemberType> PerformGetAll(params int[] ids)
|
||||
@@ -98,11 +99,11 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return sql;
|
||||
}
|
||||
|
||||
sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias",
|
||||
sql.Select("umbracoNode.*", "cmsContentType.*", "cmsPropertyType.id AS PropertyTypeId", "cmsPropertyType.Alias",
|
||||
"cmsPropertyType.Name", "cmsPropertyType.Description", "cmsPropertyType.helpText", "cmsPropertyType.mandatory",
|
||||
"cmsPropertyType.validationRegExp", "cmsPropertyType.dataTypeId", "cmsPropertyType.sortOrder AS PropertyTypeSortOrder",
|
||||
"cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile",
|
||||
"cmsDataType.controlId", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId",
|
||||
"cmsDataType.controlId", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId",
|
||||
"cmsPropertyTypeGroup.text AS PropertyGroupName", "cmsPropertyTypeGroup.parentGroupId",
|
||||
"cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder", "cmsPropertyTypeGroup.contenttypeNodeId")
|
||||
.From<NodeDto>()
|
||||
@@ -168,15 +169,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
((MemberType)entity).AddingEntity();
|
||||
|
||||
//By Convention we add 9 stnd PropertyTypes to an Umbraco MemberType
|
||||
entity.AddPropertyGroup(Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
var standardPropertyTypes = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
foreach (var standardPropertyType in standardPropertyTypes)
|
||||
{
|
||||
entity.AddPropertyType(standardPropertyType.Value);
|
||||
entity.AddPropertyType(standardPropertyType.Value, Constants.Conventions.Member.StandardPropertiesGroupName);
|
||||
}
|
||||
|
||||
var factory = new MemberTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
EnsureExplicitDataTypeForBuiltInProperties(entity);
|
||||
|
||||
PersistNewBaseContentType(dto, entity);
|
||||
|
||||
//Handles the MemberTypeDto (cmsMemberType table)
|
||||
@@ -191,6 +195,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
protected override void PersistUpdatedItem(IMemberType entity)
|
||||
{
|
||||
ValidateAlias(entity);
|
||||
|
||||
//Updates Modified date
|
||||
((MemberType)entity).UpdatingEntity();
|
||||
|
||||
@@ -210,10 +216,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberTypeFactory(NodeObjectTypeId);
|
||||
var dto = factory.BuildDto(entity);
|
||||
|
||||
EnsureExplicitDataTypeForBuiltInProperties(entity);
|
||||
|
||||
PersistUpdatedBaseContentType(dto, entity);
|
||||
|
||||
//Remove existing entries before inserting new ones
|
||||
Database.Delete<MemberTypeDto>("WHERE NodeId = @Id", new {Id = entity.Id});
|
||||
Database.Delete<MemberTypeDto>("WHERE NodeId = @Id", new { Id = entity.Id });
|
||||
|
||||
//Handles the MemberTypeDto (cmsMemberType table)
|
||||
var memberTypeDtos = factory.BuildMemberTypeDtos(entity);
|
||||
@@ -227,7 +235,50 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IMemberType> BuildFromDtos(List<MemberTypeReadOnlyDto> dtos)
|
||||
/// <summary>
|
||||
/// Override so we can specify explicit db type's on any property types that are built-in.
|
||||
/// </summary>
|
||||
/// <param name="dataTypeId"></param>
|
||||
/// <param name="dbType"></param>
|
||||
/// <param name="propertyTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
protected override PropertyType CreatePropertyType(Guid dataTypeId, DataTypeDatabaseType dbType, string propertyTypeAlias)
|
||||
{
|
||||
//custom property type constructor logic to set explicit dbtype's for built in properties
|
||||
var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
var propDbType = GetDbTypeForBuiltInProperty(propertyTypeAlias, dbType, stdProps);
|
||||
return new PropertyType(dataTypeId, 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensure that all the built-in membership provider properties have their correct data type
|
||||
/// and property editors assigned. This occurs prior to saving so that the correct values are persisted.
|
||||
/// </summary>
|
||||
/// <param name="memberType"></param>
|
||||
private static void EnsureExplicitDataTypeForBuiltInProperties(IContentTypeBase memberType)
|
||||
{
|
||||
var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs();
|
||||
foreach (var propertyType in memberType.PropertyTypes)
|
||||
{
|
||||
var dbTypeAttempt = GetDbTypeForBuiltInProperty(propertyType.Alias, propertyType.DataTypeDatabaseType, stdProps);
|
||||
if (dbTypeAttempt)
|
||||
{
|
||||
//this reset's it's current data type reference which will be re-assigned based on the property editor assigned on the next line
|
||||
propertyType.DataTypeDefinitionId = 0;
|
||||
propertyType.DataTypeId = GetPropertyEditorForBuiltInProperty(propertyType.Alias, propertyType.DataTypeId, stdProps).Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds a collection of entities from a collection of Dtos
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <returns></returns>
|
||||
private static IEnumerable<IMemberType> BuildFromDtos(List<MemberTypeReadOnlyDto> dtos)
|
||||
{
|
||||
if (dtos == null || dtos.Any() == false)
|
||||
return Enumerable.Empty<IMemberType>();
|
||||
@@ -235,5 +286,58 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
var factory = new MemberTypeReadOnlyFactory();
|
||||
return dtos.Select(factory.BuildEntity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If this is one of our internal properties - we will manually assign the data type since they must
|
||||
/// always correspond to the correct db type no matter what the backing data type is assigned.
|
||||
/// </summary>
|
||||
/// <param name="propAlias"></param>
|
||||
/// <param name="dbType"></param>
|
||||
/// <param name="standardProps"></param>
|
||||
/// <returns>
|
||||
/// Successful attempt if it was a built in property
|
||||
/// </returns>
|
||||
internal static Attempt<DataTypeDatabaseType> GetDbTypeForBuiltInProperty(
|
||||
string propAlias,
|
||||
DataTypeDatabaseType dbType,
|
||||
Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var aliases = standardProps.Select(x => x.Key).ToArray();
|
||||
|
||||
//check if it is built in
|
||||
if (aliases.Contains(propAlias))
|
||||
{
|
||||
//return the pre-determined db type for this property
|
||||
return Attempt<DataTypeDatabaseType>.Succeed(standardProps.Single(x => x.Key == propAlias).Value.DataTypeDatabaseType);
|
||||
}
|
||||
|
||||
return Attempt<DataTypeDatabaseType>.Fail(dbType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="propAlias"></param>
|
||||
/// <param name="propertyEditor"></param>
|
||||
/// <param name="standardProps"></param>
|
||||
/// <returns>
|
||||
/// Successful attempt if it was a built in property
|
||||
/// </returns>
|
||||
internal static Attempt<Guid> GetPropertyEditorForBuiltInProperty(
|
||||
string propAlias,
|
||||
Guid propertyEditor,
|
||||
Dictionary<string, PropertyType> standardProps)
|
||||
{
|
||||
var aliases = standardProps.Select(x => x.Key).ToArray();
|
||||
|
||||
//check if it is built in
|
||||
if (aliases.Contains(propAlias))
|
||||
{
|
||||
//return the pre-determined db type for this property
|
||||
return Attempt<Guid>.Succeed(standardProps.Single(x => x.Key == propAlias).Value.DataTypeId);
|
||||
}
|
||||
|
||||
return Attempt<Guid>.Fail(propertyEditor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Dynamic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.Caching;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
@@ -11,22 +14,26 @@ using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using Umbraco.Core.Services;
|
||||
using CacheKeys = Umbraco.Core.Cache.CacheKeys;
|
||||
using Umbraco.Core.Cache;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// A repository that exposes functionality to modify assigned permissions to a node
|
||||
/// </summary>
|
||||
/// <typeparam name="TId"></typeparam>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
internal class PermissionRepository<TEntity>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IDatabaseUnitOfWork _unitOfWork;
|
||||
private readonly CacheHelper _cache;
|
||||
|
||||
internal PermissionRepository(IDatabaseUnitOfWork unitOfWork)
|
||||
internal PermissionRepository(IDatabaseUnitOfWork unitOfWork, CacheHelper cache)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
_cache = cache;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,39 +42,57 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds)
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds)
|
||||
{
|
||||
var whereBuilder = new StringBuilder();
|
||||
|
||||
//where userId = @userId AND
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("userId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(userId);
|
||||
whereBuilder.Append(" AND ");
|
||||
|
||||
//where nodeId = @nodeId1 OR nodeId = @nodeId2, etc...
|
||||
whereBuilder.Append("(");
|
||||
for (var index = 0; index < entityIds.Length; index++)
|
||||
{
|
||||
var entityId = entityIds[index];
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("nodeId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(entityId);
|
||||
if (index < entityIds.Length - 1)
|
||||
var entityIdKey = string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
|
||||
return _cache.RuntimeCache.GetCacheItem<IEnumerable<EntityPermission>>(
|
||||
string.Format("{0}{1}{2}", CacheKeys.UserPermissionsCacheKey, userId, entityIdKey),
|
||||
() =>
|
||||
{
|
||||
whereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
whereBuilder.Append(")");
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<User2NodePermissionDto>()
|
||||
.Where(whereBuilder.ToString());
|
||||
var whereBuilder = new StringBuilder();
|
||||
|
||||
//where userId = @userId AND
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("userId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(userId);
|
||||
|
||||
if (entityIds.Any())
|
||||
{
|
||||
whereBuilder.Append(" AND ");
|
||||
|
||||
//where nodeId = @nodeId1 OR nodeId = @nodeId2, etc...
|
||||
whereBuilder.Append("(");
|
||||
for (var index = 0; index < entityIds.Length; index++)
|
||||
{
|
||||
var entityId = entityIds[index];
|
||||
whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("nodeId"));
|
||||
whereBuilder.Append("=");
|
||||
whereBuilder.Append(entityId);
|
||||
if (index < entityIds.Length - 1)
|
||||
{
|
||||
whereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
whereBuilder.Append(")");
|
||||
}
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<User2NodePermissionDto>()
|
||||
.Where(whereBuilder.ToString());
|
||||
|
||||
//ToArray() to ensure it's all fetched from the db once.
|
||||
var result = _unitOfWork.Database.Fetch<User2NodePermissionDto>(sql).ToArray();
|
||||
return ConvertToPermissionList(result);
|
||||
|
||||
},
|
||||
//Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will only have this exist in cache for 20 minutes,
|
||||
// then it will refresh from the database.
|
||||
new TimeSpan(0, 20, 0),
|
||||
//Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will make this priority below average
|
||||
priority: CacheItemPriority.BelowNormal);
|
||||
|
||||
//ToArray() to ensure it's all fetched from the db once.
|
||||
var result = _unitOfWork.Database.Fetch<User2NodePermissionDto>(sql).ToArray();
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -75,7 +100,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
@@ -88,7 +113,118 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
private IEnumerable<EntityPermission> ConvertToPermissionList(IEnumerable<User2NodePermissionDto> result)
|
||||
/// <summary>
|
||||
/// Assigns the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <remarks>
|
||||
/// This will first clear the permissions for this user and entities and recreate them
|
||||
/// </remarks>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE userId=@userId AND nodeId in (@nodeIds)",
|
||||
new {userId = userId, nodeIds = entityIds});
|
||||
|
||||
var toInsert = new List<User2NodePermissionDto>();
|
||||
foreach (var p in permissions)
|
||||
{
|
||||
foreach (var e in entityIds)
|
||||
{
|
||||
toInsert.Add(new User2NodePermissionDto
|
||||
{
|
||||
NodeId = e,
|
||||
Permission = p.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = userId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(toInsert, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(toInsert), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns one permission to an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignEntityPermission(TEntity entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE nodeId=@nodeId AND permission=@permission AND userId in (@userIds)",
|
||||
new
|
||||
{
|
||||
nodeId = entity.Id,
|
||||
permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
userIds = userIds
|
||||
});
|
||||
|
||||
var actions = userIds.Select(id => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = id
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns permissions to an entity for multiple users/permission entries
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="userPermissions">
|
||||
/// A key/value pair list containing a userId and a permission to assign
|
||||
/// </param>
|
||||
/// <remarks>
|
||||
/// This will first clear the permissions for this entity then re-create them
|
||||
/// </remarks>
|
||||
public void ReplaceEntityPermissions(TEntity entity, IEnumerable<Tuple<int, string>> userPermissions)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
using (var trans = db.GetTransaction())
|
||||
{
|
||||
db.Execute("DELETE FROM umbracoUser2NodePermission WHERE nodeId=@nodeId", new { nodeId = entity.Id });
|
||||
|
||||
var actions = userPermissions.Select(p => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = p.Item2,
|
||||
UserId = p.Item1
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, trans);
|
||||
|
||||
trans.Complete();
|
||||
|
||||
//Raise the event
|
||||
AssignedPermissions.RaiseEvent(
|
||||
new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false), this);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<EntityPermission> ConvertToPermissionList(IEnumerable<User2NodePermissionDto> result)
|
||||
{
|
||||
var permissions = new List<EntityPermission>();
|
||||
var nodePermissions = result.GroupBy(x => x.NodeId);
|
||||
@@ -104,116 +240,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns one permission to an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable<object> userIds)
|
||||
{
|
||||
var actions = userIds.Select(id => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = permission.ToString(CultureInfo.InvariantCulture),
|
||||
UserId = (int)id
|
||||
});
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns permissions to an entity for multiple users/permission entries
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="userPermissions">
|
||||
/// A key/value pair list containing a userId and a permission to assign
|
||||
/// </param>
|
||||
internal void AssignEntityPermissions(TEntity entity, IEnumerable<Tuple<object, string>> userPermissions)
|
||||
{
|
||||
var actions = userPermissions.Select(p => new User2NodePermissionDto
|
||||
{
|
||||
NodeId = entity.Id,
|
||||
Permission = p.Item2,
|
||||
UserId = (int)p.Item1
|
||||
});
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replace permissions for an entity for multiple users
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void ReplaceEntityPermissions(TEntity entity, string permissions, IEnumerable<object> userIds)
|
||||
{
|
||||
_unitOfWork.Database.Update<User2NodePermissionDto>(
|
||||
GenerateReplaceEntityPermissionsSql(entity.Id, permissions, userIds.ToArray()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An overload to replace entity permissions and all replace all descendant permissions
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="getDescendantIds">
|
||||
/// A callback to get the descendant Ids of the current entity
|
||||
/// </param>
|
||||
/// <param name="userIds"></param>
|
||||
internal void ReplaceEntityPermissions(TEntity entity, string permissions, Func<IEntity, IEnumerable<int>> getDescendantIds, IEnumerable<object> userIds)
|
||||
{
|
||||
_unitOfWork.Database.Update<User2NodePermissionDto>(
|
||||
GenerateReplaceEntityPermissionsSql(
|
||||
new[] { entity.Id }.Concat(getDescendantIds(entity)).ToArray(),
|
||||
permissions,
|
||||
userIds.ToArray()));
|
||||
}
|
||||
|
||||
internal static string GenerateReplaceEntityPermissionsSql(int entityId, string permissions, object[] userIds)
|
||||
{
|
||||
return GenerateReplaceEntityPermissionsSql(new[] { entityId }, permissions, userIds);
|
||||
}
|
||||
|
||||
internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, string permissions, object[] userIds)
|
||||
{
|
||||
//create the "SET" clause of the update statement
|
||||
var sqlSet = string.Format("SET {0}={1}",
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("permission"),
|
||||
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(permissions));
|
||||
|
||||
//build the nodeIds part of the where clause
|
||||
var sqlNodeWhere = BuildOrClause(entityIds, "nodeId");
|
||||
|
||||
//build up the userIds part of the where clause
|
||||
var userWhereBuilder = BuildOrClause(userIds, "userId");
|
||||
|
||||
var sqlWhere = new Sql();
|
||||
sqlWhere.Where(string.Format("{0} AND {1}", sqlNodeWhere, userWhereBuilder));
|
||||
|
||||
return string.Format("{0} {1}", sqlSet, sqlWhere.SQL);
|
||||
}
|
||||
|
||||
private static string BuildOrClause<T>(IEnumerable<T> ids, string colName)
|
||||
{
|
||||
var asArray = ids.ToArray();
|
||||
var userWhereBuilder = new StringBuilder();
|
||||
userWhereBuilder.Append("(");
|
||||
for (var index = 0; index < asArray.Length; index++)
|
||||
{
|
||||
var userId = asArray[index];
|
||||
userWhereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName(colName));
|
||||
userWhereBuilder.Append("=");
|
||||
userWhereBuilder.Append(userId);
|
||||
if (index < asArray.Length - 1)
|
||||
{
|
||||
userWhereBuilder.Append(" OR ");
|
||||
}
|
||||
}
|
||||
userWhereBuilder.Append(")");
|
||||
return userWhereBuilder.ToString();
|
||||
}
|
||||
|
||||
public static event TypedEventHandler<PermissionRepository<TEntity>, SaveEventArgs<EntityPermission>> AssignedPermissions;
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entity"></param>
|
||||
public void AddOrUpdate(TEntity entity)
|
||||
{
|
||||
if (!entity.HasIdentity)
|
||||
if (entity.HasIdentity == false)
|
||||
{
|
||||
_work.RegisterAdded(entity, this);
|
||||
}
|
||||
@@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
//on initial construction we don't want to have dirty properties tracked
|
||||
// http://issues.umbraco.org/issue/U4-1946
|
||||
TracksChangesEntityBase asEntity = entity as TracksChangesEntityBase;
|
||||
var asEntity = entity as TracksChangesEntityBase;
|
||||
if (asEntity != null)
|
||||
{
|
||||
asEntity.ResetDirtyProperties(false);
|
||||
@@ -132,13 +132,16 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
if (ids.Any())
|
||||
{
|
||||
var entities = _cache.GetByIds(typeof(TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList());
|
||||
var entities = _cache.GetByIds(
|
||||
typeof (TEntity), ids.Select(id => id is int ? ConvertIdToGuid(id) : ConvertStringIdToGuid(id.ToString())).ToList())
|
||||
.ToArray();
|
||||
|
||||
if (ids.Count().Equals(entities.Count()) && entities.Any(x => x == null) == false)
|
||||
return entities.Select(x => (TEntity)x);
|
||||
}
|
||||
else
|
||||
{
|
||||
var allEntities = _cache.GetAllByType(typeof(TEntity));
|
||||
var allEntities = _cache.GetAllByType(typeof (TEntity)).ToArray();
|
||||
|
||||
if (allEntities.Any())
|
||||
{
|
||||
@@ -151,7 +154,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
var entityCollection = PerformGetAll(ids);
|
||||
var entityCollection = PerformGetAll(ids)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull()
|
||||
.ToArray();
|
||||
|
||||
foreach (var entity in entityCollection)
|
||||
{
|
||||
@@ -172,7 +178,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <returns></returns>
|
||||
public IEnumerable<TEntity> GetByQuery(IQuery<TEntity> query)
|
||||
{
|
||||
return PerformGetByQuery(query);
|
||||
return PerformGetByQuery(query)
|
||||
//ensure we don't include any null refs in the returned collection!
|
||||
.WhereNotNull();
|
||||
}
|
||||
|
||||
protected abstract bool PerformExists(TId id);
|
||||
|
||||
@@ -22,17 +22,20 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
internal class UserRepository : PetaPocoRepositoryBase<int, IUser>, IUserRepository
|
||||
{
|
||||
private readonly IUserTypeRepository _userTypeRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public UserRepository(IDatabaseUnitOfWork work, IUserTypeRepository userTypeRepository)
|
||||
public UserRepository(IDatabaseUnitOfWork work, IUserTypeRepository userTypeRepository, CacheHelper cacheHelper)
|
||||
: base(work)
|
||||
{
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public UserRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IUserTypeRepository userTypeRepository)
|
||||
public UserRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IUserTypeRepository userTypeRepository, CacheHelper cacheHelper)
|
||||
: base(work, cache)
|
||||
{
|
||||
_userTypeRepository = userTypeRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,IUser>
|
||||
@@ -128,6 +131,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
var list = new List<string>
|
||||
{
|
||||
"DELETE FROM cmsTask WHERE userId = @Id",
|
||||
"DELETE FROM cmsTask WHERE parentUserId = @Id",
|
||||
"DELETE FROM umbracoUser2NodePermission WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUser2NodeNotify WHERE userId = @Id",
|
||||
"DELETE FROM umbracoUserLogins WHERE userId = @Id",
|
||||
@@ -315,12 +320,24 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(object userId, params int[] entityIds)
|
||||
public IEnumerable<EntityPermission> GetUserPermissionsForEntities(int userId, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork);
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
return repo.GetUserPermissionsForEntities(userId, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper);
|
||||
repo.ReplaceUserPermissions(userId, permissions, entityIds);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private IEnumerable<IUser> ConvertFromDtos(IEnumerable<UserDto> dtos)
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Factories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
@@ -90,5 +92,42 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
protected abstract void PerformDeleteVersion(int id, Guid versionId);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// This is a fix for U4-1407 - when property types are added to a content type - the property of the entity are not actually created
|
||||
/// and we get YSODs
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="versionId"></param>
|
||||
/// <param name="contentType"></param>
|
||||
/// <param name="createDate"></param>
|
||||
/// <param name="updateDate"></param>
|
||||
/// <returns></returns>
|
||||
protected PropertyCollection GetPropertyCollection(int id, Guid versionId, IContentTypeComposition contentType, DateTime createDate, DateTime updateDate)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<PropertyDataDto>()
|
||||
.InnerJoin<PropertyTypeDto>()
|
||||
.On<PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
|
||||
.Where<PropertyDataDto>(x => x.NodeId == id)
|
||||
.Where<PropertyDataDto>(x => x.VersionId == versionId);
|
||||
|
||||
var propertyDataDtos = Database.Fetch<PropertyDataDto, PropertyTypeDto>(sql);
|
||||
var propertyFactory = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
|
||||
var properties = propertyFactory.BuildEntity(propertyDataDtos).ToArray();
|
||||
|
||||
var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);
|
||||
foreach (var property in newProperties)
|
||||
{
|
||||
var propertyDataDto = new PropertyDataDto { NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId };
|
||||
int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));
|
||||
|
||||
property.Version = versionId;
|
||||
property.Id = primaryKey;
|
||||
}
|
||||
|
||||
return new PropertyCollection(properties);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
using System;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
@@ -10,6 +11,7 @@ namespace Umbraco.Core.Persistence
|
||||
public class RepositoryFactory
|
||||
{
|
||||
private readonly bool _disableAllCache;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
|
||||
public RepositoryFactory()
|
||||
: this(false)
|
||||
@@ -17,9 +19,24 @@ namespace Umbraco.Core.Persistence
|
||||
|
||||
}
|
||||
|
||||
public RepositoryFactory(CacheHelper cacheHelper)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_disableAllCache = false;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public RepositoryFactory(bool disableAllCache, CacheHelper cacheHelper)
|
||||
{
|
||||
if (cacheHelper == null) throw new ArgumentNullException("cacheHelper");
|
||||
_disableAllCache = disableAllCache;
|
||||
_cacheHelper = cacheHelper;
|
||||
}
|
||||
|
||||
public RepositoryFactory(bool disableAllCache)
|
||||
{
|
||||
_disableAllCache = disableAllCache;
|
||||
_cacheHelper = disableAllCache ? CacheHelper.CreateDisabledCacheHelper() : ApplicationContext.Current.ApplicationCache;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +46,15 @@ namespace Umbraco.Core.Persistence
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateContentTypeRepository(uow),
|
||||
CreateTemplateRepository(uow)) { EnsureUniqueNaming = Umbraco.Core.Configuration.UmbracoSettings.EnsureUniqueNaming };
|
||||
CreateTemplateRepository(uow),
|
||||
_cacheHelper) { EnsureUniqueNaming = Configuration.UmbracoSettings.EnsureUniqueNaming };
|
||||
}
|
||||
|
||||
public virtual IContentTypeRepository CreateContentTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new ContentTypeRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
new TemplateRepository(uow, NullCacheProvider.Current));
|
||||
}
|
||||
|
||||
@@ -51,7 +69,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new DictionaryRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateLanguageRepository(uow));
|
||||
}
|
||||
|
||||
@@ -59,7 +77,7 @@ namespace Umbraco.Core.Persistence
|
||||
{
|
||||
return new LanguageRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
public virtual IMediaRepository CreateMediaRepository(IDatabaseUnitOfWork uow)
|
||||
@@ -67,14 +85,14 @@ namespace Umbraco.Core.Persistence
|
||||
return new MediaRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateMediaTypeRepository(uow)) { EnsureUniqueNaming = Umbraco.Core.Configuration.UmbracoSettings.EnsureUniqueNaming };
|
||||
CreateMediaTypeRepository(uow)) { EnsureUniqueNaming = Configuration.UmbracoSettings.EnsureUniqueNaming };
|
||||
}
|
||||
|
||||
public virtual IMediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MediaTypeRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
public virtual IRelationRepository CreateRelationRepository(IDatabaseUnitOfWork uow)
|
||||
@@ -114,33 +132,44 @@ namespace Umbraco.Core.Persistence
|
||||
NullCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IUserTypeRepository CreateUserTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserTypeRepository(
|
||||
uow,
|
||||
//There's not many user types but we query on users all the time so the result needs to be cached
|
||||
RuntimeCacheProvider.Current);
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
public virtual IUserRepository CreateUserRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new UserRepository(
|
||||
uow,
|
||||
NullCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow));
|
||||
//Need to cache users - we look up user information more than anything in the back office!
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateUserTypeRepository(uow),
|
||||
_cacheHelper);
|
||||
}
|
||||
|
||||
internal virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current, CreateMemberTypeRepository(uow));
|
||||
return new MemberRepository(
|
||||
uow,
|
||||
_disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current,
|
||||
CreateMemberTypeRepository(uow),
|
||||
CreateMemberGroupRepository(uow));
|
||||
}
|
||||
|
||||
internal virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberTypeRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : InMemoryCacheProvider.Current);
|
||||
return new MemberTypeRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current);
|
||||
}
|
||||
|
||||
internal virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
public virtual IMemberGroupRepository CreateMemberGroupRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new MemberGroupRepository(uow, _disableAllCache ? (IRepositoryCacheProvider)NullCacheProvider.Current : RuntimeCacheProvider.Current, _cacheHelper);
|
||||
}
|
||||
|
||||
public virtual IEntityRepository CreateEntityRepository(IDatabaseUnitOfWork uow)
|
||||
{
|
||||
return new EntityRepository(uow);
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
/// </summary>
|
||||
public interface ISqlSyntaxProvider
|
||||
{
|
||||
string EscapeString(string val);
|
||||
|
||||
string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType);
|
||||
string GetStringColumnStartsWithComparison(string column, string value, TextColumnType columnType);
|
||||
string GetStringColumnEndsWithComparison(string column, string value, TextColumnType columnType);
|
||||
|
||||
@@ -327,5 +327,10 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
// add message to check with their hosting provider
|
||||
return supportsCaseInsensitiveQueries;
|
||||
}
|
||||
|
||||
public override string EscapeString(string val)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(MySql.Data.MySqlClient.MySqlHelper.EscapeString(val));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,6 +103,11 @@ namespace Umbraco.Core.Persistence.SqlSyntax
|
||||
DbTypeMap.Set<byte[]>(DbType.Binary, BlobColumnDefinition);
|
||||
}
|
||||
|
||||
public virtual string EscapeString(string val)
|
||||
{
|
||||
return PetaPocoExtensions.EscapeAtSymbols(val.Replace("'", "''"));
|
||||
}
|
||||
|
||||
public virtual string GetStringColumnEqualComparison(string column, string value, TextColumnType columnType)
|
||||
{
|
||||
//use the 'upper' method to always ensure strings are matched without case sensitivity no matter what the db setting.
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace Umbraco.Core
|
||||
/// it will use the cached resolved plugins that it has already found which means that no assembly scanning is necessary. This leads
|
||||
/// to much faster startup times.
|
||||
/// </remarks>
|
||||
internal class PluginManager
|
||||
public class PluginManager
|
||||
{
|
||||
private readonly ApplicationContext _appContext;
|
||||
private const string CacheKey = "umbraco-plugins.list";
|
||||
@@ -106,7 +106,7 @@ namespace Umbraco.Core
|
||||
/// <remarks>
|
||||
/// The setter is generally only used for unit tests
|
||||
/// </remarks>
|
||||
internal static PluginManager Current
|
||||
public static PluginManager Current
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -750,15 +750,16 @@ namespace Umbraco.Core
|
||||
UpdateCachedPluginsFile<T>(typeList.GetTypes(), resolutionKind);
|
||||
}
|
||||
|
||||
#region Public Methods
|
||||
/// <summary>
|
||||
/// Generic method to find the specified type and cache the result
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypes<T>(bool cacheResult = true)
|
||||
public IEnumerable<Type> ResolveTypes<T>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
{
|
||||
return ResolveTypes<T>(
|
||||
() => TypeFinder.FindClassesOfType<T>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesOfType<T>(specificAssemblies ?? AssembliesToScan),
|
||||
TypeResolutionKind.FindAllTypes,
|
||||
cacheResult);
|
||||
}
|
||||
@@ -769,11 +770,11 @@ namespace Umbraco.Core
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true)
|
||||
public IEnumerable<Type> ResolveTypesWithAttribute<T, TAttribute>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<T>(
|
||||
() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesOfTypeWithAttribute<T, TAttribute>(specificAssemblies ?? AssembliesToScan),
|
||||
TypeResolutionKind.FindTypesWithAttribute,
|
||||
cacheResult);
|
||||
}
|
||||
@@ -783,14 +784,15 @@ namespace Umbraco.Core
|
||||
/// </summary>
|
||||
/// <typeparam name="TAttribute"></typeparam>
|
||||
/// <returns></returns>
|
||||
internal IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true)
|
||||
public IEnumerable<Type> ResolveAttributedTypes<TAttribute>(bool cacheResult = true, IEnumerable<Assembly> specificAssemblies = null)
|
||||
where TAttribute : Attribute
|
||||
{
|
||||
return ResolveTypes<TAttribute>(
|
||||
() => TypeFinder.FindClassesWithAttribute<TAttribute>(AssembliesToScan),
|
||||
() => TypeFinder.FindClassesWithAttribute<TAttribute>(specificAssemblies ?? AssembliesToScan),
|
||||
TypeResolutionKind.FindAttributedTypes,
|
||||
cacheResult);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used for unit tests
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// A marker interface used internally to identify Umbraco built-in Users membership providers
|
||||
/// </summary>
|
||||
internal interface IUsersMembershipProvider
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,16 @@ namespace Umbraco.Core.Security
|
||||
{
|
||||
internal static class MembershipProviderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns true if the provider specified is a built-in Umbraco users provider
|
||||
/// </summary>
|
||||
/// <param name="membershipProvider"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsUmbracoUsersProvider(this MembershipProvider membershipProvider)
|
||||
{
|
||||
return (membershipProvider is IUsersMembershipProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if the provider specified is a built-in Umbraco membership provider
|
||||
/// </summary>
|
||||
@@ -20,6 +30,8 @@ namespace Umbraco.Core.Security
|
||||
return (membershipProvider is UmbracoMembershipProviderBase);
|
||||
}
|
||||
|
||||
//TODO: Add role provider checks too
|
||||
|
||||
public static UmbracoMembershipProviderBase AsUmbracoMembershipProvider(this MembershipProvider membershipProvider)
|
||||
{
|
||||
return (UmbracoMembershipProviderBase)membershipProvider;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System.Collections.Specialized;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
/// <summary>
|
||||
/// An interface for exposing the content type properties for storing membership data in when
|
||||
/// a membership provider's data is backed by an Umbraco content type.
|
||||
/// </summary>
|
||||
public interface IUmbracoMemberTypeMembershipProvider
|
||||
{
|
||||
|
||||
string LockPropertyTypeAlias { get; }
|
||||
string LastLockedOutPropertyTypeAlias { get; }
|
||||
string FailedPasswordAttemptsPropertyTypeAlias { get; }
|
||||
string ApprovedPropertyTypeAlias { get; }
|
||||
string CommentPropertyTypeAlias { get; }
|
||||
string LastLoginPropertyTypeAlias { get; }
|
||||
string LastPasswordChangedPropertyTypeAlias { get; }
|
||||
string PasswordRetrievalQuestionPropertyTypeAlias { get; }
|
||||
string PasswordRetrievalAnswerPropertyTypeAlias { get; }
|
||||
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,6 @@ using System.Web.Security;
|
||||
|
||||
namespace Umbraco.Core.Security
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A base membership provider class for umbraco providers
|
||||
/// </summary>
|
||||
|
||||
@@ -9,6 +9,7 @@ using Umbraco.Core.Events;
|
||||
using Umbraco.Core.IO;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Caching;
|
||||
@@ -58,14 +59,32 @@ namespace Umbraco.Core.Services
|
||||
_repositoryFactory = repositoryFactory;
|
||||
}
|
||||
|
||||
//TODO: There are various ways to expose permission setting on this service, we just need to list out the different ways we'll need to
|
||||
// be able to acheive this for the core, for now this is here so I can run a unit test.
|
||||
internal void AssignContentPermissions(IContent entity, char permission, IEnumerable<object> userIds)
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
public void AssignContentPermission(IContent entity, char permission, IEnumerable<int> userIds)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
repository.AssignEntityPermissions(entity, permission, userIds);
|
||||
repository.AssignEntityPermission(entity, permission, userIds);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
return repository.GetPermissionsForEntity(content.Id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,12 +176,20 @@ namespace Umbraco.Core.Services
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parentId, contentType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parentId), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
@@ -172,6 +199,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
@@ -197,12 +226,20 @@ namespace Umbraco.Core.Services
|
||||
var contentType = FindContentTypeByAlias(contentTypeAlias);
|
||||
var content = new Content(name, parent, contentType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IContent>(content, contentTypeAlias, parent), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this))
|
||||
{
|
||||
content.WasCancelled = true;
|
||||
return content;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateContentRepository(uow))
|
||||
{
|
||||
@@ -212,6 +249,8 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IContent>(content, false, contentTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Content '{0}' was created with Id {1}", name, content.Id), content.CreatorId, content.Id);
|
||||
@@ -622,10 +661,10 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
[Obsolete("Use PublishWithStatus instead, that method will provide more detailed information on the outcome")]
|
||||
public bool Publish(IContent content, int userId = 0)
|
||||
{
|
||||
var result = SaveAndPublishDo(content, userId);
|
||||
LogHelper.Info<ContentService>("Call was made to ContentService.Publish, use PublishWithStatus instead since that method will provide more detailed information on the outcome");
|
||||
return result.Success;
|
||||
}
|
||||
|
||||
@@ -1217,6 +1256,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Sends an <see cref="IContent"/> to Publication, which executes handlers and events for the 'Send to Publication' action.
|
||||
/// </summary>
|
||||
@@ -1491,6 +1531,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
@@ -1962,6 +2004,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Create
|
||||
/// </summary>
|
||||
[Obsolete("Use the Created event instead, the Creating and Created events both offer the same functionality, Creating event has been deprecated.")]
|
||||
public static event TypedEventHandler<IContentService, NewEventArgs<IContent>> Creating;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -214,17 +214,17 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var uow = _uowProvider.GetUnitOfWork())
|
||||
{
|
||||
var sortOrderObj =
|
||||
uow.Database.ExecuteScalar<object>(
|
||||
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
|
||||
int sortOrder;
|
||||
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
|
||||
using (var transaction = uow.Database.GetTransaction())
|
||||
{
|
||||
var sortOrderObj =
|
||||
uow.Database.ExecuteScalar<object>(
|
||||
"SELECT max(sortorder) FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
|
||||
int sortOrder;
|
||||
if (sortOrderObj == null || int.TryParse(sortOrderObj.ToString(), out sortOrder) == false)
|
||||
{
|
||||
sortOrder = 1;
|
||||
}
|
||||
|
||||
foreach (var value in values)
|
||||
{
|
||||
var dto = new DataTypePreValueDto { DataTypeNodeId = id, Value = value, SortOrder = sortOrder };
|
||||
|
||||
@@ -11,6 +11,20 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
public interface IContentService : IService
|
||||
{
|
||||
/// <summary>
|
||||
/// Assigns a single permission to the current content item for the specified user ids
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="userIds"></param>
|
||||
void AssignContentPermission(IContent entity, char permission, IEnumerable<int> userIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content);
|
||||
|
||||
bool SendToPublication(IContent content, int userId = 0);
|
||||
|
||||
@@ -249,7 +263,6 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="content">The <see cref="IContent"/> to publish</param>
|
||||
/// <param name="userId">Optional Id of the User issueing the publishing</param>
|
||||
/// <returns>True if publishing succeeded, otherwise False</returns>
|
||||
[Obsolete("Use PublishWithStatus instead, that method will provide more detailed information on the outcome")]
|
||||
bool Publish(IContent content, int userId = 0);
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public interface IMemberGroupService : IService
|
||||
{
|
||||
IEnumerable<IMemberGroup> GetAll();
|
||||
IMemberGroup GetById(int id);
|
||||
IMemberGroup GetByName(string name);
|
||||
void Save(IMemberGroup memberGroup, bool raiseEvents = true);
|
||||
void Delete(IMemberGroup memberGroup);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Defines the MemberService, which is an easy access to operations involving (umbraco) members.
|
||||
/// </summary>
|
||||
internal interface IMemberService : IMembershipMemberService
|
||||
public interface IMemberService : IMembershipMemberService
|
||||
{
|
||||
/// <summary>
|
||||
/// Checks if a member with the id exists
|
||||
@@ -16,14 +16,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
bool Exists(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by its id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IMember GetById(int id);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by the unique key
|
||||
/// </summary>
|
||||
@@ -31,6 +24,13 @@ namespace Umbraco.Core.Services
|
||||
/// <returns></returns>
|
||||
IMember GetByKey(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a member by it's id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IMember GetById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get all members for the member type alias
|
||||
/// </summary>
|
||||
@@ -65,6 +65,17 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="memberTypeId"></param>
|
||||
void DeleteMembersOfType(int memberTypeId);
|
||||
|
||||
/// <summary>
|
||||
/// Find members based on their display name
|
||||
/// </summary>
|
||||
/// <param name="displayNameToMatch"></param>
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <param name="matchType"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<IMember> FindMembersByDisplayName(string displayNameToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Get members based on a property search
|
||||
/// </summary>
|
||||
|
||||
@@ -3,28 +3,28 @@ using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal interface IMemberTypeService : IService
|
||||
{
|
||||
public 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);
|
||||
IEnumerable<IMemberType> GetAll(params int[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMemberType"/> object by its Id
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMediaType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMediaType"/></returns>
|
||||
IMemberType GetMemberType(int id);
|
||||
IMemberType Get(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="IMemberType"/> object by its Alias
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the <see cref="IMediaType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMediaType"/></returns>
|
||||
IMemberType GetMemberType(string alias);
|
||||
IMemberType Get(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Saves a single <see cref="IMemberType"/> object
|
||||
|
||||
@@ -6,16 +6,16 @@ using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Defines part of the MemberService, which is specific to methods used by the membership provider.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipMemberService : IMembershipMemberService<IMember>
|
||||
public interface IMembershipMemberService : IMembershipMemberService<IMember>, IMembershipRoleService<IMember>
|
||||
{
|
||||
IMember CreateMember(string email, string username, string password, IMemberType memberType);
|
||||
IMember CreateMember(string username, string email, string password, string memberType);
|
||||
IMember CreateMemberWithIdentity(string username, string email, string password, IMemberType memberType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Core.Services
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipMemberService<T> : IService
|
||||
public interface IMembershipMemberService<T> : IService
|
||||
where T : class, IMembershipUser
|
||||
{
|
||||
/// <summary>
|
||||
@@ -48,9 +48,14 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="password"></param>
|
||||
/// <param name="memberTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
T CreateMember(string username, string email, string password, string memberTypeAlias);
|
||||
T CreateWithIdentity(string username, string email, string password, string memberTypeAlias);
|
||||
|
||||
T GetById(object id);
|
||||
/// <summary>
|
||||
/// Gets the member by the provider key
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
T GetByProviderKey(object id);
|
||||
|
||||
/// <summary>
|
||||
/// Get a member by email
|
||||
@@ -62,20 +67,20 @@ namespace Umbraco.Core.Services
|
||||
T GetByUsername(string login);
|
||||
|
||||
void Delete(T membershipUser);
|
||||
|
||||
void Save(T entity, bool raiseEvents = true);
|
||||
|
||||
void Save(T membershipUser, bool raiseEvents = true);
|
||||
void Save(IEnumerable<T> entities, bool raiseEvents = true);
|
||||
|
||||
void Save(IEnumerable<T> members, bool raiseEvents = true);
|
||||
IEnumerable<T> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
IEnumerable<T> FindMembersByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
IEnumerable<T> FindMembersByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
IEnumerable<T> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the total number of members based on the count type
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
int GetMemberCount(MemberCountType countType);
|
||||
int GetCount(MemberCountType countType);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of paged member data
|
||||
@@ -84,6 +89,6 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="pageSize"></param>
|
||||
/// <param name="totalRecords"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<T> GetAllMembers(int pageIndex, int pageSize, out int totalRecords);
|
||||
IEnumerable<T> GetAll(int pageIndex, int pageSize, out int totalRecords);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public interface IMembershipRoleService<out T>
|
||||
where T : class, IMembershipUser
|
||||
{
|
||||
void AddRole(string roleName);
|
||||
IEnumerable<string> GetAllRoles();
|
||||
IEnumerable<string> GetAllRoles(int memberId);
|
||||
IEnumerable<string> GetAllRoles(string username);
|
||||
IEnumerable<T> GetMembersInRole(string roleName);
|
||||
IEnumerable<T> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
|
||||
bool DeleteRole(string roleName, bool throwIfBeingUsed);
|
||||
void AssignRoles(string[] usernames, string[] roleNames);
|
||||
void DissociateRoles(string[] usernames, string[] roleNames);
|
||||
void AssignRoles(int[] memberIds, string[] roleNames);
|
||||
void DissociateRoles(int[] memberIds, string[] roleNames);
|
||||
}
|
||||
}
|
||||
@@ -8,10 +8,10 @@ namespace Umbraco.Core.Services
|
||||
/// <remarks>
|
||||
/// Idea is to have this is an isolated interface so that it can be easily 'replaced' in the membership provider impl.
|
||||
/// </remarks>
|
||||
internal interface IMembershipUserService : IMembershipMemberService<IUser>
|
||||
public interface IMembershipUserService : IMembershipMemberService<IUser>
|
||||
{
|
||||
|
||||
IUser CreateMember(string username, string email, string password, IUserType userType);
|
||||
IUser CreateUserWithIdentity(string username, string email, string password, IUserType userType);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,64 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Defines the UserService, which is an easy access to operations involving <see cref="IProfile"/> and eventually Users.
|
||||
/// </summary>
|
||||
internal interface IUserService : IMembershipUserService
|
||||
public interface IUserService : IMembershipUserService
|
||||
{
|
||||
/// <summary>
|
||||
/// To permanently delete the user pass in true, otherwise they will just be disabled
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="deletePermanently"></param>
|
||||
void Delete(IUser user, bool deletePermanently);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IProfile by User Id.
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the User to retrieve</param>
|
||||
/// <returns><see cref="IProfile"/></returns>
|
||||
IProfile GetProfileById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Get profile by username
|
||||
/// </summary>
|
||||
/// <param name="username"></param>
|
||||
/// <returns></returns>
|
||||
IProfile GetProfileByUserName(string username);
|
||||
|
||||
/// <summary>
|
||||
/// Get user by Id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IUser GetUserById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// This is useful when an entire section is removed from config
|
||||
/// </summary>
|
||||
/// <param name="sectionAlias"></param>
|
||||
void DeleteSectionFromAllUsers(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Get permissions set for user and specified node ids
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="nodeIds">
|
||||
/// Specifiying nothing will return all user permissions for all nodes
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds);
|
||||
|
||||
#region User types
|
||||
|
||||
IEnumerable<IUserType> GetAllUserTypes(params int[] ids);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Alias
|
||||
/// </summary>
|
||||
@@ -26,6 +72,13 @@ namespace Umbraco.Core.Services
|
||||
/// <returns><see cref="IUserType"/></returns>
|
||||
IUserType GetUserTypeByAlias(string alias);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Id
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
IUserType GetUserTypeById(int id);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Name
|
||||
/// </summary>
|
||||
@@ -45,19 +98,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="userType"></param>
|
||||
void DeleteUserType(IUserType userType);
|
||||
|
||||
/// <summary>
|
||||
/// This is useful when an entire section is removed from config
|
||||
/// </summary>
|
||||
/// <param name="sectionAlias"></param>
|
||||
void DeleteSectionFromAllUsers(string sectionAlias);
|
||||
|
||||
/// <summary>
|
||||
/// Returns a list of the sections that the user is allowed access to
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerable<string> GetUserSections(IUser user);
|
||||
|
||||
IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -122,12 +122,23 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parentId, mediaType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parentId), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(media), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
//TODO: Once we fix up the transaction logic, these write locks should be replaced with
|
||||
// an outter transaction instead.
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -142,6 +153,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parentId), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
@@ -166,12 +179,21 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var mediaType = FindMediaTypeByAlias(mediaTypeAlias);
|
||||
var media = new Models.Media(name, parent, mediaType);
|
||||
|
||||
//NOTE: I really hate the notion of these Creating/Created events - they are so inconsistent, I've only just found
|
||||
// out that in these 'WithIdentity' methods, the Saving/Saved events were not fired, wtf. Anyways, they're added now.
|
||||
if (Creating.IsRaisedEventCancelled(new NewEventArgs<IMedia>(media, mediaTypeAlias, parent), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMedia>(media), this))
|
||||
{
|
||||
media.WasCancelled = true;
|
||||
return media;
|
||||
}
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -186,6 +208,8 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMedia>(media, false), this);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMedia>(media, false, mediaTypeAlias, parent), this);
|
||||
|
||||
Audit.Add(AuditTypes.New, string.Format("Media '{0}' was created with Id {1}", name, media.Id), media.CreatorId, media.Id);
|
||||
@@ -938,6 +962,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
|
||||
Audit.Add(AuditTypes.Publish, "RebuildXmlStructures completed, the xml has been regenerated in the database", 0, -1);
|
||||
@@ -1040,6 +1066,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Create
|
||||
/// </summary>
|
||||
[Obsolete("Use the Created event instead, the Creating and Created events both offer the same functionality, Creating event has been deprecated.")]
|
||||
public static event TypedEventHandler<IMediaService, NewEventArgs<IMedia>> Creating;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
public class MemberGroupService : IMemberGroupService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
public MemberGroupService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberGroupService(IDatabaseUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
{
|
||||
}
|
||||
|
||||
public MemberGroupService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
{
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_uowProvider = provider;
|
||||
|
||||
//Proxy events!
|
||||
MemberGroupRepository.SavedMemberGroup += MemberGroupRepository_SavedMemberGroup;
|
||||
MemberGroupRepository.SavingMemberGroup += MemberGroupRepository_SavingMemberGroup;
|
||||
}
|
||||
|
||||
#region Proxied event handlers
|
||||
void MemberGroupRepository_SavingMemberGroup(IMemberGroupRepository sender, SaveEventArgs<IMemberGroup> e)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(e.SavedEntities), this))
|
||||
{
|
||||
e.Cancel = true;
|
||||
}
|
||||
}
|
||||
|
||||
void MemberGroupRepository_SavedMemberGroup(IMemberGroupRepository sender, SaveEventArgs<IMemberGroup> e)
|
||||
{
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberGroup>(e.SavedEntities, false), this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
public IEnumerable<IMemberGroup> GetAll()
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetAll();
|
||||
}
|
||||
}
|
||||
|
||||
public IMemberGroup GetById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(id);
|
||||
}
|
||||
}
|
||||
|
||||
public IMemberGroup GetByName(string name)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.GetByName(name);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(IMemberGroup memberGroup, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberGroup>(memberGroup), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(memberGroup);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberGroup>(memberGroup, false), this);
|
||||
}
|
||||
|
||||
public void Delete(IMemberGroup memberGroup)
|
||||
{
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMemberGroup>(memberGroup), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.Delete(memberGroup);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMemberGroup>(memberGroup, false), this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete of a member group
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberGroupService, DeleteEventArgs<IMemberGroup>> Deleting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete of a member group
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberGroupService, DeleteEventArgs<IMemberGroup>> Deleted;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save of a member group
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to proxy these events because the events need to take place at the repo level
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberGroupService, SaveEventArgs<IMemberGroup>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save of a member group
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// We need to proxy these events because the events need to take place at the repo level
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberGroupService, SaveEventArgs<IMemberGroup>> Saved;
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,13 @@ using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Web.Security;
|
||||
using System.Xml.Linq;
|
||||
using Umbraco.Core.Auditing;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.Repositories;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using System.Linq;
|
||||
@@ -18,26 +20,31 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Represents the MemberService.
|
||||
/// </summary>
|
||||
internal class MemberService : IMemberService
|
||||
public class MemberService : IMemberService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IMemberGroupService _memberGroupService;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
|
||||
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
|
||||
|
||||
public MemberService(RepositoryFactory repositoryFactory)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory)
|
||||
public MemberService(RepositoryFactory repositoryFactory, IMemberGroupService memberGroupService)
|
||||
: this(new PetaPocoUnitOfWorkProvider(), repositoryFactory, memberGroupService)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider)
|
||||
: this(provider, new RepositoryFactory())
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, IMemberGroupService memberGroupService)
|
||||
: this(provider, new RepositoryFactory(), memberGroupService)
|
||||
{
|
||||
}
|
||||
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory)
|
||||
public MemberService(IDatabaseUnitOfWorkProvider provider, RepositoryFactory repositoryFactory, IMemberGroupService memberGroupService)
|
||||
{
|
||||
if (provider == null) throw new ArgumentNullException("provider");
|
||||
if (repositoryFactory == null) throw new ArgumentNullException("repositoryFactory");
|
||||
if (memberGroupService == null) throw new ArgumentNullException("memberGroupService");
|
||||
_repositoryFactory = repositoryFactory;
|
||||
_memberGroupService = memberGroupService;
|
||||
_uowProvider = provider;
|
||||
}
|
||||
|
||||
@@ -205,6 +212,38 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersByDisplayName(string displayNameToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
var query = new Query<IMember>();
|
||||
|
||||
switch (matchType)
|
||||
{
|
||||
case StringPropertyMatchType.Exact:
|
||||
query.Where(member => member.Name.Equals(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Contains:
|
||||
query.Where(member => member.Name.Contains(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.StartsWith:
|
||||
query.Where(member => member.Name.StartsWith(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.EndsWith:
|
||||
query.Where(member => member.Name.EndsWith(displayNameToMatch));
|
||||
break;
|
||||
case StringPropertyMatchType.Wildcard:
|
||||
query.Where(member => member.Name.SqlWildcard(displayNameToMatch, TextColumnType.NVarchar));
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException("matchType");
|
||||
}
|
||||
|
||||
return repository.GetPagedResultsByQuery(query, pageIndex, pageSize, out totalRecords, dto => dto.Name);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does a search for members that contain the specified string in their email address
|
||||
/// </summary>
|
||||
@@ -214,7 +253,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="pageIndex"></param>
|
||||
/// <param name="pageSize"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<IMember> FindMembersByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IMember> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -246,7 +285,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IMember> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -487,7 +526,7 @@ namespace Umbraco.Core.Services
|
||||
/// that have their last active date within the Membership.UserIsOnlineTimeWindow (which is in minutes). It isn't exact science
|
||||
/// but that is how MS have made theirs so we'll follow that principal.
|
||||
/// </remarks>
|
||||
public int GetMemberCount(MemberCountType countType)
|
||||
public int GetCount(MemberCountType countType)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -527,7 +566,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetAllMembers(int pageIndex, int pageSize, out int totalRecords)
|
||||
public IEnumerable<IMember> GetAll(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -536,11 +575,29 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IMember CreateMember(string email, string username, string password, IMemberType memberType)
|
||||
public IMember CreateMember(string username, string email, string password, string memberTypeAlias)
|
||||
{
|
||||
var memberTypeService = ApplicationContext.Current.Services.MemberTypeService;
|
||||
var memberType = memberTypeService.Get(memberTypeAlias);
|
||||
|
||||
var member = new Member(username, email.ToLower().Trim(), username, password, -1, memberType);
|
||||
|
||||
Created.RaiseEvent(new NewEventArgs<IMember>(member, false, memberTypeAlias, -1), this);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
public IMember CreateMemberWithIdentity(string username, string email, string password, IMemberType memberType)
|
||||
{
|
||||
if (memberType == null) throw new ArgumentNullException("memberType");
|
||||
|
||||
var member = new Member(email, email, username, password, -1, memberType);
|
||||
var member = new Member(username, email.ToLower().Trim(), username, password, -1, memberType);
|
||||
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(member), this))
|
||||
{
|
||||
member.WasCancelled = true;
|
||||
return member;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
@@ -553,9 +610,12 @@ namespace Umbraco.Core.Services
|
||||
CreateAndSaveMemberXml(xml, member.Id, uow.Database);
|
||||
}
|
||||
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(member, false), this);
|
||||
Created.RaiseEvent(new NewEventArgs<IMember>(member, false, memberType.Alias, -1), this);
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates and persists a new Member
|
||||
/// </summary>
|
||||
@@ -564,7 +624,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="password"></param>
|
||||
/// <param name="memberTypeAlias"></param>
|
||||
/// <returns></returns>
|
||||
public IMember CreateMember(string email, string username, string password, string memberTypeAlias)
|
||||
IMember IMembershipMemberService<IMember>.CreateWithIdentity(string username, string email, string password, string memberTypeAlias)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
IMemberType memberType;
|
||||
@@ -580,7 +640,7 @@ namespace Umbraco.Core.Services
|
||||
throw new ArgumentException(string.Format("No MemberType matching the passed in Alias: '{0}' was found", memberTypeAlias));
|
||||
}
|
||||
|
||||
return CreateMember(email, username, password, memberTypeAlias);
|
||||
return CreateMemberWithIdentity(username, email, password, memberType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -591,17 +651,18 @@ namespace Umbraco.Core.Services
|
||||
/// </remarks>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public IMember GetById(object id)
|
||||
public IMember GetByProviderKey(object id)
|
||||
{
|
||||
if (id is int)
|
||||
{
|
||||
return GetById((int)id);
|
||||
}
|
||||
|
||||
if (id is Guid)
|
||||
var asGuid = id.TryConvertTo<Guid>();
|
||||
if (asGuid.Success)
|
||||
{
|
||||
return GetByKey((Guid)id);
|
||||
}
|
||||
var asInt = id.TryConvertTo<int>();
|
||||
if (asInt.Success)
|
||||
{
|
||||
return GetById((int)id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
@@ -631,7 +692,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IMember>.Builder.Where(x => x.Username == userName);
|
||||
var query = Query<IMember>.Builder.Where(x => x.Username.Equals(userName));
|
||||
var member = repository.GetByQuery(query).FirstOrDefault();
|
||||
|
||||
return member;
|
||||
@@ -656,39 +717,42 @@ namespace Umbraco.Core.Services
|
||||
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMember>(member, false), this);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves an updated Member
|
||||
/// </summary>
|
||||
/// <param name="member"></param>
|
||||
/// <param name="entity"></param>
|
||||
/// <param name="raiseEvents"></param>
|
||||
public void Save(IMember member, bool raiseEvents = true)
|
||||
public void Save(IMember entity, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(member), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(entity), this))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(member);
|
||||
repository.AddOrUpdate(entity);
|
||||
uow.Commit();
|
||||
|
||||
var xml = member.ToXml();
|
||||
CreateAndSaveMemberXml(xml, member.Id, uow.Database);
|
||||
var xml = entity.ToXml();
|
||||
CreateAndSaveMemberXml(xml, entity.Id, uow.Database);
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(member, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(entity, false), this);
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<IMember> members, bool raiseEvents = true)
|
||||
public void Save(IEnumerable<IMember> entities, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(members), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMember>(entities), this))
|
||||
return;
|
||||
}
|
||||
using (new WriteLock(Locker))
|
||||
@@ -696,7 +760,7 @@ namespace Umbraco.Core.Services
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
foreach (var member in members)
|
||||
foreach (var member in entities)
|
||||
{
|
||||
repository.AddOrUpdate(member);
|
||||
}
|
||||
@@ -704,19 +768,143 @@ namespace Umbraco.Core.Services
|
||||
//commit the whole lot in one go
|
||||
uow.Commit();
|
||||
|
||||
foreach (var member in members)
|
||||
foreach (var member in entities)
|
||||
{
|
||||
CreateAndSaveMemberXml(member.ToXml(), member.Id, uow.Database);
|
||||
}
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(members, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMember>(entities, false), this);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region IMembershipRoleService Implementation
|
||||
|
||||
public void AddRole(string roleName)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.CreateIfNotExists(roleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles()
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetAll();
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles(int memberId)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetMemberGroupsForMember(memberId);
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<string> GetAllRoles(string username)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var result = repository.GetMemberGroupsForMember(username);
|
||||
return result.Select(x => x.Name).Distinct();
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> GetMembersInRole(string roleName)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
return repository.GetByMemberGroup(roleName);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IMember> FindMembersInRole(string roleName, string usernameToMatch, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberRepository(uow))
|
||||
{
|
||||
return repository.FindMembersInRole(roleName, usernameToMatch, matchType);
|
||||
}
|
||||
}
|
||||
|
||||
public bool DeleteRole(string roleName, bool throwIfBeingUsed)
|
||||
{
|
||||
using (new WriteLock(Locker))
|
||||
{
|
||||
if (throwIfBeingUsed)
|
||||
{
|
||||
var inRole = GetMembersInRole(roleName);
|
||||
if (inRole.Any())
|
||||
{
|
||||
throw new InvalidOperationException("The role " + roleName + " is currently assigned to members");
|
||||
}
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
var qry = new Query<IMemberGroup>().Where(g => g.Name == roleName);
|
||||
var found = repository.GetByQuery(qry).ToArray();
|
||||
|
||||
foreach (var memberGroup in found)
|
||||
{
|
||||
_memberGroupService.Delete(memberGroup);
|
||||
}
|
||||
return found.Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AssignRoles(usernames, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(string[] usernames, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.DissociateRoles(usernames, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void AssignRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.AssignRoles(memberIds, roleNames);
|
||||
}
|
||||
}
|
||||
|
||||
public void DissociateRoles(int[] memberIds, string[] roleNames)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateMemberGroupRepository(uow))
|
||||
{
|
||||
repository.DissociateRoles(memberIds, roleNames);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Rebuilds all xml content in the cmsContentXml table for all media
|
||||
/// </summary>
|
||||
@@ -793,6 +981,8 @@ namespace Umbraco.Core.Services
|
||||
|
||||
//bulk insert it into the database
|
||||
uow.Database.BulkInsertRecords(xmlItems, tr);
|
||||
|
||||
tr.Complete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -806,7 +996,6 @@ namespace Umbraco.Core.Services
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
@@ -821,6 +1010,15 @@ namespace Umbraco.Core.Services
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberService, SaveEventArgs<IMember>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Create
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Please note that the Member object has been created, but might not have been saved
|
||||
/// so it does not have an identity yet (meaning no Id has been set).
|
||||
/// </remarks>
|
||||
public static event TypedEventHandler<IMemberService, NewEventArgs<IMember>> Created;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
@@ -890,5 +1088,6 @@ namespace Umbraco.Core.Services
|
||||
|
||||
// return new Member(name, email, username, password, -1, memType);
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal class MemberTypeService : ContentTypeServiceBase, IMemberTypeService
|
||||
public class MemberTypeService : ContentTypeServiceBase, IMemberTypeService
|
||||
{
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Core.Services
|
||||
_memberService = memberService;
|
||||
}
|
||||
|
||||
public IEnumerable<IMemberType> GetAllMemberTypes(params int[] ids)
|
||||
public IEnumerable<IMemberType> GetAll(params int[] ids)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -49,7 +49,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="id">Id of the <see cref="IMemberType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMemberType"/></returns>
|
||||
public IMemberType GetMemberType(int id)
|
||||
public IMemberType Get(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -62,7 +62,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="alias">Alias of the <see cref="IMemberType"/> to retrieve</param>
|
||||
/// <returns><see cref="IMemberType"/></returns>
|
||||
public IMemberType GetMemberType(string alias)
|
||||
public IMemberType Get(string alias)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateMemberTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -75,7 +75,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
public void Save(IMemberType memberType, int userId = 0)
|
||||
{
|
||||
if (SavingMemberType.IsRaisedEventCancelled(new SaveEventArgs<IMemberType>(memberType), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberType>(memberType), this))
|
||||
return;
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
@@ -91,14 +91,14 @@ namespace Umbraco.Core.Services
|
||||
|
||||
UpdateContentXmlStructure(memberType);
|
||||
}
|
||||
SavedMemberType.RaiseEvent(new SaveEventArgs<IMemberType>(memberType, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberType>(memberType, false), this);
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<IMemberType> memberTypes, int userId = 0)
|
||||
{
|
||||
var asArray = memberTypes.ToArray();
|
||||
|
||||
if (SavingMemberType.IsRaisedEventCancelled(new SaveEventArgs<IMemberType>(asArray), this))
|
||||
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IMemberType>(asArray), this))
|
||||
return;
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
@@ -118,12 +118,12 @@ namespace Umbraco.Core.Services
|
||||
|
||||
UpdateContentXmlStructure(asArray.Cast<IContentTypeBase>().ToArray());
|
||||
}
|
||||
SavedMemberType.RaiseEvent(new SaveEventArgs<IMemberType>(asArray, false), this);
|
||||
Saved.RaiseEvent(new SaveEventArgs<IMemberType>(asArray, false), this);
|
||||
}
|
||||
|
||||
public void Delete(IMemberType memberType, int userId = 0)
|
||||
{
|
||||
if (DeletingMemberType.IsRaisedEventCancelled(new DeleteEventArgs<IMemberType>(memberType), this))
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMemberType>(memberType), this))
|
||||
return;
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
@@ -136,7 +136,7 @@ namespace Umbraco.Core.Services
|
||||
repository.Delete(memberType);
|
||||
uow.Commit();
|
||||
|
||||
DeletedMemberType.RaiseEvent(new DeleteEventArgs<IMemberType>(memberType, false), this);
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMemberType>(memberType, false), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,7 +145,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
var asArray = memberTypes.ToArray();
|
||||
|
||||
if (DeletingMemberType.IsRaisedEventCancelled(new DeleteEventArgs<IMemberType>(asArray), this))
|
||||
if (Deleting.IsRaisedEventCancelled(new DeleteEventArgs<IMemberType>(asArray), this))
|
||||
return;
|
||||
|
||||
using (new WriteLock(Locker))
|
||||
@@ -165,7 +165,7 @@ namespace Umbraco.Core.Services
|
||||
|
||||
uow.Commit();
|
||||
|
||||
DeletedMemberType.RaiseEvent(new DeleteEventArgs<IMemberType>(asArray, false), this);
|
||||
Deleted.RaiseEvent(new DeleteEventArgs<IMemberType>(asArray, false), this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,21 +195,21 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberTypeService, SaveEventArgs<IMemberType>> SavingMemberType;
|
||||
public static event TypedEventHandler<IMemberTypeService, SaveEventArgs<IMemberType>> Saving;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberTypeService, SaveEventArgs<IMemberType>> SavedMemberType;
|
||||
public static event TypedEventHandler<IMemberTypeService, SaveEventArgs<IMemberType>> Saved;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberTypeService, DeleteEventArgs<IMemberType>> DeletingMemberType;
|
||||
public static event TypedEventHandler<IMemberTypeService, DeleteEventArgs<IMemberType>> Deleting;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IMemberTypeService, DeleteEventArgs<IMemberType>> DeletedMemberType;
|
||||
public static event TypedEventHandler<IMemberTypeService, DeleteEventArgs<IMemberType>> Deleted;
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Services
|
||||
IContent[] allVersions = null;
|
||||
|
||||
int totalUsers;
|
||||
var allUsers = _userService.GetAllMembers(0, int.MaxValue, out totalUsers);
|
||||
var allUsers = _userService.GetAll(0, int.MaxValue, out totalUsers);
|
||||
foreach (var u in allUsers)
|
||||
{
|
||||
if (u.IsApproved == false) continue;
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace Umbraco.Core.Services
|
||||
//private Lazy<ISectionService> _sectionService;
|
||||
//private Lazy<IMacroService> _macroService;
|
||||
private Lazy<IMemberTypeService> _memberTypeService;
|
||||
private Lazy<IMemberGroupService> _memberGroupService;
|
||||
private Lazy<INotificationService> _notificationService;
|
||||
|
||||
/// <summary>
|
||||
@@ -45,6 +46,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="sectionService"></param>
|
||||
/// <param name="treeService"></param>
|
||||
/// <param name="tagService"></param>
|
||||
/// <param name="memberGroupService"></param>
|
||||
public ServiceContext(
|
||||
IContentService contentService,
|
||||
IMediaService mediaService,
|
||||
@@ -54,7 +56,8 @@ namespace Umbraco.Core.Services
|
||||
ILocalizationService localizationService,
|
||||
PackagingService packagingService,
|
||||
IEntityService entityService,
|
||||
IRelationService relationService/*,
|
||||
IRelationService relationService,
|
||||
IMemberGroupService memberGroupService/*,
|
||||
ISectionService sectionService,
|
||||
IApplicationTreeService treeService*/)
|
||||
{
|
||||
@@ -67,6 +70,7 @@ namespace Umbraco.Core.Services
|
||||
_packagingService = new Lazy<PackagingService>(() => packagingService);
|
||||
_entityService = new Lazy<IEntityService>(() => entityService);
|
||||
_relationService = new Lazy<IRelationService>(() => relationService);
|
||||
_memberGroupService = new Lazy<IMemberGroupService>(() => memberGroupService);
|
||||
//_sectionService = new Lazy<ISectionService>(() => sectionService);
|
||||
//_treeService = new Lazy<IApplicationTreeService>(() => treeService);
|
||||
}
|
||||
@@ -109,7 +113,7 @@ namespace Umbraco.Core.Services
|
||||
_userService = new Lazy<IUserService>(() => new UserService(provider, repositoryFactory.Value));
|
||||
|
||||
if (_memberService == null)
|
||||
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory.Value));
|
||||
_memberService = new Lazy<IMemberService>(() => new MemberService(provider, repositoryFactory.Value, _memberGroupService.Value));
|
||||
|
||||
if (_contentService == null)
|
||||
_contentService = new Lazy<IContentService>(() => new ContentService(provider, repositoryFactory.Value, publishingStrategy));
|
||||
@@ -149,6 +153,9 @@ namespace Umbraco.Core.Services
|
||||
|
||||
if (_memberTypeService == null)
|
||||
_memberTypeService = new Lazy<IMemberTypeService>(() => new MemberTypeService(provider, repositoryFactory.Value, _memberService.Value));
|
||||
|
||||
if (_memberGroupService == null)
|
||||
_memberGroupService = new Lazy<IMemberGroupService>(() => new MemberGroupService(provider, repositoryFactory.Value));
|
||||
|
||||
}
|
||||
|
||||
@@ -251,7 +258,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets the <see cref="UserService"/>
|
||||
/// </summary>
|
||||
internal IUserService UserService
|
||||
public IUserService UserService
|
||||
{
|
||||
get { return _userService.Value; }
|
||||
}
|
||||
@@ -259,7 +266,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets the <see cref="MemberService"/>
|
||||
/// </summary>
|
||||
internal IMemberService MemberService
|
||||
public IMemberService MemberService
|
||||
{
|
||||
get { return _memberService.Value; }
|
||||
}
|
||||
@@ -283,10 +290,18 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Gets the MemberTypeService
|
||||
/// </summary>
|
||||
internal IMemberTypeService MemberTypeService
|
||||
public IMemberTypeService MemberTypeService
|
||||
{
|
||||
get { return _memberTypeService.Value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the MemberGroupService
|
||||
/// </summary>
|
||||
public IMemberGroupService MemberGroupService
|
||||
{
|
||||
get { return _memberGroupService.Value; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Events;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
@@ -16,7 +15,7 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Represents the UserService, which is an easy access to operations involving <see cref="IProfile"/>, <see cref="IMembershipUser"/> and eventually Backoffice Users.
|
||||
/// </summary>
|
||||
internal class UserService : IUserService
|
||||
public class UserService : IUserService
|
||||
{
|
||||
private readonly RepositoryFactory _repositoryFactory;
|
||||
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
|
||||
@@ -76,10 +75,12 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IUser CreateMember(string username, string email, string password, IUserType userType)
|
||||
public IUser CreateUserWithIdentity(string username, string email, string password, IUserType userType)
|
||||
{
|
||||
if (userType == null) throw new ArgumentNullException("userType");
|
||||
|
||||
//TODO: PUT lock here!!
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
@@ -102,14 +103,19 @@ namespace Umbraco.Core.Services
|
||||
IsApproved = true
|
||||
};
|
||||
|
||||
if (SavingUser.IsRaisedEventCancelled(new SaveEventArgs<IUser>(user), this))
|
||||
return user;
|
||||
|
||||
repository.AddOrUpdate(user);
|
||||
uow.Commit();
|
||||
|
||||
SavedUser.RaiseEvent(new SaveEventArgs<IUser>(user, false), this);
|
||||
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
public IUser CreateMember(string username, string email, string password, string memberTypeAlias)
|
||||
IUser IMembershipMemberService<IUser>.CreateWithIdentity(string username, string email, string password, string memberTypeAlias)
|
||||
{
|
||||
var userType = GetUserTypeByAlias(memberTypeAlias);
|
||||
if (userType == null)
|
||||
@@ -117,19 +123,25 @@ namespace Umbraco.Core.Services
|
||||
throw new ArgumentException("The user type " + memberTypeAlias + " could not be resolved");
|
||||
}
|
||||
|
||||
return CreateMember(username, email, password, userType);
|
||||
return CreateUserWithIdentity(username, email, password, userType);
|
||||
}
|
||||
|
||||
public IUser GetById(object id)
|
||||
public IUser GetById(int id)
|
||||
{
|
||||
if (id is int)
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var user = repository.Get((int) id);
|
||||
var user = repository.Get((int)id);
|
||||
|
||||
return user;
|
||||
}
|
||||
return user;
|
||||
}
|
||||
}
|
||||
|
||||
public IUser GetByProviderKey(object id)
|
||||
{
|
||||
var asInt = id.TryConvertTo<int>();
|
||||
if (asInt.Success)
|
||||
{
|
||||
return GetById((int)id);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -150,57 +162,89 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
var query = Query<IUser>.Builder.Where(x => x.Username == login);
|
||||
var query = Query<IUser>.Builder.Where(x => x.Username.Equals(login));
|
||||
return repository.GetByQuery(query).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This disables and renames the user, it does not delete them, use the overload to delete them
|
||||
/// </summary>
|
||||
/// <param name="membershipUser"></param>
|
||||
public void Delete(IUser membershipUser)
|
||||
{
|
||||
if (UserDeleting.IsRaisedEventCancelled(new DeleteEventArgs<IUser>(membershipUser), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
//disable
|
||||
membershipUser.IsApproved = false;
|
||||
//can't rename if it's going to take up too many chars
|
||||
if (membershipUser.Username.Length + 9 <= 125)
|
||||
{
|
||||
repository.Delete(membershipUser);
|
||||
uow.Commit();
|
||||
membershipUser.Username = DateTime.Now.ToString("yyyyMMdd") + "_" + membershipUser.Username;
|
||||
}
|
||||
Save(membershipUser);
|
||||
|
||||
UserDeleted.RaiseEvent(new DeleteEventArgs<IUser>(membershipUser, false), this);
|
||||
//clear out the user logins!
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
uow.Database.Execute("delete from umbracoUserLogins where userID = @id", new {id = membershipUser.Id});
|
||||
}
|
||||
|
||||
public void Save(IUser membershipUser, bool raiseEvents = true)
|
||||
/// <summary>
|
||||
/// To permanently delete the user pass in true, otherwise they will just be disabled
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="deletePermanently"></param>
|
||||
public void Delete(IUser user, bool deletePermanently)
|
||||
{
|
||||
if (deletePermanently == false)
|
||||
{
|
||||
Delete(user);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DeletingUser.IsRaisedEventCancelled(new DeleteEventArgs<IUser>(user), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
repository.Delete(user);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
DeletedUser.RaiseEvent(new DeleteEventArgs<IUser>(user, false), this);
|
||||
}
|
||||
}
|
||||
|
||||
public void Save(IUser entity, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (UserSaving.IsRaisedEventCancelled(new SaveEventArgs<IUser>(membershipUser), this))
|
||||
if (SavingUser.IsRaisedEventCancelled(new SaveEventArgs<IUser>(entity), this))
|
||||
return;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
repository.AddOrUpdate(membershipUser);
|
||||
repository.AddOrUpdate(entity);
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
UserSaved.RaiseEvent(new SaveEventArgs<IUser>(membershipUser, false), this);
|
||||
SavedUser.RaiseEvent(new SaveEventArgs<IUser>(entity, false), this);
|
||||
}
|
||||
|
||||
public void Save(IEnumerable<IUser> members, bool raiseEvents = true)
|
||||
public void Save(IEnumerable<IUser> entities, bool raiseEvents = true)
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (UserSaving.IsRaisedEventCancelled(new SaveEventArgs<IUser>(members), this))
|
||||
if (SavingUser.IsRaisedEventCancelled(new SaveEventArgs<IUser>(entities), this))
|
||||
return;
|
||||
}
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
foreach (var member in members)
|
||||
foreach (var member in entities)
|
||||
{
|
||||
repository.AddOrUpdate(member);
|
||||
}
|
||||
@@ -209,10 +253,10 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
UserSaved.RaiseEvent(new SaveEventArgs<IUser>(members, false), this);
|
||||
SavedUser.RaiseEvent(new SaveEventArgs<IUser>(entities, false), this);
|
||||
}
|
||||
|
||||
public IEnumerable<IUser> FindMembersByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IUser> FindByEmail(string emailStringToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
@@ -244,7 +288,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IUser> FindMembersByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
public IEnumerable<IUser> FindByUsername(string login, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
@@ -276,7 +320,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public int GetMemberCount(MemberCountType countType)
|
||||
public int GetCount(MemberCountType countType)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
@@ -312,7 +356,7 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IUser> GetAllMembers(int pageIndex, int pageSize, out int totalRecords)
|
||||
public IEnumerable<IUser> GetAll(int pageIndex, int pageSize, out int totalRecords)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
@@ -333,15 +377,15 @@ namespace Umbraco.Core.Services
|
||||
public IProfile GetProfileById(int id)
|
||||
{
|
||||
var user = GetUserById(id);
|
||||
return user;
|
||||
return user.ProfileData;
|
||||
}
|
||||
|
||||
public IProfile GetProfileByUserName(string login)
|
||||
{
|
||||
var user = GetByUsername(login);
|
||||
return user;
|
||||
return user.ProfileData;
|
||||
}
|
||||
|
||||
|
||||
public IUser GetUserById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(_uowProvider.GetUnitOfWork()))
|
||||
@@ -350,6 +394,30 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single user to any number of entities
|
||||
/// </summary>
|
||||
/// <param name="userId"></param>
|
||||
/// <param name="permissions"></param>
|
||||
/// <param name="entityIds"></param>
|
||||
public void ReplaceUserPermissions(int userId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserRepository(uow))
|
||||
{
|
||||
repository.ReplaceUserPermissions(userId, permissions, entityIds);
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<IUserType> GetAllUserTypes(params int[] ids)
|
||||
{
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
using (var repository = _repositoryFactory.CreateUserTypeRepository(uow))
|
||||
{
|
||||
return repository.GetAll(ids);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Alias
|
||||
/// </summary>
|
||||
@@ -365,6 +433,14 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
public IUserType GetUserTypeById(int id)
|
||||
{
|
||||
using (var repository = _repositoryFactory.CreateUserTypeRepository(_uowProvider.GetUnitOfWork()))
|
||||
{
|
||||
return repository.Get(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets an IUserType by its Name
|
||||
/// </summary>
|
||||
@@ -384,7 +460,7 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
if (raiseEvents)
|
||||
{
|
||||
if (UserTypeSaving.IsRaisedEventCancelled(new SaveEventArgs<IUserType>(userType), this))
|
||||
if (SavingUserType.IsRaisedEventCancelled(new SaveEventArgs<IUserType>(userType), this))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -396,12 +472,12 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
if (raiseEvents)
|
||||
UserTypeSaved.RaiseEvent(new SaveEventArgs<IUserType>(userType, false), this);
|
||||
SavedUserType.RaiseEvent(new SaveEventArgs<IUserType>(userType, false), this);
|
||||
}
|
||||
|
||||
public void DeleteUserType(IUserType userType)
|
||||
{
|
||||
if (UserTypeDeleting.IsRaisedEventCancelled(new DeleteEventArgs<IUserType>(userType), this))
|
||||
if (DeletingUserType.IsRaisedEventCancelled(new DeleteEventArgs<IUserType>(userType), this))
|
||||
return;
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
@@ -411,7 +487,7 @@ namespace Umbraco.Core.Services
|
||||
uow.Commit();
|
||||
}
|
||||
|
||||
UserTypeDeleted.RaiseEvent(new DeleteEventArgs<IUserType>(userType, false), this);
|
||||
DeletedUserType.RaiseEvent(new DeleteEventArgs<IUserType>(userType, false), this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -434,22 +510,6 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the user's applications that they are allowed to access
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<string> GetUserSections(IUser user)
|
||||
{
|
||||
//TODO: We need to cache this result
|
||||
|
||||
var uow = _uowProvider.GetUnitOfWork();
|
||||
var sql = new Sql();
|
||||
sql.Select("app").From<User2AppDto>()
|
||||
.Where<User2AppDto>(dto => dto.UserId == (int)user.Id);
|
||||
return uow.Database.Fetch<string>(sql);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions for a given user for any number of nodes
|
||||
/// </summary>
|
||||
@@ -487,41 +547,41 @@ namespace Umbraco.Core.Services
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUser>> UserSaving;
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUser>> SavingUser;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUser>> UserSaved;
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUser>> SavedUser;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUser>> UserDeleting;
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUser>> DeletingUser;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUser>> UserDeleted;
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUser>> DeletedUser;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUserType>> UserTypeSaving;
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUserType>> SavingUserType;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Save
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUserType>> UserTypeSaved;
|
||||
public static event TypedEventHandler<IUserService, SaveEventArgs<IUserType>> SavedUserType;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs before Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUserType>> UserTypeDeleting;
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUserType>> DeletingUserType;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs after Delete
|
||||
/// </summary>
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUserType>> UserTypeDeleted;
|
||||
public static event TypedEventHandler<IUserService, DeleteEventArgs<IUserType>> DeletedUserType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Web.Security;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Core.Services
|
||||
{
|
||||
internal static class UserServiceExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Maps a custom provider's information to an umbraco user account
|
||||
/// </summary>
|
||||
/// <param name="userService"></param>
|
||||
/// <param name="member"></param>
|
||||
/// <remarks>
|
||||
/// To maintain compatibility we have to check the login name if the provider key lookup fails but otherwise
|
||||
/// we'll store the provider user key in the login column.
|
||||
/// </remarks>
|
||||
public static IUser CreateUserMappingForCustomProvider(this IUserService userService, MembershipUser member)
|
||||
{
|
||||
if (member == null) throw new ArgumentNullException("member");
|
||||
|
||||
|
||||
var valToLookup = member.ProviderUserKey == null ? member.UserName : member.ProviderUserKey.ToString();
|
||||
var found = userService.GetByUsername(valToLookup);
|
||||
if (found == null && member.ProviderUserKey != null)
|
||||
{
|
||||
//try by username
|
||||
found = userService.GetByUsername(member.UserName);
|
||||
}
|
||||
|
||||
if (found == null)
|
||||
{
|
||||
var writer = userService.GetUserTypeByAlias("writer");
|
||||
if (writer == null)
|
||||
{
|
||||
throw new InvalidOperationException("Could not map the custom user to an Umbraco user, no 'writer' user type could be found");
|
||||
}
|
||||
var user = new User(
|
||||
member.UserName,
|
||||
member.Email ?? Guid.NewGuid().ToString("N") + "@example.com", //email cannot be empty
|
||||
member.ProviderUserKey == null ? member.UserName : member.ProviderUserKey.ToString(),
|
||||
Guid.NewGuid().ToString("N"), //pass cannot be empty
|
||||
writer);
|
||||
user.AddAllowedSection(Constants.Applications.Content);
|
||||
userService.Save(user);
|
||||
return user;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,25 +14,6 @@ namespace Umbraco.Core.Strings
|
||||
// note: you have 32 bits at your disposal
|
||||
// 0xffffffff
|
||||
|
||||
|
||||
// masks
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for casing.
|
||||
/// </summary>
|
||||
CaseMask = 0x3f, // 0xff - 8 possible values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for encoding.
|
||||
/// </summary>
|
||||
CodeMask = 0x700, // 0xff00 - 8 possible values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for role.
|
||||
/// </summary>
|
||||
RoleMask = 0x070000, // 0xff0000 - 8 possible values
|
||||
|
||||
|
||||
// no value
|
||||
|
||||
/// <summary>
|
||||
@@ -43,6 +24,11 @@ namespace Umbraco.Core.Strings
|
||||
|
||||
// casing values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for casing.
|
||||
/// </summary>
|
||||
CaseMask = PascalCase | CamelCase | Unchanged | LowerCase | UpperCase | UmbracoCase,
|
||||
|
||||
/// <summary>
|
||||
/// Pascal casing eg "PascalCase".
|
||||
/// </summary>
|
||||
@@ -78,6 +64,11 @@ namespace Umbraco.Core.Strings
|
||||
|
||||
// encoding values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for encoding.
|
||||
/// </summary>
|
||||
CodeMask = Unicode | Utf8 | Ascii,
|
||||
|
||||
/// <summary>
|
||||
/// Unicode encoding.
|
||||
/// </summary>
|
||||
@@ -97,6 +88,11 @@ namespace Umbraco.Core.Strings
|
||||
|
||||
// role values
|
||||
|
||||
/// <summary>
|
||||
/// Flag mask for role.
|
||||
/// </summary>
|
||||
RoleMask = UrlSegment | Alias | FileName | ConvertCase,
|
||||
|
||||
/// <summary>
|
||||
/// Url role.
|
||||
/// </summary>
|
||||
@@ -110,6 +106,11 @@ namespace Umbraco.Core.Strings
|
||||
/// <summary>
|
||||
/// FileName role.
|
||||
/// </summary>
|
||||
FileName = 0x040000
|
||||
FileName = 0x040000,
|
||||
|
||||
/// <summary>
|
||||
/// ConvertCase role.
|
||||
/// </summary>
|
||||
ConvertCase = 0x080000
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,20 @@
|
||||
using System;
|
||||
|
||||
// debugging
|
||||
// define WRTCONS to write cleaning details & steps to console
|
||||
// leave it wrapped within #if DEBUG to make sure it does leak
|
||||
// into RELEASE, see http://issues.umbraco.org/issue/U4-4199
|
||||
#if DEBUG
|
||||
#undef WRTCONS
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Globalization;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Umbraco.Core.Configuration;
|
||||
|
||||
namespace Umbraco.Core.Strings
|
||||
@@ -104,6 +115,11 @@ namespace Umbraco.Core.Strings
|
||||
return InvalidFileNameChars.Contains(c) == false;
|
||||
}
|
||||
|
||||
public static string CutMaxLength(string text, int length)
|
||||
{
|
||||
return text.Length <= length ? text : text.Substring(0, length);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Configuration
|
||||
@@ -157,6 +173,7 @@ namespace Umbraco.Core.Strings
|
||||
return WithConfig(CleanStringType.UrlSegment, new Config
|
||||
{
|
||||
PreFilter = ApplyUrlReplaceCharacters,
|
||||
PostFilter = x => CutMaxLength(x, 240),
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = (UrlReplacingToAscii ? CleanStringType.Ascii : CleanStringType.Utf8) | CleanStringType.LowerCase,
|
||||
BreakTermsOnUpper = false,
|
||||
@@ -176,6 +193,12 @@ namespace Umbraco.Core.Strings
|
||||
: (char.IsLetterOrDigit(c) || c == '_'), // letter, digit or underscore
|
||||
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
|
||||
BreakTermsOnUpper = false
|
||||
}).WithConfig(CleanStringType.ConvertCase, new Config
|
||||
{
|
||||
PreFilter = null,
|
||||
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
|
||||
StringType = CleanStringType.Ascii,
|
||||
BreakTermsOnUpper = true
|
||||
});
|
||||
}
|
||||
|
||||
@@ -185,6 +208,7 @@ namespace Umbraco.Core.Strings
|
||||
{
|
||||
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
|
||||
PreFilter = null;
|
||||
PostFilter = null;
|
||||
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
|
||||
BreakTermsOnUpper = false;
|
||||
CutAcronymOnNonUpper = false;
|
||||
@@ -197,6 +221,7 @@ namespace Umbraco.Core.Strings
|
||||
return new Config
|
||||
{
|
||||
PreFilter = PreFilter,
|
||||
PostFilter = PostFilter,
|
||||
IsTerm = IsTerm,
|
||||
StringType = StringType,
|
||||
BreakTermsOnUpper = BreakTermsOnUpper,
|
||||
@@ -207,6 +232,7 @@ namespace Umbraco.Core.Strings
|
||||
}
|
||||
|
||||
public Func<string, string> PreFilter { get; set; }
|
||||
public Func<string, string> PostFilter { get; set; }
|
||||
public Func<char, bool, bool> IsTerm { get; set; }
|
||||
|
||||
public CleanStringType StringType { get; set; }
|
||||
@@ -503,6 +529,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
if (culture == null)
|
||||
throw new ArgumentNullException("culture");
|
||||
|
||||
#if WRTCONS
|
||||
Console.WriteLine("STRING TYPE {0}", stringType);
|
||||
#endif
|
||||
|
||||
// get config
|
||||
var config = GetConfig(stringType, culture);
|
||||
stringType = config.StringTypeExtend(stringType);
|
||||
@@ -533,6 +563,10 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
// clean
|
||||
text = CleanCodeString(text, stringType, separator.Value, culture, config);
|
||||
|
||||
// apply post-filter
|
||||
if (config.PostFilter != null)
|
||||
text = config.PostFilter(text);
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -570,6 +604,9 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
var state = StateBreak;
|
||||
|
||||
caseType &= CleanStringType.CaseMask;
|
||||
#if WRTCONS
|
||||
Console.WriteLine("CASE {0}", caseType);
|
||||
#endif
|
||||
|
||||
// if we apply global ToUpper or ToLower to text here
|
||||
// then we cannot break words on uppercase chars
|
||||
@@ -595,13 +632,13 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
var isPair = char.IsSurrogate(c);
|
||||
if (isPair)
|
||||
throw new NotSupportedException("Surrogate pairs are not supported.");
|
||||
|
||||
//Console.WriteLine("CHAR '{0}' {1} {2} - {3} - {4}/{5} {6}",
|
||||
// c,
|
||||
// isTerm ? "term" : "!term", isUpper ? "upper" : "!upper",
|
||||
// state,
|
||||
// i, ipos, leading ? "leading" : "!leading");
|
||||
|
||||
#if WRTCONS
|
||||
Console.WriteLine("CHAR '{0}' {1} {2} - {3} - {4}/{5} {6}",
|
||||
c,
|
||||
isTerm ? "term" : "!term", isUpper ? "upper" : "!upper",
|
||||
state,
|
||||
i, ipos, leading ? "leading" : "!leading");
|
||||
#endif
|
||||
switch (state)
|
||||
{
|
||||
// within a break
|
||||
@@ -708,11 +745,12 @@ function validateSafeAlias(id, value, immediate, callback) {{
|
||||
CleanStringType caseType, CultureInfo culture, bool isAcronym)
|
||||
{
|
||||
var term = input.Substring(ipos, len);
|
||||
//Console.WriteLine("TERM \"{0}\" {1} {2}",
|
||||
// term,
|
||||
// isAcronym ? "acronym" : "word",
|
||||
// caseType);
|
||||
|
||||
#if WRTCONS
|
||||
Console.WriteLine("TERM \"{0}\" {1} {2}",
|
||||
term,
|
||||
isAcronym ? "acronym" : "word",
|
||||
caseType);
|
||||
#endif
|
||||
if (isAcronym)
|
||||
{
|
||||
if ((caseType == CleanStringType.CamelCase && len <= 2 && opos > 0) ||
|
||||
|
||||
@@ -45,6 +45,10 @@
|
||||
<Reference Include="MiniProfiler">
|
||||
<HintPath>..\packages\MiniProfiler.2.1.0\lib\net40\MiniProfiler.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="MySql.Data">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\packages\MySql.Data.6.6.5\lib\net40\MySql.Data.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json">
|
||||
<HintPath>..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
@@ -144,6 +148,7 @@
|
||||
<Compile Include="Configuration\UmbracoConfigurationSection.cs" />
|
||||
<Compile Include="Configuration\UmbracoVersion.cs" />
|
||||
<Compile Include="Attempt.cs" />
|
||||
<Compile Include="ControlExtensions.cs" />
|
||||
<Compile Include="CoreBootManager.cs" />
|
||||
<Compile Include="DatabaseContext.cs" />
|
||||
<Compile Include="DataTableExtensions.cs" />
|
||||
@@ -189,9 +194,13 @@
|
||||
<Compile Include="Models\ContentTypeCompositionBase.cs" />
|
||||
<Compile Include="Models\ContentTypeExtensions.cs" />
|
||||
<Compile Include="Models\ContentTypeSort.cs" />
|
||||
<Compile Include="Models\EntityExtensions.cs" />
|
||||
<Compile Include="Models\IMemberGroup.cs" />
|
||||
<Compile Include="Models\IRelation.cs" />
|
||||
<Compile Include="Models\IRelationType.cs" />
|
||||
<Compile Include="Models\MemberGroup.cs" />
|
||||
<Compile Include="Models\Membership\EntityPermission.cs" />
|
||||
<Compile Include="Models\MemberTypePropertyProfileAccess.cs" />
|
||||
<Compile Include="Models\Notification.cs" />
|
||||
<Compile Include="Models\PreValue.cs" />
|
||||
<Compile Include="Models\PreValueCollection.cs" />
|
||||
@@ -202,10 +211,13 @@
|
||||
<Compile Include="Models\PublishedContent\PublishedContentModel.cs" />
|
||||
<Compile Include="Models\PublishedContent\PublishedContentModelFactoryResolver.cs" />
|
||||
<Compile Include="Models\TemplateNode.cs" />
|
||||
<Compile Include="Persistence\Factories\MemberGroupFactory.cs" />
|
||||
<Compile Include="Persistence\Mappers\MemberGroupMapper.cs" />
|
||||
<Compile Include="Persistence\Querying\SqlStringExtensions.cs" />
|
||||
<Compile Include="Persistence\Querying\StringPropertyMatchType.cs" />
|
||||
<Compile Include="Persistence\Querying\TextColumnType.cs" />
|
||||
<Compile Include="Persistence\Querying\ValuePropertyMatchType.cs" />
|
||||
<Compile Include="Persistence\Repositories\Interfaces\IMemberGroupRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\NotificationsRepository.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\MySqlSyntax.cs" />
|
||||
<Compile Include="Persistence\SqlSyntax\SqlCeSyntax.cs" />
|
||||
@@ -740,10 +752,12 @@
|
||||
<Compile Include="Publishing\PublishStatusType.cs" />
|
||||
<Compile Include="RenderingEngine.cs" />
|
||||
<Compile Include="Security\AuthenticationExtensions.cs" />
|
||||
<Compile Include="Security\IUsersMembershipProvider.cs" />
|
||||
<Compile Include="Security\MembershipProviderBase.cs" />
|
||||
<Compile Include="Security\MembershipProviderExtensions.cs" />
|
||||
<Compile Include="Security\UmbracoBackOfficeIdentity.cs" />
|
||||
<Compile Include="Security\UmbracoMembershipProviderBase.cs" />
|
||||
<Compile Include="Security\UmbracoMembersMembershipProviderBase.cs" />
|
||||
<Compile Include="Security\UserData.cs" />
|
||||
<Compile Include="Serialization\AbstractSerializationService.cs" />
|
||||
<Compile Include="Serialization\Formatter.cs" />
|
||||
@@ -767,8 +781,10 @@
|
||||
<Compile Include="Services\IFileService.cs" />
|
||||
<Compile Include="Services\ILocalizationService.cs" />
|
||||
<Compile Include="Services\IMediaService.cs" />
|
||||
<Compile Include="Services\IMemberGroupService.cs" />
|
||||
<Compile Include="Services\IMemberService.cs" />
|
||||
<Compile Include="Services\IMembershipMemberService.cs" />
|
||||
<Compile Include="Services\IMembershipRoleService.cs" />
|
||||
<Compile Include="Services\IMembershipUserService.cs" />
|
||||
<Compile Include="Services\IMemberTypeService.cs" />
|
||||
<Compile Include="Services\INotificationService.cs" />
|
||||
@@ -778,6 +794,7 @@
|
||||
<Compile Include="Services\LocalizationService.cs" />
|
||||
<Compile Include="Services\MediaService.cs" />
|
||||
<Compile Include="Services\MemberCountType.cs" />
|
||||
<Compile Include="Services\MemberGroupService.cs" />
|
||||
<Compile Include="Services\MemberService.cs" />
|
||||
<Compile Include="Services\MemberTypeService.cs" />
|
||||
<Compile Include="Services\NotificationService.cs" />
|
||||
@@ -786,6 +803,7 @@
|
||||
<Compile Include="Services\PackagingService.cs" />
|
||||
<Compile Include="Services\ServiceContext.cs" />
|
||||
<Compile Include="Services\UserService.cs" />
|
||||
<Compile Include="Services\UserServiceExtensions.cs" />
|
||||
<Compile Include="Standalone\ServiceContextManager.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreApplication.cs" />
|
||||
<Compile Include="Standalone\StandaloneCoreBootManager.cs" />
|
||||
|
||||
@@ -116,6 +116,23 @@ namespace Umbraco.Core
|
||||
return afterAuthority.InvariantStartsWith(IOHelper.ResolveUrl("~/install").TrimStart("/"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the uri is a request for the default back office page
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool IsDefaultBackOfficeRequest(this Uri url)
|
||||
{
|
||||
if (url.AbsolutePath.InvariantEquals(GlobalSettings.Path.TrimEnd("/"))
|
||||
|| url.AbsolutePath.InvariantEquals(GlobalSettings.Path.EnsureEndsWith('/'))
|
||||
|| url.AbsolutePath.InvariantStartsWith(GlobalSettings.Path.EnsureEndsWith('/') + "Default.aspx")
|
||||
|| url.AbsolutePath.InvariantStartsWith(GlobalSettings.Path.EnsureEndsWith('/') + "Umbraco.aspx"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This is a performance tweak to check if this is a .css, .js or .ico, .jpg, .jpeg, .png, .gif file request since
|
||||
/// .Net will pass these requests through to the module when in integrated mode.
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<package id="Microsoft.AspNet.WebPages" version="2.0.30506.0" targetFramework="net40" />
|
||||
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net40" />
|
||||
<package id="MiniProfiler" version="2.1.0" targetFramework="net40" />
|
||||
<package id="MySql.Data" version="6.6.5" targetFramework="net40" />
|
||||
<package id="Newtonsoft.Json" version="4.5.11" targetFramework="net40" />
|
||||
<package id="SqlServerCE" version="4.0.0.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false"/>
|
||||
<section name="FileSystemProviders" type="Umbraco.Core.Configuration.FileSystemProvidersSection, Umbraco.Core" requirePermission="false" />
|
||||
</configSections>
|
||||
|
||||
<appSettings>
|
||||
@@ -26,7 +26,7 @@
|
||||
</appSettings>
|
||||
|
||||
<connectionStrings>
|
||||
<add name="umbracoDbDSN" connectionString="Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;" providerName="System.Data.SqlServerCe.4.0"/>
|
||||
<add name="umbracoDbDSN" connectionString="Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;" providerName="System.Data.SqlServerCe.4.0" />
|
||||
</connectionStrings>
|
||||
|
||||
<FileSystemProviders>
|
||||
@@ -74,9 +74,9 @@
|
||||
|
||||
<system.data>
|
||||
<DbProviderFactories>
|
||||
<remove invariant="System.Data.SqlServerCe.4.0"/>
|
||||
<remove invariant="System.Data.SqlServerCe.4.0" />
|
||||
<add name="Microsoft SQL Server Compact Data Provider 4.0" invariant="System.Data.SqlServerCe.4.0" description=".NET Framework Data Provider for Microsoft SQL Server Compact" type="System.Data.SqlServerCe.SqlCeProviderFactory, System.Data.SqlServerCe, Version=4.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
|
||||
<remove invariant="MySql.Data.MySqlClient"/>
|
||||
<remove invariant="MySql.Data.MySqlClient" />
|
||||
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.6.4.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
|
||||
</DbProviderFactories>
|
||||
</system.data>
|
||||
@@ -93,4 +93,35 @@
|
||||
</siteMap>
|
||||
</system.web>
|
||||
|
||||
<runtime>
|
||||
|
||||
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
<dependentAssembly>
|
||||
|
||||
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" culture="neutral" />
|
||||
|
||||
<bindingRedirect oldVersion="0.0.0.0-2.0.0.0" newVersion="2.0.0.0" />
|
||||
|
||||
</dependentAssembly>
|
||||
|
||||
</assemblyBinding>
|
||||
|
||||
</runtime>
|
||||
</configuration>
|
||||
@@ -94,8 +94,8 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateMember(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m, bool b) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
})
|
||||
@@ -125,8 +125,8 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateMember(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m, bool b) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
})
|
||||
@@ -158,8 +158,8 @@ namespace Umbraco.Tests.Membership
|
||||
mServiceMock.Setup(service => service.GetByEmail("test@test.com")).Returns(() => null);
|
||||
mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member");
|
||||
mServiceMock.Setup(
|
||||
service => service.CreateMember(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m) =>
|
||||
service => service.CreateWithIdentity(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))
|
||||
.Callback((string u, string e, string p, string m, bool b) =>
|
||||
{
|
||||
createdMember = new Member("test", e, u, p, memberType);
|
||||
})
|
||||
|
||||
@@ -47,7 +47,8 @@ namespace Umbraco.Tests
|
||||
new RelationService(
|
||||
new Mock<IDatabaseUnitOfWorkProvider>().Object,
|
||||
new RepositoryFactory(true),
|
||||
new Mock<IEntityService>().Object)/*,
|
||||
new Mock<IEntityService>().Object),
|
||||
new Mock<IMemberGroupService>().Object/*,
|
||||
new Mock<ISectionService>().Object,
|
||||
new Mock<IApplicationTreeService>().Object*/);
|
||||
Assert.Pass();
|
||||
@@ -66,26 +67,27 @@ namespace Umbraco.Tests
|
||||
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<IContentTypeService>().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)),
|
||||
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),
|
||||
new Mock<IMemberGroupService>().Object),
|
||||
CacheHelper.CreateDisabledCacheHelper());
|
||||
Assert.Pass();
|
||||
}
|
||||
@@ -107,7 +109,6 @@ namespace Umbraco.Tests
|
||||
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()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
namespace Umbraco.Tests.Models
|
||||
{
|
||||
[TestFixture]
|
||||
public class UmbracoEntityTests
|
||||
{
|
||||
[Test]
|
||||
public void UmbracoEntity_Can_Be_Initialized_From_Dynamic()
|
||||
{
|
||||
var boolIsTrue = true;
|
||||
ulong ulongIsTrue = 1; // because MySql might return ulong
|
||||
|
||||
var trashedWithBool = new UmbracoEntity((dynamic)boolIsTrue);
|
||||
var trashedWithInt = new UmbracoEntity((dynamic)ulongIsTrue);
|
||||
|
||||
Assert.IsTrue(trashedWithBool.Trashed);
|
||||
Assert.IsTrue(trashedWithInt.Trashed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,30 +105,24 @@ namespace Umbraco.Tests
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public virtual void CanConvertStringToDateTime()
|
||||
[TestCase("2012-11-10", true)]
|
||||
[TestCase("2012/11/10", true)]
|
||||
[TestCase("10/11/2012", true)]// assuming your culture uses DD/MM/YYYY
|
||||
[TestCase("11/10/2012", false)]// assuming your culture uses DD/MM/YYYY
|
||||
[TestCase("Sat 10, Nov 2012", true)]
|
||||
[TestCase("Saturday 10, Nov 2012", true)]
|
||||
[TestCase("Sat 10, November 2012", true)]
|
||||
[TestCase("Saturday 10, November 2012", true)]
|
||||
[TestCase("2012-11-10 13:14:15", true)]
|
||||
[TestCase("2012-11-10T13:14:15Z", true)]
|
||||
public virtual void CanConvertStringToDateTime(string date, bool outcome)
|
||||
{
|
||||
var dateTime = new DateTime(2012, 11, 10, 13, 14, 15);
|
||||
var testCases = new Dictionary<string, bool>
|
||||
{
|
||||
{"2012-11-10", true},
|
||||
{"2012/11/10", true},
|
||||
{"10/11/2012", true}, // assuming your culture uses DD/MM/YYYY
|
||||
{"11/10/2012", false}, // assuming your culture uses DD/MM/YYYY
|
||||
{"Sat 10, Nov 2012", true},
|
||||
{"Saturday 10, Nov 2012", true},
|
||||
{"Sat 10, November 2012", true},
|
||||
{"Saturday 10, November 2012", true},
|
||||
{"2012-11-10 13:14:15", true}
|
||||
};
|
||||
|
||||
foreach (var testCase in testCases)
|
||||
{
|
||||
var result = testCase.Key.TryConvertTo<DateTime>();
|
||||
var result = date.TryConvertTo<DateTime>();
|
||||
|
||||
Assert.IsTrue(result.Success, testCase.Key);
|
||||
Assert.AreEqual(DateTime.Equals(dateTime.Date, result.Result.Date), testCase.Value, testCase.Key);
|
||||
}
|
||||
Assert.IsTrue(result.Success, date);
|
||||
Assert.AreEqual(DateTime.Equals(dateTime.Date, result.Result.Date), outcome, date);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -25,8 +25,7 @@ namespace Umbraco.Tests.Persistence
|
||||
string path = TestHelper.CurrentAssemblyDirectory;
|
||||
AppDomain.CurrentDomain.SetData("DataDirectory", path);
|
||||
|
||||
RepositoryResolver.Current = new RepositoryResolver(
|
||||
new RepositoryFactory());
|
||||
RepositoryResolver.Current = new RepositoryResolver(new RepositoryFactory(true));
|
||||
|
||||
//disable cache
|
||||
var cacheHelper = CacheHelper.CreateDisabledCacheHelper();
|
||||
|
||||
@@ -2,7 +2,10 @@
|
||||
using System.Linq.Expressions;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
|
||||
namespace Umbraco.Tests.Persistence.Querying
|
||||
@@ -35,5 +38,60 @@ namespace Umbraco.Tests.Persistence.Querying
|
||||
|
||||
Assert.AreEqual("[umbracoNode].[parentID] = -1", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Equals_Operator_For_Value_Gets_Escaped()
|
||||
{
|
||||
Expression<Func<IUser, bool>> predicate = user => user.Username == "hello@world.com";
|
||||
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>();
|
||||
var result = modelToSqlExpressionHelper.Visit(predicate);
|
||||
|
||||
Console.WriteLine("Model to Sql ExpressionHelper: \n" + result);
|
||||
|
||||
Assert.AreEqual("[umbracoUser].[userLogin] = 'hello@@world.com'", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Equals_Method_For_Value_Gets_Escaped()
|
||||
{
|
||||
Expression<Func<IUser, bool>> predicate = user => user.Username.Equals("hello@world.com");
|
||||
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>();
|
||||
var result = modelToSqlExpressionHelper.Visit(predicate);
|
||||
|
||||
Console.WriteLine("Model to Sql ExpressionHelper: \n" + result);
|
||||
|
||||
Assert.AreEqual("upper([umbracoUser].[userLogin]) = 'HELLO@@WORLD.COM'", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Model_Expression_Value_Does_Not_Get_Double_Escaped()
|
||||
{
|
||||
//mysql escapes backslashes, so we'll test with that
|
||||
SqlSyntaxContext.SqlSyntaxProvider = MySqlSyntax.Provider;
|
||||
|
||||
Expression<Func<IUser, bool>> predicate = user => user.Username.Equals("mydomain\\myuser");
|
||||
var modelToSqlExpressionHelper = new ModelToSqlExpressionHelper<IUser>();
|
||||
var result = modelToSqlExpressionHelper.Visit(predicate);
|
||||
|
||||
Console.WriteLine("Model to Sql ExpressionHelper: \n" + result);
|
||||
|
||||
Assert.AreEqual("upper(`umbracoUser`.`userLogin`) = 'MYDOMAIN\\\\MYUSER'", result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Poco_Expression_Value_Does_Not_Get_Double_Escaped()
|
||||
{
|
||||
//mysql escapes backslashes, so we'll test with that
|
||||
SqlSyntaxContext.SqlSyntaxProvider = MySqlSyntax.Provider;
|
||||
|
||||
Expression<Func<UserDto, bool>> predicate = user => user.Login.StartsWith("mydomain\\myuser");
|
||||
var modelToSqlExpressionHelper = new PocoToSqlExpressionHelper<UserDto>();
|
||||
var result = modelToSqlExpressionHelper.Visit(predicate);
|
||||
|
||||
Console.WriteLine("Poco to Sql ExpressionHelper: \n" + result);
|
||||
|
||||
Assert.AreEqual("upper(`umbracoUser`.`userLogin`) like 'MYDOMAIN\\\\MYUSER%'", result);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,6 @@ namespace Umbraco.Tests.Persistence.Querying
|
||||
[TestFixture]
|
||||
public class PetaPocoSqlTests : BaseUsingSqlCeSyntax
|
||||
{
|
||||
[Test]
|
||||
public void Generate_Replace_Entity_Permissions_Test()
|
||||
{
|
||||
// Act
|
||||
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(123, "A", new object[] {10, 11, 12});
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Generate_Replace_Entity_Permissions_With_Descendants_Test()
|
||||
{
|
||||
// Act
|
||||
var sql = PermissionRepository<IContent>.GenerateReplaceEntityPermissionsSql(new[] { 123, 456 },"A", new object[] { 10, 11, 12 });
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123 OR [nodeId]=456) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Select_From_With_Type()
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Rdbms;
|
||||
using Umbraco.Core.Persistence;
|
||||
@@ -38,7 +39,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current);
|
||||
contentTypeRepository = new ContentTypeRepository(unitOfWork, NullCacheProvider.Current, templateRepository);
|
||||
var repository = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository);
|
||||
var repository = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, CacheHelper.CreateDisabledCacheHelper());
|
||||
return repository;
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
unitOfWork.Commit();
|
||||
|
||||
// Act
|
||||
repository.AssignEntityPermissions(parentPage, 'A', new object[] { 0 });
|
||||
repository.AssignEntityPermission(parentPage, 'A', new int[] { 0 });
|
||||
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
|
||||
repository.AddOrUpdate(childPage);
|
||||
unitOfWork.Commit();
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
{
|
||||
var templateRepository = new TemplateRepository(unitOfWork, NullCacheProvider.Current);
|
||||
contentTypeRepository = new ContentTypeRepository(unitOfWork, NullCacheProvider.Current, templateRepository);
|
||||
var repository = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository);
|
||||
var repository = new ContentRepository(unitOfWork, NullCacheProvider.Current, contentTypeRepository, templateRepository, CacheHelper.CreateDisabledCacheHelper());
|
||||
return repository;
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user