From 2b89839724074e8f0f230b9d0daf4b5036f2b61d Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Thu, 11 Mar 2021 13:20:46 +0100 Subject: [PATCH] Netcore: Get rid of default files in config folder (#9966) * TourController now uses the core tours from embedded resources * Moved tinyMceConfig.*.config to IOptions * Embedded the default grid.editors.config.js * Fixed issue when saving grid with an empty media cell * Logviewer now uses sql as database instead of file. * Remove config folder from build script and nuget pacakges. * Removing auto-generated Id added to appsettings.json * Update src/Umbraco.Web.BackOffice/Controllers/TourController.cs Co-authored-by: Elitsa Marinovska Co-authored-by: Elitsa Marinovska <21998037+elit0451@users.noreply.github.com> --- build/NuSpecs/UmbracoCms.nuspec | 1 - build/build.ps1 | 14 +- .../Configuration/Grid/GridEditorsConfig.cs | 11 ++ .../Models/RichTextEditorSettings.cs | 77 ++++++++++ src/Umbraco.Core/Constants-Configuration.cs | 1 + .../UmbracoBuilder.Configuration.cs | 1 + .../Grid}/grid.editors.config.js | 0 src/Umbraco.Core/Models/ILogViewerQuery.cs | 10 ++ src/Umbraco.Core/Models/LogViewerQuery.cs | 34 +++++ .../Persistence/Constants-DatabaseSchema.cs | 2 + .../Repositories/ILogViewerQueryRepository.cs | 9 ++ src/Umbraco.Core/Umbraco.Core.csproj | 7 +- .../UmbracoBuilder.CoreServices.cs | 2 - .../UmbracoBuilder.Repositories.cs | 1 + .../Logging/Viewer/LogViewerConfig.cs | 78 +++------- .../Migrations/Install/DatabaseDataCreator.cs | 17 +++ .../Install/DatabaseSchemaCreator.cs | 3 +- .../DeleteLogViewerQueryFile.cs | 34 +++++ .../Migrations/Upgrade/UmbracoPlan.cs | 4 + .../MigrateLogViewerQueriesFromFileToDb.cs | 108 ++++++++++++++ .../Persistence/Dtos/LogViewerQueryDto.cs | 22 +++ .../Mappers/LogViewerQueryMapper.cs | 22 +++ .../Mappers/MapperCollectionBuilder.cs | 1 + .../Implement/LogViewerQueryRepository.cs | 140 ++++++++++++++++++ .../PropertyEditors/GridPropertyEditor.cs | 2 +- .../Persistence/SqlServerTableByTableTest.cs | 13 ++ .../Assets/logviewer.searches.config.js | 42 ------ .../Logging/LogviewerTests.cs | 75 ++++++++-- .../Umbraco.Tests.UnitTests.csproj | 1 - .../Controllers/TourController.cs | 37 +++-- .../ServiceCollectionExtensions.cs | 2 +- .../Tours}/getting-started.json | 0 .../RichTextPreValueController.cs | 123 +++------------ .../Umbraco.Web.BackOffice.csproj | 4 + .../appsettings.Development.json | 33 +++-- .../config/lang/cs-CZ.user.xml | 3 - .../config/lang/da-DK.user.xml | 3 - .../config/lang/de-DE.user.xml | 3 - .../config/lang/en-GB.user.xml | 3 - .../config/lang/en-US.user.xml | 3 - .../config/lang/es-ES.user.xml | 3 - .../config/lang/fr-FR.user.xml | 3 - .../config/lang/he-IL.user.xml | 3 - .../config/lang/it-IT.user.xml | 3 - .../config/lang/ja-JP.user.xml | 3 - .../config/lang/ko-KR.user.xml | 3 - .../config/lang/nb-NO.user.xml | 3 - .../config/lang/nl-NL.user.xml | 3 - .../config/lang/pl-PL.user.xml | 3 - .../config/lang/pt-BR.user.xml | 3 - .../config/lang/ru-RU.user.xml | 3 - .../config/lang/sv-SE.user.xml | 3 - .../config/lang/zh-CN.user.xml | 3 - .../config/logviewer.searches.config.js | 42 ------ .../config/tinyMceConfig.Release.config | 72 --------- .../config/tinyMceConfig.config | 74 --------- 56 files changed, 668 insertions(+), 505 deletions(-) create mode 100644 src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs rename src/{Umbraco.Web.UI.NetCore/config => Umbraco.Core/EmbeddedResources/Grid}/grid.editors.config.js (100%) create mode 100644 src/Umbraco.Core/Models/ILogViewerQuery.cs create mode 100644 src/Umbraco.Core/Models/LogViewerQuery.cs create mode 100644 src/Umbraco.Core/Persistence/Repositories/ILogViewerQueryRepository.cs create mode 100644 src/Umbraco.Infrastructure/Migrations/PostMigrations/DeleteLogViewerQueryFile.cs create mode 100644 src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/MigrateLogViewerQueriesFromFileToDb.cs create mode 100644 src/Umbraco.Infrastructure/Persistence/Dtos/LogViewerQueryDto.cs create mode 100644 src/Umbraco.Infrastructure/Persistence/Mappers/LogViewerQueryMapper.cs create mode 100644 src/Umbraco.Infrastructure/Persistence/Repositories/Implement/LogViewerQueryRepository.cs delete mode 100644 src/Umbraco.Tests.UnitTests/TestHelpers/Assets/logviewer.searches.config.js rename src/{Umbraco.Web.UI.NetCore/config/BackOfficeTours => Umbraco.Web.BackOffice/EmbeddedResources/Tours}/getting-started.json (100%) delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/cs-CZ.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/da-DK.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/de-DE.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/en-GB.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/en-US.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/es-ES.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/fr-FR.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/he-IL.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/it-IT.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/ja-JP.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/ko-KR.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/nb-NO.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/nl-NL.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/pl-PL.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/pt-BR.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/ru-RU.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/sv-SE.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/lang/zh-CN.user.xml delete mode 100644 src/Umbraco.Web.UI.NetCore/config/logviewer.searches.config.js delete mode 100644 src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.Release.config delete mode 100644 src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.config diff --git a/build/NuSpecs/UmbracoCms.nuspec b/build/NuSpecs/UmbracoCms.nuspec index ef48ce0de2..a8a0538b20 100644 --- a/build/NuSpecs/UmbracoCms.nuspec +++ b/build/NuSpecs/UmbracoCms.nuspec @@ -30,7 +30,6 @@ - diff --git a/build/build.ps1 b/build/build.ps1 index 58d56fcdfe..f1d041d97c 100644 --- a/build/build.ps1 +++ b/build/build.ps1 @@ -194,14 +194,12 @@ # remove extra files $webAppBin = "$($this.BuildTemp)\WebApp\bin" - $excludeDirs = @("$($webAppBin)\Config","$($webAppBin)\refs","$($webAppBin)\runtimes","$($webAppBin)\Umbraco","$($webAppBin)\wwwroot") + $excludeDirs = @("$($webAppBin)\refs","$($webAppBin)\runtimes","$($webAppBin)\Umbraco","$($webAppBin)\wwwroot") $excludeFiles = @("$($webAppBin)\appsettings.*","$($webAppBin)\*.deps.json","$($webAppBin)\*.exe","$($webAppBin)\*.config","$($webAppBin)\*.runtimeconfig.json") $this.RemoveDirectory($excludeDirs) $this.RemoveFile($excludeFiles) # copy rest of the files into WebApp - $this.CopyFiles("$($this.SolutionRoot)\src\Umbraco.Web.UI.NetCore\Config", "*", "$($this.BuildTemp)\WebApp\config") - $this.RemoveFile("$($this.BuildTemp)\WebApp\Config\*.Release.*") $this.CopyFiles("$($this.SolutionRoot)\src\Umbraco.Web.UI.NetCore\Umbraco", "*", "$($this.BuildTemp)\WebApp\umbraco") $excludeUmbracoDirs = @("$($this.BuildTemp)\WebApp\umbraco\lib") $this.RemoveDirectory($excludeUmbracoDirs) @@ -300,8 +298,6 @@ # create directories Write-Host "Create directories" - mkdir "$tmp\Configs" > $null - mkdir "$tmp\Configs\Lang" > $null mkdir "$tmp\WebApp\App_Data" > $null mkdir "$tmp\Templates" > $null #mkdir "$tmp\WebApp\Media" > $null @@ -311,14 +307,6 @@ Write-Host "Copy xml documentation" Copy-Item -force "$tmp\bin\*.xml" "$tmp\WebApp\bin" - Write-Host "Copy transformed configs and langs" - # note: exclude imageprocessor/*.config as imageprocessor pkg installs them - $this.CopyFiles("$tmp\WebApp\config", "*.config", "$tmp\Configs", ` - { -not $_.RelativeName.StartsWith("imageprocessor") }) - $this.CopyFiles("$tmp\WebApp\config", "*.js", "$tmp\Configs") - $this.CopyFiles("$tmp\WebApp\config\lang", "*.xml", "$tmp\Configs\Lang") - #$this.CopyFile("$tmp\WebApp\web.config", "$tmp\Configs\web.config.transform") - # Write-Host "Copy transformed web.config" # $this.CopyFile("$src\Umbraco.Web.UI\web.$buildConfiguration.Config.transformed", "$tmp\WebApp\web.config") diff --git a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs index 680c47590e..ab6a7e9396 100644 --- a/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs +++ b/src/Umbraco.Core/Configuration/Grid/GridEditorsConfig.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Text; using Microsoft.Extensions.Logging; using Umbraco.Cms.Core.Cache; using Umbraco.Cms.Core.Hosting; @@ -51,6 +52,16 @@ namespace Umbraco.Cms.Core.Configuration.Grid _logger.LogError(ex, "Could not parse the contents of grid.editors.config.js into a JSON array '{Json}", sourceString); } } + else// Read default from embedded file + { + var assembly = GetType().Assembly; + var resourceStream = assembly.GetManifestResourceStream( + "Umbraco.Cms.Core.EmbeddedResources.Grid.grid.editors.config.js"); + + using var reader = new StreamReader(resourceStream, Encoding.UTF8); + var sourceString = reader.ReadToEnd(); + editors.AddRange(_jsonSerializer.Deserialize>(sourceString)); + } // add manifest editors, skip duplicates foreach (var gridEditor in _manifestParser.Manifest.GridEditors) diff --git a/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs b/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs new file mode 100644 index 0000000000..cdd88ca409 --- /dev/null +++ b/src/Umbraco.Core/Configuration/Models/RichTextEditorSettings.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Models.ContentEditing; + +namespace Umbraco.Cms.Core.Configuration.Models +{ + public class RichTextEditorSettings + { + private static readonly string[] s_default_plugins = new[] + { + "paste", + "anchor", + "charmap", + "table", + "lists", + "advlist", + "hr", + "autolink", + "directionality", + "tabfocus", + "searchreplace" + }; + private static readonly RichTextEditorCommand[] s_default_commands = new [] + { + new RichTextEditorCommand(){Alias = "ace" , Name = "Source code editor" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "removeformat" , Name = "Remove format" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "undo" , Name = "Undo" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "redo" , Name = "Redo" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "cut" , Name = "Cut" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "copy" , Name = "Copy" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "paste" , Name = "Paste" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "styleselect" , Name = "Style select" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "bold" , Name = "Bold" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "italic" , Name = "Italic" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "underline" , Name = "Underline" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "strikethrough" , Name = "Strikethrough" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "alignleft" , Name = "Justify left" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "aligncenter" , Name = "Justify center" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "alignright" , Name = "Justify right" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "alignjustify" , Name = "Justify full" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "bullist" , Name = "Bullet list" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "numlist" , Name = "Numbered list" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "outdent" , Name = "Decrease indent" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "indent" , Name = "Increase indent" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "link" , Name = "Insert/edit link" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "unlink" , Name = "Remove link" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "anchor" , Name = "Anchor" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "umbmediapicker" , Name = "Image" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "umbmacro" , Name = "Macro" , Mode = RichTextEditorCommandMode.All}, + new RichTextEditorCommand(){Alias = "table" , Name = "Table" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "umbembeddialog" , Name = "Embed" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "hr" , Name = "Horizontal rule" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "subscript" , Name = "Subscript" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "superscript" , Name = "Superscript" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "charmap" , Name = "Character map" , Mode = RichTextEditorCommandMode.Insert}, + new RichTextEditorCommand(){Alias = "rtl" , Name = "Right to left" , Mode = RichTextEditorCommandMode.Selection}, + new RichTextEditorCommand(){Alias = "ltr" , Name = "Left to right" , Mode = RichTextEditorCommandMode.Selection}, + }; + + private static readonly IDictionary s_default_custom_config = new Dictionary() + { + ["entity_encoding"] = "raw" + }; + + public RichTextEditorCommand[] Commands { get; set; } = s_default_commands; + public string[] Plugins { get; set; } = s_default_plugins; + public IDictionary CustomConfig { get; set; } = s_default_custom_config; + public string ValidElements { get; set; } = "+a[id|style|rel|data-id|data-udi|rev|charset|hreflang|dir|lang|tabindex|accesskey|type|name|href|target|title|class|onfocus|onblur|onclick|ondblclick|onmousedown|onmouseup|onmouseover|onmousemove|onmouseout|onkeypress|onkeydown|onkeyup],-strong/-b[class|style],-em/-i[class|style],-strike[class|style],-u[class|style],#p[id|style|dir|class|align],-ol[class|reversed|start|style|type],-ul[class|style],-li[class|style],br[class],img[id|dir|lang|longdesc|usemap|style|class|src|onmouseover|onmouseout|border|alt=|title|hspace|vspace|width|height|align|umbracoorgwidth|umbracoorgheight|onresize|onresizestart|onresizeend|rel|data-id],-sub[style|class],-sup[style|class],-blockquote[dir|style|class],-table[border=0|cellspacing|cellpadding|width|height|class|align|summary|style|dir|id|lang|bgcolor|background|bordercolor],-tr[id|lang|dir|class|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor],tbody[id|class],thead[id|class],tfoot[id|class],#td[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|bgcolor|background|bordercolor|scope],-th[id|lang|dir|class|colspan|rowspan|width|height|align|valign|style|scope],caption[id|lang|dir|class|style],-div[id|dir|class|align|style],-span[class|align|style],-pre[class|align|style],address[class|align|style],-h1[id|dir|class|align|style],-h2[id|dir|class|align|style],-h3[id|dir|class|align|style],-h4[id|dir|class|align|style],-h5[id|dir|class|align|style],-h6[id|style|dir|class|align|style],hr[class|style],small[class|style],dd[id|class|title|style|dir|lang],dl[id|class|title|style|dir|lang],dt[id|class|title|style|dir|lang],object[class|id|width|height|codebase|*],param[name|value|_value|class],embed[type|width|height|src|class|*],map[name|class],area[shape|coords|href|alt|target|class],bdo[class],button[class],iframe[*]"; + public string InvalidElements { get; set; } = "font"; + + public class RichTextEditorCommand + { + public string Alias { get; set; } + public string Name { get; set; } + public RichTextEditorCommandMode Mode { get; set; } + } + } +} diff --git a/src/Umbraco.Core/Constants-Configuration.cs b/src/Umbraco.Core/Constants-Configuration.cs index 0d62094dad..d596d3feec 100644 --- a/src/Umbraco.Core/Constants-Configuration.cs +++ b/src/Umbraco.Core/Constants-Configuration.cs @@ -50,6 +50,7 @@ public const string ConfigTypeFinder = ConfigPrefix + "TypeFinder"; public const string ConfigWebRouting = ConfigPrefix + "WebRouting"; public const string ConfigUserPassword = ConfigPrefix + "Security:UserPassword"; + public const string ConfigRichTextEditor = ConfigPrefix + "RichTextEditor"; } } } diff --git a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs index 47a98ea9e1..c37f8fb760 100644 --- a/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs +++ b/src/Umbraco.Core/DependencyInjection/UmbracoBuilder.Configuration.cs @@ -56,6 +56,7 @@ namespace Umbraco.Cms.Core.DependencyInjection AddOptions(builder, Constants.Configuration.ConfigWebRouting); AddOptions(builder, Constants.Configuration.ConfigPlugins); AddOptions(builder, Constants.Configuration.ConfigUnattended); + AddOptions(builder, Constants.Configuration.ConfigRichTextEditor); return builder; } diff --git a/src/Umbraco.Web.UI.NetCore/config/grid.editors.config.js b/src/Umbraco.Core/EmbeddedResources/Grid/grid.editors.config.js similarity index 100% rename from src/Umbraco.Web.UI.NetCore/config/grid.editors.config.js rename to src/Umbraco.Core/EmbeddedResources/Grid/grid.editors.config.js diff --git a/src/Umbraco.Core/Models/ILogViewerQuery.cs b/src/Umbraco.Core/Models/ILogViewerQuery.cs new file mode 100644 index 0000000000..3b36f0a9e8 --- /dev/null +++ b/src/Umbraco.Core/Models/ILogViewerQuery.cs @@ -0,0 +1,10 @@ +using Umbraco.Cms.Core.Models.Entities; + +namespace Umbraco.Cms.Core.Models +{ + public interface ILogViewerQuery : IEntity + { + string Name { get; set; } + string Query { get; set; } + } +} diff --git a/src/Umbraco.Core/Models/LogViewerQuery.cs b/src/Umbraco.Core/Models/LogViewerQuery.cs new file mode 100644 index 0000000000..5addfa705f --- /dev/null +++ b/src/Umbraco.Core/Models/LogViewerQuery.cs @@ -0,0 +1,34 @@ +using System; +using System.Runtime.Serialization; +using Umbraco.Cms.Core.Models.Entities; + +namespace Umbraco.Cms.Core.Models +{ + [Serializable] + [DataContract(IsReference = true)] + public class LogViewerQuery : EntityBase, ILogViewerQuery + { + private string _name; + private string _query; + + public LogViewerQuery(string name, string query) + { + Name = name; + _query = query; + } + + [DataMember] + public string Name + { + get => _name; + set => SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name)); + } + + [DataMember] + public string Query + { + get => _query; + set => SetPropertyValueAndDetectChanges(value, ref _query, nameof(Query)); + } + } +} diff --git a/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs b/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs index 73004c491d..e20a6d4344 100644 --- a/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs +++ b/src/Umbraco.Core/Persistence/Constants-DatabaseSchema.cs @@ -75,6 +75,8 @@ namespace Umbraco.Cms.Core public const string AuditEntry = TableNamePrefix + "Audit"; public const string Consent = TableNamePrefix + "Consent"; public const string UserLogin = TableNamePrefix + "UserLogin"; + + public const string LogViewerQuery = "cms" + "LogViewerQuery"; } } } diff --git a/src/Umbraco.Core/Persistence/Repositories/ILogViewerQueryRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ILogViewerQueryRepository.cs new file mode 100644 index 0000000000..d21cd2aa1e --- /dev/null +++ b/src/Umbraco.Core/Persistence/Repositories/ILogViewerQueryRepository.cs @@ -0,0 +1,9 @@ +using Umbraco.Cms.Core.Models; + +namespace Umbraco.Cms.Core.Persistence.Repositories +{ + public interface ILogViewerQueryRepository : IReadWriteQueryRepository + { + ILogViewerQuery GetByName(string name); + } +} diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index bcd73a4a8b..c223b1c8a4 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -1,4 +1,4 @@ - + netstandard2.0 @@ -12,6 +12,7 @@ + @@ -43,4 +44,8 @@ <_Parameter1>DynamicProxyGenAssembly2 + + + + diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs index ec9031c497..e3b327ffaa 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs @@ -125,8 +125,6 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection builder.Services.AddUnique(); - builder.Services.AddUnique(); - // register *all* checks, except those marked [HideFromTypeFinder] of course builder.Services.AddUnique(); diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs index 8292fd2ecb..710565500e 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.Repositories.cs @@ -55,6 +55,7 @@ namespace Umbraco.Cms.Infrastructure.DependencyInjection builder.Services.AddUnique(); builder.Services.AddUnique(); builder.Services.AddUnique(); + builder.Services.AddUnique(); return builder; } diff --git a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs index da17bad085..a758b08081 100644 --- a/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs +++ b/src/Umbraco.Infrastructure/Logging/Viewer/LogViewerConfig.cs @@ -1,85 +1,45 @@ using System.Collections.Generic; -using System.IO; using System.Linq; -using Newtonsoft.Json; -using Umbraco.Cms.Core.Hosting; -using Umbraco.Cms.Core.Routing; -using Formatting = Newtonsoft.Json.Formatting; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Persistence.Repositories; +using Umbraco.Cms.Core.Scoping; namespace Umbraco.Cms.Core.Logging.Viewer { public class LogViewerConfig : ILogViewerConfig { - private readonly IHostingEnvironment _hostingEnvironment; - private static readonly string _pathToSearches = WebPath.Combine(Cms.Core.Constants.SystemDirectories.Config, "logviewer.searches.config.js"); - private readonly FileInfo _searchesConfig; + private readonly ILogViewerQueryRepository _logViewerQueryRepository; + private readonly IScopeProvider _scopeProvider; - public LogViewerConfig(IHostingEnvironment hostingEnvironment) + public LogViewerConfig(ILogViewerQueryRepository logViewerQueryRepository, IScopeProvider scopeProvider) { - _hostingEnvironment = hostingEnvironment; - var trimmedPath = _pathToSearches.TrimStart(Constants.CharArrays.TildeForwardSlash).Replace('/', Path.DirectorySeparatorChar); - var absolutePath = Path.Combine(_hostingEnvironment.ApplicationPhysicalPath, trimmedPath); - _searchesConfig = new FileInfo(absolutePath); + _logViewerQueryRepository = logViewerQueryRepository; + _scopeProvider = scopeProvider; } public IReadOnlyList GetSavedSearches() { - //Our default implementation - - //If file does not exist - lets create it with an empty array - EnsureFileExists(); - - var rawJson = System.IO.File.ReadAllText(_searchesConfig.FullName); - return JsonConvert.DeserializeObject(rawJson); + using var scope = _scopeProvider.CreateScope(autoComplete: true); + var logViewerQueries = _logViewerQueryRepository.GetMany(); + var result = logViewerQueries.Select(x => new SavedLogSearch() { Name = x.Name, Query = x.Query }).ToArray(); + return result; } public IReadOnlyList AddSavedSearch(string name, string query) { - //Get the existing items - var searches = GetSavedSearches().ToList(); + using var scope = _scopeProvider.CreateScope(autoComplete: true); + _logViewerQueryRepository.Save(new LogViewerQuery(name, query)); - //Add the new item to the bottom of the list - searches.Add(new SavedLogSearch { Name = name, Query = query }); - - //Serialize to JSON string - var rawJson = JsonConvert.SerializeObject(searches, Formatting.Indented); - - //If file does not exist - lets create it with an empty array - EnsureFileExists(); - - //Write it back down to file - System.IO.File.WriteAllText(_searchesConfig.FullName, rawJson); - - //Return the updated object - so we can instantly reset the entire array from the API response - //As opposed to push a new item into the array - return searches; + return GetSavedSearches(); } public IReadOnlyList DeleteSavedSearch(string name, string query) { - //Get the existing items - var searches = GetSavedSearches().ToList(); - - //Removes the search - searches.RemoveAll(s => s.Name.Equals(name) && s.Query.Equals(query)); - - //Serialize to JSON string - var rawJson = JsonConvert.SerializeObject(searches, Formatting.Indented); - - //Write it back down to file - System.IO.File.WriteAllText(_searchesConfig.FullName, rawJson); - + using var scope = _scopeProvider.CreateScope(autoComplete: true); + var item = _logViewerQueryRepository.GetByName(name); + _logViewerQueryRepository.Delete(item); //Return the updated object - so we can instantly reset the entire array from the API response - return searches; - } - - private void EnsureFileExists() - { - if (_searchesConfig.Exists) return; - using (var writer = _searchesConfig.CreateText()) - { - writer.Write("[]"); - } + return GetSavedSearches(); } } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 72e8b864bf..30759ae789 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1,9 +1,11 @@ using System; +using System.Linq; using Microsoft.Extensions.Logging; using NPoco; using Umbraco.Cms.Core.Configuration; 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; @@ -76,6 +78,9 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install if (tableName.Equals(Cms.Core.Constants.DatabaseSchema.Tables.KeyValue)) CreateKeyValueData(); + if (tableName.Equals(Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery)) + CreateLogViewerQueryData(); + _logger.LogInformation("Done creating table {TableName} data.", tableName); } @@ -345,5 +350,17 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install _database.Insert(Cms.Core.Constants.DatabaseSchema.Tables.KeyValue, "key", false, new KeyValueDto { Key = stateValueKey, Value = finalState, UpdateDate = DateTime.Now }); } + + private void CreateLogViewerQueryData() + { + var defaultData = MigrateLogViewerQueriesFromFileToDb.DefaultLogQueries.ToArray(); + + for (int i = 0; i < defaultData.Length; i++) + { + var dto = defaultData[i]; + dto.Id = i+1; + _database.Insert(Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery, "id", false, dto); + } + } } } diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs index d7db160b56..d4ce35aebc 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs @@ -91,7 +91,8 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Install typeof (AuditEntryDto), typeof (ContentVersionCultureVariationDto), typeof (DocumentCultureVariationDto), - typeof (ContentScheduleDto) + typeof (ContentScheduleDto), + typeof (LogViewerQueryDto) }; /// diff --git a/src/Umbraco.Infrastructure/Migrations/PostMigrations/DeleteLogViewerQueryFile.cs b/src/Umbraco.Infrastructure/Migrations/PostMigrations/DeleteLogViewerQueryFile.cs new file mode 100644 index 0000000000..cc1828dc2e --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/PostMigrations/DeleteLogViewerQueryFile.cs @@ -0,0 +1,34 @@ +using System.IO; +using Umbraco.Cms.Core.Hosting; +using Umbraco.Cms.Core.Migrations; +using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0; + +namespace Umbraco.Cms.Infrastructure.Migrations.PostMigrations +{ + /// + /// Deletes the old file that saved log queries + /// + public class DeleteLogViewerQueryFile : IMigration + { + private readonly IHostingEnvironment _hostingEnvironment; + + /// + /// Initializes a new instance of the class. + /// + public DeleteLogViewerQueryFile(IMigrationContext context, IHostingEnvironment hostingEnvironment) + { + _hostingEnvironment = hostingEnvironment; + } + + /// + public void Migrate() + { + var logViewerQueryFile = MigrateLogViewerQueriesFromFileToDb.GetLogViewerQueryFile(_hostingEnvironment); + + if(File.Exists(logViewerQueryFile)) + { + File.Delete(logViewerQueryFile); + } + } + } +} diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs index 9aacab1740..64d704bb11 100644 --- a/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs @@ -9,6 +9,7 @@ using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_10_0; using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_6_0; using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_7_0; using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_8_9_0; +using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0; using Umbraco.Extensions; namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade @@ -197,6 +198,9 @@ namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade To("{B5838FF5-1D22-4F6C-BCEB-F83ACB14B575}"); // to 8.10.0 To("{D6A8D863-38EC-44FB-91EC-ACD6A668BD18}"); + + // to 8.10.0 + To("{22D801BA-A1FF-4539-BFCC-2139B55594F8}"); //FINAL } } diff --git a/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/MigrateLogViewerQueriesFromFileToDb.cs b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/MigrateLogViewerQueriesFromFileToDb.cs new file mode 100644 index 0000000000..88ffe1a66c --- /dev/null +++ b/src/Umbraco.Infrastructure/Migrations/Upgrade/V_9_0_0/MigrateLogViewerQueriesFromFileToDb.cs @@ -0,0 +1,108 @@ +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using Newtonsoft.Json; +using Umbraco.Cms.Core.Hosting; +using Umbraco.Cms.Infrastructure.Migrations.PostMigrations; +using Umbraco.Cms.Infrastructure.Persistence.Dtos; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0 +{ + + public class MigrateLogViewerQueriesFromFileToDb : MigrationBase + { + private readonly IHostingEnvironment _hostingEnvironment; + internal static readonly IEnumerable DefaultLogQueries = new LogViewerQueryDto[] + { + new (){ + Name = "Find all logs where the Level is NOT Verbose and NOT Debug", + Query = "Not(@Level='Verbose') and Not(@Level='Debug')" + }, + new (){ + Name = "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)", + Query = "Has(@Exception)" + }, + new (){ + Name = "Find all logs that have the property 'Duration'", + Query = "Has(Duration)" + }, + new (){ + Name = "Find all logs that have the property 'Duration' and the duration is greater than 1000ms", + Query = "Has(Duration) and Duration > 1000" + }, + new (){ + Name = "Find all logs that are from the namespace 'Umbraco.Core'", + Query = "StartsWith(SourceContext, 'Umbraco.Core')" + }, + new (){ + Name = "Find all logs that use a specific log message template", + Query = "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'" + }, + new (){ + Name = "Find logs where one of the items in the SortedComponentTypes property array is equal to", + Query = "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'" + }, + new (){ + Name = "Find logs where one of the items in the SortedComponentTypes property array contains", + Query = "Contains(SortedComponentTypes[?], 'DatabaseServer')" + }, + new (){ + Name = "Find all logs that the message has localhost in it with SQL like", + Query = "@Message like '%localhost%'" + }, + new (){ + Name = "Find all logs that the message that starts with 'end' in it with SQL like", + Query = "@Message like 'end%'" + } + }; + + public MigrateLogViewerQueriesFromFileToDb(IMigrationContext context, IHostingEnvironment hostingEnvironment) + : base(context) + { + _hostingEnvironment = hostingEnvironment; + } + + public override void Migrate() + { + Debugger.Launch(); + Debugger.Break(); + CreateDatabaseTable(); + MigrateFileContentToDB(); + } + private void CreateDatabaseTable() + { + var tables = SqlSyntax.GetTablesInSchema(Context.Database); + if (!tables.InvariantContains(Core.Constants.DatabaseSchema.Tables.LogViewerQuery)) + { + Create.Table().Do(); + } + } + + internal static string GetLogViewerQueryFile(IHostingEnvironment hostingEnvironment) + { + return hostingEnvironment.MapPathContentRoot( + Path.Combine(Cms.Core.Constants.SystemDirectories.Config, "logviewer.searches.config.js")); + } + private void MigrateFileContentToDB() + { + var logViewerQueryFile = GetLogViewerQueryFile(_hostingEnvironment); + + var logQueriesInFile = File.Exists(logViewerQueryFile) ? + JsonConvert.DeserializeObject(File.ReadAllText(logViewerQueryFile)) + : DefaultLogQueries; + + var logQueriesInDb = Database.Query().ToArray(); + + if (logQueriesInDb.Any()) + { + return; + } + + Database.InsertBulk(logQueriesInFile); + + Context.AddPostMigration(); + } + } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Dtos/LogViewerQueryDto.cs b/src/Umbraco.Infrastructure/Persistence/Dtos/LogViewerQueryDto.cs new file mode 100644 index 0000000000..71642c8b73 --- /dev/null +++ b/src/Umbraco.Infrastructure/Persistence/Dtos/LogViewerQueryDto.cs @@ -0,0 +1,22 @@ +using NPoco; +using Umbraco.Cms.Infrastructure.Persistence.DatabaseAnnotations; + +namespace Umbraco.Cms.Infrastructure.Persistence.Dtos +{ + [TableName(Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery)] + [PrimaryKey("id")] + [ExplicitColumns] + internal class LogViewerQueryDto + { + [Column("id")] + [PrimaryKeyColumn] + public int Id { get; set; } + + [Column("name")] + [Index(IndexTypes.UniqueNonClustered, Name = "IX_LogViewerQuery_name")] + public string Name { get; set; } + + [Column("query")] + public string Query { get; set; } + } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/LogViewerQueryMapper.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/LogViewerQueryMapper.cs new file mode 100644 index 0000000000..807e3b6c02 --- /dev/null +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/LogViewerQueryMapper.cs @@ -0,0 +1,22 @@ +using System; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Infrastructure.Persistence.Dtos; + +namespace Umbraco.Cms.Infrastructure.Persistence.Mappers +{ + [MapperFor(typeof(ILogViewerQuery))] + [MapperFor(typeof(LogViewerQuery))] + public sealed class LogViewerQueryMapper : BaseMapper + { + public LogViewerQueryMapper(Lazy sqlContext, MapperConfigurationStore maps) + : base(sqlContext, maps) + { } + + protected override void DefineMaps() + { + DefineMap(nameof(ILogViewerQuery.Id), nameof(LogViewerQueryDto.Id)); + DefineMap(nameof(ILogViewerQuery.Name), nameof(LogViewerQueryDto.Name)); + DefineMap(nameof(ILogViewerQuery.Query), nameof(LogViewerQueryDto.Query)); + } + } +} diff --git a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs index c5f0814469..38f1176b75 100644 --- a/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs +++ b/src/Umbraco.Infrastructure/Persistence/Mappers/MapperCollectionBuilder.cs @@ -53,6 +53,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Mappers Add(); Add(); Add(); + Add(); return this; } } diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/LogViewerQueryRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/LogViewerQueryRepository.cs new file mode 100644 index 0000000000..35f0b8fdab --- /dev/null +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/LogViewerQueryRepository.cs @@ -0,0 +1,140 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using Microsoft.Extensions.Logging; +using NPoco; +using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Persistence.Querying; +using Umbraco.Cms.Core.Persistence.Repositories; +using Umbraco.Cms.Core.Scoping; +using Umbraco.Cms.Infrastructure.Persistence.Dtos; +using Umbraco.Extensions; + +namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement +{ + internal class LogViewerQueryRepository : EntityRepositoryBase, ILogViewerQueryRepository + { + public LogViewerQueryRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger) + : base(scopeAccessor, cache, logger) + { } + + protected override IRepositoryCachePolicy CreateCachePolicy() + { + return new FullDataSetRepositoryCachePolicy(GlobalIsolatedCache, ScopeAccessor, GetEntityId, /*expires:*/ false); + } + + protected override IEnumerable PerformGetAll(params int[] ids) + { + var sql = GetBaseQuery(false).Where($"{Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery}.id > 0"); + if (ids.Any()) + { + sql.Where($"{Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery}.id in (@ids)", new { ids = ids }); + } + + return Database.Fetch(sql).Select(ConvertFromDto); + } + + protected override IEnumerable PerformGetByQuery(IQuery query) + { + throw new NotSupportedException("This repository does not support this method"); + } + + protected override Sql GetBaseQuery(bool isCount) + { + var sql = Sql(); + sql = isCount ? sql.SelectCount() : sql.Select(); + sql = sql.From(); + return sql; + } + + protected override string GetBaseWhereClause() + { + return $"{Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery}.id = @id"; + } + + protected override IEnumerable GetDeleteClauses() + { + var list = new List + { + $"DELETE FROM {Cms.Core.Constants.DatabaseSchema.Tables.LogViewerQuery} WHERE id = @id" + }; + return list; + } + + protected override Guid NodeObjectTypeId + { + get { throw new NotImplementedException(); } + } + + protected override void PersistNewItem(ILogViewerQuery entity) + { + var exists = Database.ExecuteScalar($"SELECT COUNT(*) FROM {Core.Constants.DatabaseSchema.Tables.LogViewerQuery} WHERE name = @name", + new { name = entity.Name }); + if (exists > 0) throw new DuplicateNameException($"The log query name '{entity.Name}' is already used"); + + entity.AddingEntity(); + + var factory = new LogViewerQueryModelFactory(); + var dto = factory.BuildDto(entity); + + var id = Convert.ToInt32(Database.Insert(dto)); + entity.Id = id; + } + + protected override void PersistUpdatedItem(ILogViewerQuery entity) + { + entity.UpdatingEntity(); + + var exists = Database.ExecuteScalar($"SELECT COUNT(*) FROM {Core.Constants.DatabaseSchema.Tables.LogViewerQuery} WHERE name = @name AND id <> @id", + new { name = entity.Name, id = entity.Id }); + //ensure there is no other log query with the same name on another entity + if (exists > 0) throw new DuplicateNameException($"The log query name '{entity.Name}' is already used"); + + + var factory = new LogViewerQueryModelFactory(); + var dto = factory.BuildDto(entity); + + Database.Update(dto); + } + + private ILogViewerQuery ConvertFromDto(LogViewerQueryDto dto) + { + var factory = new LogViewerQueryModelFactory(); + var entity = factory.BuildEntity(dto); + return entity; + } + + internal class LogViewerQueryModelFactory + { + + public ILogViewerQuery BuildEntity(LogViewerQueryDto dto) + { + var logViewerQuery = new LogViewerQuery(dto.Name, dto.Query) + { + Id = dto.Id, + }; + return logViewerQuery; + } + + public LogViewerQueryDto BuildDto(ILogViewerQuery entity) + { + var dto = new LogViewerQueryDto { Name = entity.Name, Query = entity.Query, Id = entity.Id }; + return dto; + } + } + + protected override ILogViewerQuery PerformGet(int id) + { + //use the underlying GetAll which will force cache all log queries + return GetMany().FirstOrDefault(x => x.Id == id); + } + + public ILogViewerQuery GetByName(string name) + { + //use the underlying GetAll which will force cache all log queries + return GetMany().FirstOrDefault(x => x.Name == name); + } + } +} diff --git a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs index a40ab92ca8..6e732cdc0f 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/GridPropertyEditor.cs @@ -202,7 +202,7 @@ namespace Umbraco.Cms.Core.PropertyEditors _richTextPropertyValueEditor.GetReferences(x.Value))) yield return umbracoEntityReference; - foreach (var umbracoEntityReference in mediaValues.SelectMany(x => + foreach (var umbracoEntityReference in mediaValues.Where(x=>x.Value.HasValues).SelectMany(x => _mediaPickerPropertyValueEditor.GetReferences(x.Value["udi"]))) yield return umbracoEntityReference; } diff --git a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/SqlServerTableByTableTest.cs b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/SqlServerTableByTableTest.cs index a44d7ca252..55a348aad7 100644 --- a/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/SqlServerTableByTableTest.cs +++ b/src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/SqlServerTableByTableTest.cs @@ -220,6 +220,19 @@ namespace Umbraco.Cms.Tests.Integration.Umbraco.Infrastructure.Persistence } } + [Test] + public void Can_Create_umbracoLogViewerQuery_Table() + { + using (var scope = ScopeProvider.CreateScope()) + { + var helper = new DatabaseSchemaCreator(scope.Database, _loggerFactory.CreateLogger(), _loggerFactory, UmbracoVersion); + + helper.CreateTable(); + + scope.Complete(); + } + } + [Test] public void Can_Create_umbracoLanguage_Table() { diff --git a/src/Umbraco.Tests.UnitTests/TestHelpers/Assets/logviewer.searches.config.js b/src/Umbraco.Tests.UnitTests/TestHelpers/Assets/logviewer.searches.config.js deleted file mode 100644 index 25ee9b2242..0000000000 --- a/src/Umbraco.Tests.UnitTests/TestHelpers/Assets/logviewer.searches.config.js +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "name": "Find all logs where the Level is NOT Verbose and NOT Debug", - "query": "Not(@Level='Verbose') and Not(@Level='Debug')" - }, - { - "name": "Find all logs that has an exception property (Warning, Error & Critical with Exceptions)", - "query": "Has(@Exception)" - }, - { - "name": "Find all logs that have the property 'Duration'", - "query": "Has(Duration)" - }, - { - "name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms", - "query": "Has(Duration) and Duration > 1000" - }, - { - "name": "Find all logs that are from the namespace 'Umbraco.Core'", - "query": "StartsWith(SourceContext, 'Umbraco.Core')" - }, - { - "name": "Find all logs that use a specific log message template", - "query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'" - }, - { - "name": "Find logs where one of the items in the SortedComponentTypes property array is equal to", - "query": "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'" - }, - { - "name": "Find logs where one of the items in the SortedComponentTypes property array contains", - "query": "Contains(SortedComponentTypes[?], 'DatabaseServer')" - }, - { - "name": "Find all logs that the message has localhost in it with SQL like", - "query": "@Message like '%localhost%'" - }, - { - "name": "Find all logs that the message that starts with 'end' in it with SQL like", - "query": "@Message like 'end%'" - } -] diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Logging/LogviewerTests.cs b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Logging/LogviewerTests.cs index a957f3611e..9ba522fbc9 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Logging/LogviewerTests.cs +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Logging/LogviewerTests.cs @@ -16,6 +16,11 @@ using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Logging; using Umbraco.Cms.Core.Logging.Viewer; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Persistence.Querying; +using Umbraco.Cms.Core.Persistence.Repositories; +using Umbraco.Cms.Core.Scoping; +using Umbraco.Cms.Infrastructure.Migrations.Upgrade.V_9_0_0; +using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement; using Umbraco.Cms.Tests.UnitTests.TestHelpers; using File = System.IO.File; @@ -27,18 +32,16 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging private ILogViewer _logViewer; private const string LogfileName = "UmbracoTraceLog.UNITTEST.20181112.json"; - private const string SearchfileName = "logviewer.searches.config.js"; private string _newLogfilePath; private string _newLogfileDirPath; - private string _newSearchfilePath; - private string _newSearchfileDirPath; - private readonly LogTimePeriod _logTimePeriod = new LogTimePeriod( new DateTime(year: 2018, month: 11, day: 12, hour: 0, minute: 0, second: 0), new DateTime(year: 2018, month: 11, day: 13, hour: 0, minute: 0, second: 0)); + private ILogViewerQueryRepository LogViewerQueryRepository { get; } = new TestLogViewerQueryRepository(); + [OneTimeSetUp] public void Setup() { @@ -55,20 +58,14 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging _newLogfileDirPath = loggingConfiguration.LogDirectory; _newLogfilePath = Path.Combine(_newLogfileDirPath, LogfileName); - var exampleSearchfilePath = Path.Combine(testRoot, "TestHelpers", "Assets", SearchfileName); - _newSearchfileDirPath = Path.Combine(hostingEnv.ApplicationPhysicalPath, @"config"); - _newSearchfilePath = Path.Combine(_newSearchfileDirPath, SearchfileName); - // Create/ensure Directory exists ioHelper.EnsurePathExists(_newLogfileDirPath); - ioHelper.EnsurePathExists(_newSearchfileDirPath); // Copy the sample files File.Copy(exampleLogfilePath, _newLogfilePath, true); - File.Copy(exampleSearchfilePath, _newSearchfilePath, true); ILogger logger = Mock.Of>(); - var logViewerConfig = new LogViewerConfig(hostingEnv); + var logViewerConfig = new LogViewerConfig(LogViewerQueryRepository, Mock.Of()); _logViewer = new SerilogJsonLogViewer(logger, logViewerConfig, loggingConfiguration, Log.Logger); } @@ -81,11 +78,6 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging { File.Delete(_newLogfilePath); } - - if (File.Exists(_newSearchfilePath)) - { - File.Delete(_newSearchfilePath); - } } [Test] @@ -238,4 +230,55 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Infrastructure.Logging Assert.IsEmpty(findItem, "The search item should no longer exist"); } } + + internal class TestLogViewerQueryRepository : ILogViewerQueryRepository + { + public TestLogViewerQueryRepository() + { + Store = new List(MigrateLogViewerQueriesFromFileToDb.DefaultLogQueries + .Select(LogViewerQueryModelFactory.BuildEntity)); + } + + private IList Store { get; } + private LogViewerQueryRepository.LogViewerQueryModelFactory LogViewerQueryModelFactory { get; } = new LogViewerQueryRepository.LogViewerQueryModelFactory(); + + + public ILogViewerQuery Get(int id) => Store.FirstOrDefault(x => x.Id == id); + + public IEnumerable GetMany(params int[] ids) => + ids.Any() ? Store.Where(x => ids.Contains(x.Id)) : Store; + + public bool Exists(int id) => Get(id) is not null; + + public void Save(ILogViewerQuery entity) + { + var item = Get(entity.Id); + + if (item is null) + { + Store.Add(entity); + } + else + { + item.Name = entity.Name; + item.Query = entity.Query; + } + } + + public void Delete(ILogViewerQuery entity) + { + var item = Get(entity.Id); + + if (item is not null) + { + Store.Remove(item); + } + } + + public IEnumerable Get(IQuery query) => throw new NotImplementedException(); + + public int Count(IQuery query) => throw new NotImplementedException(); + + public ILogViewerQuery GetByName(string name) => Store.FirstOrDefault(x => x.Name == name); + } } diff --git a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj index 11e44d7dce..1bd1600721 100644 --- a/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj +++ b/src/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj @@ -26,7 +26,6 @@ - diff --git a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs index 607df48701..3b6116cc6c 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Text; +using System.Threading.Tasks; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Umbraco.Cms.Core; @@ -39,7 +41,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _contentTypeService = contentTypeService; } - public IEnumerable GetTours() + public async Task> GetTours() { var result = new List(); @@ -57,15 +59,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers var nonPluginFilters = _filters.Where(x => x.PluginName == null).ToList(); //add core tour files - var coreToursPath = Path.Combine(_hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.Config), "BackOfficeTours"); - if (Directory.Exists(coreToursPath)) + var embeddedTourNames = GetType() + .Assembly + .GetManifestResourceNames() + .Where(x => x.StartsWith("Umbraco.Cms.Web.BackOffice.EmbeddedResources.Tours.")); + + foreach (var embeddedTourName in embeddedTourNames) { - foreach (var tourFile in Directory.EnumerateFiles(coreToursPath, "*.json")) - { - TryParseTourFile(tourFile, result, nonPluginFilters, aliasOnlyFilters); - } + await TryParseTourFile(embeddedTourName, result, nonPluginFilters, aliasOnlyFilters, async x=> await GetContentFromEmbeddedResource(x)); } + //collect all tour files in packages var appPlugins = _hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins); if (Directory.Exists(appPlugins)) @@ -89,7 +93,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers { foreach (var tourFile in Directory.EnumerateFiles(tourDir, "*.json")) { - TryParseTourFile(tourFile, result, combinedFilters, aliasOnlyFilters, pluginName); + await TryParseTourFile(tourFile, result, combinedFilters, aliasOnlyFilters, async x => await System.IO.File.ReadAllTextAsync(x), pluginName); } } } @@ -126,14 +130,22 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return result.Except(toursToBeRemoved).OrderBy(x => x.FileName, StringComparer.InvariantCultureIgnoreCase); } + private async Task GetContentFromEmbeddedResource(string fileName) + { + var resourceStream = GetType().Assembly.GetManifestResourceStream(fileName); + + using var reader = new StreamReader(resourceStream, Encoding.UTF8); + return await reader.ReadToEndAsync(); + } + /// /// Gets a tours for a specific doctype /// /// The documenttype alias /// A - public IEnumerable GetToursForDoctype(string doctypeAlias) + public async Task> GetToursForDoctype(string doctypeAlias) { - var tourFiles = this.GetTours(); + var tourFiles = await this.GetTours(); var doctypeAliasWithCompositions = new List { @@ -159,10 +171,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers }); } - private void TryParseTourFile(string tourFile, + private async Task TryParseTourFile(string tourFile, ICollection result, List filters, List aliasOnlyFilters, + Func> fileNameToFileContent, string pluginName = null) { var fileName = Path.GetFileNameWithoutExtension(tourFile); @@ -182,7 +195,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers try { - var contents = System.IO.File.ReadAllText(tourFile); + var contents = await fileNameToFileContent(tourFile); var tours = JsonConvert.DeserializeObject(contents); var backOfficeTours = tours.Where(x => diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs index 9c4caac73e..3218897eee 100644 --- a/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/DependencyInjection/ServiceCollectionExtensions.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using Umbraco.Cms.Core; using Umbraco.Cms.Core.Actions; using Umbraco.Cms.Core.Net; using Umbraco.Cms.Core.Security; @@ -11,7 +12,6 @@ using Umbraco.Cms.Web.BackOffice.Security; using Umbraco.Cms.Web.Common.AspNetCore; using Umbraco.Cms.Web.Common.Authorization; using Umbraco.Cms.Web.Common.Security; -using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Extensions { diff --git a/src/Umbraco.Web.UI.NetCore/config/BackOfficeTours/getting-started.json b/src/Umbraco.Web.BackOffice/EmbeddedResources/Tours/getting-started.json similarity index 100% rename from src/Umbraco.Web.UI.NetCore/config/BackOfficeTours/getting-started.json rename to src/Umbraco.Web.BackOffice/EmbeddedResources/Tours/getting-started.json diff --git a/src/Umbraco.Web.BackOffice/PropertyEditors/RichTextPreValueController.cs b/src/Umbraco.Web.BackOffice/PropertyEditors/RichTextPreValueController.cs index faa4cc83dc..3d0d746d5a 100644 --- a/src/Umbraco.Web.BackOffice/PropertyEditors/RichTextPreValueController.cs +++ b/src/Umbraco.Web.BackOffice/PropertyEditors/RichTextPreValueController.cs @@ -1,13 +1,10 @@ -using System.Collections.Generic; -using System.Xml; +using System.Linq; +using Microsoft.Extensions.Options; using Umbraco.Cms.Core; -using Umbraco.Cms.Core.Hosting; -using Umbraco.Cms.Core.IO; +using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Web.BackOffice.Controllers; using Umbraco.Cms.Web.Common.Attributes; -using Umbraco.Extensions; -using Constants = Umbraco.Cms.Core.Constants; namespace Umbraco.Cms.Web.BackOffice.PropertyEditors { @@ -17,115 +14,35 @@ namespace Umbraco.Cms.Web.BackOffice.PropertyEditors [PluginController(Constants.Web.Mvc.BackOfficeApiArea)] public class RichTextPreValueController : UmbracoAuthorizedJsonController { - private readonly IHostingEnvironment _hostingEnvironment; + private readonly IOptions _richTextEditorSettings; - public RichTextPreValueController(IHostingEnvironment hostingEnvironment) + public RichTextPreValueController(IOptions richTextEditorSettings) { - _hostingEnvironment = hostingEnvironment; + _richTextEditorSettings = richTextEditorSettings; } - private static volatile bool _init; - private static readonly object Locker = new object(); - private static readonly Dictionary Commands = new Dictionary(); - private static readonly Dictionary Plugins = new Dictionary(); - private static readonly Dictionary ConfigOptions = new Dictionary(); - - private static string _invalidElements = ""; - private static string _validElements = ""; - public RichTextEditorConfiguration GetConfiguration() { - EnsureInit(); + var settings = _richTextEditorSettings.Value; var config = new RichTextEditorConfiguration { - Plugins = Plugins.Values, - Commands = Commands.Values, - ValidElements = _validElements, - InvalidElements = _invalidElements, - CustomConfig = ConfigOptions + Plugins = settings.Plugins.Select(x=>new RichTextEditorPlugin() + { + Name = x + }), + Commands = settings.Commands.Select(x=>new RichTextEditorCommand() + { + Alias = x.Alias, + Mode = x.Mode, + Name = x.Name + }), + ValidElements = settings.ValidElements, + InvalidElements = settings.InvalidElements, + CustomConfig = settings.CustomConfig }; return config; } - - private void EnsureInit() - { - - if (_init == false) - { - lock (Locker) - { - if (_init == false) - { - // Load config - XmlDocument xd = new XmlDocument(); - xd.Load(_hostingEnvironment.MapPathContentRoot(SystemFiles.TinyMceConfig)); - - foreach (XmlNode n in xd.DocumentElement.SelectNodes("//command")) - { - var alias = n.AttributeValue("alias").ToLower(); - - if (!Commands.ContainsKey(alias)) - Commands.Add( - alias, - new RichTextEditorCommand() - { - Name = n.AttributeValue("name") ?? alias, - Alias = alias, - Mode = Enum.Parse(n.AttributeValue("mode"), true) - } - ); - } - - - foreach (XmlNode n in xd.DocumentElement.SelectNodes("//plugin")) - { - if (!Plugins.ContainsKey(n.FirstChild.Value)) - { - - Plugins.Add( - n.FirstChild.Value.ToLower(), - new RichTextEditorPlugin() - { - Name = n.FirstChild.Value, - }); - } - } - - - foreach (XmlNode n in xd.DocumentElement.SelectNodes("//config")) - { - if (!ConfigOptions.ContainsKey(n.Attributes["key"].FirstChild.Value)) - { - var value = ""; - if (n.FirstChild != null) - value = n.FirstChild.Value; - - ConfigOptions.Add( - n.Attributes["key"].FirstChild.Value.ToLower(), - value); - } - } - - if (xd.DocumentElement.SelectSingleNode("./invalidElements") != null) - _invalidElements = xd.DocumentElement.SelectSingleNode("./invalidElements").FirstChild.Value; - if (xd.DocumentElement.SelectSingleNode("./validElements") != null) - { - string _val = xd.DocumentElement.SelectSingleNode("./validElements").FirstChild.Value.Replace("\r", "").Replace("\n", ""); - _validElements = _val; - - /*foreach (string s in _val.Split("\n".ToCharArray())) - _validElements += "'" + s + "' + \n"; - _validElements = _validElements.Substring(0, _validElements.Length - 4);*/ - } - - _init = true; - } - } - } - - } - } } diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj index 22799eaa63..f6f0113fc2 100644 --- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj +++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj @@ -36,4 +36,8 @@ + + + + diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json index 983b157ef1..06afcf2a7a 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.Development.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.Development.json @@ -18,16 +18,29 @@ }, "Umbraco": { "CMS": { - "Global": { - "Smtp": { -// "From": "your@email.here", -// "Host": "localhost", -// "Port": "25" - } - }, - "Hosting": { - "Debug": true - } + "Global": { + "Smtp": { + //"From": "your@email.here", + //"Host": "localhost", + // "Port": "25" + } + }, + "Hosting": { + "Debug": true + }, + "RichTextEditor": { + "Commands" : [ + { + "Alias": "fullscreen", + "Name": "Full Screen", + "Mode": "All" + } + ], + "Plugins": [ + "fullscreen" + ] + } } + } } diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/cs-CZ.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/cs-CZ.user.xml deleted file mode 100644 index d4902d563d..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/cs-CZ.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/da-DK.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/da-DK.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/da-DK.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/de-DE.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/de-DE.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/de-DE.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/en-GB.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/en-GB.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/en-GB.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/en-US.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/en-US.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/en-US.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/es-ES.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/es-ES.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/es-ES.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/fr-FR.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/fr-FR.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/fr-FR.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/he-IL.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/he-IL.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/he-IL.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/it-IT.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/it-IT.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/it-IT.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/ja-JP.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/ja-JP.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/ja-JP.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/ko-KR.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/ko-KR.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/ko-KR.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/nb-NO.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/nb-NO.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/nb-NO.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/nl-NL.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/nl-NL.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/nl-NL.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/pl-PL.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/pl-PL.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/pl-PL.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/pt-BR.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/pt-BR.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/pt-BR.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/ru-RU.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/ru-RU.user.xml deleted file mode 100644 index 7a8ce2c28a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/ru-RU.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/sv-SE.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/sv-SE.user.xml deleted file mode 100644 index 3a0ad355c3..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/sv-SE.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/Umbraco.Web.UI.NetCore/config/lang/zh-CN.user.xml b/src/Umbraco.Web.UI.NetCore/config/lang/zh-CN.user.xml deleted file mode 100644 index 8d2add98dd..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/lang/zh-CN.user.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/Umbraco.Web.UI.NetCore/config/logviewer.searches.config.js b/src/Umbraco.Web.UI.NetCore/config/logviewer.searches.config.js deleted file mode 100644 index 345fe23764..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/logviewer.searches.config.js +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "name": "Find all logs where the Level is NOT Verbose and NOT Debug", - "query": "Not(@Level='Verbose') and Not(@Level='Debug')" - }, - { - "name": "Find all logs that has an exception property (Warning, Error & Fatal with Exceptions)", - "query": "Has(@Exception)" - }, - { - "name": "Find all logs that have the property 'Duration'", - "query": "Has(Duration)" - }, - { - "name": "Find all logs that have the property 'Duration' and the duration is greater than 1000ms", - "query": "Has(Duration) and Duration > 1000" - }, - { - "name": "Find all logs that are from the namespace 'Umbraco.Core'", - "query": "StartsWith(SourceContext, 'Umbraco.Core')" - }, - { - "name": "Find all logs that use a specific log message template", - "query": "@MessageTemplate = '[Timing {TimingId}] {EndMessage} ({TimingDuration}ms)'" - }, - { - "name": "Find logs where one of the items in the SortedComponentTypes property array is equal to", - "query": "SortedComponentTypes[?] = 'Umbraco.Web.Search.ExamineComponent'" - }, - { - "name": "Find logs where one of the items in the SortedComponentTypes property array contains", - "query": "Contains(SortedComponentTypes[?], 'DatabaseServer')" - }, - { - "name": "Find all logs that the message has localhost in it with SQL like", - "query": "@Message like '%localhost%'" - }, - { - "name": "Find all logs that the message that starts with 'end' in it with SQL like", - "query": "@Message like 'end%'" - } -] diff --git a/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.Release.config b/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.Release.config deleted file mode 100644 index f6a26ee89a..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.Release.config +++ /dev/null @@ -1,72 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - paste - anchor - charmap - table - lists - advlist - hr - autolink - directionality - tabfocus - searchreplace - - - - - font - - - - - raw - - diff --git a/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.config b/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.config deleted file mode 100644 index 7f7cb657e6..0000000000 --- a/src/Umbraco.Web.UI.NetCore/config/tinyMceConfig.config +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - paste - anchor - charmap - table - lists - advlist - hr - autolink - directionality - tabfocus - searchreplace - fullscreen - - - - - font - - - - - raw - -