From 902f126e6bf788ba5b506a323405a8793ea7c0c0 Mon Sep 17 00:00:00 2001 From: Anders Bjerner Date: Fri, 9 Sep 2022 12:50:21 +0200 Subject: [PATCH] Added support for virtual backoffice icons (#12833) --- .../Services/IconService.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/Umbraco.Web.BackOffice/Services/IconService.cs b/src/Umbraco.Web.BackOffice/Services/IconService.cs index 7f060dc756..c8b6eaaf1b 100644 --- a/src/Umbraco.Web.BackOffice/Services/IconService.cs +++ b/src/Umbraco.Web.BackOffice/Services/IconService.cs @@ -136,6 +136,9 @@ public class IconService : IIconService } } + // Get icons from the web root file provider (both physical and virtual) + icons.UnionWith(GetIconsFiles(_webHostEnvironment.WebRootFileProvider, Constants.SystemDirectories.AppPlugins)); + IDirectoryContents? iconFolder = _webHostEnvironment.WebRootFileProvider.GetDirectoryContents(_globalSettings.IconsPath); @@ -148,6 +151,63 @@ public class IconService : IIconService return icons; } + + /// + /// Finds all SVG icon files based on the specified and . + /// The method will find both physical and virtual (eg. from a Razor Class Library) icons. + /// + /// The file provider to be used. + /// The sub path to start from - should probably always be . + /// A collection of representing the found SVG icon files. + private static IEnumerable GetIconsFiles(IFileProvider fileProvider, string path) + { + // Iterate through all plugin folders, this is necessary because on Linux we'll get casing issues when + // we directly try to access {path}/{pluginDirectory.Name}/{Constants.SystemDirectories.PluginIcons} + foreach (IFileInfo pluginDirectory in fileProvider.GetDirectoryContents(path)) + { + // Ideally there shouldn't be any files, but we'd better check to be sure + if (!pluginDirectory.IsDirectory) + { + continue; + } + + // Iterate through the sub directories of each plugin folder + foreach (IFileInfo subDir1 in fileProvider.GetDirectoryContents($"{path}/{pluginDirectory.Name}")) + { + // Skip files again + if (!subDir1.IsDirectory) + { + continue; + } + + // Iterate through second level sub directories + foreach (IFileInfo subDir2 in fileProvider.GetDirectoryContents($"{path}/{pluginDirectory.Name}/{subDir1.Name}")) + { + // Skip files again + if (!subDir2.IsDirectory) + { + continue; + } + + // Does the directory match the plugin icons folder? (case insensitive for legacy support) + if (!$"/{subDir1.Name}/{subDir2.Name}".InvariantEquals(Constants.SystemDirectories.PluginIcons)) + { + continue; + } + + // Iterate though the files of the second level sub directory. This should be where the SVG files are located :D + foreach (IFileInfo file in fileProvider.GetDirectoryContents($"{path}/{pluginDirectory.Name}/{subDir1.Name}/{subDir2.Name}")) + { + if (file.Name.InvariantEndsWith(".svg")) + { + yield return new FileInfo(file.PhysicalPath); + } + } + } + } + } + } + private IReadOnlyDictionary? GetIconDictionary() => _cache.GetCacheItem( $"{typeof(IconService).FullName}.{nameof(GetIconDictionary)}", () => GetAllIconsFiles()