Moved more files to abstractions and eliminated the use of JObject

This commit is contained in:
Bjarke Berg
2019-12-05 14:03:09 +01:00
parent 816baa5eaf
commit fb562817bc
39 changed files with 259 additions and 175 deletions

View File

@@ -0,0 +1,57 @@
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Umbraco.Core
{
public static class ContentExtensions
{
#region XML methods
/// <summary>
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
/// </summary>
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
internal static XElement ToDeepXml(this IContent content, IEntityXmlSerializer serializer)
{
return serializer.Serialize(content, false, true);
}
/// <summary>
/// Creates the xml representation for the <see cref="IContent"/> object
/// </summary>
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IContent content, IEntityXmlSerializer serializer)
{
return serializer.Serialize(content, false, false);
}
/// <summary>
/// Creates the xml representation for the <see cref="IMedia"/> object
/// </summary>
/// <param name="media"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMedia media, IEntityXmlSerializer serializer)
{
return serializer.Serialize(media);
}
/// <summary>
/// Creates the xml representation for the <see cref="IMember"/> object
/// </summary>
/// <param name="member"><see cref="IMember"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMember member, IEntityXmlSerializer serializer)
{
return serializer.Serialize(member);
}
#endregion
}
}

View File

@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Runtime.Serialization;
namespace Umbraco.Core.Deploy
{
/// <summary>
/// Provides a base class to all artifacts.
/// </summary>
[DataContract]
public abstract class ArtifactBase<TUdi> : IArtifact
where TUdi : Udi
{
@@ -34,14 +35,16 @@ namespace Umbraco.Core.Deploy
get { return Udi; }
}
[DataMember]
public TUdi Udi { get; set; }
[JsonIgnore]
[IgnoreDataMember]
public string Checksum
{
get { return _checksum.Value; }
}
[DataMember]
public IEnumerable<ArtifactDependency> Dependencies
{
get { return _dependencies; }
@@ -50,7 +53,9 @@ namespace Umbraco.Core.Deploy
#endregion
[DataMember]
public string Name { get; set; }
[DataMember]
public string Alias { get; set; }
}
}

View File

@@ -4,7 +4,7 @@ using Umbraco.Core.Models.Membership;
namespace Umbraco.Core.Events
{
internal class ExportedMemberEventArgs : EventArgs
public class ExportedMemberEventArgs : EventArgs
{
public IMember Member { get; }
public MemberExportModel Exported { get; }

View File

@@ -7,7 +7,7 @@ using Umbraco.Core.Logging;
namespace Umbraco.Core.Manifest
{
internal class ManifestWatcher : DisposableObjectSlim
public class ManifestWatcher : DisposableObjectSlim
{
private static readonly object Locker = new object();
private static volatile bool _isRestarting;

View File

@@ -1,8 +1,8 @@
using System.Collections;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Composing;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
namespace Umbraco.Core.PackageActions
{
@@ -12,6 +12,12 @@ namespace Umbraco.Core.PackageActions
/// </summary>
public class AllowDoctype : IPackageAction
{
private readonly IContentTypeService _contentTypeService;
public AllowDoctype(IContentTypeService contentTypeService)
{
_contentTypeService = contentTypeService;
}
#region IPackageAction Members
@@ -31,8 +37,8 @@ namespace Umbraco.Core.PackageActions
//global::umbraco.cms.businesslogic.ContentType ct = global::umbraco.cms.businesslogic.ContentType.GetByAlias(doctypeName);
//global::umbraco.cms.businesslogic.ContentType parentct = global::umbraco.cms.businesslogic.ContentType.GetByAlias(parentDoctypeName);
var ct = Current.Services.ContentTypeService.Get(doctypeName);
var parentct = Current.Services.ContentTypeService.Get(parentDoctypeName);
var ct = _contentTypeService.Get(doctypeName);
var parentct = _contentTypeService.Get(parentDoctypeName);
if (ct != null && parentct != null)
{
@@ -57,7 +63,7 @@ namespace Umbraco.Core.PackageActions
var so = 0;
parentct.AllowedContentTypes = ids.Select(x => new ContentTypeSort(x, so++));
//parentct.Save();
Current.Services.ContentTypeService.Save(parentct);
_contentTypeService.Save(parentct);
return true;
}
}
@@ -85,6 +91,6 @@ namespace Umbraco.Core.PackageActions
}
#endregion
}
}

View File

@@ -1,5 +1,5 @@
using System.Xml.Linq;
using Umbraco.Core.Composing;
using Umbraco.Core.Services;
namespace Umbraco.Core.PackageActions
{
@@ -9,6 +9,13 @@ namespace Umbraco.Core.PackageActions
/// </summary>
public class PublishRootDocument : IPackageAction
{
private readonly IContentService _contentService;
public PublishRootDocument(IContentService contentService)
{
_contentService = contentService;
}
#region IPackageAction Members
/// <summary>
@@ -25,14 +32,14 @@ namespace Umbraco.Core.PackageActions
string documentName = xmlData.AttributeValue<string>("documentName");
var rootDocs = Current.Services.ContentService.GetRootContent();
var rootDocs = _contentService.GetRootContent();
foreach (var rootDoc in rootDocs)
{
if (rootDoc.Name.Trim() == documentName.Trim() && rootDoc.ContentType != null)
{
// TODO: variants?
Current.Services.ContentService.SaveAndPublishBranch(rootDoc, true);
_contentService.SaveAndPublishBranch(rootDoc, true);
break;
}
}
@@ -59,6 +66,6 @@ namespace Umbraco.Core.PackageActions
return "publishRootDocument";
}
#endregion
}
}

View File

@@ -5,7 +5,6 @@ using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Xml.Linq;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
@@ -19,7 +18,7 @@ namespace Umbraco.Core.Packaging
/// <summary>
/// Manages the storage of installed/created package definitions
/// </summary>
internal class PackagesRepository : ICreatedPackagesRepository, IInstalledPackagesRepository
public class PackagesRepository : ICreatedPackagesRepository, IInstalledPackagesRepository
{
private readonly IContentService _contentService;
private readonly IContentTypeService _contentTypeService;
@@ -61,6 +60,7 @@ namespace Umbraco.Core.Packaging
IIOHelper ioHelper,
IEntityXmlSerializer serializer, ILogger logger,
IUmbracoVersion umbracoVersion,
IGlobalSettings globalSettings,
string packageRepositoryFileName,
string tempFolderPath = null, string packagesFolderPath = null, string mediaFolderPath = null)
{
@@ -78,7 +78,7 @@ namespace Umbraco.Core.Packaging
_tempFolderPath = tempFolderPath ?? Constants.SystemDirectories.TempData.EnsureEndsWith('/') + "PackageFiles";
_packagesFolderPath = packagesFolderPath ?? Constants.SystemDirectories.Packages;
_mediaFolderPath = mediaFolderPath ?? Current.Configs.Global().UmbracoMediaPath + "/created-packages";
_mediaFolderPath = mediaFolderPath ?? globalSettings.UmbracoMediaPath + "/created-packages";
_parser = new PackageDefinitionXmlParser(logger, umbracoVersion);
_umbracoVersion = umbracoVersion;

View File

@@ -12,14 +12,20 @@ namespace Umbraco.Core.PropertyEditors
{ }
public IManifestValueValidator Create(string name)
{
var v = GetByName(name);
// TODO: what is this exactly?
// we cannot return this instance, need to clone it?
return (IManifestValueValidator) Activator.CreateInstance(v.GetType()); // ouch
}
public IManifestValueValidator GetByName(string name)
{
var v = this.FirstOrDefault(x => x.ValidationName.InvariantEquals(name));
if (v == null)
throw new InvalidOperationException($"Could not find a validator named \"{name}\".");
// TODO: what is this exactly?
// we cannot return this instance, need to clone it?
return (IManifestValueValidator) Activator.CreateInstance(v.GetType()); // ouch
return v;
}
}
}

