Copied to clipboard

Flag this post as spam?

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


  • Nigel Wilson 944 posts 2076 karma points
    Aug 30, 2015 @ 07:30
    Nigel Wilson
    0

    Dynamically Added Properties on Document Type

    Hey I am rebuilding the IPN package in V7 and have struck a small hiccup.

    My code receives all the data from Paypal, then loops through all the fields and checks that the properties exist on the document type, if not it is added. Then I again loop through the fields and apply the values to the property.

    The issue I have is that the first time I run a test the properties are added, but the values are not. Subsequently tho the values are saved fine.

    The relevant section of my code is below:

    foreach (var item in paypalItems)
    {
    if (!paypalDoc.HasProperty(item.key.ToString()))
    {
    UmbracoHelper.AddDocumentTypeProperty(item.key); //custom method to add property to document type
    }
    }
    
    // add values
    foreach (var item in paypalItems)
    {
    // set value
    paypalDoc.SetValue(item.key.ToLower(), item.value);
    }
    

    I tried putting a System.Threading.Thread.Sleep(1000); between the 2 loops but this didn't help.

    What am I missing please

    Cheers, Nigel

  • Nigel Wilson 944 posts 2076 karma points
    Aug 31, 2015 @ 03:43
    Nigel Wilson
    0

    So have solved the issue and as usual, a breakdown in logic within my code.

    I was creating a new document based on existing properties, then adding the new properties, and then trying to add the values to the new properties. As I had instantiated the new documents prior to adding the new properties, it was failing.

    Refactoring the code so that the new properties were added, then the new document created sorted the problem.

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 09, 2016 @ 11:27
    Jon R. Humphrey
    0

    Nigel,

    Could you share your solution as I've run into the same issue and am kind of stuck?

    Thanks in advance!

    Jon

  • Nigel Wilson 944 posts 2076 karma points
    Feb 10, 2016 @ 21:39
    Nigel Wilson
    0

    Hi Jon

    My package isn't in a shape to be able to provide the source code for - sorry, but bad organisational skills :-)

    However, below is my helper class that adds the properties to the document type which should be all you need... Only a couple of things to change (NAMESPACE & DOCUMENTTYPE)

    using System.Collections.Specialized;
    using System.Linq;
    using Umbraco.Core.Models;
    using Umbraco.Core.Services;
    
    namespace YOURNAMESPACE
    {
        public class UmbracoHelper
        {
            private static IDataTypeService dataTypeService = Umbraco.Core.ApplicationContext.Current.Services.DataTypeService;
            private static IDataTypeDefinition[] dataTypeDefinitions = dataTypeService.GetAllDataTypeDefinitions().ToArray();
            private static IDataTypeDefinition definition = dataTypeDefinitions.FirstOrDefault(p => p.Name.ToLower() == "textstring");
            private static IContentTypeService contentTypeService = Umbraco.Core.ApplicationContext.Current.Services.ContentTypeService;
            private static IContentType paypalContentType = contentTypeService.GetContentType(YOURDOCUMENTTYPEHERE));
    
            public static bool AddDocumentTypeProperty(NameValueCollection docTypeProperties)
            {
                try
                {
                    var items = docTypeProperties.AllKeys.SelectMany(docTypeProperties.GetValues, (k, v) => new { key = k, value = v });
    
                    foreach (var item in items)
                    {
                        if (!paypalContentType.PropertyTypeExists(item.key.ToLower()))
                        {
                            paypalContentType.AddPropertyType(new PropertyType(definition) { Name = item.key.ToString(), Alias = item.key.ToLower() });
                        }
                    }
                    contentTypeService.Save(paypalContentType);
                    return true;
                }
                catch
                {
                    return false;
                }
            }
        }
    }
    

    Hope this helps - keep me posted if I can assist further.

    Cheers, Nigel

  • Jon R. Humphrey 164 posts 455 karma points c-trib
    Feb 12, 2016 @ 19:29
    Jon R. Humphrey
    0

    NIgel,

    Thanks for this, I am almost there with it too!

    Sadly, while your snippet seems to work with a single document type, I'm trying to add this new property to all the instances of certain doctypes, here's my code, which errors on the doctype.AddPropertyType() method with a "Object reference not set to an instance of an object." message:

      private static bool AddLatestNewsToSiteDocTypes()
      {
        try
        {
          //Grab hold of the content type service
          var contentTypeService = UmbracoContext.Current.Application.Services.ContentTypeService;
    
          //Use the CSO to get all the required doctypes
          var siteContentDocTypes = contentTypeService.GetAllContentTypes().Where(
          node =>
            node.Alias.InvariantEquals("NG_USK_Homepage") ||
            node.Alias.InvariantEquals("NG_USK_FrontPage") ||
            node.Alias.InvariantEquals("NG_USK_StandardPage") ||
            node.Alias.InvariantEquals("NG_USK_StandardPage_w_News") ||
            node.Alias.InvariantEquals("NG_USK_StandardPageChild") ||
            node.Alias.InvariantEquals("NG_USK_StandardPageChild_w_News")
            );
    
          // loopp through to check if the doctype has the property or add it otherwise:
          foreach (var doctype in siteContentDocTypes)
          {
            try
            {
              //Found it - go to next doctype
              if (doctype.PropertyTypeExists("NG_NEWS_DisplayWidget")) continue;
    
              var dataTypeService = Umbraco.Core.ApplicationContext.Current.Services.DataTypeService;
              IDataTypeDefinition[] dataTypeDefinitions = dataTypeService.GetAllDataTypeDefinitions().ToArray();
              var checkbox = dataTypeDefinitions.FirstOrDefault(p => p.PropertyEditorAlias == "Umbraco.Truefalse");
    
              doctype.AddPropertyType(new PropertyType(checkbox)
              {
                Name = "Display Latest News Widget",
                Alias = "NG_NEWS_DisplayWidget",
                Description = "[Optional] Show the two Latest News titles here with a link to each article.",
                Mandatory = false,
                SortOrder = 2
              }, "Sidebar");
    
              contentTypeService.Save(doctype); //save the new property to the doctype
    
            }
            catch (Exception err)
            {
              // Get stack trace for the exception with source file information
              var st = new StackTrace(err, true);
              // Get the top stack frame
              var frame = st.GetFrame(0);
              // Get the line number from the stack frame
              var line = frame.GetFileLineNumber();
              LogHelper.Warn(typeof(BootstrapLatestNews),
                "ERROR ON: AddLatestNewsToSiteDocTypes - " + doctype.Alias + " ~ " + err.Message + "[" + line + "]:" + st);
            }
          }
          //Grab hold of the content service this time
          var contentService = UmbracoContext.Current.Application.Services.ContentService;
          //Refresh the content tree so we don't have to do it manually
          contentService.RebuildXmlStructures();
          //Add this even to the logs for our records
          LogHelper.Info<BootstrapLatestNews>("LATEST NEWS MODULE INSTALLER: Home Node and children were just saved and the xml tree was rebuilt");
    
          return true;
        }
        catch (Exception err)
        {
          // Get stack trace for the exception with source file information
          var st = new StackTrace(err, true);
          // Get the top stack frame
          var frame = st.GetFrame(0);
          // Get the line number from the stack frame
          var line = frame.GetFileLineNumber();
          LogHelper.Warn(typeof(BootstrapLatestNews),
            "ERROR ON: AddLatestNewsToSiteDocTypes - " + err.Message + "[" + line + "]:" + st);
          return false;
        }
      }
    

    Any thoughts?

Please Sign in or register to post replies

Write your reply to:

Draft