From e0878fdd9fde7282257be6a1c898b07f9cc645f8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 14:48:05 +1000 Subject: [PATCH 01/15] fixes unit test --- src/Umbraco.Tests/PluginManagerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/PluginManagerTests.cs b/src/Umbraco.Tests/PluginManagerTests.cs index 9544845041..861b598c1e 100644 --- a/src/Umbraco.Tests/PluginManagerTests.cs +++ b/src/Umbraco.Tests/PluginManagerTests.cs @@ -296,7 +296,7 @@ namespace Umbraco.Tests public void Resolves_Trees() { var trees = PluginManager.Current.ResolveTrees(); - Assert.AreEqual(36, trees.Count()); + Assert.AreEqual(40, trees.Count()); } [Test] From 56f1062db8cfb1c96f6d5d15a5090c958e076f3b Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 17:28:44 +1000 Subject: [PATCH 02/15] Fixes up EditUser - non-admins who have access to the Users app can edit other non-admins and cannot change anyone to be admin, but only admins can edit other admins that are not the root admin. Only the root admin can edit the root admin. --- .../umbraco.presentation/umbraco/users/EditUser.aspx.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index 1d6b362259..132917d737 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -65,13 +65,7 @@ namespace umbraco.cms.presentation.user protected void Page_Load(object sender, EventArgs e) { - //if the current user is not an admin they cannot edit a user at all - if (CurrentUser.IsAdmin() == false) - { - throw new UserAuthorizationException("Access denied"); - } - - int UID = int.Parse(Request.QueryString["id"]); + int UID = int.Parse(Request.QueryString["id"]); u = BusinessLogic.User.GetUser(UID); //the true admin can only edit the true admin From 010d47c68b843a66cd601f60fa53516cba984c54 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 10:23:43 +0200 Subject: [PATCH 03/15] Fixes U4-2822 Datepicker throws "Specified cast is not valid" when saving through API --- src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs | 4 ++-- src/umbraco.editorControls/datepicker/DateData.cs | 15 +++++++++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs index 4b50d835fe..29e4c472b7 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyDataDto.cs @@ -65,12 +65,12 @@ namespace Umbraco.Core.Models.Rdbms return Date.Value; } - if(!string.IsNullOrEmpty(VarChar)) + if(string.IsNullOrEmpty(VarChar) == false) { return VarChar; } - if(!string.IsNullOrEmpty(Text)) + if(string.IsNullOrEmpty(Text) == false) { return Text; } diff --git a/src/umbraco.editorControls/datepicker/DateData.cs b/src/umbraco.editorControls/datepicker/DateData.cs index fe1edc7be4..d7e29bef8e 100644 --- a/src/umbraco.editorControls/datepicker/DateData.cs +++ b/src/umbraco.editorControls/datepicker/DateData.cs @@ -11,10 +11,17 @@ namespace umbraco.editorControls.datepicker public override System.Xml.XmlNode ToXMl(System.Xml.XmlDocument d) { - if (Value != null && Value.ToString() != "") - return d.CreateTextNode(((DateTime) Value).ToString("s")); - else - return d.CreateTextNode(""); + if (Value != null && Value.ToString() != "") + { + if(Value is DateTime) + return d.CreateTextNode(((DateTime) Value).ToString("s")); + + DateTime convertedDate; + if (DateTime.TryParse(Value.ToString(), out convertedDate)) + return d.CreateTextNode(convertedDate.ToString("s")); + } + + return d.CreateTextNode(""); } public override void MakeNew(int PropertyId) From 767252cdf1cfa80542cd0ce8371a01432ed69159 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 10:31:45 +0200 Subject: [PATCH 04/15] Creates IDisposeOnRequestEnd and ensures UmbracoContext and UmbracoDatabase implement it, then we only dispose of these types of objects at the end of the request if they are part of the httpcontext items (U4-2738). Fixes: U4-2988 UmbracoObjectTypesExtensions is not thread safe --- src/Umbraco.Core/IDisposeOnRequestEnd.cs | 14 ++++++++ .../Models/UmbracoObjectTypesExtensions.cs | 32 +++++++++--------- .../Persistence/UmbracoDatabase.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + src/Umbraco.Web/UmbracoContext.cs | 2 +- src/Umbraco.Web/UmbracoModule.cs | 33 +++++++++++++++++-- 6 files changed, 64 insertions(+), 20 deletions(-) create mode 100644 src/Umbraco.Core/IDisposeOnRequestEnd.cs diff --git a/src/Umbraco.Core/IDisposeOnRequestEnd.cs b/src/Umbraco.Core/IDisposeOnRequestEnd.cs new file mode 100644 index 0000000000..cf1ec3a177 --- /dev/null +++ b/src/Umbraco.Core/IDisposeOnRequestEnd.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Umbraco.Core +{ + /// + /// Any class implementing this interface that is added to the httpcontext.items keys or values will be disposed of at the end of the request. + /// + public interface IDisposeOnRequestEnd : IDisposable + { + } +} diff --git a/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs index a97f1fe976..7cc130600b 100644 --- a/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs +++ b/src/Umbraco.Core/Models/UmbracoObjectTypesExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using Umbraco.Core.CodeAnnotations; @@ -9,7 +10,8 @@ namespace Umbraco.Core.Models /// public static class UmbracoObjectTypesExtensions { - private static readonly Dictionary UmbracoObjectTypeCache = new Dictionary(); + //MUST be concurrent to avoid thread collisions! + private static readonly ConcurrentDictionary UmbracoObjectTypeCache = new ConcurrentDictionary(); /// /// Get an UmbracoObjectTypes value from it's name @@ -48,24 +50,22 @@ namespace Umbraco.Core.Models /// a GUID value of the UmbracoObjectTypes public static Guid GetGuid(this UmbracoObjectTypes umbracoObjectType) { - if (UmbracoObjectTypeCache.ContainsKey(umbracoObjectType)) - return UmbracoObjectTypeCache[umbracoObjectType]; + return UmbracoObjectTypeCache.GetOrAdd(umbracoObjectType, types => + { + var type = typeof(UmbracoObjectTypes); + var memInfo = type.GetMember(umbracoObjectType.ToString()); + var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute), + false); - var type = typeof(UmbracoObjectTypes); - var memInfo = type.GetMember(umbracoObjectType.ToString()); - var attributes = memInfo[0].GetCustomAttributes(typeof(UmbracoObjectTypeAttribute), - false); + if (attributes.Length == 0) + return Guid.Empty; - if (attributes.Length == 0) - return Guid.Empty; + var attribute = ((UmbracoObjectTypeAttribute)attributes[0]); + if (attribute == null) + return Guid.Empty; - var attribute = ((UmbracoObjectTypeAttribute)attributes[0]); - if (attribute == null) - return Guid.Empty; - - UmbracoObjectTypeCache.Add(umbracoObjectType, attribute.ObjectId); - - return attribute.ObjectId; + return attribute.ObjectId; + }); } /// diff --git a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs index 522e0b4173..98d5d9cebc 100644 --- a/src/Umbraco.Core/Persistence/UmbracoDatabase.cs +++ b/src/Umbraco.Core/Persistence/UmbracoDatabase.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Persistence /// can then override any additional execution (such as additional loggging, functionality, etc...) that we need to without breaking compatibility since we'll always be exposing /// this object instead of the base PetaPoco database object. /// - public class UmbracoDatabase : Database + public class UmbracoDatabase : Database, IDisposeOnRequestEnd { private readonly Guid _instanceId = Guid.NewGuid(); /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 4d5bd09932..566fdb85a7 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -165,6 +165,7 @@ + diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs index 17751b4077..2458dc62e0 100644 --- a/src/Umbraco.Web/UmbracoContext.cs +++ b/src/Umbraco.Web/UmbracoContext.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web /// /// Class that encapsulates Umbraco information of a specific HTTP request /// - public class UmbracoContext : DisposableObject + public class UmbracoContext : DisposableObject, IDisposeOnRequestEnd { private const string HttpContextItemName = "Umbraco.Web.UmbracoContext"; private static readonly object Locker = new object(); diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index 4ef5bc99a7..398ba2786e 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -1,5 +1,6 @@ using System; using System.Collections; +using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; @@ -465,10 +466,38 @@ namespace Umbraco.Web /// private static void DisposeHttpContextItems(HttpContext http) { + // do not process if client-side request + if (http.Request.Url.IsClientSideRequest()) + return; + + //get a list of keys to dispose + var keys = new HashSet(); foreach (DictionaryEntry i in http.Items) { - i.Value.DisposeIfDisposable(); - i.Key.DisposeIfDisposable(); + if (i.Value is IDisposeOnRequestEnd || i.Key is IDisposeOnRequestEnd) + { + keys.Add(i.Key); + } + } + //dispose each item and key that was found as disposable. + foreach (var k in keys) + { + try + { + http.Items[k].DisposeIfDisposable(); + } + catch (Exception ex) + { + LogHelper.Error("Could not dispose item with key " + k, ex); + } + try + { + k.DisposeIfDisposable(); + } + catch (Exception ex) + { + LogHelper.Error("Could not dispose item key " + k, ex); + } } } From 328ada2f3829c33f2066ba1a8c7fa565f8e8a914 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 10:46:08 +0200 Subject: [PATCH 05/15] Bump version number --- build/Build.bat | 2 +- src/Umbraco.Core/Configuration/UmbracoVersion.cs | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build/Build.bat b/build/Build.bat index 2664474af3..98f37514f6 100644 --- a/build/Build.bat +++ b/build/Build.bat @@ -1,5 +1,5 @@ @ECHO OFF -SET release=6.1.5 +SET release=6.1.6 SET comment= SET version=%release% diff --git a/src/Umbraco.Core/Configuration/UmbracoVersion.cs b/src/Umbraco.Core/Configuration/UmbracoVersion.cs index 357bc475c9..818d0cca0d 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("6.1.5"); + private static readonly Version Version = new Version("6.1.6"); /// /// 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 8ed914eeeb..dc143c0c1d 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -2602,9 +2602,9 @@ xcopy "$(ProjectDir)"..\packages\SqlServerCE.4.0.0.0\x86\*.* "$(TargetDir)x86\" True True - 6150 + 6160 / - http://localhost:6150 + http://localhost:6160 False False From abbf8aeb421230f8b28e1d74b1d06df90ae4fca9 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 10:49:33 +0200 Subject: [PATCH 06/15] U4-2709 Error after upgrading from 6.1.3 to 6.1.4 --- build/NuSpecs/UmbracoCms.Core.nuspec | 104 +++++++++++++-------------- build/NuSpecs/UmbracoCms.nuspec | 2 +- 2 files changed, 53 insertions(+), 53 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 009b47b89b..28d8be35c8 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -1,8 +1,8 @@ - + UmbracoCms.Core - 6.1.2 + 6.2.0 Umbraco Cms Core Binaries Morten Christensen Umbraco HQ @@ -14,57 +14,57 @@ Contains the core assemblies needed to run Umbraco Cms en-US umbraco - + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index e84ebc8e2e..babaf5f845 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -1,4 +1,4 @@ - + UmbracoCms From 965a7fc500396c583e0425313083cf608f199f83 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 10:55:13 +0200 Subject: [PATCH 07/15] Fixes: U4-2925 Tree performance is very poor in 6.1.x when having event subscriptions --- src/Umbraco.Core/TypeHelper.cs | 10 ++ .../Trees/BaseContentTreeTests.cs | 156 +++++++++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + .../umbraco/Trees/BaseContentTree.cs | 129 +++++++++----- .../umbraco/Trees/BaseMediaTree.cs | 163 ++++++++++++------ .../umbraco/Trees/BaseTree.cs | 10 ++ 6 files changed, 367 insertions(+), 102 deletions(-) create mode 100644 src/Umbraco.Tests/Trees/BaseContentTreeTests.cs diff --git a/src/Umbraco.Core/TypeHelper.cs b/src/Umbraco.Core/TypeHelper.cs index 26dd2a8402..377cfb65c5 100644 --- a/src/Umbraco.Core/TypeHelper.cs +++ b/src/Umbraco.Core/TypeHelper.cs @@ -16,6 +16,16 @@ namespace Umbraco.Core private static readonly ConcurrentDictionary GetFieldsCache = new ConcurrentDictionary(); private static readonly ConcurrentDictionary, PropertyInfo[]> GetPropertiesCache = new ConcurrentDictionary, PropertyInfo[]>(); + /// + /// Checks if the method is actually overriding a base method + /// + /// + /// + public static bool IsOverride(MethodInfo m) + { + return m.GetBaseDefinition().DeclaringType != m.DeclaringType; + } + /// /// Find all assembly references that are referencing the assignTypeFrom Type's assembly found in the assemblyList /// diff --git a/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs b/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs new file mode 100644 index 0000000000..70c4ed9326 --- /dev/null +++ b/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using NUnit.Framework; +using umbraco.cms.presentation.Trees; + +namespace Umbraco.Tests.Trees +{ + + [TestFixture] + public class BaseMediaTreeTests + { + + [TearDown] + public void TestTearDown() + { + BaseTree.AfterTreeRender -= EventHandler; + BaseTree.BeforeTreeRender -= EventHandler; + } + + [Test] + public void Run_Optimized() + { + var tree = new MyOptimizedMediaTree("media"); + + Assert.IsTrue(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_AfterRender() + { + var tree = new MyOptimizedMediaTree("media"); + + BaseTree.AfterTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_BeforeRender() + { + var tree = new MyOptimizedMediaTree("media"); + + BaseTree.BeforeTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + private void EventHandler(object sender, TreeEventArgs treeEventArgs) + { + + } + + public class MyOptimizedMediaTree : BaseMediaTree + { + public MyOptimizedMediaTree(string application) + : base(application) + { + } + + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + + } + } + + + } + + [TestFixture] + public class BaseContentTreeTests + { + + [TearDown] + public void TestTearDown() + { + BaseTree.AfterTreeRender -= EventHandler; + BaseTree.BeforeTreeRender -= EventHandler; + } + + [Test] + public void Run_Optimized() + { + var tree = new MyOptimizedContentTree("content"); + + Assert.IsTrue(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_AfterRender() + { + var tree = new MyOptimizedContentTree("content"); + + BaseTree.AfterTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_BeforeRender() + { + var tree = new MyOptimizedContentTree("content"); + + BaseTree.BeforeTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Overriden_Method() + { + var tree = new MyNotOptimizedContentTree("content"); + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + private void EventHandler(object sender, TreeEventArgs treeEventArgs) + { + + } + + public class MyOptimizedContentTree : BaseContentTree + { + public MyOptimizedContentTree(string application) + : base(application) + { + } + + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + + } + } + + public class MyNotOptimizedContentTree : BaseContentTree + { + public MyNotOptimizedContentTree(string application) + : base(application) + { + } + + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + + } + + protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc) + { + base.OnRenderNode(ref xNode, doc); + } + } + + + } +} diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 72950fe466..7dc568704b 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -350,6 +350,7 @@ + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs index 39eb33e31f..bb1046985b 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Reflection; using System.Text; using System.Web; +using Umbraco.Core; using Umbraco.Core.Models; using umbraco.BasePages; using umbraco.BusinessLogic; @@ -73,61 +75,64 @@ function openContent(id) { /// Renders the specified tree item. /// /// The tree. - /*public override void Render(ref XmlTree Tree) - { - //get documents to render - Document[] docs = Document.GetChildrenForTree(m_id); - - var args = new TreeEventArgs(Tree); - OnBeforeTreeRender(docs, args); - - foreach (Document dd in docs) - { - List allowedUserOptions = GetUserActionsForNode(dd); - if (CanUserAccessNode(dd, allowedUserOptions)) - { - - XmlTreeNode node = CreateNode(dd, allowedUserOptions); - - OnRenderNode(ref node, dd); - - OnBeforeNodeRender(ref Tree, ref node, EventArgs.Empty); - if (node != null) - { - Tree.Add(node); - OnAfterNodeRender(ref Tree, ref node, EventArgs.Empty); - } - } - } - OnAfterTreeRender(docs, args); - }*/ public override void Render(ref XmlTree Tree) { - //get documents to render - var entities = Services.EntityService.GetChildren(m_id, UmbracoObjectTypes.Document).ToArray(); - - var args = new TreeEventArgs(Tree); - OnBeforeTreeRender(entities, args, true); - - foreach (var entity in entities) + if (UseOptimizedRendering == false) { - var e = entity as UmbracoEntity; - List allowedUserOptions = GetUserActionsForNode(e); - if (CanUserAccessNode(e, allowedUserOptions)) + //We cannot run optimized mode since there are subscribers to events/methods that require document instances + // so we'll render the original way by looking up the docs. + + //get documents to render + var docs = Document.GetChildrenForTree(m_id); + + var args = new TreeEventArgs(Tree); + OnBeforeTreeRender(docs, args); + + foreach (var dd in docs) { - XmlTreeNode node = CreateNode(e, allowedUserOptions); - - OnRenderNode(ref node, new Document(entity, LoadMinimalDocument)); - - OnBeforeNodeRender(ref Tree, ref node, EventArgs.Empty); - if (node != null) + var allowedUserOptions = GetUserActionsForNode(dd); + if (CanUserAccessNode(dd, allowedUserOptions)) { - Tree.Add(node); - OnAfterNodeRender(ref Tree, ref node, EventArgs.Empty); + + var node = CreateNode(dd, allowedUserOptions); + + OnRenderNode(ref node, dd); + + OnBeforeNodeRender(ref Tree, ref node, EventArgs.Empty); + if (node != null) + { + Tree.Add(node); + OnAfterNodeRender(ref Tree, ref node, EventArgs.Empty); + } + } + } + OnAfterTreeRender(docs, args); + } + else + { + + //We ARE running in optmized mode, this means we will NOT be raising the BeforeTreeRender or AfterTreeRender + // events and NOT calling the OnRenderNode method - we've already detected that there are not subscribers or implementations + // to call so that is fine. + + var entities = Services.EntityService.GetChildren(m_id, UmbracoObjectTypes.Document).ToArray(); + foreach (var entity in entities) + { + var e = entity as UmbracoEntity; + var allowedUserOptions = GetUserActionsForNode(e); + if (CanUserAccessNode(e, allowedUserOptions)) + { + var node = CreateNode(e, allowedUserOptions); + + OnBeforeNodeRender(ref Tree, ref node, EventArgs.Empty); + if (node != null) + { + Tree.Add(node); + OnAfterNodeRender(ref Tree, ref node, EventArgs.Empty); + } } } } - OnAfterTreeRender(entities, args, true); } #region Tree Create-node-helper Methods - Legacy @@ -475,5 +480,35 @@ function openContent(id) { return umbraco.BusinessLogic.Actions.Action.FromString(fullMenu); } + /// + /// Returns true if we can use the EntityService to render the tree or revert to the original way + /// using normal documents + /// + /// + /// We determine this by: + /// * If there are any subscribers to the events: BeforeTreeRender or AfterTreeRender - then we cannot run optimized + /// * If there are any overrides of the method: OnRenderNode - then we cannot run optimized + /// + internal bool UseOptimizedRendering + { + get + { + if (HasEntityBasedEventSubscribers) + { + return false; + } + + //now we need to check if the current tree type has OnRenderNode overridden with a custom implementation + //Strangely - this even works in med trust! + var method = this.GetType().GetMethod("OnRenderNode", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(XmlTreeNode).MakeByRefType(), typeof(Document) }, null); + if (TypeHelper.IsOverride(method)) + { + return false; + } + + return true; + } + } + } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs index f4e4684c72..e501489534 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs @@ -2,12 +2,14 @@ using System; using System.Collections.Generic; using System.Globalization; using System.Linq; +using System.Reflection; using System.Text; using Umbraco.Core.Logging; using Umbraco.Core.Models; using umbraco.BasePages; using umbraco.BusinessLogic; using umbraco.BusinessLogic.Actions; +using umbraco.cms.businesslogic.web; using umbraco.interfaces; using Umbraco.Core; using Media = umbraco.cms.businesslogic.media.Media; @@ -17,7 +19,6 @@ namespace umbraco.cms.presentation.Trees { public abstract class BaseMediaTree : BaseTree { - private DisposableTimer _timer; private User _user; public BaseMediaTree(string application) @@ -57,78 +58,109 @@ function openMedia(id) { } } - //Updated Render method for improved performance, but currently not usable because of backwards compatibility - //with the OnBeforeTreeRender/OnAfterTreeRender events, which sends an array for legacy Media items. public override void Render(ref XmlTree tree) { - //_timer = DisposableTimer.Start(x => LogHelper.Debug("Media tree loaded" + " (took " + x + "ms)")); - var entities = Services.EntityService.GetChildren(m_id, UmbracoObjectTypes.Media).ToArray(); - - var args = new TreeEventArgs(tree); - OnBeforeTreeRender(entities, args, false); - - foreach (UmbracoEntity entity in entities) + if (UseOptimizedRendering == false) { - XmlTreeNode xNode = XmlTreeNode.Create(this); - xNode.NodeID = entity.Id.ToString(CultureInfo.InvariantCulture); - xNode.Text = entity.Name; + //We cannot run optimized mode since there are subscribers to events/methods that require document instances + // so we'll render the original way by looking up the docs. - xNode.HasChildren = entity.HasChildren; - xNode.Source = this.IsDialog ? GetTreeDialogUrl(entity.Id) : GetTreeServiceUrl(entity.Id); + var docs = new Media(m_id).Children; - xNode.Icon = entity.ContentTypeIcon; - xNode.OpenIcon = entity.ContentTypeIcon; - - if (IsDialog == false) + var args = new TreeEventArgs(tree); + OnBeforeTreeRender(docs, args); + + foreach (var dd in docs) { - if(this.ShowContextMenu == false) - xNode.Menu = null; - xNode.Action = "javascript:openMedia(" + entity.Id + ");"; - } - else - { - xNode.Menu = this.ShowContextMenu ? new List(new IAction[] { ActionRefresh.Instance }) : null; - if (this.DialogMode == TreeDialogModes.fulllink) + var e = dd; + var xNode = PerformNodeRender(e.Id, e.Text, e.HasChildren, e.ContentType.IconUrl, e.ContentType.Alias, () => GetLinkValue(e, e.Id.ToString(CultureInfo.InvariantCulture))); + + + OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); + if (xNode != null) { - string nodeLink = GetLinkValue(entity); - if (string.IsNullOrEmpty(nodeLink) == false) - { - xNode.Action = "javascript:openMedia('" + nodeLink + "');"; - } - else - { - if (string.Equals(entity.ContentTypeAlias, Constants.Conventions.MediaTypes.Folder, StringComparison.OrdinalIgnoreCase)) - { - //#U4-2254 - Inspiration to use void from here: http://stackoverflow.com/questions/4924383/jquery-object-object-error - xNode.Action = "javascript:void jQuery('.umbTree #" + entity.Id.ToString(CultureInfo.InvariantCulture) + "').click();"; - } - else - { - xNode.Action = null; - xNode.Style.DimNode(); - } - } + tree.Add(xNode); + OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); + } + } + + OnAfterTreeRender(docs, args); + } + else + { + //We ARE running in optmized mode, this means we will NOT be raising the BeforeTreeRender or AfterTreeRender + // events - we've already detected that there are not subscribers or implementations + // to call so that is fine. + + var entities = Services.EntityService.GetChildren(m_id, UmbracoObjectTypes.Media).ToArray(); + + foreach (UmbracoEntity entity in entities) + { + var e = entity; + var xNode = PerformNodeRender(e.Id, entity.Name, e.HasChildren, e.ContentTypeIcon, e.ContentTypeAlias, () => GetLinkValue(e)); + + OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); + if (xNode != null) + { + tree.Add(xNode); + OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); + } + } + } + } + + private XmlTreeNode PerformNodeRender(int nodeId, string nodeName, bool hasChildren, string icon, string contentTypeAlias, Func getLinkValue) + { + var xNode = XmlTreeNode.Create(this); + xNode.NodeID = nodeId.ToString(CultureInfo.InvariantCulture); + xNode.Text = nodeName; + + xNode.HasChildren = hasChildren; + xNode.Source = this.IsDialog ? GetTreeDialogUrl(nodeId) : GetTreeServiceUrl(nodeId); + + xNode.Icon = icon; + xNode.OpenIcon = icon; + + if (IsDialog == false) + { + if (this.ShowContextMenu == false) + xNode.Menu = null; + xNode.Action = "javascript:openMedia(" + nodeId + ");"; + } + else + { + xNode.Menu = this.ShowContextMenu ? new List(new IAction[] { ActionRefresh.Instance }) : null; + if (this.DialogMode == TreeDialogModes.fulllink) + { + string nodeLink = getLinkValue(); + if (string.IsNullOrEmpty(nodeLink) == false) + { + xNode.Action = "javascript:openMedia('" + nodeLink + "');"; } else { - xNode.Action = "javascript:openMedia('" + entity.Id.ToString(CultureInfo.InvariantCulture) + "');"; + if (string.Equals(contentTypeAlias, Constants.Conventions.MediaTypes.Folder, StringComparison.OrdinalIgnoreCase)) + { + //#U4-2254 - Inspiration to use void from here: http://stackoverflow.com/questions/4924383/jquery-object-object-error + xNode.Action = "javascript:void jQuery('.umbTree #" + nodeId.ToString(CultureInfo.InvariantCulture) + "').click();"; + } + else + { + xNode.Action = null; + xNode.Style.DimNode(); + } } } - - OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); - if (xNode != null) + else { - tree.Add(xNode); - OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); + xNode.Action = "javascript:openMedia('" + nodeId.ToString(CultureInfo.InvariantCulture) + "');"; } } - //stop the timer and log the output - //_timer.Dispose(); - - OnAfterTreeRender(entities, args, false); + return xNode; } + /// /// Returns the value for a link in WYSIWYG mode, by default only media items that have a @@ -183,5 +215,26 @@ function openMedia(id) { /// public static List LinkableMediaDataTypes { get; protected set; } + /// + /// Returns true if we can use the EntityService to render the tree or revert to the original way + /// using normal documents + /// + /// + /// We determine this by: + /// * If there are any subscribers to the events: BeforeTreeRender or AfterTreeRender - then we cannot run optimized + /// + internal bool UseOptimizedRendering + { + get + { + if (HasEntityBasedEventSubscribers) + { + return false; + } + + return true; + } + } + } } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs index 08038f0421..9c547edf04 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseTree.cs @@ -527,6 +527,7 @@ namespace umbraco.cms.presentation.Trees AfterTreeRender(sender, e); } + [Obsolete("Do not use this method to raise events, it is no longer used and will cause very high performance spikes!")] protected internal virtual void OnBeforeTreeRender(IEnumerable sender, TreeEventArgs e, bool isContent) { if (BeforeTreeRender != null) @@ -542,6 +543,7 @@ namespace umbraco.cms.presentation.Trees } } + [Obsolete("Do not use this method to raise events, it is no longer used and will cause very high performance spikes!")] protected internal virtual void OnAfterTreeRender(IEnumerable sender, TreeEventArgs e, bool isContent) { if (AfterTreeRender != null) @@ -557,6 +559,14 @@ namespace umbraco.cms.presentation.Trees } } + /// + /// Returns true if there are subscribers to either BeforeTreeRender or AfterTreeRender + /// + internal bool HasEntityBasedEventSubscribers + { + get { return BeforeTreeRender != null || AfterTreeRender != null; } + } + /// /// Event that is raised once actions are assigned to nodes /// From e5320f0abd103d4f97df897374458eb4442a1e43 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 13:36:49 +1000 Subject: [PATCH 08/15] Obsoletes the LoadMinimalDocument flag since it no longer serves a purpose. --- .../umbraco/Trees/BaseContentTree.cs | 10 ++-------- .../umbraco/Trees/ContentRecycleBin.cs | 4 +++- .../umbraco.presentation/umbraco/Trees/loadContent.cs | 5 ++++- .../MultiNodeTreePicker/FilteredContentTree.cs | 1 + 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs index bb1046985b..31f65e3dde 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs @@ -26,14 +26,8 @@ namespace umbraco.cms.presentation.Trees public BaseContentTree(string application) : base(application) { } private User _user; - - /// - /// Determines whether the (legacy) Document object passed to the OnRenderNode-method - /// should be initialized with a full set of properties. - /// By default the Document will be initialized, so setting the boolean to True will - /// ensure that the Document object is loaded with a minimum set of properties to - /// improve performance. - /// + + [Obsolete("This is no longer used and has no effect")] protected virtual bool LoadMinimalDocument { get; set; } /// diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs index aff51792be..c8ef6f2b2f 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Text; using umbraco.businesslogic; using umbraco.cms.businesslogic; @@ -19,6 +20,7 @@ namespace umbraco.cms.presentation.Trees public ContentRecycleBin(string application) : base(application) { } + [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs index abd79a204a..8098c26470 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs @@ -1,10 +1,12 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using umbraco.BusinessLogic.Actions; using umbraco.businesslogic; using umbraco.cms.businesslogic.web; using umbraco.cms.presentation.Trees; using umbraco.interfaces; using Umbraco.Core; +using Action = umbraco.BusinessLogic.Actions.Action; namespace umbraco { @@ -54,6 +56,7 @@ namespace umbraco } } + [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get diff --git a/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs b/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs index 664282ec89..c05f9849d9 100644 --- a/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs +++ b/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs @@ -36,6 +36,7 @@ namespace umbraco.editorControls.MultiNodeTreePicker /// private int? m_DeterminedStartNodeId = null; + [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get From 35f65a2c64c492c1c6cc521de0c5d9826eca320f Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 13:47:19 +1000 Subject: [PATCH 09/15] re-enables LoadMinimalDocument and adds this to the optimized check, even in optimized model the OnRenderNode can still execute with a minimal doc. --- .../Trees/BaseContentTreeTests.cs | 105 +++++++----------- src/Umbraco.Tests/Trees/BaseMediaTreeTests.cs | 65 +++++++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + .../umbraco/Trees/BaseContentTree.cs | 8 +- .../umbraco/Trees/ContentRecycleBin.cs | 1 - .../umbraco/Trees/loadContent.cs | 1 - .../FilteredContentTree.cs | 1 - 7 files changed, 110 insertions(+), 72 deletions(-) create mode 100644 src/Umbraco.Tests/Trees/BaseMediaTreeTests.cs diff --git a/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs b/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs index 70c4ed9326..4a2c856a15 100644 --- a/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs +++ b/src/Umbraco.Tests/Trees/BaseContentTreeTests.cs @@ -7,67 +7,6 @@ using umbraco.cms.presentation.Trees; namespace Umbraco.Tests.Trees { - - [TestFixture] - public class BaseMediaTreeTests - { - - [TearDown] - public void TestTearDown() - { - BaseTree.AfterTreeRender -= EventHandler; - BaseTree.BeforeTreeRender -= EventHandler; - } - - [Test] - public void Run_Optimized() - { - var tree = new MyOptimizedMediaTree("media"); - - Assert.IsTrue(tree.UseOptimizedRendering); - } - - [Test] - public void Not_Optimized_Events_AfterRender() - { - var tree = new MyOptimizedMediaTree("media"); - - BaseTree.AfterTreeRender += EventHandler; - - Assert.IsFalse(tree.UseOptimizedRendering); - } - - [Test] - public void Not_Optimized_Events_BeforeRender() - { - var tree = new MyOptimizedMediaTree("media"); - - BaseTree.BeforeTreeRender += EventHandler; - - Assert.IsFalse(tree.UseOptimizedRendering); - } - - private void EventHandler(object sender, TreeEventArgs treeEventArgs) - { - - } - - public class MyOptimizedMediaTree : BaseMediaTree - { - public MyOptimizedMediaTree(string application) - : base(application) - { - } - - protected override void CreateRootNode(ref XmlTreeNode rootNode) - { - - } - } - - - } - [TestFixture] public class BaseContentTreeTests { @@ -82,15 +21,17 @@ namespace Umbraco.Tests.Trees [Test] public void Run_Optimized() { - var tree = new MyOptimizedContentTree("content"); + var tree1 = new MyOptimizedContentTree1("content"); + var tree2 = new MyOptimizedContentTree2("content"); - Assert.IsTrue(tree.UseOptimizedRendering); + Assert.IsTrue(tree1.UseOptimizedRendering); + Assert.IsTrue(tree2.UseOptimizedRendering); } [Test] public void Not_Optimized_Events_AfterRender() { - var tree = new MyOptimizedContentTree("content"); + var tree = new MyOptimizedContentTree1("content"); BaseTree.AfterTreeRender += EventHandler; @@ -100,7 +41,7 @@ namespace Umbraco.Tests.Trees [Test] public void Not_Optimized_Events_BeforeRender() { - var tree = new MyOptimizedContentTree("content"); + var tree = new MyOptimizedContentTree1("content"); BaseTree.BeforeTreeRender += EventHandler; @@ -120,17 +61,42 @@ namespace Umbraco.Tests.Trees } - public class MyOptimizedContentTree : BaseContentTree + //optimized because we are not overriding OnRenderNode + public class MyOptimizedContentTree1 : BaseContentTree { - public MyOptimizedContentTree(string application) + public MyOptimizedContentTree1(string application) : base(application) { } + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + + } + } + + public class MyOptimizedContentTree2 : BaseContentTree + { + public MyOptimizedContentTree2(string application) + : base(application) + { + } + + protected override bool LoadMinimalDocument + { + get { return true; } + } + protected override void CreateRootNode(ref XmlTreeNode rootNode) { } + + //even if we override it will still be optimized because of the LoadMinimalDocument flag + protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc) + { + base.OnRenderNode(ref xNode, doc); + } } public class MyNotOptimizedContentTree : BaseContentTree @@ -145,6 +111,11 @@ namespace Umbraco.Tests.Trees } + protected override bool LoadMinimalDocument + { + get { return false; } + } + protected override void OnRenderNode(ref XmlTreeNode xNode, umbraco.cms.businesslogic.web.Document doc) { base.OnRenderNode(ref xNode, doc); diff --git a/src/Umbraco.Tests/Trees/BaseMediaTreeTests.cs b/src/Umbraco.Tests/Trees/BaseMediaTreeTests.cs new file mode 100644 index 0000000000..0e93b3db78 --- /dev/null +++ b/src/Umbraco.Tests/Trees/BaseMediaTreeTests.cs @@ -0,0 +1,65 @@ +using NUnit.Framework; +using umbraco.cms.presentation.Trees; + +namespace Umbraco.Tests.Trees +{ + [TestFixture] + public class BaseMediaTreeTests + { + + [TearDown] + public void TestTearDown() + { + BaseTree.AfterTreeRender -= EventHandler; + BaseTree.BeforeTreeRender -= EventHandler; + } + + [Test] + public void Run_Optimized() + { + var tree = new MyOptimizedMediaTree("media"); + + Assert.IsTrue(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_AfterRender() + { + var tree = new MyOptimizedMediaTree("media"); + + BaseTree.AfterTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + [Test] + public void Not_Optimized_Events_BeforeRender() + { + var tree = new MyOptimizedMediaTree("media"); + + BaseTree.BeforeTreeRender += EventHandler; + + Assert.IsFalse(tree.UseOptimizedRendering); + } + + private void EventHandler(object sender, TreeEventArgs treeEventArgs) + { + + } + + public class MyOptimizedMediaTree : BaseMediaTree + { + public MyOptimizedMediaTree(string application) + : base(application) + { + } + + protected override void CreateRootNode(ref XmlTreeNode rootNode) + { + + } + } + + + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 7dc568704b..b90845f2e6 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -351,6 +351,7 @@ + diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs index 31f65e3dde..81a97ab593 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs @@ -27,7 +27,6 @@ namespace umbraco.cms.presentation.Trees private User _user; - [Obsolete("This is no longer used and has no effect")] protected virtual bool LoadMinimalDocument { get; set; } /// @@ -118,6 +117,11 @@ function openContent(id) { { var node = CreateNode(e, allowedUserOptions); + //in optimized mode the LoadMinimalDocument will ALWAYS be true, if it is not true then we will + // be rendering in non-optimized mode and this code will not get executed so we don't need to worry + // about performance here. + OnRenderNode(ref node, new Document(e, LoadMinimalDocument)); + OnBeforeNodeRender(ref Tree, ref node, EventArgs.Empty); if (node != null) { @@ -495,7 +499,7 @@ function openContent(id) { //now we need to check if the current tree type has OnRenderNode overridden with a custom implementation //Strangely - this even works in med trust! var method = this.GetType().GetMethod("OnRenderNode", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(XmlTreeNode).MakeByRefType(), typeof(Document) }, null); - if (TypeHelper.IsOverride(method)) + if (TypeHelper.IsOverride(method) && LoadMinimalDocument == false) { return false; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs index c8ef6f2b2f..31dc820127 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/ContentRecycleBin.cs @@ -20,7 +20,6 @@ namespace umbraco.cms.presentation.Trees public ContentRecycleBin(string application) : base(application) { } - [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs index 8098c26470..5791cb0d08 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadContent.cs @@ -56,7 +56,6 @@ namespace umbraco } } - [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get diff --git a/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs b/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs index c05f9849d9..664282ec89 100644 --- a/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs +++ b/src/umbraco.editorControls/MultiNodeTreePicker/FilteredContentTree.cs @@ -36,7 +36,6 @@ namespace umbraco.editorControls.MultiNodeTreePicker /// private int? m_DeterminedStartNodeId = null; - [Obsolete("This is no longer used and has no effect")] protected override bool LoadMinimalDocument { get From 830fde372e06a4547626b24fe7848f479eb9d93d Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 14:15:39 +1000 Subject: [PATCH 10/15] Fixes EditUser.aspx --- .../umbraco/users/EditUser.aspx.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs index 1569a2d110..1d6b362259 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/EditUser.aspx.cs @@ -10,6 +10,7 @@ using System.Xml; using Umbraco.Core.Logging; using umbraco.BasePages; using umbraco.BusinessLogic; +using umbraco.businesslogic.Exceptions; using umbraco.cms.businesslogic.media; using umbraco.cms.businesslogic.propertytype; using umbraco.cms.businesslogic.web; @@ -64,20 +65,27 @@ namespace umbraco.cms.presentation.user protected void Page_Load(object sender, EventArgs e) { + //if the current user is not an admin they cannot edit a user at all + if (CurrentUser.IsAdmin() == false) + { + throw new UserAuthorizationException("Access denied"); + } int UID = int.Parse(Request.QueryString["id"]); u = BusinessLogic.User.GetUser(UID); - // do initial check for edit rights + //the true admin can only edit the true admin if (u.Id == 0 && CurrentUser.Id != 0) { throw new Exception("Only the root user can edit the 'root' user (id:0)"); } - else if (u.IsAdmin() && !CurrentUser.IsAdmin()) + + //only another admin can edit another admin (who is not the true admin) + if (u.IsAdmin() && CurrentUser.IsAdmin() == false) { throw new Exception("Admin users can only be edited by admins"); } - + // check if canvas editing is enabled DefaultToLiveEditing.Visible = UmbracoSettings.EnableCanvasEditing; @@ -351,6 +359,8 @@ namespace umbraco.cms.presentation.user protected override void OnInit(EventArgs e) { + base.OnInit(e); + //lapps.SelectionMode = ListSelectionMode.Multiple; lapps.RepeatLayout = RepeatLayout.Flow; lapps.RepeatDirection = RepeatDirection.Vertical; From 0cff484113bd2df6c7e0b15297d76f7d34446bf3 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 14:48:05 +1000 Subject: [PATCH 11/15] fixes unit test --- src/Umbraco.Tests/PluginManagerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/PluginManagerTests.cs b/src/Umbraco.Tests/PluginManagerTests.cs index 4610839fcf..eb78b43918 100644 --- a/src/Umbraco.Tests/PluginManagerTests.cs +++ b/src/Umbraco.Tests/PluginManagerTests.cs @@ -296,7 +296,7 @@ namespace Umbraco.Tests public void Resolves_Trees() { var trees = PluginManager.Current.ResolveTrees(); - Assert.AreEqual(36, trees.Count()); + Assert.AreEqual(40, trees.Count()); } [Test] From a21bee6683e1a9078d570ac9de49c858567ceda6 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Mon, 30 Sep 2013 12:12:58 +0200 Subject: [PATCH 12/15] Fixing MemberType- and MemberRepository so properties, property types and property groups are properly initialized. --- src/Umbraco.Core/Models/MemberType.cs | 21 +++++ .../Models/Rdbms/PropertyTypeReadOnlyDto.cs | 2 +- .../Factories/MemberReadOnlyFactory.cs | 2 +- .../Factories/MemberTypeReadOnlyFactory.cs | 89 ++++++++++++------- .../Relators/PropertyDataRelator.cs | 2 + .../PropertyTypePropertyGroupRelator.cs | 3 +- .../Repositories/MemberRepository.cs | 10 +-- .../Repositories/MemberTypeRepository.cs | 2 +- .../Repositories/MemberRepositoryTest.cs | 26 ++++++ .../Entities/MockedContentTypes.cs | 27 ++++++ .../TestHelpers/Entities/MockedMember.cs | 26 ++++++ src/Umbraco.Tests/Umbraco.Tests.csproj | 1 + 12 files changed, 167 insertions(+), 44 deletions(-) create mode 100644 src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs diff --git a/src/Umbraco.Core/Models/MemberType.cs b/src/Umbraco.Core/Models/MemberType.cs index ed7d5cd3ab..2b32681392 100644 --- a/src/Umbraco.Core/Models/MemberType.cs +++ b/src/Umbraco.Core/Models/MemberType.cs @@ -114,5 +114,26 @@ namespace Umbraco.Core.Models MemberTypePropertyTypes.Add(propertyTypeAlias, tuple); } } + + /// + /// Method to call when Entity is being saved + /// + /// Created date is set and a Unique key is assigned + internal override void AddingEntity() + { + base.AddingEntity(); + + if (Key == Guid.Empty) + 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(); + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs index 78e250a8b5..2f48035ba5 100644 --- a/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/PropertyTypeReadOnlyDto.cs @@ -17,7 +17,7 @@ namespace Umbraco.Core.Models.Rdbms [Column("contentTypeId")] public int ContentTypeId { get; set; } - [Column("propertyTypeGroupId")] + [Column("PropertyTypesGroupId")] public int? PropertyTypeGroupId { get; set; } [Column("Alias")] diff --git a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs index eb6e2c787d..09d4765eb3 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs @@ -61,7 +61,7 @@ namespace Umbraco.Core.Persistence.Factories ? propertyType.CreatePropertyFromValue(null) : propertyType.CreatePropertyFromRawValue(propertyDataDto.GetValue, propertyDataDto.VersionId, - propertyDataDto.Id); + propertyDataDto.PropertyDataId.Value); //on initial construction we don't want to have dirty properties tracked property.CreateDate = createDate; property.UpdateDate = createDate; diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs index e9e7fe19c4..925e0edccd 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs @@ -55,51 +55,72 @@ namespace Umbraco.Core.Persistence.Factories private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType) { - var propertyTypeGroupCollection = new PropertyGroupCollection(); - foreach (var propertyTypeGroup in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) + var propertyGroups = new PropertyGroupCollection(); + foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) { - //Find PropertyTypes that belong to the current PropertyTypeGroup - var groupId = propertyTypeGroup.Id.Value; - var propertyTypesByGroup = - dto.PropertyTypes.Where( - x => x.Id.HasValue && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value.Equals(groupId)); - //Create PropertyTypeCollection for passing into the PropertyTypeGroup, and loop through the above result to create PropertyTypes - var propertyTypeCollection = new PropertyTypeCollection(); - foreach (var propTypeDto in propertyTypesByGroup) + var group = new PropertyGroup(); + //Only assign an Id if the PropertyGroup belongs to this ContentType + if (groupDto.Id.HasValue && groupDto.Id == memberType.Id) { - //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType - memberType.MemberTypePropertyTypes.Add(propTypeDto.Alias, - new Tuple(propTypeDto.CanEdit, propTypeDto.ViewOnProfile, propTypeDto.Id.Value)); - //PropertyType Collection - propertyTypeCollection.Add(new PropertyType(propTypeDto.ControlId, - propTypeDto.DbType.EnumParse(true)) - { - Alias = propTypeDto.Alias, - DataTypeDefinitionId = propTypeDto.DataTypeId, - Description = propTypeDto.Description, - HelpText = propTypeDto.HelpText, - Id = propTypeDto.Id.Value, - Mandatory = propTypeDto.Mandatory, - Name = propTypeDto.Name, - SortOrder = propTypeDto.SortOrder, - ValidationRegExp = propTypeDto.ValidationRegExp, - PropertyGroupId = new Lazy(() => propTypeDto.PropertyTypeGroupId.Value), - CreateDate = dto.CreateDate, - UpdateDate = dto.CreateDate - }); + group.Id = groupDto.Id.Value; + + if (groupDto.ParentGroupId.HasValue) + group.ParentId = groupDto.ParentGroupId.Value; + } + else + { + //If the PropertyGroup is inherited, we add a reference to the group as a Parent. + group.ParentId = groupDto.Id; } - var group = new PropertyGroup(propertyTypeCollection) {Id = groupId}; - propertyTypeGroupCollection.Add(@group); + group.Name = groupDto.Text; + group.SortOrder = groupDto.SortOrder; + group.PropertyTypes = new PropertyTypeCollection(); + + //Because we are likely to have a group with no PropertyTypes we need to ensure that these are excluded + var typeDtos = dto.PropertyTypes.Where(x => x.Id.HasValue && x.Id > 0 && x.PropertyTypeGroupId.HasValue && x.PropertyTypeGroupId.Value == groupDto.Id.Value); + foreach (var typeDto in typeDtos) + { + //Internal dictionary for adding "MemberCanEdit" and "VisibleOnProfile" properties to each PropertyType + memberType.MemberTypePropertyTypes.Add(typeDto.Alias, + new Tuple(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value)); + + var tempGroupDto = groupDto; + var propertyType = new PropertyType(typeDto.ControlId, + typeDto.DbType.EnumParse(true)) + { + Alias = typeDto.Alias, + DataTypeDefinitionId = typeDto.DataTypeId, + Description = typeDto.Description, + Id = typeDto.Id.Value, + Name = typeDto.Name, + HelpText = typeDto.HelpText, + Mandatory = typeDto.Mandatory, + SortOrder = typeDto.SortOrder, + ValidationRegExp = typeDto.ValidationRegExp, + PropertyGroupId = new Lazy(() => tempGroupDto.Id.Value), + CreateDate = memberType.CreateDate, + UpdateDate = memberType.UpdateDate + }; + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + propertyType.ResetDirtyProperties(false); + group.PropertyTypes.Add(propertyType); + } + //on initial construction we don't want to have dirty properties tracked + // http://issues.umbraco.org/issue/U4-1946 + group.ResetDirtyProperties(false); + propertyGroups.Add(group); } - return propertyTypeGroupCollection; + + return propertyGroups; } private List GetPropertyTypes(MemberTypeReadOnlyDto dto, MemberType memberType) { //Find PropertyTypes that does not belong to a PropertyTypeGroup var propertyTypes = new List(); - foreach (var propertyType in dto.PropertyTypes.Where(x => x.PropertyTypeGroupId.HasValue == false && x.Id.HasValue)) + foreach (var propertyType 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, diff --git a/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs b/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs index 49c5e671e6..4eabe8c669 100644 --- a/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs +++ b/src/Umbraco.Core/Persistence/Relators/PropertyDataRelator.cs @@ -15,6 +15,8 @@ namespace Umbraco.Core.Persistence.Relators if (a == null) return Current; + p.VersionId = a.VersionId; + // Is this the same MemberReadOnlyDto as the current one we're processing if (Current != null && Current.UniqueId == a.UniqueId) { diff --git a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs b/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs index e16a61db6f..a9129498c5 100644 --- a/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs +++ b/src/Umbraco.Core/Persistence/Relators/PropertyTypePropertyGroupRelator.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Linq; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Relators @@ -21,7 +22,7 @@ namespace Umbraco.Core.Persistence.Relators // Yes, just add this PropertyTypeReadOnlyDto to the current MemberTypeReadOnlyDto's collection Current.PropertyTypes.Add(p); - if(g.Id.HasValue) + if (g.Id.HasValue && Current.PropertyTypeGroups != null && Current.PropertyTypeGroups.Any(x => x.Id == g.Id.Value) == false) Current.PropertyTypeGroups.Add(g); // Return null to indicate we're not done with this MemberTypeReadOnlyDto yet diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index 856ede87d1..caa92f94ef 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -229,10 +229,8 @@ namespace Umbraco.Core.Persistence.Repositories dto.NodeId = nodeDto.NodeId; Database.Insert(dto); - //TODO ContentType for the Member entity - //Create the PropertyData for this version - cmsPropertyData - /*var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties); var keyDictionary = new Dictionary(); @@ -247,7 +245,7 @@ namespace Umbraco.Core.Persistence.Repositories foreach (var property in ((Member)entity).Properties) { property.Id = keyDictionary[property.PropertyTypeId]; - }*/ + } ((Member)entity).ResetDirtyProperties(); } @@ -300,7 +298,7 @@ namespace Umbraco.Core.Persistence.Repositories //TODO ContentType for the Member entity //Create the PropertyData for this version - cmsPropertyData - /*var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); + var propertyFactory = new PropertyFactory(entity.ContentType, entity.Version, entity.Id); var propertyDataDtos = propertyFactory.BuildDto(((Member)entity).Properties); var keyDictionary = new Dictionary(); @@ -325,7 +323,7 @@ namespace Umbraco.Core.Persistence.Repositories { property.Id = keyDictionary[property.PropertyTypeId]; } - }*/ + } ((ICanBeDirty)entity).ResetDirtyProperties(); } diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs index 305f828c2d..be3a9eb752 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs @@ -101,7 +101,7 @@ namespace Umbraco.Core.Persistence.Repositories 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", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", + "cmsPropertyType.propertyTypeGroupId AS PropertyTypesGroupId", "cmsMemberType.memberCanEdit", "cmsMemberType.viewOnProfile", "cmsDataType.controlId", "cmsDataType.dbType", "cmsPropertyTypeGroup.id AS PropertyTypeGroupId", "cmsPropertyTypeGroup.text AS PropertyGroupName", "cmsPropertyTypeGroup.parentGroupId", "cmsPropertyTypeGroup.sortorder AS PropertyGroupSortOrder") diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs index 6aa9609807..6795f2c608 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberRepositoryTest.cs @@ -15,6 +15,7 @@ using Umbraco.Core.Persistence.UnitOfWork; using Umbraco.Core.Publishing; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers; +using Umbraco.Tests.TestHelpers.Entities; namespace Umbraco.Tests.Persistence.Repositories { @@ -174,6 +175,31 @@ namespace Umbraco.Tests.Persistence.Repositories } } + [Test] + public void MemberRepository_Can_Persist_Member() + { + IMember sut; + var unitOfWork = UnitOfWorkProvider.GetUnitOfWork(); + MemberTypeRepository memberTypeRepository; + using (var repository = CreateRepository(unitOfWork, out memberTypeRepository)) + { + var memberType = MockedContentTypes.CreateSimpleMemberType(); + memberTypeRepository.AddOrUpdate(memberType); + unitOfWork.Commit(); + + var member = MockedMember.CreateSimpleContent(memberType, "Johnny Hefty", "johnny@example.com", "123", "hefty", -1); + repository.AddOrUpdate(member); + unitOfWork.Commit(); + + sut = repository.Get(member.Id); + + Assert.That(sut, Is.Not.Null); + Assert.That(sut.ContentType.PropertyGroups.Count(), Is.EqualTo(1)); + Assert.That(sut.ContentType.PropertyTypes.Count(), Is.EqualTo(12)); + Assert.That(sut.Properties.Count(), Is.EqualTo(12)); + } + } + [Test] public void Can_Create_Correct_Subquery() { diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index f3f09e5fae..cc22ce913b 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -265,5 +265,32 @@ namespace Umbraco.Tests.TestHelpers.Entities return mediaType; } + + public static MemberType CreateSimpleMemberType() + { + var contentType = new MemberType(-1) + { + Alias = "simple", + Name = "Simple Page", + Description = "ContentType used for simple text pages", + Icon = ".sprTreeDoc3", + Thumbnail = "doc.png", + SortOrder = 1, + CreatorId = 0, + Trashed = false + }; + + var contentCollection = new PropertyTypeCollection(); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "title", Name = "Title", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 }); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Description = "", HelpText = "", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -87 }); + contentCollection.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "author", Name = "Author", Description = "Name of the author", HelpText = "", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88 }); + + contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); + + //ensure that nothing is marked as dirty + contentType.ResetDirtyProperties(false); + + return contentType; + } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs new file mode 100644 index 0000000000..4aeb406811 --- /dev/null +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedMember.cs @@ -0,0 +1,26 @@ +using Umbraco.Core.Models; + +namespace Umbraco.Tests.TestHelpers.Entities +{ + public class MockedMember + { + public static Member CreateSimpleContent(IMemberType contentType, string name, string email, string password, string username, int parentId) + { + var member = new Member(name, parentId, contentType, new PropertyCollection()) + { + CreatorId = 0, + Email = email, + Password = password, + Username = username + }; + + member.SetValue("title", name + " member"); + member.SetValue("bodyText", "This is a subpage"); + member.SetValue("author", "John Doe"); + + member.ResetDirtyProperties(false); + + return member; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index a37a253e9b..469caa926c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -301,6 +301,7 @@ + From 5aa01e78ab283f06a961d074ac9faa1dde1705c8 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Mon, 30 Sep 2013 12:13:49 +0200 Subject: [PATCH 13/15] Updating conn.string in test --- .../Persistence/Repositories/MemberTypeRepositoryTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs index cc4553cce5..c9a88878d4 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/MemberTypeRepositoryTest.cs @@ -29,7 +29,7 @@ namespace Umbraco.Tests.Persistence.Repositories public override string ConnectionString { - get { return @"server=.\SQLEXPRESS;database=Kloud-Website-Production;user id=umbraco;password=umbraco"; } + get { return @"server=.\SQLEXPRESS;database=EmptyForTest;user id=umbraco;password=umbraco"; } } public override string ProviderName From cdda69c4cd62a33ebc885504d38e69db12ea1aa7 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 12:39:28 +0200 Subject: [PATCH 14/15] U4-2788 Error installing Umbraco 6.1.5 with SQL CE 4 option --- src/Umbraco.Core/DatabaseContext.cs | 2 +- src/Umbraco.Tests/App.config | 2 +- src/Umbraco.Tests/BusinessLogic/BaseTest.cs | 2 +- src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs | 2 +- src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs | 2 +- .../Migrations/Upgrades/ValidateOlderSchemaTest.cs | 2 +- src/Umbraco.Tests/Persistence/DatabaseContextTests.cs | 2 +- src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs | 4 ++-- src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs | 2 +- src/Umbraco.Tests/TestHelpers/TestHelper.cs | 2 +- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 1 + 11 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Core/DatabaseContext.cs b/src/Umbraco.Core/DatabaseContext.cs index 2f0efcbfc0..dbbc476ae9 100644 --- a/src/Umbraco.Core/DatabaseContext.cs +++ b/src/Umbraco.Core/DatabaseContext.cs @@ -112,7 +112,7 @@ namespace Umbraco.Core public void ConfigureEmbeddedDatabaseConnection() { const string providerName = "System.Data.SqlServerCe.4.0"; - const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;File Access Retry Timeout=10"; + const string connectionString = @"Data Source=|DataDirectory|\Umbraco.sdf;Flush Interval=1;"; SaveConnectionString(connectionString, providerName); diff --git a/src/Umbraco.Tests/App.config b/src/Umbraco.Tests/App.config index 78ddfe8dcb..d86051cdee 100644 --- a/src/Umbraco.Tests/App.config +++ b/src/Umbraco.Tests/App.config @@ -26,7 +26,7 @@ - + diff --git a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs index 73d51e7816..692e0d6586 100644 --- a/src/Umbraco.Tests/BusinessLogic/BaseTest.cs +++ b/src/Umbraco.Tests/BusinessLogic/BaseTest.cs @@ -53,7 +53,7 @@ namespace Umbraco.Tests.BusinessLogic private void InitializeDatabase() { - ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"); + ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;"); ClearDatabase(); diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs index 9f8a3be793..f75a215763 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeDataUpgradeTest.cs @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs index 3dfc059358..238256499c 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/SqlCeUpgradeTest.cs @@ -63,7 +63,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public override UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public override DatabaseProviders GetDatabaseProvider() diff --git a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs index 1abb496fe9..3824cf1837 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/ValidateOlderSchemaTest.cs @@ -100,7 +100,7 @@ namespace Umbraco.Tests.Migrations.Upgrades public UmbracoDatabase GetConfiguredDatabase() { - return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10", "System.Data.SqlServerCe.4.0"); + return new UmbracoDatabase("Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } public string GetDatabaseSpecificSqlScript() diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 9132db95c2..25fe36cbf7 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence //Get the connectionstring settings from config var settings = ConfigurationManager.ConnectionStrings[Core.Configuration.GlobalSettings.UmbracoConnectionName]; - //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10 + //by default the conn string is: Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1; //we'll just replace the sdf file with our custom one: //Create the Sql CE database var engine = new SqlCeEngine(settings.ConnectionString.Replace("UmbracoPetaPocoTests", "DatabaseContextTests")); diff --git a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs index 7147dea975..54b427e2eb 100644 --- a/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs +++ b/src/Umbraco.Tests/Persistence/SqlCeTableByTableTest.cs @@ -35,12 +35,12 @@ namespace Umbraco.Tests.Persistence } //Create the Sql CE database - var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10"); + var engine = new SqlCeEngine("Datasource=|DataDirectory|test.sdf;Flush Interval=1;"); engine.CreateDatabase(); SqlSyntaxContext.SqlSyntaxProvider = SqlCeSyntax.Provider; - _database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;File Access Retry Timeout=10", + _database = new Database("Datasource=|DataDirectory|test.sdf;Flush Interval=1;", "System.Data.SqlServerCe.4.0"); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index d85d9813f5..261d35057f 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -105,7 +105,7 @@ namespace Umbraco.Tests.TestHelpers /// protected virtual string GetDbConnectionString() { - return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"; + return @"Datasource=|DataDirectory|UmbracoPetaPocoTests.sdf;Flush Interval=1;"; } /// diff --git a/src/Umbraco.Tests/TestHelpers/TestHelper.cs b/src/Umbraco.Tests/TestHelpers/TestHelper.cs index 5c4eaad051..d7b72958fc 100644 --- a/src/Umbraco.Tests/TestHelpers/TestHelper.cs +++ b/src/Umbraco.Tests/TestHelpers/TestHelper.cs @@ -47,7 +47,7 @@ namespace Umbraco.Tests.TestHelpers /// public static void InitializeDatabase() { - ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;File Access Retry Timeout=10"); + ConfigurationManager.AppSettings.Set(Core.Configuration.GlobalSettings.UmbracoConnectionName, @"datalayer=SQLCE4Umbraco.SqlCEHelper,SQLCE4Umbraco;data source=|DataDirectory|\UmbracoPetaPocoTests.sdf;Flush Interval=1;"); ClearDatabase(); diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index dc143c0c1d..c7a6b7d3e7 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -46,6 +46,7 @@ ..\ true + true bin\ From 226e35d65a6e0cf93fba71006781a209370664b3 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Mon, 30 Sep 2013 14:32:06 +0200 Subject: [PATCH 15/15] NuSpec update: we can only accept a specific version of MySQL --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 28d8be35c8..a747183c1c 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -22,7 +22,7 @@ - +