From 7d8247047b32e8ea81a45c1371782fa098a07d40 Mon Sep 17 00:00:00 2001 From: Jeavon Date: Mon, 21 Sep 2015 14:23:36 +0100 Subject: [PATCH 01/11] Fix for U4-6784 Multiple Media Picker - Failed to retrieve entity data for ids --- src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs index 55095e1f8e..ac7e410a8f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs @@ -307,7 +307,7 @@ namespace Umbraco.Core.Persistence.Repositories .Append(new Sql(") tmpTbl LEFT JOIN (")) .Append(joinSql) .Append(new Sql(") as property ON id = property.contentNodeId")) - .OrderBy("sortOrder"); + .OrderBy("sortOrder, id"); return wrappedSql; } From 3612780d150f9b0b5f61f3ed5e02cb7d6fe8e89e Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 22 Sep 2015 11:18:06 +0200 Subject: [PATCH 02/11] git-ignore loader.dev.js --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index ebee9f6ae9..04e39e37c9 100644 --- a/.gitignore +++ b/.gitignore @@ -76,6 +76,7 @@ src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/umbraco.* src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/routes.js src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.dev.js src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.js +src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/loader.dev.js src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/main.js src/Umbraco.Web.UI/[Uu]mbraco/[Jj]s/app.js From 25cfe0193ce44dc71ab4a3a1bbb088adacfbbb9d Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 22 Sep 2015 12:19:14 +0200 Subject: [PATCH 03/11] adds detailed shutdown info to logs by default --- src/Umbraco.Core/UmbracoApplicationBase.cs | 44 +++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs index 5b9c8903c6..6aadbd269a 100644 --- a/src/Umbraco.Core/UmbracoApplicationBase.cs +++ b/src/Umbraco.Core/UmbracoApplicationBase.cs @@ -1,5 +1,7 @@ using System; +using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Web; using System.Web.Hosting; using log4net; @@ -180,7 +182,47 @@ namespace Umbraco.Core { if (SystemUtilities.GetCurrentTrustLevel() == AspNetHostingPermissionLevel.Unrestricted) { - Logger.Info("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason); + //Try to log the detailed shutdown message (typical asp.net hack: http://weblogs.asp.net/scottgu/433194) + try + { + var runtime = (HttpRuntime)typeof(HttpRuntime).InvokeMember("_theRuntime", + BindingFlags.NonPublic + | BindingFlags.Static + | BindingFlags.GetField, + null, + null, + null); + if (runtime == null) + return; + + var shutDownMessage = (string)runtime.GetType().InvokeMember("_shutDownMessage", + BindingFlags.NonPublic + | BindingFlags.Instance + | BindingFlags.GetField, + null, + runtime, + null); + + var shutDownStack = (string)runtime.GetType().InvokeMember("_shutDownStack", + BindingFlags.NonPublic + | BindingFlags.Instance + | BindingFlags.GetField, + null, + runtime, + null); + + var shutdownMsg = string.Format("{0}\r\n\r\n_shutDownMessage={1}\r\n\r\n_shutDownStack={2}", + HostingEnvironment.ShutdownReason, + shutDownMessage, + shutDownStack); + + Logger.Info("Application shutdown. Details: " + shutdownMsg); + } + catch (Exception) + { + //if for some reason that fails, then log the normal output + Logger.Info("Application shutdown. Reason: " + HostingEnvironment.ShutdownReason); + } } OnApplicationEnd(sender, e); From 03f68cefb7ecc2cc1534ebb063d0a1a35e0525c2 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 22 Sep 2015 14:39:55 +0200 Subject: [PATCH 04/11] performs a fallback check for HttpContext in the batched server messengers in some cases where cache refreshers are executed on async threads... though there's not much we can do about when they are fired on background threads. --- src/Umbraco.Web/BatchedDatabaseServerMessenger.cs | 12 ++++++++++-- src/Umbraco.Web/BatchedWebServiceServerMessenger.cs | 13 +++++++++++-- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index 714b79514d..00dc4e8063 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -98,11 +98,19 @@ namespace Umbraco.Web protected ICollection GetBatch(bool ensureHttpContext) { - var httpContext = UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext; + //try get the http context from the UmbracoContext, we do this because in the case we are launching an async + // thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we + // can get the http context from it + var httpContext = (UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext) + //if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext + // wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be + // the case if the asp.net synchronization context has kicked in + ?? (HttpContext.Current == null ? null : new HttpContextWrapper(HttpContext.Current)); + if (httpContext == null) { if (ensureHttpContext) - throw new NotSupportedException("Cannot execute without a valid/current UmbracoContext with an HttpContext assigned."); + throw new NotSupportedException("Cannot execute without a valid/current HttpContext assigned."); return null; } diff --git a/src/Umbraco.Web/BatchedWebServiceServerMessenger.cs b/src/Umbraco.Web/BatchedWebServiceServerMessenger.cs index 5fc3b48eee..63536ca9f7 100644 --- a/src/Umbraco.Web/BatchedWebServiceServerMessenger.cs +++ b/src/Umbraco.Web/BatchedWebServiceServerMessenger.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Web; using Umbraco.Core.Sync; namespace Umbraco.Web @@ -38,11 +39,19 @@ namespace Umbraco.Web protected override ICollection GetBatch(bool ensureHttpContext) { - var httpContext = UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext; + //try get the http context from the UmbracoContext, we do this because in the case we are launching an async + // thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we + // can get the http context from it + var httpContext = (UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext) + //if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext + // wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be + // the case if the asp.net synchronization context has kicked in + ?? (HttpContext.Current == null ? null : new HttpContextWrapper(HttpContext.Current)); + if (httpContext == null) { if (ensureHttpContext) - throw new NotSupportedException("Cannot execute without a valid/current UmbracoContext with an HttpContext assigned."); + throw new NotSupportedException("Cannot execute without a valid/current HttpContext assigned."); return null; } From e9afa78444f5372a03097cdf48bf524d029bcbc2 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 22 Sep 2015 16:13:21 +0200 Subject: [PATCH 05/11] U4-7124 - add initial migration as part of BaseDataCreation --- .../Persistence/DatabaseSchemaHelper.cs | 3 --- .../Migrations/Initial/BaseDataCreation.cs | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs index 55c1fe505f..dc3b2f3e8b 100644 --- a/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs +++ b/src/Umbraco.Core/Persistence/DatabaseSchemaHelper.cs @@ -80,9 +80,6 @@ namespace Umbraco.Core.Persistence var creation = new DatabaseSchemaCreation(_db, _logger, _syntaxProvider); creation.InitializeDatabaseSchema(); - //Now ensure to cretae the tag in the db for the current migration version - migrationEntryService.CreateEntry(GlobalSettings.UmbracoMigrationName, UmbracoVersion.GetSemanticVersion()); - _logger.Info("Finalized database schema creation"); } diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index c36e0850c1..fbe7675836 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -1,4 +1,5 @@ using System; +using Umbraco.Core.Configuration; using Umbraco.Core.Logging; using Umbraco.Core.Models.Rdbms; @@ -86,11 +87,17 @@ namespace Umbraco.Core.Persistence.Migrations.Initial { CreateUmbracoRelationTypeData(); } + if (tableName.Equals("cmsTaskType")) { CreateCmsTaskTypeData(); } + if (tableName.Equals("umbracoMigration")) + { + CreateUmbracoMigrationData(); + } + _logger.Info(string.Format("Done creating data in table {0}", tableName)); } @@ -274,5 +281,18 @@ namespace Umbraco.Core.Persistence.Migrations.Initial { _database.Insert("cmsTaskType", "id", false, new TaskTypeDto { Id = 1, Alias = "toTranslate" }); } + + private void CreateUmbracoMigrationData() + { + var dto = new MigrationDto + { + Id = 1, + Name = GlobalSettings.UmbracoMigrationName, + Version = UmbracoVersion.GetSemanticVersion().ToString(), + CreateDate = DateTime.Now + }; + + _database.Insert("umbracoMigration", "pk", false, dto); + } } } \ No newline at end of file From 3124ea4e676aa4b70716c913f4a9085756c436e4 Mon Sep 17 00:00:00 2001 From: Stephan Date: Tue, 22 Sep 2015 15:38:19 +0200 Subject: [PATCH 06/11] U4-7129 - BatchedDatabaseServerMessenger degraded non-batching mode when no context --- .../BatchedDatabaseServerMessenger.cs | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs index 00dc4e8063..730efd380b 100644 --- a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs +++ b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs @@ -85,7 +85,11 @@ namespace Umbraco.Web var instructions = batch.SelectMany(x => x.Instructions).ToArray(); batch.Clear(); if (instructions.Length == 0) return; + WriteInstructions(instructions); + } + private void WriteInstructions(RefreshInstruction[] instructions) + { var dto = new CacheInstructionDto { UtcStamp = DateTime.UtcNow, @@ -96,29 +100,25 @@ namespace Umbraco.Web ApplicationContext.DatabaseContext.Database.Insert(dto); } - protected ICollection GetBatch(bool ensureHttpContext) + protected ICollection GetBatch(bool create) { - //try get the http context from the UmbracoContext, we do this because in the case we are launching an async + // try get the http context from the UmbracoContext, we do this because in the case we are launching an async // thread and we know that the cache refreshers will execute, we will ensure the UmbracoContext and therefore we // can get the http context from it var httpContext = (UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext) - //if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext + // if this is null, it could be that an async thread is calling this method that we weren't aware of and the UmbracoContext // wasn't ensured at the beginning of the thread. We can try to see if the HttpContext.Current is available which might be // the case if the asp.net synchronization context has kicked in ?? (HttpContext.Current == null ? null : new HttpContextWrapper(HttpContext.Current)); - if (httpContext == null) - { - if (ensureHttpContext) - throw new NotSupportedException("Cannot execute without a valid/current HttpContext assigned."); - return null; - } + // if no context was found, return null - we cannot not batch + if (httpContext == null) return null; var key = typeof (BatchedDatabaseServerMessenger).Name; // no thread-safety here because it'll run in only 1 thread (request) at a time var batch = (ICollection)httpContext.Items[key]; - if (batch == null && ensureHttpContext) + if (batch == null && create) httpContext.Items[key] = batch = new List(); return batch; } @@ -132,11 +132,13 @@ namespace Umbraco.Web string json = null) { var batch = GetBatch(true); - if (batch == null) - throw new Exception("Failed to get a batch."); + var instructions = RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json); - batch.Add(new RefreshInstructionEnvelope(servers, refresher, - RefreshInstruction.GetInstructions(refresher, messageType, ids, idType, json))); + // batch if we can, else write to DB immediately + if (batch == null) + WriteInstructions(instructions.ToArray()); + else + batch.Add(new RefreshInstructionEnvelope(servers, refresher, instructions)); } } } \ No newline at end of file From 5b688d42ba4b468d14a580b4f035467bcee623fb Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 23 Sep 2015 15:56:05 +1000 Subject: [PATCH 07/11] Add custom repo package resotore Adds the ability for contributors to pull the Umbraco specific Nuget packages from the Myget repository using package restore. https://docs.nuget.org/consume/nuget-config-file --- src/NuGet.Config | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/NuGet.Config diff --git a/src/NuGet.Config b/src/NuGet.Config new file mode 100644 index 0000000000..44cee4cc3c --- /dev/null +++ b/src/NuGet.Config @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file From 6b639e940c077d6bda6b242c3d82fb414c768a49 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 23 Sep 2015 16:05:07 +1000 Subject: [PATCH 08/11] Update ImageProcessor dependency for core An update to U4-7053. Reduced memory usage plus web optimised images. --- build/NuSpecs/UmbracoCms.Core.nuspec | 4 ++-- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 8 ++------ src/Umbraco.Web.UI/packages.config | 4 ++-- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 0c7d51334e..cba4de7cbe 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -33,8 +33,8 @@ - - + + diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 39258f6b1a..9f34fca837 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -135,12 +135,8 @@ False ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll - - ..\packages\ImageProcessor.2.2.8.0\lib\net45\ImageProcessor.dll - True - - - ..\packages\ImageProcessor.Web.4.3.6.0\lib\net45\ImageProcessor.Web.dll + + ..\packages\ImageProcessor.2.3.0.0\lib\net45\ImageProcessor.dll True diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index efab0db7da..289aed138d 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -5,8 +5,8 @@ - - + + From d05395075dd9e5b953d1323d4d73db2daea49de2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Wed, 23 Sep 2015 08:34:55 +0200 Subject: [PATCH 09/11] Indentation --- src/NuGet.Config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NuGet.Config b/src/NuGet.Config index 44cee4cc3c..f8a7d20499 100644 --- a/src/NuGet.Config +++ b/src/NuGet.Config @@ -2,6 +2,6 @@ - + \ No newline at end of file From 2599fdb1d288dc706fac2b2a4641ffd4ca822a18 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 23 Sep 2015 18:06:49 +1000 Subject: [PATCH 10/11] Fix missing project reference --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 9f34fca837..bb30ea09b9 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -139,6 +139,10 @@ ..\packages\ImageProcessor.2.3.0.0\lib\net45\ImageProcessor.dll True + + ..\packages\ImageProcessor.Web.4.4.0.0\lib\net45\ImageProcessor.Web.dll + True + False ..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll From 14c4e9dda7a4b0033df5410432b5a058c22d4ca9 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 23 Sep 2015 11:29:29 +0200 Subject: [PATCH 11/11] Fixes upgrade issue for when the same alias is used between content types and media types. --- .../AddUniqueIdPropertyTypeColumn.cs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs index f2f9261f52..58278eff84 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenThreeZero/AddUniqueIdPropertyTypeColumn.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Persistence.SqlSyntax; namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZero { + [Migration("7.3.0", 13, GlobalSettings.UmbracoMigrationName)] public class AddUniqueIdPropertyTypeColumn : MigrationBase { @@ -35,13 +36,17 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenThreeZe // the already existing data, see: http://issues.umbraco.org/issue/U4-6942 foreach (var data in Context.Database.Query(@" -SELECT cmsPropertyType.id ptId, cmsPropertyType.Alias ptAlias, cmsContentType.alias ctAlias +SELECT cmsPropertyType.id ptId, cmsPropertyType.Alias ptAlias, cmsContentType.alias ctAlias, umbracoNode.nodeObjectType nObjType FROM cmsPropertyType INNER JOIN cmsContentType -ON cmsPropertyType.contentTypeId = cmsContentType.nodeId")) +ON cmsPropertyType.contentTypeId = cmsContentType.nodeId +INNER JOIN umbracoNode +ON cmsContentType.nodeId = umbracoNode.id")) { - //create a guid from the concatenation of the property type alias + the doc type alias - string concatAlias = data.ptAlias + data.ctAlias; + //create a guid from the concatenation of the: + // property type alias + the doc type alias + the content type node object type + // - the latter is required because there can be a content type and media type with the same alias!! + string concatAlias = data.ptAlias + data.ctAlias + data.nObjType; var ptGuid = concatAlias.ToGuid(); //set the Unique Id to the one we've generated