mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-24 10:11:35 +08:00
Extensions are not enabled any more if they can't actually be loaded, fixes #2437
This commit is contained in:
@@ -194,6 +194,10 @@ Features:
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -114,6 +114,10 @@ namespace Orchard.Tests.Environment.Extensions {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,6 +119,10 @@ namespace Orchard.Tests.Environment.Extensions {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,8 +46,7 @@ namespace Orchard.Modules.Controllers {
|
|||||||
IRecipeManager recipeManager,
|
IRecipeManager recipeManager,
|
||||||
ShellDescriptor shellDescriptor,
|
ShellDescriptor shellDescriptor,
|
||||||
ShellSettings shellSettings,
|
ShellSettings shellSettings,
|
||||||
IShapeFactory shapeFactory)
|
IShapeFactory shapeFactory) {
|
||||||
{
|
|
||||||
Services = services;
|
Services = services;
|
||||||
_extensionDisplayEventHandler = extensionDisplayEventHandlers.FirstOrDefault();
|
_extensionDisplayEventHandler = extensionDisplayEventHandlers.FirstOrDefault();
|
||||||
_moduleService = moduleService;
|
_moduleService = moduleService;
|
||||||
@@ -77,7 +76,7 @@ namespace Orchard.Modules.Controllers {
|
|||||||
|
|
||||||
IEnumerable<ModuleEntry> modules = _extensionManager.AvailableExtensions()
|
IEnumerable<ModuleEntry> modules = _extensionManager.AvailableExtensions()
|
||||||
.Where(extensionDescriptor => DefaultExtensionTypes.IsModule(extensionDescriptor.ExtensionType) &&
|
.Where(extensionDescriptor => DefaultExtensionTypes.IsModule(extensionDescriptor.ExtensionType) &&
|
||||||
|
|
||||||
(string.IsNullOrEmpty(options.SearchText) || extensionDescriptor.Name.ToLowerInvariant().Contains(options.SearchText.ToLowerInvariant())))
|
(string.IsNullOrEmpty(options.SearchText) || extensionDescriptor.Name.ToLowerInvariant().Contains(options.SearchText.ToLowerInvariant())))
|
||||||
.OrderBy(extensionDescriptor => extensionDescriptor.Name)
|
.OrderBy(extensionDescriptor => extensionDescriptor.Name)
|
||||||
.Select(extensionDescriptor => new ModuleEntry { Descriptor = extensionDescriptor });
|
.Select(extensionDescriptor => new ModuleEntry { Descriptor = extensionDescriptor });
|
||||||
@@ -158,13 +157,13 @@ namespace Orchard.Modules.Controllers {
|
|||||||
try {
|
try {
|
||||||
_recipeManager.Execute(recipe);
|
_recipeManager.Execute(recipe);
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch (Exception e) {
|
||||||
Logger.Error(e, "Error while executing recipe {0} in {1}", moduleId, name);
|
Logger.Error(e, "Error while executing recipe {0} in {1}", moduleId, name);
|
||||||
Services.Notifier.Error(T("Recipes {0} contains unsupported module installation steps.", recipe.Name));
|
Services.Notifier.Error(T("Recipes {0} contains unsupported module installation steps.", recipe.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.Notifier.Success(T("The recipe {0} was executed successfully.", recipe.Name));
|
Services.Notifier.Success(T("The recipe {0} was executed successfully.", recipe.Name));
|
||||||
|
|
||||||
return RedirectToAction("Recipes");
|
return RedirectToAction("Recipes");
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -177,15 +176,15 @@ namespace Orchard.Modules.Controllers {
|
|||||||
IEnumerable<ModuleFeature> features = _featureManager.GetAvailableFeatures()
|
IEnumerable<ModuleFeature> features = _featureManager.GetAvailableFeatures()
|
||||||
.Where(f => !DefaultExtensionTypes.IsTheme(f.Extension.ExtensionType))
|
.Where(f => !DefaultExtensionTypes.IsTheme(f.Extension.ExtensionType))
|
||||||
.Select(f => new ModuleFeature {
|
.Select(f => new ModuleFeature {
|
||||||
Descriptor = f,
|
Descriptor = f,
|
||||||
IsEnabled = _shellDescriptor.Features.Any(sf => sf.Name == f.Id),
|
IsEnabled = _shellDescriptor.Features.Any(sf => sf.Name == f.Id),
|
||||||
IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension),
|
IsRecentlyInstalled = _moduleService.IsRecentlyInstalled(f.Extension),
|
||||||
NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id),
|
NeedsUpdate = featuresThatNeedUpdate.Contains(f.Id),
|
||||||
DependentFeatures = _moduleService.GetDependentFeatures(f.Id).Where(x => x.Id != f.Id).ToList()
|
DependentFeatures = _moduleService.GetDependentFeatures(f.Id).Where(x => x.Id != f.Id).ToList()
|
||||||
})
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
return View(new FeaturesViewModel {
|
return View(new FeaturesViewModel {
|
||||||
Features = features,
|
Features = features,
|
||||||
IsAllowed = ExtensionIsAllowed
|
IsAllowed = ExtensionIsAllowed
|
||||||
});
|
});
|
||||||
@@ -212,13 +211,13 @@ namespace Orchard.Modules.Controllers {
|
|||||||
case FeaturesBulkAction.None:
|
case FeaturesBulkAction.None:
|
||||||
break;
|
break;
|
||||||
case FeaturesBulkAction.Enable:
|
case FeaturesBulkAction.Enable:
|
||||||
_moduleService.EnableFeatures(disabledFeatures, force == true);
|
EnableFeatures(disabledFeatures, force == true);
|
||||||
break;
|
break;
|
||||||
case FeaturesBulkAction.Disable:
|
case FeaturesBulkAction.Disable:
|
||||||
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
||||||
break;
|
break;
|
||||||
case FeaturesBulkAction.Toggle:
|
case FeaturesBulkAction.Toggle:
|
||||||
_moduleService.EnableFeatures(disabledFeatures, force == true);
|
EnableFeatures(disabledFeatures, force == true);
|
||||||
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
_moduleService.DisableFeatures(enabledFeatures, force == true);
|
||||||
break;
|
break;
|
||||||
case FeaturesBulkAction.Update:
|
case FeaturesBulkAction.Update:
|
||||||
@@ -250,5 +249,16 @@ namespace Orchard.Modules.Controllers {
|
|||||||
private bool ExtensionIsAllowed(ExtensionDescriptor extensionDescriptor) {
|
private bool ExtensionIsAllowed(ExtensionDescriptor extensionDescriptor) {
|
||||||
return _shellSettings.Modules.Length == 0 || _shellSettings.Modules.Contains(extensionDescriptor.Id);
|
return _shellSettings.Modules.Length == 0 || _shellSettings.Modules.Contains(extensionDescriptor.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void EnableFeatures(List<string> disabledFeatures, bool force) {
|
||||||
|
foreach (var feature in disabledFeatures) {
|
||||||
|
if (_featureManager.HasLoader(feature)) {
|
||||||
|
_moduleService.EnableFeatures(disabledFeatures, force);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Services.Notifier.Error(T("No loader found for feature's (\"{0}\") exension!", feature));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,10 +11,12 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
public class CoreExtensionLoader : ExtensionLoaderBase {
|
public class CoreExtensionLoader : ExtensionLoaderBase {
|
||||||
private const string CoreAssemblyName = "Orchard.Core";
|
private const string CoreAssemblyName = "Orchard.Core";
|
||||||
private readonly IAssemblyLoader _assemblyLoader;
|
private readonly IAssemblyLoader _assemblyLoader;
|
||||||
|
private readonly IDependenciesFolder _dependenciesFolder;
|
||||||
|
|
||||||
public CoreExtensionLoader(IDependenciesFolder dependenciesFolder, IAssemblyLoader assemblyLoader)
|
public CoreExtensionLoader(IAssemblyLoader assemblyLoader, IDependenciesFolder dependenciesFolder)
|
||||||
: base(dependenciesFolder) {
|
: base(dependenciesFolder) {
|
||||||
_assemblyLoader = assemblyLoader;
|
_assemblyLoader = assemblyLoader;
|
||||||
|
_dependenciesFolder = dependenciesFolder;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -59,6 +61,15 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id);
|
||||||
|
if (dependency != null && dependency.LoaderName == this.Name) {
|
||||||
|
return _assemblyLoader.Load(CoreAssemblyName) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static bool IsTypeFromModule(Type type, ExtensionDescriptor descriptor) {
|
private static bool IsTypeFromModule(Type type, ExtensionDescriptor descriptor) {
|
||||||
return (type.Namespace + ".").StartsWith(CoreAssemblyName + "." + descriptor.Id + ".");
|
return (type.Namespace + ".").StartsWith(CoreAssemblyName + "." + descriptor.Id + ".");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -212,6 +212,20 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
return dependencies;
|
return dependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id);
|
||||||
|
if (dependency != null && dependency.LoaderName == this.Name) {
|
||||||
|
var projectPath = GetProjectPath(descriptor);
|
||||||
|
if (projectPath == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _buildManager.GetCompiledAssembly(projectPath) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void AddDependencies(string projectPath, HashSet<string> currentSet) {
|
private void AddDependencies(string projectPath, HashSet<string> currentSet) {
|
||||||
// Skip files from locations other than "~/Modules" and "~/Themes" etc.
|
// Skip files from locations other than "~/Modules" and "~/Themes" etc.
|
||||||
if (string.IsNullOrEmpty(PrefixMatch(projectPath, _extensionsVirtualPathPrefixes))) {
|
if (string.IsNullOrEmpty(PrefixMatch(projectPath, _extensionsVirtualPathPrefixes))) {
|
||||||
|
|||||||
@@ -57,5 +57,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
public virtual IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
|
public virtual IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency) {
|
||||||
return Enumerable.Empty<string>();
|
return Enumerable.Empty<string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract bool LoaderIsSuitable(ExtensionDescriptor descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -59,5 +59,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
/// For example, Razor or WebForms views needs to be recompiled when a dependency of a module changes.
|
/// For example, Razor or WebForms views needs to be recompiled when a dependency of a module changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency);
|
IEnumerable<string> GetVirtualPathDependencies(DependencyDescriptor dependency);
|
||||||
|
|
||||||
|
bool LoaderIsSuitable(ExtensionDescriptor descriptor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -19,6 +19,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
private readonly IAssemblyProbingFolder _assemblyProbingFolder;
|
private readonly IAssemblyProbingFolder _assemblyProbingFolder;
|
||||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||||
private readonly IVirtualPathMonitor _virtualPathMonitor;
|
private readonly IVirtualPathMonitor _virtualPathMonitor;
|
||||||
|
private readonly IDependenciesFolder _dependenciesFolder;
|
||||||
|
|
||||||
public PrecompiledExtensionLoader(
|
public PrecompiledExtensionLoader(
|
||||||
IHostEnvironment hostEnvironment,
|
IHostEnvironment hostEnvironment,
|
||||||
@@ -31,6 +32,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
_assemblyProbingFolder = assemblyProbingFolder;
|
_assemblyProbingFolder = assemblyProbingFolder;
|
||||||
_virtualPathProvider = virtualPathProvider;
|
_virtualPathProvider = virtualPathProvider;
|
||||||
_virtualPathMonitor = virtualPathMonitor;
|
_virtualPathMonitor = virtualPathMonitor;
|
||||||
|
_dependenciesFolder = dependenciesFolder;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -166,7 +168,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
Loader = this,
|
Loader = this,
|
||||||
Name = Path.GetFileNameWithoutExtension(path),
|
Name = Path.GetFileNameWithoutExtension(path),
|
||||||
VirtualPath = path
|
VirtualPath = path
|
||||||
} )
|
})
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
Logger.Information("Done probing references for module '{0}'", descriptor.Id);
|
Logger.Information("Done probing references for module '{0}'", descriptor.Id);
|
||||||
@@ -244,5 +246,14 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
|
|
||||||
return assemblyPath;
|
return assemblyPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id);
|
||||||
|
if (dependency != null && dependency.LoaderName == this.Name) {
|
||||||
|
return _assemblyProbingFolder.AssemblyExists(descriptor.Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -8,10 +8,12 @@ using Orchard.Logging;
|
|||||||
namespace Orchard.Environment.Extensions.Loaders {
|
namespace Orchard.Environment.Extensions.Loaders {
|
||||||
public class RawThemeExtensionLoader : ExtensionLoaderBase {
|
public class RawThemeExtensionLoader : ExtensionLoaderBase {
|
||||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||||
|
private readonly IDependenciesFolder _dependenciesFolder;
|
||||||
|
|
||||||
public RawThemeExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider)
|
public RawThemeExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider)
|
||||||
: base(dependenciesFolder) {
|
: base(dependenciesFolder) {
|
||||||
_virtualPathProvider = virtualPathProvider;
|
_virtualPathProvider = virtualPathProvider;
|
||||||
|
_dependenciesFolder = dependenciesFolder;
|
||||||
|
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -26,12 +28,12 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
return null;
|
return null;
|
||||||
|
|
||||||
// Temporary - theme without own project should be under ~/themes
|
// Temporary - theme without own project should be under ~/themes
|
||||||
if (descriptor.Location.StartsWith("~/Themes",StringComparison.InvariantCultureIgnoreCase)) {
|
if (descriptor.Location.StartsWith("~/Themes", StringComparison.InvariantCultureIgnoreCase)) {
|
||||||
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
string projectPath = _virtualPathProvider.Combine(descriptor.Location, descriptor.Id,
|
||||||
descriptor.Id + ".csproj");
|
descriptor.Id + ".csproj");
|
||||||
|
|
||||||
// ignore themes including a .csproj in this loader
|
// ignore themes including a .csproj in this loader
|
||||||
if ( _virtualPathProvider.FileExists(projectPath) ) {
|
if (_virtualPathProvider.FileExists(projectPath)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,7 +41,7 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
descriptor.Id + ".dll");
|
descriptor.Id + ".dll");
|
||||||
|
|
||||||
// ignore themes with /bin in this loader
|
// ignore themes with /bin in this loader
|
||||||
if ( _virtualPathProvider.FileExists(assemblyPath) )
|
if (_virtualPathProvider.FileExists(assemblyPath))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new ExtensionProbeEntry {
|
return new ExtensionProbeEntry {
|
||||||
@@ -64,5 +66,14 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
ExportedTypes = new Type[0]
|
ExportedTypes = new Type[0]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id);
|
||||||
|
if (dependency != null && dependency.LoaderName == this.Name) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13,12 +13,14 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
public class ReferencedExtensionLoader : ExtensionLoaderBase {
|
public class ReferencedExtensionLoader : ExtensionLoaderBase {
|
||||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||||
private readonly IBuildManager _buildManager;
|
private readonly IBuildManager _buildManager;
|
||||||
|
private readonly IDependenciesFolder _dependenciesFolder;
|
||||||
|
|
||||||
public ReferencedExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider, IBuildManager buildManager)
|
public ReferencedExtensionLoader(IDependenciesFolder dependenciesFolder, IVirtualPathProvider virtualPathProvider, IBuildManager buildManager)
|
||||||
: base(dependenciesFolder) {
|
: base(dependenciesFolder) {
|
||||||
|
|
||||||
_virtualPathProvider = virtualPathProvider;
|
_virtualPathProvider = virtualPathProvider;
|
||||||
_buildManager = buildManager;
|
_buildManager = buildManager;
|
||||||
|
_dependenciesFolder = dependenciesFolder;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,5 +84,14 @@ namespace Orchard.Environment.Extensions.Loaders {
|
|||||||
ExportedTypes = assembly.GetExportedTypes()
|
ExportedTypes = assembly.GetExportedTypes()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool LoaderIsSuitable(ExtensionDescriptor descriptor) {
|
||||||
|
var dependency = _dependenciesFolder.GetDescriptor(descriptor.Id);
|
||||||
|
if (dependency != null && dependency.LoaderName == this.Name) {
|
||||||
|
return _buildManager.GetReferencedAssembly(descriptor.Id) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ using System.Linq;
|
|||||||
using Orchard.Environment.Descriptor;
|
using Orchard.Environment.Descriptor;
|
||||||
using Orchard.Environment.Descriptor.Models;
|
using Orchard.Environment.Descriptor.Models;
|
||||||
using Orchard.Environment.Extensions;
|
using Orchard.Environment.Extensions;
|
||||||
using Orchard.Environment.Extensions.Helpers;
|
using Orchard.Environment.Extensions.Loaders;
|
||||||
using Orchard.Environment.Extensions.Models;
|
using Orchard.Environment.Extensions.Models;
|
||||||
using Orchard.Localization;
|
using Orchard.Localization;
|
||||||
using Orchard.Logging;
|
using Orchard.Logging;
|
||||||
@@ -13,6 +13,7 @@ namespace Orchard.Environment.Features {
|
|||||||
public class FeatureManager : IFeatureManager {
|
public class FeatureManager : IFeatureManager {
|
||||||
private readonly IExtensionManager _extensionManager;
|
private readonly IExtensionManager _extensionManager;
|
||||||
private readonly IShellDescriptorManager _shellDescriptorManager;
|
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||||
|
private readonly IEnumerable<IExtensionLoader> _loaders;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Delegate to notify about feature dependencies.
|
/// Delegate to notify about feature dependencies.
|
||||||
@@ -21,10 +22,11 @@ namespace Orchard.Environment.Features {
|
|||||||
|
|
||||||
public FeatureManager(
|
public FeatureManager(
|
||||||
IExtensionManager extensionManager,
|
IExtensionManager extensionManager,
|
||||||
IShellDescriptorManager shellDescriptorManager) {
|
IShellDescriptorManager shellDescriptorManager,
|
||||||
|
IEnumerable<IExtensionLoader> loaders) {
|
||||||
_extensionManager = extensionManager;
|
_extensionManager = extensionManager;
|
||||||
_shellDescriptorManager = shellDescriptorManager;
|
_shellDescriptorManager = shellDescriptorManager;
|
||||||
|
_loaders = loaders;
|
||||||
T = NullLocalizer.Instance;
|
T = NullLocalizer.Instance;
|
||||||
Logger = NullLogger.Instance;
|
Logger = NullLogger.Instance;
|
||||||
}
|
}
|
||||||
@@ -161,6 +163,22 @@ namespace Orchard.Environment.Features {
|
|||||||
return GetAffectedFeatures(featureId, availableFeatures, getEnabledDependants);
|
return GetAffectedFeatures(featureId, availableFeatures, getEnabledDependants);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasLoader(string featureId) {
|
||||||
|
var descriptor = _extensionManager
|
||||||
|
.AvailableExtensions()
|
||||||
|
.Where(d => DefaultExtensionTypes.IsModule(d.ExtensionType) || DefaultExtensionTypes.IsTheme(d.ExtensionType))
|
||||||
|
.OrderBy(d => d.Id)
|
||||||
|
.FirstOrDefault(e => e.Id == featureId || e.Features.Select(f => f.Id).Contains(featureId));
|
||||||
|
|
||||||
|
foreach (var loader in _loaders) {
|
||||||
|
if (loader.LoaderIsSuitable(descriptor)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Enables a feature.
|
/// Enables a feature.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -228,7 +246,7 @@ namespace Orchard.Environment.Features {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<string> GetAffectedFeatures(
|
private static IEnumerable<string> GetAffectedFeatures(
|
||||||
string featureId, IDictionary<FeatureDescriptor, bool> features,
|
string featureId, IDictionary<FeatureDescriptor, bool> features,
|
||||||
Func<string, IDictionary<FeatureDescriptor, bool>, IDictionary<FeatureDescriptor, bool>> getAffectedDependencies) {
|
Func<string, IDictionary<FeatureDescriptor, bool>, IDictionary<FeatureDescriptor, bool>> getAffectedDependencies) {
|
||||||
|
|
||||||
var dependencies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { featureId };
|
var dependencies = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { featureId };
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Orchard.Environment.Extensions.Models;
|
using Orchard.Environment.Extensions.Models;
|
||||||
|
using Orchard.Environment.Extensions;
|
||||||
|
|
||||||
namespace Orchard.Environment.Features {
|
namespace Orchard.Environment.Features {
|
||||||
public delegate void FeatureDependencyNotificationHandler(string messageFormat, string featureId, IEnumerable<string> featureIds);
|
public delegate void FeatureDependencyNotificationHandler(string messageFormat, string featureId, IEnumerable<string> featureIds);
|
||||||
@@ -61,5 +62,12 @@ namespace Orchard.Environment.Features {
|
|||||||
/// <param name="featureId">ID of the feature to check.</param>
|
/// <param name="featureId">ID of the feature to check.</param>
|
||||||
/// <returns>An enumeration with dependent feature IDs.</returns>
|
/// <returns>An enumeration with dependent feature IDs.</returns>
|
||||||
IEnumerable<string> GetDependentFeatures(string featureId);
|
IEnumerable<string> GetDependentFeatures(string featureId);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the feature's extension has a loadee, i.e. a suitable <see cref="IExtensionLoader"/> can be found.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="featureId">ID of the feature to check.</param>
|
||||||
|
/// <returns><c>True</c> if a suitable <see cref="IExtensionLoader"/> can be found.</returns>
|
||||||
|
bool HasLoader(string featureId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user