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
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/NuGet.Config b/src/NuGet.Config
new file mode 100644
index 0000000000..f8a7d20499
--- /dev/null
+++ b/src/NuGet.Config
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
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
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
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;
}
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);
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 39258f6b1a..bb30ea09b9 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -135,12 +135,12 @@
False
..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll
-
- ..\packages\ImageProcessor.2.2.8.0\lib\net45\ImageProcessor.dll
+
+ ..\packages\ImageProcessor.2.3.0.0\lib\net45\ImageProcessor.dll
True
-
- ..\packages\ImageProcessor.Web.4.3.6.0\lib\net45\ImageProcessor.Web.dll
+
+ ..\packages\ImageProcessor.Web.4.4.0.0\lib\net45\ImageProcessor.Web.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 @@
-
-
+
+
diff --git a/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs b/src/Umbraco.Web/BatchedDatabaseServerMessenger.cs
index 714b79514d..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,21 +100,25 @@ namespace Umbraco.Web
ApplicationContext.DatabaseContext.Database.Insert(dto);
}
- protected ICollection GetBatch(bool ensureHttpContext)
+ protected ICollection GetBatch(bool create)
{
- var httpContext = UmbracoContext.Current == null ? null : UmbracoContext.Current.HttpContext;
- if (httpContext == null)
- {
- if (ensureHttpContext)
- throw new NotSupportedException("Cannot execute without a valid/current UmbracoContext with an HttpContext assigned.");
- return null;
- }
+ // 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 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;
}
@@ -124,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
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;
}