Skip to content

Commit 4a54215

Browse files
Zeegaankjac
andauthored
V13: Add rcl files to static files tree (#17671)
* Refactor to use IWebhostEnvironment for wwwroot files. * Obsolete ctor * Add ActivatorUtiiliesConstructor * Refactor logic to include folders * Fix so we can see files in wwwroot/App_Plugins * Cosmetic: Use invariant comparison for the "umbraco" folder". --------- Co-authored-by: kjac <[email protected]>
1 parent c96dc7e commit 4a54215

File tree

1 file changed

+114
-26
lines changed

1 file changed

+114
-26
lines changed
Lines changed: 114 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
using System.Net;
2+
using Microsoft.AspNetCore.Hosting;
23
using Microsoft.AspNetCore.Http;
34
using Microsoft.AspNetCore.Mvc;
5+
using Microsoft.Extensions.DependencyInjection;
6+
using Microsoft.Extensions.FileProviders;
47
using Umbraco.Cms.Core;
8+
using Umbraco.Cms.Core.DependencyInjection;
59
using Umbraco.Cms.Core.Events;
610
using Umbraco.Cms.Core.IO;
711
using Umbraco.Cms.Core.Services;
@@ -17,68 +21,152 @@ public class StaticFilesTreeController : TreeController
1721
private const string Webroot = "wwwroot";
1822
private readonly IFileSystem _fileSystem;
1923
private readonly IMenuItemCollectionFactory _menuItemCollectionFactory;
24+
private readonly IWebHostEnvironment _webHostEnvironment;
2025

26+
[ActivatorUtilitiesConstructor]
2127
public StaticFilesTreeController(
2228
ILocalizedTextService localizedTextService,
2329
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
2430
IEventAggregator eventAggregator,
2531
IPhysicalFileSystem fileSystem,
26-
IMenuItemCollectionFactory menuItemCollectionFactory)
32+
IMenuItemCollectionFactory menuItemCollectionFactory,
33+
IWebHostEnvironment webHostEnvironment)
2734
: base(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator)
2835
{
2936
_fileSystem = fileSystem;
3037
_menuItemCollectionFactory = menuItemCollectionFactory;
38+
_webHostEnvironment = webHostEnvironment;
39+
}
40+
41+
[Obsolete("Obsolete, use ctor that takes an IWebHostEnvironment, will be removed in future versions.")]
42+
public StaticFilesTreeController(
43+
ILocalizedTextService localizedTextService,
44+
UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection,
45+
IEventAggregator eventAggregator,
46+
IPhysicalFileSystem fileSystem,
47+
IMenuItemCollectionFactory menuItemCollectionFactory)
48+
: this(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator, fileSystem, menuItemCollectionFactory, StaticServiceProvider.Instance.GetRequiredService<IWebHostEnvironment>())
49+
{
3150
}
3251

3352
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
3453
{
3554
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.RootString
3655
? WebUtility.UrlDecode(id).TrimStart("/")
37-
: "";
56+
: string.Empty;
3857

3958
var nodes = new TreeNodeCollection();
40-
IEnumerable<string> directories = _fileSystem.GetDirectories(path);
4159

42-
foreach (var directory in directories)
60+
// Add App_Plugins && wwwroot folder if path is empty, as we are only returning root folders.
61+
if (path == string.Empty)
4362
{
44-
// We don't want any other directories under the root node other than the ones serving static files - App_Plugins and wwwroot
45-
if (id == Constants.System.RootString && directory != AppPlugins && directory != Webroot)
63+
AddRootFolder(AppPlugins, queryStrings, nodes);
64+
AddRootFolder(Webroot, queryStrings, nodes);
65+
}
66+
else
67+
{
68+
if (path.StartsWith(Webroot, StringComparison.OrdinalIgnoreCase))
69+
{
70+
AddWebRootFiles(path, queryStrings, nodes);
71+
}
72+
else if (path.StartsWith(AppPlugins, StringComparison.OrdinalIgnoreCase))
4673
{
47-
continue;
74+
AddPhysicalFiles(path, queryStrings, nodes);
4875
}
76+
}
4977

50-
var hasChildren = _fileSystem.GetFiles(directory).Any() || _fileSystem.GetDirectories(directory).Any();
78+
return nodes;
79+
}
5180

52-
var name = Path.GetFileName(directory);
53-
TreeNode? node = CreateTreeNode(WebUtility.UrlEncode(directory), path, queryStrings, name,
54-
Constants.Icons.Folder, hasChildren);
81+
// We don't have any menu item options (such as create/delete/reload) & only use the root node to load a custom UI
82+
protected override ActionResult<MenuItemCollection> GetMenuForNode(string id, FormCollection queryStrings) =>
83+
_menuItemCollectionFactory.Create();
5584

