Fixes: U4-4842 Unable to edit "name" and "alias" to MediaType property

This commit is contained in:
Shannon
2014-05-16 12:09:08 +10:00
parent 365a8e85e9
commit d8edf67b82
5 changed files with 59 additions and 29 deletions

View File

@@ -133,29 +133,6 @@ namespace Umbraco.Core.Models
Key = Guid.NewGuid();
}
/// <summary>
/// Method to call when Entity is being updated
/// </summary>
/// <remarks>Modified Date is set and a new Version guid is set</remarks>
internal override void UpdatingEntity()
{
base.UpdatingEntity();
}
public override object DeepClone()
{
var clone = (ContentType)base.DeepClone();
var propertyGroups = PropertyGroups.Select(x => (PropertyGroup)x.DeepClone()).ToList();
clone.PropertyGroups = new PropertyGroupCollection(propertyGroups);
//set the property types that are not part of a group
clone.PropertyTypes = PropertyTypeCollection
.Where(x => x.PropertyGroupId == null)
.Select(x => (PropertyType)x.DeepClone()).ToList();
clone.ResetDirtyProperties(false);
return clone;
}
/// <summary>
/// Creates a deep clone of the current entity with its identity/alias and it's property identities reset

View File

@@ -351,7 +351,9 @@ namespace Umbraco.Core.Models
/// <summary>
/// List of PropertyGroups available on this ContentType
/// </summary>
/// <remarks>A PropertyGroup corresponds to a Tab in the UI</remarks>
/// <remarks>
/// A PropertyGroup corresponds to a Tab in the UI
/// </remarks>
[DataMember]
public virtual PropertyGroupCollection PropertyGroups
{
@@ -367,7 +369,13 @@ namespace Umbraco.Core.Models
/// List of PropertyTypes available on this ContentType.
/// This list aggregates PropertyTypes across the PropertyGroups.
/// </summary>
/// <remarks>
/// Marked as DoNotClone because the result of this property is not the natural result of the data, it is
/// a union of data so when auto-cloning if the setter is used it will be setting the unnatural result of the
/// data. We manually clone this instead.
/// </remarks>
[IgnoreDataMember]
[DoNotClone]
public virtual IEnumerable<PropertyType> PropertyTypes
{
get
@@ -383,6 +391,14 @@ namespace Umbraco.Core.Models
}
/// <summary>
/// Returns the property type collection containing types that are non-groups - used for tests
/// </summary>
internal IEnumerable<PropertyType> NonGroupedPropertyTypes
{
get { return _propertyTypes; }
}
/// <summary>
/// A boolean flag indicating if a property type has been removed from this instance.
/// </summary>
/// <remarks>
@@ -579,5 +595,19 @@ namespace Umbraco.Core.Models
propertyType.ResetDirtyProperties();
}
}
public override object DeepClone()
{
var clone = (ContentTypeBase)base.DeepClone();
//need to manually wire up the event handlers for the property type collections - we've ensured
// its ignored from the auto-clone process because its return values are unions, not raw and
// we end up with duplicates, see: http://issues.umbraco.org/issue/U4-4842
clone._propertyTypes = (PropertyTypeCollection)_propertyTypes.DeepClone();
clone._propertyTypes.CollectionChanged += clone.PropertyTypesChanged;
return clone;
}
}
}

View File

@@ -2,9 +2,29 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace Umbraco.Core.Models
{
/// <summary>
/// Used to attribute properties that have a setter and are a reference type
/// that should be ignored for cloning when using the DeepCloneHelper
/// </summary>
/// <remarks>
///
/// This attribute must be used:
/// * when the property is backed by a field but the result of the property is the un-natural data stored in the field
///
/// This attribute should not be used:
/// * when the property is virtual
/// * when the setter performs additional required logic other than just setting the underlying field
///
/// </remarks>
internal class DoNotCloneAttribute : Attribute
{
}
public static class DeepCloneHelper
{
/// <summary>
@@ -25,8 +45,10 @@ namespace Umbraco.Core.Models
var refProperties = inputType.GetProperties()
.Where(x =>
//is not attributed with the ignore clone attribute
x.GetCustomAttribute<DoNotCloneAttribute>() == null
//reference type but not string
x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
&& x.PropertyType.IsValueType == false && x.PropertyType != typeof (string)
//settable
&& x.CanWrite
//non-indexed

View File

@@ -128,9 +128,9 @@ namespace Umbraco.Core.Persistence.Caching
public void Save(Type type, IEntity entity)
{
//IMPORTANT: we must clone to store, see: http://issues.umbraco.org/issue/U4-4259
entity = (IEntity)entity.DeepClone();
var clone = (IEntity)entity.DeepClone();
var key = GetCompositeId(type, entity.Id);
var key = GetCompositeId(type, clone.Id);
_keyTracker.TryAdd(key);
@@ -139,11 +139,11 @@ namespace Umbraco.Core.Persistence.Caching
if (_memoryCache != null)
{
_memoryCache.Set(key, entity, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) });
_memoryCache.Set(key, clone, new CacheItemPolicy { SlidingExpiration = TimeSpan.FromMinutes(5) });
}
else
{
HttpRuntime.Cache.Insert(key, entity, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
HttpRuntime.Cache.Insert(key, clone, null, System.Web.Caching.Cache.NoAbsoluteExpiration, TimeSpan.FromMinutes(5));
}
}

View File

@@ -162,6 +162,7 @@ namespace Umbraco.Tests.Models
}
Assert.AreNotSame(clone.PropertyTypes, contentType.PropertyTypes);
Assert.AreEqual(clone.PropertyTypes.Count(), contentType.PropertyTypes.Count());
Assert.AreEqual(0, ((ContentTypeBase)clone).NonGroupedPropertyTypes.Count());
for (var index = 0; index < contentType.PropertyTypes.Count(); index++)
{
Assert.AreNotSame(clone.PropertyTypes.ElementAt(index), contentType.PropertyTypes.ElementAt(index));