diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs
index df241c2bd3..b08e0c9418 100644
--- a/src/Umbraco.Core/UmbracoApplicationBase.cs
+++ b/src/Umbraco.Core/UmbracoApplicationBase.cs
@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Web;
using System.Web.Hosting;
+using System.Web.Mvc;
using Umbraco.Core.Logging;
namespace Umbraco.Core
@@ -27,6 +28,9 @@ namespace Umbraco.Core
///
internal void StartApplication(object sender, EventArgs e)
{
+ //don't output the MVC version header (security)
+ MvcHandler.DisableMvcResponseHeader = true;
+
//boot up the application
GetBootManager()
.Initialize()
diff --git a/src/Umbraco.Web.UI/umbraco/login.aspx b/src/Umbraco.Web.UI/umbraco/login.aspx
index 93ca7a7034..47f65fb716 100644
--- a/src/Umbraco.Web.UI/umbraco/login.aspx
+++ b/src/Umbraco.Web.UI/umbraco/login.aspx
@@ -21,7 +21,7 @@
}
body
{
- font-size: 11px;
+ font-size: 11px;
width: 100%;
font-family: Trebuchet MS, verdana, arial, Lucida Grande;
text-align: center;
@@ -70,7 +70,7 @@
-
@@ -85,7 +85,7 @@
|
-
diff --git a/src/Umbraco.Web/UmbracoApplication.cs b/src/Umbraco.Web/UmbracoApplication.cs
index b32cbc1f0f..6561c6f5ab 100644
--- a/src/Umbraco.Web/UmbracoApplication.cs
+++ b/src/Umbraco.Web/UmbracoApplication.cs
@@ -18,10 +18,7 @@ namespace Umbraco.Web
///
public class UmbracoApplication : UmbracoApplicationBase
{
- //don't output the MVC version header (security)
- MvcHandler.DisableMvcResponseHeader = true;
-
-
+
protected override IBootManager GetBootManager()
{
return new WebBootManager(this);
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs
index e1c23b4ad6..4ecebc4378 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs
@@ -132,32 +132,32 @@ namespace umbraco.controls
string originalAlias,
string originalName,
string newAlias,
- string newName
+ string newName,
string[] originalPropertyAliases)
{
SaveArgs = saveArgs;
_originalAlias = originalAlias;
_originalName = originalName;
- NewAlias = newAlias;
+ _newAlias = newAlias;
_originalPropertyAliases = originalPropertyAliases;
- NewName = newName;
+ _newName = newName;
}
public SaveClickEventArgs SaveArgs { get; private set; }
private readonly string _originalAlias;
private readonly string _originalName;
- public string NewAlias { get; private set; }
- public string NewName { get; private set; }
+ private readonly string _newAlias;
+ private readonly string _newName;
private readonly string[] _originalPropertyAliases;
public bool HasAliasChanged()
{
- return (string.Compare(OriginalAlias, NewAlias, StringComparison.OrdinalIgnoreCase) != 0);
+ return (string.Compare(_originalAlias, _newAlias, StringComparison.OrdinalIgnoreCase) != 0);
}
public bool HasNameChanged()
{
- return (string.Compare(OriginalName, NewName, StringComparison.OrdinalIgnoreCase) != 0);
+ return (string.Compare(_originalName, _newName, StringComparison.OrdinalIgnoreCase) != 0);
}
///
@@ -339,7 +339,7 @@ namespace umbraco.controls
// Only if the doctype alias changed, cause a regeneration of the xml cache file since
// the xml element names will need to be updated to reflect the new alias
- if (asyncState.HasAliasChanged(_contentType) || asyncState.HasAnyPropertyAliasChanged(_contentType))
+ if (asyncState.HasAliasChanged() || asyncState.HasAnyPropertyAliasChanged(_contentType))
RegenerateXmlCaches();
Trace.Write("ContentTypeControlNew", "task completing");
@@ -1037,6 +1037,47 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
}
}
+ ///
+ /// Called asynchronously in order to delete a content type property
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private IAsyncResult BeginAsyncDeleteOperation(object sender, EventArgs e, AsyncCallback cb, object state)
+ {
+ Trace.Write("ContentTypeControlNew", "Start async operation");
+
+ //get the args from the async state
+ var args = (GenericPropertyWrapper)state;
+
+ //start the task
+ var result = _asyncDeleteTask.BeginInvoke(args, cb, args);
+ return result;
+ }
+
+ ///
+ /// Occurs once the async database delete operation has completed
+ ///
+ ///
+ ///
+ /// This updates the UI elements
+ ///
+ private void EndAsyncDeleteOperation(IAsyncResult ar)
+ {
+ Trace.Write("ContentTypeControlNew", "ending async operation");
+
+ // reload content type (due to caching)
+ LoadContentType(_contentType.Id);
+ BindDataGenericProperties(true);
+
+ Trace.Write("ContentTypeControlNew", "async operation ended");
+
+ //complete it
+ _asyncDeleteTask.EndInvoke(ar);
+ }
+
///
/// Removes a PropertyType from the current ContentType when user clicks "red x"
///
@@ -1044,20 +1085,35 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }});
///
protected void gpw_Delete(object sender, EventArgs e)
{
- var gpw = (GenericPropertyWrapper)sender;
+ //Add the async operation to the page
+ Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, (GenericPropertyWrapper)sender));
- if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType)
+ //create the save task to be executed async
+ _asyncDeleteTask = genericPropertyWrapper =>
{
- _contentType.ContentTypeItem.RemovePropertyType(gpw.PropertyType.Alias);
- _contentType.Save();
- }
+ Trace.Write("ContentTypeControlNew", "executing task");
- gpw.GenricPropertyControl.PropertyType.delete();
+ if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType)
+ {
+ _contentType.ContentTypeItem.RemovePropertyType(genericPropertyWrapper.PropertyType.Alias);
+ _contentType.Save();
+ }
+
+ //delete the property
+ genericPropertyWrapper.GenricPropertyControl.PropertyType.delete();
+
+ //we need to re-generate the xml structures because we're removing a content type property
+ RegenerateXmlCaches();
+
+ Trace.Write("ContentTypeControlNew", "task completing");
+ };
+
+ //execute the async tasks
+ Page.ExecuteRegisteredAsyncTasks();
- LoadContentType(_contentType.Id);
- BindDataGenericProperties(true);
}
+
#endregion
#region "Tab" Pane
diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs
index c11c26f0ee..2013b898f5 100644
--- a/src/umbraco.cms/businesslogic/ContentType.cs
+++ b/src/umbraco.cms/businesslogic/ContentType.cs
@@ -6,6 +6,7 @@ using System.Runtime.CompilerServices;
using System.Linq;
using System.Xml;
using Umbraco.Core;
+using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence.Caching;
diff --git a/src/umbraco.cms/businesslogic/web/DocumentType.cs b/src/umbraco.cms/businesslogic/web/DocumentType.cs
index a552176fd4..ef22568f8a 100644
--- a/src/umbraco.cms/businesslogic/web/DocumentType.cs
+++ b/src/umbraco.cms/businesslogic/web/DocumentType.cs
@@ -286,29 +286,49 @@ namespace umbraco.cms.businesslogic.web
/// This will return all PUBLISHED content Ids that are of this content type or any descendant types as well.
///
///
+ ///
+ /// This will also work if we have multiple child content types (if one day we support that)
+ ///
internal override IEnumerable GetContentIdsForContentType()
{
var ids = new List();
- int? currentContentTypeId = this.Id;
- while (currentContentTypeId != null)
+
+ var currentContentTypeIds = new[] { this.Id };
+ while (currentContentTypeIds.Any())
{
- //get all the content item ids of the current content type
- using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsDocument.nodeId FROM cmsDocument
+ var childContentTypeIds = new List();
+
+ //loop through each content type id
+ foreach (var currentContentTypeId in currentContentTypeIds)
+ {
+ //get all the content item ids of the current content type
+ using (var dr = SqlHelper.ExecuteReader(@"SELECT DISTINCT cmsDocument.nodeId FROM cmsDocument
INNER JOIN cmsContent ON cmsContent.nodeId = cmsDocument.nodeId
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId AND cmsDocument.published = 1",
- SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
- {
- while (dr.Read())
+ SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
{
- ids.Add(dr.GetInt("nodeId"));
+ while (dr.Read())
+ {
+ ids.Add(dr.GetInt("nodeId"));
+ }
+ dr.Close();
}
- dr.Close();
+
+ //lookup the child content types if there are any and add the ids to the content type ids array
+ using (var reader = SqlHelper.ExecuteReader("SELECT childContentTypeId FROM cmsContentType2ContentType WHERE parentContentTypeId=@contentTypeId",
+ SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
+ {
+ while (reader.Read())
+ {
+ childContentTypeIds.Add(reader.GetInt("childContentTypeId"));
+ }
+ }
+
}
- //lookup the child content type if there is one
- currentContentTypeId = SqlHelper.ExecuteScalar("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
- SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
+ currentContentTypeIds = childContentTypeIds.ToArray();
+
}
return ids;
}
@@ -337,25 +357,40 @@ namespace umbraco.cms.businesslogic.web
/// Clears all xml structures in the cmsContentXml table for the current content type and any of it's descendant types
///
///
- /// This is not thread safe
+ /// This is not thread safe.
+ /// This will also work if we have multiple child content types (if one day we support that)
///
internal override void ClearXmlStructuresForContent()
{
- int? currentContentTypeId = this.Id;
- while (currentContentTypeId != null)
+ var currentContentTypeIds = new[] {this.Id};
+ while (currentContentTypeIds.Any())
{
- //Remove all items from the cmsContentXml table that are of this current content type
- SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
+ var childContentTypeIds = new List();
+
+ //loop through each content type id
+ foreach (var currentContentTypeId in currentContentTypeIds)
+ {
+ //Remove all items from the cmsContentXml table that are of this current content type
+ SqlHelper.ExecuteNonQuery(@"DELETE FROM cmsContentXml WHERE nodeId IN
(SELECT DISTINCT cmsContent.nodeId FROM cmsContent
INNER JOIN cmsContentType ON cmsContent.contentType = cmsContentType.nodeId
WHERE cmsContentType.nodeId = @contentTypeId)",
- SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
+ SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
- //lookup the child content type if there is one
- currentContentTypeId = SqlHelper.ExecuteScalar("SELECT nodeId FROM cmsContentType WHERE masterContentType=@contentTypeId",
- SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId));
+ //lookup the child content types if there are any and add the ids to the content type ids array
+ using (var reader = SqlHelper.ExecuteReader("SELECT childContentTypeId FROM cmsContentType2ContentType WHERE parentContentTypeId=@contentTypeId",
+ SqlHelper.CreateParameter("@contentTypeId", currentContentTypeId)))
+ {
+ while (reader.Read())
+ {
+ childContentTypeIds.Add(reader.GetInt("childContentTypeId"));
+ }
+ }
+
+ }
+
+ currentContentTypeIds = childContentTypeIds.ToArray();
}
-
}
#endregion
|