public IDataValueEditor GetValueEditor(IDataEditor editor, IDataType dataType) { // Lock just in case multiple threads uses the cache at the same time. lock (_dictionaryLocker) { // We try and get the dictionary based on the IDataEditor alias, // this is here just in case a data type can have more than one value data editor. // If this is not the case this could be simplified quite a bit, by just using the inner dictionary only. IDataValueEditor?valueEditor; if (_valueEditorCache.TryGetValue(editor.Alias, out Dictionary <int, IDataValueEditor>?dataEditorCache)) { if (dataEditorCache.TryGetValue(dataType.Id, out valueEditor)) { return(valueEditor); } valueEditor = editor.GetValueEditor(dataType.Configuration); dataEditorCache[dataType.Id] = valueEditor; return(valueEditor); } valueEditor = editor.GetValueEditor(dataType.Configuration); _valueEditorCache[editor.Alias] = new Dictionary <int, IDataValueEditor> { [dataType.Id] = valueEditor }; return(valueEditor); } }
private void MockObjects(out PropertyValidationService validationService, out IDataType dt) { var textService = new Mock <ILocalizedTextService>(); textService.Setup(x => x.Localize(It.IsAny <string>(), It.IsAny <string>(), Thread.CurrentThread.CurrentCulture, null)).Returns("Localized text"); var dataTypeService = new Mock <IDataTypeService>(); IDataType dataType = Mock.Of <IDataType>( x => x.Configuration == (object)string.Empty && // irrelevant but needs a value x.DatabaseType == ValueStorageType.Nvarchar && x.EditorAlias == Constants.PropertyEditors.Aliases.TextBox); dataTypeService.Setup(x => x.GetDataType(It.IsAny <int>())).Returns(() => dataType); dt = dataType; // new data editor that returns a TextOnlyValueEditor which will do the validation for the properties IDataEditor dataEditor = Mock.Of <IDataEditor>( x => x.Type == EditorType.PropertyValue && x.Alias == Constants.PropertyEditors.Aliases.TextBox); Mock.Get(dataEditor).Setup(x => x.GetValueEditor(It.IsAny <object>())) .Returns(new CustomTextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object, Mock.Of <IShortStringHelper>(), new JsonNetSerializer(), Mock.Of <IIOHelper>())); var propEditors = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor })); validationService = new PropertyValidationService(propEditors, dataTypeService.Object, Mock.Of <ILocalizedTextService>(), new ValueEditorCache()); }
// Umbraco.Code.MapAll -Udi -HasPrevalues -IsSystemDataType -Id -Trashed -Key // Umbraco.Code.MapAll -ParentId -Path private static void Map(IDataEditor source, DataTypeBasic target, MapperContext context) { target.Alias = source.Alias; target.Group = source.Group; target.Icon = source.Icon; target.Name = source.Name; }
/// <summary> /// Initializes a new instance of the <see cref="DataType"/> class. /// </summary> public DataType(IDataEditor editor, int parentId = -1) { _editor = editor ?? throw new ArgumentNullException(nameof(editor)); ParentId = parentId; // set a default configuration Configuration = _editor.GetConfigurationEditor().DefaultConfigurationObject; }
private void UpdateEditableTargets(TData target, IDataEditor <TData> exception) { _editableTarget = target; foreach (var editor in _editors) { if (editor != exception) { editor.EditableTarget = _editableTarget; } } }
private DataType CreateDataType(IDataEditor dataEditor, Action <DataType> config) { #if NETFRAMEWORK var dataType = new DataType(dataEditor); #else var dataType = new DataType(dataEditor, _configurationEditorJsonSerializer); #endif config.Invoke(dataType); return(dataType); }
public void CanParseManifest_ParameterEditors() { const string json = @"{'parameterEditors': [ { alias: 'parameter1', name: 'My Parameter', view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html' }, { alias: 'parameter2', name: 'Another parameter', config: { key1: 'some config val' }, view: '~/App_Plugins/MyPackage/PropertyEditors/CsvEditor.html' }, { alias: 'parameter3', name: 'Yet another parameter' } ]}"; PackageManifest manifest = _parser.ParseManifest(json); Assert.AreEqual(3, manifest.ParameterEditors.Length); Assert.IsTrue(manifest.ParameterEditors.All(x => (x.Type & EditorType.MacroParameter) > 0)); IDataEditor editor = manifest.ParameterEditors[1]; Assert.AreEqual("parameter2", editor.Alias); Assert.AreEqual("Another parameter", editor.Name); IDictionary <string, object> config = editor.DefaultConfiguration; Assert.AreEqual(1, config.Count); Assert.IsTrue(config.ContainsKey("key1")); Assert.AreEqual("some config val", config["key1"]); IDataValueEditor valueEditor = editor.GetValueEditor(); Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/CsvEditor.html"), valueEditor.View); editor = manifest.ParameterEditors[2]; Assert.Throws <InvalidOperationException>(() => { IDataValueEditor valueEditor = editor.GetValueEditor(); }); }
public IDataEditor GetEditor(object data) { IDataEditor editor = null; if (!TypeEditor.TryGetValue(data.GetType(), out editor)) { return(null); } IDataEditor objectEditor = null; if (!ObjectEditors.TryGetValue(data, out objectEditor)) { objectEditor = assembly.CreateInstance(editor.GetType().FullName) as IDataEditor; ObjectEditors.Add(data, objectEditor); } return(objectEditor); }
private IEnumerable <DataTypeConfigurationFieldDisplay> MapPreValues(IDataEditor source, MapperContext context) { // this is a new data type, initialize default configuration // get the configuration editor, // get the configuration fields and map to UI, // get the configuration default values and map to UI var configurationEditor = source.GetConfigurationEditor(); var fields = context.MapEnumerable <ConfigurationField, DataTypeConfigurationFieldDisplay>(configurationEditor.Fields); var defaultConfiguration = configurationEditor.DefaultConfiguration; if (defaultConfiguration != null) { MapConfigurationFields(null, fields, defaultConfiguration); } return(fields); }
public void Add(IDataEditor <TData> editor) { if (_editors.Contains(editor)) { return; } _editors.AddLast(editor); editor.TargetUpdated += OnEditorUpdatesTarget; // update target editor.EditableTarget = _editableTarget; // update validation state var validatedEditor = editor as IValidatedComponent <TValidationResult>; if (validatedEditor != null) { UpdateEditorValidityState(validatedEditor); } }
internal static IEnumerable <ValidationResult> ValidatePropertyValue( ILocalizedTextService textService, IDataEditor editor, IDataType dataType, object postedValue, bool isRequired, string validationRegExp, string isRequiredMessage, string validationRegExpMessage) { // Retrieve default messages used for required and regex validatation. We'll replace these // if set with custom ones if they've been provided for a given property. var requiredDefaultMessages = new[] { textService.Localize("validation", "invalidNull"), textService.Localize("validation", "invalidEmpty") }; var formatDefaultMessages = new[] { textService.Localize("validation", "invalidPattern"), }; var valueEditor = editor.GetValueEditor(dataType.Configuration); foreach (var validationResult in valueEditor.Validate(postedValue, isRequired, validationRegExp)) { // If we've got custom error messages, we'll replace the default ones that will have been applied in the call to Validate(). if (isRequired && !string.IsNullOrWhiteSpace(isRequiredMessage) && requiredDefaultMessages.Contains(validationResult.ErrorMessage, StringComparer.OrdinalIgnoreCase)) { validationResult.ErrorMessage = isRequiredMessage; } if (!string.IsNullOrWhiteSpace(validationRegExp) && !string.IsNullOrWhiteSpace(validationRegExpMessage) && formatDefaultMessages.Contains(validationResult.ErrorMessage, StringComparer.OrdinalIgnoreCase)) { validationResult.ErrorMessage = validationRegExpMessage; } yield return(validationResult); } }
/// <summary> /// Determines whether an editor supports tags. /// </summary> public static bool IsTagsEditor(this IDataEditor editor) => editor.GetTagAttribute() != null;
// Umbraco.Code.MapAll private static void Map(IDataEditor source, PropertyEditorBasic target, MapperContext context) { target.Alias = source.Alias; target.Icon = source.Icon; target.Name = source.Name; }
public void CanParseManifest_PropertyEditors() { const string json = @"{'propertyEditors': [ { alias: 'Test.Test1', name: 'Test 1', editor: { view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html', valueType: 'int', hideLabel: true, validation: { 'required': true, 'Regex': '\\d*' } }, prevalues: { fields: [ { label: 'Some config 1', key: 'key1', view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val1.html', validation: { required: true } }, { label: 'Some config 2', key: 'key2', view: '~/App_Plugins/MyPackage/PropertyEditors/Views/pre-val2.html' } ] } }, { alias: 'Test.Test2', name: 'Test 2', isParameterEditor: true, defaultConfig: { key1: 'some default val' }, editor: { view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html', valueType: 'int', validation: { required : true, regex : '\\d*' } } } ]}"; PackageManifest manifest = _parser.ParseManifest(json); Assert.AreEqual(2, manifest.PropertyEditors.Length); IDataEditor editor = manifest.PropertyEditors[1]; Assert.IsTrue((editor.Type & EditorType.MacroParameter) > 0); Assert.IsNotEmpty(editor.DefaultConfiguration); Assert.AreEqual("some default val", editor.DefaultConfiguration["key1"]); editor = manifest.PropertyEditors[0]; Assert.AreEqual("Test.Test1", editor.Alias); Assert.AreEqual("Test 1", editor.Name); Assert.IsFalse((editor.Type & EditorType.MacroParameter) > 0); IDataValueEditor valueEditor = editor.GetValueEditor(); Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/MyEditor.html"), valueEditor.View); Assert.AreEqual("int", valueEditor.ValueType); Assert.IsTrue(valueEditor.HideLabel); // these two don't make much sense here //// valueEditor.RegexValidator; //// valueEditor.RequiredValidator; List <IValueValidator> validators = valueEditor.Validators; Assert.AreEqual(2, validators.Count); IValueValidator validator = validators[0]; var v1 = validator as RequiredValidator; Assert.IsNotNull(v1); Assert.AreEqual("Required", v1.ValidationName); validator = validators[1]; var v2 = validator as RegexValidator; Assert.IsNotNull(v2); Assert.AreEqual("Regex", v2.ValidationName); Assert.AreEqual("\\d*", v2.Configuration); // this is not part of the manifest IDictionary <string, object> preValues = editor.GetConfigurationEditor().DefaultConfiguration; Assert.IsEmpty(preValues); IConfigurationEditor preValueEditor = editor.GetConfigurationEditor(); Assert.IsNotNull(preValueEditor); Assert.IsNotNull(preValueEditor.Fields); Assert.AreEqual(2, preValueEditor.Fields.Count); ConfigurationField f = preValueEditor.Fields[0]; Assert.AreEqual("key1", f.Key); Assert.AreEqual("Some config 1", f.Name); Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/Views/pre-val1.html"), f.View); List <IValueValidator> fvalidators = f.Validators; Assert.IsNotNull(fvalidators); Assert.AreEqual(1, fvalidators.Count); var fv = fvalidators[0] as RequiredValidator; Assert.IsNotNull(fv); Assert.AreEqual("Required", fv.ValidationName); f = preValueEditor.Fields[1]; Assert.AreEqual("key2", f.Key); Assert.AreEqual("Some config 2", f.Name); Assert.AreEqual(_ioHelper.ResolveUrl("/App_Plugins/MyPackage/PropertyEditors/Views/pre-val2.html"), f.View); fvalidators = f.Validators; Assert.IsNotNull(fvalidators); Assert.AreEqual(0, fvalidators.Count); }
public bool IsCompressed(IReadOnlyContentBase content, IPropertyType propertyType, IDataEditor dataEditor, bool published) { if (!published && propertyType.SupportsPublishing && propertyType.ValueStorageType == ValueStorageType.Ntext) { // Only compress non published content that supports publishing and the property is text return(true); } if (propertyType.ValueStorageType == ValueStorageType.Integer && Constants.PropertyEditors.Aliases.Boolean.Equals(dataEditor.Alias)) { // Compress boolean values from int to bool return(true); } return(false); }
public bool IsForEditor(IDataEditor dataEditor) => dataEditor.Alias == Constants.PropertyEditors.Aliases.Label;
public bool IsForEditor(IDataEditor dataEditor) => dataEditor.Alias.InvariantEquals(OutboundRedirectEditor.EditorAlias);
public bool IsCompressed(IReadOnlyContentBase content, IPropertyType propertyType, IDataEditor dataEditor, bool published) => false;
public void Remove(IDataEditor <TData> editor) { editor.TargetUpdated -= OnEditorUpdatesTarget; _editors.Remove(editor); }
public bool IsForEditor(IDataEditor dataEditor) => dataEditor.Alias.InvariantEquals(Constants.PropertyEditors.Aliases.Grid);
/// <summary> /// Gets the tags configuration attribute of an editor. /// </summary> public static TagsPropertyEditorAttribute GetTagAttribute(this IDataEditor editor) => editor?.GetType().GetCustomAttribute <TagsPropertyEditorAttribute>(false);
/// <summary> /// Create member controller to test /// </summary> /// <param name="memberService">Member service</param> /// <param name="memberTypeService">Member type service</param> /// <param name="memberGroupService">Member group service</param> /// <param name="membersUserManager">Members user manager</param> /// <param name="dataTypeService">Data type service</param> /// <param name="backOfficeSecurityAccessor">Back office security accessor</param> /// <param name="mockPasswordChanger">Password changer class</param> /// <returns>A member controller for the tests</returns> private MemberController CreateSut( IMemberService memberService, IMemberTypeService memberTypeService, IMemberGroupService memberGroupService, IUmbracoUserManager <MemberIdentityUser> membersUserManager, IDataTypeService dataTypeService, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, IPasswordChanger <MemberIdentityUser> passwordChanger, IOptions <GlobalSettings> globalSettings, IUser user) { var httpContextAccessor = new HttpContextAccessor(); var mockShortStringHelper = new MockShortStringHelper(); var textService = new Mock <ILocalizedTextService>(); var contentTypeBaseServiceProvider = new Mock <IContentTypeBaseServiceProvider>(); contentTypeBaseServiceProvider.Setup(x => x.GetContentTypeOf(It.IsAny <IContentBase>())).Returns(new ContentType(mockShortStringHelper, 123)); var contentAppFactories = new Mock <List <IContentAppFactory> >(); var mockContentAppFactoryCollection = new Mock <ILogger <ContentAppFactoryCollection> >(); var hybridBackOfficeSecurityAccessor = new BackOfficeSecurityAccessor(httpContextAccessor); var contentAppFactoryCollection = new ContentAppFactoryCollection( () => contentAppFactories.Object, mockContentAppFactoryCollection.Object, hybridBackOfficeSecurityAccessor); var mockUserService = new Mock <IUserService>(); var commonMapper = new CommonMapper( mockUserService.Object, contentTypeBaseServiceProvider.Object, contentAppFactoryCollection, textService.Object); var mockCultureDictionary = new Mock <ICultureDictionary>(); var mockPasswordConfig = new Mock <IOptions <MemberPasswordConfigurationSettings> >(); mockPasswordConfig.Setup(x => x.Value).Returns(() => new MemberPasswordConfigurationSettings()); IDataEditor dataEditor = Mock.Of <IDataEditor>( x => x.Type == EditorType.PropertyValue && x.Alias == Constants.PropertyEditors.Aliases.Label); Mock.Get(dataEditor).Setup(x => x.GetValueEditor()).Returns(new TextOnlyValueEditor(new DataEditorAttribute(Constants.PropertyEditors.Aliases.TextBox, "Test Textbox", "textbox"), textService.Object, Mock.Of <IShortStringHelper>(), Mock.Of <IJsonSerializer>(), Mock.Of <IIOHelper>())); var propertyEditorCollection = new PropertyEditorCollection(new DataEditorCollection(() => new[] { dataEditor })); IMapDefinition memberMapDefinition = new MemberMapDefinition( commonMapper, new CommonTreeNodeMapper(Mock.Of <LinkGenerator>()), new MemberTabsAndPropertiesMapper( mockCultureDictionary.Object, backOfficeSecurityAccessor, textService.Object, memberTypeService, memberService, memberGroupService, mockPasswordConfig.Object, contentTypeBaseServiceProvider.Object, propertyEditorCollection)); var map = new MapDefinitionCollection(() => new List <IMapDefinition>() { new global::Umbraco.Cms.Core.Models.Mapping.MemberMapDefinition(), memberMapDefinition, new ContentTypeMapDefinition( commonMapper, propertyEditorCollection, dataTypeService, new Mock <IFileService>().Object, new Mock <IContentTypeService>().Object, new Mock <IMediaTypeService>().Object, memberTypeService, new Mock <ILoggerFactory>().Object, mockShortStringHelper, globalSettings, new Mock <IHostingEnvironment>().Object) }); var scopeProvider = Mock.Of <IScopeProvider>(x => x.CreateScope( It.IsAny <IsolationLevel>(), It.IsAny <RepositoryCacheMode>(), It.IsAny <IEventDispatcher>(), It.IsAny <IScopedNotificationPublisher>(), It.IsAny <bool?>(), It.IsAny <bool>(), It.IsAny <bool>()) == Mock.Of <IScope>()); _mapper = new UmbracoMapper(map, scopeProvider); return(new MemberController( new DefaultCultureDictionary( new Mock <ILocalizationService>().Object, NoAppCache.Instance), new LoggerFactory(), mockShortStringHelper, new DefaultEventMessagesFactory( new Mock <IEventMessagesAccessor>().Object), textService.Object, propertyEditorCollection, _mapper, memberService, memberTypeService, (IMemberManager)membersUserManager, dataTypeService, backOfficeSecurityAccessor, new ConfigurationEditorJsonSerializer(), passwordChanger, scopeProvider )); }
public bool IsForEditor(IDataEditor dataEditor) => dataEditor.Alias.InvariantEquals(ImagePickerPropertyEditor.EditorAlias);