View File

@@ -2,15 +2,13 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Umbraco.Core.PropertyEditors.Validators
{
/// <summary>
/// A validator that validates a delimited set of values against a common regex
/// </summary>
internal sealed class DelimitedValueValidator : IManifestValueValidator
public sealed class DelimitedValueValidator : IManifestValueValidator
{
/// <inheritdoc />
public string ValidationName => "Delimited";
@@ -18,7 +16,8 @@ namespace Umbraco.Core.PropertyEditors.Validators
/// <summary>
/// Gets or sets the configuration, when parsed as <see cref="IManifestValueValidator"/>.
/// </summary>
public JObject Configuration { get; set; }
public DelimitedValueValidatorConfig Configuration { get; set; }
/// <inheritdoc />
public IEnumerable<ValidationResult> Validate(object value, string valueType, object dataTypeConfiguration)
@@ -26,20 +25,8 @@ namespace Umbraco.Core.PropertyEditors.Validators
// TODO: localize these!
if (value != null)
{
var delimiter = ",";
Regex regex = null;
if (Configuration is JObject jobject)
{
if (jobject["delimiter"] != null)
{
delimiter = jobject["delimiter"].ToString();
}
if (jobject["pattern"] != null)
{
var regexPattern = jobject["pattern"].ToString();
regex = new Regex(regexPattern);
}
}
var delimiter = Configuration?.Delimiter ?? ",";
var regex = (Configuration?.Pattern != null) ? new Regex(Configuration.Pattern) : null;
var stringVal = value.ToString();
var split = stringVal.Split(new[] { delimiter }, StringSplitOptions.RemoveEmptyEntries);
@@ -63,4 +50,10 @@ namespace Umbraco.Core.PropertyEditors.Validators
}
}
}
public class DelimitedValueValidatorConfig
{
public string Delimiter { get; set; }
public string Pattern { get; set; }
}
}

View File

@@ -27,7 +27,7 @@ namespace Umbraco.Core.PropertyEditors.Validators
/// and the regular expression is supplied at validation time. This constructor is also used when
/// the validator is used as an <see cref="IManifestValueValidator"/> and the regular expression
/// is supplied via the <see cref="Configuration"/> method.</remarks>
public RegexValidator() : this(Current.HasFactory ? Current.Services.TextService : null, null)
public RegexValidator(ILocalizedTextService textService) : this(textService, null)
{ }
/// <summary>

View File

