FileSystemTreeController compatibility
This commit is contained in:
@@ -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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
128
src/Umbraco.Web/Trees/FileSystemTreeController2.cs
Normal file
128
src/Umbraco.Web/Trees/FileSystemTreeController2.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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" />
|
||||||
|
|||||||
Reference in New Issue
Block a user