2014-05-09 12:23:59 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
2016-03-30 16:07:45 +02:00
|
|
|
|
using System.Net.Http.Formatting;
|
2017-05-12 14:49:44 +02:00
|
|
|
|
using System.Web;
|
2016-03-30 16:07:45 +02:00
|
|
|
|
using Umbraco.Core;
|
2014-05-09 12:23:59 +02:00
|
|
|
|
using Umbraco.Core.IO;
|
2016-03-30 16:07:45 +02:00
|
|
|
|
using Umbraco.Core.Services;
|
2014-05-09 12:23:59 +02:00
|
|
|
|
using Umbraco.Web.Models.Trees;
|
2016-03-30 16:07:45 +02:00
|
|
|
|
using Umbraco.Web._Legacy.Actions;
|
|
|
|
|
|
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; }
|
2016-03-30 16:07:45 +02:00
|
|
|
|
protected abstract bool EnableCreateOnFolder { get; }
|
2014-05-09 12:23:59 +02:00
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// Inheritors can override this method to modify the file node that is created.
|
|
|
|
|
|
/// </summary>
|
2017-05-12 14:49:44 +02:00
|
|
|
|
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>
|
2017-05-12 14:49:44 +02:00
|
|
|
|
protected virtual void OnRenderFolderNode(ref TreeNode treeNode)
|
|
|
|
|
|
{ }
|
2014-05-09 12:23:59 +02:00
|
|
|
|
|
2016-03-30 16:07:45 +02:00
|
|
|
|
protected override TreeNodeCollection GetTreeNodes(string id, FormDataCollection queryStrings)
|
2014-05-09 12:23:59 +02:00
|
|
|
|
{
|
2016-03-30 16:07:45 +02:00
|
|
|
|
var nodes = new TreeNodeCollection();
|
|
|
|
|
|
|
2017-05-12 14:49:44 +02:00
|
|
|
|
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
|
|
|
|
|
|
? 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);
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
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)
|
2016-03-30 16:07:45 +02:00
|
|
|
|
nodes.Add(node);
|
2014-05-09 12:23:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-05-12 14:49:44 +02:00
|
|
|
|
var files = FileSystem.GetFiles(path).Where(x =>
|
|
|
|
|
|
{
|
|
|
|
|
|
var extension = Path.GetExtension(x);
|
|
|
|
|
|
return extension != null && Extensions.Contains(extension.Trim('.'), StringComparer.InvariantCultureIgnoreCase);
|
|
|
|
|
|
|
|
|
|
|
|
// fixme - should we filter out hidden files? but then, FileSystem does not support attributes!
|
|
|
|
|
|
});
|
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);
|
|
|
|
|
|
if (string.IsNullOrWhiteSpace(withoutExt)) continue;
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
2017-05-12 14:49:44 +02:00
|
|
|
|
var name = Path.GetFileName(file);
|
|
|
|
|
|
var node = CreateTreeNode(HttpUtility.UrlEncode(file), path, queryStrings, name, FileIcon, false);
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
2017-05-12 14:49:44 +02:00
|
|
|
|
OnRenderFileNode(ref node);
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
2017-05-12 14:49:44 +02:00
|
|
|
|
if (node != null)
|
|
|
|
|
|
nodes.Add(node);
|
2014-05-09 12:23:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2016-03-30 16:07:45 +02:00
|
|
|
|
return nodes;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual TreeNodeCollection GetTreeNodesForFile(string path, string id, FormDataCollection queryStrings)
|
|
|
|
|
|
{
|
|
|
|
|
|
return new TreeNodeCollection();
|
|
|
|
|
|
}
|
2016-09-01 19:06:08 +02:00
|
|
|
|
|
2016-03-30 16:07:45 +02:00
|
|
|
|
protected override MenuItemCollection GetMenuForNode(string id, FormDataCollection queryStrings)
|
|
|
|
|
|
{
|
|
|
|
|
|
var menu = new MenuItemCollection();
|
2016-09-01 19:06:08 +02:00
|
|
|
|
|
2016-03-30 16:07:45 +02:00
|
|
|
|
OnBeforeRenderMenu(menu, id, queryStrings);
|
|
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
// if root node no need to visit the filesystem so lets just create the menu and return it
|
2016-03-30 16:07:45 +02:00
|
|
|
|
if (id == Constants.System.Root.ToInvariantString())
|
2014-05-09 12:23:59 +02:00
|
|
|
|
{
|
2018-03-27 16:18:51 +02:00
|
|
|
|
GetMenuForRootNode(menu, queryStrings);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var path = string.IsNullOrEmpty(id) == false && id != Constants.System.Root.ToInvariantString()
|
|
|
|
|
|
? HttpUtility.UrlDecode(id).TrimStart("/")
|
|
|
|
|
|
: "";
|
|
|
|
|
|
var isFile = FileSystem.FileExists(path);
|
|
|
|
|
|
var isDirectory = FileSystem.DirectoryExists(path);
|
|
|
|
|
|
|
|
|
|
|
|
if (isDirectory)
|
|
|
|
|
|
GetMenuForFolder(menu, path, id, queryStrings);
|
|
|
|
|
|
else if (isFile)
|
|
|
|
|
|
GetMenuForFile(menu, path, id, queryStrings);
|
|
|
|
|
|
}
|
2014-05-09 12:23:59 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
OnAfterRenderMenu(menu, id, queryStrings);
|
2014-05-09 12:23:59 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
return menu;
|
|
|
|
|
|
}
|
2016-09-01 19:06:08 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
protected virtual void GetMenuForRootNode(MenuItemCollection menu, FormDataCollection queryStrings)
|
|
|
|
|
|
{
|
|
|
|
|
|
// default create
|
|
|
|
|
|
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
2017-05-12 14:49:44 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
// create action
|
|
|
|
|
|
//Since we haven't implemented anything for file systems in angular, this needs to be converted to
|
|
|
|
|
|
//use the legacy format
|
|
|
|
|
|
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
|
|
|
|
|
.ConvertLegacyFileSystemMenuItem("", "init" + TreeAlias, queryStrings.GetValue<string>("application"));
|
|
|
|
|
|
|
|
|
|
|
|
// refresh action
|
|
|
|
|
|
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual void GetMenuForFolder(MenuItemCollection menu, string path, string id, FormDataCollection queryStrings)
|
|
|
|
|
|
{
|
|
|
|
|
|
if (EnableCreateOnFolder)
|
2017-05-12 14:49:44 +02:00
|
|
|
|
{
|
2018-03-27 16:18:51 +02:00
|
|
|
|
// default create
|
|
|
|
|
|
menu.DefaultMenuAlias = ActionNew.Instance.Alias;
|
|
|
|
|
|
|
|
|
|
|
|
// create action
|
|
|
|
|
|
//Since we haven't implemented anything for file systems in angular, this needs to be converted to
|
|
|
|
|
|
//use the legacy format
|
|
|
|
|
|
menu.Items.Add<ActionNew>(Services.TextService.Localize("actions", ActionNew.Instance.Alias))
|
|
|
|
|
|
.ConvertLegacyFileSystemMenuItem(id, TreeAlias + "Folder", queryStrings.GetValue<string>("application"));
|
2014-05-09 12:23:59 +02:00
|
|
|
|
}
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
// delete action
|
|
|
|
|
|
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true)
|
|
|
|
|
|
.ConvertLegacyFileSystemMenuItem(id, TreeAlias + "Folder", queryStrings.GetValue<string>("application"));
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
2018-03-27 16:18:51 +02:00
|
|
|
|
// refresh action
|
|
|
|
|
|
menu.Items.Add<RefreshNode, ActionRefresh>(Services.TextService.Localize("actions", ActionRefresh.Instance.Alias), true);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual void GetMenuForFile(MenuItemCollection menu, string path, string id, FormDataCollection queryStrings)
|
|
|
|
|
|
{
|
|
|
|
|
|
// delete action
|
|
|
|
|
|
menu.Items.Add<ActionDelete>(Services.TextService.Localize("actions", ActionDelete.Instance.Alias), true)
|
|
|
|
|
|
.ConvertLegacyFileSystemMenuItem(id, TreeAlias, queryStrings.GetValue<string>("application"));
|
2016-03-30 16:07:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
protected virtual void OnBeforeRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings)
|
2017-05-12 14:49:44 +02:00
|
|
|
|
{ }
|
2016-03-30 16:07:45 +02:00
|
|
|
|
|
|
|
|
|
|
protected virtual void OnAfterRenderMenu(MenuItemCollection menu, string id, FormDataCollection queryStrings)
|
2017-05-12 14:49:44 +02:00
|
|
|
|
{ }
|
2014-05-09 12:23:59 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|