-
Notifications
You must be signed in to change notification settings - Fork 2.6k
/
MediaTypeTreeController.cs
152 lines (128 loc) · 6.8 KB
/
MediaTypeTreeController.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Actions;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Trees;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Trees;
using Umbraco.Cms.Infrastructure.Search;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Extensions;
using Constants = Umbraco.Cms.Core.Constants;
namespace Umbraco.Cms.Web.BackOffice.Trees
{
[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)]
[Tree(Constants.Applications.Settings, Constants.Trees.MediaTypes, SortOrder = 1, TreeGroup = Constants.Trees.Groups.Settings)]
[PluginController(Constants.Web.Mvc.BackOfficeTreeArea)]
[CoreTree]
public class MediaTypeTreeController : TreeController, ISearchableTree
{
private readonly UmbracoTreeSearcher _treeSearcher;
private readonly IMenuItemCollectionFactory _menuItemCollectionFactory;
private readonly IMediaTypeService _mediaTypeService;
private readonly IEntityService _entityService;
public MediaTypeTreeController(ILocalizedTextService localizedTextService, UmbracoApiControllerTypeCollection umbracoApiControllerTypeCollection, UmbracoTreeSearcher treeSearcher, IMenuItemCollectionFactory menuItemCollectionFactory, IMediaTypeService mediaTypeService, IEntityService entityService, IEventAggregator eventAggregator) : base(localizedTextService, umbracoApiControllerTypeCollection, eventAggregator)
{
_treeSearcher = treeSearcher;
_menuItemCollectionFactory = menuItemCollectionFactory;
_mediaTypeService = mediaTypeService;
_entityService = entityService;
}
protected override ActionResult<TreeNodeCollection> GetTreeNodes(string id, FormCollection queryStrings)
{
if (!int.TryParse(id, NumberStyles.Integer, CultureInfo.InvariantCulture, out var intId))
{
throw new InvalidOperationException("Id must be an integer");
}
var nodes = new TreeNodeCollection();
nodes.AddRange(
_entityService.GetChildren(intId, UmbracoObjectTypes.MediaTypeContainer)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
var node = CreateTreeNode(dt.Id.ToString(), id, queryStrings, dt.Name, Constants.Icons.Folder, dt.HasChildren, "");
node.Path = dt.Path;
node.NodeType = "container";
// TODO: This isn't the best way to ensure a no operation process for clicking a node but it works for now.
node.AdditionalData["jsClickCallback"] = "javascript:void(0);";
return node;
}));
// if the request is for folders only then just return
if (queryStrings["foldersonly"].ToString().IsNullOrWhiteSpace() == false && queryStrings["foldersonly"].ToString() == "1") return nodes;
var mediaTypes = _mediaTypeService.GetAll();
nodes.AddRange(
_entityService.GetChildren(intId, UmbracoObjectTypes.MediaType)
.OrderBy(entity => entity.Name)
.Select(dt =>
{
// since 7.4+ child type creation is enabled by a config option. It defaults to on, but can be disabled if we decide to.
// need this check to keep supporting sites where children have already been created.
var hasChildren = dt.HasChildren;
var mt = mediaTypes.FirstOrDefault(x => x.Id == dt.Id);
var node = CreateTreeNode(dt, Constants.ObjectTypes.MediaType, id, queryStrings, mt?.Icon ?? Constants.Icons.MediaType, hasChildren);
node.Path = dt.Path;
return node;
}));
return nodes;
}
protected override ActionResult<MenuItemCollection> GetMenuForNode(string id, FormCollection queryStrings)
{
var menu = _menuItemCollectionFactory.Create();
if (id == Constants.System.RootString)
{
// set the default to create
menu.DefaultMenuAlias = ActionNew.ActionAlias;
// root actions
menu.Items.Add<ActionNew>(LocalizedTextService, opensDialog: true);
menu.Items.Add(new RefreshNode(LocalizedTextService));
return menu;
}
var container = _entityService.Get(int.Parse(id, CultureInfo.InvariantCulture), UmbracoObjectTypes.MediaTypeContainer);
if (container != null)
{
// set the default to create
menu.DefaultMenuAlias = ActionNew.ActionAlias;
menu.Items.Add<ActionNew>(LocalizedTextService, opensDialog: true);
menu.Items.Add(new MenuItem("rename", LocalizedTextService.Localize("actions", "rename"))
{
Icon = "icon icon-edit"
});
if (container.HasChildren == false)
{
// can delete doc type
menu.Items.Add<ActionDelete>(LocalizedTextService, opensDialog: true);
}
menu.Items.Add(new RefreshNode(LocalizedTextService, true));
}
else
{
var ct = _mediaTypeService.Get(int.Parse(id, CultureInfo.InvariantCulture));
var parent = ct == null ? null : _mediaTypeService.Get(ct.ParentId);
menu.Items.Add<ActionNew>(LocalizedTextService, opensDialog: true);
// no move action if this is a child doc type
if (parent == null)
{
menu.Items.Add<ActionMove>(LocalizedTextService, true, opensDialog: true);
}
menu.Items.Add<ActionCopy>(LocalizedTextService, opensDialog: true);
if(ct?.IsSystemMediaType() == false)
{
menu.Items.Add<ActionDelete>(LocalizedTextService, opensDialog: true);
}
menu.Items.Add(new RefreshNode(LocalizedTextService, true));
}
return menu;
}
public IEnumerable<SearchResultEntity?> Search(string query, int pageSize, long pageIndex, out long totalFound, string? searchFrom = null)
=> _treeSearcher.EntitySearch(UmbracoObjectTypes.MediaType, query, pageSize, pageIndex, out totalFound, searchFrom);
}
}