From 6377b9aa50539e456b0cef8d7ef7b5e95ca5e8a1 Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 23 Jan 2014 13:33:58 +1100 Subject: [PATCH] Fixes some underlying type conversions, fixes more of the member type wrapping, updates contenttypecontrolnew to work with member types properly, ensures the property type cache is cleared when member types change. --- src/Umbraco.Core/Models/ContentBase.cs | 6 +- src/Umbraco.Core/Models/Member.cs | 78 +++++------ .../Cache/CacheRefresherEventHandler.cs | 28 +++- .../Cache/DistributedCacheExtensions.cs | 74 +++++++--- .../controls/ContentTypeControlNew.ascx.cs | 128 ++++++++++-------- .../businesslogic/member/MemberType.cs | 10 ++ 6 files changed, 197 insertions(+), 127 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentBase.cs b/src/Umbraco.Core/Models/ContentBase.cs index 9a5e735e9e..9531860051 100644 --- a/src/Umbraco.Core/Models/ContentBase.cs +++ b/src/Umbraco.Core/Models/ContentBase.cs @@ -306,10 +306,8 @@ namespace Umbraco.Core.Models /// Value as a public virtual TPassType GetValue(string propertyTypeAlias) { - if (Properties[propertyTypeAlias].Value is TPassType) - return (TPassType)Properties[propertyTypeAlias].Value; - - return (TPassType)Convert.ChangeType(Properties[propertyTypeAlias].Value, typeof(TPassType)); + var convertAttempt = Properties[propertyTypeAlias].Value.TryConvertTo(); + return convertAttempt.Success ? convertAttempt.Result : default(TPassType); } /// diff --git a/src/Umbraco.Core/Models/Member.cs b/src/Umbraco.Core/Models/Member.cs index 7bd43233b2..48683071d6 100644 --- a/src/Umbraco.Core/Models/Member.cs +++ b/src/Umbraco.Core/Models/Member.cs @@ -207,13 +207,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.IsApproved].Value == null) - return default(bool); - - if (Properties[Constants.Conventions.Member.IsApproved].Value is bool) - return (bool)Properties[Constants.Conventions.Member.IsApproved].Value; - - return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsApproved].Value, typeof(bool)); + var tryConvert = Properties[Constants.Conventions.Member.IsApproved].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(bool); } set { @@ -233,13 +232,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.IsLockedOut].Value == null) - return default(bool); - - if (Properties[Constants.Conventions.Member.IsLockedOut].Value is bool) - return (bool)Properties[Constants.Conventions.Member.IsLockedOut].Value; - - return (bool)Convert.ChangeType(Properties[Constants.Conventions.Member.IsLockedOut].Value, typeof(bool)); + var tryConvert = Properties[Constants.Conventions.Member.IsLockedOut].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(bool); } set { @@ -259,13 +257,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.LastLoginDate].Value == null) - return default(DateTime); - - if (Properties[Constants.Conventions.Member.LastLoginDate].Value is DateTime) - return (DateTime)Properties[Constants.Conventions.Member.LastLoginDate].Value; - - return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLoginDate].Value, typeof(DateTime)); + var tryConvert = Properties[Constants.Conventions.Member.LastLoginDate].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(DateTime); } set { @@ -285,13 +282,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value == null) - return default(DateTime); - - if (Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value is DateTime) - return (DateTime)Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value; - - return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value, typeof(DateTime)); + var tryConvert = Properties[Constants.Conventions.Member.LastPasswordChangeDate].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(DateTime); } set { @@ -311,13 +307,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.LastLockoutDate].Value == null) - return default(DateTime); - - if (Properties[Constants.Conventions.Member.LastLockoutDate].Value is DateTime) - return (DateTime)Properties[Constants.Conventions.Member.LastLockoutDate].Value; - - return (DateTime)Convert.ChangeType(Properties[Constants.Conventions.Member.LastLockoutDate].Value, typeof(DateTime)); + var tryConvert = Properties[Constants.Conventions.Member.LastLockoutDate].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(DateTime); } set { @@ -338,13 +333,12 @@ namespace Umbraco.Core.Models { get { - if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value == null) - return default(int); - - if (Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value is int) - return (int)Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value; - - return (int)Convert.ChangeType(Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value, typeof(int)); + var tryConvert = Properties[Constants.Conventions.Member.FailedPasswordAttempts].Value.TryConvertTo(); + if (tryConvert.Success) + { + return tryConvert.Result; + } + return default(int); } set { diff --git a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs index cb1dd65029..22dd740310 100644 --- a/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs +++ b/src/Umbraco.Web/Cache/CacheRefresherEventHandler.cs @@ -86,6 +86,8 @@ namespace Umbraco.Web.Cache ContentTypeService.SavedMediaType += ContentTypeServiceSavedMediaType; ContentTypeService.DeletedContentType += ContentTypeServiceDeletedContentType; ContentTypeService.DeletedMediaType += ContentTypeServiceDeletedMediaType; + MemberTypeService.Saved += MemberTypeServiceSaved; + MemberTypeService.Deleted += MemberTypeServiceDeleted; //Bind to user events @@ -363,7 +365,7 @@ namespace Umbraco.Web.Cache } #endregion - #region Content/media Type event handlers + #region Content/media/member Type event handlers /// /// Fires when a media type is deleted /// @@ -384,6 +386,16 @@ namespace Umbraco.Web.Cache e.DeletedEntities.ForEach(contentType => DistributedCache.Instance.RemoveContentTypeCache(contentType)); } + /// + /// Fires when a member type is deleted + /// + /// + /// + static void MemberTypeServiceDeleted(IMemberTypeService sender, Core.Events.DeleteEventArgs e) + { + e.DeletedEntities.ForEach(contentType => DistributedCache.Instance.RemoveMemberTypeCache(contentType)); + } + /// /// Fires when a media type is saved /// @@ -402,7 +414,19 @@ namespace Umbraco.Web.Cache static void ContentTypeServiceSavedContentType(IContentTypeService sender, Core.Events.SaveEventArgs e) { e.SavedEntities.ForEach(contentType => DistributedCache.Instance.RefreshContentTypeCache(contentType)); - } + } + + /// + /// Fires when a member type is saved + /// + /// + /// + static void MemberTypeServiceSaved(IMemberTypeService sender, Core.Events.SaveEventArgs e) + { + e.SavedEntities.ForEach(x => DistributedCache.Instance.RefreshMemberTypeCache(x)); + } + + #endregion #region User event handlers diff --git a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs index 274705439e..f4f70e32ba 100644 --- a/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs +++ b/src/Umbraco.Web/Cache/DistributedCacheExtensions.cs @@ -353,7 +353,7 @@ namespace Umbraco.Web.Cache } #endregion - #region Content type cache + #region Document type cache /// /// Remove all cache for a given content type @@ -364,27 +364,11 @@ namespace Umbraco.Web.Cache { if (contentType != null) { - //dc.Refresh(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, contentType); dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), ContentTypeCacheRefresher.SerializeToJsonPayload(false, contentType)); } } - /// - /// Remove all cache for a given media type - /// - /// - /// - public static void RefreshMediaTypeCache(this DistributedCache dc, IMediaType mediaType) - { - if (mediaType != null) - { - //dc.Refresh(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, mediaType); - dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), - ContentTypeCacheRefresher.SerializeToJsonPayload(false, mediaType)); - } - } - /// /// Remove all cache for a given content type /// @@ -394,12 +378,29 @@ namespace Umbraco.Web.Cache { if (contentType != null) { - //dc.Remove(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, contentType); dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), ContentTypeCacheRefresher.SerializeToJsonPayload(true, contentType)); } } + #endregion + + #region Media type cache + + /// + /// Remove all cache for a given media type + /// + /// + /// + public static void RefreshMediaTypeCache(this DistributedCache dc, IMediaType mediaType) + { + if (mediaType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), + ContentTypeCacheRefresher.SerializeToJsonPayload(false, mediaType)); + } + } + /// /// Remove all cache for a given media type /// @@ -409,13 +410,46 @@ namespace Umbraco.Web.Cache { if (mediaType != null) { - //dc.Remove(new Guid(DistributedCache.ContentTypeCacheRefresherId), x => x.Id, mediaType); dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), ContentTypeCacheRefresher.SerializeToJsonPayload(true, mediaType)); } - } + } + #endregion + #region Media type cache + + /// + /// Remove all cache for a given media type + /// + /// + /// + public static void RefreshMemberTypeCache(this DistributedCache dc, IMemberType memberType) + { + if (memberType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), + ContentTypeCacheRefresher.SerializeToJsonPayload(false, memberType)); + } + } + + /// + /// Remove all cache for a given media type + /// + /// + /// + public static void RemoveMemberTypeCache(this DistributedCache dc, IMemberType memberType) + { + if (memberType != null) + { + dc.RefreshByJson(new Guid(DistributedCache.ContentTypeCacheRefresherId), + ContentTypeCacheRefresher.SerializeToJsonPayload(true, memberType)); + } + } + + #endregion + + #region Stylesheet Cache public static void RefreshStylesheetPropertyCache(this DistributedCache dc, global::umbraco.cms.businesslogic.web.StylesheetProperty styleSheetProperty) 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 9173f9f681..c621efb30a 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -292,8 +292,10 @@ namespace umbraco.controls //to avoid the multiple cache flushing when each property is set using the legacy ContentType class, //which has been reduced to the else-clause. //For IContentType and IMediaType the cache will only be flushed upon saving. - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { + //if (_contentType.ContentTypeItem is IContentType + // || _contentType.ContentTypeItem is IMediaType + // || _contentType.ContentTypeItem is IMemberType) + //{ _contentType.ContentTypeItem.Name = txtName.Text; _contentType.ContentTypeItem.Alias = txtAlias.Text; _contentType.ContentTypeItem.Icon = ddlIcons.SelectedValue; @@ -331,40 +333,40 @@ namespace umbraco.controls } _contentType.Save(); - } - else //Legacy approach for supporting MemberType - { - if (asyncState.HasNameChanged()) - _contentType.Text = txtName.Text; + //} + //else //Legacy approach for supporting MemberType + //{ + // if (asyncState.HasNameChanged()) + // _contentType.Text = txtName.Text; - if (asyncState.HasAliasChanged()) - _contentType.Alias = txtAlias.Text; + // if (asyncState.HasAliasChanged()) + // _contentType.Alias = txtAlias.Text; - _contentType.IconUrl = ddlIcons.SelectedValue; - _contentType.Description = description.Text; - _contentType.Thumbnail = ddlThumbnails.SelectedValue; + // _contentType.IconUrl = ddlIcons.SelectedValue; + // _contentType.Description = description.Text; + // _contentType.Thumbnail = ddlThumbnails.SelectedValue; - SavePropertyTypesLegacy(asyncState.SaveArgs); + // SavePropertyTypesLegacy(asyncState.SaveArgs); - var tabs = SaveTabs(); - foreach (var tab in tabs) - { - _contentType.SetTabName(tab.Item1, tab.Item2); - _contentType.SetTabSortOrder(tab.Item1, tab.Item3); - } + // var tabs = SaveTabs(); + // foreach (var tab in tabs) + // { + // _contentType.SetTabName(tab.Item1, tab.Item2); + // _contentType.SetTabSortOrder(tab.Item1, tab.Item3); + // } - _contentType.AllowedChildContentTypeIDs = SaveAllowedChildTypes(); - _contentType.AllowAtRoot = allowAtRoot.Checked; + // _contentType.AllowedChildContentTypeIDs = SaveAllowedChildTypes(); + // _contentType.AllowAtRoot = allowAtRoot.Checked; - _contentType.Save(); + // _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(); - } - } + // // 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"); }; @@ -1042,8 +1044,10 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); int propertyId = int.Parse(e.Item.Cells[0].Text); string rawName = string.Empty; - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { + //if (_contentType.ContentTypeItem is IContentType + // || _contentType.ContentTypeItem is IMediaType + // || _contentType.ContentTypeItem is IMemberType) + //{ var propertyType = _contentType.ContentTypeItem.PropertyTypes.FirstOrDefault(x => x.Id == propertyId); if (propertyType != null && string.IsNullOrEmpty(propertyType.Alias) == false) { @@ -1051,13 +1055,13 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); _contentType.ContentTypeItem.RemovePropertyType(propertyType.Alias); _contentType.Save(); } - } - else - { - cms.businesslogic.propertytype.PropertyType pt = cms.businesslogic.propertytype.PropertyType.GetPropertyType(propertyId); - rawName = pt.GetRawName(); - pt.delete(); - } + //} + //else + //{ + // cms.businesslogic.propertytype.PropertyType pt = cms.businesslogic.propertytype.PropertyType.GetPropertyType(propertyId); + // rawName = pt.GetRawName(); + // pt.delete(); + //} RaiseBubbleEvent(new object(), new SaveClickEventArgs("Property ´" + rawName + "´ deleted")); @@ -1128,20 +1132,22 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); //we need to re-set the UmbracoContext since it will be nulled and our cache handlers need it global::Umbraco.Web.UmbracoContext.Current = asyncState.UmbracoContext; - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { + //if (_contentType.ContentTypeItem is IContentType + // || _contentType.ContentTypeItem is IMediaType + // || _contentType.ContentTypeItem is IMemberType) + //{ _contentType.ContentTypeItem.RemovePropertyType(asyncState.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 ?) - asyncState.GenericPropertyWrapper.GenricPropertyControl.PropertyType.delete(); + //} + //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 ?) + // asyncState.GenericPropertyWrapper.GenricPropertyControl.PropertyType.delete(); - } + //} Trace.Write("ContentTypeControlNew", "task completing"); }; @@ -1277,15 +1283,17 @@ jQuery(document).ready(function() {{ refreshDropDowns(); }}); { if (txtNewTab.Text.Trim() != "") { - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { + //if (_contentType.ContentTypeItem is IContentType + // || _contentType.ContentTypeItem is IMediaType + // || _contentType.ContentTypeItem is IMemberType) + //{ _contentType.ContentTypeItem.AddPropertyGroup(txtNewTab.Text); _contentType.Save(); - } - else - { - _contentType.AddVirtualTab(txtNewTab.Text); - } + //} + //else + //{ + // _contentType.AddVirtualTab(txtNewTab.Text); + //} LoadContentType(); @@ -1317,15 +1325,17 @@ Umbraco.Controls.TabView.onActiveTabChange(function(tabviewid, tabid, tabs) { if (e.CommandName == "Delete") { int propertyGroupId = int.Parse(e.Item.Cells[0].Text); - if (_contentType.ContentTypeItem is IContentType || _contentType.ContentTypeItem is IMediaType) - { + //if (_contentType.ContentTypeItem is IContentType + // || _contentType.ContentTypeItem is IMediaType + // || _contentType.ContentTypeItem is IMemberType) + //{ var propertyGroup = _contentType.ContentTypeItem.PropertyGroups.FirstOrDefault(x => x.Id == propertyGroupId); if (propertyGroup != null && string.IsNullOrEmpty(propertyGroup.Name) == false) { _contentType.ContentTypeItem.PropertyGroups.Remove(propertyGroup.Name); _contentType.Save(); } - } + //} _contentType.DeleteVirtualTab(propertyGroupId); diff --git a/src/umbraco.cms/businesslogic/member/MemberType.cs b/src/umbraco.cms/businesslogic/member/MemberType.cs index e0bcd8bf73..7df9c80fa3 100644 --- a/src/umbraco.cms/businesslogic/member/MemberType.cs +++ b/src/umbraco.cms/businesslogic/member/MemberType.cs @@ -247,6 +247,16 @@ namespace umbraco.cms.businesslogic.member } #endregion + #region Protected Methods + + protected override void setupNode() + { + var memberType = ApplicationContext.Current.Services.MemberTypeService.Get(Id); + SetupNode(memberType); + } + + #endregion + #region Private Methods private void SetupNode(IMemberType contentType)