Copied to clipboard

Flag this post as spam?

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


  • Danny 10 posts 71 karma points
    Jun 17, 2016 @ 15:18
    Danny
    0

    Upgrading Fiasco from 4.7.1 to 7+

    Hi, I'm wondering if anyone can help.

    I'm not a master of Umbraco by any means, but have managed to upgrade them before; but never from a site this old. I managed to get it 6.0.0 then all went wrong(!).

    We have an old large news-based website (v4.7.1) built using custom XSLT/Marco scripts with a large involvement of uComponents and imageCropper/imageGen. It has multiple news elements including Events, Features, Blogs, Videos and News etc with 1000+ entries.

    We are looking to upgrade the website to the latest version (7+) having already got many Umbraco websites in 7 but this is the first one that could do with an upgrade/change of code from XSLT to Razor etc.

    We tried upgrading and I got as far as 6.0.0. After this the upgrade process ground to a halt due to many errors. Upon investigation we came to realise that there are a few code-breaking things; uComponents is no longer supported. Legacy business logic events didn't work, along with many Umbraco 4.7 plugins no longer supported. This is all fine and I'm happy to put some time into this, but I can't even get it to start the install/upgrade process, we're continually presented with the error;

    CS0234: The type or namespace name 'MacroComment' does not exist in the namespace 'umbraco.cms.businesslogic.macro' (are you missing an assembly reference?)
    [umbraco.cms.businesslogic.macro.MacroComment("Choose the Document type that you wish to be created")]
    

    If anyone could provide any advice on this matter or simply a process of how to get the stories and related media/files out the old site and into a new build? My experience of CMS Export and Import have always resulted in errors!?

    Many thanks in advance, Dan.

  • Mohammed BOUTEBEL 64 posts 103 karma points
    Jun 21, 2016 @ 15:31
    Mohammed BOUTEBEL
    0

    The legacy API still work and is still present on version 7. It is just not recommanded to use it because it will be removed from the 8 version. But it seems the class MacroComment has been removed from Umbraco API in 2013 :

    http://issues.umbraco.org/issue/U4-2896

    What is weird is that it is supposed to be useless and never used by anyone. So I suspect an old package using this class. Did you checked your web site in debug mode in VS ? That should give you some clues on which package can use the class MacroComment.

  • Danny 10 posts 71 karma points
    Jun 21, 2016 @ 15:45
    Danny
    0

    Hi Mohammed,

    Not tried it yet, I will give it another go with the debugger (although I can't always get that working). I noticed the same about the MacroComment - must be an old package!

    Have you had any luck upgrading from old websites to the new Umbraco 7 framework before? Bearing in mind i'm not a .Net Developer, I'm a Web Developer who can fumble his way through a few bits of code within complex databases ! :)

  • Mohammed BOUTEBEL 64 posts 103 karma points
    Jun 22, 2016 @ 09:05
    Mohammed BOUTEBEL
    0

    Yes, after a lot of work, especially rewriting the macros, replacing the old datatypes and packages by newer equivalent, it worked. But I agree, upgrading has always be a hard thing on Umbraco.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jun 21, 2016 @ 16:05
    Nicholas Westby
    0

    I recently upgraded a site from 6.x to 7.4.3. It too had uComponents. I basically updated to the latest Umbraco files and config changes and removed any legacy stuff (e.g., uComponents binaries). I created a page that performs a migration from uComponents to Archetype (uComponents was being used primarily for lists of data, which Archetype is good at). Umbraco retains data after the upgrade, even for properties with property editors that are no longer support (namely, the ones in uComponents). That makes it easier to transition to new property editors (i.e., you can still read the old data).

    Errors like the one you mentioned could possibly be caused by missing deleting some old binaries (e.g., by overwriting new/updated files, but not removing old files). Or perhaps a plugin that is referencing the old class, in which case you'd need to update/replace/remove/rebuild that plugin.

  • Danny 10 posts 71 karma points
    Jun 21, 2016 @ 16:56
    Danny
    0

    That's the part I'm lost on....

    I created a page that performs a migration from uComponents to Archetype (uComponents was being used primarily for lists of data, which Archetype is good at)

    I don't know how to go about changing old functionality ie. uComponents to newer components in V7 without being able to actually get V7 installed? It's a bit of catch 22 (forgive me if I'm being stupid).

    I think I'm going to try again, get to the same point and try to utilise the debugger to find out what's using the MacroComment. If I can it to recognise the upgrade process I'll be halfway there - as I really don't want to have to come up with a way to export bespoke news/video articles and import them along with the document type relationships (most that would fail as they are out of date) into V7...

    Sometimes I with it was all done with a push of a button(!)

    Thanks Nicholas.

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Jun 21, 2016 @ 17:30
    Nicholas Westby
    0

    Here's what I did:

    • Remove all references to uComponents before the upgrade.
    • Create a fake version of uComponents (easy, since it's open source) that can be used to parse the old data: Fake uComponents
    • Upgrade.
    • Run my code that converts data from uComponents to Archetype.

    Here's a code snippet that shows how I perform the conversion:

    /// <summary>
    /// Converts uComponent links to Archetype links.
    /// </summary>
    private void ConvertLinks()
    {
    
        // Anonymous types.
        var propMap = new[]
        {
            new
            {
                doctype = default(string),
                oldProp = default(string),
                newProp = default(string)
            }
        };
    
    
        // Variables.
        var services = ApplicationContext.Current.Services;
        var cts = services.ContentTypeService;
        var cs = services.ContentService;
        var links = CastTo(GetLinksToConvert(), propMap);
    
    
        // Convert links.
        foreach (var link in links)
        {
            var doctype = cts.GetContentType(link.doctype);
            var nodes = cs.GetContentOfContentType(doctype.Id);
            foreach (var potentialNode in nodes)
            {
    
                // Check old property.
                var node = CacheContentNode(potentialNode);
                if (!node.HasProperty(link.oldProp))
                {
                    LogHelper.Warn<Main>("Skipping upgrade for node {0} ({1}).",
                        () => node.Id, () => node.Name);
                    continue;
                }
    
    
                // Variables.
                var shouldPublish = node.HasPublishedVersion;
                var strValue = node.GetValue<string>(link.oldProp);
                var oldValue = DeserializeOldLink(strValue);
                if (oldValue != null)
                {
    
                    // Set new link.
                    var linkModel = ConvertLink(oldValue);
                    node.SetValue(link.newProp, linkModel.SerializeForPersistence());
                    LogHelper.Info<Main>("{3} link was upgraded for node with ID {0}. {1} to {2}.",
                        () => node.Id, () => link.oldProp, () => link.newProp,
                        () => oldValue.Mode.ToString());
    
    
                    // Store for later to be saved and published.
                    if (shouldPublish)
                    {
                        AddContentToPublish(node);
                    }
                    else
                    {
                        AddContentToSave(node);
                    }
    
                }
            }
        }
    
    }
    

    Essentially, I'm reading in the old uComponents property, transforming it from uComponents to Archetype, then setting the new Archetype property value.

    I also had a bit of transitional code that attempts to read from the new property. If the new property doesn't have a value set, the code reverts to reading the old property. However, now that I've upgraded everything, I deleted the old properties and the transitional code.

  • Dhiren 59 posts 201 karma points
    Nov 07, 2016 @ 05:26
    Dhiren
    0

    Hi Nicholas,

    I am facing issues while upgrading from 4.11.10 to 7.3.8 due to uComponents.

    I need your help on your solution. Can you please share your solution regarding fakeUComponents as well as entire method to migrate data from uComponents to Archtypes with steps?

    Please help me on this.

    Thanks in Advance.

    Dhiren

  • Nicholas Westby 2054 posts 7100 karma points c-trib
    Nov 08, 2016 @ 04:38
    Nicholas Westby
    0

    What sorts of issues are you facing? My above post pretty much covered it. In fact, you can probably just skip the parts about creating transitional code and just convert everything to Archetype.

    The only reason you'd need a FakeUComponents would be to read in the old property data during the conversion process. In particular, I pretty much just had to do that for the links that are part of uComponents. Here are a few of the files in my FakeUComponents project:


    // UrlPickerStates.cs:
    namespace uComponents.DataTypes.UrlPicker.Dto
    {
        using System;
        using System.Collections.Generic;
        using System.Web.Script.Serialization;
        using System.Xml.Linq;
        using umbraco;
        using Umbraco.Web;
    
    
        public class UrlPickerState
        {
    
            #region DTO Properties
    
            /// <summary>
            /// Title for the URL
            /// </summary>
            public string Title { get; set; }
            /// <summary>
            /// Mode that the URL picker is set to.  See UrlPickerMode.
            /// </summary>
            public UrlPickerMode Mode { get; set; }
            /// <summary>
            /// Node ID, if set, for a content node
            /// </summary>
            public int? NodeId { get; set; }
            /// <summary>
            /// URL which is the whole point of this datatype
            /// </summary>
            public string Url { get; set; }
            /// <summary>
            /// Whether the URL is to open in a new window
            /// </summary>
            public bool NewWindow { get; set; }
    
            #endregion
    
    
            public static UrlPickerState Deserialize(string serializedState)
            {
                // Can't deserialize an empty whatever
                if (string.IsNullOrEmpty(serializedState))
                {
                    return null;
                }
    
                // Default
                var state = new UrlPickerState();
    
                // Imply data format from the formatting of the serialized state
                UrlPickerDataFormat impliedDataFormat;
                if (serializedState.StartsWith("<"))
                {
                    impliedDataFormat = UrlPickerDataFormat.Xml;
                }
                else if (serializedState.StartsWith("{"))
                {
                    impliedDataFormat = UrlPickerDataFormat.Json;
                }
                else
                {
                    impliedDataFormat = UrlPickerDataFormat.Csv;
                }
    
                // Try to deserialize the string
                try
                {
                    switch (impliedDataFormat)
                    {
                        case UrlPickerDataFormat.Xml:
                            var dataNode = XElement.Parse(serializedState);
    
                            // Carefully try to get values out.  This is in case new versions add
                            // to the XML
                            var modeAttribute = dataNode.Attribute("mode");
                            if (modeAttribute != null)
                            {
                                state.Mode = (UrlPickerMode)Enum.Parse(typeof(UrlPickerMode), modeAttribute.Value, false);
                            }
    
                            var newWindowElement = dataNode.Element("new-window");
                            if (newWindowElement != null)
                            {
                                state.NewWindow = bool.Parse(newWindowElement.Value);
                            }
    
                            var nodeIdElement = dataNode.Element("node-id");
                            if (nodeIdElement != null)
                            {
                                int nodeId;
                                if (int.TryParse(nodeIdElement.Value, out nodeId))
                                {
                                    state.NodeId = nodeId;
                                }
                            }
    
                            var urlElement = dataNode.Element("url");
                            if (urlElement != null)
                            {
                                state.Url = urlElement.Value;
                            }
    
                            var linkTitleElement = dataNode.Element("link-title");
                            if (linkTitleElement != null && !string.IsNullOrEmpty(linkTitleElement.Value))
                            {
                                state.Title = linkTitleElement.Value;
                            }
    
                            break;
                        case UrlPickerDataFormat.Csv:
    
                            var parameters = serializedState.Split(',');
    
                            if (parameters.Length > 0)
                            {
                                state.Mode = (UrlPickerMode)Enum.Parse(typeof(UrlPickerMode), parameters[0], false);
                            }
                            if (parameters.Length > 1)
                            {
                                state.NewWindow = bool.Parse(parameters[1]);
                            }
                            if (parameters.Length > 2)
                            {
                                int nodeId;
                                if (int.TryParse(parameters[2], out nodeId))
                                {
                                    state.NodeId = nodeId;
                                }
                            }
                            if (parameters.Length > 3)
                            {
                                state.Url = parameters[3].Replace("&#45;", ",");
                            }
                            if (parameters.Length > 4)
                            {
                                if (!string.IsNullOrEmpty(parameters[4]))
                                {
                                    state.Title = parameters[4].Replace("&#45;", ",");
                                }
                            }
    
                            break;
                        case UrlPickerDataFormat.Json:
    
                            var jss = new JavaScriptSerializer();
                            state = jss.Deserialize<UrlPickerState>(serializedState);
    
                            // Check for old states
                            var untypedState = jss.DeserializeObject(serializedState);
                            if (untypedState is Dictionary<string, object>)
                            {
                                var dictState = (Dictionary<string, object>)untypedState;
    
                                if (dictState.ContainsKey("LinkTitle"))
                                {
                                    state.Title = (string)dictState["LinkTitle"];
    
                                    if (dictState.ContainsKey("NewWindow"))
                                    {
                                        // There was a short period where the UrlPickerMode values were
                                        // integers starting with zero, instead of one.  This period only
                                        // existed when both the "LinkTitle" and "NewWindow" keys were
                                        // used.
                                        state.Mode = (UrlPickerMode)((int)dictState["Mode"] + 1);
                                    }
                                }
                            }
    
                            break;
                        default:
                            throw new NotImplementedException();
                    }
    
                    // If the mode is a content node, get the url for the node
                    if (state.Mode == UrlPickerMode.Content && state.NodeId.HasValue && UmbracoContext.Current != null)
                    {
                        var n = uQuery.GetNode(state.NodeId.Value);
                        var url = n != null ? n.Url : "#";
    
                        if (!string.IsNullOrWhiteSpace(url))
                        {
                            state.Url = url;
                        }
    
                        if (string.IsNullOrWhiteSpace(state.Title) && n != null)
                        {
                            state.Title = n.Name;
                        }
                    }
                }
                catch (Exception ex)
                {
                    // Could not be deserialised, return null
                    state = null;
                }
    
                return state;
            }
    
        }
    }
    

    // UrlPickerDataFormat.cs
    namespace uComponents.DataTypes.UrlPicker
    {
        public enum UrlPickerDataFormat
        {
            /// <summary>
            /// Store as XML
            /// </summary>
            Xml,
            /// <summary>
            /// Store as comma delimited (CSV, single line)
            /// </summary>
            Csv,
            /// <summary>
            /// Store as a JSON object, which can be deserialized by .NET or JavaScript
            /// </summary>
            Json
        }
    }
    

    // UrlPickerMode.cs
    namespace uComponents.DataTypes.UrlPicker
    {
        public enum UrlPickerMode : int
        {
            /// <summary>
            /// URL string
            /// </summary>
            URL = 1,
            /// <summary>
            /// Content node
            /// </summary>
            Content = 2,
            /// <summary>
            /// Media node
            /// </summary>
            Media = 3,
            /// <summary>
            /// Upload a file
            /// </summary>
            Upload = 4
        }
    }
    

    The code is all open source, so you pretty much just copy/paste what you need.

Please Sign in or register to post replies

Write your reply to:

Draft