Files
Umbraco-CMS/src/Umbraco.Web/Trees/FileSystemTreeController.cs

165 lines
6.1 KiB
C#
Raw Normal View History

2014-05-09 12:23:59 +02:00
using System;
using System.IO;
using System.Linq;
using System.Net.Http.Formatting;
2017-05-12 14:49:44 +02:00
using System.Web;
using Umbraco.Core;
2014-05-09 12:23:59 +02:00
using Umbraco.Core.IO;
using Umbraco.Web.Actions;
2014-05-09 12:23:59 +02:00
using Umbraco.Web.Models.Trees;
using Constants = Umbraco.Core.Constants;
2014-05-09 12:23:59 +02:00
namespace Umbraco.Web.Trees
{
public abstract class FileSystemTreeController : TreeController
{
2017-05-12 14:49:44 +02:00
protected abstract IFileSystem FileSystem { get; }
protected abstract string[] Extensions { get; }
protected abstract string FileIcon { get; }
2014-05-09 12:23:59 +02:00
/// <summary>
/// Inheritors can override this method to modify the file node that is created.
/// </summary>
2018-05-01 00:35:49 +10:00
/// <param name="treeNode"></param>
protected virtual void OnRenderFileNode(ref TreeNode treeNode) { }
2014-05-09 12:23:59 +02:00
/// <summary>
/// Inheritors can override this method to modify the folder node that is created.
/// </summary>
2018-05-01 00:35:49 +10:00
/// <param name="treeNode"></param>
protected virtual void OnRenderFolderNode(ref TreeNode treeNode) {
// TODO: This isn't the best way to ensure a noop process for clicking a node but it works for now.
treeNode.AdditionalData["jsClickCallback"] = "javascript:void(0);";
}
2014-05-09 12:23:59 +02:00
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
2014-05-09 12:23:59 +02:00
{
2019-11-05 12:54:22 +01:00
var path = string.IsNullOrEmpty(id) == false && id != ConstantsCore.System.RootString
2017-05-12 14:49:44 +02:00
? HttpUtility.UrlDecode(id).TrimStart("/")
: "";
2014-05-09 12:23:59 +02:00
2017-05-12 14:49:44 +02:00
var directories = FileSystem.GetDirectories(path);
2018-05-01 00:35:49 +10:00
var nodes = new TreeNodeCollection();
2017-05-12 14:49:44 +02:00
foreach (var directory in directories)
2014-05-09 12:23:59 +02:00
{
2017-05-12 14:49:44 +02:00
var hasChildren = FileSystem.GetFiles(directory).Any() || FileSystem.GetDirectories(directory).Any();
2014-05-09 12:23:59 +02:00
2017-05-12 14:49:44 +02:00
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);
2014-05-09 12:23:59 +02:00
}
2018-05-01 00:35:49 +10:00
//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
2017-05-12 14:49:44 +02:00
var files = FileSystem.GetFiles(path).Where(x =>
{
var extension = Path.GetExtension(x);
if (Extensions.Contains("*"))
return true;
2019-11-05 12:54:22 +01:00
2017-05-12 14:49:44 +02:00
return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
});
2014-05-09 12:23:59 +02:00
2017-05-12 14:49:44 +02:00
foreach (var file in files)
2014-05-09 12:23:59 +02:00
{
2017-05-12 14:49:44 +02:00
var withoutExt = Path.GetFileNameWithoutExtension(file);
2018-05-01 00:35:49 +10:00
if (withoutExt.IsNullOrWhiteSpace()) continue;
2017-05-12 14:49:44 +02:00
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);
2014-05-09 12:23:59 +02:00
}
return nodes;
}
protected override TreeNode CreateRootNode(FormDataCollection queryStrings)
{
var root = base.CreateRootNode(queryStrings);
//check if there are any children
2019-11-05 12:54:22 +01:00
root.HasChildren = GetTreeNodes(ConstantsCore.System.RootString, queryStrings).Any();
return root;
}
2018-05-01 00:35:49 +10:00
protected virtual MenuItemCollection GetMenuForRootNode(FormDataCollection queryStrings)
{
2018-05-01 00:35:49 +10:00
var menu = new MenuItemCollection();
//set the default to create
menu.DefaultMenuAlias = ActionNew.ActionAlias;
2018-05-01 00:35:49 +10:00
//create action
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
2018-05-01 00:35:49 +10:00
//refresh action
menu.Items.Add(new RefreshNode(Services.TextService, true));
2018-05-01 00:35:49 +10:00
return menu;
}
2018-05-01 00:35:49 +10:00
protected virtual MenuItemCollection GetMenuForFolder(string path, FormDataCollection queryStrings)
{
var menu = new MenuItemCollection();
2018-05-01 00:35:49 +10:00
//set the default to create
menu.DefaultMenuAlias = ActionNew.ActionAlias;
2018-05-01 00:35:49 +10:00
//create action
menu.Items.Add<ActionNew>(Services.TextService, opensDialog: true);
2018-05-01 00:35:49 +10:00
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)
2018-03-27 16:18:51 +02:00
{
2018-05-01 00:35:49 +10:00
//delete action
menu.Items.Add<ActionDelete>(Services.TextService, true, opensDialog: true);
2018-03-27 16:18:51 +02:00
}
2014-05-09 12:23:59 +02:00
2018-05-01 00:35:49 +10:00
//refresh action
menu.Items.Add(new RefreshNode(Services.TextService, true));
2014-05-09 12:23:59 +02:00
2018-03-27 16:18:51 +02:00
return menu;
}
2018-05-01 00:35:49 +10:00
protected virtual MenuItemCollection GetMenuForFile(string path, FormDataCollection queryStrings)
2018-03-27 16:18:51 +02:00
{
2018-05-01 00:35:49 +10:00
var menu = new MenuItemCollection();
2017-05-12 14:49:44 +02:00
2018-05-01 00:35:49 +10:00
//if it's not a directory then we only allow to delete the item
menu.Items.Add<ActionDelete>(Services.TextService, opensDialog: true);
2018-03-27 16:18:51 +02:00
2018-05-01 00:35:49 +10:00
return menu;
2018-03-27 16:18:51 +02:00
}
2018-05-01 00:35:49 +10:00
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
2018-03-27 16:18:51 +02:00
{
2018-05-01 00:35:49 +10:00
//if root node no need to visit the filesystem so lets just create the menu and return it
2019-11-05 12:54:22 +01:00
if (id == ConstantsCore.System.RootString)
2017-05-12 14:49:44 +02:00
{
2018-05-01 00:35:49 +10:00
return GetMenuForRootNode(queryStrings);
2014-05-09 12:23:59 +02:00
}
2018-05-01 00:35:49 +10:00
var menu = new MenuItemCollection();
2019-11-05 12:54:22 +01:00
var path = string.IsNullOrEmpty(id) == false && id != ConstantsCore.System.RootString
2018-05-01 00:35:49 +10:00
? HttpUtility.UrlDecode(id).TrimStart("/")
: "";
2018-03-27 16:18:51 +02:00
2018-05-01 00:35:49 +10:00
var isFile = FileSystem.FileExists(path);
var isDirectory = FileSystem.DirectoryExists(path);
2018-05-01 00:35:49 +10:00
if (isDirectory)
{
return GetMenuForFolder(path, queryStrings);
}
2018-05-01 00:35:49 +10:00
return isFile ? GetMenuForFile(path, queryStrings) : menu;
}
2014-05-09 12:23:59 +02:00
}
}