diff --git a/src/Umbraco.Core/Models/ContentType.cs b/src/Umbraco.Core/Models/ContentType.cs index d675b966ba..4577046b17 100644 --- a/src/Umbraco.Core/Models/ContentType.cs +++ b/src/Umbraco.Core/Models/ContentType.cs @@ -161,14 +161,24 @@ namespace Umbraco.Core.Models { base.ResetDirtyProperties(); + //loop through each property group to reset the property types + var propertiesReset = new List(); + foreach (var propertyGroup in PropertyGroups) { propertyGroup.ResetDirtyProperties(); foreach (var propertyType in propertyGroup.PropertyTypes) - { + { propertyType.ResetDirtyProperties(); + propertiesReset.Add(propertyType.Id); } } + //then loop through our property type collection since some might not exist on a property group + //but don't re-reset ones we've already done. + foreach (var propertyType in PropertyTypes.Where(x => propertiesReset.Contains(x.Id) == false)) + { + propertyType.ResetDirtyProperties(); + } } /// diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs index e53c7719ae..df0cf13052 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/DatabaseSchemaCreation.cs @@ -62,6 +62,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial {41, typeof (ServerRegistrationDto)} }; #endregion + /// /// Drops all Umbraco tables in the db /// @@ -90,29 +91,6 @@ namespace Umbraco.Core.Persistence.Migrations.Initial } } - /// - /// Drops all Umbraco tables in the db - /// - internal void UninstallDatabaseSchema() - { - foreach (var item in OrderedTables.OrderByDescending(x => x.Key)) - { - var tableNameAttribute = item.Value.FirstAttribute(); - string tableName = tableNameAttribute == null ? item.Value.Name : tableNameAttribute.Value; - - try - { - _database.DropTable(tableName); - } - catch (Exception ex) - { - //swallow this for now, not sure how best to handle this with diff databases... though this is internal - // and only used for unit tests. If this fails its because the table doesn't exist... generally! - LogHelper.Error("Could not drop table " + tableName, ex); - } - } - } - public DatabaseSchemaCreation(Database database) { _database = database; diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index f037d25bc2..1c764d88cf 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -152,29 +152,41 @@ namespace Umbraco.Core.Services foreach (var contentType in contentTypes) { //we need to determine if we need to refresh the xml content in the database. This is to be done when: - // - the item is not new (already existed in the db) - // - a content type changes it's alias - // - if a content type has it's property removed + // - the item is not new (already existed in the db) AND + // - a content type changes it's alias OR + // - if a content type has it's property removed OR + // - if a content type has a property whose alias has changed //here we need to check if the alias of the content type changed or if one of the properties was removed. var dirty = contentType as IRememberBeingDirty; - if (dirty != null - && !dirty.WasPropertyDirty("HasIdentity") //ensure it's now 'new' - && (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved"))) + if (dirty == null) continue; + + //check if any property types have changed their aliases (and not new property types) + var hasAnyPropertiesChangedAlias = contentType.PropertyTypes.Any(propType => + { + var dirtyProperty = propType as IRememberBeingDirty; + if (dirtyProperty == null) return false; + return dirtyProperty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new' + && dirtyProperty.WasPropertyDirty("Alias"); //alias has changed + }); + + if (dirty.WasPropertyDirty("HasIdentity") == false //ensure it's not 'new' + && (dirty.WasPropertyDirty("Alias") || dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") || hasAnyPropertiesChangedAlias)) { - //if the alias was changed then we only need to update the xml structures for content of the current content type. - //if a property was deleted then we need to update the xml structures for any content of the current content type - // and any of the content type's child content types. - if (dirty.WasPropertyDirty("Alias") && !dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved")) + //If the alias was changed then we only need to update the xml structures for content of the current content type. + //If a property was deleted or a property alias was changed then we need to update the xml structures for any + // content of the current content type and any of the content type's child content types. + if (dirty.WasPropertyDirty("Alias") + && dirty.WasPropertyDirty("HasPropertyTypeBeenRemoved") == false && hasAnyPropertiesChangedAlias == false) { //if only the alias changed then only update the current content type toUpdate.Add(contentType); } else { - //if a property was deleted (and maybe the alias changed too), then update all content of the current content type + //if a property was deleted or alias changed, then update all content of the current content type // and all of it's desscendant doc types. toUpdate.AddRange(contentType.DescendantsAndSelf()); - } + } } } diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 5bf656e8a4..6bb9dbcb9d 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -389,6 +389,7 @@ ContentTypeControlNew.ascx + ASPXCodeBehind ContentTypeControlNew.ascx diff --git a/src/Umbraco.Web/Security/WebSecurity.cs b/src/Umbraco.Web/Security/WebSecurity.cs index e800550949..e7551ae2ea 100644 --- a/src/Umbraco.Web/Security/WebSecurity.cs +++ b/src/Umbraco.Web/Security/WebSecurity.cs @@ -366,34 +366,23 @@ namespace Umbraco.Web.Security /// /// The umbraco user context ID. public string UmbracoUserContextId - { - - //TODO: Clean this up!! We also have extension methods in StringExtensions for decrypting/encrypting in med trust - // ... though an existing cookie may fail decryption, in that case they'd just get logged out. no problems. - + { get { - // zb-00004 #29956 : refactor cookies names & handling if (StateHelper.Cookies.HasCookies && StateHelper.Cookies.UserContext.HasValue) - return StateHelper.Cookies.UserContext.GetValue(); - try { - var encTicket = StateHelper.Cookies.UserContext.GetValue(); - if (string.IsNullOrEmpty(encTicket) == false) + try { - var formsAuthenticationTicket = FormsAuthentication.Decrypt(encTicket); - if (formsAuthenticationTicket != null) - return formsAuthenticationTicket.UserData; + var encTicket = StateHelper.Cookies.UserContext.GetValue(); + if (string.IsNullOrEmpty(encTicket) == false) + { + return encTicket.DecryptWithMachineKey(); + } + } + catch (HttpException ex) + { + // we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set } - } - catch (HttpException) - { - // we swallow this type of exception as it happens if a legacy (pre 4.8.1) cookie is set - } - catch (ArgumentException ex) - { - // we swallow this one because it's 99.99% certaincy is legacy based. We'll still log it, though - LogHelper.Error(typeof(WebSecurity), "An error occurred reading auth cookie value", ex); } return ""; } @@ -408,19 +397,11 @@ namespace Umbraco.Web.Security if (string.IsNullOrEmpty(value) == false) { - var ticket = new FormsAuthenticationTicket(1, - value, - DateTime.Now, - DateTime.Now.AddDays(1), - false, - value, - FormsAuthentication.FormsCookiePath); + // Encrypt the value + var encTicket = value.EncryptWithMachineKey(); - // Encrypt the ticket. - FormsAuthentication.Encrypt(ticket); - // Create new cookie. - StateHelper.Cookies.UserContext.SetValue(value, 1); + StateHelper.Cookies.UserContext.SetValue(encTicket, 1); } else { 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 8c69de4c8f..4d7dcc48ea 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -91,13 +91,13 @@ namespace umbraco.controls protected void Page_Load(object sender, EventArgs e) { - pp_newTab.Text = ui.Text("newtab", CurrentUser); - pp_alias.Text = ui.Text("alias", CurrentUser); - pp_name.Text = ui.Text("name", CurrentUser); - pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", CurrentUser); - pp_description.Text = ui.Text("editcontenttype", "description", CurrentUser); - pp_icon.Text = ui.Text("icon", CurrentUser); - pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", CurrentUser); + pp_newTab.Text = ui.Text("newtab", Security.CurrentUser); + pp_alias.Text = ui.Text("alias", Security.CurrentUser); + pp_name.Text = ui.Text("name", Security.CurrentUser); + pp_allowedChildren.Text = ui.Text("allowedchildnodetypes", Security.CurrentUser); + pp_description.Text = ui.Text("editcontenttype", "description", Security.CurrentUser); + pp_icon.Text = ui.Text("icon", Security.CurrentUser); + pp_thumbnail.Text = ui.Text("editcontenttype", "thumbnail", Security.CurrentUser); // we'll disable this... @@ -334,6 +334,13 @@ namespace umbraco.controls _contentType.AllowAtRoot = allowAtRoot.Checked; _contentType.Save(); + + // 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() || asyncState.HasAnyPropertyAliasChanged(_contentType)) + { + _contentType.RebuildXmlStructuresForContent(); + } } Trace.Write("ContentTypeControlNew", "task completing"); @@ -1056,35 +1063,35 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); protected void gpw_Delete(object sender, EventArgs e) { //Add the async operation to the page - Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, (GenericPropertyWrapper)sender)); + Page.RegisterAsyncTask(new PageAsyncTask(BeginAsyncDeleteOperation, EndAsyncDeleteOperation, HandleAsyncSaveTimeout, (GenericPropertyWrapper) sender)); //create the save task to be executed async _asyncDeleteTask = genericPropertyWrapper => - { - Trace.Write("ContentTypeControlNew", "executing task"); + { + Trace.Write("ContentTypeControlNew", "executing task"); + + if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) + { + _contentType.ContentTypeItem.RemovePropertyType(genericPropertyWrapper.PropertyType.Alias); + _contentType.Save(); + } + else + { + //if it is not a document type or a media type, then continue to call the legacy delete() method. + //the new API for document type and media type's will ensure that the data is removed correctly and that + //the cache is flushed correctly (using events). If it is not one of these types, we'll rever to the + //legacy operation (... like for members i suppose ?) + genericPropertyWrapper.GenricPropertyControl.PropertyType.delete(); + + } + + Trace.Write("ContentTypeControlNew", "task completing"); + }; - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { - _contentType.ContentTypeItem.RemovePropertyType(gpw.PropertyType.Alias); - _contentType.Save(); - } - else - { - //if it is not a document type or a media type, then continue to call the legacy delete() method. - //the new API for document type and media type's will ensure that the data is removed correctly and that - //the cache is flushed correctly (using events). If it is not one of these types, we'll rever to the - //legacy operation (... like for members i suppose ?) - gpw.GenricPropertyControl.PropertyType.delete(); - - }; - Trace.Write("ContentTypeControlNew", "task completing"); - //execute the async tasks Page.ExecuteRegisteredAsyncTasks(); - } - #endregion #region "Tab" Pane