-
-
Notifications
You must be signed in to change notification settings - Fork 72
/
UmbracoContentDataListSource.cs
117 lines (97 loc) · 4.93 KB
/
UmbracoContentDataListSource.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
/* Copyright © 2020 Lee Kelleher.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Core.Xml;
using Umbraco.Web;
using UmbConstants = Umbraco.Core.Constants;
namespace Umbraco.Community.Contentment.DataEditors
{
public sealed class UmbracoContentDataListSource : IDataListSource, IDataListSourceValueConverter
{
private readonly IContentTypeService _contentTypeService;
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
public UmbracoContentDataListSource(IContentTypeService contentTypeService, IUmbracoContextAccessor umbracoContextAccessor)
{
_contentTypeService = contentTypeService;
_umbracoContextAccessor = umbracoContextAccessor;
}
public string Name => "Umbraco Content";
public string Description => "Select Umbraco content to use its children as a data source.";
public string Icon => "icon-umbraco";
public OverlaySize OverlaySize => OverlaySize.Small;
public IEnumerable<ConfigurationField> Fields => new ConfigurationField[]
{
new ConfigurationField
{
Key = "parentNode",
Name = "Parent node",
Description = "Set a parent node to use its child nodes as the data source items.",
View = ContentPickerDataEditor.DataEditorSourceViewPath,
}
};
public Dictionary<string, object> DefaultValues => default;
public IEnumerable<DataListItem> GetItems(Dictionary<string, object> config)
{
var preview = true;
var parentNode = config.GetValueAs("parentNode", string.Empty);
var startNode = default(IPublishedContent);
if (parentNode.InvariantStartsWith("umb://document/") == false)
{
var nodeContextId = default(int?);
var umbracoContext = _umbracoContextAccessor.UmbracoContext;
// NOTE: First we check for "id" (if on a content page), then "parentId" (if editing an element).
if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("id"), out var currentId) == true)
{
nodeContextId = currentId;
}
else if (int.TryParse(umbracoContext.HttpContext.Request.QueryString.Get("parentId"), out var parentId) == true)
{
nodeContextId = parentId;
}
if (nodeContextId == -20)
{
// TODO: [LK:2020-08-17] If the ID = -20, then we can assume that it's come from Nested Content. What to do?
}
IEnumerable<string> getPath(int id) => umbracoContext.Content.GetById(preview, id)?.Path.ToDelimitedList().Reverse();
bool publishedContentExists(int id) => umbracoContext.Content.GetById(preview, id) != null;
var parsed = UmbracoXPathPathSyntaxParser.ParseXPathQuery(parentNode, nodeContextId, getPath, publishedContentExists);
if (string.IsNullOrWhiteSpace(parsed) == false && parsed.StartsWith("$") == false)
{
startNode = umbracoContext.Content.GetSingleByXPath(preview, parsed);
}
}
else if (GuidUdi.TryParse(parentNode, out var udi) == true && udi.Guid != Guid.Empty)
{
startNode = _umbracoContextAccessor.UmbracoContext.Content.GetById(preview, udi.Guid);
}
if (startNode != null)
{
return startNode.Children.Select(x => new DataListItem
{
// TODO: [LK:2020-12-03] If multi-lingual is enabled, should the `.Name` take the culture into account?
Name = x.Name,
Value = Udi.Create(UmbConstants.UdiEntityType.Document, x.Key).ToString(),
Icon = ContentTypeCacheHelper.TryGetIcon(x.ContentType.Alias, out var icon, _contentTypeService) == true ? icon : UmbConstants.Icons.Content,
Description = x.TemplateId > 0 ? x.Url : string.Empty,
Disabled = x.IsPublished() == false,
});
}
return Enumerable.Empty<DataListItem>();
}
public Type GetValueType(Dictionary<string, object> config) => typeof(IPublishedContent);
public object ConvertValue(Type type, string value)
{
return Udi.TryParse(value, out var udi) == true
? _umbracoContextAccessor.UmbracoContext.Content.GetById(udi)
: default;
}
}
}