From 48dcc373dc518a84dbcd9527bdcf3d3e8c73a323 Mon Sep 17 00:00:00 2001 From: Damiaan Date: Tue, 13 May 2014 22:29:59 +0200 Subject: [PATCH 01/17] Oembed for slideshare not working anymore --- src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config | 2 +- src/Umbraco.Web.UI/config/EmbeddedMedia.config | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config index 8e46fd134b..fe58a8fa84 100644 --- a/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config +++ b/src/Umbraco.Web.UI/config/EmbeddedMedia.Release.config @@ -15,7 +15,7 @@ - + xml diff --git a/src/Umbraco.Web.UI/config/EmbeddedMedia.config b/src/Umbraco.Web.UI/config/EmbeddedMedia.config index ae25ac80d5..86f00b1ef4 100644 --- a/src/Umbraco.Web.UI/config/EmbeddedMedia.config +++ b/src/Umbraco.Web.UI/config/EmbeddedMedia.config @@ -15,7 +15,7 @@ - + xml From 6b313aba489358ecc5c0c5bf57cb24321d888a9a Mon Sep 17 00:00:00 2001 From: Graham Ambrose Date: Thu, 15 May 2014 22:43:24 +0100 Subject: [PATCH 02/17] CopyUmbracoFilesToWebRoot assumes packages loacation CopyUmbracoFilesToWebRoot assumes packages folder is always one dir up from project file which is not always the case. I have changed to use MSBuildThisFileDirectory which makes the path relative the the UmbracoCms.targets file. MSBuildThisFileDirectory is supported from MSBuild 4 but as ToolsVersion is already set to 4.0 that should not be a problem. UmbracoVersion property is no longer required but removing it may break external target files depending on it. Have moved it to props file as this makes it more reliable for external targets files. --- build/NuSpecs/build/UmbracoCms.props | 3 +++ build/NuSpecs/build/UmbracoCms.targets | 5 +---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/NuSpecs/build/UmbracoCms.props b/build/NuSpecs/build/UmbracoCms.props index 5e11945a9d..37f125ecb9 100644 --- a/build/NuSpecs/build/UmbracoCms.props +++ b/build/NuSpecs/build/UmbracoCms.props @@ -1,5 +1,8 @@ + + 7.1.2 + AddUmbracoFilesToOutput; diff --git a/build/NuSpecs/build/UmbracoCms.targets b/build/NuSpecs/build/UmbracoCms.targets index 721f40c976..bd8d28294c 100644 --- a/build/NuSpecs/build/UmbracoCms.targets +++ b/build/NuSpecs/build/UmbracoCms.targets @@ -1,11 +1,8 @@  - - 7.1.2 - - ..\packages\UmbracoCms.$(UmbracoVersion)\UmbracoFiles\ + $(MSBuildThisFileDirectory)..\UmbracoFiles\ From 8cae2526d5d4f0558c9af1fb189c8dd321eac80e Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 11:34:10 +1000 Subject: [PATCH 03/17] Fixes: U4-4842 Unable to edit "name" and "alias" to MediaType property --- src/Umbraco.Core/Models/ContentType.cs | 23 ------------ src/Umbraco.Core/Models/ContentTypeBase.cs | 37 ++++++++++++++++--- src/Umbraco.Core/Models/DeepCloneHelper.cs | 24 +++++++++++- .../Caching/RuntimeCacheProvider.cs | 8 ++-- src/Umbraco.Tests/Models/ContentTypeTests.cs | 1 + 5 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index 1cf7fc9684..ec763d07fa 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -133,29 +133,6 @@ namespace Umbraco.Core.Models Key = Guid.NewGuid(); } - /// - /// Method to call when Entity is being updated - /// - /// Modified Date is set and a new Version guid is set - 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; - } /// /// Creates a deep clone of the current entity with its identity/alias and it's property identities reset diff --git a/src/Umbraco.Core/Models/ContentTypeBase.cs b/src/Umbraco.Core/Models/ContentTypeBase.cs index 00e9c1e30c..5c09deadb8 100644 --- a/src/Umbraco.Core/Models/ContentTypeBase.cs +++ b/src/Umbraco.Core/Models/ContentTypeBase.cs @@ -331,11 +331,6 @@ namespace Umbraco.Core.Models get { return _additionalData; } } - /// - /// Some entities may expose additional data that other's might not, this custom data will be available in this collection - /// - public IDictionary AdditionalData { get; private set; } - /// /// Gets or sets a list of integer Ids for allowed ContentTypes /// @@ -356,7 +351,9 @@ namespace Umbraco.Core.Models /// /// List of PropertyGroups available on this ContentType /// - /// A PropertyGroup corresponds to a Tab in the UI + /// + /// A PropertyGroup corresponds to a Tab in the UI + /// [DataMember] public virtual PropertyGroupCollection PropertyGroups { @@ -372,7 +369,13 @@ namespace Umbraco.Core.Models /// List of PropertyTypes available on this ContentType. /// This list aggregates PropertyTypes across the PropertyGroups. /// + /// + /// 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. + /// [IgnoreDataMember] + [DoNotClone] public virtual IEnumerable PropertyTypes { get @@ -388,6 +391,14 @@ namespace Umbraco.Core.Models } /// + /// Returns the property type collection containing types that are non-groups - used for tests + /// + internal IEnumerable NonGroupedPropertyTypes + { + get { return _propertyTypes; } + } + + /// /// A boolean flag indicating if a property type has been removed from this instance. /// /// @@ -584,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; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/DeepCloneHelper.cs b/src/Umbraco.Core/Models/DeepCloneHelper.cs index aaee03f963..d8ef10751b 100644 --- a/src/Umbraco.Core/Models/DeepCloneHelper.cs +++ b/src/Umbraco.Core/Models/DeepCloneHelper.cs @@ -2,9 +2,29 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Reflection; namespace Umbraco.Core.Models { + /// + /// Used to attribute properties that have a setter and are a reference type + /// that should be ignored for cloning when using the DeepCloneHelper + /// + /// + /// + /// 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 + /// + /// + internal class DoNotCloneAttribute : Attribute + { + + } + public static class DeepCloneHelper { /// @@ -25,8 +45,10 @@ namespace Umbraco.Core.Models var refProperties = inputType.GetProperties() .Where(x => + //is not attributed with the ignore clone attribute + x.GetCustomAttribute() == 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 diff --git a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs index c2ca53a240..acacadb0cc 100644 --- a/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs +++ b/src/Umbraco.Core/Persistence/Caching/RuntimeCacheProvider.cs @@ -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)); } } diff --git a/src/Umbraco.Tests/Models/ContentTypeTests.cs b/src/Umbraco.Tests/Models/ContentTypeTests.cs index 3a0d974185..bb61a84d82 100644 --- a/src/Umbraco.Tests/Models/ContentTypeTests.cs +++ b/src/Umbraco.Tests/Models/ContentTypeTests.cs @@ -152,6 +152,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)); From 46a4f9242c813e873b656bd1cd22765c0444a04e Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 11:43:20 +1000 Subject: [PATCH 04/17] fixes test --- src/Umbraco.Tests/Models/PropertyGroupTests.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Tests/Models/PropertyGroupTests.cs b/src/Umbraco.Tests/Models/PropertyGroupTests.cs index f56bd2fbc2..413e94bfee 100644 --- a/src/Umbraco.Tests/Models/PropertyGroupTests.cs +++ b/src/Umbraco.Tests/Models/PropertyGroupTests.cs @@ -2,11 +2,12 @@ using System; using NUnit.Framework; using Umbraco.Core.Models; using Umbraco.Core.Serialization; +using Umbraco.Tests.TestHelpers; namespace Umbraco.Tests.Models { [TestFixture] - public class PropertyGroupTests + public class PropertyGroupTests : BaseUmbracoConfigurationTest { [Test] public void Can_Deep_Clone() @@ -37,7 +38,7 @@ namespace Umbraco.Tests.Models Alias = "test2", CreateDate = DateTime.Now, DataTypeDefinitionId = 6, - DataTypeId = Guid.NewGuid(), + PropertyEditorAlias = "propTest", Description = "testing2", Key = Guid.NewGuid(), Mandatory = true, @@ -118,7 +119,7 @@ namespace Umbraco.Tests.Models Alias = "test2", CreateDate = DateTime.Now, DataTypeDefinitionId = 6, - DataTypeId = Guid.NewGuid(), + PropertyEditorAlias = "propTest", Description = "testing2", Key = Guid.NewGuid(), Mandatory = true, From 762656e9643a4271e38477326228b3b91caf319f Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 12:08:17 +1000 Subject: [PATCH 05/17] Fixes: U4-4926 Pre-values need to be cloned in/out of the cache --- src/Umbraco.Core/Models/PreValue.cs | 9 +++- src/Umbraco.Core/Models/PreValueCollection.cs | 18 ++++++- .../DataTypeDefinitionRepository.cs | 4 +- .../Models/PreValueCollectionTests.cs | 51 +++++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 5 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Tests/Models/PreValueCollectionTests.cs diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs index b12312130d..61d127f50a 100644 --- a/src/Umbraco.Core/Models/PreValue.cs +++ b/src/Umbraco.Core/Models/PreValue.cs @@ -3,7 +3,7 @@ /// /// Represents a stored pre-value field value /// - public class PreValue + public class PreValue : IDeepCloneable { public PreValue(int id, string value, int sortOrder) { @@ -37,5 +37,12 @@ /// The sort order stored for the pre-value field value /// public int SortOrder { get; private set; } + + public virtual object DeepClone() + { + //Memberwise clone on PreValue will work since it doesn't have any deep elements + var clone = (PreValue)MemberwiseClone(); + return clone; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/PreValueCollection.cs b/src/Umbraco.Core/Models/PreValueCollection.cs index e6d864cd91..449eaaa3b7 100644 --- a/src/Umbraco.Core/Models/PreValueCollection.cs +++ b/src/Umbraco.Core/Models/PreValueCollection.cs @@ -14,7 +14,7 @@ namespace Umbraco.Core.Models /// Most legacy property editors won't support the dictionary format but new property editors should always use the dictionary format. /// In order to get overrideable pre-values working we need a dictionary since we'll have to reference a pre-value by a key. /// - public class PreValueCollection + public class PreValueCollection : IDeepCloneable { private IDictionary _preValuesAsDictionary; private IEnumerable _preValuesAsArray; @@ -82,5 +82,21 @@ namespace Umbraco.Core.Models } return result; } + + public object DeepClone() + { + var clone = (PreValueCollection) MemberwiseClone(); + if (_preValuesAsArray != null) + { + clone._preValuesAsArray = _preValuesAsArray.Select(x => (PreValue)x.DeepClone()).ToArray(); + } + if (_preValuesAsDictionary != null) + { + clone._preValuesAsDictionary = _preValuesAsDictionary.ToDictionary(x => x.Key, x => (PreValue)x.Value.DeepClone()); + } + + + return clone; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index 9484121ad7..0e8ae8c3bc 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -295,8 +295,8 @@ AND umbracoNode.id <> @id", var cached = _cacheHelper.RuntimeCache.GetCacheItemsByKeySearch(GetPrefixedCacheKey(dataTypeId)); if (cached != null && cached.Any()) { - //return from the cache - return cached.First(); + //return from the cache, ensure it's a cloned result + return (PreValueCollection)cached.First().DeepClone(); } l.UpgradeToWriteLock(); diff --git a/src/Umbraco.Tests/Models/PreValueCollectionTests.cs b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs new file mode 100644 index 0000000000..49c9ab16bb --- /dev/null +++ b/src/Umbraco.Tests/Models/PreValueCollectionTests.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Umbraco.Core.Models; + +namespace Umbraco.Tests.Models +{ + [TestFixture] + public class PreValueCollectionTests + { + [Test] + public void Can_Deep_Clone() + { + var d = new PreValueCollection(new Dictionary + { + {"blah1", new PreValue(1, "test1", 1)}, + {"blah2", new PreValue(2, "test1", 3)}, + {"blah3", new PreValue(3, "test1", 2)} + }); + + var a = new PreValueCollection(new[] + { + new PreValue(1, "test1", 1), + new PreValue(2, "test1", 3), + new PreValue(3, "test1", 2) + }); + + var clone1 = (PreValueCollection)d.DeepClone(); + var clone2 = (PreValueCollection)a.DeepClone(); + + Action assert = (orig, clone) => + { + Assert.AreNotSame(orig, clone); + var oDic = orig.FormatAsDictionary(); + var cDic = clone.FormatAsDictionary(); + Assert.AreEqual(oDic.Keys.Count(), cDic.Keys.Count()); + foreach (var k in oDic.Keys) + { + Assert.AreNotSame(oDic[k], cDic[k]); + Assert.AreEqual(oDic[k].Id, cDic[k].Id); + Assert.AreEqual(oDic[k].SortOrder, cDic[k].SortOrder); + Assert.AreEqual(oDic[k].Value, cDic[k].Value); + } + }; + + assert(d, clone1); + assert(a, clone2); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index fa9a84acc0..379547049d 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -191,6 +191,7 @@ + From ac9c938e926a9ee3c16f3b1f0c92fbec4731df0c Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 12:42:21 +1000 Subject: [PATCH 06/17] Fixes: U4-4923 Failed to retrieve data for application tree media after upgrade to 7.1.2 --- .../Repositories/EntityRepository.cs | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs index 02f64aa0cf..d0b81f1b8e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs @@ -493,14 +493,17 @@ namespace Umbraco.Core.Persistence.Repositories // Is this the same UmbracoEntity as the current one we're processing if (Current != null && Current.Key == a.uniqueID) { - // Add this UmbracoProperty to the current additional data - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() - }; + // Add this UmbracoProperty to the current additional data + Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + { + PropertyEditorAlias = p.PropertyEditorAlias, + Value = p.NTextValue.IsNullOrWhiteSpace() + ? p.NVarcharValue + : p.NTextValue.ConvertToJsonIfPossible() + }; + } // Return null to indicate we're not done with this UmbracoEntity yet return null; @@ -516,14 +519,17 @@ namespace Umbraco.Core.Persistence.Repositories Current = _factory.BuildEntityFromDynamic(a); - //add the property/create the prop list if null - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + if (p != null && p.PropertyAlias.IsNullOrWhiteSpace() == false) { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() - }; + //add the property/create the prop list if null + Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + { + PropertyEditorAlias = p.PropertyEditorAlias, + Value = p.NTextValue.IsNullOrWhiteSpace() + ? p.NVarcharValue + : p.NTextValue.ConvertToJsonIfPossible() + }; + } // Return the now populated previous UmbracoEntity (or null if first time through) return prev; From ffbb1a85ab8d0fbda031af3b0ba6bd9d60f60f89 Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 16 May 2014 12:43:23 +1000 Subject: [PATCH 07/17] Fixes: U4-4312 Spelling error on "Retreive" should be Retrieve -U7.0.0.4 --- .../src/common/resources/datatype.resource.js | 4 ++-- .../src/common/resources/entity.resource.js | 12 ++++++------ .../src/common/resources/log.resource.js | 2 +- .../src/common/resources/member.resource.js | 2 +- .../src/common/resources/stylesheet.resource.js | 2 +- .../src/common/resources/tree.resource.js | 2 +- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js index 5366da0db2..ed7c2e726a 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/datatype.resource.js @@ -81,7 +81,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) { umbRequestHelper.getApiUrl( "dataTypeApiBaseUrl", "GetAll")), - 'Failed to retreive data'); + 'Failed to retrieve data'); }, /** @@ -118,7 +118,7 @@ function dataTypeResource($q, $http, umbDataFormatter, umbRequestHelper) { umbRequestHelper.getApiUrl( "dataTypeApiBaseUrl", "GetEmpty")), - 'Failed to retreive data for empty datatype'); + 'Failed to retrieve data for empty datatype'); }, /** * @ngdoc method diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js index 17f1b87b5b..eeb81f2d67 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js @@ -146,7 +146,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "GetByIds", query)), - 'Failed to retreive entity data for ids ' + ids); + 'Failed to retrieve entity data for ids ' + ids); }, /** @@ -192,7 +192,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "GetAll", query)), - 'Failed to retreive entity data for type ' + type); + 'Failed to retrieve entity data for type ' + type); }, /** @@ -215,7 +215,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "GetAncestors", [{id: id}, {type: type}])), - 'Failed to retreive ancestor data for id ' + id); + 'Failed to retrieve ancestor data for id ' + id); }, /** @@ -238,7 +238,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "GetChildren", [{ id: id }, { type: type }])), - 'Failed to retreive child data for id ' + id); + 'Failed to retrieve child data for id ' + id); }, /** @@ -271,7 +271,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "Search", [{ query: query }, {type: type}])), - 'Failed to retreive entity data for query ' + query); + 'Failed to retrieve entity data for query ' + query); }, @@ -304,7 +304,7 @@ function entityResource($q, $http, umbRequestHelper) { "entityApiBaseUrl", "SearchAll", [{ query: query }])), - 'Failed to retreive entity data for query ' + query); + 'Failed to retrieve entity data for query ' + query); } }; diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/log.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/log.resource.js index 206c06ad4a..8059975fc1 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/log.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/log.resource.js @@ -99,7 +99,7 @@ function logResource($q, $http, umbRequestHelper) { "logApiBaseUrl", "GetLog", [{ logtype: type, sinceDate: since }])), - 'Failed to retreive user data for id ' + id); + 'Failed to retrieve user data for id ' + id); } }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js index 2eb104129b..65a53d233d 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js @@ -133,7 +133,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { umbRequestHelper.getApiUrl( "memberApiBaseUrl", "GetEmpty")), - 'Failed to retreive data for empty member item type ' + alias); + 'Failed to retrieve data for empty member item type ' + alias); } }, diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/stylesheet.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/stylesheet.resource.js index 3ff29a5c9d..f5eab4e902 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/stylesheet.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/stylesheet.resource.js @@ -93,7 +93,7 @@ function stylesheetResource($q, $http, umbRequestHelper) { "stylesheetApiBaseUrl", "GetRulesByName", [{ name: name }])), - 'Failed to retreive stylesheets '); + 'Failed to retrieve stylesheets '); } }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/tree.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/tree.resource.js index 52f8f07842..ea4bee718f 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/tree.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/tree.resource.js @@ -72,7 +72,7 @@ function treeResource($q, $http, umbRequestHelper) { return umbRequestHelper.resourcePromise( $http.get(getTreeNodesUrl(options.node)), - 'Failed to retreive data for child nodes ' + options.node.nodeId); + 'Failed to retrieve data for child nodes ' + options.node.nodeId); } }; } From b42d3b226d4ef3e4950cb8ed6ac9c32b8ec1a3c7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 11:29:35 +0200 Subject: [PATCH 08/17] Bump version --- build/Build.bat | 2 +- build/Build.proj | 2 +- build/NuSpecs/build/UmbracoCms.props | 9 ++++----- src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/build/Build.bat b/build/Build.bat index 0154866703..535c379d52 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -1,5 +1,5 @@ @ECHO OFF -SET release=7.1.2 +SET release=7.1.3 SET comment= SET version=%release% diff --git a/build/Build.proj b/build/Build.proj index 2b9040dab3..d37a9b7bb9 100644 --- a/build/Build.proj +++ b/build/Build.proj @@ -325,7 +325,7 @@ Regex="CurrentComment { get { return "([a-zA-Z]+)?"" ReplacementText="CurrentComment { get { return "$(BUILD_COMMENT)""/> - diff --git a/build/NuSpecs/build/UmbracoCms.props b/build/NuSpecs/build/UmbracoCms.props index 37f125ecb9..aed481dde4 100644 --- a/build/NuSpecs/build/UmbracoCms.props +++ b/build/NuSpecs/build/UmbracoCms.props @@ -1,15 +1,14 @@ - + - - 7.1.2 + + 7.1.3 AddUmbracoFilesToOutput; $(CopyAllFilesToSingleFolderForPackageDependsOn); - - + AddUmbracoFilesToOutput; $(CopyAllFilesToSingleFolderForPackageDependsOn); diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index ebaca4ed81..3c15b52de9 100644 --- a/src/Umbraco.Core/Configuration/UmbracoVersion.cs +++ b/src/Umbraco.Core/Configuration/UmbracoVersion.cs @@ -5,7 +5,7 @@ namespace Umbraco.Core.Configuration { public class UmbracoVersion { - private static readonly Version Version = new Version("7.1.2"); + private static readonly Version Version = new Version("7.1.3"); /// /// Gets the current version of Umbraco. diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index a6a7481249..78eda959b8 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2530,9 +2530,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\" True True - 7120 + 7130 / - http://localhost:7120 + http://localhost:7130 False False From a99a33477a07f27e9091d8423ce6eae4278395ff Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 12:27:54 +0200 Subject: [PATCH 09/17] Centralized the current Umbraco version number in UmbracoVersion.txt that will be read by buildbelle.bat, build.bat and the umbraco.web.ui.csproj so it works in VS, command line and also in TeamCity. --- build/Build.bat | 11 ++++++++++- build/BuildBelle.bat | 3 ++- build/UmbracoVersion.txt | 1 + src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 5 ++++- 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 build/UmbracoVersion.txt diff --git a/build/Build.bat b/build/Build.bat index 535c379d52..107edbf7ea 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -1,5 +1,9 @@ @ECHO OFF -SET release=7.1.3 +IF NOT EXIST UmbracoVersion.txt ( + ECHO UmbracoVersion.txt missing! + GOTO :showerror +) +SET /p release= - + + + + From 8d4589827470af869d65b9dffd82c5c2917ce8fe Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 12:44:02 +0200 Subject: [PATCH 10/17] UmbracoVersion property no longer needed. Added data folder to the targets. --- build/NuSpecs/build/UmbracoCms.props | 3 --- build/NuSpecs/build/UmbracoCms.targets | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/NuSpecs/build/UmbracoCms.props b/build/NuSpecs/build/UmbracoCms.props index aed481dde4..1422a4cd76 100644 --- a/build/NuSpecs/build/UmbracoCms.props +++ b/build/NuSpecs/build/UmbracoCms.props @@ -1,8 +1,5 @@  - - 7.1.3 - AddUmbracoFilesToOutput; diff --git a/build/NuSpecs/build/UmbracoCms.targets b/build/NuSpecs/build/UmbracoCms.targets index bd8d28294c..024d8af7ad 100644 --- a/build/NuSpecs/build/UmbracoCms.targets +++ b/build/NuSpecs/build/UmbracoCms.targets @@ -30,6 +30,9 @@ Config\Splashes + + data + umbraco From b07665f4d484d14a48b433af50f2c811017ff9a3 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 14:22:13 +0200 Subject: [PATCH 11/17] Fixes U4-4650 Pluralization of document type aliases doesn't always work --- src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs index 050c8cf224..bb7144de75 100644 --- a/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs +++ b/src/umbraco.MacroEngines/RazorDynamicNode/DynamicNode.cs @@ -887,7 +887,7 @@ namespace umbraco.MacroEngines //this is from SqlMetal and just makes it a bit of fun to allow pluralisation private static string MakePluralName(string name) { - if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) + if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) { name = name + "es"; return name; From 43bfd6e4722ee6358645b27fd1e4c07aa9b0d0c7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 14:33:03 +0200 Subject: [PATCH 12/17] U4-4650 Pluralization of document type aliases doesn't always work --- src/Umbraco.Core/StringExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index d1b20cce30..723ff2efc9 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -213,7 +213,7 @@ namespace Umbraco.Core //this is from SqlMetal and just makes it a bit of fun to allow pluralisation public static string MakePluralName(this string name) { - if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("ss", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) + if ((name.EndsWith("x", StringComparison.OrdinalIgnoreCase) || name.EndsWith("ch", StringComparison.OrdinalIgnoreCase)) || (name.EndsWith("s", StringComparison.OrdinalIgnoreCase) || name.EndsWith("sh", StringComparison.OrdinalIgnoreCase))) { name = name + "es"; return name; From 1dd103caa3c69c4703f275ec8a7fcb213c30aac0 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Fri, 16 May 2014 18:53:23 +0200 Subject: [PATCH 13/17] U4-4930 NuGet update fails to copy new Umbraco binaries --- build/NuSpecs/UmbracoCms.Core.nuspec | 1 + build/NuSpecs/tools/install.core.ps1 | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 build/NuSpecs/tools/install.core.ps1 diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index bb0746e8bc..b770d8cfdc 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -67,5 +67,6 @@ + \ No newline at end of file diff --git a/build/NuSpecs/tools/install.core.ps1 b/build/NuSpecs/tools/install.core.ps1 new file mode 100644 index 0000000000..c712b363bc --- /dev/null +++ b/build/NuSpecs/tools/install.core.ps1 @@ -0,0 +1,24 @@ +param($rootPath, $toolsPath, $package, $project) + +if ($project) { + $dateTime = Get-Date -Format yyyyMMdd-HHmmss + $backupPath = Join-Path (Split-Path $project.FullName -Parent) "\App_Data\NuGetBackup\$dateTime" + $copyLogsPath = Join-Path $backupPath "CopyLogs" + $projectDestinationPath = Split-Path $project.FullName -Parent + + # Create backup folder and logs folder if it doesn't exist yet + New-Item -ItemType Directory -Force -Path $backupPath + New-Item -ItemType Directory -Force -Path $copyLogsPath + + # After backing up, remove all dlls from bin folder in case dll files are included in the VS project + # See: http://issues.umbraco.org/issue/U4-4930 + $umbracoBinFolder = Join-Path $projectDestinationPath "bin" + if(Test-Path $umbracoBinFolder) { + $umbracoBinBackupPath = Join-Path $backupPath "bin" + + New-Item -ItemType Directory -Force -Path $umbracoBinBackupPath + + robocopy $umbracoBinFolder $umbracoBinBackupPath /e /LOG:$copyLogsPath\UmbracoBinBackup.log + Remove-Item $umbracoBinFolder\*.dll -Force -Confirm:$false + } +} \ No newline at end of file From 142a9963afadd002a1dcf3a2363b9b35dd3907b7 Mon Sep 17 00:00:00 2001 From: Shannon Date: Sat, 17 May 2014 15:35:30 +1000 Subject: [PATCH 14/17] Fixes macro property saving issue in repo --- src/Umbraco.Core/Models/IMacroProperty.cs | 2 +- .../Models/MacroPropertyCollection.cs | 38 ++++++++++++++ src/Umbraco.Core/ObservableDictionary.cs | 22 ++++++++ .../Repositories/MacroRepository.cs | 10 ++-- .../Repositories/MacroRepositoryTest.cs | 51 +++++++++++++++++++ 5 files changed, 119 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Models/IMacroProperty.cs b/src/Umbraco.Core/Models/IMacroProperty.cs index c39e777a0e..a6c1d9ca5f 100644 --- a/src/Umbraco.Core/Models/IMacroProperty.cs +++ b/src/Umbraco.Core/Models/IMacroProperty.cs @@ -6,7 +6,7 @@ namespace Umbraco.Core.Models /// /// Defines a Property for a Macro /// - public interface IMacroProperty : IValueObject, IDeepCloneable + public interface IMacroProperty : IValueObject, IDeepCloneable, IRememberBeingDirty { [DataMember] int Id { get; set; } diff --git a/src/Umbraco.Core/Models/MacroPropertyCollection.cs b/src/Umbraco.Core/Models/MacroPropertyCollection.cs index 7496b582b4..de23d60e7c 100644 --- a/src/Umbraco.Core/Models/MacroPropertyCollection.cs +++ b/src/Umbraco.Core/Models/MacroPropertyCollection.cs @@ -24,6 +24,44 @@ namespace Umbraco.Core.Models } return clone; } + + /// + /// Used to update an existing macro property + /// + /// + /// + /// + /// + /// The existing property alias + /// + /// + public void UpdateProperty(string currentAlias, string name = null, int? sortOrder = null, string editorAlias = null, string newAlias = null) + { + var prop = this[currentAlias]; + if (prop == null) + { + throw new InvalidOperationException("No property exists with alias " + currentAlias); + } + + if (name.IsNullOrWhiteSpace() == false) + { + prop.Name = name; + } + if (sortOrder.HasValue) + { + prop.SortOrder = sortOrder.Value; + } + if (name.IsNullOrWhiteSpace() == false) + { + prop.EditorAlias = editorAlias; + } + + if (newAlias.IsNullOrWhiteSpace() == false && currentAlias != newAlias) + { + prop.Alias = newAlias; + ChangeKey(currentAlias, newAlias); + } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/ObservableDictionary.cs b/src/Umbraco.Core/ObservableDictionary.cs index b665071386..7e988e2b05 100644 --- a/src/Umbraco.Core/ObservableDictionary.cs +++ b/src/Umbraco.Core/ObservableDictionary.cs @@ -135,6 +135,28 @@ namespace Umbraco.Core } + /// + /// Allows us to change the key of an item + /// + /// + /// + public virtual void ChangeKey(TKey currentKey, TKey newKey) + { + if (!Indecies.ContainsKey(currentKey)) + { + throw new InvalidOperationException("No item with the key " + currentKey + "was found in the collection"); + } + if (ContainsKey(newKey)) + { + throw new DuplicateKeyException(newKey.ToString()); + } + + var currentIndex = Indecies[currentKey]; + + Indecies.Remove(currentKey); + Indecies.Add(newKey, currentIndex); + } + internal class DuplicateKeyException : Exception { diff --git a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs index 4fa6215477..c8ffcbe68a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs @@ -165,9 +165,9 @@ namespace Umbraco.Core.Persistence.Repositories Database.Update(dto); - //update the sections if they've changed + //update the properties if they've changed var macro = (Macro)entity; - if (macro.IsPropertyDirty("Properties")) + if (macro.IsPropertyDirty("Properties") || macro.Properties.Any(x => x.IsDirty())) { //now we need to delete any props that have been removed foreach (var propAlias in macro.RemovedProperties) @@ -188,7 +188,11 @@ namespace Umbraco.Core.Persistence.Repositories } else { - Database.Update(propDto); + //only update if it's dirty + if (macro.Properties[propDto.Alias].IsDirty()) + { + Database.Update(propDto); + } } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs index 5907b6c6be..377b9e57e7 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs @@ -364,7 +364,58 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void Can_Update_Property_For_Macro() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + using (var repository = new MacroRepository(unitOfWork, NullCacheProvider.Current)) + { + var macro = repository.Get(1); + macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test")); + repository.AddOrUpdate(macro); + unitOfWork.Commit(); + //Act + macro = repository.Get(1); + macro.Properties["new1"].Name = "this is a new name"; + repository.AddOrUpdate(macro); + unitOfWork.Commit(); + + + // Assert + var result = repository.Get(1); + Assert.AreEqual("new1", result.Properties.First().Alias); + Assert.AreEqual("this is a new name", result.Properties.First().Name); + + } + } + + [Test] + public void Can_Update_Macro_Property_Alias() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + using (var repository = new MacroRepository(unitOfWork, NullCacheProvider.Current)) + { + var macro = repository.Get(1); + macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test")); + repository.AddOrUpdate(macro); + unitOfWork.Commit(); + + //Act + macro = repository.Get(1); + macro.Properties.UpdateProperty("new1", newAlias: "newAlias"); + repository.AddOrUpdate(macro); + unitOfWork.Commit(); + + // Assert + var result = repository.Get(1); + Assert.AreEqual("newAlias", result.Properties.First().Alias); + } + } [TearDown] public override void TearDown() From 420746397dbfdf0976880b9ee95d899c2f5f9fe8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Sat, 17 May 2014 15:35:56 +1000 Subject: [PATCH 15/17] fixes macro property saving issue in editor (to ensure the alias/key can be changed) --- .../umbraco/developer/Macros/editMacro.aspx.cs | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs index a50c2970de..50fb8b912e 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs @@ -322,8 +322,6 @@ namespace umbraco.cms.presentation.developer void Save_Click(object sender, EventArgs e) { - //disable the add validators - macroProperties. Page.Validate(); @@ -351,10 +349,14 @@ namespace umbraco.cms.presentation.developer var macroElementType = (DropDownList)item.FindControl("macroPropertyType"); var prop = _macro.Properties.Single(x => x.Id == int.Parse(macroPropertyId.Value)); - prop.Alias = macroElementAlias.Text.Trim(); - prop.Name = macroElementName.Text.Trim(); - prop.EditorAlias = macroElementType.SelectedValue; - prop.SortOrder = sort; + + _macro.Properties.UpdateProperty( + prop.Alias, + macroElementName.Text.Trim(), + sort, + macroElementType.SelectedValue, + macroElementAlias.Text.Trim()); + sort++; } From 82c1c95e357e4f64df4fd441175997013c077734 Mon Sep 17 00:00:00 2001 From: Stephan Date: Thu, 15 May 2014 22:06:07 +0200 Subject: [PATCH 16/17] Detached PublishedProperty - refactor --- .../PublishedContent/PublishedContentType.cs | 5 ++++ src/Umbraco.Web/Models/DetachedContent.cs | 24 +++++++++++++++---- src/Umbraco.Web/UmbracoHelper.cs | 3 ++- 3 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs index 676eb05ef0..a0fa7932b5 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentType.cs @@ -44,6 +44,11 @@ namespace Umbraco.Core.Models.PublishedContent InitializeIndexes(); } + // create detached content type - ie does not match anything in the DB + internal PublishedContentType(string alias, IEnumerable propertyTypes) + : this (0, alias, propertyTypes) + { } + private void InitializeIndexes() { for (var i = 0; i < _propertyTypes.Length; i++) diff --git a/src/Umbraco.Web/Models/DetachedContent.cs b/src/Umbraco.Web/Models/DetachedContent.cs index e572de656c..b00ff67c72 100644 --- a/src/Umbraco.Web/Models/DetachedContent.cs +++ b/src/Umbraco.Web/Models/DetachedContent.cs @@ -10,21 +10,36 @@ namespace Umbraco.Web.Models { private readonly Dictionary _properties; + /// + /// Initialized a new instance of the class with properties. + /// + /// The properties + /// Properties must be detached or nested properties ie their property type must be detached or nested. + /// Such a detached content can be part of a published property value. public DetachedContent(IEnumerable properties) { - _properties = properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); + var propsa = properties.ToArray(); + if (propsa.Any(x => x.PropertyType.IsDetachedOrNested == false)) + throw new ArgumentException("At least one property type is neither detached nor nested.", "properties"); + _properties = propsa.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } + // don't uncomment until you know what you are doing + /* public DetachedContent(IPublishedContent content) { _properties = content.Properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } + */ + // don't uncomment until you know what you are doing + // at the moment, I don't fully + /* public DetachedContent(IContent content, bool isPreviewing) { var publishedContentType = PublishedContentType.Get(PublishedItemType.Content, content.ContentType.Alias); _properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, content.Properties, - (t, v) => PublishedProperty.GetDetached(t, v, isPreviewing)) + (t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing)) .ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } @@ -32,7 +47,7 @@ namespace Umbraco.Web.Models { var publishedContentType = PublishedContentType.Get(PublishedItemType.Media, media.ContentType.Alias); _properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, media.Properties, - (t, v) => PublishedProperty.GetDetached(t, v, isPreviewing)) + (t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing)) .ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } @@ -40,9 +55,10 @@ namespace Umbraco.Web.Models { var publishedContentType = PublishedContentType.Get(PublishedItemType.Member, member.ContentType.Alias); _properties = PublishedProperty.MapProperties(publishedContentType.PropertyTypes, member.Properties, - (t, v) => PublishedProperty.GetDetached(t, v, isPreviewing)) + (t, v) => PublishedProperty.GetDetached(t.Detached(), v, isPreviewing)) .ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } + */ public ICollection Properties { diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index bfa57d5ab3..a0cff38414 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -437,8 +437,9 @@ namespace Umbraco.Web //currently assigned node. The PublishedContentRequest will be null if: // * we are rendering a partial view or child action // * we are rendering a view from a custom route - if (UmbracoContext.PublishedContentRequest == null + if ((UmbracoContext.PublishedContentRequest == null || UmbracoContext.PublishedContentRequest.PublishedContent.Id != currentPage.Id) + && currentPage.Id > 0) // in case we're rendering a detached content (id == 0) { item.NodeId = currentPage.Id.ToString(); } From dacec47cd9413d77b3c41c5ba89fd57741f96366 Mon Sep 17 00:00:00 2001 From: Stephan Date: Sun, 18 May 2014 21:27:41 +0200 Subject: [PATCH 17/17] Fix the build --- src/Umbraco.Web/Models/DetachedContent.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/Umbraco.Web/Models/DetachedContent.cs b/src/Umbraco.Web/Models/DetachedContent.cs index b00ff67c72..df4effa078 100644 --- a/src/Umbraco.Web/Models/DetachedContent.cs +++ b/src/Umbraco.Web/Models/DetachedContent.cs @@ -18,10 +18,7 @@ namespace Umbraco.Web.Models /// Such a detached content can be part of a published property value. public DetachedContent(IEnumerable properties) { - var propsa = properties.ToArray(); - if (propsa.Any(x => x.PropertyType.IsDetachedOrNested == false)) - throw new ArgumentException("At least one property type is neither detached nor nested.", "properties"); - _properties = propsa.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); + _properties = properties.ToDictionary(x => x.PropertyTypeAlias, x => x, StringComparer.InvariantCultureIgnoreCase); } // don't uncomment until you know what you are doing