From 42bd130a13c63b6565b5168df32a02e6f64ad082 Mon Sep 17 00:00:00 2001 From: Joe Glombek Date: Tue, 8 Oct 2024 16:37:53 +0100 Subject: [PATCH 1/2] Add a Cogworks.Meganav to Our.Umbraco.Meganav migrator --- .../Community/Meganav/MeganavToMeganavMigrator.cs | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs diff --git a/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs b/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs new file mode 100644 index 00000000..991c1243 --- /dev/null +++ b/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs @@ -0,0 +1,9 @@ +namespace uSync.Migrations.Migrators.Community.Meganav; + +[SyncMigrator("Cogworks.Meganav")] +[SyncDefaultMigrator] +public class MeganavToMeganavMigrator : SyncPropertyMigratorBase +{ + public override string GetEditorAlias(SyncMigrationDataTypeProperty dataTypeProperty, SyncMigrationContext context) + => "Our.Umbraco.Meganav"; +} From 8bff5a149bd335ba6626fb1734fb0c5ce924c3d7 Mon Sep 17 00:00:00 2001 From: Joe Glombek Date: Wed, 23 Oct 2024 16:31:42 +0100 Subject: [PATCH 2/2] Correct Meganav migration Meganav's auto-migrator doesn't kick in if using uSync Migrations! --- .../Meganav/MeganavToMeganavMigrator.cs | 116 +++++++++++++++++- 1 file changed, 114 insertions(+), 2 deletions(-) diff --git a/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs b/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs index 991c1243..e32817f1 100644 --- a/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs +++ b/uSync.Migrations.Migrators/Community/Meganav/MeganavToMeganavMigrator.cs @@ -1,9 +1,121 @@ +using System.Runtime.Serialization; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Umbraco.Cms.Core; +using Umbraco.Extensions; +using static Umbraco.Cms.Core.Models.Property; + namespace uSync.Migrations.Migrators.Community.Meganav; +/// +/// Based on https://github.com/callumbwhyte/meganav/tree/v9/dev/src/Our.Umbraco.Meganav/Migrations +/// [SyncMigrator("Cogworks.Meganav")] +[SyncMigrator("Meganav")] [SyncDefaultMigrator] public class MeganavToMeganavMigrator : SyncPropertyMigratorBase { - public override string GetEditorAlias(SyncMigrationDataTypeProperty dataTypeProperty, SyncMigrationContext context) - => "Our.Umbraco.Meganav"; + public override string GetEditorAlias(SyncMigrationDataTypeProperty dataTypeProperty, SyncMigrationContext context) + => "Our.Umbraco.Meganav"; + + public override string? GetContentValue(SyncMigrationContentProperty contentProperty, SyncMigrationContext context) + { + var oldStringValue = base.GetContentValue(contentProperty, context); + var data = JToken.Parse(string.IsNullOrEmpty(oldStringValue) ? "{}" : oldStringValue); + + var entities = ConvertToEntity(data, context); + var value = JsonConvert.SerializeObject(entities, new JsonSerializerSettings() { }); + + return value; + } + + private IEnumerable ConvertToEntity(JToken data, SyncMigrationContext context) + { + foreach (var item in data.Children()) + { + var entity = new MeganavEntity + { + Title = item.Value("title"), + Target = item.Value("target"), + Visible = !item.Value("naviHide") + }; + + + var id = item.Value("id"); + + UdiParser.TryParse(item.Value("udi"), out Udi udi); + + if (id > 0 || udi != null) + { + if (udi is GuidUdi guidUdi) + { + // UDI is healthy + + // UNDONE: the original source still obtains the object here but I think it's not needed. + // All I can see it'd do is check the node still exists, which is handled by the editor anyway. + } + else + { + // convert ID to key + guidUdi = new GuidUdi(UmbConstants.UdiEntityType.Document, context.GetKey(id)); + } + + entity.Udi = guidUdi; + } + else + { + entity.Url = item.Value("url"); + } + + var children = item.Value("children"); + + if (children != null) + { + entity.Children = ConvertToEntity(children, context); + } + + var ignoreProperties = new[] + { + "id", "key", "udi", "name", "title", "description", "target", "url", "children", "icon", "published", + "naviHide", "culture" + }; + + var settings = item.ToObject>(); + + settings.RemoveAll(x => ignoreProperties.InvariantContains(x.Key)); + + entity.Settings = settings; + + yield return entity; + } + } + + [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy))] + internal class MeganavEntity + { + [DataMember(Name = "title")] + public string Title { get; set; } + + [DataMember(Name = "url")] + public string Url { get; set; } + + [DataMember(Name = "target")] + public string Target { get; set; } + + [DataMember(Name = "visible")] + public bool Visible { get; set; } = true; + + [DataMember(Name = "udi")] + public GuidUdi Udi { get; set; } + + [DataMember(Name = "itemTypeId")] + public Guid? ItemTypeId { get; set; } + + [DataMember(Name = "settings")] + public IDictionary Settings { get; set; } + + [DataMember(Name = "children")] + public IEnumerable Children { get; set; } = new List(); + } }