@@ -13,11 +13,6 @@ namespace Umbraco.Core.PropertyEditors.Validators
private readonly ILocalizedTextService _textService;
const string ValueCannotBeNull = "Value cannot be null";
const string ValueCannotBeEmpty = "Value cannot be empty";
public RequiredValidator() : this(Current.HasFactory ? Current.Services.TextService : null)
{
}
public RequiredValidator(ILocalizedTextService textService)
{
_textService = textService;

View File

@@ -301,12 +301,17 @@ namespace Umbraco.Core.Configuration
{
try
{
return int.Parse(ConfigurationManager.AppSettings[Constants.AppSettings.VersionCheckPeriod]);
var val = ConfigurationManager.AppSettings[Constants.AppSettings.VersionCheckPeriod];
if (!(val is null))
{
return int.Parse(val);
}
}
catch
{
return 7;
// Ignore
}
return 7;
}
}

View File

@@ -46,7 +46,7 @@ namespace Umbraco.Core.Compose
public void Terminate()
{ }
internal static IUser UnknownUser => new User { Id = Constants.Security.UnknownUserId, Name = Constants.Security.UnknownUserName, Email = "" };
public static IUser UnknownUser => new User { Id = Constants.Security.UnknownUserId, Name = Constants.Security.UnknownUserName, Email = "" };
private IUser CurrentPerformingUser
{

View File

@@ -9,22 +9,33 @@ namespace Umbraco.Core.Compose
{
public sealed class RelateOnTrashComponent : IComponent
{
private readonly IRelationService _relationService;
private readonly IEntityService _entityService;
private readonly ILocalizedTextService _textService;
public RelateOnTrashComponent(IRelationService relationService, IEntityService entityService, ILocalizedTextService textService)
{
_relationService = relationService;
_entityService = entityService;
_textService = textService;
}
public void Initialize()
{
ContentService.Moved += ContentService_Moved;
ContentService.Trashed += ContentService_Trashed;
MediaService.Moved += MediaService_Moved;
MediaService.Trashed += MediaService_Trashed;
ContentService.Moved += (sender, args) => ContentService_Moved(sender, args, _relationService);
ContentService.Trashed += (sender, args) => ContentService_Trashed(sender, args, _relationService, _entityService, _textService);
MediaService.Moved += (sender, args) => MediaService_Moved(sender, args, _relationService);
MediaService.Trashed += (sender, args) => MediaService_Trashed(sender, args, _relationService, _entityService, _textService);
}
public void Terminate()
{ }
private static void ContentService_Moved(IContentService sender, MoveEventArgs<IContent> e)
private static void ContentService_Moved(IContentService sender, MoveEventArgs<IContent> e, IRelationService relationService)
{
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinContentString)))
{
var relationService = Current.Services.RelationService;
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;
var relations = relationService.GetByChildId(item.Entity.Id);
@@ -35,11 +46,10 @@ namespace Umbraco.Core.Compose
}
}
private static void MediaService_Moved(IMediaService sender, MoveEventArgs<IMedia> e)
private static void MediaService_Moved(IMediaService sender, MoveEventArgs<IMedia> e, IRelationService relationService)
{
foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinMediaString)))
{
var relationService = Current.Services.RelationService;
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias;
var relations = relationService.GetByChildId(item.Entity.Id);
foreach (var relation in relations.Where(x => x.RelationType.Alias.InvariantEquals(relationTypeAlias)))
@@ -49,11 +59,8 @@ namespace Umbraco.Core.Compose
}
}
private static void ContentService_Trashed(IContentService sender, MoveEventArgs<IContent> e)
private static void ContentService_Trashed(IContentService sender, MoveEventArgs<IContent> e, IRelationService relationService, IEntityService entityService, ILocalizedTextService textService)
{
var relationService = Current.Services.RelationService;
var entityService = Current.Services.EntityService;
var textService = Current.Services.TextService;
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;
var relationType = relationService.GetRelationTypeByAlias(relationTypeAlias);
@@ -94,11 +101,8 @@ namespace Umbraco.Core.Compose
}
}
private static void MediaService_Trashed(IMediaService sender, MoveEventArgs<IMedia> e)
private static void MediaService_Trashed(IMediaService sender, MoveEventArgs<IMedia> e, IRelationService relationService, IEntityService entityService, ILocalizedTextService textService)
{
var relationService = Current.Services.RelationService;
var entityService = Current.Services.EntityService;
var textService = Current.Services.TextService;
const string relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias;
var relationType = relationService.GetRelationTypeByAlias(relationTypeAlias);
// check that the relation-type exists, if not, then recreate it

View File

@@ -97,6 +97,7 @@ namespace Umbraco.Core.Composing.CompositionExtensions
factory.GetInstance<IEntityXmlSerializer>(),
factory.GetInstance<ILogger>(),
factory.GetInstance<IUmbracoVersion>(),
factory.GetInstance<IGlobalSettings>(),
packageRepoFileName);
private static LocalizedTextServiceFileSources SourcesFactory(IFactory container)

View File

@@ -262,53 +262,7 @@ namespace Umbraco.Core
#endregion
#region XML methods
/// <summary>
/// Creates the full xml representation for the <see cref="IContent"/> object and all of it's descendants
/// </summary>
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
internal static XElement ToDeepXml(this IContent content, IEntityXmlSerializer serializer)
{
return serializer.Serialize(content, false, true);
}
/// <summary>
/// Creates the xml representation for the <see cref="IContent"/> object
/// </summary>
/// <param name="content"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IContent content, IEntityXmlSerializer serializer)
{
return serializer.Serialize(content, false, false);
}
/// <summary>
/// Creates the xml representation for the <see cref="IMedia"/> object
/// </summary>
/// <param name="media"><see cref="IContent"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMedia media, IEntityXmlSerializer serializer)
{
return serializer.Serialize(media);
}
/// <summary>
/// Creates the xml representation for the <see cref="IMember"/> object
/// </summary>
/// <param name="member"><see cref="IMember"/> to generate xml for</param>
/// <param name="serializer"></param>
/// <returns>Xml representation of the passed in <see cref="IContent"/></returns>
public static XElement ToXml(this IMember member, IEntityXmlSerializer serializer)
{
return serializer.Serialize(member);
}
#endregion
#region Dirty

