From 93abfc0acac6bdca195e41a3456feed7ef32965d Mon Sep 17 00:00:00 2001 From: Katsuyuki Ohmuro Date: Thu, 5 Mar 2015 22:55:23 +0100 Subject: [PATCH 1/4] #21218: Fixing IFilterProvider execution order Work Item: 21218 --- src/Orchard/Mvc/Filters/OrchardFilterProvider.cs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Orchard/Mvc/Filters/OrchardFilterProvider.cs b/src/Orchard/Mvc/Filters/OrchardFilterProvider.cs index cd60fd6b3..ef095b1ed 100644 --- a/src/Orchard/Mvc/Filters/OrchardFilterProvider.cs +++ b/src/Orchard/Mvc/Filters/OrchardFilterProvider.cs @@ -7,8 +7,16 @@ namespace Orchard.Mvc.Filters { public IEnumerable GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { var workContext = controllerContext.GetWorkContext(); - var filterProviders = workContext.Resolve>(); - return filterProviders.Select(x => new Filter(x, FilterScope.Action, null)); + + // Map IFilterProvider implementations to MVC Filter objects + // Need to provide order values since Filter objects of identical + // scope and order would run in undefined order. + // We create negative order values to avoid conflicts with other + // potential user-provided MVC Filter objects, which hopefully use + // positive order values. We do this by reversing the list and + // negating the index. + var filters = workContext.Resolve>(); + return filters.Reverse().Select((filter, index) => new Filter(filter, FilterScope.Action, -(index + 1))); } } } \ No newline at end of file From 363ae13ef758c9c72f7ec340f73a5bb23c5c25c2 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 25 Apr 2015 10:13:04 +0200 Subject: [PATCH 2/4] #5137: Fixed homepage being lost when content with empty alias is removed. --- .../Implementation/Storage/AliasStorage.cs | 37 ++++++------------- .../Services/AutorouteService.cs | 33 ++++++++++++++++- 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.Alias/Implementation/Storage/AliasStorage.cs b/src/Orchard.Web/Modules/Orchard.Alias/Implementation/Storage/AliasStorage.cs index 61711eda0..09a1e2e0a 100644 --- a/src/Orchard.Web/Modules/Orchard.Alias/Implementation/Storage/AliasStorage.cs +++ b/src/Orchard.Web/Modules/Orchard.Alias/Implementation/Storage/AliasStorage.cs @@ -6,11 +6,13 @@ using System.Xml.Linq; using Orchard.Alias.Records; using Orchard.Data; using Orchard.Alias.Implementation.Holder; +using Orchard.Validation; namespace Orchard.Alias.Implementation.Storage { public interface IAliasStorage : IDependency { void Set(string path, IDictionary routeValues, string source); IDictionary Get(string aliasPath); + void Remove(Expression> filter); void Remove(string path); void Remove(string path, string aliasSource); void RemoveBySource(string aliasSource); @@ -88,36 +90,21 @@ namespace Orchard.Alias.Implementation.Storage { } public void Remove(string path) { - - if (path == null) { - throw new ArgumentNullException("path"); - } - - foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Path == path)) { - _aliasRepository.Delete(aliasRecord); - // Bulk updates might go wrong if we don't flush - _aliasRepository.Flush(); - var dict = ToDictionary(aliasRecord); - _aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 }); - } + Remove(x => x.Path == path && x.Source == path); } + public void Remove(string path, string aliasSource) { - - if (path == null) { - throw new ArgumentNullException("path"); - } - - foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Path == path && r.Source == aliasSource)) { - _aliasRepository.Delete(aliasRecord); - // Bulk updates might go wrong if we don't flush - _aliasRepository.Flush(); - var dict = ToDictionary(aliasRecord); - _aliasHolder.RemoveAlias(new AliasInfo() { Path = dict.Item1, Area = dict.Item2, RouteValues = dict.Item3 }); - } + Remove(x => x.Path == path && x.Source == aliasSource); } public void RemoveBySource(string aliasSource) { - foreach (var aliasRecord in _aliasRepository.Fetch(r => r.Source == aliasSource)) { + Remove(x => x.Source == aliasSource); + } + + public void Remove(Expression> filter) { + Argument.ThrowIfNull(filter, "filter"); + + foreach (var aliasRecord in _aliasRepository.Fetch(filter)) { _aliasRepository.Delete(aliasRecord); // Bulk updates might go wrong if we don't flush _aliasRepository.Flush(); diff --git a/src/Orchard.Web/Modules/Orchard.Autoroute/Services/AutorouteService.cs b/src/Orchard.Web/Modules/Orchard.Autoroute/Services/AutorouteService.cs index 78a6426b7..57ce977f4 100644 --- a/src/Orchard.Web/Modules/Orchard.Autoroute/Services/AutorouteService.cs +++ b/src/Orchard.Web/Modules/Orchard.Autoroute/Services/AutorouteService.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Orchard.Alias; +using Orchard.Alias.Implementation.Storage; using Orchard.Autoroute.Models; using Orchard.Autoroute.Settings; using Orchard.ContentManagement; @@ -20,6 +21,7 @@ namespace Orchard.Autoroute.Services { private readonly IContentDefinitionManager _contentDefinitionManager; private readonly IContentManager _contentManager; private readonly IRouteEvents _routeEvents; + private readonly IAliasStorage _aliasStorage; private const string AliasSource = "Autoroute:View"; public AutorouteService( @@ -27,12 +29,14 @@ namespace Orchard.Autoroute.Services { ITokenizer tokenizer, IContentDefinitionManager contentDefinitionManager, IContentManager contentManager, - IRouteEvents routeEvents) { + IRouteEvents routeEvents, + IAliasStorage aliasStorage) { _aliasService = aliasService; _tokenizer = tokenizer; _contentDefinitionManager = contentDefinitionManager; _contentManager = contentManager; _routeEvents = routeEvents; + _aliasStorage = aliasStorage; Logger = NullLogger.Instance; T = NullLocalizer.Instance; @@ -122,6 +126,23 @@ namespace Orchard.Autoroute.Services { } public void RemoveAliases(AutoroutePart part) { + // https://github.com/OrchardCMS/Orchard/issues/5137 + // If the alias of the specified part is empty while not being the homepage, + // we need to make sure we are not removing all empty aliases in order to prevent losing the homepage content item being the homepage. + if (String.IsNullOrWhiteSpace(part.Path)) { + if (!IsHomePage(part)) { + // The item being removed is NOT the homepage, so we need to make sure we're not removing the alias for the homepage. + var aliasRecordId = GetHomePageAliasRecordId(); + + // Remove all aliases EXCEPT for the alias of the homepage. + _aliasStorage.Remove(x => x.Path == part.Path && x.Source == AliasSource && x.Id != aliasRecordId); + + // Done. + return; + } + } + + // Safe to delete all aliases for the specified part since it is definitely not the homepage. _aliasService.Delete(part.Path, AliasSource); } @@ -188,5 +209,15 @@ namespace Orchard.Autoroute.Services { return true; } + + private bool IsHomePage(IContent content) { + var homePageRoute = _aliasService.Get(""); + var homePageId = homePageRoute.ContainsKey("id") ? XmlHelper.Parse((string)homePageRoute["id"]) : default(int?); + return content.Id == homePageId; + } + + private int GetHomePageAliasRecordId() { + return _aliasStorage.List(x => x.Path == "").First().Item5; + } } } From ae17c75a5ee7a7c51be4b8f2799cd068f032e67c Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 27 Apr 2015 08:36:38 +0200 Subject: [PATCH 3/4] Fixed controller for SELECT input controls. When using a SELECT input control, that control itself would be initialized with the call to "toggleWhatYouControl" instead of its child OPTION elements. --- src/Orchard.Web/Core/Shapes/Scripts/base.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Orchard.Web/Core/Shapes/Scripts/base.js b/src/Orchard.Web/Core/Shapes/Scripts/base.js index d5c1a511b..6bdf75bbf 100644 --- a/src/Orchard.Web/Core/Shapes/Scripts/base.js +++ b/src/Orchard.Web/Core/Shapes/Scripts/base.js @@ -178,9 +178,10 @@ $("[name=" + controller.attr("name") + "]").click(function () { $("[name=" + $(this).attr("name") + "]").each($(this).toggleWhatYouControl); }); } else if (controller.is("option")) { - controller.parent().change(function () { + controller.parent().change(function() { controller.toggleWhatYouControl(); - }).each($(this).toggleWhatYouControl); + }); + controller.each($(this).toggleWhatYouControl); } }); }); From a88d68ee7a5cf11d10740f3afbf59adad6c0d23d Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 27 Apr 2015 14:05:50 +0200 Subject: [PATCH 4/4] Added missing *Types* property to ContentPicker shape. This fixes an issue where you could not configure the content picker shape to filter the available content items by types or types with certain parts. --- .../Orchard.ContentPicker/Scripts/ContentPicker.js | 4 +++- .../Views/ContentPicker.Edit.cshtml | 12 +++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Scripts/ContentPicker.js b/src/Orchard.Web/Modules/Orchard.ContentPicker/Scripts/ContentPicker.js index 8c906365e..c60c6f6c3 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentPicker/Scripts/ContentPicker.js +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Scripts/ContentPicker.js @@ -54,6 +54,7 @@ var baseUrl = $(self).data("base-url"); var partName = $(self).data("part-name"); var fieldName = $(self).data("field-name"); + var types = $(self).data("types"); var refreshIds = function() { var id = $("[name='" + selectedItemsFieldname + "']"); @@ -90,7 +91,8 @@ }, baseUrl: baseUrl, part: partName, - field: fieldName + field: fieldName, + types: types }); }); diff --git a/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/ContentPicker.Edit.cshtml b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/ContentPicker.Edit.cshtml index 2e4ff3ac9..704be8779 100644 --- a/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/ContentPicker.Edit.cshtml +++ b/src/Orchard.Web/Modules/Orchard.ContentPicker/Views/ContentPicker.Edit.cshtml @@ -15,6 +15,7 @@ var partName = Model.PartName; var fieldName = Model.FieldName; var baseUrl = Url.Content("~/") + WorkContext.Resolve().RequestUrlPrefix; + var types = String.Join(",", (IEnumerable)Model.Types ?? Enumerable.Empty()); }
+ data-not-published-text="@T("Not Published")" + data-types="@types"> @if (!String.IsNullOrWhiteSpace(displayName)) { - + }
@T("You need to save your changes.")
@@ -38,7 +40,7 @@ - + @@ -48,7 +50,7 @@
 ↓ ↓ @T("Content Item")  
  - @Html.ItemEditLink(contentItem) @if(!contentItem.HasPublished()) { - @T("Not Published")} + @Html.ItemEditLink(contentItem) @if (!contentItem.HasPublished()){ - @T("Not Published")} @T("Remove") @@ -59,6 +61,6 @@
@T("Add") - + @hint
\ No newline at end of file