FileSystemTreeController compatibility

This commit is contained in:
Stephan
2017-06-01 17:24:10 +02:00
parent 92f609ff71
commit 290f34f034
6 changed files with 181 additions and 90 deletions

View File

@@ -1,70 +1,84 @@
using System; using System;
using System.IO; using System.IO;
using System.Linq;
using System.Net.Http.Formatting;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.IO; using Umbraco.Core.IO;
using Umbraco.Core.Services;
using Umbraco.Web.Models.Trees; using Umbraco.Web.Models.Trees;
using System.Web;
namespace Umbraco.Web.Trees namespace Umbraco.Web.Trees
{ {
public abstract class FileSystemTreeController : TreeController public abstract class FileSystemTreeController : TreeController
{ {
protected abstract IFileSystem2 FileSystem { get; } protected abstract string FilePath { get; }
protected abstract string[] Extensions { get; } protected abstract string FileSearchPattern { get; }
protected abstract string FileIcon { get; }
/// <summary> /// <summary>
/// Inheritors can override this method to modify the file node that is created. /// Inheritors can override this method to modify the file node that is created.
/// </summary> /// </summary>
/// <param name="treeNode"></param> /// <param name="xNode"></param>
protected virtual void OnRenderFileNode(ref TreeNode treeNode) { } protected virtual void OnRenderFileNode(ref TreeNode treeNode) { }
/// <summary> /// <summary>
/// Inheritors can override this method to modify the folder node that is created. /// Inheritors can override this method to modify the folder node that is created.
/// </summary> /// </summary>
/// <param name="treeNode"></param> /// <param name="xNode"></param>
protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { } protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { }
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings) protected override Models.Trees.TreeNodeCollection GetTreeNodes(string id, System.Net.Http.Formatting.FormDataCollection queryStrings)
{ {
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString() string orgPath = "";
? HttpUtility.UrlDecode(id).TrimStart("/") string path = "";
: ""; if (!string.IsNullOrEmpty(id) && id != "-1")
{
orgPath = id;
path = IOHelper.MapPath(FilePath + "/" + orgPath);
orgPath += "/";
}
else
{
path = IOHelper.MapPath(FilePath);
}
var directories = FileSystem.GetDirectories(path); DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectoryInfo[] dirInfos = dirInfo.GetDirectories();
var nodes = new TreeNodeCollection(); var nodes = new TreeNodeCollection();
foreach (var directory in directories) foreach (DirectoryInfo dir in dirInfos)
{ {
var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any(); if ((dir.Attributes & FileAttributes.Hidden) == 0)
{
var HasChildren = dir.GetFiles().Length > 0 || dir.GetDirectories().Length > 0;
var node = CreateTreeNode(orgPath + dir.Name, orgPath, queryStrings, dir.Name, "icon-folder", HasChildren);
var name = Path.GetFileName(directory); OnRenderFolderNode(ref node);
var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren); if (node != null)
OnRenderFolderNode(ref node); nodes.Add(node);
if(node != null) }
nodes.Add(node);
} }
//this is a hack to enable file system tree to support multiple file extension look-up //this is a hack to enable file system tree to support multiple file extension look-up
//so the pattern both support *.* *.xml and xml,js,vb for lookups //so the pattern both support *.* *.xml and xml,js,vb for lookups
var files = FileSystem.GetFiles(path).Where(x => string[] allowedExtensions = new string[0];
{ bool filterByMultipleExtensions = FileSearchPattern.Contains(",");
var extension = Path.GetExtension(x); FileInfo[] fileInfo;
return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
});
foreach (var file in files) if (filterByMultipleExtensions)
{ {
var withoutExt = Path.GetFileNameWithoutExtension(file); fileInfo = dirInfo.GetFiles();
if (withoutExt.IsNullOrWhiteSpace() == false) allowedExtensions = FileSearchPattern.ToLower().Split(',');
}
else
fileInfo = dirInfo.GetFiles(FileSearchPattern);
foreach (FileInfo file in fileInfo)
{
if ((file.Attributes & FileAttributes.Hidden) == 0)
{ {
var name = Path.GetFileName(file); if (filterByMultipleExtensions && Array.IndexOf<string>(allowedExtensions, file.Extension.ToLower().Trim('.')) < 0)
var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false); continue;
var node = CreateTreeNode(orgPath + file.Name, orgPath, queryStrings, file.Name, "icon-file", false);
OnRenderFileNode(ref node); OnRenderFileNode(ref node);
if (node != null) if (node != null)
nodes.Add(node); nodes.Add(node);
} }
@@ -72,57 +86,5 @@ namespace Umbraco.Web.Trees
return nodes; return nodes;
} }
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
{
var menu = new MenuItemCollection();
//if root node no need to visit the filesystem so lets just create the menu and return it
if (id == Constants.System.Root.ToInvariantString())
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
//create action
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
//refresh action
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
return menu;
}
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
? System.Web.HttpUtility.UrlDecode(id).TrimStart("/")
: "";
var isFile = FileSystem.FileExists(path);
var isDirectory = FileSystem.DirectoryExists(path);
if (isDirectory)
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
//create action
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
//We can only delete folders if it doesn't have any children (folders or files)
if (hasChildren == false)
{
//delete action
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
}
//refresh action
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
}
else if (isFile)
{
//if it's not a directory then we only allow to delete the item
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
}
return menu;
}
} }
} }

