diff --git a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs index e1b65e2a32..8f49ce134c 100644 --- a/src/Umbraco.Core/Cache/MacroCacheRefresher.cs +++ b/src/Umbraco.Core/Cache/MacroCacheRefresher.cs @@ -46,7 +46,10 @@ namespace Umbraco.Cms.Core.Cache { var payloads = Deserialize(json); - Refresh(payloads); + if (payloads is not null) + { + Refresh(payloads); + } } public override void Refresh(JsonPayload[] payloads) @@ -54,13 +57,15 @@ namespace Umbraco.Cms.Core.Cache foreach (var payload in payloads) { foreach (var alias in GetCacheKeysForAlias(payload.Alias)) + { AppCaches.RuntimeCache.ClearByKey(alias); + } - var macroRepoCache = AppCaches.IsolatedCaches.Get(); + Attempt macroRepoCache = AppCaches.IsolatedCaches.Get(); if (macroRepoCache) { - macroRepoCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Id)); - macroRepoCache.Result.Clear(RepositoryCacheKeys.GetKey(payload.Alias)); // Repository caching of macro definition by alias + macroRepoCache.Result?.Clear(RepositoryCacheKeys.GetKey(payload.Id)); + macroRepoCache.Result?.Clear(RepositoryCacheKeys.GetKey(payload.Alias)); // Repository caching of macro definition by alias } } diff --git a/src/Umbraco.Core/Persistence/Repositories/IMacroWithAliasRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IMacroWithAliasRepository.cs index f6cd27ad60..c42d86617f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/IMacroWithAliasRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/IMacroWithAliasRepository.cs @@ -7,8 +7,8 @@ namespace Umbraco.Cms.Core.Persistence.Repositories [Obsolete("This interface will be merged with IMacroRepository in Umbraco 11")] public interface IMacroWithAliasRepository : IMacroRepository { - IMacro GetByAlias(string alias); + IMacro? GetByAlias(string alias); - IEnumerable GetAllByAlias(string[] aliases); + IEnumerable? GetAllByAlias(string[] aliases); } } diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleContentPickerParameterEditor.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleContentPickerParameterEditor.cs index 4d88431e7c..65056c75ce 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleContentPickerParameterEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleContentPickerParameterEditor.cs @@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ParameterEditors DefaultConfiguration.Add("maxNumber", 0); } - protected override IDataValueEditor CreateValueEditor() => DataValueEditorFactory.Create(Attribute); + protected override IDataValueEditor CreateValueEditor() => DataValueEditorFactory.Create(Attribute!); internal class MultipleContentPickerParamateterValueEditor : MultiplePickerParamateterValueEditorBase { diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs index dfdd6f9b9c..4a6bab528c 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultipleMediaPickerParameterEditor.cs @@ -31,7 +31,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ParameterEditors DefaultConfiguration.Add("multiPicker", "1"); } - protected override IDataValueEditor CreateValueEditor() => DataValueEditorFactory.Create(Attribute); + protected override IDataValueEditor CreateValueEditor() => DataValueEditorFactory.Create(Attribute!); internal class MultipleMediaPickerPropertyValueEditor : MultiplePickerParamateterValueEditorBase { diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultiplePickerParamateterValueEditorBase.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultiplePickerParamateterValueEditorBase.cs index 2c4f27b560..5182c1fbd2 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultiplePickerParamateterValueEditorBase.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditors/MultiplePickerParamateterValueEditorBase.cs @@ -27,7 +27,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ParameterEditors public abstract string UdiEntityType { get; } public abstract UmbracoObjectTypes UmbracoObjectType { get; } - public IEnumerable GetReferences(object value) + public IEnumerable GetReferences(object? value) { var asString = value is string str ? str : value?.ToString(); @@ -38,7 +38,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.ParameterEditors foreach (var udiStr in asString.Split(',')) { - if (UdiParser.TryParse(udiStr, out Udi udi)) + if (UdiParser.TryParse(udiStr, out Udi? udi)) { yield return new UmbracoEntityReference(udi); } diff --git a/src/Umbraco.Core/Services/MacroService.cs b/src/Umbraco.Core/Services/MacroService.cs index 4a55411db3..e4f58e5d60 100644 --- a/src/Umbraco.Core/Services/MacroService.cs +++ b/src/Umbraco.Core/Services/MacroService.cs @@ -74,7 +74,7 @@ namespace Umbraco.Cms.Core.Services using (var scope = ScopeProvider.CreateScope(autoComplete: true)) { - return macroWithAliasRepository.GetAllByAlias(aliases); + return macroWithAliasRepository.GetAllByAlias(aliases) ?? Enumerable.Empty(); } } diff --git a/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs b/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs index 841db4b0bd..4888d173d7 100644 --- a/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs +++ b/src/Umbraco.Infrastructure/HostedServices/RecurringHostedServiceBase.cs @@ -23,7 +23,7 @@ namespace Umbraco.Cms.Infrastructure.HostedServices /// protected static readonly TimeSpan DefaultDelay = TimeSpan.FromMinutes(3); - private readonly ILogger _logger; + private readonly ILogger? _logger; private TimeSpan _period; private readonly TimeSpan _delay; private Timer? _timer; @@ -35,7 +35,7 @@ namespace Umbraco.Cms.Infrastructure.HostedServices /// Logger. /// Timespan representing how often the task should recur. /// Timespan representing the initial delay after application start-up before the first run of the task occurs. - protected RecurringHostedServiceBase(ILogger logger, TimeSpan period, TimeSpan delay) + protected RecurringHostedServiceBase(ILogger? logger, TimeSpan period, TimeSpan delay) { _logger = logger; _period = period; diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 8b1f8bb7ac..7c9aabd195 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -8,6 +8,7 @@ using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Infrastructure.Migrations.Upgrade; +using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0; using Umbraco.Cms.Infrastructure.Persistence.Dtos; using Umbraco.Extensions; @@ -1033,17 +1034,17 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install alwaysInsert = true; } - if (!alwaysInsert && installDefaultDataSettings.InstallData == InstallDefaultDataOption.None) + if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.None) { return; } - if (!alwaysInsert && installDefaultDataSettings.InstallData == InstallDefaultDataOption.Values && !installDefaultDataSettings.Values.InvariantContains(id)) + if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values && !installDefaultDataSettings.Values.InvariantContains(id)) { return; } - if (!alwaysInsert && installDefaultDataSettings.InstallData == InstallDefaultDataOption.ExceptValues && installDefaultDataSettings.Values.InvariantContains(id)) + if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.ExceptValues && installDefaultDataSettings.Values.InvariantContains(id)) { return; } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs index b934b92971..678ae1ae7a 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs @@ -108,7 +108,7 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install } public DatabaseSchemaCreator( - IUmbracoDatabase database, + IUmbracoDatabase? database, ILogger logger, ILoggerFactory loggerFactory, IUmbracoVersion umbracoVersion, diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MacroRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MacroRepository.cs index b8a29f65c8..18e9a60449 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MacroRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MacroRepository.cs @@ -70,12 +70,12 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement return Get(id) != null; } - public IMacro GetByAlias(string alias) + public IMacro? GetByAlias(string alias) { return _macroByAliasCachePolicy.Get(alias, PerformGetByAlias, PerformGetAllByAlias); } - public IEnumerable GetAllByAlias(string[] aliases) + public IEnumerable? GetAllByAlias(string[] aliases) { if (aliases.Any() is false) { @@ -85,15 +85,15 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement return _macroByAliasCachePolicy.GetAll(aliases, PerformGetAllByAlias); } - private IMacro PerformGetByAlias(string alias) + private IMacro? PerformGetByAlias(string? alias) { var query = Query().Where(x => x.Alias.Equals(alias)); - return PerformGetByQuery(query).FirstOrDefault(); + return PerformGetByQuery(query)?.FirstOrDefault(); } - private IEnumerable PerformGetAllByAlias(params string[] aliases) + private IEnumerable? PerformGetAllByAlias(params string[]? aliases) { - if (aliases.Any() is false) + if (aliases is null || aliases.Any() is false) { return base.GetMany(); } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TrackedReferencesRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TrackedReferencesRepository.cs index c50728379e..18098623cf 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TrackedReferencesRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TrackedReferencesRepository.cs @@ -58,8 +58,8 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement // Ordering is required for paging sql = sql?.OrderBy(x => x.Alias); - var pagedResult = _scopeAccessor.AmbientScope.Database.Page(pageIndex + 1, pageSize, sql); - totalRecords = pagedResult.TotalItems; + var pagedResult = _scopeAccessor.AmbientScope?.Database.Page(pageIndex + 1, pageSize, sql); + totalRecords = Convert.ToInt32(pagedResult?.TotalItems); return pagedResult?.Items.Select(MapDtoToEntity) ?? Enumerable.Empty(); } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs index 32d3e47b2d..f1a391901f 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs @@ -146,7 +146,7 @@ namespace Umbraco.Cms.Core.PropertyEditors /// /// /// - public override object FromEditor(ContentPropertyData editorValue, object currentValue) + public override object? FromEditor(ContentPropertyData editorValue, object? currentValue) { if (editorValue.Value == null) return null; @@ -222,7 +222,7 @@ namespace Umbraco.Cms.Core.PropertyEditors return grid; } - private GridValue? DeserializeGridValue(string rawJson, out IEnumerable? richTextValues, out IEnumerable? mediaValues, out IEnumerable macroValues) + private GridValue? DeserializeGridValue(string rawJson, out IEnumerable? richTextValues, out IEnumerable? mediaValues, out IEnumerable? macroValues) { var grid = JsonConvert.DeserializeObject(rawJson); @@ -232,7 +232,7 @@ namespace Umbraco.Cms.Core.PropertyEditors mediaValues = controls?.Where(x => x.Editor.Alias.ToLowerInvariant() == "media"); // Find all the macros - macroValues = controls.Where(x => x.Editor.Alias.ToLowerInvariant() == "macro"); + macroValues = controls?.Where(x => x.Editor.Alias.ToLowerInvariant() == "macro"); return grid; } @@ -251,7 +251,7 @@ namespace Umbraco.Cms.Core.PropertyEditors yield break; } - DeserializeGridValue(rawJson, out var richTextEditorValues, out var mediaValues, out var macroValues); + DeserializeGridValue(rawJson!, out var richTextEditorValues, out var mediaValues, out var macroValues); if (richTextEditorValues is not null) { @@ -262,12 +262,22 @@ namespace Umbraco.Cms.Core.PropertyEditors } } - foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value.HasValues) - .SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"]))) - yield return umbracoEntityReference; + if (mediaValues is not null) + { + foreach (var umbracoEntityReference in mediaValues.Where(x => x.Value.HasValues) + .SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"]))) + { + yield return umbracoEntityReference; + } + } - foreach (var umbracoEntityReference in _macroParameterParser.FindUmbracoEntityReferencesFromGridControlMacros(macroValues)) - yield return umbracoEntityReference; + if (macroValues is not null) + { + foreach (var umbracoEntityReference in _macroParameterParser.FindUmbracoEntityReferencesFromGridControlMacros(macroValues)) + { + yield return umbracoEntityReference; + } + } } } } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs index 4c88fd10ca..7fdf314924 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -225,15 +225,14 @@ namespace Umbraco.Cms.Core.PropertyEditors /// public IEnumerable GetReferences(object? value) { - var asString = value == null ? string.Empty : value is string str ? str : value.ToString(); + var asString = value == null ? string.Empty : value is string str ? str : value.ToString()!; - foreach (var udi in _imageSourceParser.FindUdisFromDataAttributes(asString!)) + foreach (var udi in _imageSourceParser.FindUdisFromDataAttributes(asString)) { yield return new UmbracoEntityReference(udi); } - IEnumerable udis = _localLinkParser.FindUdisFromLocalLinks(asString!); - foreach (var udi in _localLinkParser.FindUdisFromLocalLinks(asString!)) + foreach (var udi in _localLinkParser.FindUdisFromLocalLinks(asString)) { if (udi is not null) { diff --git a/src/Umbraco.Infrastructure/Security/UmbracoPasswordHasher.cs b/src/Umbraco.Infrastructure/Security/UmbracoPasswordHasher.cs index 2847f13dc4..778208fa58 100644 --- a/src/Umbraco.Infrastructure/Security/UmbracoPasswordHasher.cs +++ b/src/Umbraco.Infrastructure/Security/UmbracoPasswordHasher.cs @@ -82,17 +82,17 @@ namespace Umbraco.Cms.Core.Security return PasswordVerificationResult.Failed; } - PersistedPasswordSettings deserialized; + PersistedPasswordSettings? deserialized; try { - deserialized = _jsonSerializer.Deserialize(user.PasswordConfig); + deserialized = _jsonSerializer.Deserialize(user.PasswordConfig ?? string.Empty); } catch { return PasswordVerificationResult.Failed; } - if (!LegacyPasswordSecurity.SupportHashAlgorithm(deserialized.HashAlgorithm)) + if (deserialized?.HashAlgorithm is null || !LegacyPasswordSecurity.SupportHashAlgorithm(deserialized.HashAlgorithm)) { return PasswordVerificationResult.Failed; } diff --git a/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs b/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs index 6323139137..fc6e08c0cd 100644 --- a/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs +++ b/src/Umbraco.Infrastructure/Templates/HtmlMacroParameterParser.cs @@ -9,6 +9,7 @@ using Umbraco.Cms.Core.Models.Editors; using Umbraco.Cms.Core.PropertyEditors; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Infrastructure.Macros; +using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Templates { @@ -33,11 +34,11 @@ namespace Umbraco.Cms.Infrastructure.Templates public IEnumerable FindUmbracoEntityReferencesFromEmbeddedMacros(string text) { // There may be more than one macro with the same alias on the page so using a tuple - var foundMacros = new List>>(); + var foundMacros = new List>>(); // This legacy ParseMacros() already finds the macros within a Rich Text Editor using regexes // It seems to lowercase the macro parameter alias - so making the dictionary case insensitive - MacroTagParser.ParseMacros(text, textblock => { }, (macroAlias, macroAttributes) => foundMacros.Add(new Tuple>(macroAlias, new Dictionary(macroAttributes, StringComparer.OrdinalIgnoreCase)))); + MacroTagParser.ParseMacros(text, textblock => { }, (macroAlias, macroAttributes) => foundMacros.Add(new Tuple>(macroAlias, new Dictionary(macroAttributes, StringComparer.OrdinalIgnoreCase)))); foreach (var umbracoEntityReference in GetUmbracoEntityReferencesFromMacros(foundMacros)) { yield return umbracoEntityReference; @@ -51,7 +52,7 @@ namespace Umbraco.Cms.Infrastructure.Templates /// public IEnumerable FindUmbracoEntityReferencesFromGridControlMacros(IEnumerable macroGridControls) { - var foundMacros = new List>>(); + var foundMacros = new List>>(); foreach (var macroGridControl in macroGridControls) { @@ -60,7 +61,7 @@ namespace Umbraco.Cms.Infrastructure.Templates // Collect any macro parameters that contain the media udi format if (gridMacro is not null && gridMacro.MacroParameters is not null && gridMacro.MacroParameters.Any()) { - foundMacros.Add(new Tuple>(gridMacro.MacroAlias, gridMacro.MacroParameters)); + foundMacros.Add(new Tuple>(gridMacro.MacroAlias, gridMacro.MacroParameters)); } } @@ -70,7 +71,7 @@ namespace Umbraco.Cms.Infrastructure.Templates } } - private IEnumerable GetUmbracoEntityReferencesFromMacros(List>> macros) + private IEnumerable GetUmbracoEntityReferencesFromMacros(List>> macros) { if (_macroService is not IMacroWithAliasService macroWithAliasService) @@ -83,7 +84,7 @@ namespace Umbraco.Cms.Infrastructure.Templates // Here we are finding the used macros' Udis (there should be a Related Macro relation type - but Relations don't accept 'Macro' as an option) var foundMacroUmbracoEntityReferences = new List(); // Get all the macro configs in one hit for these unique macro aliases - this is now cached with a custom cache policy - var macroConfigs = macroWithAliasService.GetAll(uniqueMacroAliases.ToArray()); + var macroConfigs = macroWithAliasService.GetAll(uniqueMacroAliases.WhereNotNull().ToArray()); foreach (var macro in macros) { @@ -116,7 +117,7 @@ namespace Umbraco.Cms.Infrastructure.Templates var foundUmbracoEntityReferences = new List(); foreach (var parameter in macroConfig.Properties) { - if (macroParameters.TryGetValue(parameter.Alias, out string parameterValue)) + if (macroParameters.TryGetValue(parameter.Alias, out string? parameterValue)) { var parameterEditorAlias = parameter.EditorAlias; // Lookup propertyEditor from the registered ParameterEditors with the implmementation to avoid looking up for each parameter @@ -146,10 +147,10 @@ namespace Umbraco.Cms.Infrastructure.Templates private class GridMacro { [JsonProperty("macroAlias")] - public string MacroAlias { get; set; } + public string? MacroAlias { get; set; } [JsonProperty("macroParamsDictionary")] - public Dictionary MacroParameters { get; set; } + public Dictionary? MacroParameters { get; set; } } } }