mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
NavigationManager hardened against broken navigation providers.
--HG-- branch : dev
This commit is contained in:
@@ -45,6 +45,14 @@ namespace Orchard.Tests.UI.Navigation {
|
||||
Assert.That(menuItems.Last().Items.Single().Text.TextHint, Is.EqualTo("Frap"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavigationManagerShouldCatchProviderErrors() {
|
||||
var manager = new NavigationManager(new[] { new BrokenProvider() }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices());
|
||||
|
||||
var menuItems = manager.BuildMenu("admin");
|
||||
Assert.That(menuItems.Count(), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void NavigationManagerShouldMergeAndOrderNavigation() {
|
||||
var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices());
|
||||
@@ -83,6 +91,14 @@ namespace Orchard.Tests.UI.Navigation {
|
||||
}
|
||||
}
|
||||
|
||||
public class BrokenProvider : INavigationProvider {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
throw new NullReferenceException();
|
||||
}
|
||||
}
|
||||
|
||||
public class Stub2Provider : INavigationProvider {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
|
||||
@@ -20,20 +20,16 @@ namespace Orchard.Core.Navigation.Services {
|
||||
public string MenuName { get { return "admin"; } }
|
||||
|
||||
public void GetNavigation(NavigationBuilder builder) {
|
||||
var partDefinition = _contentDefinitionManager.GetPartDefinition("AdminMenuPart");
|
||||
// if the part doesn't even exist, it hasn't been migrated yet... trying to query for AdminMenuPart items would cause an error.
|
||||
if (partDefinition != null) {
|
||||
var menuParts = _contentManager.Query<AdminMenuPart, AdminMenuPartRecord>().Where(x => x.OnAdminMenu).List();
|
||||
foreach (var menuPart in menuParts) {
|
||||
if (menuPart != null) {
|
||||
var part = menuPart;
|
||||
var menuParts = _contentManager.Query<AdminMenuPart, AdminMenuPartRecord>().Where(x => x.OnAdminMenu).List();
|
||||
foreach (var menuPart in menuParts) {
|
||||
if (menuPart != null) {
|
||||
var part = menuPart;
|
||||
|
||||
builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.AdminMenuText)),
|
||||
part.AdminMenuPosition,
|
||||
item => item.Action(_contentManager.GetItemMetadata(part.ContentItem).AdminRouteValues));
|
||||
// todo: somehow determine if they will ultimately have rights to the destination and hide if not. possibly would need to add a Permission to metadata.
|
||||
// todo: give an iconset somehow (e.g. based on convention, module/content/<content-type>.adminmenu.png).
|
||||
}
|
||||
builder.Add(new LocalizedString(HttpUtility.HtmlEncode(part.AdminMenuText)),
|
||||
part.AdminMenuPosition,
|
||||
item => item.Action(_contentManager.GetItemMetadata(part.ContentItem).AdminRouteValues));
|
||||
// todo: somehow determine if they will ultimately have rights to the destination and hide if not. possibly would need to add a Permission to metadata.
|
||||
// todo: give an iconset somehow (e.g. based on convention, module/content/<content-type>.adminmenu.png).
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Web.Mvc;
|
||||
using System.Web.Routing;
|
||||
using Orchard.Logging;
|
||||
using Orchard.Security;
|
||||
using Orchard.Security.Permissions;
|
||||
|
||||
@@ -17,8 +19,11 @@ namespace Orchard.UI.Navigation {
|
||||
_authorizationService = authorizationService;
|
||||
_urlHelper = urlHelper;
|
||||
_orchardServices = orchardServices;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IEnumerable<MenuItem> BuildMenu(string menuName) {
|
||||
var sources = GetSources(menuName);
|
||||
return FinishMenu(Reduce(Merge(sources)).ToArray());
|
||||
@@ -84,8 +89,17 @@ namespace Orchard.UI.Navigation {
|
||||
foreach (var provider in _providers) {
|
||||
if (provider.MenuName == menuName) {
|
||||
var builder = new NavigationBuilder();
|
||||
provider.GetNavigation(builder);
|
||||
yield return builder.Build();
|
||||
IEnumerable<MenuItem> items = null;
|
||||
try {
|
||||
provider.GetNavigation(builder);
|
||||
items = builder.Build();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Error(ex, "Unexpected error while querying a navigation provider. It was ignored. The menu provided by the provider may not be complete.");
|
||||
}
|
||||
if (items != null) {
|
||||
yield return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,8 +108,17 @@ namespace Orchard.UI.Navigation {
|
||||
foreach (var provider in _providers) {
|
||||
if (provider.MenuName == menuName) {
|
||||
var builder = new NavigationBuilder();
|
||||
provider.GetNavigation(builder);
|
||||
yield return builder.BuildImageSets();
|
||||
IEnumerable<string> imageSets = null;
|
||||
try {
|
||||
provider.GetNavigation(builder);
|
||||
imageSets = builder.BuildImageSets();
|
||||
}
|
||||
catch (Exception ex) {
|
||||
Logger.Error(ex, "Unexpected error while querying a navigation provider. It was ignored. The menu provided by the provider may not be complete.");
|
||||
}
|
||||
if (imageSets != null) {
|
||||
yield return imageSets;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user