View File

@@ -0,0 +1,128 @@
using System;
using System.IO;
using System.Linq;
using System.Net.Http.Formatting;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.IO;
using Umbraco.Core.Services;
using Umbraco.Web.Models.Trees;
using System.Web;
namespace Umbraco.Web.Trees
{
public abstract class FileSystemTreeController2 : TreeController
{
protected abstract IFileSystem2 FileSystem { get; }
protected abstract string[] Extensions { get; }
protected abstract string FileIcon { get; }
/// <summary>
/// Inheritors can override this method to modify the file node that is created.
/// </summary>
/// <param name="treeNode"></param>
protected virtual void OnRenderFileNode(ref TreeNode treeNode) { }
/// <summary>
/// Inheritors can override this method to modify the folder node that is created.
/// </summary>
/// <param name="treeNode"></param>
protected virtual void OnRenderFolderNode(ref TreeNode treeNode) { }
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
{
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
? HttpUtility.UrlDecode(id).TrimStart("/")
: "";
var directories = FileSystem.GetDirectories(path);
var nodes = new TreeNodeCollection();
foreach (var directory in directories)
{
var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any();
var name = Path.GetFileName(directory);
var node = CreateTreeNode(HttpUtility.UrlEncode(directory), path, queryStrings, name, "icon-folder", hasChildren);
OnRenderFolderNode(ref node);
if(node != null)
nodes.Add(node);
}
//this is a hack to enable file system tree to support multiple file extension look-up
//so the pattern both support *.* *.xml and xml,js,vb for lookups
var files = FileSystem.GetFiles(path).Where(x =>
{
var extension = Path.GetExtension(x);
return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
});
foreach (var file in files)
{
var withoutExt = Path.GetFileNameWithoutExtension(file);
if (withoutExt.IsNullOrWhiteSpace() == false)
{
var name = Path.GetFileName(file);
var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false);
OnRenderFileNode(ref node);
if (node != null)
nodes.Add(node);
}
}
return nodes;
}
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
{
var menu = new MenuItemCollection();
//if root node no need to visit the filesystem so lets just create the menu and return it
if (id == Constants.System.Root.ToInvariantString())
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
//create action
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
//refresh action
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
return menu;
}
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
? System.Web.HttpUtility.UrlDecode(id).TrimStart("/")
: "";
var isFile = FileSystem.FileExists(path);
var isDirectory = FileSystem.DirectoryExists(path);
if (isDirectory)
{
//set the default to create
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
//create action
menu.Items.Add<ActionNew>(Services.TextService.Localize(string.Format("actions/{0}", ActionNew.Instance.Alias)));
var hasChildren = FileSystem.GetFiles(path).Any() || FileSystem.GetDirectories(path).Any();
//We can only delete folders if it doesn't have any children (folders or files)
if (hasChildren == false)
{
//delete action
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)), true);
}
//refresh action
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize(string.Format("actions/{0}", ActionRefresh.Instance.Alias)), true);
}
else if (isFile)
{
//if it's not a directory then we only allow to delete the item
menu.Items.Add<ActionDelete>(Services.TextService.Localize(string.Format("actions/{0}", ActionDelete.Instance.Alias)));
}
return menu;
}
}
}

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees
/// Tree for displaying partial view macros in the developer app /// Tree for displaying partial view macros in the developer app
/// </summary> /// </summary>
[Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)] [Tree(Constants.Applications.Developer, "partialViewMacros", "Partial View Macro Files", sortOrder: 6)]
public class PartialViewMacrosTreeController : FileSystemTreeController public class PartialViewMacrosTreeController : FileSystemTreeController2
{ {
protected override IFileSystem2 FileSystem protected override IFileSystem2 FileSystem
{ {

View File

@@ -8,7 +8,7 @@ namespace Umbraco.Web.Trees
/// Tree for displaying partial views in the settings app /// Tree for displaying partial views in the settings app
/// </summary> /// </summary>
[Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)] [Tree(Constants.Applications.Settings, "partialViews", "Partial Views", sortOrder: 2)]
public class PartialViewsTreeController : FileSystemTreeController public class PartialViewsTreeController : FileSystemTreeController2
{ {
protected override IFileSystem2 FileSystem protected override IFileSystem2 FileSystem
{ {

View File

@@ -5,7 +5,7 @@ using Umbraco.Web.Models.Trees;
namespace Umbraco.Web.Trees namespace Umbraco.Web.Trees
{ {
[Tree(Constants.Applications.Settings, "scripts", "Scripts", sortOrder: 4)] [Tree(Constants.Applications.Settings, "scripts", "Scripts", sortOrder: 4)]
public class ScriptTreeController : FileSystemTreeController public class ScriptTreeController : FileSystemTreeController2
{ {
protected override IFileSystem2 FileSystem protected override IFileSystem2 FileSystem
{ {

View File

@@ -435,6 +435,7 @@
<Compile Include="Security\Identity\PreviewAuthenticationMiddleware.cs" /> <Compile Include="Security\Identity\PreviewAuthenticationMiddleware.cs" />
<Compile Include="SingletonHttpContextAccessor.cs" /> <Compile Include="SingletonHttpContextAccessor.cs" />
<Compile Include="Trees\ContentTypeTreeController.cs" /> <Compile Include="Trees\ContentTypeTreeController.cs" />
<Compile Include="Trees\FileSystemTreeController.cs" />
<Compile Include="Trees\PackagesTreeController.cs" /> <Compile Include="Trees\PackagesTreeController.cs" />
<Compile Include="Trees\MediaTypeTreeController.cs" /> <Compile Include="Trees\MediaTypeTreeController.cs" />
<Compile Include="Trees\MemberTypeTreeController.cs" /> <Compile Include="Trees\MemberTypeTreeController.cs" />
@@ -712,7 +713,7 @@
<Compile Include="TagQuery.cs" /> <Compile Include="TagQuery.cs" />
<Compile Include="Trees\CoreTreeAttribute.cs" /> <Compile Include="Trees\CoreTreeAttribute.cs" />
<Compile Include="Trees\DataTypeTreeController.cs" /> <Compile Include="Trees\DataTypeTreeController.cs" />
<Compile Include="Trees\FileSystemTreeController.cs" /> <Compile Include="Trees\FileSystemTreeController2.cs" />
<Compile Include="Trees\LanguageTreeController.cs" /> <Compile Include="Trees\LanguageTreeController.cs" />
<Compile Include="Trees\LegacyBaseTreeAttribute.cs" /> <Compile Include="Trees\LegacyBaseTreeAttribute.cs" />
<Compile Include="Trees\MemberTreeController.cs" /> <Compile Include="Trees\MemberTreeController.cs" />