Merge branch 'dev-v7' into 7.3.0

Conflicts:
	build/UmbracoVersion.txt
	src/Umbraco.Core/Configuration/UmbracoVersion.cs
	src/Umbraco.Core/Persistence/Repositories/TemplateRepository.cs
	src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
This commit is contained in:
Shannon
2014-12-29 14:30:01 +11:00
121 changed files with 3261 additions and 1007 deletions

View File

@@ -15,7 +15,7 @@ namespace Umbraco.Core.Models
{
private int _defaultTemplate;
private IEnumerable<ITemplate> _allowedTemplates;
/// <summary>
/// Constuctor for creating a ContentType with the parent's id.
/// </summary>
@@ -31,9 +31,10 @@ namespace Umbraco.Core.Models
/// </summary>
/// <remarks>Use this to ensure inheritance from parent.</remarks>
/// <param name="parent"></param>
public ContentType(IContentType parent) : this(parent, null)
{
}
[Obsolete("This method is obsolete, use ContentType(IContentType parent, string alias) instead.", false)]
public ContentType(IContentType parent) : this(parent, null)
{
}
/// <summary>
/// Constuctor for creating a ContentType with the parent as an inherited type.
@@ -49,7 +50,7 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo DefaultTemplateSelector = ExpressionHelper.GetPropertyInfo<ContentType, int>(x => x.DefaultTemplateId);
private static readonly PropertyInfo AllowedTemplatesSelector = ExpressionHelper.GetPropertyInfo<ContentType, IEnumerable<ITemplate>>(x => x.AllowedTemplates);
/// <summary>
/// Gets or sets the alias of the default Template.
/// </summary>
@@ -106,7 +107,7 @@ namespace Umbraco.Core.Models
}
DefaultTemplateId = template.Id;
if(_allowedTemplates.Any(x => x != null && x.Id == template.Id) == false)
if (_allowedTemplates.Any(x => x != null && x.Id == template.Id) == false)
{
var templates = AllowedTemplates.ToList();
templates.Add(template);
@@ -140,7 +141,7 @@ namespace Umbraco.Core.Models
{
base.AddingEntity();
if(Key == Guid.Empty)
if (Key == Guid.Empty)
Key = Guid.NewGuid();
}
@@ -151,7 +152,7 @@ namespace Umbraco.Core.Models
/// <returns></returns>
[Obsolete("Use DeepCloneWithResetIdentities instead")]
public IContentType Clone(string alias)
{
{
return DeepCloneWithResetIdentities(alias);
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
@@ -15,6 +16,7 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
[DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")]
public abstract class ContentTypeBase : Entity, IContentTypeBase
{
private Lazy<int> _parentId;
@@ -497,7 +499,6 @@ namespace Umbraco.Core.Models
/// <param name="propertyTypeAlias">Alias of the <see cref="PropertyType"/> to remove</param>
public void RemovePropertyType(string propertyTypeAlias)
{
//check if the property exist in one of our collections
if (PropertyGroups.Any(group => group.PropertyTypes.Any(pt => pt.Alias == propertyTypeAlias))
|| _propertyTypes.Any(x => x.Alias == propertyTypeAlias))
@@ -524,6 +525,7 @@ namespace Umbraco.Core.Models
public void RemovePropertyGroup(string propertyGroupName)
{
PropertyGroups.RemoveItem(propertyGroupName);
OnPropertyChanged(PropertyGroupCollectionSelector);
}
/// <summary>

View File

@@ -55,7 +55,7 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Gets or sets the Path to the File from the root of the site
/// Gets or sets the Path to the File from the root of the file's associated IFileSystem
/// </summary>
[DataMember]
public virtual string Path
@@ -92,6 +92,11 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Gets or sets the file's virtual path (i.e. the file path relative to the root of the website)
/// </summary>
public string VirtualPath { get; set; }
/// <summary>
/// Boolean indicating whether the file could be validated
/// </summary>

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models
string Alias { get; }
/// <summary>
/// Gets or sets the Path to the File from the root of the site
/// Gets or sets the Path to the File from the root of the file's associated IFileSystem
/// </summary>
string Path { get; set; }
@@ -28,6 +28,11 @@ namespace Umbraco.Core.Models
/// </summary>
string Content { get; set; }
/// <summary>
/// Gets or sets the file's virtual path (i.e. the file path relative to the root of the website)
/// </summary>
string VirtualPath { get; set; }
/// <summary>
/// Boolean indicating whether the file could be validated
/// </summary>

View File

@@ -20,7 +20,6 @@ namespace Umbraco.Core.Models
private string _email;
private string _rawPasswordValue;
private object _providerUserKey;
private Type _userTypeKey;
/// <summary>
/// Constructor for creating an empty Member object
@@ -114,7 +113,6 @@ namespace Umbraco.Core.Models
private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.Email);
private static readonly PropertyInfo PasswordSelector = ExpressionHelper.GetPropertyInfo<Member, string>(x => x.RawPasswordValue);
private static readonly PropertyInfo ProviderUserKeySelector = ExpressionHelper.GetPropertyInfo<Member, object>(x => x.ProviderUserKey);
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<Member, Type>(x => x.ProviderUserKeyType);
/// <summary>
/// Gets or sets the Username
@@ -502,38 +500,7 @@ namespace Umbraco.Core.Models
}
}
/// <summary>
/// Gets or sets the type of the provider user key.
/// </summary>
/// <value>
/// The type of the provider user key.
/// </value>
[IgnoreDataMember]
internal Type ProviderUserKeyType
{
get
{
return _userTypeKey;
}
private set
{
SetPropertyValueAndDetectChanges(o =>
{
_userTypeKey = value;
return _userTypeKey;
}, _userTypeKey, UserTypeKeySelector);
}
}
/// <summary>
/// Sets the type of the provider user key.
/// </summary>
/// <param name="type">The type.</param>
internal void SetProviderUserKeyType(Type type)
{
ProviderUserKeyType = type;
}
/// <summary>
/// Method to call when Entity is being saved
/// </summary>

View File

@@ -7,9 +7,9 @@ namespace Umbraco.Core.Models.Membership
{
internal static class MembershipUserExtensions
{
internal static UmbracoMembershipMember AsConcreteMembershipUser(this IMembershipUser member, string providerName)
internal static UmbracoMembershipMember AsConcreteMembershipUser(this IMembershipUser member, string providerName, bool providerKeyAsGuid = false)
{
var membershipMember = new UmbracoMembershipMember(member, providerName);
var membershipMember = new UmbracoMembershipMember(member, providerName, providerKeyAsGuid);
return membershipMember;
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Web.Security;
using Umbraco.Core.Configuration;
namespace Umbraco.Core.Models.Membership
{
@@ -25,7 +26,7 @@ namespace Umbraco.Core.Models.Membership
//NOTE: We are not calling the base constructor which will validate that a provider with the specified name exists which causes issues with unit tests. The ctor
// validation for that doesn't need to be there anyways (have checked the source).
public UmbracoMembershipMember(IMembershipUser member, string providerName)
public UmbracoMembershipMember(IMembershipUser member, string providerName, bool providerKeyAsGuid = false)
{
_member = member;
//NOTE: We are copying the values here so that everything is consistent with how the underlying built-in ASP.Net membership user
@@ -37,7 +38,7 @@ namespace Umbraco.Core.Models.Membership
if (member.PasswordQuestion != null)
_passwordQuestion = member.PasswordQuestion.Trim();
_providerName = providerName;
_providerUserKey = member.ProviderUserKey;
_providerUserKey = providerKeyAsGuid ? member.ProviderUserKey : member.Id;
_comment = member.Comments;
_isApproved = member.IsApproved;
_isLockedOut = member.IsLockedOut;

View File

@@ -58,7 +58,6 @@ namespace Umbraco.Core.Models.Membership
private IUserType _userType;
private string _name;
private Type _userTypeKey;
private List<string> _addedSections;
private List<string> _removedSections;
private ObservableCollection<string> _sectionCollection;
@@ -80,7 +79,6 @@ namespace Umbraco.Core.Models.Membership
private static readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<User, int>(x => x.StartMediaId);
private static readonly PropertyInfo AllowedSectionsSelector = ExpressionHelper.GetPropertyInfo<User, IEnumerable<string>>(x => x.AllowedSections);
private static readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Name);
private static readonly PropertyInfo UserTypeKeySelector = ExpressionHelper.GetPropertyInfo<User, Type>(x => x.ProviderUserKeyType);
private static readonly PropertyInfo UsernameSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Username);
private static readonly PropertyInfo EmailSelector = ExpressionHelper.GetPropertyInfo<User, string>(x => x.Email);
@@ -101,37 +99,6 @@ namespace Umbraco.Core.Models.Membership
set { throw new NotSupportedException("Cannot set the provider user key for a user"); }
}
/// <summary>
/// Gets or sets the type of the provider user key.
/// </summary>
/// <value>
/// The type of the provider user key.
/// </value>
[IgnoreDataMember]
internal Type ProviderUserKeyType
{
get
{
return _userTypeKey;
}
private set
{
SetPropertyValueAndDetectChanges(o =>
{
_userTypeKey = value;
return _userTypeKey;
}, _userTypeKey, UserTypeKeySelector);
}
}
/// <summary>
/// Sets the type of the provider user key.
/// </summary>
/// <param name="type">The type.</param>
internal void SetProviderUserKeyType(Type type)
{
ProviderUserKeyType = type;
}
[DataMember]
public string Username

View File

@@ -71,16 +71,34 @@ namespace Umbraco.Core.Models
{
using (new WriteLock(_addLocker))
{
var key = GetKeyForItem(item);
if (key != null)
//Note this is done to ensure existig groups can be renamed
if (item.HasIdentity && item.Id > 0)
{
var exists = this.Contains(key);
var exists = this.Contains(item.Id);
if (exists)
{
SetItem(IndexOfKey(key), item);
var keyExists = this.Contains(item.Name);
if(keyExists)
throw new Exception(string.Format("Naming conflict: Changing the name of PropertyGroup '{0}' would result in duplicates", item.Name));
SetItem(IndexOfKey(item.Id), item);
return;
}
}
else
{
var key = GetKeyForItem(item);
if (key != null)
{
var exists = this.Contains(key);
if (exists)
{
SetItem(IndexOfKey(key), item);
return;
}
}
}
base.Add(item);
OnAdd.IfNotNull(x => x.Invoke());//Could this not be replaced by a Mandate/Contract for ensuring item is not null
@@ -99,6 +117,11 @@ namespace Umbraco.Core.Models
return this.Any(x => x.Name == groupName);
}
public bool Contains(int id)
{
return this.Any(x => x.Id == id);
}
public void RemoveItem(string propertyGroupName)
{
var key = IndexOfKey(propertyGroupName);
@@ -119,6 +142,18 @@ namespace Umbraco.Core.Models
return -1;
}
public int IndexOfKey(int id)
{
for (var i = 0; i < this.Count; i++)
{
if (this[i].Id == id)
{
return i;
}
}
return -1;
}
protected override string GetKeyForItem(PropertyGroup item)
{
return item.Name;

View File

@@ -1,9 +1,9 @@
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Persistence;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Strings;
@@ -14,6 +14,7 @@ namespace Umbraco.Core.Models
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
[DebuggerDisplay("Id: {Id}, Name: {Name}, Alias: {Alias}")]
public class PropertyType : Entity, IEquatable<PropertyType>
{
private readonly bool _isExplicitDbType;

View File

@@ -1,11 +1,36 @@
using System;
using System.Globalization;
using System.Linq;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
namespace Umbraco.Core.Models
{
internal static class UserExtensions
public static class UserExtensions
{
/// <summary>
/// Returns the culture info associated with this user, based on the language they're assigned to in the back office
/// </summary>
/// <param name="user"></param>
/// <param name="textService"></param>
/// <returns></returns>
public static CultureInfo GetUserCulture(this IUser user, ILocalizedTextService textService)
{
if (user == null) throw new ArgumentNullException("user");
if (textService == null) throw new ArgumentNullException("textService");
return GetUserCulture(user.Language, textService);
}
internal static CultureInfo GetUserCulture(string userLanguage, ILocalizedTextService textService)
{
return textService.GetSupportedCultures()
.FirstOrDefault(culture =>
//match on full name first
culture.Name.InvariantEquals(userLanguage.Replace("_", "-")) ||
//then match on the 2 letter name
culture.TwoLetterISOLanguageName.InvariantEquals(userLanguage));
}
/// <summary>
/// Checks if the user has access to the content item based on their start noe
/// </summary>