From 683d7934600c70c4a9f7ad9effc0a5f2eef19b73 Mon Sep 17 00:00:00 2001 From: Stephan Date: Wed, 6 Feb 2013 12:46:54 -0100 Subject: [PATCH 01/15] U4-1441 - refactor (fix) legacy NotFoundHandler support --- .../Routing/DefaultLastChanceLookup.cs | 228 ------------------ .../Routing/LastChanceLookupResolver.cs | 10 +- src/Umbraco.Web/Routing/LookupByAlias.cs | 1 - src/Umbraco.Web/Routing/LookupByLegacy404.cs | 52 ++++ .../Routing/LookupByNotFoundHandlers.cs | 143 +++++++++++ .../Routing/NotFoundHandlerHelper.cs | 139 +++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 4 +- src/Umbraco.Web/WebBootManager.cs | 13 +- 8 files changed, 353 insertions(+), 237 deletions(-) delete mode 100644 src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs create mode 100644 src/Umbraco.Web/Routing/LookupByLegacy404.cs create mode 100644 src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs create mode 100644 src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs diff --git a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs deleted file mode 100644 index 674a6e64a4..0000000000 --- a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs +++ /dev/null @@ -1,228 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Web; -using System.Xml; -using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using umbraco.IO; -using umbraco.interfaces; - -namespace Umbraco.Web.Routing -{ - /// - /// Provides an implementation of that handles backward compatilibty with legacy INotFoundHandler. - /// - internal class DefaultLastChanceLookup : IDocumentLastChanceLookup - { - // notes - // - // at the moment we load the legacy INotFoundHandler - // excluding those that have been replaced by proper lookups, - // and run them. - // - // when we finaly obsolete INotFoundHandler, we'll have to move - // over here code from legacy requestHandler.hande404, which - // basically uses umbraco.library.GetCurrentNotFoundPageId(); - // which also would need to be refactored / migrated here. - // - // the best way to do this would be to create a DefaultLastChanceLookup2 - // that would do everything by itself, and let ppl use it if they - // want, then make it the default one, then remove this one. - - /// - /// Tries to find and assign an Umbraco document to a PublishedContentRequest. - /// - /// The PublishedContentRequest. - /// A value indicating whether an Umbraco document was found and assigned. - public bool TrySetDocument(PublishedContentRequest docRequest) - { - docRequest.PublishedContent = HandlePageNotFound(docRequest); - return docRequest.HasNode; - } - - #region Copied over from presentation.requestHandler - - //FIXME: this is temporary and should be obsoleted - - string GetLegacyUrlForNotFoundHandlers(PublishedContentRequest docRequest) - { - // that's not backward-compatible because when requesting "/foo.aspx" - // 4.9 : url = "foo.aspx" - // 4.10 : url = "/foo" - //return docRequest.Uri.AbsolutePath; - - // so we have to run the legacy code for url preparation :-( - - // code from requestModule.UmbracoRewrite - string tmp = HttpContext.Current.Request.Path.ToLower(); - - // note: requestModule.UmbracoRewrite also does some confusing stuff - // with stripping &umbPage from the querystring?! ignored. - - // code from requestHandler.cleanUrl - string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); - if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) - tmp = tmp.Substring(root.Length); - tmp = tmp.TrimEnd('/'); - if (tmp == "/default.aspx") - tmp = string.Empty; - else if (tmp == root) - tmp = string.Empty; - - // code from UmbracoDefault.Page_PreInit - if (tmp != "" && HttpContext.Current.Request["umbPageID"] == null) - { - string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); - int result; - if (int.TryParse(tryIntParse, out result)) - tmp = tmp.Replace(".aspx", string.Empty); - } - else if (!string.IsNullOrEmpty(HttpContext.Current.Request["umbPageID"])) - { - int result; - if (int.TryParse(HttpContext.Current.Request["umbPageID"], out result)) - { - tmp = HttpContext.Current.Request["umbPageID"]; - } - } - - // code from requestHandler.ctor - if (tmp != "") - tmp = tmp.Substring(1); - - return tmp; - } - - IPublishedContent HandlePageNotFound(PublishedContentRequest docRequest) - { - LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); - - //XmlNode currentPage = null; - IPublishedContent currentPage = null; - var url = GetLegacyUrlForNotFoundHandlers(docRequest); - - foreach (var handler in GetNotFoundHandlers()) - { - if (handler.Execute(url) && handler.redirectID > 0) - { - //currentPage = umbracoContent.GetElementById(handler.redirectID.ToString()); - currentPage = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( - docRequest.RoutingContext.UmbracoContext, - handler.redirectID); - - // FIXME - could it be null? - - LogHelper.Debug("Handler '{0}' found node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID); - - //// check for caching - //if (handler.CacheUrl) - //{ - // if (url.StartsWith("/")) - // url = "/" + url; - - // var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url; - // var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias; - // SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture)); - - // HttpContext.Current.Trace.Write("NotFoundHandler", - // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); - //} - - break; - } - } - - return currentPage; - } - - static IEnumerable _customHandlerTypes = null; - static readonly object CustomHandlerTypesLock = new object(); - - IEnumerable InitializeNotFoundHandlers() - { - // initialize handlers - // create the definition cache - - LogHelper.Debug("Registering custom handlers."); - - var customHandlerTypes = new List(); - - var customHandlers = new XmlDocument(); - customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig)); - - foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound")) - { - var assemblyName = n.Attributes.GetNamedItem("assembly").Value; - - var typeName = n.Attributes.GetNamedItem("type").Value; - string ns = assemblyName; - var nsAttr = n.Attributes.GetNamedItem("namespace"); - if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value)) - ns = nsAttr.Value; - - if (assemblyName == "umbraco" && (ns + "." + typeName) != "umbraco.handle404") - { - // skip those that are in umbraco.dll because we have replaced them with IDocumentLookups - // but do not skip "handle404" as that's the built-in legacy final handler, and for the time - // being people will have it in their config. - continue; - } - - LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName); - - Type type = null; - try - { - //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type - // this loads the assembly into the wrong assembly load context!! - - var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll")); - type = assembly.GetType(ns + "." + typeName); - } - catch (Exception e) - { - LogHelper.Error("Error registering handler, ignoring.", e); - } - - if (type != null) - customHandlerTypes.Add(type); - } - - return customHandlerTypes; - } - - IEnumerable GetNotFoundHandlers() - { - // instanciate new handlers - // using definition cache - - lock (CustomHandlerTypesLock) - { - if (_customHandlerTypes == null) - _customHandlerTypes = InitializeNotFoundHandlers(); - } - - var handlers = new List(); - - foreach (var type in _customHandlerTypes) - { - try - { - var handler = Activator.CreateInstance(type) as INotFoundHandler; - if (handler != null) - handlers.Add(handler); - } - catch (Exception e) - { - LogHelper.Error(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e); - } - } - - return handlers; - } - - #endregion - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs b/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs index 0feadc8a4b..fc77661f95 100644 --- a/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs +++ b/src/Umbraco.Web/Routing/LastChanceLookupResolver.cs @@ -8,9 +8,13 @@ namespace Umbraco.Web.Routing /// internal sealed class LastChanceLookupResolver : SingleObjectResolverBase { - - internal LastChanceLookupResolver(IDocumentLastChanceLookup lastChanceLookup) - : base(lastChanceLookup) + internal LastChanceLookupResolver() + : base(true) + { + } + + internal LastChanceLookupResolver(IDocumentLastChanceLookup lastChanceLookup) + : base(lastChanceLookup, true) { } diff --git a/src/Umbraco.Web/Routing/LookupByAlias.cs b/src/Umbraco.Web/Routing/LookupByAlias.cs index 0c0c023d23..530f12fcd6 100644 --- a/src/Umbraco.Web/Routing/LookupByAlias.cs +++ b/src/Umbraco.Web/Routing/LookupByAlias.cs @@ -24,7 +24,6 @@ namespace Umbraco.Web.Routing /// A value indicating whether an Umbraco document was found and assigned. public bool TrySetDocument(PublishedContentRequest docRequest) { - IPublishedContent node = null; if (docRequest.Uri.AbsolutePath != "/") // no alias if "/" diff --git a/src/Umbraco.Web/Routing/LookupByLegacy404.cs b/src/Umbraco.Web/Routing/LookupByLegacy404.cs new file mode 100644 index 0000000000..be73fa81c4 --- /dev/null +++ b/src/Umbraco.Web/Routing/LookupByLegacy404.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; + +namespace Umbraco.Web.Routing +{ + internal class LookupByLegacy404 : IPublishedContentLookup + { + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TrySetDocument(PublishedContentRequest pcr) + { + LogHelper.Debug("Looking for a page to handle 404."); + + // TODO - replace the whole logic and stop calling into library! + var error404 = global::umbraco.library.GetCurrentNotFoundPageId(); + var id = int.Parse(error404); + + IPublishedContent content = null; + + if (id > 0) + { + LogHelper.Debug("Got id={0}.", () => id); + + content = pcr.RoutingContext.PublishedContentStore.GetDocumentById( + pcr.RoutingContext.UmbracoContext, + id); + + if (content == null) + LogHelper.Debug("Could not find content with that id."); + else + LogHelper.Debug("Found corresponding content."); + } + else + { + LogHelper.Debug("Got nothing."); + } + + pcr.PublishedContent = content; + pcr.Is404 = true; + return content != null; + } + } +} diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs new file mode 100644 index 0000000000..09ba92d506 --- /dev/null +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Reflection; +using System.Web; +using System.Xml; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; +using umbraco.IO; +using umbraco.interfaces; + +namespace Umbraco.Web.Routing +{ + /// + /// Provides an implementation of that handles backward compatilibty with legacy INotFoundHandler. + /// + internal class LookupByNotFoundHandlers : IPublishedContentLookup + { + // notes + // + // at the moment we load the legacy INotFoundHandler + // excluding those that have been replaced by proper finders, + // and run them. + + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TrySetDocument(PublishedContentRequest docRequest) + { + HandlePageNotFound(docRequest); + return docRequest.HasNode; + } + + #region Copied over and adapted from presentation.requestHandler + + //FIXME: this is temporary and should be obsoleted + + void HandlePageNotFound(PublishedContentRequest docRequest) + { + LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); + + var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); + + foreach (var handler in GetNotFoundHandlers()) + { + IPublishedContentLookup lookup = null; + + LogHelper.Debug("Handler '{0}'.", () => handler.GetType().FullName); + + // replace with our own implementation + if (handler is global::umbraco.SearchForAlias) + lookup = new LookupByAlias(); + else if (handler is global::umbraco.SearchForProfile) + lookup = new LookupByProfile(); + else if (handler is global::umbraco.SearchForTemplate) + lookup = new LookupByNiceUrlAndTemplate(); + else if (handler is global::umbraco.handle404) + lookup = new LookupByLegacy404(); + + if (lookup != null) + { + LogHelper.Debug("Replace handler '{0}' by new lookup '{1}'.", () => handler.GetType().FullName, () => lookup.GetType().FullName); + if (lookup.TrySetDocument(docRequest)) + { + // do NOT set docRequest.PublishedContent again here as + // it would clear any template that the finder might have set + LogHelper.Debug("Lookup '{0}' found node with id={1}.", () => lookup.GetType().FullName, () => docRequest.PublishedContent.Id); + if (docRequest.Is404) + LogHelper.Debug("Lookup '{0}' set status to 404.", () => lookup.GetType().FullName); + return; + } + } + + // else it's a legacy handler, run + + if (handler.Execute(url) && handler.redirectID > 0) + { + docRequest.PublishedContent = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( + docRequest.RoutingContext.UmbracoContext, + handler.redirectID); + + if (!docRequest.HasNode) + { + LogHelper.Debug("Handler '{0}' found node with id={1} which is not valid.", () => handler.GetType().FullName, () => handler.redirectID); + break; + } + + LogHelper.Debug("Handler '{0}' found valid node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID); + + if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404) + { + LogHelper.Debug("Handler '{0}' set status code to 404.", () => handler.GetType().FullName); + docRequest.Is404 = true; + } + + //// check for caching + //if (handler.CacheUrl) + //{ + // if (url.StartsWith("/")) + // url = "/" + url; + + // var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url; + // var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias; + // SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture)); + + // HttpContext.Current.Trace.Write("NotFoundHandler", + // string.Format("Added to cache '{0}', {1}.", url, handler.redirectID)); + //} + + break; + } + } + } + + IEnumerable GetNotFoundHandlers() + { + // instanciate new handlers + // using definition cache + + var handlers = new List(); + + foreach (var type in NotFoundHandlerHelper.CustomHandlerTypes) + { + try + { + var handler = Activator.CreateInstance(type) as INotFoundHandler; + if (handler != null) + handlers.Add(handler); + } + catch (Exception e) + { + LogHelper.Error(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e); + } + } + + return handlers; + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs new file mode 100644 index 0000000000..595c8fd7c9 --- /dev/null +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; +using System.Xml; +using System.Reflection; + +using Umbraco.Core; +using Umbraco.Core.Logging; + +namespace Umbraco.Web.Routing +{ + // provides internal access to legacy url -- should get rid of it eventually + internal static class NotFoundHandlerHelper + { + const string ContextKey = "Umbraco.Web.Routing.NotFoundHandlerHelper.Url"; + + static NotFoundHandlerHelper() + { + InitializeNotFoundHandlers(); + } + + public static string GetLegacyUrlForNotFoundHandlers() + { + // that's not backward-compatible because when requesting "/foo.aspx" + // 4.9 : url = "foo.aspx" + // 4.10 : url = "/foo" + //return pcr.Uri.AbsolutePath; + + // so we have to run the legacy code for url preparation :-( + + var httpContext = HttpContext.Current; + + if (httpContext == null) + return ""; + + var url = httpContext.Items[ContextKey] as string; + if (url != null) + return url; + + // code from requestModule.UmbracoRewrite + string tmp = httpContext.Request.Path.ToLower(); + + // note: requestModule.UmbracoRewrite also did some stripping of &umbPage + // from the querystring... that was in v3.x to fix some issues with pre-forms + // auth. Paul Sterling confirmed in jan. 2013 that we can get rid of it. + + // code from requestHandler.cleanUrl + string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); + if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) + tmp = tmp.Substring(root.Length); + tmp = tmp.TrimEnd('/'); + if (tmp == "/default.aspx") + tmp = string.Empty; + else if (tmp == root) + tmp = string.Empty; + + // code from UmbracoDefault.Page_PreInit + if (tmp != "" && httpContext.Request["umbPageID"] == null) + { + string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); + int result; + if (int.TryParse(tryIntParse, out result)) + tmp = tmp.Replace(".aspx", string.Empty); + } + else if (!string.IsNullOrEmpty(httpContext.Request["umbPageID"])) + { + int result; + if (int.TryParse(httpContext.Request["umbPageID"], out result)) + { + tmp = httpContext.Request["umbPageID"]; + } + } + + // code from requestHandler.ctor + if (tmp != "") + tmp = tmp.Substring(1); + + httpContext.Items[ContextKey] = tmp; + return tmp; + } + + static IEnumerable _customHandlerTypes = null; + + static void InitializeNotFoundHandlers() + { + // initialize handlers + // create the definition cache + + LogHelper.Debug("Registering custom handlers."); + + var customHandlerTypes = new List(); + + var customHandlers = new XmlDocument(); + customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig)); + + foreach (XmlNode n in customHandlers.DocumentElement.SelectNodes("notFound")) + { + var assemblyName = n.Attributes.GetNamedItem("assembly").Value; + var typeName = n.Attributes.GetNamedItem("type").Value; + + string ns = assemblyName; + var nsAttr = n.Attributes.GetNamedItem("namespace"); + if (nsAttr != null && !string.IsNullOrWhiteSpace(nsAttr.Value)) + ns = nsAttr.Value; + + LogHelper.Debug("Registering '{0}.{1},{2}'.", () => ns, () => typeName, () => assemblyName); + + Type type = null; + try + { + //TODO: This isn't a good way to load the assembly, its already in the Domain so we should be getting the type + // this loads the assembly into the wrong assembly load context!! + + var assembly = Assembly.LoadFrom(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemDirectories.Bin + "/" + assemblyName + ".dll")); + type = assembly.GetType(ns + "." + typeName); + } + catch (Exception e) + { + LogHelper.Error("Error registering handler, ignoring.", e); + } + + if (type != null) + customHandlerTypes.Add(type); + } + + _customHandlerTypes = customHandlerTypes; + } + + public static IEnumerable CustomHandlerTypes + { + get + { + return _customHandlerTypes; + } + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index fab5647622..26709f8319 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -322,8 +322,10 @@ + + @@ -423,7 +425,7 @@ - + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 2c7fd2d023..b0bc58af4e 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -193,7 +193,9 @@ namespace Umbraco.Web typeof (RenderControllerFactory) }); - LastChanceLookupResolver.Current = new LastChanceLookupResolver(new DefaultLastChanceLookup()); + // the legacy 404 will run from within LookupByNotFoundHandlers below + // so for the time being there is no last chance lookup + LastChanceLookupResolver.Current = new LastChanceLookupResolver(); DocumentLookupsResolver.Current = new DocumentLookupsResolver( //add all known resolvers in the correct order, devs can then modify this list on application startup either by binding to events @@ -203,9 +205,12 @@ namespace Umbraco.Web typeof (LookupByPageIdQuery), typeof (LookupByNiceUrl), typeof (LookupByIdPath), - typeof (LookupByNiceUrlAndTemplate), - typeof (LookupByProfile), - typeof (LookupByAlias) + // these will be handled by LookupByNotFoundHandlers + // so they can be enabled/disabled even though resolvers are not public yet + //typeof (LookupByNiceUrlAndTemplate), + //typeof (LookupByProfile), + //typeof (LookupByAlias), + typeof (LookupByNotFoundHandlers) }); RoutesCacheResolver.Current = new RoutesCacheResolver(new DefaultRoutesCache(_isForTesting == false)); From c8e08b8ef8a975204f56d2f6aec1a9755109e756 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 5 Feb 2013 16:29:10 -0100 Subject: [PATCH 02/15] U4-1441 - fix issue with IIS taking over custom errors --- src/Umbraco.Web/Routing/PublishedContentRequest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index 2f15e6e107..07a2896300 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -78,6 +78,7 @@ namespace Umbraco.Web.Routing if (this.Is404) { httpContext.Response.StatusCode = 404; + httpContext.Response.TrySkipIisCustomErrors = true; if (!this.HasNode) { @@ -136,6 +137,7 @@ namespace Umbraco.Web.Routing // here .Is404 _has_ to be true httpContext.Response.StatusCode = 404; + httpContext.Response.TrySkipIisCustomErrors = true; if (!this.HasNode) { From 97536086c0236a7f1f1902d1b76f73c96e9bc687 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Wed, 6 Feb 2013 19:14:34 +0600 Subject: [PATCH 03/15] Patches installer issue. --- .../umbraco.presentation/install/utills/p.aspx.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs index d44285e93d..4e8cde9b0c 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/utills/p.aspx.cs @@ -1,5 +1,6 @@ using System; using System.Configuration; +using System.Security.Authentication; using System.Web.Script.Serialization; using System.Web.Script.Services; using System.Web.Services; @@ -57,6 +58,12 @@ namespace umbraco.presentation.install.utills [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public static string installOrUpgrade() { + //if its not configured then we can continue + if (ApplicationContext.Current == null || ApplicationContext.Current.IsConfigured) + { + throw new AuthenticationException("The application is already configured"); + } + LogHelper.Info

("Running 'installOrUpgrade' service"); var result = ApplicationContext.Current.DatabaseContext.CreateDatabaseSchemaAndDataOrUpgrade(); From ec6158792ace89c8712f6d742e32d924bef67fb5 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 7 Feb 2013 02:07:07 +0600 Subject: [PATCH 04/15] Adds patch fixes for #U4-1653 --- .../config/xsltExtensions.config | 4 - .../LibraryCacheRefresher.cs | 81 +++++++++++-------- 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/src/Umbraco.Web.UI/config/xsltExtensions.config b/src/Umbraco.Web.UI/config/xsltExtensions.config index 354f37fd64..a372e40d95 100644 --- a/src/Umbraco.Web.UI/config/xsltExtensions.config +++ b/src/Umbraco.Web.UI/config/xsltExtensions.config @@ -8,8 +8,4 @@ - - - - \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/LibraryCacheRefresher.cs b/src/Umbraco.Web/umbraco.presentation/LibraryCacheRefresher.cs index 3e991fafc4..371d659bd8 100644 --- a/src/Umbraco.Web/umbraco.presentation/LibraryCacheRefresher.cs +++ b/src/Umbraco.Web/umbraco.presentation/LibraryCacheRefresher.cs @@ -1,8 +1,13 @@ +using Umbraco.Core; +using Umbraco.Core.Events; +using Umbraco.Core.Models; +using Umbraco.Core.Services; using umbraco.businesslogic; using umbraco.cms.businesslogic; using umbraco.cms.businesslogic.media; using umbraco.cms.businesslogic.member; using umbraco.interfaces; +using DeleteEventArgs = umbraco.cms.businesslogic.DeleteEventArgs; namespace umbraco { @@ -13,47 +18,55 @@ namespace umbraco { public LibraryCacheRefresher() { - if (UmbracoSettings.UmbracoLibraryCacheDuration > 0) - { - Member.AfterSave += new Member.SaveEventHandler(Member_AfterSave); - Member.BeforeDelete += new Member.DeleteEventHandler(Member_BeforeDelete); - Media.AfterSave += new Media.SaveEventHandler(Media_AfterSave); - Media.BeforeDelete += new Media.DeleteEventHandler(Media_BeforeDelete); - } + if (UmbracoSettings.UmbracoLibraryCacheDuration <= 0) return; - // now handled directly by the IRoutesCache implementation - //content.AfterUpdateDocumentCache += new content.DocumentCacheEventHandler(content_AfterUpdateDocumentCache); - //content.AfterRefreshContent += new content.RefreshContentEventHandler(content_AfterRefreshContent); + + Member.AfterSave += MemberAfterSave; + Member.BeforeDelete += MemberBeforeDelete; + + MediaService.Saved += MediaServiceSaved; + //We need to perform all of the 'before' events here because we need a reference to the + //media item's Path before it is moved/deleting/trashed + //see: http://issues.umbraco.org/issue/U4-1653 + MediaService.Deleting += MediaServiceDeleting; + MediaService.Moving += MediaServiceMoving; + MediaService.Trashing += MediaServiceTrashing; } - //void content_AfterRefreshContent(Document sender, RefreshContentEventArgs e) - //{ - // library.ClearNiceUrlCache(); - //} + static void MediaServiceTrashing(IMediaService sender, MoveEventArgs e) + { + library.ClearLibraryCacheForMedia(e.Entity.Id); + } - //void content_AfterUpdateDocumentCache(Document sender, DocumentCacheEventArgs e) - //{ - // library.ClearNiceUrlCache(); - //} + static void MediaServiceMoving(IMediaService sender, MoveEventArgs e) + { + library.ClearLibraryCacheForMedia(e.Entity.Id); + } - void Member_BeforeDelete(Member sender, DeleteEventArgs e) - { - library.ClearLibraryCacheForMember(sender.Id); - } + static void MediaServiceDeleting(IMediaService sender, DeleteEventArgs e) + { + foreach (var item in e.DeletedEntities) + { + library.ClearLibraryCacheForMedia(item.Id); + } + } - void Media_BeforeDelete(Media sender, DeleteEventArgs e) - { - library.ClearLibraryCacheForMedia(sender.Id); - } + static void MediaServiceSaved(IMediaService sender, SaveEventArgs e) + { + foreach (var item in e.SavedEntities) + { + library.ClearLibraryCacheForMedia(item.Id); + } + } - void Media_AfterSave(Media sender, SaveEventArgs e) - { - library.ClearLibraryCacheForMedia(sender.Id); - } + static void MemberBeforeDelete(Member sender, DeleteEventArgs e) + { + library.ClearLibraryCacheForMember(sender.Id); + } - void Member_AfterSave(Member sender, SaveEventArgs e) - { - library.ClearLibraryCacheForMember(sender.Id); - } + static void MemberAfterSave(Member sender, SaveEventArgs e) + { + library.ClearLibraryCacheForMember(sender.Id); + } } } \ No newline at end of file From 0c05cbc9db1b144cd257868ba8fcdb66379fd396 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 7 Feb 2013 13:31:39 -0100 Subject: [PATCH 05/15] Updating the EmptyRecycleBin method in the services to account for a deleted structure. Optimizing the CallTheGarbageMan method because it was sooo easy, and it would be stupid not to. --- src/Umbraco.Core/Services/ContentService.cs | 4 +- src/Umbraco.Core/Services/MediaService.cs | 4 +- .../umbraco/webservices/trashcan.asmx.cs | 8 ---- src/umbraco.cms/businesslogic/RecycleBin.cs | 41 ++++++++----------- 4 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index ec1d53867e..b55f27f9a4 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -807,8 +807,8 @@ namespace Umbraco.Core.Services var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateContentRepository(uow)) { - var query = Query.Builder.Where(x => x.ParentId == -20); - var contents = repository.GetByQuery(query); + var query = Query.Builder.Where(x => x.Path.Contains("-20")); + var contents = repository.GetByQuery(query).OrderByDescending(x => x.ParentId); foreach (var content in contents) { diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 844747bb8d..362507f7c6 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -378,8 +378,8 @@ namespace Umbraco.Core.Services var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateMediaRepository(uow)) { - var query = Query.Builder.Where(x => x.ParentId == -21); - var contents = repository.GetByQuery(query); + var query = Query.Builder.Where(x => x.Path.Contains("-21")); + var contents = repository.GetByQuery(query).OrderByDescending(x => x.ParentId); foreach (var content in contents) { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/trashcan.asmx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/trashcan.asmx.cs index e7a39a9ead..eb1b9aac71 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/trashcan.asmx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/webservices/trashcan.asmx.cs @@ -1,17 +1,9 @@ using System; -using System.Data; -using System.Threading; -using System.Web; -using System.Collections; using System.Web.Script.Services; using System.Web.Services; -using System.Web.Services.Protocols; using System.ComponentModel; using umbraco.BasePages; -using umbraco.BusinessLogic.console; using umbraco.cms.businesslogic; -using umbraco.cms.businesslogic.web; -using umbraco.cms.businesslogic.media; namespace umbraco.presentation.webservices { diff --git a/src/umbraco.cms/businesslogic/RecycleBin.cs b/src/umbraco.cms/businesslogic/RecycleBin.cs index 417c74155d..84e4319aa3 100644 --- a/src/umbraco.cms/businesslogic/RecycleBin.cs +++ b/src/umbraco.cms/businesslogic/RecycleBin.cs @@ -1,11 +1,9 @@ using System; -using System.Collections.Generic; -using System.Text; using System.Linq; +using Umbraco.Core; using umbraco.DataLayer; using umbraco.cms.businesslogic.web; using umbraco.cms.businesslogic.media; -using System.Threading; namespace umbraco.cms.businesslogic { @@ -40,7 +38,7 @@ namespace umbraco.cms.businesslogic /// Constructor to create a new recycle bin /// /// - /// + /// [Obsolete("Use the simple constructor that has the RecycleBinType only parameter")] public RecycleBin(Guid nodeObjectType, RecycleBinType type) : base((int)type) @@ -108,9 +106,7 @@ namespace umbraco.cms.businesslogic string sql = String.Format(RecycleBin.m_ChildCountSQL, (int) type); - return SqlHelper.ExecuteScalar( - sql, - SqlHelper.CreateParameter("@nodeObjectType", objectType)); + return SqlHelper.ExecuteScalar(sql, SqlHelper.CreateParameter("@nodeObjectType", objectType)); } #endregion @@ -132,26 +128,23 @@ namespace umbraco.cms.businesslogic { lock (m_Locker) { - //first, move all nodes underneath the recycle bin directly under the recycle bin node (flatten heirarchy) - //then delete them all. + var itemsInTheBin = Count(m_BinType); + itemDeletedCallback(itemsInTheBin); - SqlHelper.ExecuteNonQuery("UPDATE umbracoNode SET parentID=@parentID, level=1 WHERE path LIKE '%," + ((int)m_BinType).ToString() + ",%'", - SqlHelper.CreateParameter("@parentID", (int)m_BinType)); - - foreach (var c in Children.ToList()) + if (m_BinType == RecycleBinType.Media) { - switch (m_BinType) - { - case RecycleBinType.Content: - new Document(c.Id).delete(true); - itemDeletedCallback(RecycleBin.Count(m_BinType)); - break; - case RecycleBinType.Media: - new Media(c.Id).delete(true); - itemDeletedCallback(RecycleBin.Count(m_BinType)); - break; - } + ApplicationContext.Current.Services.MediaService.EmptyRecycleBin(); + var trashedMedia = ApplicationContext.Current.Services.MediaService.GetMediaInRecycleBin(); + itemsInTheBin = trashedMedia.Count(); } + else + { + ApplicationContext.Current.Services.ContentService.EmptyRecycleBin(); + var trashedContent = ApplicationContext.Current.Services.ContentService.GetContentInRecycleBin(); + itemsInTheBin = trashedContent.Count(); + } + + itemDeletedCallback(itemsInTheBin); } } From e24ff1b92b52a66e0f18959dd81dd310925eb662 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 7 Feb 2013 13:56:00 -0100 Subject: [PATCH 06/15] Updating the CreateDatabaseSchema method, so it can't be used if Umbraco is configured. Just to ensure that Richard doesn't accidentally break anything. --- src/Umbraco.Core/Persistence/PetaPocoExtensions.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index b2fe8fab39..56a7a2003e 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -136,6 +136,9 @@ namespace Umbraco.Core.Persistence public static void CreateDatabaseSchema(this Database db) { + if(ApplicationContext.Current.IsConfigured) + throw new Exception("Umbraco is already configured!"); + NewTable += PetaPocoExtensions_NewTable; LogHelper.Info("Initializing database schema creation"); From f7d40804725467530692cdcc7fc3eff54a08df75 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 07:51:22 -0100 Subject: [PATCH 07/15] U4-1441 - make trySkipIisCustomError value a setting --- .../Configuration/UmbracoSettings.cs | 166 ++++++++---------- .../config/umbracoSettings.Release.config | 9 + .../config/umbracoSettings.config | 9 + .../Routing/PublishedContentRequest.cs | 4 +- 4 files changed, 93 insertions(+), 95 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index aa47426eb8..d5dfa7b641 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -25,7 +25,37 @@ namespace Umbraco.Core.Configuration /// internal class UmbracoSettings { - ///

+ private static bool GetKeyWithOverride(string key, bool defaultValue, bool? overrideValue) + { + if (overrideValue.HasValue) + return overrideValue.Value; + + bool value; + string stringValue = GetKey(key); + + if (string.IsNullOrWhiteSpace(stringValue)) + return defaultValue; + if (bool.TryParse(stringValue, out value)) + return value; + return defaultValue; + } + + private static int GetKeyWithOverride(string key, int defaultValue, int? overrideValue) + { + if (overrideValue.HasValue) + return overrideValue.Value; + + int value; + string stringValue = GetKey(key); + + if (string.IsNullOrWhiteSpace(stringValue)) + return defaultValue; + if (int.TryParse(stringValue, out value)) + return value; + return defaultValue; + } + + /// /// Used in unit testing to reset all config items that were set with property setters (i.e. did not come from config) /// internal static void ResetSetters() @@ -35,6 +65,7 @@ namespace Umbraco.Core.Configuration _useLegacySchema = null; _useDomainPrefixes = null; _umbracoLibraryCacheDuration = null; + _trySkipIisCustomErrors = null; SettingsFilePath = null; } @@ -203,6 +234,7 @@ namespace Umbraco.Core.Configuration return value != null ? value.Attributes["assembly"].Value : ""; } } + /// /// Gets the type of an external logger that can be used to store log items in 3rd party systems /// @@ -351,24 +383,13 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (_useDomainPrefixes.HasValue) - return _useDomainPrefixes.Value; - bool result; - if (bool.TryParse(GetKey("/settings/requestHandler/useDomainPrefixes"), out result)) - return result; - return false; - } - catch - { - return false; - } + // default: false + return GetKeyWithOverride("/settings/requestHandler/useDomainPrefixes", false, _useDomainPrefixes); } - // for unit tests only internal set { - _useDomainPrefixes = value; + // for unit tests only + _useDomainPrefixes = value; } } @@ -382,31 +403,14 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (GlobalSettings.UseDirectoryUrls) - { - if (_addTrailingSlash.HasValue) - return _addTrailingSlash.Value; - bool result; - if (bool.TryParse(GetKey("/settings/requestHandler/addTrailingSlash"), out result)) - return result; - return false; - } - else - { - return false; - } - } - catch - { - return false; - } + // default: false + return GlobalSettings.UseDirectoryUrls + && GetKeyWithOverride("/settings/requestHandler/addTrailingSlash", false, _addTrailingSlash); } - // for unit tests only internal set { - _addTrailingSlash = value; + // for unit tests only + _addTrailingSlash = value; } } @@ -623,31 +627,34 @@ namespace Umbraco.Core.Configuration { get { - if (_forceSafeAliases.HasValue) - return _forceSafeAliases.Value; - - string forceSafeAlias = GetKey("/settings/content/ForceSafeAliases"); - if (String.IsNullOrEmpty(forceSafeAlias)) - return true; - else - { - try - { - return bool.Parse(forceSafeAlias); - } - catch - { - return true; - } - } + // default: true + return GetKeyWithOverride("/settings/content/ForceSafeAliases", true, _forceSafeAliases); } internal set { - //used for unit testing + // used for unit testing _forceSafeAliases = value; } } + private static bool? _trySkipIisCustomErrors; + + /// + /// Gets or sets a value indicating where to try to skip IIS custom errors. + /// + public static bool TrySkipIisCustomErrors + { + get + { + // default: false + return GetKeyWithOverride("/settings/TrySkipIisCustomErrors", false, _trySkipIisCustomErrors); + } + internal set + { + // used for unit testing + _trySkipIisCustomErrors = value; + } + } /// /// Gets the allowed image file types. @@ -677,26 +684,14 @@ namespace Umbraco.Core.Configuration { get { - if (_umbracoLibraryCacheDuration.HasValue) - return _umbracoLibraryCacheDuration.Value; - - string libraryCacheDuration = GetKey("/settings/content/UmbracoLibraryCacheDuration"); - if (String.IsNullOrEmpty(libraryCacheDuration)) - return 1800; - else - { - try - { - return int.Parse(libraryCacheDuration); - } - catch - { - return 1800; - } - } - + // default: 1800 + return GetKeyWithOverride("/settings/content/UmbracoLibraryCacheDuration", 1800, _umbracoLibraryCacheDuration); } - internal set { _umbracoLibraryCacheDuration = value; } + internal set + { + // for unit tests only + _umbracoLibraryCacheDuration = value; + } } /// @@ -1052,27 +1047,12 @@ namespace Umbraco.Core.Configuration { get { - try - { - if (_useLegacySchema.HasValue) - return _useLegacySchema.Value; - - string value = GetKey("/settings/content/UseLegacyXmlSchema"); - bool result; - if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out result)) - return result; - return true; - } - catch (Exception) - { - //default. TODO: When we change this to a real config section we won't have to worry about parse errors - // and should handle defaults with unit tests properly. - return false; - } + // default: true + return GetKeyWithOverride("/settings/content/UseLegacyXmlSchema", true, _useLegacySchema); } internal set { - //used for unit testing + // used for unit testing _useLegacySchema = value; } } diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index 32ab8b714d..1cabd94703 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -241,4 +241,13 @@ + + false + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 372777126a..10764d0526 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -192,4 +192,13 @@ + + false + \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index 07a2896300..6cca5613ec 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -78,7 +78,7 @@ namespace Umbraco.Web.Routing if (this.Is404) { httpContext.Response.StatusCode = 404; - httpContext.Response.TrySkipIisCustomErrors = true; + httpContext.Response.TrySkipIisCustomErrors = Umbraco.Core.Configuration.UmbracoSettings.TrySkipIisCustomErrors; if (!this.HasNode) { @@ -137,7 +137,7 @@ namespace Umbraco.Web.Routing // here .Is404 _has_ to be true httpContext.Response.StatusCode = 404; - httpContext.Response.TrySkipIisCustomErrors = true; + httpContext.Response.TrySkipIisCustomErrors = Umbraco.Core.Configuration.UmbracoSettings.TrySkipIisCustomErrors; if (!this.HasNode) { From d50396ce68506ca5f980fd865c04c1b547409c80 Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 07:36:35 -0100 Subject: [PATCH 08/15] U4-1441 - change trySkipIisCustomError config key --- .../Configuration/UmbracoSettings.cs | 31 ++++++++++++++++--- .../config/umbracoSettings.Release.config | 16 ++++++---- .../config/umbracoSettings.config | 16 ++++++---- 3 files changed, 46 insertions(+), 17 deletions(-) diff --git a/src/Umbraco.Core/Configuration/UmbracoSettings.cs b/src/Umbraco.Core/Configuration/UmbracoSettings.cs index d5dfa7b641..055353f4b5 100644 --- a/src/Umbraco.Core/Configuration/UmbracoSettings.cs +++ b/src/Umbraco.Core/Configuration/UmbracoSettings.cs @@ -157,11 +157,32 @@ namespace Umbraco.Core.Configuration { EnsureSettingsDocument(); + string attrName = null; + var pos = key.IndexOf('@'); + if (pos > 0) + { + attrName = key.Substring(pos + 1); + key = key.Substring(0, pos - 1); + } + var node = UmbracoSettingsXmlDoc.DocumentElement.SelectSingleNode(key); - if (node == null || node.FirstChild == null || node.FirstChild.Value == null) - return string.Empty; - return node.FirstChild.Value; - } + if (node == null) + return string.Empty; + + if (pos < 0) + { + if (node.FirstChild == null || node.FirstChild.Value == null) + return string.Empty; + return node.FirstChild.Value; + } + else + { + var attr = node.Attributes[attrName]; + if (attr == null) + return string.Empty; + return attr.Value; + } + } /// /// Gets a value indicating whether the media library will create new directories in the /media directory. @@ -647,7 +668,7 @@ namespace Umbraco.Core.Configuration get { // default: false - return GetKeyWithOverride("/settings/TrySkipIisCustomErrors", false, _trySkipIisCustomErrors); + return GetKeyWithOverride("/settings/web.routing/@trySkipIisCustomErrors", false, _trySkipIisCustomErrors); } internal set { diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config index 1cabd94703..d3eb0e2477 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.Release.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.Release.config @@ -242,12 +242,16 @@ - false + + diff --git a/src/Umbraco.Web.UI/config/umbracoSettings.config b/src/Umbraco.Web.UI/config/umbracoSettings.config index 10764d0526..1fafe2f61b 100644 --- a/src/Umbraco.Web.UI/config/umbracoSettings.config +++ b/src/Umbraco.Web.UI/config/umbracoSettings.config @@ -193,12 +193,16 @@ - false + + \ No newline at end of file From 2da18d45000c449e1cf32a57605fb9ac2f15948d Mon Sep 17 00:00:00 2001 From: Stephan Date: Fri, 8 Feb 2013 07:54:16 -0100 Subject: [PATCH 09/15] U4-1441 - improve logging --- src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs index 09ba92d506..311efcbcc3 100644 --- a/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs +++ b/src/Umbraco.Web/Routing/LookupByNotFoundHandlers.cs @@ -39,9 +39,8 @@ namespace Umbraco.Web.Routing void HandlePageNotFound(PublishedContentRequest docRequest) { - LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); - var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); + LogHelper.Debug("Running for legacy url='{0}'.", () => url); foreach (var handler in GetNotFoundHandlers()) { From 83518de9819745cd2ad491c6a572fe522f21c648 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 11:37:50 -0100 Subject: [PATCH 10/15] Adding no guard for testing purposes --- src/Umbraco.Core/Persistence/PetaPocoExtensions.cs | 7 ++++++- src/Umbraco.Tests/Persistence/DatabaseContextTests.cs | 2 +- src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs | 2 +- src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index 56a7a2003e..ff0b158aeb 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -136,7 +136,12 @@ namespace Umbraco.Core.Persistence public static void CreateDatabaseSchema(this Database db) { - if(ApplicationContext.Current.IsConfigured) + CreateDatabaseSchema(db, true); + } + + internal static void CreateDatabaseSchema(this Database db, bool guardConfiguration) + { + if (guardConfiguration && ApplicationContext.Current.IsConfigured) throw new Exception("Umbraco is already configured!"); NewTable += PetaPocoExtensions_NewTable; diff --git a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs index 215f658c90..acd2d7dfff 100644 --- a/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs +++ b/src/Umbraco.Tests/Persistence/DatabaseContextTests.cs @@ -78,7 +78,7 @@ namespace Umbraco.Tests.Persistence SyntaxConfig.SqlSyntaxProvider = SqlCeSyntaxProvider.Instance; //Create the umbraco database - _dbContext.Database.CreateDatabaseSchema(); + _dbContext.Database.CreateDatabaseSchema(false); bool umbracoNodeTable = _dbContext.Database.TableExist("umbracoNode"); bool umbracoUserTable = _dbContext.Database.TableExist("umbracoUser"); diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs index ec3eea2570..3b2d772072 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseFactoryTest.cs @@ -73,7 +73,7 @@ namespace Umbraco.Tests.TestHelpers //Configure the Database and Sql Syntax based on connection string set in config DatabaseContext.Initialize(); //Create the umbraco database and its base data - DatabaseContext.Database.CreateDatabaseSchema(); + DatabaseContext.Database.CreateDatabaseSchema(false); } diff --git a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs index 856bef3e86..c541a3c5a7 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseDatabaseTest.cs @@ -64,7 +64,7 @@ namespace Umbraco.Tests.TestHelpers //Create the umbraco database _database = new Database(ConnectionString, ProviderName); - _database.CreateDatabaseSchema(); + _database.CreateDatabaseSchema(false); } public abstract string ConnectionString { get; } From 1eea4dab33b96d05abb6d4df90094b8929969942 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 18:29:59 -0100 Subject: [PATCH 11/15] Fixes U4-1661 --- src/umbraco.cms/businesslogic/media/Media.cs | 14 ++++++++++++++ src/umbraco.cms/businesslogic/web/Document.cs | 9 --------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/umbraco.cms/businesslogic/media/Media.cs b/src/umbraco.cms/businesslogic/media/Media.cs index 5a698c9a4f..3cfc19bc1e 100644 --- a/src/umbraco.cms/businesslogic/media/Media.cs +++ b/src/umbraco.cms/businesslogic/media/Media.cs @@ -192,6 +192,20 @@ namespace umbraco.cms.businesslogic.media } } + [Obsolete("Obsolete, Use Name property on Umbraco.Core.Models.Content", false)] + public override string Text + { + get + { + return MediaItem.Name; + } + set + { + value = value.Trim(); + MediaItem.Name = value; + } + } + /// /// Retrieve a list of all medias underneath the current /// diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index c80264b0df..9735844b74 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -641,17 +641,11 @@ namespace umbraco.cms.businesslogic.web get { return Content.Name; - //return base.Text; } set { value = value.Trim(); - base.Text = value; Content.Name = value; - - /*SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", - SqlHelper.CreateParameter("@text", value), - SqlHelper.CreateParameter("@versionId", Version));*/ } } @@ -666,9 +660,6 @@ namespace umbraco.cms.businesslogic.web { _updated = value; Content.UpdateDate = value; - /*SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version));*/ } } From e22de5c9a05af2f3b0f8a8c943fab9e78e247893 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 18:34:47 -0100 Subject: [PATCH 12/15] Fixes U4-1666 --- .../umbraco.presentation/umbraco/editContent.aspx.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs index d6ef34ee67..a9405ca4be 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/editContent.aspx.cs @@ -2,8 +2,6 @@ using System; using System.Web.UI; using System.Web.UI.WebControls; using Umbraco.Core; -using Umbraco.Core.Models; -using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Services; using umbraco.BusinessLogic.Actions; using umbraco.IO; @@ -246,8 +244,6 @@ namespace umbraco.cms.presentation tp.ErrorControl.Visible = false; } } - //Audit trail... - BusinessLogic.Log.Add(BusinessLogic.LogTypes.Save, base.getUser(), _document.Id, ""); // Update name if (_document.Text != cControl.NameTxt.Text) From 6e6b1beffdbdb5abdde327a14a864577103dd541 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 18:37:59 -0100 Subject: [PATCH 13/15] Fixes U4-1664 --- src/umbraco.cms/businesslogic/web/Document.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 9735844b74..6aaf7a4538 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -1542,7 +1542,7 @@ namespace umbraco.cms.businesslogic.web /// /// Occurs when [before save]. /// - public static event SaveEventHandler BeforeSave; + public new static event SaveEventHandler BeforeSave; /// /// Raises the event. /// @@ -1558,12 +1558,12 @@ namespace umbraco.cms.businesslogic.web /// /// Occurs when [after save]. /// - public static event SaveEventHandler AfterSave; + public new static event SaveEventHandler AfterSave; /// /// Raises the event. /// /// The instance containing the event data. - protected virtual void FireAfterSave(SaveEventArgs e) + protected new virtual void FireAfterSave(SaveEventArgs e) { if (AfterSave != null) { From 14d40697b2d2371390d54b0ab7cb5aaf42a12046 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 18:40:52 -0100 Subject: [PATCH 14/15] Fixes U4-1662 --- src/umbraco.cms/businesslogic/web/Document.cs | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 6aaf7a4538..f32c61dc88 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -918,13 +918,25 @@ namespace umbraco.cms.businesslogic.web if (!e.Cancel) { - var result = ((ContentService)ApplicationContext.Current.Services.ContentService).SaveAndPublish(Content, true, u.Id); + var publishArgs = new PublishEventArgs(); + FireBeforePublish(publishArgs); - base.Save(); + if (!publishArgs.Cancel) + { + var result = + ((ContentService) ApplicationContext.Current.Services.ContentService).SaveAndPublish(Content, + true, u.Id); - FireAfterSave(e); + base.Save(); - return result; + //Launch the After Save event since we're doing 2 things in one operation: Saving and publishing. + FireAfterSave(e); + + //Now we need to fire the After publish event + FireAfterPublish(publishArgs); + + return result; + } } return false; From 319f257ee57db1a785c7f4c4885c26b99e16e359 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 8 Feb 2013 18:54:18 -0100 Subject: [PATCH 15/15] Minor change related to U4-1672 --- src/umbraco.cms/businesslogic/Content.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umbraco.cms/businesslogic/Content.cs b/src/umbraco.cms/businesslogic/Content.cs index 012b2759ef..6b8852e1de 100644 --- a/src/umbraco.cms/businesslogic/Content.cs +++ b/src/umbraco.cms/businesslogic/Content.cs @@ -673,7 +673,7 @@ namespace umbraco.cms.businesslogic continue; //get the propertyId - var property = propData.SingleOrDefault(x => x.PropertyTypeId == pt.Id); + var property = propData.LastOrDefault(x => x.PropertyTypeId == pt.Id); if (property == null) { //continue;