public override IDictionary <string, object> ConvertDbToEditor(IDictionary <string, object> defaultPreVals, PreValueCollection persistedPreVals) { // re-format old style (v0.1.1) pre values if necessary NestedContentHelper.ConvertPreValueCollectionFromV011(persistedPreVals); return(base.ConvertDbToEditor(defaultPreVals, persistedPreVals)); }
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue) { if (editorValue.Value == null) { return(null); } var rawValue = editorValue.Value.ToString(); if (string.IsNullOrWhiteSpace(rawValue)) { return(null); } var value = JsonConvert.DeserializeObject <List <object> >(rawValue); if (value == null) { return(null); } // Issue #38 - Keep recursive property lookups working if (!value.Any()) { return(null); } // Process value for (var i = 0; i < value.Count; i++) { var o = value[i]; var propValues = ((JObject)o); var contentType = NestedContentHelper.GetContentTypeFromItem(propValues); if (contentType == null) { continue; } var propValueKeys = propValues.Properties().Select(x => x.Name).ToArray(); foreach (var propKey in propValueKeys) { var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType == null) { if (IsSystemPropertyKey(propKey) == false) { // Property missing so just delete the value propValues[propKey] = null; } } else { // Fetch the property types prevalue var propPreValues = Services.DataTypeService.GetPreValuesCollectionByDataTypeId( propType.DataTypeDefinitionId); // Lookup the property editor var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias); // Create a fake content property data object var contentPropData = new ContentPropertyData( propValues[propKey], propPreValues, new Dictionary <string, object>()); // Get the property editor to do it's conversion var newValue = propEditor.ValueEditor.ConvertEditorToDb(contentPropData, propValues[propKey]); // Store the value back propValues[propKey] = (newValue == null) ? null : JToken.FromObject(newValue); } } } return(JsonConvert.SerializeObject(value)); }
public IEnumerable <ValidationResult> Validate(object rawValue, PreValueCollection preValues, PropertyEditor editor) { var value = JsonConvert.DeserializeObject <List <object> >(rawValue.ToString()); if (value == null) { yield break; } IDataTypeService dataTypeService = ApplicationContext.Current.Services.DataTypeService; for (var i = 0; i < value.Count; i++) { var o = value[i]; var propValues = ((JObject)o); var contentType = NestedContentHelper.GetContentTypeFromItem(propValues); if (contentType == null) { continue; } var propValueKeys = propValues.Properties().Select(x => x.Name).ToArray(); foreach (var propKey in propValueKeys) { var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType != null) { PreValueCollection propPrevalues = dataTypeService.GetPreValuesCollectionByDataTypeId(propType.DataTypeDefinitionId); PropertyEditor propertyEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias); foreach (IPropertyValidator validator in propertyEditor.ValueEditor.Validators) { foreach (ValidationResult result in validator.Validate(propValues[propKey], propPrevalues, propertyEditor)) { result.ErrorMessage = "Item " + (i + 1) + " '" + propType.Name + "' " + result.ErrorMessage; yield return(result); } } // Check mandatory if (propType.Mandatory) { if (propValues[propKey] == null) { yield return(new ValidationResult("Item " + (i + 1) + " '" + propType.Name + "' cannot be null", new[] { propKey })); } else if (propValues[propKey].ToString().IsNullOrWhiteSpace() || (propValues[propKey].Type == JTokenType.Array && !propValues[propKey].HasValues)) { yield return(new ValidationResult("Item " + (i + 1) + " '" + propType.Name + "' cannot be empty", new[] { propKey })); } } // Check regex if (!propType.ValidationRegExp.IsNullOrWhiteSpace() && propValues[propKey] != null && !propValues[propKey].ToString().IsNullOrWhiteSpace()) { var regex = new Regex(propType.ValidationRegExp); if (!regex.IsMatch(propValues[propKey].ToString())) { yield return(new ValidationResult("Item " + (i + 1) + " '" + propType.Name + "' is invalid, it does not match the correct pattern", new[] { propKey })); } } } } } }
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService) { if (property.Value == null) { return(string.Empty); } var propertyValue = property.Value.ToString(); if (string.IsNullOrWhiteSpace(propertyValue)) { return(string.Empty); } var value = JsonConvert.DeserializeObject <List <object> >(propertyValue); if (value == null) { return(string.Empty); } // Process value PreValueCollection preValues = null; for (var i = 0; i < value.Count; i++) { var o = value[i]; var propValues = ((JObject)o); // convert from old style (v0.1.1) data format if necessary NestedContentHelper.ConvertItemValueFromV011(propValues, propertyType.DataTypeDefinitionId, ref preValues); var contentType = NestedContentHelper.GetContentTypeFromItem(propValues); if (contentType == null) { continue; } var propValueKeys = propValues.Properties().Select(x => x.Name).ToArray(); foreach (var propKey in propValueKeys) { var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propKey); if (propType == null) { if (IsSystemPropertyKey(propKey) == false) { // Property missing so just delete the value propValues[propKey] = null; } } else { try { // Create a fake property using the property and stored value var prop = new Property(propType, propValues[propKey] == null ? null : propValues[propKey].ToString()); // Lookup the property editor var propEditor = PropertyEditorResolver.Current.GetByAlias(propType.PropertyEditorAlias); // Get the editor to do it's conversion var newValue = propEditor.ValueEditor.ConvertDbToEditor(prop, propType, dataTypeService); // Store the value back propValues[propKey] = (newValue == null) ? null : JToken.FromObject(newValue); } catch (InvalidOperationException) { // https://github.com/umco/umbraco-nested-content/issues/111 // Catch any invalid cast operations as likely means courier failed due to missing // or trashed item so couldn't convert a guid back to an int propValues[propKey] = null; } } } } // Return the strongly-typed object, Umbraco will handle the JSON serializing/parsing, then Angular can handle it directly return(value); }