V10: Fix build warnings in core (#12438)

* Run code cleanup

* Start manual cleanup after dotnet format

* Finish up manual pass

* Fix up missed warnings

* Fix after merge

* Update src/Umbraco.Core/Cache/ContentTypeCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/DataTypeCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/DeepCloneAppCache.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/DomainCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/FastDictionaryAppCacheBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/MacroCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/MediaCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/MemberCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Cache/MemberGroupCacheRefresher.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Composing/OrderedCollectionBuilderBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Configuration/Models/RequestHandlerSettings.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Composing/SetCollectionBuilderBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Composing/WeightedCollectionBuilderBase.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/ContentApps/ContentAppFactoryCollectionBuilder.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Dashboards/DashboardCollectionBuilder.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/ContentTypeRefreshedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/ContentTypeSavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/ContentTypeSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DictionaryCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DataTypeCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/ContentUnpublishingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DictionaryItemDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DictionaryItemSavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DictionaryItemSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/DomainCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/LanguageCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MacroCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaEmptiedRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaEmptyingRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaMovedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaMovingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaMovingToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTreeChangeNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTreeChangeNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeChangedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeMovedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeMovingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeMovingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MediaTypeRefreshedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberGroupCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberGroupDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberGroupSavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberGroupSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeChangedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeDeletedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeMovedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeMovedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeMovingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeMovingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeRefreshedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MemberTypeSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/StringExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/UriExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PartialViewDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Extensions/UriExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/IO/PhysicalFileSystem.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/IO/PhysicalFileSystem.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/IO/ShadowWrapper.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Logging/DisposableTimer.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Install/InstallSteps/UpgradeStep.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Mapping/MapDefinitionCollectionBuilder.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Media/EmbedProviders/EmbedProvidersCollectionBuilder.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PartialViewSavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Models/ContentEditing/ContentVariationDisplay.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PartialViewSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntryDeletedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntryDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntryDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntrySavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntrySavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/PublicAccessEntrySavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/RelationTypeCacheRefresherNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/RelationTypeDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/RelationTypeSavedNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/RelationTypeSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/StatefulNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/StylesheetDeletingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Notifications/StylesheetSavingNotification.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Models/DeepCloneHelper.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Models/File.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Models/PropertyGroupExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Update src/Umbraco.Core/Models/PropertyGroupExtensions.cs

Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>

* Fix based on review

* Fix after merge

Signed-off-by: Zeegaan <nge@umbraco.dk>

Co-authored-by: Nikolaj Geisle <niko737@edu.ucl.dk>
Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
Co-authored-by: Zeegaan <nge@umbraco.dk>
This commit is contained in:
Nikolaj Geisle
2022-06-07 15:28:38 +02:00
committed by GitHub
parent 86e16302bf
commit 60a5b19dc9
1931 changed files with 116387 additions and 111403 deletions

View File

@@ -1,227 +1,249 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Configuration.UmbracoSettings;
using Umbraco.Extensions;
namespace Umbraco.Cms.Core.Strings
{
public class DefaultShortStringHelperConfig
{
private readonly Dictionary<string, Dictionary<CleanStringType, Config>> _configs = new Dictionary<string, Dictionary<CleanStringType, Config>>();
namespace Umbraco.Cms.Core.Strings;
public DefaultShortStringHelperConfig Clone()
public class DefaultShortStringHelperConfig
{
private readonly Dictionary<string, Dictionary<CleanStringType, Config>> _configs = new();
public string DefaultCulture { get; set; } = string.Empty; // invariant
public Dictionary<string, string>? UrlReplaceCharacters { get; set; }
public DefaultShortStringHelperConfig Clone()
{
var config = new DefaultShortStringHelperConfig
{
var config = new DefaultShortStringHelperConfig
DefaultCulture = DefaultCulture,
UrlReplaceCharacters = UrlReplaceCharacters,
};
foreach (KeyValuePair<string, Dictionary<CleanStringType, Config>> kvp1 in _configs)
{
Dictionary<CleanStringType, Config> c = config._configs[kvp1.Key] =
new Dictionary<CleanStringType, Config>();
foreach (KeyValuePair<CleanStringType, Config> kvp2 in _configs[kvp1.Key])
{
DefaultCulture = DefaultCulture,
UrlReplaceCharacters = UrlReplaceCharacters
c[kvp2.Key] = kvp2.Value.Clone();
}
}
return config;
}
public DefaultShortStringHelperConfig WithConfig(Config config) =>
WithConfig(DefaultCulture, CleanStringType.RoleMask, config);
public DefaultShortStringHelperConfig WithConfig(CleanStringType stringRole, Config config) =>
WithConfig(DefaultCulture, stringRole, config);
public DefaultShortStringHelperConfig WithConfig(string? culture, CleanStringType stringRole, Config config)
{
if (config == null)
{
throw new ArgumentNullException(nameof(config));
}
culture = culture ?? string.Empty;
if (_configs.ContainsKey(culture) == false)
{
_configs[culture] = new Dictionary<CleanStringType, Config>();
}
_configs[culture][stringRole] = config;
return this;
}
/// <summary>
/// Sets the default configuration.
/// </summary>
/// <returns>The short string helper.</returns>
public DefaultShortStringHelperConfig WithDefault(RequestHandlerSettings requestHandlerSettings)
{
IEnumerable<IChar> charCollection = requestHandlerSettings.GetCharReplacements();
UrlReplaceCharacters = charCollection
.Where(x => string.IsNullOrEmpty(x.Char) == false)
.ToDictionary(x => x.Char, x => x.Replacement);
CleanStringType urlSegmentConvertTo = CleanStringType.Utf8;
if (requestHandlerSettings.ShouldConvertUrlsToAscii)
{
urlSegmentConvertTo = CleanStringType.Ascii;
}
if (requestHandlerSettings.ShouldTryConvertUrlsToAscii)
{
urlSegmentConvertTo = CleanStringType.TryAscii;
}
return WithConfig(CleanStringType.UrlSegment, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
PostFilter = x => CutMaxLength(x, 240),
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = urlSegmentConvertTo | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
Separator = '-',
}).WithConfig(CleanStringType.FileName, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Utf8 | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
Separator = '-',
}).WithConfig(CleanStringType.Alias, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => leading
? char.IsLetter(c) // only letters
: char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
BreakTermsOnUpper = false,
}).WithConfig(CleanStringType.UnderscoreAlias, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
BreakTermsOnUpper = false,
}).WithConfig(CleanStringType.ConvertCase, new Config
{
PreFilter = null,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Ascii,
BreakTermsOnUpper = true,
});
}
// internal: we don't want ppl to retrieve a config and modify it
// (the helper uses a private clone to prevent modifications)
internal Config For(CleanStringType stringType, string? culture)
{
culture = culture ?? string.Empty;
stringType = stringType & CleanStringType.RoleMask;
Dictionary<CleanStringType, Config> config;
if (_configs.ContainsKey(culture))
{
config = _configs[culture];
// have we got a config for _that_ role?
if (config.ContainsKey(stringType))
{
return config[stringType];
}
// have we got a generic config for _all_ roles?
if (config.ContainsKey(CleanStringType.RoleMask))
{
return config[CleanStringType.RoleMask];
}
}
else if (_configs.ContainsKey(DefaultCulture))
{
config = _configs[DefaultCulture];
// have we got a config for _that_ role?
if (config.ContainsKey(stringType))
{
return config[stringType];
}
// have we got a generic config for _all_ roles?
if (config.ContainsKey(CleanStringType.RoleMask))
{
return config[CleanStringType.RoleMask];
}
}
return Config.NotConfigured;
}
/// <summary>
/// Returns a new string in which characters have been replaced according to the Umbraco settings UrlReplaceCharacters.
/// </summary>
/// <param name="s">The string to filter.</param>
/// <returns>The filtered string.</returns>
public string ApplyUrlReplaceCharacters(string s) =>
UrlReplaceCharacters == null ? s : s.ReplaceMany(UrlReplaceCharacters);
public static string CutMaxLength(string text, int length) =>
text.Length <= length ? text : text.Substring(0, length);
public sealed class Config
{
internal static readonly Config NotConfigured = new();
public Config()
{
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
PreFilter = null;
PostFilter = null;
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
BreakTermsOnUpper = false;
CutAcronymOnNonUpper = false;
GreedyAcronyms = false;
Separator = char.MinValue;
}
public Func<string, string>? PreFilter { get; set; }
public Func<string, string>? PostFilter { get; set; }
public Func<char, bool, bool> IsTerm { get; set; }
public CleanStringType StringType { get; set; }
// indicate whether an uppercase within a term eg "fooBar" is to break
// into a new term, or to be considered as part of the current term
public bool BreakTermsOnUpper { get; set; }
// indicate whether a non-uppercase within an acronym eg "FOOBar" is to cut
// the acronym (at "B" or "a" depending on GreedyAcronyms) or to give
// up the acronym and treat the term as a word
public bool CutAcronymOnNonUpper { get; set; }
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
public bool GreedyAcronyms { get; set; }
// the separator char
// but then how can we tell we don't want any?
public char Separator { get; set; }
public Config Clone() =>
new Config
{
PreFilter = PreFilter,
PostFilter = PostFilter,
IsTerm = IsTerm,
StringType = StringType,
BreakTermsOnUpper = BreakTermsOnUpper,
CutAcronymOnNonUpper = CutAcronymOnNonUpper,
GreedyAcronyms = GreedyAcronyms,
Separator = Separator,
};
foreach (var kvp1 in _configs)
{
var c = config._configs[kvp1.Key] = new Dictionary<CleanStringType, Config>();
foreach (var kvp2 in _configs[kvp1.Key])
c[kvp2.Key] = kvp2.Value.Clone();
}
return config;
}
public string DefaultCulture { get; set; } = ""; // invariant
public Dictionary<string, string>? UrlReplaceCharacters { get; set; }
public DefaultShortStringHelperConfig WithConfig(Config config)
// extends the config
public CleanStringType StringTypeExtend(CleanStringType stringType)
{
return WithConfig(DefaultCulture, CleanStringType.RoleMask, config);
}
public DefaultShortStringHelperConfig WithConfig(CleanStringType stringRole, Config config)
{
return WithConfig(DefaultCulture, stringRole, config);
}
public DefaultShortStringHelperConfig WithConfig(string culture, CleanStringType stringRole, Config config)
{
if (config == null) throw new ArgumentNullException(nameof(config));
culture = culture ?? "";
if (_configs.ContainsKey(culture) == false)
_configs[culture] = new Dictionary<CleanStringType, Config>();
_configs[culture][stringRole] = config;
return this;
}
/// <summary>
/// Sets the default configuration.
/// </summary>
/// <returns>The short string helper.</returns>
public DefaultShortStringHelperConfig WithDefault(RequestHandlerSettings requestHandlerSettings)
{
IEnumerable<IChar> charCollection = requestHandlerSettings.GetCharReplacements();
UrlReplaceCharacters = charCollection
.Where(x => string.IsNullOrEmpty(x.Char) == false)
.ToDictionary(x => x.Char, x => x.Replacement);
var urlSegmentConvertTo = CleanStringType.Utf8;
if (requestHandlerSettings.ShouldConvertUrlsToAscii)
urlSegmentConvertTo = CleanStringType.Ascii;
if (requestHandlerSettings.ShouldTryConvertUrlsToAscii)
urlSegmentConvertTo = CleanStringType.TryAscii;
return WithConfig(CleanStringType.UrlSegment, new Config
CleanStringType st = StringType;
foreach (CleanStringType mask in new[] { CleanStringType.CaseMask, CleanStringType.CodeMask })
{
PreFilter = ApplyUrlReplaceCharacters,
PostFilter = x => CutMaxLength(x, 240),
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = urlSegmentConvertTo | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
Separator = '-'
}).WithConfig(CleanStringType.FileName, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Utf8 | CleanStringType.LowerCase,
BreakTermsOnUpper = false,
Separator = '-'
}).WithConfig(CleanStringType.Alias, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => leading
? char.IsLetter(c) // only letters
: (char.IsLetterOrDigit(c) || c == '_'), // letter, digit or underscore
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
BreakTermsOnUpper = false
}).WithConfig(CleanStringType.UnderscoreAlias, new Config
{
PreFilter = ApplyUrlReplaceCharacters,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Ascii | CleanStringType.UmbracoCase,
BreakTermsOnUpper = false
}).WithConfig(CleanStringType.ConvertCase, new Config
{
PreFilter = null,
IsTerm = (c, leading) => char.IsLetterOrDigit(c) || c == '_', // letter, digit or underscore
StringType = CleanStringType.Ascii,
BreakTermsOnUpper = true
});
}
// internal: we don't want ppl to retrieve a config and modify it
// (the helper uses a private clone to prevent modifications)
internal Config For(CleanStringType stringType, string culture)
{
culture = culture ?? "";
stringType = stringType & CleanStringType.RoleMask;
Dictionary<CleanStringType, Config> config;
if (_configs.ContainsKey(culture))
{
config = _configs[culture];
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
return config[stringType];
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
return config[CleanStringType.RoleMask];
}
else if (_configs.ContainsKey(DefaultCulture))
{
config = _configs[DefaultCulture];
if (config.ContainsKey(stringType)) // have we got a config for _that_ role?
return config[stringType];
if (config.ContainsKey(CleanStringType.RoleMask)) // have we got a generic config for _all_ roles?
return config[CleanStringType.RoleMask];
}
return Config.NotConfigured;
}
public sealed class Config
{
public Config()
{
StringType = CleanStringType.Utf8 | CleanStringType.Unchanged;
PreFilter = null;
PostFilter = null;
IsTerm = (c, leading) => leading ? char.IsLetter(c) : char.IsLetterOrDigit(c);
BreakTermsOnUpper = false;
CutAcronymOnNonUpper = false;
GreedyAcronyms = false;
Separator = char.MinValue;
}
public Config Clone()
{
return new Config
CleanStringType a = stringType & mask;
if (a == 0)
{
PreFilter = PreFilter,
PostFilter = PostFilter,
IsTerm = IsTerm,
StringType = StringType,
BreakTermsOnUpper = BreakTermsOnUpper,
CutAcronymOnNonUpper = CutAcronymOnNonUpper,
GreedyAcronyms = GreedyAcronyms,
Separator = Separator
};
}
public Func<string, string>? PreFilter { get; set; }
public Func<string, string>? PostFilter { get; set; }
public Func<char, bool, bool> IsTerm { get; set; }
public CleanStringType StringType { get; set; }
// indicate whether an uppercase within a term eg "fooBar" is to break
// into a new term, or to be considered as part of the current term
public bool BreakTermsOnUpper { get; set; }
// indicate whether a non-uppercase within an acronym eg "FOOBar" is to cut
// the acronym (at "B" or "a" depending on GreedyAcronyms) or to give
// up the acronym and treat the term as a word
public bool CutAcronymOnNonUpper { get; set; }
// indicates whether acronyms parsing is greedy ie whether "FOObar" is
// "FOO" + "bar" (greedy) or "FO" + "Obar" (non-greedy)
public bool GreedyAcronyms { get; set; }
// the separator char
// but then how can we tell we don't want any?
public char Separator { get; set; }
// extends the config
public CleanStringType StringTypeExtend(CleanStringType stringType)
{
var st = StringType;
foreach (var mask in new[] { CleanStringType.CaseMask, CleanStringType.CodeMask })
{
var a = stringType & mask;
if (a == 0) continue;
st = st & ~mask; // clear what we have
st = st | a; // set the new value
continue;
}
return st;
st = st & ~mask; // clear what we have
st = st | a; // set the new value
}
internal static readonly Config NotConfigured = new Config();
}
/// <summary>
/// Returns a new string in which characters have been replaced according to the Umbraco settings UrlReplaceCharacters.
/// </summary>
/// <param name="s">The string to filter.</param>
/// <returns>The filtered string.</returns>
public string ApplyUrlReplaceCharacters(string s)
{
return UrlReplaceCharacters == null ? s : s.ReplaceMany(UrlReplaceCharacters);
}
public static string CutMaxLength(string text, int length)
{
return text.Length <= length ? text : text.Substring(0, length);
return st;
}
}
}