2017-09-12 16:22:16 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Text.RegularExpressions;
|
|
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
|
|
using Newtonsoft.Json.Linq;
|
|
|
|
|
|
using Umbraco.Core;
|
|
|
|
|
|
using Umbraco.Core.Composing;
|
|
|
|
|
|
using Umbraco.Core.Logging;
|
|
|
|
|
|
using Umbraco.Core.Models;
|
|
|
|
|
|
using Umbraco.Core.Models.Editors;
|
|
|
|
|
|
using Umbraco.Core.PropertyEditors;
|
|
|
|
|
|
using Umbraco.Core.Services;
|
|
|
|
|
|
|
|
|
|
|
|
namespace Umbraco.Web.PropertyEditors
|
|
|
|
|
|
{
|
2018-01-24 13:37:14 +01:00
|
|
|
|
[ValueEditor(Constants.PropertyEditors.Aliases.NestedContent, "Nested Content", "nestedcontent", ValueType = "JSON", Group = "lists", Icon = "icon-thumbnail-list")]
|
2017-09-12 16:22:16 +02:00
|
|
|
|
public class NestedContentPropertyEditor : PropertyEditor
|
|
|
|
|
|
{
|
2017-09-20 20:06:46 +02:00
|
|
|
|
private readonly Lazy<PropertyEditorCollection> _propertyEditors;
|
2017-09-14 11:41:46 +02:00
|
|
|
|
|
2017-09-12 16:22:16 +02:00
|
|
|
|
internal const string ContentTypeAliasPropertyKey = "ncContentTypeAlias";
|
|
|
|
|
|
|
|
|
|
|
|
private IDictionary<string, object> _defaultPreValues;
|
|
|
|
|
|
public override IDictionary<string, object> DefaultPreValues
|
|
|
|
|
|
{
|
|
|
|
|
|
get => _defaultPreValues;
|
|
|
|
|
|
set => _defaultPreValues = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-20 20:06:46 +02:00
|
|
|
|
public NestedContentPropertyEditor(ILogger logger, Lazy<PropertyEditorCollection> propertyEditors)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
: base (logger)
|
|
|
|
|
|
{
|
2017-09-14 11:41:46 +02:00
|
|
|
|
_propertyEditors = propertyEditors;
|
|
|
|
|
|
|
2017-09-12 16:22:16 +02:00
|
|
|
|
// Setup default values
|
|
|
|
|
|
_defaultPreValues = new Dictionary<string, object>
|
|
|
|
|
|
{
|
2018-01-24 11:44:44 +01:00
|
|
|
|
{NestedContentConfigurationEditor.ContentTypesPreValueKey, ""},
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{"minItems", 0},
|
|
|
|
|
|
{"maxItems", 0},
|
|
|
|
|
|
{"confirmDeletes", "1"},
|
|
|
|
|
|
{"showIcons", "1"}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-20 20:06:46 +02:00
|
|
|
|
// has to be lazy else circular dep in ctor
|
|
|
|
|
|
private PropertyEditorCollection PropertyEditors => _propertyEditors.Value;
|
|
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
private static IContentType GetElementType(JObject item)
|
|
|
|
|
|
{
|
|
|
|
|
|
var contentTypeAlias = item[ContentTypeAliasPropertyKey]?.ToObject<string>();
|
|
|
|
|
|
return string.IsNullOrEmpty(contentTypeAlias)
|
|
|
|
|
|
? null
|
|
|
|
|
|
: Current.Services.ContentTypeService.Get(contentTypeAlias);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-12 16:22:16 +02:00
|
|
|
|
#region Pre Value Editor
|
|
|
|
|
|
|
2018-01-24 11:44:44 +01:00
|
|
|
|
protected override ConfigurationEditor CreateConfigurationEditor()
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2018-01-24 11:44:44 +01:00
|
|
|
|
return new NestedContentConfigurationEditor();
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
#region DataType Configuration
|
|
|
|
|
|
|
2018-01-15 17:32:45 +01:00
|
|
|
|
public class Configuration
|
2017-10-17 17:43:15 +02:00
|
|
|
|
{
|
2017-10-25 13:23:14 +02:00
|
|
|
|
public NestedContentType[] ContentTypes { get; set; }
|
2017-10-17 17:43:15 +02:00
|
|
|
|
public int? MinItems { get; set; }
|
|
|
|
|
|
public int? MaxItems { get; set; }
|
|
|
|
|
|
public bool ConfirmDeletes { get; set; }
|
|
|
|
|
|
public bool ShowIcons { get; set; }
|
|
|
|
|
|
public bool HideLabel { get; set; }
|
2017-10-25 13:23:14 +02:00
|
|
|
|
|
|
|
|
|
|
public class NestedContentType
|
|
|
|
|
|
{
|
|
|
|
|
|
[JsonProperty("ncAlias")]
|
|
|
|
|
|
public string Alias { get; set; }
|
|
|
|
|
|
[JsonProperty("ncTabAlias")]
|
|
|
|
|
|
public string Tab { get; set; }
|
|
|
|
|
|
[JsonProperty("nameTemplate")]
|
|
|
|
|
|
public string Template { get; set; }
|
|
|
|
|
|
}
|
2017-10-17 17:43:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-15 17:32:45 +01:00
|
|
|
|
public override object DeserializeConfiguration(string json)
|
2017-10-17 17:43:15 +02:00
|
|
|
|
{
|
2018-01-15 17:32:45 +01:00
|
|
|
|
return JsonConvert.DeserializeObject<Configuration>(json);
|
|
|
|
|
|
|
|
|
|
|
|
// fixme - can we have issues converting true/1 and false/0?
|
|
|
|
|
|
//var d = preValues.PreValuesAsDictionary;
|
|
|
|
|
|
//return new Configuration
|
|
|
|
|
|
//{
|
|
|
|
|
|
// ContentTypes = d.TryGetValue("contentTypes", out var preValue)
|
|
|
|
|
|
// ? JsonConvert.DeserializeObject<Configuration.NestedContentType[]>(preValue.Value)
|
|
|
|
|
|
// : Array.Empty<Configuration.NestedContentType>(),
|
|
|
|
|
|
// MinItems = d.TryGetValue("minItems", out preValue) && int.TryParse(preValue.Value, out var minItems) ? (int?) minItems : null,
|
|
|
|
|
|
// MaxItems = d.TryGetValue("maxItems", out preValue) && int.TryParse(preValue.Value, out var maxItems) ? (int?) maxItems : null,
|
|
|
|
|
|
// ConfirmDeletes = d.TryGetValue("confirmDeletes", out preValue) && preValue.Value == "1",
|
|
|
|
|
|
// ShowIcons = d.TryGetValue("showIcons", out preValue) && preValue.Value == "1",
|
|
|
|
|
|
// HideLabel = d.TryGetValue("hideLabel", out preValue) && preValue.Value == "1"
|
|
|
|
|
|
//};
|
2017-10-17 17:43:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2017-09-12 16:22:16 +02:00
|
|
|
|
#region Value Editor
|
|
|
|
|
|
|
2018-01-24 13:37:14 +01:00
|
|
|
|
protected override ValueEditor CreateValueEditor() => new NestedContentPropertyValueEditor(Attribute, PropertyEditors);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2018-01-24 13:37:14 +01:00
|
|
|
|
internal class NestedContentPropertyValueEditor : ValueEditor
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-09-14 11:41:46 +02:00
|
|
|
|
private readonly PropertyEditorCollection _propertyEditors;
|
|
|
|
|
|
|
2018-01-24 13:37:14 +01:00
|
|
|
|
public NestedContentPropertyValueEditor(ValueEditorAttribute attribute, PropertyEditorCollection propertyEditors)
|
|
|
|
|
|
: base(attribute)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-09-14 11:41:46 +02:00
|
|
|
|
_propertyEditors = propertyEditors;
|
|
|
|
|
|
Validators.Add(new NestedContentValidator(propertyEditors));
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-09-14 11:41:46 +02:00
|
|
|
|
internal ServiceContext Services => Current.Services;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
public override void ConfigureForDisplay(PreValueCollection preValues)
|
|
|
|
|
|
{
|
|
|
|
|
|
base.ConfigureForDisplay(preValues);
|
|
|
|
|
|
|
|
|
|
|
|
var asDictionary = preValues.PreValuesAsDictionary.ToDictionary(x => x.Key, x => x.Value.Value);
|
|
|
|
|
|
if (asDictionary.ContainsKey("hideLabel"))
|
|
|
|
|
|
{
|
|
|
|
|
|
var boolAttempt = asDictionary["hideLabel"].TryConvertTo<bool>();
|
|
|
|
|
|
if (boolAttempt.Success)
|
|
|
|
|
|
{
|
|
|
|
|
|
HideLabel = boolAttempt.Result;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#region DB to String
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
public override string ConvertDbToString(PropertyType propertyType, object propertyValue, IDataTypeService dataTypeService)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
if (propertyValue == null || string.IsNullOrWhiteSpace(propertyValue.ToString()))
|
2017-09-12 16:22:16 +02:00
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var value = JsonConvert.DeserializeObject<List<object>>(propertyValue.ToString());
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (value == null)
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
foreach (var o in value)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propValues = (JObject) o;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
var contentType = GetElementType(propValues);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (contentType == null)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propAliases = propValues.Properties().Select(x => x.Name).ToArray();
|
|
|
|
|
|
foreach (var propAlias in propAliases)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propAlias);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (propType == null)
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// type not found, and property is not system: just delete the value
|
|
|
|
|
|
if (IsSystemPropertyKey(propAlias) == false)
|
|
|
|
|
|
propValues[propAlias] = null;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// convert the value, and store the converted value
|
2017-09-14 11:41:46 +02:00
|
|
|
|
var propEditor = _propertyEditors[propType.PropertyEditorAlias];
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var convValue = propEditor.ValueEditor.ConvertDbToString(propType, propValues[propAlias], dataTypeService);
|
|
|
|
|
|
propValues[propAlias] = convValue;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
catch (InvalidOperationException)
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// deal with weird situations by ignoring them (no comment)
|
|
|
|
|
|
propValues[propAlias] = null;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
return JsonConvert.SerializeObject(value).ToXmlString<string>();
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
#region Convert database // editor
|
|
|
|
|
|
|
|
|
|
|
|
// note: there is NO variant support here
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
public override object ConvertDbToEditor(Property property, PropertyType propertyType, IDataTypeService dataTypeService)
|
|
|
|
|
|
{
|
2017-11-07 19:49:14 +01:00
|
|
|
|
if (property.GetValue() == null || string.IsNullOrWhiteSpace(property.GetValue().ToString()))
|
2017-09-12 16:22:16 +02:00
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
2017-11-07 19:49:14 +01:00
|
|
|
|
var value = JsonConvert.DeserializeObject<List<object>>(property.GetValue().ToString());
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (value == null)
|
|
|
|
|
|
return string.Empty;
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
foreach (var o in value)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propValues = (JObject) o;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
var contentType = GetElementType(propValues);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (contentType == null)
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propAliases = propValues.Properties().Select(x => x.Name).ToArray();
|
|
|
|
|
|
foreach (var propAlias in propAliases)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var propType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propAlias);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
if (propType == null)
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// type not found, and property is not system: just delete the value
|
|
|
|
|
|
if (IsSystemPropertyKey(propAlias) == false)
|
|
|
|
|
|
propValues[propAlias] = null;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// create a temp property with the value
|
|
|
|
|
|
var tempProp = new Property(propType);
|
|
|
|
|
|
tempProp.SetValue(propValues[propAlias] == null ? null : propValues[propAlias].ToString());
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// convert that temp property, and store the converted value
|
2017-09-14 11:41:46 +02:00
|
|
|
|
var propEditor = _propertyEditors[propType.PropertyEditorAlias];
|
2017-11-15 08:53:20 +01:00
|
|
|
|
var convValue = propEditor.ValueEditor.ConvertDbToEditor(tempProp, propType, dataTypeService);
|
|
|
|
|
|
propValues[propAlias] = convValue == null ? null : JToken.FromObject(convValue);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
catch (InvalidOperationException)
|
|
|
|
|
|
{
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// deal with weird situations by ignoring them (no comment)
|
|
|
|
|
|
propValues[propAlias] = null;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-15 08:53:20 +01:00
|
|
|
|
// return json
|
|
|
|
|
|
return value;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public override object ConvertEditorToDb(ContentPropertyData editorValue, object currentValue)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (editorValue.Value == null || string.IsNullOrWhiteSpace(editorValue.Value.ToString()))
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
|
|
var value = JsonConvert.DeserializeObject<List<object>>(editorValue.Value.ToString());
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
var contentType = GetElementType(propValues);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
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
|
2018-01-24 11:44:44 +01:00
|
|
|
|
var propConfiguration = Services.DataTypeService.GetDataType(propType.DataTypeId).Configuration;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
// Lookup the property editor
|
2017-09-14 11:41:46 +02:00
|
|
|
|
var propEditor = _propertyEditors[propType.PropertyEditorAlias];
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
// Create a fake content property data object
|
2018-01-20 12:09:15 +01:00
|
|
|
|
var contentPropData = new ContentPropertyData(propValues[propKey], propConfiguration);
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
// 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);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-24 11:44:44 +01:00
|
|
|
|
internal class NestedContentValidator : IValueValidator
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2017-09-14 11:41:46 +02:00
|
|
|
|
private readonly PropertyEditorCollection _propertyEditors;
|
|
|
|
|
|
|
|
|
|
|
|
public NestedContentValidator(PropertyEditorCollection propertyEditors)
|
|
|
|
|
|
{
|
|
|
|
|
|
_propertyEditors = propertyEditors;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-01-24 11:44:44 +01:00
|
|
|
|
public IEnumerable<ValidationResult> Validate(object rawValue, string valueType, object dataTypeConfiguration)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
|
|
|
|
|
var value = JsonConvert.DeserializeObject<List<object>>(rawValue.ToString());
|
|
|
|
|
|
if (value == null)
|
|
|
|
|
|
yield break;
|
|
|
|
|
|
|
2017-09-14 11:41:46 +02:00
|
|
|
|
var dataTypeService = Current.Services.DataTypeService;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
for (var i = 0; i < value.Count; i++)
|
|
|
|
|
|
{
|
|
|
|
|
|
var o = value[i];
|
2017-09-14 11:41:46 +02:00
|
|
|
|
var propValues = (JObject) o;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2017-10-17 17:43:15 +02:00
|
|
|
|
var contentType = GetElementType(propValues);
|
2018-01-20 12:09:15 +01:00
|
|
|
|
if (contentType == null) continue;
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2018-01-24 11:44:44 +01:00
|
|
|
|
var config = dataTypeService.GetDataType(propType.DataTypeId).Configuration;
|
2018-01-20 12:09:15 +01:00
|
|
|
|
var propertyEditor = _propertyEditors[propType.PropertyEditorAlias];
|
2017-09-12 16:22:16 +02:00
|
|
|
|
|
2017-09-14 11:41:46 +02:00
|
|
|
|
foreach (var validator in propertyEditor.ValueEditor.Validators)
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
2018-01-24 11:44:44 +01:00
|
|
|
|
foreach (var result in validator.Validate(propValues[propKey], propertyEditor.ValueEditor.ValueType, config))
|
2017-09-12 16:22:16 +02:00
|
|
|
|
{
|
|
|
|
|
|
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())
|
|
|
|
|
|
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 });
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
|
|
|
private static bool IsSystemPropertyKey(string propKey)
|
|
|
|
|
|
{
|
|
|
|
|
|
return propKey == "name" || propKey == "key" || propKey == ContentTypeAliasPropertyKey;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|