View File

@@ -1,5 +1,4 @@
using Umbraco.Core.Compose;
using Umbraco.Core.Composing;
using Umbraco.Core.Composing;
using Umbraco.Core.IO;
namespace Umbraco.Core.Logging.Viewer

View File

@@ -19,16 +19,18 @@ namespace Umbraco.Core.Manifest
private readonly IIOHelper _ioHelper;
private readonly IDataTypeService _dataTypeService;
private readonly ILocalizationService _localizationService;
private readonly ILocalizedTextService _textService;
/// <summary>
/// Initializes a new instance of the <see cref="DataEditorConverter"/> class.
/// </summary>
public DataEditorConverter(ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService)
public DataEditorConverter(ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, ILocalizedTextService textService)
{
_logger = logger;
_ioHelper = ioHelper;
_dataTypeService = dataTypeService;
_localizationService = localizationService;
_textService = textService;
}
/// <inheritdoc />
@@ -83,7 +85,7 @@ namespace Umbraco.Core.Manifest
// explicitly assign a value editor of type ValueEditor
// (else the deserializer will try to read it before setting it)
// (and besides it's an interface)
target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService);
target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService, _textService);
// in the manifest, validators are a simple dictionary eg
// {
@@ -155,7 +157,7 @@ namespace Umbraco.Core.Manifest
if (jobject.Property("view") != null)
{
// explicitly assign a value editor of type ParameterValueEditor
target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService);
target.ExplicitValueEditor = new DataValueEditor(_dataTypeService, _localizationService, _textService);
// move the 'view' property
jobject["editor"] = new JObject { ["view"] = jobject["view"] };

View File

@@ -19,6 +19,7 @@ namespace Umbraco.Core.Manifest
public class ManifestParser : IManifestParser
{
private readonly IJsonSerializer _jsonSerializer;
private readonly ILocalizedTextService _localizedTextService;
private static readonly string Utf8Preamble = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble());
private readonly IAppPolicyCache _cache;
@@ -34,10 +35,11 @@ namespace Umbraco.Core.Manifest
/// <summary>
/// Initializes a new instance of the <see cref="ManifestParser"/> class.
/// </summary>
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, IJsonSerializer jsonSerializer)
public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, IJsonSerializer jsonSerializer, ILocalizedTextService localizedTextService)
: this(appCaches, validators, filters, "~/App_Plugins", logger, ioHelper, dataTypeService, localizationService)
{
_jsonSerializer = jsonSerializer;
_localizedTextService = localizedTextService;
}
/// <summary>
@@ -174,7 +176,7 @@ namespace Umbraco.Core.Manifest
if (string.IsNullOrWhiteSpace(text)) throw new ArgumentException("Value can't be empty or consist only of white-space characters.", nameof(text));
var manifest = JsonConvert.DeserializeObject<PackageManifest>(text,
new DataEditorConverter(_logger, _ioHelper, _dataTypeService, _localizationService),
new DataEditorConverter(_logger, _ioHelper, _dataTypeService, _localizationService, _localizedTextService),
new ValueValidatorConverter(_validators),
new DashboardAccessRuleConverter());

View File

@@ -26,7 +26,7 @@ namespace Umbraco.Core.Manifest
if (string.IsNullOrWhiteSpace(type))
throw new InvalidOperationException("Could not get the type of the validator.");
return _validators.Create(type);
return _validators.GetByName(type);
// jObject["configuration"] is going to be deserialized in a Configuration property, if any
}

View File

