diff --git a/src/Umbraco.Core/CompositionExtensions.cs b/src/Umbraco.Core/CompositionExtensions.cs
index 828a577c34..5dd33c2a60 100644
--- a/src/Umbraco.Core/CompositionExtensions.cs
+++ b/src/Umbraco.Core/CompositionExtensions.cs
@@ -4,6 +4,7 @@ using Umbraco.Core.Composing;
using Umbraco.Core.Dictionary;
using Umbraco.Core.IO;
using Umbraco.Core.Logging.Viewer;
+using Umbraco.Core.Manifest;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PackageActions;
using Umbraco.Core.Persistence.Mappers;
@@ -66,9 +67,16 @@ namespace Umbraco.Core
/// Gets the validators collection builder.
///
/// The composition.
- internal static ManifestValueValidatorCollectionBuilder Validators(this Composition composition)
+ internal static ManifestValueValidatorCollectionBuilder ManifestValueValidators(this Composition composition)
=> composition.WithCollectionBuilder();
+ ///
+ /// Gets the manifest filter collection builder.
+ ///
+ /// The composition.
+ public static ManifestFilterCollectionBuilder ManifestFilters(this Composition composition)
+ => composition.WithCollectionBuilder();
+
///
/// Gets the components collection builder.
///
diff --git a/src/Umbraco.Core/ConfigsExtensions.cs b/src/Umbraco.Core/ConfigsExtensions.cs
index 6fdf7ea3b9..d1672c6c7f 100644
--- a/src/Umbraco.Core/ConfigsExtensions.cs
+++ b/src/Umbraco.Core/ConfigsExtensions.cs
@@ -7,6 +7,7 @@ using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
+using Umbraco.Core.Manifest;
namespace Umbraco.Core
{
@@ -41,7 +42,12 @@ namespace Umbraco.Core
configs.Add(() => new CoreDebug());
// GridConfig depends on runtime caches, manifest parsers... and cannot be available during composition
- configs.Add(factory => new GridConfig(factory.GetInstance(), factory.GetInstance(), configDir, factory.GetInstance().Debug));
+ configs.Add(factory => new GridConfig(
+ factory.GetInstance(),
+ factory.GetInstance(),
+ configDir,
+ factory.GetInstance(),
+ factory.GetInstance().Debug));
}
}
}
diff --git a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
index b2dae09fc9..9aead74886 100644
--- a/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
+++ b/src/Umbraco.Core/Configuration/Grid/GridConfig.cs
@@ -1,14 +1,15 @@
using System.IO;
using Umbraco.Core.Cache;
using Umbraco.Core.Logging;
+using Umbraco.Core.Manifest;
namespace Umbraco.Core.Configuration.Grid
{
class GridConfig : IGridConfig
{
- public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
+ public GridConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
{
- EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, isDebug);
+ EditorsConfig = new GridEditorsConfig(logger, appCaches, configFolder, manifestParser, isDebug);
}
public IGridEditorsConfig EditorsConfig { get; }
diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
index 0e7ef62c58..d434da8c70 100644
--- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
+++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs
@@ -1,9 +1,7 @@
using System;
using System.Collections.Generic;
using System.IO;
-using Newtonsoft.Json.Linq;
using Umbraco.Core.Cache;
-using Umbraco.Core.Composing;
using Umbraco.Core.Logging;
using Umbraco.Core.Manifest;
using Umbraco.Core.PropertyEditors;
@@ -15,13 +13,15 @@ namespace Umbraco.Core.Configuration.Grid
private readonly ILogger _logger;
private readonly AppCaches _appCaches;
private readonly DirectoryInfo _configFolder;
+ private readonly ManifestParser _manifestParser;
private readonly bool _isDebug;
- public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, bool isDebug)
+ public GridEditorsConfig(ILogger logger, AppCaches appCaches, DirectoryInfo configFolder, ManifestParser manifestParser, bool isDebug)
{
_logger = logger;
_appCaches = appCaches;
_configFolder = configFolder;
+ _manifestParser = manifestParser;
_isDebug = isDebug;
}
@@ -31,9 +31,6 @@ namespace Umbraco.Core.Configuration.Grid
{
List GetResult()
{
- // TODO: should use the common one somehow! + ignoring _appPlugins here!
- var parser = new ManifestParser(_appCaches, Current.ManifestValidators, _logger);
-
var editors = new List();
var gridConfig = Path.Combine(_configFolder.FullName, "grid.editors.config.js");
if (File.Exists(gridConfig))
@@ -42,7 +39,7 @@ namespace Umbraco.Core.Configuration.Grid
try
{
- editors.AddRange(parser.ParseGridEditors(sourceString));
+ editors.AddRange(_manifestParser.ParseGridEditors(sourceString));
}
catch (Exception ex)
{
@@ -51,7 +48,7 @@ namespace Umbraco.Core.Configuration.Grid
}
// add manifest editors, skip duplicates
- foreach (var gridEditor in parser.Manifest.GridEditors)
+ foreach (var gridEditor in _manifestParser.Manifest.GridEditors)
{
if (editors.Contains(gridEditor) == false) editors.Add(gridEditor);
}
diff --git a/src/Umbraco.Core/Manifest/IManifestFilter.cs b/src/Umbraco.Core/Manifest/IManifestFilter.cs
new file mode 100644
index 0000000000..505f13d385
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/IManifestFilter.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace Umbraco.Core.Manifest
+{
+ ///
+ /// Provides filtering for package manifests.
+ ///
+ public interface IManifestFilter
+ {
+ ///
+ /// Filters package manifests.
+ ///
+ /// The package manifests.
+ ///
+ /// It is possible to remove, change, or add manifests.
+ ///
+ void Filter(List manifests);
+ }
+}
diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs b/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs
new file mode 100644
index 0000000000..febdb7e356
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/ManifestFilterCollection.cs
@@ -0,0 +1,28 @@
+using System.Collections.Generic;
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Manifest
+{
+ ///
+ /// Contains the manifest filters.
+ ///
+ public class ManifestFilterCollection : BuilderCollectionBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public ManifestFilterCollection(IEnumerable items)
+ : base(items)
+ { }
+
+ ///
+ /// Filters package manifests.
+ ///
+ /// The package manifests.
+ public void Filter(List manifests)
+ {
+ foreach (var filter in this)
+ filter.Filter(manifests);
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs b/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs
new file mode 100644
index 0000000000..4d98700f93
--- /dev/null
+++ b/src/Umbraco.Core/Manifest/ManifestFilterCollectionBuilder.cs
@@ -0,0 +1,12 @@
+using Umbraco.Core.Composing;
+
+namespace Umbraco.Core.Manifest
+{
+ public class ManifestFilterCollectionBuilder : OrderedCollectionBuilderBase
+ {
+ protected override ManifestFilterCollectionBuilder This => this;
+
+ // do NOT cache this, it's only used once
+ protected override Lifetime CollectionLifetime => Lifetime.Transient;
+ }
+}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Manifest/ManifestParser.cs b/src/Umbraco.Core/Manifest/ManifestParser.cs
index dc40cd90a2..efd9e92b1f 100644
--- a/src/Umbraco.Core/Manifest/ManifestParser.cs
+++ b/src/Umbraco.Core/Manifest/ManifestParser.cs
@@ -22,24 +22,26 @@ namespace Umbraco.Core.Manifest
private readonly IAppPolicyCache _cache;
private readonly ILogger _logger;
private readonly ManifestValueValidatorCollection _validators;
+ private readonly ManifestFilterCollection _filters;
private string _path;
///
/// Initializes a new instance of the class.
///
- public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ILogger logger)
- : this(appCaches, validators, "~/App_Plugins", logger)
+ public ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, ILogger logger)
+ : this(appCaches, validators, filters, "~/App_Plugins", logger)
{ }
///
/// Initializes a new instance of the class.
///
- private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, string path, ILogger logger)
+ private ManifestParser(AppCaches appCaches, ManifestValueValidatorCollection validators, ManifestFilterCollection filters, string path, ILogger logger)
{
if (appCaches == null) throw new ArgumentNullException(nameof(appCaches));
_cache = appCaches.RuntimeCache;
_validators = validators ?? throw new ArgumentNullException(nameof(validators));
+ _filters = filters ?? throw new ArgumentNullException(nameof(filters));
if (string.IsNullOrWhiteSpace(path)) throw new ArgumentNullOrEmptyException(nameof(path));
Path = path;
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
@@ -78,6 +80,7 @@ namespace Umbraco.Core.Manifest
if (string.IsNullOrWhiteSpace(text))
continue;
var manifest = ParseManifest(text);
+ manifest.Source = path;
manifests.Add(manifest);
}
catch (Exception e)
@@ -86,6 +89,8 @@ namespace Umbraco.Core.Manifest
}
}
+ _filters.Filter(manifests);
+
return manifests;
}
diff --git a/src/Umbraco.Core/Manifest/PackageManifest.cs b/src/Umbraco.Core/Manifest/PackageManifest.cs
index 475ee8a7f8..e50eb69467 100644
--- a/src/Umbraco.Core/Manifest/PackageManifest.cs
+++ b/src/Umbraco.Core/Manifest/PackageManifest.cs
@@ -9,6 +9,16 @@ namespace Umbraco.Core.Manifest
///
public class PackageManifest
{
+ ///
+ /// Gets the source path of the manifest.
+ ///
+ ///
+ /// Gets the full absolute file path of the manifest,
+ /// using system directory separators.
+ ///
+ [JsonIgnore]
+ public string Source { get; set; }
+
///
/// Gets or sets the scripts listed in the manifest.
///
diff --git a/src/Umbraco.Core/Runtime/CoreInitialComposer.cs b/src/Umbraco.Core/Runtime/CoreInitialComposer.cs
index f32a46f3f8..1f004846d0 100644
--- a/src/Umbraco.Core/Runtime/CoreInitialComposer.cs
+++ b/src/Umbraco.Core/Runtime/CoreInitialComposer.cs
@@ -58,7 +58,7 @@ namespace Umbraco.Core.Runtime
composition.RegisterUnique();
// register our predefined validators
- composition.WithCollectionBuilder()
+ composition.ManifestValueValidators()
.Add()
.Add()
.Add()
@@ -66,6 +66,9 @@ namespace Umbraco.Core.Runtime
.Add()
.Add();
+ // register the manifest filter collection builder (collection is empty by default)
+ composition.ManifestFilters();
+
// properties and parameters derive from data editors
composition.WithCollectionBuilder()
.Add(() => composition.TypeLoader.GetDataEditors());
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index d06bedb3ef..1da0ecb772 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -219,6 +219,9 @@
+
+
+
diff --git a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs
index 6605bc4546..1c90f68d62 100644
--- a/src/Umbraco.Tests/Manifest/ManifestParserTests.cs
+++ b/src/Umbraco.Tests/Manifest/ManifestParserTests.cs
@@ -44,7 +44,7 @@ namespace Umbraco.Tests.Manifest
new RequiredValidator(Mock.Of()),
new RegexValidator(Mock.Of(), null)
};
- _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), Mock.Of());
+ _parser = new ManifestParser(AppCaches.Disabled, new ManifestValueValidatorCollection(validators), new ManifestFilterCollection(Array.Empty()), Mock.Of());
}
[Test]
diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
index 2d2cbaa3fd..7e72a5aefb 100644
--- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
+++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs
@@ -248,6 +248,11 @@ namespace Umbraco.Tests.Testing
// register empty content apps collection
Composition.WithCollectionBuilder();
+
+ // manifest
+ Composition.ManifestValueValidators();
+ Composition.ManifestFilters();
+
}
protected virtual void ComposeMapper(bool configure)
diff --git a/src/Umbraco.Web/Editors/IEditorValidator.cs b/src/Umbraco.Web/Editors/IEditorValidator.cs
index bec978788c..d469d9d9eb 100644
--- a/src/Umbraco.Web/Editors/IEditorValidator.cs
+++ b/src/Umbraco.Web/Editors/IEditorValidator.cs
@@ -21,7 +21,7 @@ namespace Umbraco.Web.Editors
///
/// Provides a general object validator.
///
- internal interface IEditorValidator : IDiscoverable
+ public interface IEditorValidator : IDiscoverable
{
///
/// Gets the object type validated by this validator.
diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs
index 359e8ac3b6..9a1b248284 100644
--- a/src/Umbraco.Web/Properties/AssemblyInfo.cs
+++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs
@@ -32,9 +32,6 @@ using System.Runtime.InteropServices;
// Umbraco Headless
[assembly: InternalsVisibleTo("Umbraco.Headless")]
-// Umbraco ModelsBuilder
-[assembly: InternalsVisibleTo("Umbraco.ModelsBuilder")]
-
// code analysis
// IDE1006 is broken, wants _value syntax for consts, etc - and it's even confusing ppl at MS, kill it
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "~_~")]