From 43232e2c636b6ca6d697f60baffd1226fc7b9496 Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Tue, 22 May 2012 17:48:19 -0700 Subject: [PATCH] Adding INavigationFilter to alter the menu dynamically --HG-- branch : 1.x --- .../UI/Navigation/NavigationManagerTests.cs | 8 +++---- src/Orchard/Orchard.Framework.csproj | 1 + .../UI/Navigation/INavigationFilter.cs | 7 ++++++ src/Orchard/UI/Navigation/MenuItem.cs | 2 -- .../UI/Navigation/NavigationBuilder.cs | 6 +++++ .../UI/Navigation/NavigationItemBuilder.cs | 5 ---- .../UI/Navigation/NavigationManager.cs | 24 ++++++++++++++----- 7 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 src/Orchard/UI/Navigation/INavigationFilter.cs diff --git a/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs b/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs index 5bf0ec9c4..fe2a8c24b 100644 --- a/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs +++ b/src/Orchard.Tests/UI/Navigation/NavigationManagerTests.cs @@ -18,7 +18,7 @@ namespace Orchard.Tests.UI.Navigation { public class NavigationManagerTests { [Test] public void EmptyMenuIfNameDoesntMatch() { - var manager = new NavigationManager(new[] { new StubProvider() }, new IMenuProvider[] { }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); + var manager = new NavigationManager(new[] { new StubProvider() }, new IMenuProvider[] { }, new StubAuth(), new INavigationFilter[0], new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); var menuItems = manager.BuildMenu("primary"); Assert.That(menuItems.Count(), Is.EqualTo(0)); @@ -35,7 +35,7 @@ namespace Orchard.Tests.UI.Navigation { [Test] public void NavigationManagerShouldUseProvidersToBuildNamedMenu() { - var manager = new NavigationManager(new[] { new StubProvider() }, new IMenuProvider[] {}, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); + var manager = new NavigationManager(new[] { new StubProvider() }, new IMenuProvider[] { }, new StubAuth(), new INavigationFilter[0], new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); var menuItems = manager.BuildMenu("admin"); Assert.That(menuItems.Count(), Is.EqualTo(2)); @@ -47,7 +47,7 @@ namespace Orchard.Tests.UI.Navigation { [Test] public void NavigationManagerShouldCatchProviderErrors() { - var manager = new NavigationManager(new[] { new BrokenProvider() }, new IMenuProvider[] { }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); + var manager = new NavigationManager(new[] { new BrokenProvider() }, new IMenuProvider[] { }, new StubAuth(), new INavigationFilter[0], new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); var menuItems = manager.BuildMenu("admin"); Assert.That(menuItems.Count(), Is.EqualTo(0)); @@ -55,7 +55,7 @@ namespace Orchard.Tests.UI.Navigation { [Test] public void NavigationManagerShouldMergeAndOrderNavigation() { - var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new IMenuProvider[] { }, new StubAuth(), new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); + var manager = new NavigationManager(new INavigationProvider[] { new StubProvider(), new Stub2Provider() }, new IMenuProvider[] { }, new StubAuth(), new INavigationFilter[0], new UrlHelper(new RequestContext(new StubHttpContext("~/"), new RouteData())), new StubOrchardServices()); var menuItems = manager.BuildMenu("admin"); Assert.That(menuItems.Count(), Is.EqualTo(3)); diff --git a/src/Orchard/Orchard.Framework.csproj b/src/Orchard/Orchard.Framework.csproj index 67b0f686a..69802b2a2 100644 --- a/src/Orchard/Orchard.Framework.csproj +++ b/src/Orchard/Orchard.Framework.csproj @@ -268,6 +268,7 @@ + diff --git a/src/Orchard/UI/Navigation/INavigationFilter.cs b/src/Orchard/UI/Navigation/INavigationFilter.cs new file mode 100644 index 000000000..aa7b5d160 --- /dev/null +++ b/src/Orchard/UI/Navigation/INavigationFilter.cs @@ -0,0 +1,7 @@ +using System.Collections.Generic; + +namespace Orchard.UI.Navigation { + public interface INavigationFilter : IDependency { + IEnumerable Filter(IEnumerable menuItems); + } +} diff --git a/src/Orchard/UI/Navigation/MenuItem.cs b/src/Orchard/UI/Navigation/MenuItem.cs index a5beb6abf..2bee57b13 100644 --- a/src/Orchard/UI/Navigation/MenuItem.cs +++ b/src/Orchard/UI/Navigation/MenuItem.cs @@ -34,7 +34,5 @@ namespace Orchard.UI.Navigation { _classes = value; } } - - public int MenuId { get; set; } } } \ No newline at end of file diff --git a/src/Orchard/UI/Navigation/NavigationBuilder.cs b/src/Orchard/UI/Navigation/NavigationBuilder.cs index c8652c51a..76d526807 100644 --- a/src/Orchard/UI/Navigation/NavigationBuilder.cs +++ b/src/Orchard/UI/Navigation/NavigationBuilder.cs @@ -41,6 +41,11 @@ namespace Orchard.UI.Navigation { return Add(caption, null, x => { }, classes); } + public NavigationBuilder Remove(MenuItem item) { + Contained.Remove(item); + return this; + } + public NavigationBuilder AddImageSet(string imageSet) { _imageSets.Add(imageSet); return this; @@ -49,6 +54,7 @@ namespace Orchard.UI.Navigation { public IEnumerable Build() { return (Contained ?? Enumerable.Empty()).ToList(); } + public IEnumerable BuildImageSets() { return _imageSets.Distinct(); } diff --git a/src/Orchard/UI/Navigation/NavigationItemBuilder.cs b/src/Orchard/UI/Navigation/NavigationItemBuilder.cs index 74fac048e..8aae06e12 100644 --- a/src/Orchard/UI/Navigation/NavigationItemBuilder.cs +++ b/src/Orchard/UI/Navigation/NavigationItemBuilder.cs @@ -23,11 +23,6 @@ namespace Orchard.UI.Navigation { return this; } - public NavigationItemBuilder MenuId(int menuId) { - _item.MenuId = menuId; - return this; - } - public NavigationItemBuilder Url(string url) { _item.Url = url; return this; diff --git a/src/Orchard/UI/Navigation/NavigationManager.cs b/src/Orchard/UI/Navigation/NavigationManager.cs index 3cf832053..97415266f 100644 --- a/src/Orchard/UI/Navigation/NavigationManager.cs +++ b/src/Orchard/UI/Navigation/NavigationManager.cs @@ -7,24 +7,28 @@ using Orchard.ContentManagement; using Orchard.Logging; using Orchard.Security; using Orchard.Security.Permissions; +using Orchard.UI.Admin; namespace Orchard.UI.Navigation { public class NavigationManager : INavigationManager { private readonly IEnumerable _navigationProviders; private readonly IEnumerable _menuProviders; private readonly IAuthorizationService _authorizationService; + private readonly IEnumerable _navigationFilters; private readonly UrlHelper _urlHelper; private readonly IOrchardServices _orchardServices; public NavigationManager( IEnumerable navigationProviders, IEnumerable menuProviders, - IAuthorizationService authorizationService, + IAuthorizationService authorizationService, + IEnumerable navigationFilters, UrlHelper urlHelper, IOrchardServices orchardServices) { _navigationProviders = navigationProviders; _menuProviders = menuProviders; _authorizationService = authorizationService; + _navigationFilters = navigationFilters; _urlHelper = urlHelper; _orchardServices = orchardServices; Logger = NullLogger.Instance; @@ -39,7 +43,7 @@ namespace Orchard.UI.Navigation { public IEnumerable BuildMenu(IContent menu) { var sources = GetSources(menu); - return FinishMenu(Reduce(Arrange(Merge(sources))).ToArray()); + return FinishMenu(Reduce(Arrange(Filter(Merge(sources)))).ToArray()); } public IEnumerable BuildImageSets(string menuName) { @@ -55,6 +59,15 @@ namespace Orchard.UI.Navigation { return menuItems; } + private IEnumerable Filter(IEnumerable menuItems) { + IEnumerable result = menuItems; + foreach(var filter in _navigationFilters) { + result = filter.Filter(result); + } + + return result; + } + public string GetUrl(string menuItemUrl, RouteValueDictionary routeValueDictionary) { var url = string.IsNullOrEmpty(menuItemUrl) && (routeValueDictionary == null || routeValueDictionary.Count == 0) ? "~/" @@ -82,8 +95,8 @@ namespace Orchard.UI.Navigation { var hasDebugShowAllMenuItems = _authorizationService.TryCheckAccess(Permission.Named("DebugShowAllMenuItems"), _orchardServices.WorkContext.CurrentUser, null); foreach (var item in items) { if (hasDebugShowAllMenuItems || - !item.Permissions.Any() || - item.Permissions.Any(x => _authorizationService.TryCheckAccess(x, _orchardServices.WorkContext.CurrentUser, null))) { + AdminFilter.IsApplied(_urlHelper.RequestContext) || + item.Permissions.Concat(new [] { Permission.Named("ViewContent") }).Any(x => _authorizationService.TryCheckAccess(x, _orchardServices.WorkContext.CurrentUser, item.Content))) { yield return new MenuItem { Items = Reduce(item.Items), Permissions = item.Permissions, @@ -96,7 +109,6 @@ namespace Orchard.UI.Navigation { Url = item.Url, LinkToFirstChild = item.LinkToFirstChild, Href = item.Href, - MenuId = item.MenuId, Content = item.Content }; } @@ -225,9 +237,9 @@ namespace Orchard.UI.Navigation { Items = Merge(items.Select(x => x.Items)).ToArray(), Position = SelectBestPositionValue(items.Select(x => x.Position)), Permissions = items.SelectMany(x => x.Permissions).Distinct(), - MenuId = items.First().MenuId, Content = items.First().Content }; + return joined; }