@@ -1,7 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using Newtonsoft.Json;
using System.Runtime.Serialization;
using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
@@ -16,6 +16,7 @@ namespace Umbraco.Core.PropertyEditors
/// </remarks>
[DebuggerDisplay("{" + nameof(DebuggerDisplay) + "(),nq}")]
[HideFromTypeFinder]
[DataContract]
public class DataEditor : IDataEditor
{
private IDictionary<string, object> _defaultConfiguration;
@@ -55,27 +56,27 @@ namespace Umbraco.Core.PropertyEditors
protected ILogger Logger { get; }
/// <inheritdoc />
[JsonProperty("alias", Required = Required.Always)]
[DataMember(Name = "alias", IsRequired = true)]
public string Alias { get; internal set; }
/// <inheritdoc />
[JsonIgnore]
[IgnoreDataMember]
public EditorType Type { get; }
/// <inheritdoc />
[JsonProperty("name", Required = Required.Always)]
[DataMember(Name = "name", IsRequired = true)]
public string Name { get; internal set; }
/// <inheritdoc />
[JsonProperty("icon")]
[DataMember(Name = "icon")]
public string Icon { get; internal set; }
/// <inheritdoc />
[JsonProperty("group")]
[DataMember(Name = "group")]
public string Group { get; internal set; }
/// <inheritdoc />
[JsonIgnore]
[IgnoreDataMember]
public bool IsDeprecated { get; }
/// <inheritdoc />
@@ -121,7 +122,7 @@ namespace Umbraco.Core.PropertyEditors
/// Gets or sets an explicit value editor.
/// </summary>
/// <remarks>Used for manifest data editors.</remarks>
[JsonProperty("editor")]
[DataMember(Name = "editor")]
public IDataValueEditor ExplicitValueEditor { get; set; }
/// <inheritdoc />
@@ -139,11 +140,11 @@ namespace Umbraco.Core.PropertyEditors
/// Gets or sets an explicit configuration editor.
/// </summary>
/// <remarks>Used for manifest data editors.</remarks>
[JsonProperty("config")]
[DataMember(Name = "config")]
public IConfigurationEditor ExplicitConfigurationEditor { get; set; }
/// <inheritdoc />
[JsonProperty("defaultConfig")]
[DataMember(Name = "defaultConfig")]
public IDictionary<string, object> DefaultConfiguration
{
// for property value editors, get the ConfigurationEditor.DefaultConfiguration

View File

@@ -20,14 +20,16 @@ namespace Umbraco.Core.PropertyEditors
/// </summary>
public class DataValueEditor : IDataValueEditor
{
private readonly ILocalizedTextService _localizedTextService;
protected IDataTypeService DataTypeService { get; }
protected ILocalizationService LocalizationService { get; }
/// <summary>
/// Initializes a new instance of the <see cref="DataValueEditor"/> class.
/// </summary>
public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService) // for tests, and manifest
public DataValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, ILocalizedTextService localizedTextService) // for tests, and manifest
{
_localizedTextService = localizedTextService;
ValueType = ValueTypes.String;
Validators = new List<IValueValidator>();
DataTypeService = dataTypeService;
@@ -110,12 +112,12 @@ namespace Umbraco.Core.PropertyEditors
/// <summary>
/// Gets the validator used to validate the special property type -level "required".
/// </summary>
public virtual IValueRequiredValidator RequiredValidator => new RequiredValidator(); //TODO: Pass in the ILocalizedTextService here and not rely on Current!
public virtual IValueRequiredValidator RequiredValidator => new RequiredValidator(_localizedTextService);
/// <summary>
/// Gets the validator used to validate the special property type -level "format".
/// </summary>
public virtual IValueFormatValidator FormatValidator => new RegexValidator(); //TODO: Pass in the ILocalizedTextService here and not rely on Current!
public virtual IValueFormatValidator FormatValidator => new RegexValidator(_localizedTextService);
/// <summary>
/// If this is true than the editor will be displayed full width without a label

View File

@@ -127,16 +127,19 @@
</Compile>
-->
<Compile Include="Cache\DefaultRepositoryCachePolicy.cs" />
<Compile Include="Compose\AuditEventsComponent.cs" />
<Compile Include="Cache\FullDataSetRepositoryCachePolicy.cs" />
<Compile Include="Cache\RepositoryCachePolicyBase.cs" />
<Compile Include="Cache\SingleItemsOnlyRepositoryCachePolicy.cs" />
<Compile Include="Compose\AuditEventsComponent.cs" />
<Compile Include="Compose\AuditEventsComposer.cs" />
<Compile Include="Compose\ManifestWatcherComponent.cs" />
<Compile Include="Compose\ManifestWatcherComposer.cs" />
<Compile Include="Compose\RelateOnCopyComponent.cs" />
<Compile Include="Compose\RelateOnCopyComposer.cs" />
<Compile Include="Compose\RelateOnTrashComponent.cs" />
<Compile Include="Compose\RelateOnTrashComposer.cs" />
<Compile Include="Composing\RegisterFactory.cs" />
<Compile Include="CompositionExtensions.cs" />
<Compile Include="Compose\ManifestWatcherComposer.cs" />
<Compile Include="Compose\RelateOnCopyComposer.cs" />
<Compile Include="Compose\RelateOnTrashComposer.cs" />
<Compile Include="Composing\CompositionExtensions\Configuration.cs" />
<Compile Include="Composing\CompositionExtensions\CoreMappingProfiles.cs" />
<Compile Include="Composing\CompositionExtensions\FileSystems.cs" />
@@ -148,19 +151,12 @@
<Compile Include="Deploy\IGridCellValueConnector.cs" />
<Compile Include="Dictionary\UmbracoCultureDictionary.cs" />
<Compile Include="Dictionary\UmbracoCultureDictionaryFactory.cs" />
<Compile Include="Events\ContentPublishedEventArgs.cs" />
<Compile Include="Events\ContentPublishingEventArgs.cs" />
<Compile Include="Events\ContentSavedEventArgs.cs" />
<Compile Include="Events\ContentSavingEventArgs.cs" />
<Compile Include="Events\ExportedMemberEventArgs.cs" />
<Compile Include="Events\ImportPackageEventArgs.cs" />
<Compile Include="Events\MigrationEventArgs.cs" />
<Compile Include="Events\QueuingEventDispatcherBase.cs" />
<Compile Include="Composing\Current.cs" />
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
<Compile Include="Composing\LightInject\MixedLightInjectScopeManagerProvider.cs" />
<Compile Include="Events\QueuingEventDispatcher.cs" />
<Compile Include="Logging\Viewer\LogTimePeriod.cs" />
<Compile Include="Manifest\IPackageManifest.cs" />
<Compile Include="Manifest\ManifestParser.cs" />
<Compile Include="Migrations\IMigrationBuilder.cs" />
<Compile Include="Migrations\Upgrade\Common\DeleteKeysAndIndexes.cs" />
@@ -210,9 +206,6 @@
<Compile Include="Packaging\PackageDataInstallation.cs" />
<Compile Include="Packaging\PackageInstallation.cs" />
<Compile Include="Persistence\Mappers\SimpleContentTypeMapper.cs" />
<Compile Include="PropertyEditors\Validators\DelimitedValueValidator.cs" />
<Compile Include="PropertyEditors\Validators\RegexValidator.cs" />
<Compile Include="PropertyEditors\Validators\RequiredValidator.cs" />
<Compile Include="PropertyEditors\ValueConverters\ColorPickerValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\GridValueConverter.cs" />
<Compile Include="PropertyEditors\ValueConverters\ImageCropperValue.cs" />
@@ -261,7 +254,6 @@
<Compile Include="Logging\Viewer\MessageTemplateFilter.cs" />
<Compile Include="Logging\Viewer\SavedLogSearch.cs" />
<Compile Include="Manifest\DashboardAccessRuleConverter.cs" />
<Compile Include="Manifest\ManifestContentAppFactory.cs" />
<Compile Include="Migrations\MergeBuilder.cs" />
<Compile Include="Migrations\MigrationBase_Extra.cs" />
<Compile Include="Migrations\PostMigrations\IPublishedSnapshotRebuilder.cs" />
@@ -300,9 +292,6 @@
<Compile Include="Models\ContentTagsExtensions.cs" />
<Compile Include="Models\PathValidationExtensions.cs" />
<Compile Include="Models\PropertyTagsExtensions.cs" />
<Compile Include="PackageActions\AllowDoctype.cs" />
<Compile Include="PackageActions\PublishRootDocument.cs" />
<Compile Include="Packaging\PackagesRepository.cs" />
<Compile Include="Persistence\Dtos\AuditEntryDto.cs" />
<Compile Include="Persistence\Dtos\ConsentDto.cs" />
<Compile Include="Persistence\Dtos\ContentScheduleDto.cs" />
@@ -335,11 +324,8 @@
<Compile Include="Migrations\Expressions\Create\Table\CreateTableOfDtoBuilder.cs" />
<Compile Include="Migrations\Expressions\Delete\KeysAndIndexes\DeleteKeysAndIndexesBuilder.cs" />
<Compile Include="Migrations\Install\DatabaseBuilder.cs" />
<Compile Include="Deploy\ArtifactBase.cs" />
<Compile Include="Diagnostics\MiniDump.cs" />
<Compile Include="EmailSender.cs" />
<Compile Include="Events\QueuingEventDispatcher.cs" />
<Compile Include="Events\UninstallPackageEventArgs.cs" />
<Compile Include="Composing\LightInject\LightInjectException.cs" />
<Compile Include="FileResources\Files.Designer.cs" />
<Compile Include="Logging\Serilog\SerilogLogger.cs" />
@@ -347,7 +333,6 @@
<Compile Include="Logging\OwinLoggerFactory.cs" />
<Compile Include="MainDom.cs" />
<Compile Include="Manifest\ValueValidatorConverter.cs" />
<Compile Include="Manifest\ManifestWatcher.cs" />
<Compile Include="Manifest\DataEditorConverter.cs" />
<Compile Include="Migrations\MigrationBuilder.cs" />
<Compile Include="Migrations\MigrationPlan.cs" />
@@ -786,9 +771,6 @@
<Compile Include="Services\Implement\ServerRegistrationService.cs" />
<Compile Include="Services\Implement\TagService.cs" />
<Compile Include="Services\Implement\UserService.cs" />
<Compile Include="Compose\ManifestWatcherComponent.cs" />
<Compile Include="Compose\RelateOnCopyComponent.cs" />
<Compile Include="Compose\RelateOnTrashComponent.cs" />
<Compile Include="Sync\DatabaseServerMessenger.cs" />
<Compile Include="Sync\RefreshInstruction.cs" />
<Compile Include="Sync\ServerMessengerBase.cs" />
@@ -811,6 +793,10 @@
<Project>{29aa69d9-b597-4395-8d42-43b1263c240a}</Project>
<Name>Umbraco.Abstractions</Name>
</ProjectReference>
<ProjectReference Include="..\Umbraco.Infrastructure\Umbraco.Infrastructure.csproj">
<Project>{3ae7bf57-966b-45a5-910a-954d7c554441}</Project>
<Name>Umbraco.Infrastructure</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@@ -30,9 +30,46 @@ namespace Umbraco.Tests.Manifest
var validators = new IManifestValueValidator[]
{
new RequiredValidator(Mock.Of<ILocalizedTextService>()),
new RegexValidator(Mock.Of<ILocalizedTextService>(), null)
new RegexValidator(Mock.Of<ILocalizedTextService>(), null),
new DelimitedValueValidator(),
};
_parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty<IManifestFilter>()), Mock.Of<ILogger>(), TestHelper.IOHelper, Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(), new JsonNetSerializer());
_parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty<IManifestFilter>()), Mock.Of<ILogger>(), TestHelper.IOHelper, Mock.Of<IDataTypeService>(), Mock.Of<ILocalizationService>(), new JsonNetSerializer(), Mock.Of<ILocalizedTextService>());
}
[Test]
public void DelimitedValueValidator()
{
const string json = @"{'propertyEditors': [
{
alias: 'Test.Test2',
name: 'Test 2',
isParameterEditor: true,
defaultConfig: { key1: 'some default val' },
editor: {
view: '~/App_Plugins/MyPackage/PropertyEditors/MyEditor.html',
valueType: 'int',
validation: {
delimited: {
delimiter: ',',
pattern: '^[a-zA-Z]*$'
}
}
}
}
]}";
var manifest = _parser.ParseManifest(json);
Assert.AreEqual(1, manifest.ParameterEditors.Length);
Assert.AreEqual(1, manifest.ParameterEditors[0].GetValueEditor().Validators.Count);
Assert.IsTrue(manifest.ParameterEditors[0].GetValueEditor().Validators[0] is DelimitedValueValidator);
var validator = manifest.ParameterEditors[0].GetValueEditor().Validators[0] as DelimitedValueValidator;
Assert.IsNotNull(validator.Configuration);
Assert.AreEqual(",", validator.Configuration.Delimiter);
Assert.AreEqual("^[a-zA-Z]*$", validator.Configuration.Pattern);
}
[Test]