56-
if (node != null)
57-
{
58-
nodes.Add(node);
59-
}
85+
private void AddRootFolder(string directory, FormCollection queryStrings, TreeNodeCollection nodes)
86+
{
87+
if (_fileSystem.DirectoryExists(directory) is false)
88+
{
89+
return;
6090
}
6191

62-
// Only get the files inside App_Plugins and wwwroot
92+
var hasChildren = _fileSystem.GetFiles(directory).Any() || _fileSystem.GetDirectories(directory).Any();
93+
94+
var name = Path.GetFileName(directory);
95+
TreeNode node = CreateTreeNode(WebUtility.UrlEncode(directory), "", queryStrings, name, Constants.Icons.Folder, hasChildren);
96+
nodes.Add(node);
97+
}
98+
99+
private void AddPhysicalFiles(string path, FormCollection queryStrings, TreeNodeCollection nodes)
100+
{
63101
IEnumerable<string> files = _fileSystem.GetFiles(path)
64102
.Where(x => x.StartsWith(AppPlugins) || x.StartsWith(Webroot));
65103

66104
foreach (var file in files)
67105
{
68106
var name = Path.GetFileName(file);
69-
TreeNode? node = CreateTreeNode(WebUtility.UrlEncode(file), path, queryStrings, name,
70-
Constants.Icons.DefaultIcon, false);
107+
TreeNode node = CreateTreeNode(WebUtility.UrlEncode(file), path, queryStrings, name, Constants.Icons.DefaultIcon, false);
108+
nodes.Add(node);
109+
}
110+
111+
IEnumerable<string> directories = _fileSystem.GetDirectories(path);
71112

72-
if (node != null)
113+
foreach (var directory in directories)
114+
{
115+
var hasChildren = _fileSystem.GetFiles(directory).Any() || _fileSystem.GetDirectories(directory).Any();
116+
var name = Path.GetFileName(directory);
117+
TreeNode node = CreateTreeNode(WebUtility.UrlEncode(directory), path, queryStrings, name, Constants.Icons.Folder, hasChildren);
118+
nodes.Add(node);
119+
}
120+
}
121+
122+
private void AddWebRootFiles(string path, FormCollection queryStrings, TreeNodeCollection nodes)
123+
{
124+
var calculatedPath = path.TrimStart(Webroot);
125+
IDirectoryContents files = _webHostEnvironment.WebRootFileProvider.GetDirectoryContents(calculatedPath);
126+
foreach (IFileInfo file in files.OrderByDescending(x => x.IsDirectory))
127+
{
128+
// This logic looks a little wierd, but because the WebrootFileProvider can actually detect
129+
// our files from App_Plugins, we have to manually exclude them, luckily they are always physical files
130+
// so we can just check if the files are in there, and then exclude them.
131+
bool isPhysicalFile = file.PhysicalPath is not null;
132+
if (isPhysicalFile)
73133
{
74-
nodes.Add(node);
134+
if (file.PhysicalPath!.StartsWith(_webHostEnvironment.ContentRootPath + $"\\{AppPlugins}", StringComparison.OrdinalIgnoreCase))
135+
{
136+
continue;
137+
}
75138
}
76-
}
77139

78-
return nodes;
79-
}
140+
TreeNode? node;
141+
if (file.IsDirectory)
142+
{
143+
// We don't want to include the umbraco folder, so exclude it.
144+
if (calculatedPath == string.Empty && "umbraco".InvariantEquals(file.Name))
145+
{
146+
continue;
147+
}
80148

81-
// We don't have any menu item options (such as create/delete/reload) & only use the root node to load a custom UI
82-
protected override ActionResult<MenuItemCollection> GetMenuForNode(string id, FormCollection queryStrings) =>
83-
_menuItemCollectionFactory.Create();
149+
bool hasChildren;
150+
151+
if (isPhysicalFile)
152+
{
153+
var calculatedFilePaths = _webHostEnvironment.WebRootPath + calculatedPath;
154+
hasChildren = _fileSystem.GetFiles(calculatedFilePaths).Any() || _fileSystem.GetDirectories(calculatedFilePaths).Any();
155+
}
156+
else
157+
{
158+
IDirectoryContents childFiles = _webHostEnvironment.WebRootFileProvider.GetDirectoryContents(calculatedPath + $"/{file.Name}");
159+
hasChildren = childFiles.Any();
160+
}
161+
162+
node = CreateTreeNode(WebUtility.UrlEncode(string.Join("/", path, file.Name)), path, queryStrings, file.Name, Constants.Icons.Folder, hasChildren);
163+
}
164+
else
165+
{
166+
node = CreateTreeNode(WebUtility.UrlEncode(string.Join("/", path, file.Name)), path, queryStrings, file.Name, Constants.Icons.DefaultIcon, false);
167+
}
168+
169+
nodes.Add(node);
170+
}
171+
}
84172
}

0 commit comments

Comments
 (0)