From e34c857f6c7902dac45f14856f8fc445db38b438 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Thu, 4 Jul 2013 11:22:59 +0200 Subject: [PATCH] A bit of refactoring around unique naming, and implementing it for media as well --- .../Repositories/ContentRepository.cs | 40 ----------------- .../Repositories/MediaRepository.cs | 44 ++++++++++++++++++ .../Repositories/SimilarNodeNameComparer.cs | 45 +++++++++++++++++++ .../Persistence/RepositoryFactory.cs | 2 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + 5 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/Repositories/SimilarNodeNameComparer.cs diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 49e7f1df48..58b07e1583 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -533,45 +533,5 @@ namespace Umbraco.Core.Persistence.Repositories return currentName; } - - /// - /// Comparer that takes into account the duplicate index of a node name - /// This is needed as a normal alphabetic sort would go Page (1), Page (10), Page (2) etc. - /// - private class SimilarNodeNameComparer : IComparer - { - public int Compare(string x, string y) - { - if (x.LastIndexOf(')') == x.Length - 1 && y.LastIndexOf(')') == y.Length - 1) - { - if (x.ToLower().Substring(0, x.LastIndexOf('(')) == y.ToLower().Substring(0, y.LastIndexOf('('))) - { - int xDuplicateIndex = ExtractDuplicateIndex(x); - int yDuplicateIndex = ExtractDuplicateIndex(y); - - if (xDuplicateIndex != 0 && yDuplicateIndex != 0) - { - return xDuplicateIndex.CompareTo(yDuplicateIndex); - } - } - } - return String.Compare(x.ToLower(), y.ToLower(), StringComparison.Ordinal); - } - - private int ExtractDuplicateIndex(string text) - { - int index = 0; - - if (text.LastIndexOf('(') != -1 && text.LastIndexOf('(') < text.Length - 2) - { - int startPos = text.LastIndexOf('(') + 1; - int length = text.Length - 1 - startPos; - - int.TryParse(text.Substring(startPos, length), out index); - } - - return index; - } - } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 81ec056f0a..94b8a21859 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -25,14 +25,20 @@ namespace Umbraco.Core.Persistence.Repositories : base(work) { _mediaTypeRepository = mediaTypeRepository; + + EnsureUniqueNaming = true; } public MediaRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMediaTypeRepository mediaTypeRepository) : base(work, cache) { _mediaTypeRepository = mediaTypeRepository; + + EnsureUniqueNaming = true; } + public bool EnsureUniqueNaming { get; set; } + #region Overrides of RepositoryBase protected override IMedia PerformGet(int id) @@ -182,6 +188,9 @@ namespace Umbraco.Core.Persistence.Repositories { ((Models.Media)entity).AddingEntity(); + //Ensure unique name on the same level + entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name); + var factory = new MediaFactory(NodeObjectTypeId, entity.Id); var dto = factory.BuildDto(entity); @@ -246,6 +255,9 @@ namespace Umbraco.Core.Persistence.Repositories //Updates Modified date ((Models.Media)entity).UpdatingEntity(); + //Ensure unique name on the same level + entity.Name = EnsureUniqueNodeName(entity.ParentId, entity.Name); + //Look up parent to get and set the correct Path and update SortOrder if ParentId has changed if (((ICanBeDirty)entity).IsPropertyDirty("ParentId")) { @@ -370,5 +382,37 @@ namespace Umbraco.Core.Persistence.Repositories return new PropertyCollection(properties); } + + private string EnsureUniqueNodeName(int parentId, string nodeName, int id = 0) + { + if (EnsureUniqueNaming == false) + return nodeName; + + var sql = new Sql(); + sql.Select("*") + .From() + .Where(x => x.NodeObjectType == NodeObjectTypeId && x.ParentId == parentId && x.Text.StartsWith(nodeName)); + + int uniqueNumber = 1; + var currentName = nodeName; + + var dtos = Database.Fetch(sql); + if (dtos.Any()) + { + var results = dtos.OrderBy(x => x.Text, new SimilarNodeNameComparer()); + foreach (var dto in results) + { + if (id != 0 && id == dto.NodeId) continue; + + if (dto.Text.ToLowerInvariant().Equals(currentName.ToLowerInvariant())) + { + currentName = nodeName + string.Format(" ({0})", uniqueNumber); + uniqueNumber++; + } + } + } + + return currentName; + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/SimilarNodeNameComparer.cs b/src/Umbraco.Core/Persistence/Repositories/SimilarNodeNameComparer.cs new file mode 100644 index 0000000000..734eecf1f9 --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/SimilarNodeNameComparer.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; + +namespace Umbraco.Core.Persistence.Repositories +{ + /// + /// Comparer that takes into account the duplicate index of a node name + /// This is needed as a normal alphabetic sort would go Page (1), Page (10), Page (2) etc. + /// + internal class SimilarNodeNameComparer : IComparer + { + public int Compare(string x, string y) + { + if (x.LastIndexOf(')') == x.Length - 1 && y.LastIndexOf(')') == y.Length - 1) + { + if (x.ToLower().Substring(0, x.LastIndexOf('(')) == y.ToLower().Substring(0, y.LastIndexOf('('))) + { + int xDuplicateIndex = ExtractDuplicateIndex(x); + int yDuplicateIndex = ExtractDuplicateIndex(y); + + if (xDuplicateIndex != 0 && yDuplicateIndex != 0) + { + return xDuplicateIndex.CompareTo(yDuplicateIndex); + } + } + } + return String.Compare(x.ToLower(), y.ToLower(), StringComparison.Ordinal); + } + + private int ExtractDuplicateIndex(string text) + { + int index = 0; + + if (text.LastIndexOf('(') != -1 && text.LastIndexOf('(') < text.Length - 2) + { + int startPos = text.LastIndexOf('(') + 1; + int length = text.Length - 1 - startPos; + + int.TryParse(text.Substring(startPos, length), out index); + } + + return index; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index 38189576a7..73c7b290f9 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -81,7 +81,7 @@ namespace Umbraco.Core.Persistence return new MediaRepository( uow, RuntimeCacheProvider.Current, - CreateMediaTypeRepository(uow)); + CreateMediaTypeRepository(uow)) { EnsureUniqueNaming = Umbraco.Core.Configuration.UmbracoSettings.EnsureUniqueNaming }; } public virtual IMediaTypeRepository CreateMediaTypeRepository(IDatabaseUnitOfWork uow) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 97c29aac50..9c97c3d453 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -497,6 +497,7 @@ +