View File

@@ -7,6 +7,7 @@ using System.Xml.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
using Umbraco.Core.Models.Packaging;
using Umbraco.Core.Packaging;
@@ -43,6 +44,7 @@ namespace Umbraco.Tests.Packaging
IOHelper,
Factory.GetInstance<IEntityXmlSerializer>(), Logger,
UmbracoVersion,
Factory.GetInstance<IGlobalSettings>(),
"createdPackages.config",
//temp paths
tempFolderPath: "~/" + _testBaseFolder + "/temp",

View File

@@ -179,9 +179,9 @@ namespace Umbraco.Tests.TestHelpers
return new PackagingService(
auditService.Value,
new PackagesRepository(contentService.Value, contentTypeService.Value, dataTypeService.Value, fileService.Value, macroService.Value, localizationService.Value, ioHelper,
new EntityXmlSerializer(contentService.Value, mediaService.Value, dataTypeService.Value, userService.Value, localizationService.Value, contentTypeService.Value, urlSegmentProviders), logger, umbracoVersion, "createdPackages.config"),
new EntityXmlSerializer(contentService.Value, mediaService.Value, dataTypeService.Value, userService.Value, localizationService.Value, contentTypeService.Value, urlSegmentProviders), logger, umbracoVersion, globalSettings, "createdPackages.config"),
new PackagesRepository(contentService.Value, contentTypeService.Value, dataTypeService.Value, fileService.Value, macroService.Value, localizationService.Value, ioHelper,
new EntityXmlSerializer(contentService.Value, mediaService.Value, dataTypeService.Value, userService.Value, localizationService.Value, contentTypeService.Value, urlSegmentProviders), logger, umbracoVersion, "installedPackages.config"),
new EntityXmlSerializer(contentService.Value, mediaService.Value, dataTypeService.Value, userService.Value, localizationService.Value, contentTypeService.Value, urlSegmentProviders), logger, umbracoVersion, globalSettings, "installedPackages.config"),
new PackageInstallation(
new PackageDataInstallation(logger, fileService.Value, macroService.Value, localizationService.Value, dataTypeService.Value, entityService.Value, contentTypeService.Value, contentService.Value, propertyEditorCollection, scopeProvider),
new PackageFileInstallation(compiledPackageXmlParser, ioHelper, new ProfilingLogger(logger, new TestProfiler())),

View File

@@ -29,18 +29,24 @@ namespace Umbraco.Web.PropertyEditors
public class MultipleTextStringPropertyEditor : DataEditor
{
private readonly IIOHelper _ioHelper;
private readonly IDataTypeService _dataTypeService;
private readonly ILocalizationService _localizationService;
private readonly ILocalizedTextService _localizedTextService;
/// <summary>
/// Initializes a new instance of the <see cref="MultipleTextStringPropertyEditor"/> class.
/// </summary>
public MultipleTextStringPropertyEditor(ILogger logger, IIOHelper ioHelper)
public MultipleTextStringPropertyEditor(ILogger logger, IIOHelper ioHelper, IDataTypeService dataTypeService, ILocalizationService localizationService, ILocalizedTextService localizedTextService)
: base(logger)
{
_ioHelper = ioHelper;
_dataTypeService = dataTypeService;
_localizationService = localizationService;
_localizedTextService = localizedTextService;
}
/// <inheritdoc />
protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService,Attribute);
protected override IDataValueEditor CreateValueEditor() => new MultipleTextStringPropertyValueEditor(_dataTypeService, _localizationService,Attribute, _localizedTextService);
/// <inheritdoc />
protected override IConfigurationEditor CreateConfigurationEditor() => new MultipleTextStringConfigurationEditor(_ioHelper);
@@ -50,9 +56,13 @@ namespace Umbraco.Web.PropertyEditors
/// </summary>
internal class MultipleTextStringPropertyValueEditor : DataValueEditor
{
public MultipleTextStringPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute)
private readonly ILocalizedTextService _localizedTextService;
public MultipleTextStringPropertyValueEditor(IDataTypeService dataTypeService, ILocalizationService localizationService, DataEditorAttribute attribute, ILocalizedTextService localizedTextService)
: base(dataTypeService, localizationService, attribute)
{ }
{
_localizedTextService = localizedTextService;
}
/// <summary>
/// The value passed in from the editor will be an array of simple objects so we'll need to parse them to get the string
@@ -112,11 +122,18 @@ namespace Umbraco.Web.PropertyEditors
/// A custom FormatValidator is used as for multiple text strings, each string should individually be checked
/// against the configured regular expression, rather than the JSON representing all the strings as a whole.
/// </summary>
public override IValueFormatValidator FormatValidator => new MultipleTextStringFormatValidator();
public override IValueFormatValidator FormatValidator => new MultipleTextStringFormatValidator(_localizedTextService);
}
internal class MultipleTextStringFormatValidator : IValueFormatValidator
{
private readonly ILocalizedTextService _localizedTextService;
public MultipleTextStringFormatValidator(ILocalizedTextService localizedTextService)
{
_localizedTextService = localizedTextService;
}
public IEnumerable<ValidationResult> ValidateFormat(object value, string valueType, string format)
{
var asArray = value as JArray;
@@ -128,7 +145,7 @@ namespace Umbraco.Web.PropertyEditors
var textStrings = asArray.OfType<JObject>()
.Where(x => x["value"] != null)
.Select(x => x["value"].Value<string>());
var textStringValidator = new RegexValidator();
var textStringValidator = new RegexValidator(_localizedTextService);
foreach (var textString in textStrings)
{
var validationResults = textStringValidator.ValidateFormat(textString, valueType, format).ToList();

View File

@@ -6,6 +6,7 @@ using Umbraco.Core.IO;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.PropertyEditors.Validators;
using Umbraco.Core.Services;
namespace Umbraco.Web.PropertyEditors
{
@@ -14,10 +15,10 @@ namespace Umbraco.Web.PropertyEditors
/// </summary>
public class TagConfigurationEditor : ConfigurationEditor<TagConfiguration>
{
public TagConfigurationEditor(ManifestValueValidatorCollection validators, IIOHelper ioHelper) : base(ioHelper)
public TagConfigurationEditor(ManifestValueValidatorCollection validators, IIOHelper ioHelper, ILocalizedTextService localizedTextService) : base(ioHelper)
{
Field(nameof(TagConfiguration.Group)).Validators.Add(new RequiredValidator());
Field(nameof(TagConfiguration.StorageType)).Validators.Add(new RequiredValidator());
Field(nameof(TagConfiguration.Group)).Validators.Add(new RequiredValidator(localizedTextService));
Field(nameof(TagConfiguration.StorageType)).Validators.Add(new RequiredValidator(localizedTextService));
}
public override Dictionary<string, object> ToConfigurationEditor(TagConfiguration configuration)

View File

@@ -27,17 +27,19 @@ namespace Umbraco.Web.PropertyEditors
{
private readonly ManifestValueValidatorCollection _validators;
private readonly IIOHelper _ioHelper;
private readonly ILocalizedTextService _localizedTextService;
public TagsPropertyEditor(ManifestValueValidatorCollection validators, ILogger logger, IIOHelper ioHelper)
public TagsPropertyEditor(ManifestValueValidatorCollection validators, ILogger logger, IIOHelper ioHelper, ILocalizedTextService localizedTextService)
: base(logger)
{
_validators = validators;
_ioHelper = ioHelper;
_localizedTextService = localizedTextService;
}
protected override IDataValueEditor CreateValueEditor() => new TagPropertyValueEditor(Current.Services.DataTypeService, Current.Services.LocalizationService, Attribute);
protected override IConfigurationEditor CreateConfigurationEditor() => new TagConfigurationEditor(_validators, _ioHelper);
protected override IConfigurationEditor CreateConfigurationEditor() => new TagConfigurationEditor(_validators, _ioHelper, _localizedTextService);
internal class TagPropertyValueEditor : DataValueEditor
{

View File

@@ -144,6 +144,10 @@
<Compile Include="Composing\CompositionExtensions\Installer.cs" />
<Compile Include="Composing\LightInject\LightInjectContainer.cs" />
<Compile Include="Compose\BackOfficeUserAuditEventsComponent.cs" />
<Compile Include="ContentApps\ContentAppFactoryCollection.cs" />
<Compile Include="ContentApps\ContentAppFactoryCollectionBuilder.cs" />
<Compile Include="ContentApps\ContentEditorContentAppFactory.cs" />
<Compile Include="ContentApps\ContentInfoContentAppFactory.cs" />
<Compile Include="ContentApps\ListViewContentAppFactory.cs" />
<Compile Include="Dashboards\ContentDashboard.cs" />
<Compile Include="Dashboards\DashboardCollection.cs" />
@@ -306,10 +310,6 @@
<Compile Include="Models\ContentEditing\SearchResult.cs" />
<Compile Include="Models\ContentEditing\SearchResults.cs" />
<Compile Include="Models\ContentEditing\UnpublishContent.cs" />
<Compile Include="ContentApps\ContentAppFactoryCollection.cs" />
<Compile Include="ContentApps\ContentAppFactoryCollectionBuilder.cs" />
<Compile Include="ContentApps\ContentEditorContentAppFactory.cs" />
<Compile Include="ContentApps\ContentInfoContentAppFactory.cs" />
<Compile Include="Services\ITreeService.cs" />
<Compile Include="Services\ISectionService.cs" />
<Compile Include="Sections\SectionCollection.cs" />