Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Jesse Andrews 129 posts 499 karma points
    Oct 04, 2019 @ 23:36
    Jesse Andrews
    0

    Having issues wiring up custom mapper

    I'm working on a mapper for a customized version of LeBlender that is compatible with umbraco 8, but I'm having trouble getting it to trigger. I've confirmed that it is added to the SyncValueMapperCollection, but I haven't had any luck getting it to trigger. I tried putting a breakpoint within the IsMapper method, but that isn't getting hit.

    My current code can be seen below.

    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    using uSync8.ContentEdition.Mapping;
    using uSync8.Core.Dependency;
    using Umbraco.Core.Logging;
    using Umbraco.Core;
    
    namespace BonsaiSeed.Toolkit.Umbraco.UsyncExtensions {
        public class LeBlenderContentMapper : SyncValueMapperBase, ISyncMapper {
            private IDataTypeService _dataTypeService;
            private ILogger _logger;
    
            public override string Name => "LeBlender Mapper";
    
            public override string[] Editors => new string[] {
                "Umbraco.Grid.html"
            };
    
            public LeBlenderContentMapper(IEntityService entityService, IDataTypeService dataTypeService, ILogger logger) : base(entityService) {
                _dataTypeService = dataTypeService;
                _logger = logger;
            }
    
            public override bool IsMapper(PropertyType propertyType) {
                return Editors.InvariantContains(propertyType.PropertyEditorAlias);
            }
    
            public override IEnumerable<uSyncDependency> GetDependencies(object value, string editorAlias, DependencyFlags flags) {
                if (value == null) {
                    return Enumerable.Empty<uSyncDependency>();
                }
                var stringValue = value.ToString();
                if (!IsJson(stringValue)) {
                    return Enumerable.Empty<uSyncDependency>();
                }
    
                if (!IsJsonArray(stringValue)) {
                    stringValue = $"[{stringValue}]";
                }
    
                var items = JsonConvert.DeserializeObject<IEnumerable<JObject>>(stringValue);
                var dependencies = new List<uSyncDependency>();
                if (items != null) {
                    foreach (var item in items) {
                        foreach (var val in item.Values()) {
                            _logger.Debug<LeBlenderContentMapper>($"Value: {val.ToString()}");
                            var dtdValue = val.Value<string>("dataTypeGuid");
    
                            if (Guid.TryParse(dtdValue, out Guid dtdGuid)) {
                                var prop = _dataTypeService.GetDataType(dtdGuid);
                                if (prop != null) {
                                    var mapper = SyncValueMapperFactory.GetMapper(prop.EditorAlias);
                                    if (mapper != null) {
                                        dependencies.AddRange(mapper.GetDependencies(val["value"], prop.EditorAlias, flags));
                                    }
                                }
                            }
                        }
                    }
                }
                return dependencies;
            }
    
            public override string GetExportValue(object value, string editorAlias) {
                if (value == null) {
                    return null;
                }
                var stringValue = value.ToString();
                if (!IsJson(stringValue)) {
                    return stringValue;
                }
    
                if (!IsJsonArray(stringValue)) {
                    stringValue = $"[{stringValue}]";
                }
    
                var items = JsonConvert.DeserializeObject<IEnumerable<JObject>>(stringValue);
                if (items != null) {
                    foreach (var item in items) {
                        foreach (var val in item.Values()) {
                            if (val["value"] != null) {
                                _logger.Debug<LeBlenderContentMapper>($"Value: {val.ToString()}");
                                var dtdValue = val.Value<string>("dataTypeGuid");
    
                                if (Guid.TryParse(dtdValue, out Guid dtdGuid)) {
                                    var prop = _dataTypeService.GetDataType(dtdGuid);
                                    if (prop != null) {
                                        var mapper = SyncValueMapperFactory.GetMapper(prop.EditorAlias);
                                        if (mapper != null) {
                                            val["value"] = mapper.GetExportValue(val["value"], prop.EditorAlias);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return items.ToString();
            }
    
            public override string GetImportValue(string value, string editorAlias) {
                if (value == null) {
                    return null;
                }
                if (!IsJson(value)) {
                    return value;
                }
    
                if (!IsJsonArray(value)) {
                    value = $"[{value}]";
                }
    
                var items = JsonConvert.DeserializeObject<IEnumerable<JObject>>(value);
                if (items != null) {
                    foreach (var item in items) {
                        foreach (var val in item.Values()) {
                            if (val["value"] != null) {
                                _logger.Debug<LeBlenderContentMapper>($"Value: {val.ToString()}");
                                var dtdValue = val.Value<string>("dataTypeGuid");
    
                                if (Guid.TryParse(dtdValue, out Guid dtdGuid)) {
                                    var prop = _dataTypeService.GetDataType(dtdGuid);
                                    if (prop != null) {
                                        var mapper = SyncValueMapperFactory.GetMapper(prop.EditorAlias);
                                        if (mapper != null) {
                                            val["value"] = mapper.GetImportValue(val["value"].ToString(), prop.EditorAlias);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                return items.ToString();
            }
            private bool IsJson(string val) {
                val = val.Trim();
                return (val.StartsWith("{") && val.EndsWith("}"))
                    || (val.StartsWith("[") && val.EndsWith("]"));
            }
    
            private bool IsJsonArray(string val) {
                val = val.Trim();
                return (val.StartsWith("[") && val.EndsWith("]"));
            }
        }
    }
    

    This is based of the version of the LeBlenderContentMapper from the umbraco 7 compatible version of usync.

    Any ideas why it might be failing to trigger?

    Also, there is a potential issue with how the GridMapper resolves the aliases of controls inside it, which is why it currently targets "Umbraco.Grid.html" instead of something more descriptive. See here for the bug report.

  • Kevin Jump 1517 posts 9724 karma points MVP 3x c-trib
    Oct 05, 2019 @ 06:25
    Kevin Jump
    0

    Hi Jesse

    I suppose the short answer is because the code that would trigger this is commented out in the GridMapper !

    https://github.com/KevinJump/uSync8/blob/v8/8.2/uSync8.ContentEdition/Mapping/Mappers/GridMapper.cs#L44

    To be honest I am not sure why that is - it 'looks' OK.

    The code that is there is for dependency checking, which isn't actually used in the core import/exporting of items rather when they are referenced in uSync.Complete export or publish.

    In general, you shouldn't need a value mapper for your control unless you are storing internal Umbraco int Ids for items within it (and then the strong advice for Umbraco 8 would be store the Guid Key-value instead!).

    but I will take a look and try to work out what I was thinking when I wrote all that code and then commented it out!

  • Jesse Andrews 129 posts 499 karma points
    Oct 07, 2019 @ 22:29
    Jesse Andrews
    0

    Thanks for the update. I had already updated most of the controls I use to use udis already, but there are a couple stragglers that still use ids that now have content tied to them. I am hoping to add mappers as a quick fix for this, so that I don't have to track down all of the affected existing content.

  • Kevin Jump 1517 posts 9724 karma points MVP 3x c-trib
    29 days ago
    Kevin Jump
    0

    Hi

    uSync 8.2.4 - now has the grid mapper in properly so your custom mappers should now get found and ran.

    https://github.com/KevinJump/uSync8/releases/tag/8.2.4

Please Sign in or register to post replies

Write your reply to:

Draft