From b2b2e1cf374e1cb204a751464ffb03b3efaf08a9 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Sat, 25 Apr 2015 10:13:04 +0200 Subject: [PATCH] #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; + } } }