From e0878fdd9fde7282257be6a1c898b07f9cc645f8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Sep 2013 14:48:05 +1000 Subject: [PATCH 01/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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/31] 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 @@ - + From 59196020bb03b2d1d728cd9d0138fcb2d7e74bcb Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 10:04:07 +1000 Subject: [PATCH 16/31] Fixes up content controller move/copy actions --- src/Umbraco.Web/Editors/ContentController.cs | 87 +++++++++++++------ .../{ContentMove.cs => MoveOrCopy.cs} | 13 ++- src/Umbraco.Web/Umbraco.Web.csproj | 2 +- 3 files changed, 70 insertions(+), 32 deletions(-) rename src/Umbraco.Web/Models/ContentEditing/{ContentMove.cs => MoveOrCopy.cs} (62%) diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index a1e4754bf2..bc19ee4ad2 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -366,55 +366,86 @@ namespace Umbraco.Web.Editors /// /// Change the sort order for media /// - /// + /// /// [EnsureUserPermissionForContent("move.ParentId", 'M')] - public HttpResponseMessage PostMove(ContentMove move) + public HttpResponseMessage PostMove(MoveOrCopy move) { - if (move == null) - { - return Request.CreateResponse(HttpStatusCode.NotFound); - } + var toMove = ValidateMoveOrCopy(move); - var contentService = Services.ContentService; - try - { - contentService.Move(contentService.GetById(move.Id), move.ParentId); - return Request.CreateResponse(HttpStatusCode.OK); - } - catch (Exception ex) - { - LogHelper.Error("Could not move content", ex); - throw; - } + Services.ContentService.Move(toMove, move.ParentId); + + return Request.CreateResponse(HttpStatusCode.OK); } /// /// Copies a /// - /// + /// /// [EnsureUserPermissionForContent("copy.ParentId", 'C')] - public HttpResponseMessage PostCopy(ContentMove copy) + public HttpResponseMessage PostCopy(MoveOrCopy copy) { - if (copy == null) + var toCopy = ValidateMoveOrCopy(copy); + + Services.ContentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal); + + return Request.CreateResponse(HttpStatusCode.OK); + } + + /// + /// Ensures the item can be moved/copied to the new location + /// + /// + /// + private IContent ValidateMoveOrCopy(MoveOrCopy model) + { + if (model == null) { - return Request.CreateResponse(HttpStatusCode.NotFound); + throw new HttpResponseException(HttpStatusCode.NotFound); } var contentService = Services.ContentService; - try + var toMove = contentService.GetById(model.Id); + if (toMove == null) { - contentService.Copy(contentService.GetById(copy.Id), copy.ParentId, true); - return Request.CreateResponse(HttpStatusCode.OK); + throw new HttpResponseException(HttpStatusCode.NotFound); } - catch (Exception ex) + if (model.ParentId < 0) { - LogHelper.Error("Could not copy content", ex); - throw; + //cannot move if the content item is not allowed at the root + if (toMove.ContentType.AllowedAsRoot == false) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedAtRoot", Security.CurrentUser))); + } } - } + else + { + var parent = contentService.GetById(model.ParentId); + if (parent == null) + { + throw new HttpResponseException(HttpStatusCode.NotFound); + } + //check if the item is allowed under this one + if (parent.ContentType.AllowedContentTypes.Select(x => x.Id).ToArray() + .Any(x => x.Value == toMove.ContentType.Id) == false) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedByContentType", Security.CurrentUser))); + } + + // Check on paths + if ((string.Format(",{0},", parent.Path)).IndexOf(string.Format(",{0},", toMove.Id), StringComparison.Ordinal) > -1) + { + throw new HttpResponseException( + Request.CreateValidationErrorResponse(ui.Text("moveOrCopy", "notAllowedByPath", Security.CurrentUser))); + } + } + + return toMove; + } private void ShowMessageForStatus(PublishStatus status, ContentItemDisplay display) { diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentMove.cs b/src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs similarity index 62% rename from src/Umbraco.Web/Models/ContentEditing/ContentMove.cs rename to src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs index 7b1e209504..6aa87f9e74 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentMove.cs +++ b/src/Umbraco.Web/Models/ContentEditing/MoveOrCopy.cs @@ -8,10 +8,10 @@ using System.Text; namespace Umbraco.Web.Models.ContentEditing { /// - /// A model representing a new sort order for a content/media item + /// A model representing a model for moving or copying /// [DataContract(Name = "content", Namespace = "")] - public class ContentMove + public class MoveOrCopy { /// /// The Id of the node to move or copy to @@ -21,11 +21,18 @@ namespace Umbraco.Web.Models.ContentEditing public int ParentId { get; set; } /// - /// ´The id of the node to move or copy + /// The id of the node to move or copy /// [DataMember(Name = "id", IsRequired = true)] [Required] public int Id { get; set; } + + /// + /// Boolean indicating whether copying the object should create a relation to it's original + /// + [DataMember(Name = "relateToOriginal", IsRequired = true)] + [Required] + public bool RelateToOriginal { get; set; } } } diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 729585950c..0c085bfcab 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -313,7 +313,7 @@ - + From 79e35d5c06e166438b71e863eb005294d08c51db Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 10:08:55 +1000 Subject: [PATCH 17/31] Ensures that if a user session times out and another user logs in that we redirect to root --- .../src/views/common/main.controller.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js index 502a379aa9..66ef09e5ab 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js @@ -8,7 +8,7 @@ * The main application controller * */ -function MainController($scope, $routeParams, $rootScope, $timeout, $http, $log, notificationsService, userService, navigationService, legacyJsLoader) { +function MainController($scope, $location, $routeParams, $rootScope, $timeout, $http, $log, notificationsService, userService, navigationService, legacyJsLoader) { var legacyTreeJsLoaded = false; @@ -78,6 +78,12 @@ function MainController($scope, $routeParams, $rootScope, $timeout, $http, $log, $scope.authenticated = data.authenticated; $scope.user = data.user; + //if the user has changed we need to redirect to the root so they don't try to continue editing the + //last item in the URL + if (data.lastUserId !== data.user.id) { + $location.path("/").search(""); + } + //var url = "http://www.gravatar.com/avatar/" + $scope.user.emailHash + ".json?404=404"; //$http.jsonp(url).then(function(response){ // $log.log("found: " + response); From 7451e83c73b9f15ab31dec28b99450de3045b447 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 13:23:13 +1000 Subject: [PATCH 18/31] Integrates authentication within the routes and prevents controllers from being loaded when the user isn't authorized. Ensures we also have a /login route and allows routes to redirect when auth fails. --- .../src/common/resources/auth.resource.js | 20 ++++- .../src/common/services/user.service.js | 69 +++++++++------ src/Umbraco.Web.UI.Client/src/routes.js | 88 ++++++++++++++++--- .../views/common/dialogs/user.controller.js | 6 +- .../src/views/common/login.controller.js | 11 +++ .../src/views/common/login.html | 3 + .../src/views/common/main.controller.js | 2 +- .../Editors/AuthenticationController.cs | 21 ++++- 8 files changed, 174 insertions(+), 46 deletions(-) create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/login.controller.js create mode 100644 src/Umbraco.Web.UI.Client/src/views/common/login.html diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js index 710ee58e52..604ba4b582 100644 --- a/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js +++ b/src/Umbraco.Web.UI.Client/src/common/resources/auth.resource.js @@ -34,16 +34,28 @@ function authResource($q, $http, umbRequestHelper, angularHelper) { "PostLogout"))); }, - /** Sends a request to the server to check if the current cookie value is valid for the user */ - isAuthenticated: function () { + /** Sends a request to the server to get the current user details, will return a 401 if the user is not logged in */ + getCurrentUser: function () { return umbRequestHelper.resourcePromise( $http.get( umbRequestHelper.getApiUrl( "authenticationApiBaseUrl", "GetCurrentUser")), - 'Server call failed for checking authorization'); - } + 'Server call failed for getting current user'); + }, + + /** Checks if the user is logged in or not - does not return 401 or 403 */ + isAuthenticated: function () { + + return umbRequestHelper.resourcePromise( + $http.get( + umbRequestHelper.getApiUrl( + "authenticationApiBaseUrl", + "IsAuthenticated")), + 'Server call failed for checking authentication'); + }, + }; } diff --git a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js index 626b11b98f..811ed55c18 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/user.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/user.service.js @@ -53,30 +53,20 @@ angular.module('umbraco.services') return { + /** Internal method to display the login dialog */ + _showLoginDialog: function () { + openLoginDialog(); + }, + /** Returns a promise, sends a request to the server to check if the current cookie is authorized */ - isAuthenticated: function (args) { - - return authResource.isAuthenticated() - .then(function(data) { - - //note, this can return null if they are not authenticated - if (!data) { - throw "Not authenticated"; - } - else { - - var result = { user: data, authenticated: true, lastUserId: lastUserId }; - - if (args.broadcastEvent) { - //broadcast a global event, will inform listening controllers to load in the user specific data - $rootScope.$broadcast("authenticated", result); - } - - currentUser = data; - currentUser.avatar = 'http://www.gravatar.com/avatar/' + data.emailHash + '?s=40&d=404'; - return result; - } - }); + isAuthenticated: function () { + //if we've got a current user then just return true + if (currentUser) { + var deferred = $q.defer(); + deferred.resolve(true); + return deferred.promise; + } + return authResource.isAuthenticated(); }, /** Returns a promise, sends a request to the server to validate the credentials */ @@ -97,6 +87,7 @@ angular.module('umbraco.services') }); }, + /** Logs the user out and redirects to the login page */ logout: function () { return authResource.performLogout() .then(function (data) { @@ -107,14 +98,38 @@ angular.module('umbraco.services') //broadcast a global event $rootScope.$broadcast("notAuthenticated"); - openLoginDialog(); + $location.path("/login").search({check: false}); + return null; }); }, - /** Returns the current user object, if null then calls to authenticated or authenticate must be called */ - getCurrentUser: function () { - return currentUser; + /** Returns the current user object in a promise */ + getCurrentUser: function (args) { + var deferred = $q.defer(); + + if (!currentUser) { + authResource.getCurrentUser() + .then(function(data) { + + var result = { user: data, authenticated: true, lastUserId: lastUserId }; + + if (args.broadcastEvent) { + //broadcast a global event, will inform listening controllers to load in the user specific data + $rootScope.$broadcast("authenticated", result); + } + + currentUser = data; + currentUser.avatar = 'http://www.gravatar.com/avatar/' + data.emailHash + '?s=40&d=404'; + deferred.resolve(currentUser); + }); + + } + else { + deferred.resolve(currentUser); + } + + return deferred.promise; } }; diff --git a/src/Umbraco.Web.UI.Client/src/routes.js b/src/Umbraco.Web.UI.Client/src/routes.js index b3bd6791cd..bbda26b835 100644 --- a/src/Umbraco.Web.UI.Client/src/routes.js +++ b/src/Umbraco.Web.UI.Client/src/routes.js @@ -1,15 +1,62 @@ app.config(function ($routeProvider) { + + /** This checks if the user is authenticated for a route and what the isRequired is set to. + Depending on whether isRequired = true, it first check if the user is authenticated and will resolve successfully + otherwise the route will fail and the $routeChangeError event will execute, in that handler we will redirect to the rejected + path that is resolved from this method and prevent default (prevent the route from executing) */ + var checkAuth = function(isRequired) { + return { + isAuthenticated: function ($q, userService, $route) { + var deferred = $q.defer(); + + //don't need to check if we've redirected to login and we've already checked auth + if (!$route.current.params.section && $route.current.params.check === false) { + deferred.resolve(true); + return deferred.promise; + } + + userService.isAuthenticated() + .then(function () { + if (isRequired) { + //this will resolve successfully so the route will continue + deferred.resolve(true); + } + else { + deferred.reject({ path: "/" }); + } + }, function () { + if (isRequired) { + //the check=false is checked above so that we don't have to make another http call to check + //if they are logged in since we already know they are not. + deferred.reject({ path: "/login", search: { check: false } }); + } + else { + //this will resolve successfully so the route will continue + deferred.resolve(true); + } + }); + return deferred.promise; + } + }; + }; + $routeProvider + .when('/login', { + templateUrl: 'views/common/login.html', + //ensure auth is *not* required so it will redirect to /content otherwise + resolve: checkAuth(false) + }) .when('/:section', { templateUrl: function (rp) { - if (rp.section === "default" || rp.section === "") + if (rp.section.toLowerCase() === "default" || rp.section.toLowerCase() === "umbraco" || rp.section === "") { rp.section = "content"; } rp.url = "dashboard.aspx?app=" + rp.section; return 'views/common/dashboard.html'; - } + }, + resolve: checkAuth(true) }) .when('/framed/:url', { //This occurs when we need to launch some content in an iframe @@ -18,7 +65,8 @@ app.config(function ($routeProvider) { throw "A framed resource must have a url route parameter"; return 'views/common/legacy.html'; - } + }, + resolve: checkAuth(true) }) .when('/:section/:method', { templateUrl: function(rp) { @@ -32,7 +80,8 @@ app.config(function ($routeProvider) { // dashboards (as tabs if we wanted) and each tab could actually be a route link to one of these views? return 'views/' + rp.section + '/' + rp.method + '.html'; - } + }, + resolve: checkAuth(true) }) .when('/:section/:tree/:method/:id', { templateUrl: function (rp) { @@ -43,9 +92,10 @@ app.config(function ($routeProvider) { //we don't need to put views into section folders since theoretically trees // could be moved among sections, we only need folders for specific trees. return 'views/' + rp.tree + '/' + rp.method + '.html'; - } + }, + resolve: checkAuth(true) }) - .otherwise({ redirectTo: '/content' }); + .otherwise({ redirectTo: '/login' }); }).config(function ($locationProvider) { //$locationProvider.html5Mode(false).hashPrefix('!'); //turn html5 mode off @@ -53,10 +103,28 @@ app.config(function ($routeProvider) { }); -app.run(['userService', '$log', '$rootScope', function (userService, $log, $rootScope) { +app.run(['userService', '$log', '$rootScope', '$location', function (userService, $log, $rootScope, $location) { - // Get the current user when the application starts - // (in case they are still logged in from a previous session) + var firstRun = true; + + /** when we have a successful first route that is not the login page - meaning the user is authenticated + we'll get the current user from the user service and ensure it broadcasts it's events. If the route + is successful from after a login then this will not actually do anything since the authenticated event would + have alraedy fired, but if the user is loading the angularjs app for the first time and they are already authenticated + then this is when the authenticated event will be fired. + */ + $rootScope.$on('$routeChangeSuccess', function (event, current, previous) { + if (firstRun && !$location.url().toLowerCase().startsWith("/login")) { + firstRun = false; + userService.getCurrentUser({ broadcastEvent: true }); + } + }); + + /** When the route change is rejected - based on checkAuth - we'll prevent the rejected route from executing including + wiring up it's controller, etc... and then redirect to the rejected URL. */ + $rootScope.$on('$routeChangeError', function (event, current, previous, rejection) { + event.preventDefault(); + $location.path(rejection.path).search(rejection.search); + }); - userService.isAuthenticated({broadcastEvent: true}); }]); diff --git a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js index e683c831d1..a7ecbada40 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/dialogs/user.controller.js @@ -5,9 +5,9 @@ angular.module("umbraco") $scope.history = historyService.current; $scope.logout = function () { - userService.logout(); - $scope.hide(); - $location.path("/"); + userService.logout().then(function() { + $scope.hide(); + }); }; $scope.gotoHistory = function (link) { diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js new file mode 100644 index 0000000000..8b94debf39 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/login.controller.js @@ -0,0 +1,11 @@ +/** This controller is simply here to launch the login dialog when the route is explicitly changed to /login */ +angular.module('umbraco').controller("Umbraco.LoginController", function ($scope, userService, $location) { + + userService._showLoginDialog(); + + //when a user is authorized redirect - this will only be handled here when we are actually on the /login route + $scope.$on("authenticated", function(evt, data) { + $location.path("/").search(""); + }); + +}); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/login.html b/src/Umbraco.Web.UI.Client/src/views/common/login.html new file mode 100644 index 0000000000..d490d395eb --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/views/common/login.html @@ -0,0 +1,3 @@ +
+ +
\ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js index 66ef09e5ab..5a0347254d 100644 --- a/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/common/main.controller.js @@ -80,7 +80,7 @@ function MainController($scope, $location, $routeParams, $rootScope, $timeout, $ //if the user has changed we need to redirect to the root so they don't try to continue editing the //last item in the URL - if (data.lastUserId !== data.user.id) { + if (data.lastUserId && data.lastUserId !== data.user.id) { $location.path("/").search(""); } diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index f2a8996203..793ca4be62 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -33,7 +33,26 @@ namespace Umbraco.Web.Editors } /// - /// Simply checks if the current user's cookie is valid and if so returns the user object associated + /// Checks if the current user's cookie is valid and if so returns OK or a 400 (BadRequest) + /// + /// + [HttpGet] + public HttpResponseMessage IsAuthenticated() + { + var attempt = UmbracoContext.Security.AuthorizeRequest(); + if (attempt == ValidateRequestAttempt.Success) + { + return Request.CreateResponse(HttpStatusCode.OK); + } + //return Forbidden (403), we don't want to return a 401 because that get's intercepted + // by our angular helper because it thinks that we need to re-perform the request once we are + // authorized. + return Request.CreateResponse(HttpStatusCode.Forbidden); + } + + + /// + /// Checks if the current user's cookie is valid and if so returns the user object associated /// /// public UserDetail GetCurrentUser() From bb350035ef7cb370c726fab6036cdd19e07e71a6 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 13:43:55 +1000 Subject: [PATCH 19/31] Fixed merge issues --- .../Persistence/Factories/MemberTypeReadOnlyFactory.cs | 2 +- .../TestHelpers/Entities/MockedContentTypes.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs index c903f087b4..f7b314cbff 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs @@ -86,7 +86,7 @@ namespace Umbraco.Core.Persistence.Factories new Tuple(typeDto.CanEdit, typeDto.ViewOnProfile, typeDto.Id.Value)); var tempGroupDto = groupDto; - var propertyType = new PropertyType(typeDto.ControlId, + var propertyType = new PropertyType(typeDto.PropertyEditorAlias, typeDto.DbType.EnumParse(true)) { Alias = typeDto.Alias, diff --git a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs index e18f0fecc3..430172916a 100644 --- a/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs +++ b/src/Umbraco.Tests/TestHelpers/Entities/MockedContentTypes.cs @@ -295,9 +295,9 @@ namespace Umbraco.Tests.TestHelpers.Entities }; 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 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "title", Name = "Title", Description = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "bodyText", Name = "Body Text", Description = "", Mandatory = false, SortOrder = 2, DataTypeDefinitionId = -87 }); + contentCollection.Add(new PropertyType(Constants.PropertyEditors.TextboxAlias, DataTypeDatabaseType.Ntext) { Alias = "author", Name = "Author", Description = "Name of the author", Mandatory = false, SortOrder = 3, DataTypeDefinitionId = -88 }); contentType.PropertyGroups.Add(new PropertyGroup(contentCollection) { Name = "Content", SortOrder = 1 }); From a8f87d6dc1ea97ecbe95a1e27c791da96090b3ca Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:07:56 +1000 Subject: [PATCH 20/31] Updates mediapicker to not use jquery each methods since they are not DOM items, use underscore instead. --- .../propertyeditors/mediapicker/mediapicker.controller.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index c028217f71..e41961fff9 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -12,7 +12,7 @@ angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", mediaResource.getByIds($scope.ids).then(function(medias){ //img.media = media; - $(medias).each(function(i, media){ + _.each(medias, function (media, i) { //shortcuts //TODO, do something better then this for searching var img = {}; @@ -31,7 +31,7 @@ angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", $scope.add = function(){ dialogService.mediaPicker({multipicker:true, callback: function(data){ - $(data.selection).each(function(i, media){ + _.each(data.selection, function (media, i) { //shortcuts //TODO, do something better then this for searching @@ -50,5 +50,7 @@ angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", $scope.sync = function(){ $scope.model.value = $scope.ids.join(); }; + + //TODO: Need to add the onValueChanged method to detect if the server has changed the model value and re-create the ids }); \ No newline at end of file From 2bb279d8f7c347d89207446528e0772fb307d1c4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:08:14 +1000 Subject: [PATCH 21/31] Ensures rte controller will re-load itself if server data has changed. --- .../propertyeditors/rte/rte.controller.js | 116 ++++++++++-------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js index 1cf64e286f..c87be39b71 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/rte/rte.controller.js @@ -32,65 +32,79 @@ angular.module("umbraco") var plugins = "code"; assetsService.loadJs("lib/tinymce/tinymce.min.js", $scope).then(function () { - //we need to add a timeout here, to force a redraw so TinyMCE can find - //the elements needed - $timeout(function () { - tinymce.DOM.events.domLoaded = true; - tinymce.init({ - mode: "exact", - elements: $scope.model.alias + "_rte", - skin: "umbraco", - plugins: plugins, - valid_elements: validElements, - menubar: false, - statusbar: false, - height: 340, - toolbar: toolbar, - setup: function (editor) { - - //We need to listen on multiple things here because of the nature of tinymce, it doesn't - //fire events when you think! - //The change event doesn't fire when content changes, only when cursor points are changed and undo points - //are created. the blur event doesn't fire if you insert content into the editor with a button and then - //press save. - //We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can - //listen to both change and blur and also on our own 'saving' event. I think this will be best because a - //timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked - //save before the timeout elapsed. - editor.on('change', function (e) { - angularHelper.safeApply($scope, function() { - $scope.model.value = editor.getContent(); - }); - }); - editor.on('blur', function (e) { - angularHelper.safeApply($scope, function () { + + /** Loads in the editor */ + function loadTinyMce() { + + //we need to add a timeout here, to force a redraw so TinyMCE can find + //the elements needed + $timeout(function () { + tinymce.DOM.events.domLoaded = true; + tinymce.init({ + mode: "exact", + elements: $scope.model.alias + "_rte", + skin: "umbraco", + plugins: plugins, + valid_elements: validElements, + menubar: false, + statusbar: false, + height: 340, + toolbar: toolbar, + setup: function (editor) { + + //We need to listen on multiple things here because of the nature of tinymce, it doesn't + //fire events when you think! + //The change event doesn't fire when content changes, only when cursor points are changed and undo points + //are created. the blur event doesn't fire if you insert content into the editor with a button and then + //press save. + //We have a couple of options, one is to do a set timeout and check for isDirty on the editor, or we can + //listen to both change and blur and also on our own 'saving' event. I think this will be best because a + //timer might end up using unwanted cpu and we'd still have to listen to our saving event in case they clicked + //save before the timeout elapsed. + editor.on('change', function (e) { + angularHelper.safeApply($scope, function () { + $scope.model.value = editor.getContent(); + }); + }); + editor.on('blur', function (e) { + angularHelper.safeApply($scope, function () { + $scope.model.value = editor.getContent(); + }); + }); + var unsubscribe = $scope.$on("saving", function () { $scope.model.value = editor.getContent(); }); - }); - var unsubscribe = $scope.$on("saving", function() { - $scope.model.value = editor.getContent(); - }); - //when the element is disposed we need to unsubscribe! - // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom - // element might still be there even after the modal has been hidden. - $element.bind('$destroy', function () { - unsubscribe(); - }); + //when the element is disposed we need to unsubscribe! + // NOTE: this is very important otherwise if this is part of a modal, the listener still exists because the dom + // element might still be there even after the modal has been hidden. + $element.bind('$destroy', function () { + unsubscribe(); + }); - //Create the insert media plugin - tinyMceService.createMediaPicker(editor, $scope); + //Create the insert media plugin + tinyMceService.createMediaPicker(editor, $scope); - //Create the insert icon plugin - tinyMceService.createInsertEmbeddedMedia(editor, $scope); + //Create the insert icon plugin + tinyMceService.createInsertEmbeddedMedia(editor, $scope); - //Create the insert macro plugin - tinyMceService.createInsertMacro(editor, $scope); + //Create the insert macro plugin + tinyMceService.createInsertMacro(editor, $scope); - } - }); - }, 1); + } + }); + }, 1); + } + + loadTinyMce(); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + loadTinyMce(); + }; }); }); \ No newline at end of file From 6277bc379ecca07d6e9713aa355c57db256efda4 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:10:11 +1000 Subject: [PATCH 22/31] updates mediapicker to use onValueChanged in case the server value changes. --- .../mediapicker/mediapicker.controller.js | 104 ++++++++++-------- 1 file changed, 58 insertions(+), 46 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index e41961fff9..59a8193866 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -1,56 +1,68 @@ //this controller simply tells the dialogs service to open a mediaPicker window //with a specified callback, this callback will receive an object with a selection on it -angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", - function($rootScope, $scope, dialogService, mediaResource, imageHelper, $log){ - - - $scope.images = []; - $scope.ids = []; +angular.module('umbraco').controller("Umbraco.Editors.MediaPickerController", + function($rootScope, $scope, dialogService, mediaResource, imageHelper, $log) { - if($scope.model.value){ - $scope.ids = $scope.model.value.split(','); - mediaResource.getByIds($scope.ids).then(function(medias){ - //img.media = media; - _.each(medias, function (media, i) { - //shortcuts - //TODO, do something better then this for searching - var img = {}; - img.src = imageHelper.getImagePropertyValue({imageModel: media}); - img.thumbnail = imageHelper.getThumbnailFromPath(img.src); - $scope.images.push(img); - }); - }); - } + function setupViewModel() { + $scope.images = []; + $scope.ids = []; - $scope.remove = function(index){ - $scope.images.splice(index, 1); - $scope.ids.splice(index, 1); - $scope.sync(); - }; + if ($scope.model.value) { + $scope.ids = $scope.model.value.split(','); - $scope.add = function(){ - dialogService.mediaPicker({multipicker:true, callback: function(data){ - _.each(data.selection, function (media, i) { - //shortcuts - //TODO, do something better then this for searching + mediaResource.getByIds($scope.ids).then(function (medias) { + //img.media = media; + _.each(medias, function (media, i) { + //shortcuts + //TODO, do something better then this for searching + var img = {}; + img.src = imageHelper.getImagePropertyValue({ imageModel: media }); + img.thumbnail = imageHelper.getThumbnailFromPath(img.src); + $scope.images.push(img); + }); + }); + } + } - var img = {}; - img.id = media.id; - img.src = imageHelper.getImagePropertyValue({imageModel: media}); - img.thumbnail = imageHelper.getThumbnailFromPath(img.src); - $scope.images.push(img); - $scope.ids.push(img.id); - }); + setupViewModel(); - $scope.sync(); - }}); - }; + $scope.remove = function(index) { + $scope.images.splice(index, 1); + $scope.ids.splice(index, 1); + $scope.sync(); + }; - $scope.sync = function(){ - $scope.model.value = $scope.ids.join(); - }; - - //TODO: Need to add the onValueChanged method to detect if the server has changed the model value and re-create the ids + $scope.add = function() { + dialogService.mediaPicker({ + multipicker: true, + callback: function(data) { + _.each(data.selection, function(media, i) { + //shortcuts + //TODO, do something better then this for searching -}); \ No newline at end of file + var img = {}; + img.id = media.id; + img.src = imageHelper.getImagePropertyValue({ imageModel: media }); + img.thumbnail = imageHelper.getThumbnailFromPath(img.src); + $scope.images.push(img); + $scope.ids.push(img.id); + }); + + $scope.sync(); + } + }); + }; + + $scope.sync = function() { + $scope.model.value = $scope.ids.join(); + }; + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; + + }); \ No newline at end of file From e5c7a35e8f43cf32d99ad36a22508dcc28cbd70a Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:12:15 +1000 Subject: [PATCH 23/31] updates g-maps editor to use onValueChanged to detect if a server val has changed. --- .../googlemaps/googlemaps.controller.js | 131 ++++++++++-------- 1 file changed, 70 insertions(+), 61 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js index bbd76874b5..c7e85c2138 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/googlemaps/googlemaps.controller.js @@ -1,75 +1,84 @@ angular.module("umbraco") .controller("Umbraco.Editors.GoogleMapsController", function ($rootScope, $scope, notificationsService, dialogService, assetsService, $log, $timeout) { - - assetsService.loadJs('http://www.google.com/jsapi') - .then(function(){ - google.load("maps", "3", - { - callback: initMap, - other_params: "sensor=false" + + assetsService.loadJs('http://www.google.com/jsapi') + .then(function () { + google.load("maps", "3", + { + callback: initMap, + other_params: "sensor=false" + }); + }); + + function initMap() { + //Google maps is available and all components are ready to use. + var valueArray = $scope.model.value.split(','); + var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]); + var mapDiv = document.getElementById($scope.model.alias + '_map'); + var mapOptions = { + zoom: $scope.model.config.zoom, + center: latLng, + mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType] + }; + var geocoder = new google.maps.Geocoder(); + var map = new google.maps.Map(mapDiv, mapOptions); + + var marker = new google.maps.Marker({ + map: map, + position: latLng, + draggable: true + }); + + google.maps.event.addListener(map, 'click', function (event) { + + dialogService.mediaPicker({ + scope: $scope, callback: function (data) { + var image = data.selection[0].src; + + var latLng = event.latLng; + var marker = new google.maps.Marker({ + map: map, + icon: image, + position: latLng, + draggable: true }); - }); - function initMap(){ - //Google maps is available and all components are ready to use. - var valueArray = $scope.model.value.split(','); - var latLng = new google.maps.LatLng(valueArray[0], valueArray[1]); - var mapDiv = document.getElementById($scope.model.alias + '_map'); - var mapOptions = { - zoom: $scope.model.config.zoom, - center: latLng, - mapTypeId: google.maps.MapTypeId[$scope.model.config.mapType] - }; - var geocoder = new google.maps.Geocoder(); - var map = new google.maps.Map(mapDiv, mapOptions); + google.maps.event.addListener(marker, "dragend", function (e) { + var newLat = marker.getPosition().lat(); + var newLng = marker.getPosition().lng(); - var marker = new google.maps.Marker({ - map: map, - position: latLng, - draggable: true - }); + codeLatLng(marker.getPosition(), geocoder); - google.maps.event.addListener(map, 'click', function(event) { + //set the model value + $scope.model.vvalue = newLat + "," + newLng; + }); - dialogService.mediaPicker({scope: $scope, callback: function(data){ - var image = data.selection[0].src; - - var latLng = event.latLng; - var marker = new google.maps.Marker({ - map: map, - icon: image, - position: latLng, - draggable: true + } }); + }); - google.maps.event.addListener(marker, "dragend", function(e){ - var newLat = marker.getPosition().lat(); - var newLng = marker.getPosition().lng(); + $('a[data-toggle="tab"]').on('shown', function (e) { + google.maps.event.trigger(map, 'resize'); + }); + } - codeLatLng(marker.getPosition(), geocoder); - - //set the model value - $scope.model.vvalue = newLat + "," + newLng; - }); - - }}); - }); - - $('a[data-toggle="tab"]').on('shown', function (e) { - google.maps.event.trigger(map, 'resize'); - }); - } - - function codeLatLng(latLng, geocoder) { - geocoder.geocode({'latLng': latLng}, - function(results, status) { - if (status == google.maps.GeocoderStatus.OK) { - var location = results[0].formatted_address; + function codeLatLng(latLng, geocoder) { + geocoder.geocode({ 'latLng': latLng }, + function (results, status) { + if (status == google.maps.GeocoderStatus.OK) { + var location = results[0].formatted_address; $rootScope.$apply(function () { notificationsService.success("Peter just went to: ", location); }); - } - }); - } -}); \ No newline at end of file + } + }); + } + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + initMap(); + }; + }); \ No newline at end of file From e27a0e2bd21e44f55cade6932badc88bda168a7e Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:16:57 +1000 Subject: [PATCH 24/31] updates boolean and check box list to use onValueChanged to detect any server value changes. --- .../boolean/boolean.controller.js | 22 +++++++++--- .../checkboxlist/checkboxlist.controller.js | 36 ++++++++++++------- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js index db185da7d0..bafd28e90b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/boolean/boolean.controller.js @@ -1,14 +1,26 @@ function booleanEditorController($scope, $rootScope, assetsService) { - $scope.renderModel = { - value: false - }; - if ($scope.model && $scope.model.value && ($scope.model.value.toString() === "1" || angular.lowercase($scope.model.value) === "true")) { - $scope.renderModel.value = true; + + function setupViewModel() { + $scope.renderModel = { + value: false + }; + if ($scope.model && $scope.model.value && ($scope.model.value.toString() === "1" || angular.lowercase($scope.model.value) === "true")) { + $scope.renderModel.value = true; + } } + setupViewModel(); + $scope.$watch("renderModel.value", function (newVal) { $scope.model.value = newVal === true ? "1" : "0"; }); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; } angular.module("umbraco").controller("Umbraco.Editors.BooleanController", booleanEditorController); \ No newline at end of file diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js index eaeaef2860..d343fe903e 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/checkboxlist/checkboxlist.controller.js @@ -1,22 +1,27 @@ angular.module("umbraco").controller("Umbraco.Editors.CheckboxListController", function($scope) { - - $scope.selectedItems = []; - + if (!angular.isObject($scope.model.config.items)) { throw "The model.config.items property must be either a dictionary"; } - - //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set - // to "" gets selected by default - if ($scope.model.value === null || $scope.model.value === undefined) { - $scope.model.value = []; + + function setupViewModel() { + $scope.selectedItems = []; + + //now we need to check if the value is null/undefined, if it is we need to set it to "" so that any value that is set + // to "" gets selected by default + if ($scope.model.value === null || $scope.model.value === undefined) { + $scope.model.value = []; + } + + for (var i in $scope.model.config.items) { + var isChecked = _.contains($scope.model.value, i); + $scope.selectedItems.push({ checked: isChecked, key: i, val: $scope.model.config.items[i] }); + } } - for (var i in $scope.model.config.items) { - var isChecked = _.contains($scope.model.value, i); - $scope.selectedItems.push({ checked: isChecked, key: i, val: $scope.model.config.items[i] }); - } + setupViewModel(); + //update the model when the items checked changes $scope.$watch("selectedItems", function(newVal, oldVal) { @@ -29,5 +34,12 @@ angular.module("umbraco").controller("Umbraco.Editors.CheckboxListController", } }, true); + + //here we declare a special method which will be called whenever the value has changed from the server + //this is instead of doing a watch on the model.value = faster + $scope.model.onValueChanged = function (newVal, oldVal) { + //update the display val again if it has changed from the server + setupViewModel(); + }; }); From 4602a6b989bc511014f743217f822a9869b1da26 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 14:46:16 +1000 Subject: [PATCH 25/31] Fixes an issue with the MemberTypeReadOnlyFactory --- .../Persistence/Factories/MemberTypeReadOnlyFactory.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs index f7b314cbff..3462cef894 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs @@ -59,8 +59,11 @@ namespace Umbraco.Core.Persistence.Factories foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) { var group = new PropertyGroup(); + //Only assign an Id if the PropertyGroup belongs to this ContentType - if (groupDto.Id.HasValue && groupDto.Id == memberType.Id) + if (groupDto.Id.HasValue + /*SD: I've commented this out since it's never correct, why would the group id be the same as the type?? + * && groupDto.Id == memberType.Id*/) { group.Id = groupDto.Id.Value; From 76b7b131a90ccba9d8e77332e024bf3f954ab5ec Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 15:25:04 +1000 Subject: [PATCH 26/31] Gets members saving (initially) still needs lots more work though, waiting on some feedback from morten in the meantime. --- src/Umbraco.Web/Editors/MemberController.cs | 5 +++++ src/Umbraco.Web/WebApi/Binders/MemberBinder.cs | 14 ++++++++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs index a424324b3c..565c0fbfa2 100644 --- a/src/Umbraco.Web/Editors/MemberController.cs +++ b/src/Umbraco.Web/Editors/MemberController.cs @@ -89,6 +89,11 @@ namespace Umbraco.Web.Editors UpdateName(contentItem); + //map the custom properties + contentItem.PersistedContent.Email = contentItem.Email; + //TODO: If we allow changing the alias then we'll need to change URLs, etc... in the editor, would prefer to use + // a unique id but then need to figure out how to handle that with custom membership providers - waiting on feedback from morten. + MapPropertyValues(contentItem); //We need to manually check the validation results here because: diff --git a/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs b/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs index ee02c4e076..be399b88a6 100644 --- a/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs +++ b/src/Umbraco.Web/WebApi/Binders/MemberBinder.cs @@ -3,6 +3,8 @@ using AutoMapper; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.WebApi.Filters; +using System.Linq; namespace Umbraco.Web.WebApi.Binders { @@ -23,9 +25,17 @@ namespace Umbraco.Web.WebApi.Binders protected override IMember GetExisting(MemberSave model) { - return ApplicationContext.Services.MemberService.GetByUsername(model.Username); - } + //TODO: We're going to remove the built-in member properties from this editor - not sure if we should be persisting them elsewhere ? + var toRemove = Constants.Conventions.Member.StandardPropertyTypeStubs.Select(x => x.Value.Alias).ToArray(); + var member = ApplicationContext.Services.MemberService.GetByUsername(model.Username); + foreach (var remove in toRemove) + { + member.Properties.Remove(remove); + } + return member; + } + protected override IMember CreateNew(MemberSave model) { var contentType = ApplicationContext.Services.ContentTypeService.GetMemberType(model.ContentTypeAlias); From 31a59516260723beea5df982599c720f562637ac Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 15:36:08 +1000 Subject: [PATCH 27/31] Updated member tree/editor to use the GUID --- src/Umbraco.Core/Services/IMemberService.cs | 2 + .../src/common/resources/member.resource.js | 22 ++--- .../views/member/member.edit.controller.js | 2 +- src/Umbraco.Web/Editors/MemberController.cs | 8 +- src/Umbraco.Web/Trees/MediaTreeController.cs | 79 ---------------- src/Umbraco.Web/Trees/MemberTreeController.cs | 91 +++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 7 files changed, 110 insertions(+), 95 deletions(-) create mode 100644 src/Umbraco.Web/Trees/MemberTreeController.cs diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs index a6a2a14424..737e142c3b 100644 --- a/src/Umbraco.Core/Services/IMemberService.cs +++ b/src/Umbraco.Core/Services/IMemberService.cs @@ -14,6 +14,8 @@ namespace Umbraco.Core.Services IEnumerable GetMembersByMemberType(string memberTypeAlias); IEnumerable GetMembersByGroup(string memberGroupName); IEnumerable GetAllMembers(params int[] ids); + + //TODO: Need to get all members that start with a certain letter } /// 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 d879aa322c..fa2a8efa27 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 @@ -26,7 +26,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { /** * @ngdoc method - * @name umbraco.resources.memberResource#getByLogin + * @name umbraco.resources.memberResource#getByKey * @methodOf umbraco.resources.memberResource * * @description @@ -34,7 +34,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) { * * ##usage *
-         * memberResource.getByLogin("tom")
+         * memberResource.getByKey("0000-0000-000-00000-000")
          *    .then(function(member) {
          *        var mymember = member; 
          *        alert('its here!');
@@ -45,20 +45,20 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          * @returns {Promise} resourcePromise object containing the member item.
          *
          */
-        getByLogin: function (loginName) {
+        getByKey: function (key) {
             
             return umbRequestHelper.resourcePromise(
                $http.get(
                    umbRequestHelper.getApiUrl(
                        "memberApiBaseUrl",
-                       "GetByLogin",
-                       [{ loginName: loginName }])),
-               'Failed to retreive data for member id ' + loginName);
+                       "GetByKey",
+                       [{ key: key }])),
+               'Failed to retreive data for member id ' + key);
         },
 
         /**
          * @ngdoc method
-         * @name umbraco.resources.memberResource#deleteByLogin
+         * @name umbraco.resources.memberResource#deleteByKey
          * @methodOf umbraco.resources.memberResource
          *
          * @description
@@ -66,7 +66,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          *
          * ##usage
          * 
-         * memberResource.deleteByLogin(1234)
+         * memberResource.deleteByKey("0000-0000-000-00000-000")
          *    .then(function() {
          *        alert('its gone!');
          *    });
@@ -76,14 +76,14 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
          * @returns {Promise} resourcePromise object.
          *
          */
-        deleteByLogin: function (id) {
+        deleteByKey: function (key) {
             return umbRequestHelper.resourcePromise(
                 $http.delete(
                     umbRequestHelper.getApiUrl(
                         "memberApiBaseUrl",
                         "DeleteById",
-                        [{ id: id }])),
-                'Failed to delete item ' + id);
+                        [{ key: key }])),
+                'Failed to delete item ' + key);
         },
 
         /**
diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
index 4ff85a6f95..493739842b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
@@ -22,7 +22,7 @@ function MemberEditController($scope, $routeParams, $q, $timeout, $window, membe
     }
     else {
         //we are editing so get the content item from the server
-        memberResource.getByLogin($routeParams.id)
+        memberResource.getByKey($routeParams.id)
             .then(function(data) {
                 $scope.loaded = true;
                 $scope.content = data;
diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs
index 565c0fbfa2..87403d8713 100644
--- a/src/Umbraco.Web/Editors/MemberController.cs
+++ b/src/Umbraco.Web/Editors/MemberController.cs
@@ -50,16 +50,16 @@ namespace Umbraco.Web.Editors
         /// 
         /// Gets the content json for the member
         /// 
-        /// 
+        /// 
         /// 
-        public MemberDisplay GetByLogin(string loginName)
+        public MemberDisplay GetByKey(Guid key)
         {
             if (Member.InUmbracoMemberMode())
             {
-                var foundMember = Services.MemberService.GetByUsername(loginName);
+                var foundMember = Services.MemberService.GetByKey(key);
                 if (foundMember == null)
                 {
-                    HandleContentNotFound(loginName);
+                    HandleContentNotFound(key);
                 }
                 return Mapper.Map(foundMember);
             }
diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs
index ee2432bf15..fac1e5386b 100644
--- a/src/Umbraco.Web/Trees/MediaTreeController.cs
+++ b/src/Umbraco.Web/Trees/MediaTreeController.cs
@@ -1,11 +1,9 @@
 using System;
-using System.Globalization;
 using System.Linq;
 using System.Net;
 using System.Net.Http.Formatting;
 using System.Web;
 using System.Web.Http;
-using System.Web.Security;
 using Umbraco.Core;
 using Umbraco.Core.Models;
 using Umbraco.Core.Services;
@@ -14,86 +12,9 @@ using Umbraco.Web.Trees.Menu;
 using umbraco;
 using umbraco.BusinessLogic.Actions;
 using Constants = Umbraco.Core.Constants;
-using LegacyMember = umbraco.cms.businesslogic.member.Member;
 
 namespace Umbraco.Web.Trees
 {
-    [LegacyBaseTree(typeof (loadMembers))]
-    [Tree(Constants.Applications.Members, Constants.Trees.Members, "Members")]
-    [PluginController("UmbracoTrees")]
-    public class MemberTreeController : TreeController
-    {
-        protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
-        {
-            var nodes = new TreeNodeCollection();
-
-            if (id == Constants.System.Root.ToInvariantString())
-            {
-                //list out all the letters
-                for (var i = 97; i < 123; i++)
-                {
-                    var charString = ((char) i).ToString(CultureInfo.InvariantCulture);
-                    nodes.Add(CreateTreeNode(charString, queryStrings, charString, "icon-folder-close", true));
-                }
-                //list out 'Others' if the membership provider is umbraco
-                if (LegacyMember.InUmbracoMemberMode())
-                {
-                    nodes.Add(CreateTreeNode("others", queryStrings, "Others", "icon-folder-close", true));
-                }
-            }
-            else
-            {
-                //if it is a letter
-                if (id.Length == 1 && char.IsLower(id, 0))
-                {
-                    if (LegacyMember.InUmbracoMemberMode())
-                    {
-                        //get the members from our member data layer
-                        nodes.AddRange(
-                            LegacyMember.getMemberFromFirstLetter(id.ToCharArray()[0])
-                                        .Select(m => CreateTreeNode(m.LoginName, queryStrings, m.Text, "icon-user")));
-                    }
-                    else
-                    {
-                        //get the members from the provider
-                        int total;
-                        nodes.AddRange(
-                            Membership.Provider.FindUsersByName(id + "%", 0, 9999, out total).Cast()
-                                      .Select(m => CreateTreeNode(m.UserName, queryStrings, m.UserName, "icon-user")));
-                    }
-                }
-                else if (id == "others")
-                {
-                    //others will only show up when in umbraco membership mode
-                    nodes.AddRange(
-                        LegacyMember.getAllOtherMembers()
-                                    .Select(m => CreateTreeNode(m.Id.ToInvariantString(), queryStrings, m.Text, "icon-user")));
-                }
-            }
-            return nodes;
-        }
-
-        protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
-        {
-            var menu = new MenuItemCollection();
-
-            if (id == Constants.System.Root.ToInvariantString())
-            {
-                //set default
-                menu.DefaultMenuAlias = ActionNew.Instance.Alias;
-
-                // root actions         
-                menu.AddMenuItem();
-                menu.AddMenuItem(true);
-                return menu;
-            }
-
-            menu.AddMenuItem();
-            return menu;
-        }
-    }
-
-
     [LegacyBaseTree(typeof(loadMedia))]
     [Tree(Constants.Applications.Media, Constants.Trees.Media, "Media")]
     [PluginController("UmbracoTrees")]
diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs
new file mode 100644
index 0000000000..b127ae5808
--- /dev/null
+++ b/src/Umbraco.Web/Trees/MemberTreeController.cs
@@ -0,0 +1,91 @@
+using System.Globalization;
+using System.Linq;
+using System.Net.Http.Formatting;
+using System.Web.Security;
+using Umbraco.Core;
+using Umbraco.Web.Mvc;
+using Umbraco.Web.Trees.Menu;
+using umbraco;
+using umbraco.BusinessLogic.Actions;
+using umbraco.cms.businesslogic.member;
+using Constants = Umbraco.Core.Constants;
+
+namespace Umbraco.Web.Trees
+{
+    //TODO: Upgrade thsi to use the new Member Service!
+
+    [LegacyBaseTree(typeof (loadMembers))]
+    [Tree(Constants.Applications.Members, Constants.Trees.Members, "Members")]
+    [PluginController("UmbracoTrees")]
+    public class MemberTreeController : TreeController
+    {
+        protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
+        {
+            var nodes = new TreeNodeCollection();
+
+            if (id == Constants.System.Root.ToInvariantString())
+            {
+                //list out all the letters
+                for (var i = 97; i < 123; i++)
+                {
+                    var charString = ((char) i).ToString(CultureInfo.InvariantCulture);
+                    nodes.Add(CreateTreeNode(charString, queryStrings, charString, "icon-folder-close", true));
+                }
+                //list out 'Others' if the membership provider is umbraco
+                if (Member.InUmbracoMemberMode())
+                {
+                    nodes.Add(CreateTreeNode("others", queryStrings, "Others", "icon-folder-close", true));
+                }
+            }
+            else
+            {
+                //if it is a letter
+                if (id.Length == 1 && char.IsLower(id, 0))
+                {
+                    if (Member.InUmbracoMemberMode())
+                    {
+                        //get the members from our member data layer
+                        nodes.AddRange(
+                            Member.getMemberFromFirstLetter(id.ToCharArray()[0])
+                                        .Select(m => CreateTreeNode(m.UniqueId.ToString("N"), queryStrings, m.Text, "icon-user")));
+                    }
+                    else
+                    {
+                        //get the members from the provider
+                        int total;
+                        nodes.AddRange(
+                            Membership.Provider.FindUsersByName(id + "%", 0, 9999, out total).Cast()
+                                      .Select(m => CreateTreeNode(m.ProviderUserKey.ToString(), queryStrings, m.UserName, "icon-user")));
+                    }
+                }
+                else if (id == "others")
+                {
+                    //others will only show up when in umbraco membership mode
+                    nodes.AddRange(
+                        Member.getAllOtherMembers()
+                                    .Select(m => CreateTreeNode(m.Id.ToInvariantString(), queryStrings, m.Text, "icon-user")));
+                }
+            }
+            return nodes;
+        }
+
+        protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
+        {
+            var menu = new MenuItemCollection();
+
+            if (id == Constants.System.Root.ToInvariantString())
+            {
+                //set default
+                menu.DefaultMenuAlias = ActionNew.Instance.Alias;
+
+                // root actions         
+                menu.AddMenuItem();
+                menu.AddMenuItem(true);
+                return menu;
+            }
+
+            menu.AddMenuItem();
+            return menu;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 0c085bfcab..1bc820439e 100644
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -370,6 +370,7 @@
     
     
     
+    
     
     
     

From 770514919d26a746568261cb5ef633a64f04aeb2 Mon Sep 17 00:00:00 2001
From: Shannon 
Date: Tue, 1 Oct 2013 15:54:44 +1000
Subject: [PATCH 28/31] Gets member deleting working and adds refresh to each
 letter node.

---
 .../src/common/resources/member.resource.js   |  2 +-
 .../views/member/member.delete.controller.js  |  2 +-
 src/Umbraco.Web/Editors/MemberController.cs   | 21 +++++++++++++++++++
 src/Umbraco.Web/Trees/MemberTreeController.cs |  1 +
 4 files changed, 24 insertions(+), 2 deletions(-)

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 fa2a8efa27..bf726be952 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
@@ -81,7 +81,7 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
                 $http.delete(
                     umbRequestHelper.getApiUrl(
                         "memberApiBaseUrl",
-                        "DeleteById",
+                        "DeleteByKey",
                         [{ key: key }])),
                 'Failed to delete item ' + key);
         },
diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js
index 27d01f6a4a..dc86b21731 100644
--- a/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/member/member.delete.controller.js
@@ -13,7 +13,7 @@ function MemberDeleteController($scope, memberResource, treeService, navigationS
         //mark it for deletion (used in the UI)
         $scope.currentNode.loading = true;
 
-        memberResource.deleteByLogin($scope.currentNode.id).then(function () {
+        memberResource.deleteByKey($scope.currentNode.id).then(function () {
             $scope.currentNode.loading = false;
 
             //TODO: Need to sync tree, etc...
diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs
index 87403d8713..9ce07c1fa5 100644
--- a/src/Umbraco.Web/Editors/MemberController.cs
+++ b/src/Umbraco.Web/Editors/MemberController.cs
@@ -1,6 +1,8 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Net;
+using System.Net.Http;
 using System.Text;
 using System.Threading.Tasks;
 using System.Web.Http;
@@ -135,5 +137,24 @@ namespace Umbraco.Web.Editors
 
             return display;
         }
+
+
+        /// 
+        /// Permanently deletes a member
+        /// 
+        /// 
+        ///         
+        public HttpResponseMessage DeleteByKey(Guid key)
+        {
+            var foundMember = Services.MemberService.GetByKey(key);
+            if (foundMember == null)
+            {
+                return HandleContentNotFound(key, false);
+            }
+
+            Services.MemberService.Delete(foundMember);
+
+            return Request.CreateResponse(HttpStatusCode.OK);
+        }
     }
 }
diff --git a/src/Umbraco.Web/Trees/MemberTreeController.cs b/src/Umbraco.Web/Trees/MemberTreeController.cs
index b127ae5808..081f7c8c33 100644
--- a/src/Umbraco.Web/Trees/MemberTreeController.cs
+++ b/src/Umbraco.Web/Trees/MemberTreeController.cs
@@ -85,6 +85,7 @@ namespace Umbraco.Web.Trees
             }
 
             menu.AddMenuItem();
+            menu.AddMenuItem(true);
             return menu;
         }
     }

From 4e56d88eb5f09b5bd9b5fd036734636aa773aa83 Mon Sep 17 00:00:00 2001
From: Shannon 
Date: Tue, 1 Oct 2013 16:38:10 +1000
Subject: [PATCH 29/31] Fixes: U4-2672 Fix how trees are rendered when a start
 node is applied, the Content/Media titles must always be visible

---
 .../Trees/ContentTreeController.cs            | 41 +++++++------------
 .../Trees/ContentTreeControllerBase.cs        | 13 ++++--
 src/Umbraco.Web/Trees/MediaTreeController.cs  | 22 ++++++++++
 src/Umbraco.Web/Trees/TreeNode.cs             |  7 ----
 4 files changed, 47 insertions(+), 36 deletions(-)

diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index 0136510628..20b17babf9 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -26,36 +26,13 @@ namespace Umbraco.Web.Trees
     {
         protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
         {
-            TreeNode node;
-
-            //if the user's start node is not default, then return their start node as the root node.
+            var node = base.CreateRootNode(queryStrings); 
+            //if the user's start node is not default, then ensure the root doesn't have a menu
             if (Security.CurrentUser.StartContentId != Constants.System.Root)
             {
-                var currApp = queryStrings.GetValue(TreeQueryStringParameters.Application);
-                var userRoot = Services.EntityService.Get(Security.CurrentUser.StartContentId, UmbracoObjectTypes.Document);
-                if (userRoot == null)
-                {
-                    throw new HttpResponseException(HttpStatusCode.NotFound);
-                }
-
-                node = new TreeNode(
-                    userRoot.Id.ToInvariantString(),
-                    "", //root nodes aren't expandable, no need to lookup the child nodes url
-                    Url.GetMenuUrl(GetType(), userRoot.Id.ToInvariantString(), queryStrings))
-                    {
-                        HasChildren = true,
-                        RoutePath = currApp,
-                        Title = userRoot.Name
-                    };
-
-
-            }
-            else
-            {
-                node = base.CreateRootNode(queryStrings);    
+                node.MenuUrl = "";
             }
             return node;
-            
         }
 
         protected override int RecycleBinId
@@ -68,6 +45,11 @@ namespace Umbraco.Web.Trees
             get { return Services.ContentService.RecycleBinSmells(); }
         }
 
+        protected override int UserStartNode
+        {
+            get { return Security.CurrentUser.StartContentId; }
+        }
+
         protected override TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings)
         {
             var entities = GetChildEntities(id);
@@ -111,10 +93,17 @@ namespace Umbraco.Web.Trees
             {
                 var menu = new MenuItemCollection();
 
+                //if the user's start node is not the root then ensure the root menu is empty/doesn't exist
+                if (Security.CurrentUser.StartContentId != Constants.System.Root)
+                {
+                    return menu;
+                }
+
                 //set the default to create
                 menu.DefaultMenuAlias = ActionNew.Instance.Alias;
 
                 // we need to get the default permissions as you can't set permissions on the very root node
+                //TODO: Use the new services to get permissions
                 var nodeActions = global::umbraco.BusinessLogic.Actions.Action.FromString(
                     UmbracoUser.GetPermissions(Constants.System.Root.ToInvariantString()))
                                         .Select(x => new MenuItem(x));
diff --git a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
index b3ebabb0f9..a1e646e70a 100644
--- a/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeControllerBase.cs
@@ -23,6 +23,11 @@ namespace Umbraco.Web.Trees
         /// 
protected abstract bool RecycleBinSmells { get; } + /// + /// Returns the user's start node for this tree + /// + protected abstract int UserStartNode { get; } + protected abstract TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings); protected abstract MenuItemCollection PerformGetMenuForNode(string id, FormDataCollection queryStrings); @@ -39,9 +44,11 @@ namespace Umbraco.Web.Trees //if a request is made for the root node data but the user's start node is not the default, then // we need to return their start node data - if (iid == Constants.System.Root && UmbracoUser.StartNodeId != Constants.System.Root) + if (iid == Constants.System.Root && UserStartNode != Constants.System.Root) { - return Services.EntityService.GetChildren(UmbracoUser.StartNodeId, UmbracoObjectType).ToArray(); + //just return their single start node, it will show up under the 'Content' label + var startNode = Services.EntityService.Get(UserStartNode, UmbracoObjectType); + return new[] {startNode}; } return Services.EntityService.GetChildren(iid, UmbracoObjectType).ToArray(); @@ -56,7 +63,7 @@ namespace Umbraco.Web.Trees /// protected sealed override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) { - if (id == Constants.System.Root.ToInvariantString()) + if (id == Constants.System.Root.ToInvariantString() && UserStartNode == Constants.System.Root) { //we need to append the recycle bin to the end (if not in dialog mode) var nodes = PerformGetTreeNodes(id, queryStrings); diff --git a/src/Umbraco.Web/Trees/MediaTreeController.cs b/src/Umbraco.Web/Trees/MediaTreeController.cs index fac1e5386b..3df864cbd7 100644 --- a/src/Umbraco.Web/Trees/MediaTreeController.cs +++ b/src/Umbraco.Web/Trees/MediaTreeController.cs @@ -20,6 +20,17 @@ namespace Umbraco.Web.Trees [PluginController("UmbracoTrees")] public class MediaTreeController : ContentTreeControllerBase { + protected override TreeNode CreateRootNode(FormDataCollection queryStrings) + { + var node = base.CreateRootNode(queryStrings); + //if the user's start node is not default, then ensure the root doesn't have a menu + if (Security.CurrentUser.StartMediaId != Constants.System.Root) + { + node.MenuUrl = ""; + } + return node; + } + protected override int RecycleBinId { get { return Constants.System.RecycleBinContent; } @@ -30,6 +41,11 @@ namespace Umbraco.Web.Trees get { return Services.MediaService.RecycleBinSmells(); } } + protected override int UserStartNode + { + get { return Security.CurrentUser.StartMediaId; } + } + protected override TreeNodeCollection PerformGetTreeNodes(string id, FormDataCollection queryStrings) { var entities = GetChildEntities(id); @@ -53,6 +69,12 @@ namespace Umbraco.Web.Trees if (id == Constants.System.Root.ToInvariantString()) { + //if the user's start node is not the root then ensure the root menu is empty/doesn't exist + if (Security.CurrentUser.StartMediaId != Constants.System.Root) + { + return menu; + } + // root actions menu.AddMenuItem(); menu.AddMenuItem(true); diff --git a/src/Umbraco.Web/Trees/TreeNode.cs b/src/Umbraco.Web/Trees/TreeNode.cs index fd62dff815..fefd5e6f80 100644 --- a/src/Umbraco.Web/Trees/TreeNode.cs +++ b/src/Umbraco.Web/Trees/TreeNode.cs @@ -53,13 +53,6 @@ namespace Umbraco.Web.Trees [DataMember(Name = "name")] public string Title { get; set; } - //TODO: This doesn't seem to be used by anything! - /// - /// Gets or sets the node path. - /// - [DataMember(Name = "nodePath")] - public string NodePath { get; set; } - /// /// The icon to use for the node, this can be either a path to an image or a Css class. /// If a '/' is found in the string then it will be considered a path to an image. From a90e96d06661b7f9e92559e23a4375a8958797e0 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 16:42:32 +1000 Subject: [PATCH 30/31] Completes: U4-2926 Remove unused/obsoleted 'tasks' for media & content --- src/Umbraco.Tests/UI/LegacyDialogTests.cs | 2 - .../umbraco/config/create/UI.Release.xml | 18 +----- .../umbraco/config/create/UI.xml | 18 +----- src/Umbraco.Web/Umbraco.Web.csproj | 2 - .../umbraco/create/contentTasks.cs | 58 ------------------- .../umbraco/create/mediaTasks.cs | 50 ---------------- 6 files changed, 2 insertions(+), 146 deletions(-) delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs diff --git a/src/Umbraco.Tests/UI/LegacyDialogTests.cs b/src/Umbraco.Tests/UI/LegacyDialogTests.cs index 1a5b01964f..11633b7f88 100644 --- a/src/Umbraco.Tests/UI/LegacyDialogTests.cs +++ b/src/Umbraco.Tests/UI/LegacyDialogTests.cs @@ -42,14 +42,12 @@ namespace Umbraco.Tests.UI [TestCase(typeof(memberTasks), DefaultApps.member)] [TestCase(typeof(MemberGroupTasks), DefaultApps.member)] [TestCase(typeof(MediaTypeTasks), DefaultApps.settings)] - [TestCase(typeof(mediaTasks), DefaultApps.media)] [TestCase(typeof(dictionaryTasks), DefaultApps.settings)] [TestCase(typeof(macroTasks), DefaultApps.developer)] [TestCase(typeof(languageTasks), DefaultApps.settings)] [TestCase(typeof(DLRScriptingTasks), DefaultApps.developer)] [TestCase(typeof(DataTypeTasks), DefaultApps.developer)] [TestCase(typeof(CreatedPackageTasks), DefaultApps.developer)] - [TestCase(typeof(contentTasks), DefaultApps.content)] [TestCase(typeof(PartialViewTasks), DefaultApps.settings)] public void Check_Assigned_Apps_For_Tasks(Type taskType, DefaultApps app) { diff --git a/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml b/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml index 569defa824..3d7bca0afd 100644 --- a/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml +++ b/src/Umbraco.Web.UI/umbraco/config/create/UI.Release.xml @@ -59,14 +59,6 @@ - -
Page
- /create/content.ascx - - - - -
User
/create/simple.ascx @@ -138,15 +130,7 @@ -
- -
Media
- /create/media.ascx - - - - -
+
member
/create/member.ascx diff --git a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml index 86dceaf5c0..15a3f1d3e2 100644 --- a/src/Umbraco.Web.UI/umbraco/config/create/UI.xml +++ b/src/Umbraco.Web.UI/umbraco/config/create/UI.xml @@ -59,14 +59,6 @@
- -
Page
- /create/content.ascx - - - - -
User
/create/simple.ascx @@ -138,15 +130,7 @@ -
- -
Media
- /create/media.ascx - - - - -
+
member
/create/member.ascx diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 1bc820439e..689715fc24 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -1010,7 +1010,6 @@ - @@ -1023,7 +1022,6 @@ - diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs deleted file mode 100644 index 160cb7b610..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/contentTasks.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Data; -using System.Web.Security; -using Umbraco.Web.UI; -using umbraco.BusinessLogic; -using umbraco.DataLayer; -using umbraco.BasePages; -using umbraco.IO; -using umbraco.cms.businesslogic.member; - -namespace umbraco -{ - public class contentTasks : LegacyDialogTask - { - private string _returnUrl = ""; - - public override string ReturnUrl - { - get { return _returnUrl; } - } - - public override string AssignedApp - { - get { return DefaultApps.content.ToString(); } - } - - public override bool PerformSave() - { - var dt = new cms.businesslogic.web.DocumentType(TypeID); - var d = cms.businesslogic.web.Document.MakeNew(Alias, dt, User, ParentID); - if (d == null) - { - //TODO: Slace - Fix this to use the language files - BasePage.Current.ClientTools.ShowSpeechBubble(BasePage.speechBubbleIcon.error, "Document Creation", "Document creation was canceled"); - return false; - } - else - { - _returnUrl = "editContent.aspx?id=" + d.Id.ToString() + "&isNew=true"; - return true; - } - } - - public override bool PerformDelete() - { - var d = new cms.businesslogic.web.Document(ParentID); - - d.delete(); - - // Log - Log.Add(LogTypes.Delete, User.GetCurrent(), d.Id, ""); - - return true; - - } - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs deleted file mode 100644 index aadd439a00..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/mediaTasks.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Data; -using System.Web.Security; -using Umbraco.Core.Logging; -using Umbraco.Web.UI; -using umbraco.BusinessLogic; -using umbraco.DataLayer; -using umbraco.BasePages; -using umbraco.IO; -using umbraco.cms.businesslogic.member; - -namespace umbraco -{ - public class mediaTasks : LegacyDialogTask - { - private string _returnUrl = ""; - - public override string ReturnUrl - { - get { return _returnUrl; } - } - - public override string AssignedApp - { - get { return DefaultApps.media.ToString(); } - } - - public override bool PerformSave() - { - var dt = new cms.businesslogic.media.MediaType(TypeID); - var m = cms.businesslogic.media.Media.MakeNew(Alias, dt, User, ParentID); - _returnUrl = "editMedia.aspx?id=" + m.Id.ToString() + "&isNew=true"; - - return true; - } - - public override bool PerformDelete() - { - var d = new cms.businesslogic.media.Media(ParentID); - - // Log - LogHelper.Debug(string.Format("Delete media item {0} by user {1}", d.Id, User.GetCurrent().Id)); - - d.delete(); - return true; - - } - - } -} From f7103c97cf680a71a012c252b86d75d952a41630 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 1 Oct 2013 17:03:03 +1000 Subject: [PATCH 31/31] Completes: U4-2768 Remove legacy/unused webforms files/classes in folder: /umbraco --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 22 - src/Umbraco.Web.UI/umbraco/Create.aspx.cs | 39 -- .../umbraco/Create.aspx.designer.cs | 25 - src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs | 185 ----- .../umbraco/Umbraco.aspx.designer.cs | 286 -------- src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx | 16 - src/Umbraco.Web.UI/umbraco/create.aspx | 43 -- src/Umbraco.Web.UI/umbraco/dashboard.aspx | 11 - src/Umbraco.Web.UI/umbraco/editContent.aspx | 62 -- src/Umbraco.Web.UI/umbraco/editMedia.aspx | 28 - src/Umbraco.Web.UI/umbraco/login.aspx | 129 ---- src/Umbraco.Web.UI/umbraco/logout.aspx | 18 - src/Umbraco.Web.UI/umbraco/umbraco.aspx | 399 ----------- src/Umbraco.Web/Umbraco.Web.csproj | 30 - .../umbraco/cacheBrowser.aspx.cs | 42 -- .../umbraco/create.aspx.cs | 50 -- .../umbraco/dashboard.aspx.cs | 377 ---------- .../umbraco/editContent.aspx.cs | 642 ------------------ .../umbraco/editMedia.aspx.cs | 191 ------ .../umbraco/login.aspx.cs | 307 --------- .../umbraco/logout.aspx.cs | 28 - .../umbraco/timerModule.cs | 39 -- .../umbraco.presentation/umbraco/umbWindow.cs | 148 ---- .../umbraco/umbraco.aspx.cs | 460 ------------- 24 files changed, 3577 deletions(-) delete mode 100644 src/Umbraco.Web.UI/umbraco/Create.aspx.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs delete mode 100644 src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/create.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/dashboard.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/editContent.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/editMedia.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/login.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/logout.aspx delete mode 100644 src/Umbraco.Web.UI/umbraco/umbraco.aspx delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs delete mode 100644 src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index ce8005583b..fa90a61110 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -422,13 +422,6 @@ ImageViewer.ascx - - create.aspx - ASPXCodeBehind - - - create.aspx - PartialView.ascx ASPXCodeBehind @@ -588,13 +581,6 @@ treeInit.aspx - - umbraco.aspx - ASPXCodeBehind - - - umbraco.aspx - @@ -695,7 +681,6 @@ - @@ -2048,7 +2033,6 @@ UserControl - Designer @@ -2182,7 +2166,6 @@ - @@ -2191,8 +2174,6 @@ - - @@ -2397,8 +2378,6 @@ - - Form @@ -2422,7 +2401,6 @@ - diff --git a/src/Umbraco.Web.UI/umbraco/Create.aspx.cs b/src/Umbraco.Web.UI/umbraco/Create.aspx.cs deleted file mode 100644 index 304e7ffdb1..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Create.aspx.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web; -using System.Xml; -using Umbraco.Core; -using Umbraco.Core.IO; -using umbraco.cms.presentation.Trees; - -namespace Umbraco.Web.UI.Umbraco -{ - public partial class CreateDialog : global::umbraco.cms.presentation.Create - { - - protected override void OnLoad(EventArgs e) - { - if (SecurityCheck(Request.QueryString["nodeType"])) - { - //if we're allowed, then continue - base.OnLoad(e); - } - else - { - //otherwise show an error - UI.Visible = false; - AccessError.Visible = true; - } - } - - private bool SecurityCheck(string nodeTypeAlias) - { - return LegacyDialogHandler.UserHasCreateAccess( - new HttpContextWrapper(Context), - getUser(), - nodeTypeAlias); - } - - } -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs deleted file mode 100644 index 1e11eaf00d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Create.aspx.designer.cs +++ /dev/null @@ -1,25 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco { - - - public partial class CreateDialog - { - - /// - /// AccessError control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder AccessError; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs b/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs deleted file mode 100644 index 02b0feee92..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.IO; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; -using System.Web; -using System.Web.UI; -using Umbraco.Core.IO; -using umbraco; -using Umbraco.Core; - -namespace Umbraco.Web.UI.Umbraco -{ - public partial class Umbraco : Pages.UmbracoEnsuredPage - { - public string DefaultApp { get; private set; } - - protected void Page_Load(object sender, System.EventArgs e) - { - var apps = UmbracoUser.Applications.ToList(); - bool userHasAccesstodefaultApp = apps.Any(x => x.alias == Constants.Applications.Content); - - // Load user module icons .. - if (apps.Count() > 1) - { - - var jsEvents = new StringBuilder(); - - PlaceHolderAppIcons.Text = ui.Text("main", "sections", UmbracoUser); - plcIcons.Text = ""; - foreach (global::umbraco.BusinessLogic.Application a in apps.OrderBy(x => x.sortOrder)) - { - - string appClass = a.icon.StartsWith(".") ? a.icon.Substring(1, a.icon.Length - 1) : a.alias; - - //adds client side event handlers to the icon buttons - jsEvents.Append(@"jQuery('." + appClass + "').click(function() { appClick.call(this, '" + a.alias + "'); } );"); - jsEvents.Append(@"jQuery('." + appClass + "').dblclick(function() { appDblClick.call(this, '" + a.alias + "'); } );"); - - string iconElement = String.Format("
  • ", appClass); - if (a.icon.StartsWith(".")) - iconElement += - "\"\"
  • "; - else - iconElement += "\"""; - plcIcons.Text += iconElement; - - } - - //registers the jquery event handlers. - Page.ClientScript.RegisterStartupScript(this.GetType(), "AppIcons", "jQuery(document).ready(function() { " + jsEvents.ToString() + " } );", true); - - } - else - PlaceHolderAppIcons.Visible = false; - - - //if user does not have access to content (ie, he's probably a translator)... - //then change the default tree app - if (!userHasAccesstodefaultApp) - { - JTree.App = apps[0].alias; - DefaultApp = apps[0].alias; - } - else - { - DefaultApp = Constants.Applications.Content; - } - - - // Load globalized labels - treeWindow.Text = ui.Text("main", "tree", UmbracoUser); - - RenderActionJs(); - - // Version check goes here! - - // zb-00004 #29956 : refactor cookies names & handling - var updChkCookie = new global::umbraco.BusinessLogic.StateHelper.Cookies.Cookie("UMB_UPDCHK", GlobalSettings.VersionCheckPeriod); // was "updateCheck" - string updateCheckCookie = updChkCookie.HasValue ? updChkCookie.GetValue() : ""; - - if (GlobalSettings.VersionCheckPeriod > 0 && String.IsNullOrEmpty(updateCheckCookie) && UmbracoUser.UserType.Alias == "admin") - { - - // Add scriptmanager version check - ScriptManager sm = ScriptManager.GetCurrent(Page); - sm.Scripts.Add(new ScriptReference(SystemDirectories.Umbraco + "/js/umbracoUpgradeChecker.js")); - sm.Services.Add(new ServiceReference(SystemDirectories.WebServices + "/CheckForUpgrade.asmx")); - - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "upgradeChecker", "jQuery(document).ready(function() {umbraco.presentation.webservices.CheckForUpgrade.CallUpgradeService(umbracoCheckUpgrade);});", true); - - updChkCookie.SetValue("1"); - } - DataBind(); - - AddIe9Meta(); - } - - private void AddIe9Meta() - { - if (Request.Browser.Browser == "IE" && Request.Browser.MajorVersion == 9) - { - var metadata = new StringBuilder(); - metadata.AppendFormat( - @" - - - - - ", - IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/Images/PinnedIcons/umb.ico"), - HttpContext.Current.Request.Url.Host.ToLower().Replace("www.", "")); - - var user = UmbracoUser; - if (user != null && user.Applications != null && user.Applications.Length > 0) - { - foreach (var app in user.Applications) - { - metadata.AppendFormat( - @"", - ui.Text("sections", app.alias, user), - IOHelper.ResolveUrl(string.Format("{0}/umbraco.aspx#{1}", SystemDirectories.Umbraco, app.alias)), - File.Exists( - IOHelper.MapPath( - IOHelper.ResolveUrl( - string.Format("{0}/Images/PinnedIcons/task_{1}.ico", SystemDirectories.Umbraco, app.alias)))) - ? "/umbraco/Images/PinnedIcons/task_" + app.alias + ".ico" - : "/umbraco/Images/PinnedIcons/task_default.ico"); - } - } - - this.Header.Controls.Add(new LiteralControl(metadata.ToString())); - } - } - - /// - /// Renders out all JavaScript references that have bee declared in IActions - /// - private void RenderActionJs() - { - var item = 0; - foreach (var jsFile in global::umbraco.BusinessLogic.Actions.Action.GetJavaScriptFileReferences()) - { - //validate that this is a url, if it is not, we'll assume that it is a text block and render it as a text - //block instead. - var isValid = true; - try - { - var jsUrl = new Uri(jsFile, UriKind.RelativeOrAbsolute); - //ok it validates, but so does alert('hello'); ! so we need to do more checks - - //here are the valid chars in a url without escaping - if (Regex.IsMatch(jsFile, @"[^a-zA-Z0-9-._~:/?#\[\]@!$&'\(\)*\+,%;=]")) - isValid = false; - - //we'll have to be smarter and just check for certain js patterns now too! - var jsPatterns = new string[] { @"\+\s*\=", @"\);", @"function\s*\(", @"!=", @"==" }; - if (jsPatterns.Any(p => Regex.IsMatch(jsFile, p))) - { - isValid = false; - } - - if (isValid) - { - //add to page - Page.ClientScript.RegisterClientScriptInclude(this.GetType(), item.ToString(), jsFile); - } - } - catch (UriFormatException) - { - isValid = false; - } - - if (!isValid) - { - //it is invalid, let's render it as a script block instead as devs may have written real Javascript instead - //of a JS path - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), item.ToString(), jsFile, true); - } - - item++; - } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs b/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs deleted file mode 100644 index f7e448af08..0000000000 --- a/src/Umbraco.Web.UI/umbraco/Umbraco.aspx.designer.cs +++ /dev/null @@ -1,286 +0,0 @@ -//------------------------------------------------------------------------------ -// -// This code was generated by a tool. -// -// Changes to this file may cause incorrect behavior and will be lost if -// the code is regenerated. -// -//------------------------------------------------------------------------------ - -namespace Umbraco.Web.UI.Umbraco { - - - public partial class Umbraco - { - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// CssInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude2; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JSON2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JSON2; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude14 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude14; - - /// - /// JsInclude5 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude5; - - /// - /// JsInclude6 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude6; - - /// - /// JsInclude13 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude13; - - /// - /// JsInclude7 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude7; - - /// - /// JsInclude8 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude8; - - /// - /// JsInclude9 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude9; - - /// - /// JsInclude10 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude10; - - /// - /// JsInclude11 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude11; - - /// - /// JsInclude4 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude4; - - /// - /// JsInclude17 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude17; - - /// - /// JsInclude12 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude12; - - /// - /// JsInclude15 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude15; - - /// - /// JsInclude16 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude16; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// umbracoScriptManager control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.ScriptManager umbracoScriptManager; - - /// - /// FindDocuments control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel FindDocuments; - - /// - /// Search control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::Umbraco.Web.UI.Umbraco.Search.QuickSearch Search; - - /// - /// treeWindow control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel treeWindow; - - /// - /// JTree control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.controls.Tree.TreeControl JTree; - - /// - /// PlaceHolderAppIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel PlaceHolderAppIcons; - - /// - /// plcIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal plcIcons; - - /// - /// bubbleText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder bubbleText; - } -} diff --git a/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx b/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx deleted file mode 100644 index 7aa26dda00..0000000000 --- a/src/Umbraco.Web.UI/umbraco/cacheBrowser.aspx +++ /dev/null @@ -1,16 +0,0 @@ -<%@ Page language="c#" Codebehind="cacheBrowser.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.cacheBrowser" trace="true" %> - - - - cacheBrowser - - - - - - -
    - -
    - - diff --git a/src/Umbraco.Web.UI/umbraco/create.aspx b/src/Umbraco.Web.UI/umbraco/create.aspx deleted file mode 100644 index 782b7f178d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/create.aspx +++ /dev/null @@ -1,43 +0,0 @@ -<%@ Page Language="c#" MasterPageFile="masterpages/umbracoDialog.Master" Codebehind="CreateDialog.aspx.cs" AutoEventWireup="True" Inherits="Umbraco.Web.UI.Umbraco.CreateDialog" %> -<%@ Register Namespace="umbraco" TagPrefix="umb" Assembly="umbraco" %> - - - - - - - - - -
    -

    - The current user does not have access to create this type of object -

    -
    -
    -
    - - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/dashboard.aspx b/src/Umbraco.Web.UI/umbraco/dashboard.aspx deleted file mode 100644 index 91a4de4c0d..0000000000 --- a/src/Umbraco.Web.UI/umbraco/dashboard.aspx +++ /dev/null @@ -1,11 +0,0 @@ -<%@ Page language="c#" MasterPageFile="masterpages/umbracoPage.Master" Title="dashboard" Codebehind="dashboard.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.dashboard" trace="false" validateRequest="false"%> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> - - - -
    - -
    -
    - -
    \ No newline at end of file diff --git a/src/Umbraco.Web.UI/umbraco/editContent.aspx b/src/Umbraco.Web.UI/umbraco/editContent.aspx deleted file mode 100644 index 8c7ec1317f..0000000000 --- a/src/Umbraco.Web.UI/umbraco/editContent.aspx +++ /dev/null @@ -1,62 +0,0 @@ -<%@ Page Title="Edit content" Language="c#" MasterPageFile="masterpages/umbracoPage.Master" - CodeBehind="editContent.aspx.cs" ValidateRequest="false" AutoEventWireup="True" - Inherits="umbraco.cms.presentation.editContent" Trace="false" %> - -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - - - - - - - - -
    - - -
    - - - -
    diff --git a/src/Umbraco.Web.UI/umbraco/editMedia.aspx b/src/Umbraco.Web.UI/umbraco/editMedia.aspx deleted file mode 100644 index 50368f0cd7..0000000000 --- a/src/Umbraco.Web.UI/umbraco/editMedia.aspx +++ /dev/null @@ -1,28 +0,0 @@ -<%@ Page Language="c#" CodeBehind="editMedia.aspx.cs" ValidateRequest="false" MasterPageFile="masterpages/umbracoPage.Master" - AutoEventWireup="True" Inherits="umbraco.cms.presentation.editMedia" %> - - - - - - - - - diff --git a/src/Umbraco.Web.UI/umbraco/login.aspx b/src/Umbraco.Web.UI/umbraco/login.aspx deleted file mode 100644 index 5d299e9e0c..0000000000 --- a/src/Umbraco.Web.UI/umbraco/login.aspx +++ /dev/null @@ -1,129 +0,0 @@ -<%@ Page Language="c#" CodeBehind="login.aspx.cs" AutoEventWireup="True" Inherits="umbraco.cms.presentation.login" %> - -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register Namespace="umbraco" TagPrefix="umb" Assembly="umbraco" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - Login - Umbraco - <%=Request.Url.Host.ToLower().Replace("www.", "") %> - - - - - - - - -
    - -
    -

    - -

    - - - - - - - - - - - - - - - - - - -
    - - - -
    -
    - - - -
    -
    - -
    -
    -
    - - - - - - - - - - - - - diff --git a/src/Umbraco.Web.UI/umbraco/logout.aspx b/src/Umbraco.Web.UI/umbraco/logout.aspx deleted file mode 100644 index 41289b10d2..0000000000 --- a/src/Umbraco.Web.UI/umbraco/logout.aspx +++ /dev/null @@ -1,18 +0,0 @@ -<%@ Page language="c#" Codebehind="logout.aspx.cs" AutoEventWireup="True" Inherits="umbraco.logout" %> - - - - - logout - - - - - - - -
    -
    - - - diff --git a/src/Umbraco.Web.UI/umbraco/umbraco.aspx b/src/Umbraco.Web.UI/umbraco/umbraco.aspx deleted file mode 100644 index 0bcb810d20..0000000000 --- a/src/Umbraco.Web.UI/umbraco/umbraco.aspx +++ /dev/null @@ -1,399 +0,0 @@ -<%@ Page Trace="false" Language="c#" CodeBehind="umbraco.aspx.cs" AutoEventWireup="True" - Inherits="Umbraco.Web.UI.Umbraco.Umbraco" %> - -<%@ Import Namespace="System.Web.Script.Serialization" %> - -<%@ Register Src="controls/Tree/TreeControl.ascx" TagName="TreeControl" TagPrefix="umbraco" %> -<%@ Import Namespace="StackExchange.Profiling" %> -<%@ Import Namespace="Umbraco.Core.Profiling" %> -<%@ Import Namespace="Umbraco.Web" %> -<%@ Register TagPrefix="cc1" Namespace="umbraco.uicontrols" Assembly="controls" %> -<%@ Register TagPrefix="uc1" TagName="quickSearch" Src="Search/QuickSearch.ascx" %> -<%@ Register TagPrefix="umb" Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" %> - - - - Umbraco CMS - - <%=Request.Url.Host.ToLower().Replace("www.", "") %> - - " /> - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - - - - - - -
    -
    - -
    -
    - -
    - -
    - -
    -
    -
    - - - -
    -
    -
    - -   -
    -
    - - - - -
      - -
    -
    -
    -
    - - -
    -
    - -
    -
    -
    -
    -
    - × -
    - -
    -
    - - - <%if(string.IsNullOrEmpty(Request["umbDebug"]) == false && umbraco.GlobalSettings.DebugMode) - { - Response.Write(Html.RenderProfiler()); - }%> - - diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 689715fc24..cd713f4daa 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -691,9 +691,6 @@
    - - ASPXCodeBehind - ASPXCodeBehind @@ -706,21 +703,9 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -728,12 +713,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -1558,9 +1537,6 @@ True Resources.resx - - Code - default.aspx ASPXCodeBehind @@ -1632,12 +1608,6 @@ XmlTree.xsd - - ASPXCodeBehind - - - Code - EditUser.aspx diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs deleted file mode 100644 index 0e923ffc03..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/cacheBrowser.aspx.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Collections; -using umbraco.BasePages; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for cacheBrowser. - /// - public partial class cacheBrowser : UmbracoEnsuredPage - { - public cacheBrowser() - { - CurrentApp = BusinessLogic.DefaultApps.developer.ToString(); - - } - protected void Page_Load(object sender, System.EventArgs e) - { - // Cache removal checks - if (Request.QueryString["clearByType"] != null) - ApplicationContext.ApplicationCache.ClearCacheObjectTypes(Request.QueryString["clearByType"]); - else if (Request.QueryString["clearByKey"] != null) - ApplicationContext.ApplicationCache.ClearCacheItem(Request.QueryString["clearByKey"]); - - // Put user code to initialize the page here - Hashtable ht = cms.businesslogic.cache.Cache.ReturnCacheItemsOrdred(); - foreach (string key in ht.Keys) - { - Response.Write("" + key + ": " + ((ArrayList)ht[key]).Count.ToString() + " (Delete)
    "); - if (Request.QueryString["key"] == key) - for (int i = 0; i < ((ArrayList)ht[key]).Count; i++) - Response.Write(" - " + ((ArrayList)ht[key])[i] + " (Delete)
    "); - } - } - protected void Button1_Click(object sender, System.EventArgs e) - { - ApplicationContext.ApplicationCache.ClearAllCache(); - } - - protected System.Web.UI.HtmlControls.HtmlForm Form1; - protected System.Web.UI.WebControls.Button Button1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs deleted file mode 100644 index c8ec4a581d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/create.aspx.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -using System.Xml; -using Umbraco.Core.IO; - -namespace umbraco.cms.presentation -{ - public class Create : BasePages.UmbracoEnsuredPage - { - [Obsolete("This property is no longer used")] - protected umbWindow createWindow; - protected Label helpText; - protected TextBox rename; - protected Label Label1; - protected ListBox nodeType; - protected PlaceHolder UI; - - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - - // Load create definitions - var nodeType = Request.QueryString["nodeType"]; - - var createDef = new XmlDocument(); - var defReader = new XmlTextReader(IOHelper.MapPath(SystemFiles.CreateUiXml)); - createDef.Load(defReader); - defReader.Close(); - - // Find definition for current nodeType - var def = createDef.SelectSingleNode("//nodeType [@alias = '" + nodeType + "']"); - if (def == null) - { - throw new ArgumentException("The create dialog for \"" + nodeType + "\" does not match anything defined in the \"" + SystemFiles.CreateUiXml + "\". This could mean an incorrectly installed package or a corrupt UI file"); - } - - try - { - var virtualPath = SystemDirectories.Umbraco + def.SelectSingleNode("./usercontrol").FirstChild.Value; - var mainControl = LoadControl(virtualPath); - UI.Controls.Add(mainControl); - } - catch (Exception ex) - { - throw new ArgumentException("ERROR CREATING CONTROL FOR NODETYPE: " + nodeType, ex); - } - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs deleted file mode 100644 index ee3798c660..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dashboard.aspx.cs +++ /dev/null @@ -1,377 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Reflection; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using System.IO; -using System.Xml; -using System.Xml.XPath; -using umbraco.uicontrols; -using umbraco.IO; -using umbraco.cms.helpers; -using umbraco.BusinessLogic; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for dashboard. - /// - /// - - public partial class dashboard : BasePages.UmbracoEnsuredPage - { - - - private string _section = ""; - - protected void Page_Load(object sender, System.EventArgs e) - { - // Put user code to initialize the page here - Panel2.Text = ui.Text("dashboard", "welcome", UmbracoUser) + " " + UmbracoUser.Name; - } - - private Control CreateDashBoardWrapperControl(Control control) - { - PlaceHolder placeHolder = new PlaceHolder(); - placeHolder.Controls.Add(new LiteralControl("
    ")); - placeHolder.Controls.Add(control); - placeHolder.Controls.Add(new LiteralControl("
    ")); - return placeHolder; - } - - override protected void OnInit(EventArgs e) - { - - base.OnInit(e); - - /* - // Load dashboard content - if (helper.Request("app") != "") - _section = helper.Request("app"); - else if (getUser().Applications.Length > 0) - _section = "default"; - else - _section = getUser().Applications[0].alias; - - XmlDocument dashBoardXml = new XmlDocument(); - dashBoardXml.Load(IOHelper.MapPath(SystemFiles.DashboardConfig)); - - var control = dashBoardXml.DocumentElement.SelectSingleNode("//control [areas/area = '" + _section.ToLower() + "']"); - */ - /* - // test for new tab interface - foreach (XmlNode section in dashBoardXml.DocumentElement.SelectNodes("//section [areas/area = '" + _section.ToLower() + "']")) - { - if (section != null && validateAccess(section)) - { - Panel2.Visible = false; - dashboardTabs.Visible = true; - - foreach (XmlNode entry in section.SelectNodes("./tab")) - { - if (validateAccess(entry)) - { - TabPage tab = dashboardTabs.NewTabPage(entry.Attributes.GetNamedItem("caption").Value); - tab.HasMenu = true; - tab.Style.Add("padding", "0 10px"); - - foreach (XmlNode uc in entry.SelectNodes("./control")) - { - if (validateAccess(uc)) - { - string control = getFirstText(uc).Trim(' ', '\r', '\n'); - string path = IOHelper.FindFile(control); - - - try - { - Control c = LoadControl(path); - - // set properties - Type type = c.GetType(); - if (type != null) - { - foreach (XmlAttribute att in uc.Attributes) - { - string attributeName = att.Name; - string attributeValue = parseControlValues(att.Value).ToString(); - // parse special type of values - - - PropertyInfo prop = type.GetProperty(attributeName); - if (prop == null) - { - continue; - } - - prop.SetValue(c, Convert.ChangeType(attributeValue, prop.PropertyType), - null); - - } - } - - //resolving files from dashboard config which probably does not map to a virtual fi - tab.Controls.Add(AddPanel(uc, c)); - } - catch (Exception ee) - { - tab.Controls.Add( - new LiteralControl( - "

    Could not load control: '" + path + - "'.
    Error message: " + - ee.ToString() + "

    ")); - } - } - } - } - } - } - else - { - - - foreach ( - XmlNode entry in dashBoardXml.SelectNodes("//entry [@section='" + _section.ToLower() + "']")) - { - PlaceHolder placeHolder = new PlaceHolder(); - if (entry == null || entry.FirstChild == null) - { - placeHolder.Controls.Add( - CreateDashBoardWrapperControl(new LiteralControl("Error loading DashBoard Content"))); - } - else - { - string path = IOHelper.FindFile(entry.FirstChild.Value); - - try - { - placeHolder.Controls.Add(CreateDashBoardWrapperControl(LoadControl(path))); - } - catch (Exception err) - { - Trace.Warn("Dashboard", string.Format("error loading control '{0}'", - path), err); - placeHolder.Controls.Clear(); - placeHolder.Controls.Add(CreateDashBoardWrapperControl(new LiteralControl(string.Format( - "Error loading DashBoard Content '{0}'; {1}", path, - err.Message)))); - } - } - dashBoardContent.Controls.Add(placeHolder); - } - } - }*/ - } - - private object parseControlValues(string value) - { - if (!String.IsNullOrEmpty(value)) - { - if (value.StartsWith("[#")) - { - value = value.Substring(2, value.Length - 3).ToLower(); - switch (value) - { - case "usertype": - return BusinessLogic.User.GetCurrent().UserType.Alias; - case "username": - return BusinessLogic.User.GetCurrent().Name; - case "userlogin": - return BusinessLogic.User.GetCurrent().LoginName; - case "usercontentstartnode": - return BusinessLogic.User.GetCurrent().StartNodeId; - case "usermediastartnode": - return BusinessLogic.User.GetCurrent().StartMediaId; - default: - return value; - } - } - } - - return value; - } - - private Control AddPanel(XmlNode node, Control c) - { - LiteralControl hide = AddShowOnceLink(node); - if (node.Attributes.GetNamedItem("addPanel") != null && - node.Attributes.GetNamedItem("addPanel").Value == "true") - { - Pane p = new Pane(); - PropertyPanel pp = new PropertyPanel(); - if (node.Attributes.GetNamedItem("panelCaption") != null && - !String.IsNullOrEmpty(node.Attributes.GetNamedItem("panelCaption").Value)) - { - string panelCaption = node.Attributes.GetNamedItem("panelCaption").Value; - if (panelCaption.StartsWith("#")) - { - panelCaption = ui.Text(panelCaption.Substring(1)); - } - pp.Text = panelCaption; - } - // check for hide in the future link - if (!String.IsNullOrEmpty(hide.Text)) - { - pp.Controls.Add(hide); - } - pp.Controls.Add(c); - p.Controls.Add(pp); - return p; - } - - if (!String.IsNullOrEmpty(hide.Text)) - { - PlaceHolder ph = new PlaceHolder(); - ph.Controls.Add(hide); - ph.Controls.Add(c); - return ph; - } - else - { - return c; - } - } - - private LiteralControl AddShowOnceLink(XmlNode node) - { - LiteralControl onceLink = new LiteralControl(); - if (node.Attributes.GetNamedItem("showOnce") != null && - node.Attributes.GetNamedItem("showOnce").Value.ToLower() == "true") - { - onceLink.Text = "" + ui.Text("dashboard", "dontShowAgain") + ""; - } - return onceLink; - } - - private string getFirstText(XmlNode node) - { - foreach (XmlNode n in node.ChildNodes) - { - if (n.NodeType == XmlNodeType.Text) - return n.Value; - } - - return ""; - } - - private string generateCookieKey(XmlNode node) - { - string key = String.Empty; - if (node.Name.ToLower() == "control") - { - key = node.FirstChild.Value + "_" + generateCookieKey(node.ParentNode); - } - else if (node.Name.ToLower() == "tab") - { - key = node.Attributes.GetNamedItem("caption").Value; - } - - return Casing.SafeAlias(key.ToLower()); - } - - private bool validateAccess(XmlNode node) - { - // check if this area should be shown at all - string onlyOnceValue = StateHelper.GetCookieValue(generateCookieKey(node)); - if (!String.IsNullOrEmpty(onlyOnceValue)) - { - return false; - } - - // the root user can always see everything - if (CurrentUser.IsRoot()) - { - return true; - } - else if (node != null) - { - XmlNode accessRules = node.SelectSingleNode("access"); - bool retVal = true; - if (accessRules != null && accessRules.HasChildNodes) - { - string currentUserType = CurrentUser.UserType.Alias.ToLowerInvariant(); - - //Update access rules so we'll be comparing lower case to lower case always - - var denies = accessRules.SelectNodes("deny"); - foreach (XmlNode deny in denies) - { - deny.InnerText = deny.InnerText.ToLowerInvariant(); - } - - var grants = accessRules.SelectNodes("grant"); - foreach (XmlNode grant in grants) - { - grant.InnerText = grant.InnerText.ToLowerInvariant(); - } - - string allowedSections = ","; - foreach (BusinessLogic.Application app in CurrentUser.Applications) - { - allowedSections += app.alias.ToLower() + ","; - } - XmlNodeList grantedTypes = accessRules.SelectNodes("grant"); - XmlNodeList grantedBySectionTypes = accessRules.SelectNodes("grantBySection"); - XmlNodeList deniedTypes = accessRules.SelectNodes("deny"); - - // if there's a grant type, everyone who's not granted is automatically denied - if (grantedTypes.Count > 0 || grantedBySectionTypes.Count > 0) - { - retVal = false; - if (grantedBySectionTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("grantBySection [contains('{0}', concat(',',.,','))]", allowedSections)) != null) - { - retVal = true; - } - else if (grantedTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("grant [. = '{0}']", currentUserType)) != null) - { - retVal = true; - } - } - // if the current type of user is denied we'll say nay - if (deniedTypes.Count > 0 && accessRules.SelectSingleNode(String.Format("deny [. = '{0}']", currentUserType)) != null) - { - retVal = false; - } - - } - - return retVal; - } - return false; - } - - /// - /// Panel2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel Panel2; - - /// - /// dashBoardContent control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder dashBoardContent; - - /// - /// dashboardTabs control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.TabView dashboardTabs; - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs deleted file mode 100644 index 60a6f9048b..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ /dev/null @@ -1,642 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Caching; -using Umbraco.Core.IO; -using Umbraco.Core.Publishing; -using Umbraco.Core.Services; -using umbraco.BusinessLogic.Actions; -using umbraco.uicontrols.DatePicker; -using umbraco.BusinessLogic; -using umbraco.cms.businesslogic.web; -using umbraco.presentation; -using System.Linq; -using Image = System.Web.UI.WebControls.Image; -using Umbraco.Core; - -namespace umbraco.cms.presentation -{ - public class editContent : BasePages.UmbracoEnsuredPage - { - protected uicontrols.TabView TabView1; - protected TextBox documentName; - private Document _document; - private bool _documentHasPublishedVersion = false; - protected Literal jsIds; - private readonly LiteralControl _dp = new LiteralControl(); - private readonly DateTimePicker _dpRelease = new DateTimePicker(); - private readonly DateTimePicker _dpExpire = new DateTimePicker(); - - private controls.ContentControl _cControl; - - private readonly DropDownList _ddlDefaultTemplate = new DropDownList(); - - private readonly uicontrols.Pane _publishProps = new uicontrols.Pane(); - private readonly uicontrols.Pane _linkProps = new uicontrols.Pane(); - - private readonly Button _unPublish = new Button(); - private readonly Literal _littPublishStatus = new Literal(); - - private controls.ContentControl.publishModes _canPublish = controls.ContentControl.publishModes.Publish; - - private int? _contentId = null; - - override protected void OnInit(EventArgs e) - { - base.OnInit(e); - - //validate! - int id; - if (int.TryParse(Request.QueryString["id"], out id) == false) - { - //if this is invalid show an error - this.DisplayFatalError("Invalid query string"); - return; - } - _contentId = id; - - - _unPublish.Click += UnPublishDo; - - //Loading Content via new public service to ensure that the Properties are loaded correct - var content = ApplicationContext.Current.Services.ContentService.GetById(id); - _document = new Document(content); - - //check if the doc exists - if (string.IsNullOrEmpty(_document.Path)) - { - //if this is invalid show an error - this.DisplayFatalError("No document found with id " + _contentId); - //reset the content id to null so processing doesn't continue on OnLoad - _contentId = null; - return; - } - - // we need to check if there's a published version of this document - _documentHasPublishedVersion = _document.Content.HasPublishedVersion(); - - // Check publishing permissions - if (!UmbracoUser.GetPermissions(_document.Path).Contains(ActionPublish.Instance.Letter.ToString())) - { - // Check to see if the user has send to publish permissions - if (!UmbracoUser.GetPermissions(_document.Path).Contains(ActionToPublish.Instance.Letter.ToString())) - { - //If no send to publish permission then revert to NoPublish mode - _canPublish = controls.ContentControl.publishModes.NoPublish; - } - else - { - _canPublish = controls.ContentControl.publishModes.SendToPublish; - } - } - - _cControl = new controls.ContentControl(_document, _canPublish, "TabView1"); - - _cControl.ID = "TabView1"; - - _cControl.Width = Unit.Pixel(666); - _cControl.Height = Unit.Pixel(666); - - // Add preview button - - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - AddPreviewButton(tp.Menu, _document.Id); - } - - plc.Controls.Add(_cControl); - - - var publishStatus = new PlaceHolder(); - if (_documentHasPublishedVersion) - { - _littPublishStatus.Text = ui.Text("content", "lastPublished", UmbracoUser) + ": " + _document.VersionDate.ToShortDateString() + "   "; - - publishStatus.Controls.Add(_littPublishStatus); - if (UmbracoUser.GetPermissions(_document.Path).IndexOf("U") > -1) - _unPublish.Visible = true; - else - _unPublish.Visible = false; - } - else - { - _littPublishStatus.Text = ui.Text("content", "itemNotPublished", UmbracoUser); - publishStatus.Controls.Add(_littPublishStatus); - _unPublish.Visible = false; - } - - _unPublish.Text = ui.Text("content", "unPublish", UmbracoUser); - _unPublish.ID = "UnPublishButton"; - _unPublish.Attributes.Add("onClick", "if (!confirm('" + ui.Text("defaultdialogs", "confirmSure", UmbracoUser) + "')) return false; "); - publishStatus.Controls.Add(_unPublish); - - _publishProps.addProperty(ui.Text("content", "publishStatus", UmbracoUser), publishStatus); - - // Template - var template = new PlaceHolder(); - var documentType = new DocumentType(_document.ContentType.Id); - _cControl.PropertiesPane.addProperty(ui.Text("documentType"), new LiteralControl(documentType.Text)); - - - //template picker - _cControl.PropertiesPane.addProperty(ui.Text("template"), template); - int defaultTemplate; - if (_document.Template != 0) - defaultTemplate = _document.Template; - else - defaultTemplate = documentType.DefaultTemplate; - - if (UmbracoUser.UserType.Name == "writer") - { - if (defaultTemplate != 0) - template.Controls.Add(new LiteralControl(businesslogic.template.Template.GetTemplate(defaultTemplate).Text)); - else - template.Controls.Add(new LiteralControl(ui.Text("content", "noDefaultTemplate"))); - } - else - { - _ddlDefaultTemplate.Items.Add(new ListItem(ui.Text("choose") + "...", "")); - foreach (var t in documentType.allowedTemplates) - { - - var tTemp = new ListItem(t.Text, t.Id.ToString()); - if (t.Id == defaultTemplate) - tTemp.Selected = true; - _ddlDefaultTemplate.Items.Add(tTemp); - } - template.Controls.Add(_ddlDefaultTemplate); - } - - - // Editable update date, release date and expire date added by NH 13.12.04 - _dp.ID = "updateDate"; - _dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); - _publishProps.addProperty(ui.Text("content", "updateDate", UmbracoUser), _dp); - - _dpRelease.ID = "releaseDate"; - _dpRelease.DateTime = _document.ReleaseDate; - _dpRelease.ShowTime = true; - _publishProps.addProperty(ui.Text("content", "releaseDate", UmbracoUser), _dpRelease); - - _dpExpire.ID = "expireDate"; - _dpExpire.DateTime = _document.ExpireDate; - _dpExpire.ShowTime = true; - _publishProps.addProperty(ui.Text("content", "expireDate", UmbracoUser), _dpExpire); - - _cControl.Save += Save; - _cControl.SaveAndPublish += Publish; - _cControl.SaveToPublish += SendToPublish; - - // Add panes to property page... - _cControl.tpProp.Controls.AddAt(1, _publishProps); - _cControl.tpProp.Controls.AddAt(2, _linkProps); - - // add preview to properties pane too - AddPreviewButton(_cControl.tpProp.Menu, _document.Id); - - - } - - protected void Page_Load(object sender, EventArgs e) - { - if (!_contentId.HasValue) - return; - - if (!CheckUserValidation()) - return; - - // clear preview cookie - // zb-00004 #29956 : refactor cookies names & handling - StateHelper.Cookies.Preview.Clear(); - - if (!IsPostBack) - { - - Log.Add(LogTypes.Open, UmbracoUser, _document.Id, ""); - ClientTools.SyncTree(_document.Path, false); - } - - - jsIds.Text = "var umbPageId = " + _document.Id.ToString() + ";\nvar umbVersionId = '" + _document.Version.ToString() + "';\n"; - - } - - protected override void OnPreRender(EventArgs e) - { - base.OnPreRender(e); - UpdateNiceUrls(); - } - - /// - /// Handles the Save event for the ContentControl. - /// - /// - /// - /// - /// This will set the document's properties and persist a new document revision - /// - protected void Save(object sender, EventArgs e) - { - //NOTE: This is only here because we have to keep backwards compatibility with events in the ContentControl. - // see: http://issues.umbraco.org/issue/U4-1660 - // in this case both Save and SaveAndPublish will fire when we are publishing but we only want to handle that once, - // so if this is actually doing a publish, we'll exit and rely on the SaveAndPublish handler to do all the work. - if (_cControl.DoesPublish) - { - return; - } - - //update UI and set document properties - PerformSaveLogic(); - - //persist the document - _document.Save(); - - // Run Handler - BusinessLogic.Actions.Action.RunActionHandlers(_document, ActionUpdate.Instance); - - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSavedHeader"), - ui.Text("speechBubbles", "editContentSavedText")); - - ClientTools.SyncTree(_document.Path, true); - } - - /// - /// Handles the SendToPublish event - /// - /// - /// - protected void SendToPublish(object sender, EventArgs e) - { - if (Page.IsValid) - { - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, ui.Text("speechBubbles", "editContentSendToPublish", UmbracoUser), - ui.Text("speechBubbles", "editContentSendToPublishText", UmbracoUser)); - _document.SendToPublication(UmbracoUser); - } - } - - /// - /// Handles the SaveAndPublish event - /// - /// - /// - /// - /// Sets the document's properties and if the page is valid continues to publish it, otherwise just saves a revision. - /// - protected void Publish(object sender, EventArgs e) - { - //update UI and set document properties - PerformSaveLogic(); - - //the business logic here will check to see if the doc can actually be published and will return the - // appropriate result so we can display the correct error messages (or success). - var savePublishResult = _document.SaveAndPublishWithResult(UmbracoUser); - - ShowMessageForStatus(savePublishResult.Result); - - if (savePublishResult.Success) - { - _littPublishStatus.Text = string.Format("{0}: {1}
    ", ui.Text("content", "lastPublished", UmbracoUser), _document.VersionDate.ToString()); - - if (UmbracoUser.GetPermissions(_document.Path).IndexOf("U") > -1) - { - _unPublish.Visible = true; - } - - _documentHasPublishedVersion = _document.Content.HasPublishedVersion(); - } - - ClientTools.SyncTree(_document.Path, true); - } - - private void ShowMessageForStatus(PublishStatus status) - { - switch (status.StatusType) - { - case PublishStatusType.Success: - case PublishStatusType.SuccessAlreadyPublished: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.save, - ui.Text("speechBubbles", "editContentPublishedHeader", UmbracoUser), - ui.Text("speechBubbles", "editContentPublishedText", UmbracoUser)); - break; - case PublishStatusType.FailedPathNotPublished: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("publish", "contentPublishedFailedByParent", - string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), - UmbracoUser).Trim()); - break; - case PublishStatusType.FailedCancelledByEvent: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("speechBubbles", "contentPublishedFailedByEvent")); - break; - case PublishStatusType.FailedHasExpired: - case PublishStatusType.FailedAwaitingRelease: - case PublishStatusType.FailedIsTrashed: - case PublishStatusType.FailedContentInvalid: - ClientTools.ShowSpeechBubble( - speechBubbleIcon.warning, - ui.Text("publish"), - ui.Text("publish", "contentPublishedFailedInvalid", - new[] - { - string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), - string.Join(",", status.InvalidProperties.Select(x => x.Alias)) - }, - UmbracoUser).Trim()); - break; - default: - throw new IndexOutOfRangeException(); - } - } - - protected void UnPublishDo(object sender, EventArgs e) - { - _document.UnPublish(); - _littPublishStatus.Text = ui.Text("content", "itemNotPublished", UmbracoUser); - _unPublish.Visible = false; - _documentHasPublishedVersion = false; - - //library.UnPublishSingleNode(_document.Id); - - Current.ClientTools.SyncTree(_document.Path, true); - ClientTools.ShowSpeechBubble(speechBubbleIcon.success, ui.Text("unpublish"), ui.Text("speechBubbles", "contentUnpublished")); - - //newPublishStatus.Text = "0"; - } - - void UpdateNiceUrlProperties(string niceUrlText, string altUrlsText) - { - _linkProps.Controls.Clear(); - - var lit = new Literal(); - lit.Text = niceUrlText; - _linkProps.addProperty(ui.Text("content", "urls", UmbracoUser), lit); - - if (!string.IsNullOrWhiteSpace(altUrlsText)) - { - lit = new Literal(); - lit.Text = altUrlsText; - _linkProps.addProperty(ui.Text("content", "alternativeUrls", UmbracoUser), lit); - } - } - - void UpdateNiceUrls() - { - if (_documentHasPublishedVersion == false) - { - UpdateNiceUrlProperties("" + ui.Text("content", "itemNotPublished", UmbracoUser) + "", null); - return; - } - - var urlProvider = Umbraco.Web.UmbracoContext.Current.RoutingContext.UrlProvider; - var url = urlProvider.GetUrl(_document.Id); - string niceUrlText = null; - var altUrlsText = new System.Text.StringBuilder(); - - if (url == "#") - { - // document as a published version yet it's url is "#" => a parent must be - // unpublished, walk up the tree until we find it, and report. - var parent = _document; - do - { - parent = parent.ParentId > 0 ? new Document(parent.ParentId) : null; - } - while (parent != null && parent.Published); - - if (parent == null) // oops - internal error - niceUrlText = "" + ui.Text("content", "parentNotPublishedAnomaly", UmbracoUser) + ""; - else - niceUrlText = "" + ui.Text("content", "parentNotPublished", parent.Text, UmbracoUser) + ""; - } - else - { - niceUrlText = string.Format("{0}", url); - - foreach (var otherUrl in urlProvider.GetOtherUrls(_document.Id)) - altUrlsText.AppendFormat("{0}
    ", otherUrl); - } - - UpdateNiceUrlProperties(niceUrlText, altUrlsText.ToString()); - } - - /// - /// When a document is saved or published all of this logic must be performed. - /// - /// - /// This updates both UI controls and business logic object properties but does not persist any data to - /// business logic repositories. - /// - private void PerformSaveLogic() - { - // error handling test - if (!Page.IsValid) - { - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - tp.ErrorControl.Visible = true; - tp.ErrorHeader = ui.Text("errorHandling", "errorButDataWasSaved"); - tp.CloseCaption = ui.Text("close"); - } - } - else if (Page.IsPostBack) - { - // hide validation summaries - foreach (uicontrols.TabPage tp in _cControl.GetPanels()) - { - tp.ErrorControl.Visible = false; - } - } - - if (_dpRelease.DateTime > new DateTime(1753, 1, 1) && _dpRelease.DateTime < new DateTime(9999, 12, 31)) - _document.ReleaseDate = _dpRelease.DateTime; - else - _document.ReleaseDate = new DateTime(1, 1, 1, 0, 0, 0); - if (_dpExpire.DateTime > new DateTime(1753, 1, 1) && _dpExpire.DateTime < new DateTime(9999, 12, 31)) - _document.ExpireDate = _dpExpire.DateTime; - else - _document.ExpireDate = new DateTime(1, 1, 1, 0, 0, 0); - - // Update default template - if (_ddlDefaultTemplate.SelectedIndex > 0) - { - _document.Template = int.Parse(_ddlDefaultTemplate.SelectedValue); - } - else - { - if (new DocumentType(_document.ContentType.Id).allowedTemplates.Length == 0) - { - _document.RemoveTemplate(); - } - } - - //The value of the properties has been set on IData through IDataEditor in the ContentControl - //so we need to 'retrieve' that value and set it on the property of the new IContent object. - //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property - //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). - foreach (var item in _cControl.DataTypes) - { - _document.getProperty(item.Key).Value = item.Value.Data.Value; - } - - // Update the update date - _dp.Text = _document.UpdateDate.ToShortDateString() + " " + _document.UpdateDate.ToShortTimeString(); - } - - /// - /// Clears the page of all controls and shows a simple message. Used if users don't have visible access to the page. - /// - /// - private void ShowUserValidationError(string message) - { - this.Controls.Clear(); - this.Controls.Add(new LiteralControl(String.Format("

    Access denied

    Access denied{0}
    ", message))); - } - - /// - /// Checks if the user cannot view/browse this page/app and displays an html message to the user if this is not the case. - /// - /// - private bool CheckUserValidation() - { - // Validate permissions - if (!base.ValidateUserApp(Constants.Applications.Content)) - { - ShowUserValidationError("

    The current user doesn't have access to this application

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - if (!ValidateUserNodeTreePermissions(_document.Path, ActionBrowse.Instance.Letter.ToString())) - { - ShowUserValidationError( - "

    The current user doesn't have permissions to browse this document

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - //TODO: Change this, when we add view capabilities, the user will be able to view but not edit! - if (!ValidateUserNodeTreePermissions(_document.Path, ActionUpdate.Instance.Letter.ToString())) - { - ShowUserValidationError("

    The current user doesn't have permissions to edit this document

    Please contact the system administrator if you think that you should have access.

    "); - return false; - } - return true; - } - - private void AddPreviewButton(uicontrols.ScrollingMenu menu, int id) - { - uicontrols.MenuIconI menuItem; - - // Find the first splitter in the Menu - Should be the rte toolbar's splitter - var startIndex = menu.FindSplitter(1); - - if (startIndex == -1) - { - // No Splitter found - rte toolbar isn't loaded - menu.InsertSplitter(); - menuItem = menu.NewIcon(); - } - else - { - // Rte toolbar is loaded, inject after it's Splitter - menuItem = menu.NewIcon(startIndex + 1); - menu.InsertSplitter(startIndex + 2); - } - - menuItem.ImageURL = SystemDirectories.Umbraco + "/images/editor/vis.gif"; - - if (EnablePreviewButton()) - { - menuItem.AltText = ui.Text("buttons", "showPage", UmbracoUser); - menuItem.OnClickCommand = "window.open('dialogs/preview.aspx?id=" + id + "','umbPreview')"; - } - else - { - var showPageDisabledText = ui.Text("buttons", "showPageDisabled", UmbracoUser); - if (showPageDisabledText.StartsWith("[")) - showPageDisabledText = ui.GetText("buttons", "showPageDisabled", null, "en"); - - menuItem.AltText = showPageDisabledText; - ((Image) menuItem).Attributes.Add("style", "opacity: 0.5"); - } - } - - private bool EnablePreviewButton() - { - // Fix for U4-862, if there's no template, disable the preview button - // Fixed again for U4-2587, apparently at some point "no template" changed from -1 to 0? -SJ - // Now also catches when template doesn't exist any more or is not allowed any more - // Don't think there's a better way to check if the template exists besides trying to instantiate it.. - try - { - var template = new businesslogic.template.Template(_document.Template); - // If template is found check if it's in the list of allowed templates for this document - return _document.Content.ContentType.AllowedTemplates.ToList().Any(t => t.Id == template.Id); - } - catch (Exception) { } - - return false; - } - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// plc control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder plc; - - /// - /// doSave control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doSave; - - /// - /// doPublish control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doPublish; - - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs deleted file mode 100644 index 0245097ce5..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editMedia.aspx.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Xml; -using Umbraco.Core; -using umbraco.cms.businesslogic.datatype.controls; -using System.Collections.Generic; -using System.Linq; -using System.IO; -using Umbraco.Core.IO; -using umbraco.cms.businesslogic.property; -using Umbraco.Core; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for editMedia. - /// - public partial class editMedia : BasePages.UmbracoEnsuredPage - { - private readonly uicontrols.Pane _mediaPropertiesPane = new uicontrols.Pane(); - private readonly LiteralControl _updateDateLiteral = new LiteralControl(); - private readonly LiteralControl _mediaFileLinksLiteral = new LiteralControl(); - - public editMedia() - { - CurrentApp = BusinessLogic.DefaultApps.media.ToString(); - } - - protected uicontrols.TabView TabView1; - protected TextBox documentName; - private businesslogic.media.Media _media; - controls.ContentControl _contentControl; - - override protected void OnInit(EventArgs e) - { - base.OnInit(e); - - int id = int.Parse(Request.QueryString["id"]); - - //Loading Media via new public service to ensure that the Properties are loaded correct - var media = ApplicationContext.Current.Services.MediaService.GetById(id); - _media = new cms.businesslogic.media.Media(media); - - // Save media on first load - bool exists = SqlHelper.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @nodeId", - SqlHelper.CreateParameter("@nodeId", _media.Id)) > 0; - if (!exists) - { - _media.XmlGenerate(new XmlDocument()); - } - - _contentControl = new controls.ContentControl(_media, controls.ContentControl.publishModes.NoPublish, "TabView1"); - _contentControl.Width = Unit.Pixel(666); - _contentControl.Height = Unit.Pixel(666); - - //this must be set to false as we don't want to proceed to save anything if the page is invalid - _contentControl.SavePropertyDataWhenInvalid = false; - - plc.Controls.Add(_contentControl); - - _contentControl.Save += new System.EventHandler(Save); - - this._updateDateLiteral.ID = "updateDate"; - this._updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString(); - - this._mediaFileLinksLiteral.ID = "mediaFileLinks"; - _mediaPropertiesPane.addProperty(ui.Text("content", "updateDate", base.getUser()), this._updateDateLiteral); - - this.UpdateMediaFileLinksLiteral(); - _mediaPropertiesPane.addProperty(ui.Text("content", "mediaLinks"), this._mediaFileLinksLiteral); - - // add the property pane to the page rendering - _contentControl.tpProp.Controls.AddAt(1, _mediaPropertiesPane); - } - - protected void Page_Load(object sender, System.EventArgs e) - { - if (!IsPostBack) - { - ClientTools.SyncTree(_media.Path, false); - } - } - - protected void Save(object sender, EventArgs e) - { - // do not continue saving anything if the page is invalid! - // http://issues.umbraco.org/issue/U4-227 - if (!Page.IsValid) - { - foreach (uicontrols.TabPage tp in _contentControl.GetPanels()) - { - tp.ErrorControl.Visible = true; - tp.ErrorHeader = ui.Text("errorHandling", "errorHeader"); - tp.CloseCaption = ui.Text("close"); - } - } - else - { - if (Page.IsPostBack) - { - // hide validation summaries - foreach (uicontrols.TabPage tp in _contentControl.GetPanels()) - { - tp.ErrorControl.Visible = false; - } - } - - //The value of the properties has been set on IData through IDataEditor in the ContentControl - //so we need to 'retrieve' that value and set it on the property of the new IContent object. - //NOTE This is a workaround for the legacy approach to saving values through the DataType instead of the Property - //- (The DataType shouldn't be responsible for saving the value - especically directly to the db). - foreach (var item in _contentControl.DataTypes) - { - _media.getProperty(item.Key).Value = item.Value.Data.Value; - } - - _media.Save(); - - this._updateDateLiteral.Text = _media.VersionDate.ToShortDateString() + " " + _media.VersionDate.ToShortTimeString(); - this.UpdateMediaFileLinksLiteral(); - - _media.XmlGenerate(new XmlDocument()); - ClientTools.ShowSpeechBubble(speechBubbleIcon.save, ui.Text("speechBubbles", "editMediaSaved"), ui.Text("editMediaSavedText")); - ClientTools.SyncTree(_media.Path, true); - } - } - - private void UpdateMediaFileLinksLiteral() - { - var uploadField = DataTypesResolver.Current.GetById(new Guid(Constants.PropertyEditors.UploadField)); - - // always clear, incase the upload file was removed - this._mediaFileLinksLiteral.Text = string.Empty; - - try - { - var uploadProperties = _media.GenericProperties - .Where(p => p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id - && p.Value.ToString() != "" - && File.Exists(IOHelper.MapPath(p.Value.ToString()))); - - var properties = uploadProperties as List ?? uploadProperties.ToList(); - - if (properties.Any()) - { - this._mediaFileLinksLiteral.Text += ""; - - foreach (var property in properties) - { - this._mediaFileLinksLiteral.Text += string.Format("", property.PropertyType.Name, property.Value); - } - - this._mediaFileLinksLiteral.Text += "
    {0} {1}
    "; - } - } - catch - { - //the data type definition may not exist anymore at this point because another thread may - //have deleted it. - } - } - - /// - /// plc control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder plc; - - /// - /// doSave control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doSave; - - /// - /// doPublish control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlInputHidden doPublish; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs deleted file mode 100644 index f5bb290d47..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/login.aspx.cs +++ /dev/null @@ -1,307 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Globalization; -using System.Security; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Membership; -using System.Web.Security; -using umbraco.businesslogic.Exceptions; -using umbraco.IO; -using umbraco.cms.businesslogic.web; -using System.Linq; -using Umbraco.Core; -using User = umbraco.BusinessLogic.User; - -namespace umbraco.cms.presentation -{ - /// - /// Summary description for login. - /// - [Obsolete("This class is no longer used and will be removed")] - public partial class login : BasePages.BasePage - { - [Obsolete("This property is no longer used")] - protected umbWindow treeWindow; - - protected override void OnLoad(EventArgs e) - { - base.OnLoad(e); - ClientLoader.DataBind(); - - // validate redirect url - string redirUrl = Request["redir"]; - if (!String.IsNullOrEmpty(redirUrl)) - { - validateRedirectUrl(redirUrl); - } - } - - - protected override void OnPreRender(EventArgs e) - { - base.OnPreRender(e); - Button1.Text = ui.Text("general", "login"); - Panel1.Text = ui.Text("general", "welcome"); - Panel1.Style.Add("padding", "10px;"); - username.Text = ui.Text("general", "username"); - password.Text = ui.Text("general", "password"); - - // Add bottom and top texts - TopText.Text = ui.Text("login", "topText"); - - - BottomText.Text = ui.Text("login", "bottomText", DateTime.Now.Year.ToString(CultureInfo.InvariantCulture)); - - //added this little hack to remove unessary formatting, without breaking all current language files. - if (BottomText.Text.Contains("

    ")) - BottomText.Text = BottomText.Text.Substring(29).Replace("
    ", "").Replace("

    ", ""); - } - - - protected void Button1_Click(object sender, System.EventArgs e) - { - // Authenticate users by using the provider specified in umbracoSettings.config - if (Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider].ValidateUser(lname.Text, passw.Text)) - { - if (Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider] is ActiveDirectoryMembershipProvider) - ActiveDirectoryMapping(lname.Text, Membership.Providers[UmbracoConfig.For.UmbracoSettings().Providers.DefaultBackOfficeUserProvider].GetUser(lname.Text, false).Email); - - var u = new User(lname.Text); - doLogin(u); - - if (hf_height.Value != "undefined") - { - Session["windowHeight"] = hf_height.Value; - Session["windowWidth"] = hf_width.Value; - } - - string redirUrl = Request["redir"]; - - if (string.IsNullOrEmpty(redirUrl)) - Response.Redirect("umbraco.aspx"); - else if (validateRedirectUrl(redirUrl)) - { - Response.Redirect(redirUrl, true); - } - } - else - { - loginError.Visible = true; - } - } - - private bool validateRedirectUrl(string url) - { - if (!isUrlLocalToHost(url)) - { - LogHelper.Info(String.Format("Security warning: Login redirect was attempted to a site at another domain: '{0}'", url)); - - throw new UserAuthorizationException( - String.Format(@"There was attempt to redirect to '{0}' which is another domain than where you've logged in. If you clicked a link to reach this login - screen, please double check that the link came from someone you trust. You *might* have been exposed to an *attempt* to breach the security of your website. Nothing - have been compromised, though!", url)); - } - - return true; - } - - private bool isUrlLocalToHost(string url) - { - if (String.IsNullOrEmpty(url)) - { - return false; - } - - Uri absoluteUri; - if (Uri.TryCreate(url, UriKind.Absolute, out absoluteUri)) - { - return String.Equals(HttpContext.Current.Request.Url.Host, absoluteUri.Host, - StringComparison.OrdinalIgnoreCase); - } - - bool isLocal = !url.StartsWith("http:", StringComparison.OrdinalIgnoreCase) - && !url.StartsWith("https:", StringComparison.OrdinalIgnoreCase) - && Uri.IsWellFormedUriString(url, UriKind.Relative); - return isLocal; - } - - /// - /// Maps active directory account to umbraco user account - /// - /// Name of the login. - /// Email address of the user - private void ActiveDirectoryMapping(string loginName, string email) - { - // Password is not copied over because it is stored in active directory for security! - // The user is create with default access to content and as a writer user type - if (BusinessLogic.User.getUserId(loginName) == -1) - { - BusinessLogic.User.MakeNew(loginName, loginName, string.Empty, email ?? "", BusinessLogic.UserType.GetUserType(2)); - var u = new User(loginName); - u.addApplication(Constants.Applications.Content); - } - } - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// Panel1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel Panel1; - - /// - /// TopText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal TopText; - - /// - /// username control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label username; - - /// - /// lname control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox lname; - - /// - /// password control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Label password; - - /// - /// passw control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.TextBox passw; - - /// - /// Button1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Button Button1; - - /// - /// BottomText control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal BottomText; - - /// - /// hf_height control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.HiddenField hf_height; - - /// - /// hf_width control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.HiddenField hf_width; - - /// - /// loginError control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.PlaceHolder loginError; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs deleted file mode 100644 index 15f8be030f..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/logout.aspx.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; - -namespace umbraco -{ - /// - /// Summary description for logout. - /// - public partial class logout : BasePages.BasePage - { - protected void Page_Load(object sender, System.EventArgs e) - { - // Put user code to initialize the page here - if (umbracoUserContextID != "") - base.ClearLogin(); - } - - protected System.Web.UI.HtmlControls.HtmlForm Form1; - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs deleted file mode 100644 index 2f747cf79d..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/timerModule.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Data; -using System.Threading; -using System.Web; -using Umbraco.Core.Logging; -using umbraco.BusinessLogic; - -namespace umbraco -{ - /// - /// Summary description for timerModule. - /// - public class timerModule : IHttpModule - { - protected Timer t; - - #region IHttpModule Members - - public void Init(HttpApplication context) - { - LogHelper.Debug("timer init"); - - t = new Timer(new TimerCallback(this.doStuff), context.Context, 1000, 1000); - } - - private void doStuff(object sender) - { - LogHelper.Debug("timer ping"); - } - - public void Dispose() - { - if(t != null) - t.Dispose(); - t = null; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs deleted file mode 100644 index 4094c4fe2f..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/umbWindow.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.ComponentModel; - -namespace umbraco -{ - /// - /// Summary description for umbWindow. - /// - [DefaultProperty("Text"), ToolboxData("<{0}:umbWindow runat=server>")] - [Obsolete("This class is no longer used and will be removed from the codebase in future versions")] - public class umbWindow : System.Web.UI.WebControls.PlaceHolder - { - private string content; - private string windowName; - private int width; - private int height; - private string margin; - private bool scroll; - private bool bottomLabel = false; - private string imageUrlPreFix = ""; - private string label; - - [Bindable(true), - Category("Umbraco"), - DefaultValue("")] - public string ImageUrlPreFix - { - get {return imageUrlPreFix;} - set {imageUrlPreFix = value;} - } - - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Content - { - get {return content;} - set {content = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public int Height - { - get {return height;} - set {height = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public int Width - { - get {return width;} - set {width = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Margin - { - get {return margin;} - set {margin = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string Label - { - get {return label;} - set {label = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public bool Scroll - { - get {return scroll;} - set {scroll = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public bool ShowBottomLabel - { - get {return bottomLabel;} - set {bottomLabel = value;} - } - [Bindable(true), - Category("Appearance"), - DefaultValue("")] - public string WindowName - { - get {return windowName;} - set {windowName = value;} - } - - protected override void Render(HtmlTextWriter output) - { - output.Write( - "
    " + - "" + - "" + - "" + - "" + - "" + - "
    \"\"\"\"
    " + label + "
    \"\"
    " + - - "" + - "" + - "" + - "" + - " " + - "" + - "
    "); - if (scroll) - output.Write( - "
    "); - else - output.Write( - "
    "); - - base.RenderChildren(output); - output.Write( - "
    " + - "
    " + - - " " + - ""); - - if (bottomLabel) - output.Write( - "" + - "" + - ""); - else - output.Write( - "" + - "" + - ""); - - output.Write( - "" + - "
    \"\"" + label + "\"\"\"\"\"\"
    "); - } - } -} diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs deleted file mode 100644 index 223cedccb3..0000000000 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/umbraco.aspx.cs +++ /dev/null @@ -1,460 +0,0 @@ -using System; -using System.Collections; -using System.ComponentModel; -using System.Data; -using System.Drawing; -using System.IO; -using System.Web; -using System.Web.SessionState; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Web.UI.HtmlControls; -using Umbraco.Core.IO; -using umbraco.BasePages; -using System.Xml; -using System.Xml.XPath; -using umbraco.BusinessLogic.Actions; -using ClientDependency.Core; -using System.Linq; -using System.Text; -using ClientDependency.Core.Controls; -using System.Text.RegularExpressions; - -namespace umbraco.cms.presentation -{ - /// - /// The back office rendering page - /// - public class _umbraco : UmbracoEnsuredPage - { - [Obsolete("This property is no longer used")] - protected umbWindow UmbWindow1; - protected System.Web.UI.WebControls.PlaceHolder bubbleText; - - public string DefaultApp { get; private set; } - - protected void Page_Load(object sender, System.EventArgs e) - { - var apps = UmbracoUser.Applications.ToList(); - bool userHasAccesstodefaultApp = apps.Where(x => x.alias == Umbraco.Core.Constants.Applications.Content).Count() > 0; - - // Load user module icons .. - if (apps.Count() > 1) - { - - var jsEvents = new StringBuilder(); - - PlaceHolderAppIcons.Text = ui.Text("main", "sections", UmbracoUser); - plcIcons.Text = ""; - foreach (var a in apps.OrderBy(x => x.sortOrder)) - { - - string appClass = a.icon.StartsWith(".") ? a.icon.Substring(1, a.icon.Length - 1) : a.alias; - - //adds client side event handlers to the icon buttons - jsEvents.Append(@"jQuery('." + appClass + "').click(function() { appClick.call(this, '" + a.alias + "'); } );"); - jsEvents.Append(@"jQuery('." + appClass + "').dblclick(function() { appDblClick.call(this, '" + a.alias + "'); } );"); - - string iconElement = String.Format("
  • ", appClass); - if (a.icon.StartsWith(".")) - iconElement += - "\"\"
  • "; - else - iconElement += "\"""; - plcIcons.Text += iconElement; - - } - - //registers the jquery event handlers. - Page.ClientScript.RegisterStartupScript(this.GetType(), "AppIcons", "jQuery(document).ready(function() { " + jsEvents.ToString() + " } );", true); - - } - else - PlaceHolderAppIcons.Visible = false; - - - //if user does not have access to content (ie, he's probably a translator)... - //then change the default tree app - if (!userHasAccesstodefaultApp) - { - JTree.App = apps[0].alias; - DefaultApp = apps[0].alias; - } - else - { - DefaultApp = Umbraco.Core.Constants.Applications.Content; - } - - - // Load globalized labels - treeWindow.Text = ui.Text("main", "tree", UmbracoUser); - - RenderActionJS(); - - // Version check goes here! - - // zb-00004 #29956 : refactor cookies names & handling - var updChkCookie = new umbraco.BusinessLogic.StateHelper.Cookies.Cookie("UMB_UPDCHK", GlobalSettings.VersionCheckPeriod); // was "updateCheck" - string updateCheckCookie = updChkCookie.HasValue ? updChkCookie.GetValue() : ""; - - if (GlobalSettings.VersionCheckPeriod > 0 && String.IsNullOrEmpty(updateCheckCookie) && UmbracoUser.UserType.Alias == "admin") - { - - // Add scriptmanager version check - ScriptManager sm = ScriptManager.GetCurrent(Page); - sm.Scripts.Add(new ScriptReference(SystemDirectories.Umbraco + "/js/umbracoUpgradeChecker.js")); - sm.Services.Add(new ServiceReference(SystemDirectories.WebServices + "/CheckForUpgrade.asmx")); - - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "upgradeChecker", "jQuery(document).ready(function() {umbraco.presentation.webservices.CheckForUpgrade.CallUpgradeService(umbracoCheckUpgrade);});", true); - - updChkCookie.SetValue("1"); - } - DataBind(); - - AddIe9Meta(); - } - - private void AddIe9Meta() - { - if (Request.Browser.Browser == "IE" && Request.Browser.MajorVersion == 9) - { - StringBuilder metadata = new StringBuilder(); - metadata.AppendFormat( - @" - - - - - ", - IOHelper.ResolveUrl(SystemDirectories.Umbraco + "/images/pinnedIcons/umb.ico"), - HttpContext.Current.Request.Url.Host.ToLower().Replace("www.", "")); - - var user = UmbracoUser; - if (user != null && user.Applications != null && user.Applications.Length > 0) - { - foreach (var app in user.Applications) - { - metadata.AppendFormat( - @"", - ui.Text("sections", app.alias, user), - IOHelper.ResolveUrl(string.Format("{0}/umbraco.aspx#{1}", SystemDirectories.Umbraco, app.alias)), - File.Exists( - IOHelper.MapPath( - IOHelper.ResolveUrl( - string.Format("{0}/images/pinnedIcons/task_{1}.ico", SystemDirectories.Umbraco, app.alias)))) - ? "/umbraco/images/pinnedIcons/task_" + app.alias + ".ico" - : "/umbraco/images/pinnedIcons/task_default.ico"); - } - } - - this.Header.Controls.Add(new LiteralControl(metadata.ToString())); - } - } - - /// - /// Renders out all JavaScript references that have bee declared in IActions - /// - private void RenderActionJS() - { - var item = 0; - foreach (var jsFile in umbraco.BusinessLogic.Actions.Action.GetJavaScriptFileReferences()) - { - //validate that this is a url, if it is not, we'll assume that it is a text block and render it as a text - //block instead. - var isValid = true; - try - { - var jsUrl = new Uri(jsFile, UriKind.RelativeOrAbsolute); - //ok it validates, but so does alert('hello'); ! so we need to do more checks - - //here are the valid chars in a url without escaping - if (Regex.IsMatch(jsFile, @"[^a-zA-Z0-9-._~:/?#\[\]@!$&'\(\)*\+,%;=]")) - isValid = false; - - //we'll have to be smarter and just check for certain js patterns now too! - var jsPatterns = new string[] { @"\+\s*\=", @"\);", @"function\s*\(", @"!=", @"==" }; - foreach (var p in jsPatterns) - { - if (Regex.IsMatch(jsFile, p)) - { - isValid = false; - break; - } - } - - if (isValid) - { - //add to page - Page.ClientScript.RegisterClientScriptInclude(this.GetType(), item.ToString(), jsFile); - } - } - catch (UriFormatException) - { - isValid = false; - } - - if (!isValid) - { - //it is invalid, let's render it as a script block instead as devs may have written real Javascript instead - //of a JS path - Page.ClientScript.RegisterClientScriptBlock(this.GetType(), item.ToString(), jsFile, true); - } - - item++; - } - } - - /// - /// ClientLoader control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoClientDependencyLoader ClientLoader; - - /// - /// CssInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude1; - - /// - /// CssInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.CssInclude CssInclude2; - - /// - /// JsInclude1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude1; - - /// - /// JsInclude2 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude2; - - /// - /// JsInclude3 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude3; - - /// - /// JsInclude14 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude14; - - /// - /// JsInclude5 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude5; - - /// - /// JsInclude6 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude6; - - /// - /// JsInclude13 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude13; - - /// - /// JsInclude7 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude7; - - /// - /// JsInclude8 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude8; - - /// - /// JsInclude9 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude9; - - /// - /// JsInclude10 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude10; - - /// - /// JsInclude11 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude11; - - /// - /// JsInclude4 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude4; - - /// - /// JsInclude17 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude17; - - /// - /// JsInclude12 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude12; - - /// - /// JsInclude15 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude15; - - /// - /// JsInclude16 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::ClientDependency.Core.Controls.JsInclude JsInclude16; - - /// - /// Form1 control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.HtmlControls.HtmlForm Form1; - - /// - /// umbracoScriptManager control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.ScriptManager umbracoScriptManager; - - /// - /// FindDocuments control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Panel FindDocuments; - - /// - /// Search control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.presentation.Search.QuickSearch Search; - - /// - /// treeWindow control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel treeWindow; - - /// - /// JTree control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.controls.Tree.TreeControl JTree; - - /// - /// PlaceHolderAppIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::umbraco.uicontrols.UmbracoPanel PlaceHolderAppIcons; - - /// - /// plcIcons control. - /// - /// - /// Auto-generated field. - /// To modify move field declaration from designer file to code-behind file. - /// - protected global::System.Web.UI.WebControls.Literal plcIcons; - - } -}