public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue) { if (editorValue.Value == null || editorValue.Value.ToString().IsNullOrWhiteSpace()) { return(string.Empty); } try { var value = JsonConvert.DeserializeObject <VortoValue>(editorValue.Value.ToString()); if (value.Values != null) { var dtd = VortoHelper.GetTargetDataTypeDefinition(value.DtdGuid); var preValues = ApplicationContext.Current.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(dtd.Id); var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias); var keys = value.Values.Keys.ToArray(); foreach (var key in keys) { var propData = new ContentPropertyData(value.Values[key], preValues, new Dictionary <string, object>()); var newValue = propEditor.ValueEditor.ConvertEditorToDb(propData, value.Values[key]); value.Values[key] = (newValue == null) ? null : JToken.FromObject(newValue); } } return(JsonConvert.SerializeObject(value)); } catch (Exception ex) { LogHelper.Error <VortoPropertyValueEditor>("Error converting DB value to Editor", ex); } return(base.ConvertEditorToDb(editorValue, currentValue)); }
public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null) { return(string.Empty); } try { var value = JsonConvert.DeserializeObject <VortoValue>(property.Value.ToString()); var dtd = VortoHelper.GetTargetDataTypeDefinition(value.DtdGuid); var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias); var propType = new PropertyType(dtd); var keys = value.Values.Keys.ToArray(); foreach (var key in keys) { var prop = new Property(propType, value.Values[key] == null ? null : value.Values[key].ToString()); var newValue = propEditor.ValueEditor.ConvertDbToString(prop, propType, dataTypeService); value.Values[key] = newValue; } property.Value = JsonConvert.SerializeObject(value); } catch (Exception ex) { LogHelper.Error <VortoPropertyValueEditor>("Error converting DB value to String", ex); } return(base.ConvertDbToString(property, propertyType, dataTypeService)); }
public Type GetPropertyValueType(PublishedPropertyType propertyType) { var innerPropType = VortoHelper.GetInnerPublishedPropertyType(propertyType); return(innerPropType != null ? typeof(VortoValue <>).MakeGenericType(innerPropType.ClrType) : typeof(VortoValue <object>)); }
public override string ConvertDbToString(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null || property.Value.ToString().IsNullOrWhiteSpace()) { return(string.Empty); } // Something weird is happening in core whereby ConvertDbToString is getting // called loads of times on publish, forcing the property value to get converted // again, which in tern screws up the values. To get round it, we create a // dummy property copying the original properties value, this way not overwriting // the original property value allowing it to be re-converted again later var prop2 = new Property(propertyType, property.Value); try { var value = JsonConvert.DeserializeObject <VortoValue>(property.Value.ToString()); if (value.Values != null) { // If the DTD Guid isn't set (probably because someone has made the value manually) // then do a lookup and store it if (value.DtdGuid == Guid.Empty) { var vortoDtd = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId); value.DtdGuid = vortoDtd.Key; } var dtd = VortoHelper.GetTargetDataTypeDefinition(value.DtdGuid); if (dtd != null) { var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias); var propType = new PropertyType(dtd); var keys = value.Values.Keys.ToArray(); foreach (var key in keys) { var prop = new Property(propType, value.Values[key] == null ? null : value.Values[key].ToString()); var newValue = propEditor.ValueEditor.ConvertDbToString(prop, propType, dataTypeService); value.Values[key] = newValue; } prop2.Value = JsonConvert.SerializeObject(value); } else { LogHelper.Error <VortoPropertyValueEditor>($"Unabled to locate target DTD for source DTD ${value.DtdGuid}", null); } } } catch (Exception ex) { LogHelper.Error <VortoPropertyValueEditor>("Error converting DB value to String", ex); } return(base.ConvertDbToString(prop2, propertyType, dataTypeService)); }
public override object ConvertSourceToObject(PublishedPropertyType propertyType, object source, bool preview) { var vortoValue = source as VortoValue; if (vortoValue != null) { var innerPropType = VortoHelper.GetInnerPublishedPropertyType(propertyType); if (innerPropType != null) { var type = GetPropertyValueType(propertyType); var model = Activator.CreateInstance(type); var dtdGuidProp = type.GetProperty("DtdGuid", BindingFlags.Instance | BindingFlags.Public); if (dtdGuidProp != null && dtdGuidProp.CanWrite) { dtdGuidProp.SetValue(model, vortoValue.DtdGuid); } var valuesProp = type.GetProperty("Values", BindingFlags.Instance | BindingFlags.Public); var valuesAdd = valuesProp.PropertyType.GetMethod("Add", new[] { typeof(string), innerPropType.ClrType }); var modelKeys = vortoValue.Values.Keys.ToArray(); foreach (var key in modelKeys) { var value = innerPropType.ConvertSourceToObject(vortoValue.Values[key], preview); if (innerPropType.ClrType.IsAssignableFrom(value.GetType())) { valuesAdd.Invoke(valuesProp.GetValue(model), new[] { key, value }); } else { var attempt = value.TryConvertTo(innerPropType.ClrType); if (attempt.Success) { valuesAdd.Invoke(valuesProp.GetValue(model), new[] { key, attempt.Result }); } } } return(model); } } return(base.ConvertSourceToObject(propertyType, source, preview)); }
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null || property.Value.ToString().IsNullOrWhiteSpace()) { return(string.Empty); } // Something weird is happening in core whereby ConvertDbToString is getting // called loads of times on publish, forcing the property value to get converted // again, which in tern screws up the values. To get round it, we create a // dummy property copying the original properties value, this way not overwriting // the original property value allowing it to be re-converted again later var prop2 = new Property(propertyType, property.Value); try { var value = JsonConvert.DeserializeObject <VortoValue>(property.Value.ToString()); if (value.Values != null) { var dtd = VortoHelper.GetTargetDataTypeDefinition(value.DtdGuid); var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias); var propType = new PropertyType(dtd); var keys = value.Values.Keys.ToArray(); foreach (var key in keys) { var prop = new Property(propType, value.Values[key] == null ? null : value.Values[key].ToString()); var newValue = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService); value.Values[key] = (newValue == null) ? null : JToken.FromObject(newValue); } prop2.Value = JsonConvert.SerializeObject(value); } } catch (Exception ex) { LogHelper.Error <VortoPropertyValueEditor>("Error converting DB value to Editor", ex); } return(base.ConvertDbToEditor(prop2, propertyType, dataTypeService)); }
public override bool IsValid(XElement node) { var name = GetName(node); var alias = GetAlias(node); var databaseType = GetDatabaseType(node); if (node.Name.LocalName == this.ItemType && name != string.Empty && alias != string.Empty && databaseType != string.Empty) { if (VortoHelper.IsVortoType(node, alias)) { //By returning false, we indicate that this type is NOT to be imported throw new System.Exception("Vorto datatype ignored. Do not worry."); } return(true); } return(base.IsValid(node)); }
public override object ConvertDataToSource(PublishedPropertyType propertyType, object source, bool preview) { try { if (source == null || source.ToString().IsNullOrWhiteSpace()) { return(null); } var model = JsonConvert.DeserializeObject <VortoValue>(source.ToString()); if (model.Values == null) { return(null); } var innerPropType = VortoHelper.GetInnerPublishedPropertyType(propertyType); if (innerPropType == null) { return(null); } var modelKeys = model.Values.Keys.ToArray(); foreach (var key in modelKeys) { model.Values[key] = innerPropType.ConvertDataToSource(model.Values[key], preview); } return(model); } catch (Exception e) { LogHelper.Error <VortoValueConverter>("Error converting Vorto value", e); } return(null); }
private static T DoInnerGetVortoValue <T>(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false, T defaultValue = default(T)) { if (content.HasValue(propertyAlias)) { var prop = content.GetProperty(propertyAlias); var vortoModel = prop.Value as VortoValue; if (vortoModel != null && vortoModel.Values != null) { // Get the serialized value var bestMatchCultureName = vortoModel.FindBestMatchCulture(cultureName); if (!bestMatchCultureName.IsNullOrWhiteSpace() && vortoModel.Values.ContainsKey(bestMatchCultureName) && vortoModel.Values[bestMatchCultureName] != null && !vortoModel.Values[bestMatchCultureName].ToString().IsNullOrWhiteSpace()) { var value = vortoModel.Values[bestMatchCultureName]; // Get target datatype var targetDataType = VortoHelper.GetTargetDataTypeDefinition(vortoModel.DtdGuid); // Umbraco has the concept of a IPropertyEditorValueConverter which it // also queries for property resolvers. However I'm not sure what these // are for, nor can I find any implementations in core, so am currently // just ignoring these when looking up converters. // NB: IPropertyEditorValueConverter not to be confused with // IPropertyValueConverter which are the ones most people are creating var properyType = CreateDummyPropertyType( targetDataType.Id, targetDataType.PropertyEditorAlias, content.ContentType); var inPreviewMode = UmbracoContext.Current != null ? UmbracoContext.Current.InPreviewMode : false; // Try convert data to source // We try this first as the value is stored as JSON not // as XML as would occur in the XML cache as in the act // of concerting to XML this would ordinarily get called // but with JSON it doesn't, so we try this first var converted1 = properyType.ConvertDataToSource(value, inPreviewMode); if (converted1 is T) { return((T)converted1); } var convertAttempt = converted1.TryConvertTo <T>(); if (convertAttempt.Success) { return(convertAttempt.Result); } // Try convert source to object // If the source value isn't right, try converting to object var converted2 = properyType.ConvertSourceToObject(converted1, inPreviewMode); if (converted2 is T) { return((T)converted2); } convertAttempt = converted2.TryConvertTo <T>(); if (convertAttempt.Success) { return(convertAttempt.Result); } // Try just converting convertAttempt = value.TryConvertTo <T>(); if (convertAttempt.Success) { return(convertAttempt.Result); } // Still not right type so return default value return(defaultValue); } } } return(recursive && content.Parent != null ? content.Parent.DoInnerGetVortoValue <T>(propertyAlias, cultureName, recursive, defaultValue) : defaultValue); }
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { var propertyValue = property?.Value?.ToString(); if (propertyValue.IsNullOrWhiteSpace()) { return(string.Empty); } // Something weird is happening in core whereby ConvertDbToEditor is getting // called loads of times on publish, forcing the property value to get converted // again, which in tern screws up the values. To get round it, we create a // dummy property copying the original properties value, this way not overwriting // the original property value allowing it to be re-converted again later var prop2 = new Property(propertyType, property.Value); try { VortoValue value = null; // Does the value look like JSON and does it look like a vorto value? if (propertyValue.DetectIsJson() && propertyValue.IndexOf("dtdGuid") != -1) { value = JsonConvert.DeserializeObject <VortoValue>(propertyValue); } else { // Doesn't look like a vorto value so we are going to assume it got converted // from a normal prop editor to a vorto editor, so lets construct a VortoValue var dataTypeDef = dataTypeService.GetDataTypeDefinitionById(propertyType.DataTypeDefinitionId); string primaryLanguage = null; // Look for primary language in prevalues var preValues = dataTypeService.GetPreValuesCollectionByDataTypeId(dataTypeDef.Id)?.PreValuesAsDictionary; if (preValues != null) { // We need to store the current value inder a language key so try and find the best key to store it under primaryLanguage = preValues.ContainsKey("primaryLanguage") && !preValues["primaryLanguage"].Value.IsNullOrWhiteSpace() ? preValues["primaryLanguage"].Value : null; } // No explicit primary language set, so try and work out the best match if (primaryLanguage.IsNullOrWhiteSpace()) { var currentCulture = Thread.CurrentThread.CurrentUICulture.Name; var languages = umbraco.cms.businesslogic.language.Language.GetAllAsList() .Select(x => x.CultureAlias) .ToList(); // Check for an exact culture match primaryLanguage = languages.FirstOrDefault(x => x == currentCulture); // Check for a close match if (primaryLanguage.IsNullOrWhiteSpace()) { primaryLanguage = languages.FirstOrDefault(x => x.Contains(currentCulture)); } // Check for a close match if (primaryLanguage.IsNullOrWhiteSpace()) { primaryLanguage = languages.FirstOrDefault(x => currentCulture.Contains(x)); } // Couldn't find a good enough match, just select the first language if (primaryLanguage.IsNullOrWhiteSpace()) { primaryLanguage = languages.FirstOrDefault(); } } if (!primaryLanguage.IsNullOrWhiteSpace()) { value = new VortoValue { DtdGuid = dataTypeDef.Key, Values = new Dictionary <string, object> { { primaryLanguage, property.Value } } }; } } if (value?.Values != null) { var dtd = VortoHelper.GetTargetDataTypeDefinition(value.DtdGuid); if (dtd != null) { var propEditor = PropertyEditorResolver.Current.GetByAlias(dtd.PropertyEditorAlias); var propType = new PropertyType(dtd); var keys = value.Values.Keys.ToArray(); foreach (var key in keys) { var prop = new Property(propType, value.Values[key] == null ? null : value.Values[key].ToString()); var newValue = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService); value.Values[key] = (newValue == null) ? null : JToken.FromObject(newValue); } prop2.Value = JsonConvert.SerializeObject(value); } else { LogHelper.Error <VortoPropertyValueEditor>($"Unabled to locate target DTD for source DTD ${value.DtdGuid}", null); } } } catch (Exception ex) { LogHelper.Error <VortoPropertyValueEditor>("Error converting DB value to Editor", ex); } return(base.ConvertDbToEditor(prop2, propertyType, dataTypeService)); }
private static T DoGetVortoValue <T>(this IPublishedContent content, string propertyAlias, string cultureName = null, bool recursive = false, T defaultValue = default(T)) { if (cultureName == null) { cultureName = Thread.CurrentThread.CurrentUICulture.Name; } if (content.HasVortoValue(propertyAlias, cultureName, recursive)) { var prop = content.GetProperty(propertyAlias, recursive); if (prop.Value is VortoValue) { // Get the serialized value var vortoModel = prop.Value as VortoValue; var value = vortoModel.Values[cultureName]; // If the value is of type T, just return it //if (value is T) // return (T)value; // Get target datatype var targetDataType = VortoHelper.GetTargetDataTypeDefinition(vortoModel.DtdGuid); // Umbraco has the concept of a IPropertyEditorValueConverter which it // also queries for property resolvers. However I'm not sure what these // are for, nor can I find any implementations in core, so am currently // just ignoring these when looking up converters. // NB: IPropertyEditorValueConverter not to be confused with // IPropertyValueConverter which are the ones most people are creating var properyType = CreateDummyPropertyType(targetDataType.Id, targetDataType.PropertyEditorAlias, content.ContentType); var converters = PropertyValueConvertersResolver.Current.Converters.ToArray(); // In umbraco, there are default value converters that try to convert the // value if all else fails. The problem is, they are also in the list of // converters, and the means for filtering these out is internal, so // we currently have to try ALL converters to see if they can convert // rather than just finding the most appropreate. If the ability to filter // out default value converters becomes public, the following logic could // and probably should be changed. foreach (var converter in converters.Where(x => x.IsConverter(properyType))) { // Convert the type using a found value converter var value2 = converter.ConvertDataToSource(properyType, value, false); // If the value is of type T, just return it if (value2 is T) { return((T)value2); } // Value is not final value type, so try a regular type conversion aswell var convertAttempt = value2.TryConvertTo <T>(); if (convertAttempt.Success) { return(convertAttempt.Result); } } // Value is not final value type, so try a regular type conversion var convertAttempt2 = value.TryConvertTo <T>(); if (convertAttempt2.Success) { return(convertAttempt2.Result); } return(default(T)); } if (prop.Value is T) { return((T)prop.Value); } return(default(T)); } return(defaultValue); }
private XElement CreateContentType(XElement node) { var infoNode = GetInfoNode(node); var keyAttr = GetKeyAttribute(node); if (keyAttr.Equals(Guid.Empty)) { var key = GetKey(infoNode); var alias = GetAlias(infoNode); node.Add(new XAttribute("Key", key)); node.Add(new XAttribute("Alias", alias)); } var hasVortoProperties = false; var propertiesNode = GetPropertiesNode(node); if (propertiesNode != null) { var properties = propertiesNode.Elements("GenericProperty"); foreach (var property in properties) { var propertyType = GetPropertyType(property); if (propertyType != string.Empty) { propertyType = PropertyTypeHelper.GetUpdatedAlias(propertyType); if (VortoHelper.IsVortoType(propertyType)) { var propertyDefinition = GetPropertyDefinition(property); var vortoDataType = VortoHelper.GetDataType(propertyDefinition); if (vortoDataType != null) { propertyType = vortoDataType.PropertyEditorAlias; property.Element("Definition").SetValue(vortoDataType.Guid); hasVortoProperties = true; property.Add(new XElement("Variations", "Culture")); } } } property.Element("Type").SetValue(propertyType); } } if (hasVortoProperties) { infoNode.Add(new XElement("Variations", "Culture")); } //Rename Structure/DocumentType to Structure/ContentType var structureNode = GetStructureNode(node); if (structureNode != null) { foreach (var docTypeNode in structureNode.Elements("DocumentType")) { docTypeNode.Name = "ContentType"; } } return(node); }