Makes the TourFilterResolver a real resolver
This commit is contained in:
@@ -394,7 +394,7 @@ namespace Umbraco.Core.ObjectResolution
|
||||
/// WARNING! Do not use this unless you know what you are doing, clear all types registered and instances
|
||||
/// created. Typically only used if a resolver is no longer used in an application and memory is to be GC'd
|
||||
/// </summary>
|
||||
internal void ResetCollections()
|
||||
internal virtual void ResetCollections()
|
||||
{
|
||||
using (new WriteLock(_lock))
|
||||
{
|
||||
|
||||
@@ -23,15 +23,21 @@ namespace Umbraco.Web.Editors
|
||||
if (UmbracoConfig.For.UmbracoSettings().BackOffice.Tours.EnableTours == false)
|
||||
return result;
|
||||
|
||||
var filters = TourFilterResolver.Current.Filters.ToList();
|
||||
|
||||
//get all filters that will be applied to all tour aliases
|
||||
var aliasOnlyFilters = filters.Where(x => x.PluginName == null && x.TourFileName == null).ToList();
|
||||
|
||||
//don't pass in any filters for core tours that have a plugin name assigned
|
||||
var nonPluginFilters = filters.Where(x => x.PluginName == null).ToList();
|
||||
|
||||
//add core tour files
|
||||
var coreToursPath = Path.Combine(IOHelper.MapPath(SystemDirectories.Config), "BackOfficeTours");
|
||||
if (Directory.Exists(coreToursPath))
|
||||
{
|
||||
var coreTourFiles = Directory.GetFiles(coreToursPath, "*.json");
|
||||
|
||||
foreach (var tourFile in coreTourFiles)
|
||||
foreach (var tourFile in Directory.EnumerateFiles(coreToursPath, "*.json"))
|
||||
{
|
||||
TryParseTourFile(tourFile, result);
|
||||
TryParseTourFile(tourFile, result, nonPluginFilters, aliasOnlyFilters);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +45,14 @@ namespace Umbraco.Web.Editors
|
||||
foreach (var plugin in Directory.EnumerateDirectories(IOHelper.MapPath(SystemDirectories.AppPlugins)))
|
||||
{
|
||||
var pluginName = Path.GetFileName(plugin.TrimEnd('\\'));
|
||||
var pluginFilters = filters.Where(x => x.PluginName != null && x.PluginName.IsMatch(pluginName)).ToList();
|
||||
|
||||
//If there is any filter applied to match the plugin only (no file or tour alias) then ignore the plugin entirely
|
||||
var isPluginFiltered = pluginFilters.Any(x => x.TourFileName == null && x.TourAlias == null);
|
||||
if (isPluginFiltered) continue;
|
||||
|
||||
//combine matched package filters with filters not specific to a package
|
||||
var combinedFilters = nonPluginFilters.Concat(pluginFilters).ToList();
|
||||
|
||||
foreach (var backofficeDir in Directory.EnumerateDirectories(plugin, "backoffice"))
|
||||
{
|
||||
@@ -46,7 +60,7 @@ namespace Umbraco.Web.Editors
|
||||
{
|
||||
foreach (var tourFile in Directory.EnumerateFiles(tourDir, "*.json"))
|
||||
{
|
||||
TryParseTourFile(tourFile, result, pluginName);
|
||||
TryParseTourFile(tourFile, result, combinedFilters, aliasOnlyFilters, pluginName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,22 +69,44 @@ namespace Umbraco.Web.Editors
|
||||
return result.OrderBy(x => x.FileName, StringComparer.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
private void TryParseTourFile(string tourFile, List<BackOfficeTourFile> result, string pluginName = null)
|
||||
private void TryParseTourFile(string tourFile,
|
||||
ICollection<BackOfficeTourFile> result,
|
||||
List<BackOfficeTourFilter> filters,
|
||||
List<BackOfficeTourFilter> aliasOnlyFilters,
|
||||
string pluginName = null)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(tourFile);
|
||||
if (fileName == null) return;
|
||||
|
||||
//get the filters specific to this file
|
||||
var fileFilters = filters.Where(x => x.TourFileName != null && x.TourFileName.IsMatch(fileName)).ToList();
|
||||
|
||||
//If there is any filter applied to match the file only (no tour alias) then ignore the file entirely
|
||||
var isFileFiltered = fileFilters.Any(x => x.TourAlias == null);
|
||||
if (isFileFiltered) return;
|
||||
|
||||
//now combine all aliases to filter below
|
||||
var aliasFilters = aliasOnlyFilters.Concat(filters.Where(x => x.TourAlias != null))
|
||||
.Select(x => x.TourAlias)
|
||||
.ToList();
|
||||
|
||||
try
|
||||
{
|
||||
var contents = File.ReadAllText(tourFile);
|
||||
var tours = JsonConvert.DeserializeObject<BackOfficeTour[]>(contents);
|
||||
var disabledTours = TourFilterResolver.Current.DisabledTours;
|
||||
|
||||
result.Add(new BackOfficeTourFile
|
||||
var tour = new BackOfficeTourFile
|
||||
{
|
||||
FileName = Path.GetFileNameWithoutExtension(tourFile),
|
||||
PluginName = pluginName,
|
||||
Tours = tours
|
||||
.Where(x => disabledTours.Contains(x.Alias, StringComparer.InvariantCultureIgnoreCase) == false)
|
||||
.Where(x => aliasFilters.Count == 0 || aliasFilters.All(filter => filter.IsMatch(x.Alias)) == false)
|
||||
.ToArray()
|
||||
});
|
||||
};
|
||||
|
||||
//don't add if all of the tours are filtered
|
||||
if (tour.Tours.Any())
|
||||
result.Add(tour);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
|
||||
61
src/Umbraco.Web/Models/BackOfficeTourFilter.cs
Normal file
61
src/Umbraco.Web/Models/BackOfficeTourFilter.cs
Normal file
@@ -0,0 +1,61 @@
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
public class BackOfficeTourFilter
|
||||
{
|
||||
public Regex PluginName { get; private set; }
|
||||
public Regex TourFileName { get; private set; }
|
||||
public Regex TourAlias { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Create a filter to filter out a whole plugin's tours
|
||||
/// </summary>
|
||||
/// <param name="pluginName"></param>
|
||||
/// <returns></returns>
|
||||
public static BackOfficeTourFilter FilterPlugin(Regex pluginName)
|
||||
{
|
||||
return new BackOfficeTourFilter(pluginName, null, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a filter to filter out a whole tour file
|
||||
/// </summary>
|
||||
/// <param name="tourFileName"></param>
|
||||
/// <returns></returns>
|
||||
public static BackOfficeTourFilter FilterFile(Regex tourFileName)
|
||||
{
|
||||
return new BackOfficeTourFilter(null, tourFileName, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a filter to filter out a tour alias, this will filter out the same alias found in all files
|
||||
/// </summary>
|
||||
/// <param name="tourAlias"></param>
|
||||
/// <returns></returns>
|
||||
public static BackOfficeTourFilter FilterAlias(Regex tourAlias)
|
||||
{
|
||||
return new BackOfficeTourFilter(null, null, tourAlias);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Constructor to create a tour filter
|
||||
/// </summary>
|
||||
/// <param name="pluginName">Value to filter out tours by a plugin, can be null</param>
|
||||
/// <param name="tourFileName">Value to filter out a tour file, can be null</param>
|
||||
/// <param name="tourAlias">Value to filter out a tour alias, can be null</param>
|
||||
/// <remarks>
|
||||
/// Depending on what is null will depend on how the filter is applied.
|
||||
/// If pluginName is not NULL and it's matched then we check if tourFileName is not NULL and it's matched then we check tour alias is not NULL and then match it,
|
||||
/// if any steps is NULL then the filters upstream are applied.
|
||||
/// Example, pluginName = "hello", tourFileName="stuff", tourAlias=NULL = we will filter out the tour file "stuff" from the plugin "hello" but not from other plugins if the same file name exists.
|
||||
/// Example, tourAlias="test.*" = we will filter out all tour aliases that start with the word "test" regardless of the plugin or file name
|
||||
/// </remarks>
|
||||
public BackOfficeTourFilter(Regex pluginName, Regex tourFileName, Regex tourAlias)
|
||||
{
|
||||
PluginName = pluginName;
|
||||
TourFileName = tourFileName;
|
||||
TourAlias = tourAlias;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,79 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.ObjectResolution;
|
||||
using Umbraco.Web.Models;
|
||||
|
||||
namespace Umbraco.Web
|
||||
{
|
||||
public class TourFilterResolver
|
||||
/// <summary>
|
||||
/// Allows for adding filters for tours during startup
|
||||
/// </summary>
|
||||
public class TourFilterResolver : ManyObjectsResolverBase<TourFilterResolver, BackOfficeTourFilter>
|
||||
{
|
||||
private static TourFilterResolver _current;
|
||||
|
||||
private readonly HashSet<string> _disabledTours;
|
||||
|
||||
public TourFilterResolver()
|
||||
public TourFilterResolver(IServiceProvider serviceProvider, ILogger logger) : base(serviceProvider, logger)
|
||||
{
|
||||
_disabledTours = new HashSet<string>();
|
||||
}
|
||||
|
||||
public static TourFilterResolver Current
|
||||
private readonly HashSet<BackOfficeTourFilter> _instances = new HashSet<BackOfficeTourFilter>();
|
||||
|
||||
public IEnumerable<BackOfficeTourFilter> Filters
|
||||
{
|
||||
get { return _current ?? (_current = new TourFilterResolver()); }
|
||||
get { return Values; }
|
||||
}
|
||||
|
||||
public void Disable(string tour)
|
||||
/// <summary>
|
||||
/// Adds a filter instance
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
public void AddFilter(BackOfficeTourFilter filter)
|
||||
{
|
||||
_disabledTours.Add(tour);
|
||||
using (Resolution.Configuration)
|
||||
_instances.Add(filter);
|
||||
}
|
||||
|
||||
public string[] DisabledTours
|
||||
/// <summary>
|
||||
/// Removes a filter instance
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
public void RemoveFilter(BackOfficeTourFilter filter)
|
||||
{
|
||||
get { return _disabledTours.ToArray(); }
|
||||
using (Resolution.Configuration)
|
||||
_instances.Remove(filter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a filter instance based on callback
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
public void RemoveFilterWhere(Func<BackOfficeTourFilter, bool> filter)
|
||||
{
|
||||
using (Resolution.Configuration)
|
||||
_instances.RemoveWhere(new Predicate<BackOfficeTourFilter>(filter));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>
|
||||
/// Overridden to return the combined created instances based on the resolved Types and the Concrete values added with AddFilter
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
protected override IEnumerable<BackOfficeTourFilter> CreateInstances()
|
||||
{
|
||||
var createdInstances = base.CreateInstances();
|
||||
return createdInstances.Concat(_instances);
|
||||
}
|
||||
|
||||
public override void Clear()
|
||||
{
|
||||
base.Clear();
|
||||
_instances.Clear();
|
||||
}
|
||||
|
||||
internal override void ResetCollections()
|
||||
{
|
||||
base.ResetCollections();
|
||||
_instances.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,6 +328,7 @@
|
||||
<Compile Include="Editors\ParameterSwapControllerActionSelector.cs" />
|
||||
<Compile Include="Editors\CodeFileController.cs" />
|
||||
<Compile Include="Editors\TourController.cs" />
|
||||
<Compile Include="Models\BackOfficeTourFilter.cs" />
|
||||
<Compile Include="TourFilterResolver.cs" />
|
||||
<Compile Include="Editors\UserEditorAuthorizationHelper.cs" />
|
||||
<Compile Include="Editors\UserGroupAuthorizationAttribute.cs" />
|
||||
|
||||
@@ -353,6 +353,8 @@ namespace Umbraco.Web
|
||||
{
|
||||
base.InitializeResolvers();
|
||||
|
||||
TourFilterResolver.Current = new TourFilterResolver(ServiceProvider, LoggerResolver.Current.Logger);
|
||||
|
||||
SearchableTreeResolver.Current = new SearchableTreeResolver(ServiceProvider, LoggerResolver.Current.Logger, ApplicationContext.Services.ApplicationTreeService, () => PluginManager.ResolveSearchableTrees());
|
||||
|
||||
XsltExtensionsResolver.Current = new XsltExtensionsResolver(ServiceProvider, LoggerResolver.Current.Logger, () => PluginManager.ResolveXsltExtensions());
|
||||
|
||||
Reference in New Issue
Block a user