diff --git a/src/Umbraco.Core/EnumExtensions.cs b/src/Umbraco.Core/EnumExtensions.cs index 1443a27876..b2e5f32c9a 100644 --- a/src/Umbraco.Core/EnumExtensions.cs +++ b/src/Umbraco.Core/EnumExtensions.cs @@ -41,5 +41,43 @@ namespace Umbraco.Core return (num & nums) > 0; } + + /// + /// Sets a flag of the given input enum + /// + /// + /// Enum to set flag of + /// Flag to set + /// A new enum with the flag set + public static T SetFlag(this T input, T flag) + where T : Enum + { + var i = Convert.ToUInt64(input); + var f = Convert.ToUInt64(flag); + + // bitwise OR to set flag f of enum i + var result = i | f; + + return (T)Enum.ToObject(typeof(T), result); + } + + /// + /// Unsets a flag of the given input enum + /// + /// + /// Enum to unset flag of + /// Flag to unset + /// A new enum with the flag unset + public static T UnsetFlag(this T input, T flag) + where T : Enum + { + var i = Convert.ToUInt64(input); + var f = Convert.ToUInt64(flag); + + // bitwise AND combined with bitwise complement to unset flag f of enum i + var result = i & ~f; + + return (T)Enum.ToObject(typeof(T), result); + } } } diff --git a/src/Umbraco.Tests/CoreThings/EnumExtensionsTests.cs b/src/Umbraco.Tests/CoreThings/EnumExtensionsTests.cs index 72a55cee85..4a0c1d0f41 100644 --- a/src/Umbraco.Tests/CoreThings/EnumExtensionsTests.cs +++ b/src/Umbraco.Tests/CoreThings/EnumExtensionsTests.cs @@ -51,5 +51,47 @@ namespace Umbraco.Tests.CoreThings else Assert.IsFalse(value.HasFlagAny(test)); } + + [TestCase(TreeUse.None, TreeUse.None, TreeUse.None)] + [TestCase(TreeUse.None, TreeUse.Main, TreeUse.Main)] + [TestCase(TreeUse.None, TreeUse.Dialog, TreeUse.Dialog)] + [TestCase(TreeUse.None, TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main, TreeUse.None, TreeUse.Main)] + [TestCase(TreeUse.Main, TreeUse.Main, TreeUse.Main)] + [TestCase(TreeUse.Main, TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main, TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.None, TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.Main, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.Dialog, TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.None, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Main, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog)] + public void SetFlagTests(TreeUse value, TreeUse flag, TreeUse expected) + { + Assert.AreEqual(expected, value.SetFlag(flag)); + } + + [TestCase(TreeUse.None, TreeUse.None, TreeUse.None)] + [TestCase(TreeUse.None, TreeUse.Main, TreeUse.None)] + [TestCase(TreeUse.None, TreeUse.Dialog, TreeUse.None)] + [TestCase(TreeUse.None, TreeUse.Main | TreeUse.Dialog, TreeUse.None)] + [TestCase(TreeUse.Main, TreeUse.None, TreeUse.Main)] + [TestCase(TreeUse.Main, TreeUse.Main, TreeUse.None)] + [TestCase(TreeUse.Main, TreeUse.Dialog, TreeUse.Main)] + [TestCase(TreeUse.Main, TreeUse.Main | TreeUse.Dialog, TreeUse.None)] + [TestCase(TreeUse.Dialog, TreeUse.None, TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.Main, TreeUse.Dialog)] + [TestCase(TreeUse.Dialog, TreeUse.Dialog, TreeUse.None)] + [TestCase(TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog, TreeUse.None)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.None, TreeUse.Main | TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Main, TreeUse.Dialog)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Dialog, TreeUse.Main)] + [TestCase(TreeUse.Main | TreeUse.Dialog, TreeUse.Main | TreeUse.Dialog, TreeUse.None)] + public void UnsetFlagTests(TreeUse value, TreeUse flag, TreeUse expected) + { + Assert.AreEqual(expected, value.UnsetFlag(flag)); + } } } diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeMapDefinition.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeMapDefinition.cs index e18861e0dd..95101da4e3 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeMapDefinition.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeMapDefinition.cs @@ -225,8 +225,10 @@ namespace Umbraco.Web.Models.Mapping target.MandatoryMessage = source.Validation.MandatoryMessage; target.ValidationRegExp = source.Validation.Pattern; target.ValidationRegExpMessage = source.Validation.PatternMessage; - target.Variations = source.AllowCultureVariant ? ContentVariation.Culture : ContentVariation.Nothing; - + target.Variations = source.AllowCultureVariant + ? target.Variations.SetFlag(ContentVariation.Culture) + : target.Variations.UnsetFlag(ContentVariation.Culture); + if (source.Id > 0) target.Id = source.Id; @@ -397,9 +399,9 @@ namespace Umbraco.Web.Models.Mapping if (!(target is IMemberType)) { - target.Variations = ContentVariation.Nothing; - if (source.AllowCultureVariant) - target.Variations |= ContentVariation.Culture; + target.Variations = source.AllowCultureVariant + ? target.Variations.SetFlag(ContentVariation.Culture) + : target.Variations.UnsetFlag(ContentVariation.Culture); } // handle property groups and property types