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.
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.
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.
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;
}
}
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:
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
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.
Nigel,
Could you share your solution as I've run into the same issue and am kind of stuck?
Thanks in advance!
Jon
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)
Hope this helps - keep me posted if I can assist further.
Cheers, Nigel
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:
Any thoughts?
is working on a reply...