Skip to content

Commit e4531bd

Browse files
Merge pull request #6 from umbraco/temp-deploy-373
Deploy-373 Adds 2 ValueConnectors for RelatedLinks datatype
2 parents ed74466 + c938e7a commit e4531bd

File tree

3 files changed

+216
-0
lines changed

3 files changed

+216
-0
lines changed

src/Umbraco.Deploy.Contrib.Connectors/Umbraco.Deploy.Contrib.Connectors.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@
238238
<Compile Include="Properties\VersionInfo.cs" />
239239
<Compile Include="ValueConnectors\ArchetypeValueConnector.cs" />
240240
<Compile Include="ValueConnectors\MultiUrlPickerValueConnector.cs" />
241+
<Compile Include="ValueConnectors\RelatedLinksValueConnector.cs" />
242+
<Compile Include="ValueConnectors\RelatedLinks2ValueConnector.cs" />
241243
<Compile Include="ValueConnectors\VortoValueConnector.cs" />
242244
<Compile Include="ValueConnectors\InnerContentConnector.cs" />
243245
<Compile Include="ValueConnectors\StackedContentConnector.cs" />
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using Newtonsoft.Json;
4+
using Umbraco.Core;
5+
using Umbraco.Core.Deploy;
6+
using Umbraco.Core.Models;
7+
8+
namespace Umbraco.Deploy.Contrib.Connectors.ValueConnectors
9+
{
10+
/*
11+
[
12+
{
13+
"caption": "Page A Internal Link",
14+
"link": "umb://document/a3e8d3e344a64be9871a54cae6b65008",
15+
"newWindow": false,
16+
"internal": "umb://document/a3e8d3e344a64be9871a54cae6b65008",
17+
"edit": false,
18+
"isInternal": true,
19+
"internalName": "Page A",
20+
"internalIcon": "icon-document",
21+
"type": "internal",
22+
"title": "Page A Internal Link"
23+
}
24+
]
25+
*/
26+
27+
/// <summary>
28+
/// Implements a value connector for the new related links editor (storing Udis).
29+
/// </summary>
30+
public class RelatedLinks2ValueConnector : IValueConnector
31+
{
32+
public string GetValue(Property property, ICollection<ArtifactDependency> dependencies)
33+
{
34+
35+
var value = property.Value as string;
36+
37+
if (string.IsNullOrWhiteSpace(value))
38+
return null;
39+
40+
if (value.DetectIsJson() == false)
41+
return null;
42+
43+
var relatedLinks = JsonConvert.DeserializeObject<IEnumerable<RelatedLinkUdiModel>>(value);
44+
45+
if (relatedLinks == null)
46+
return null;
47+
48+
//Loop over array of links (Some may be external) so we can skip those
49+
//For each internal link get the current UDI of the picked node add it to the list of dependencies
50+
foreach (var internalLink in relatedLinks.Where(x => x.IsInternal))
51+
{
52+
//As the page was picked we need to add it to collection of depenencies for this deployment
53+
dependencies.Add(new ArtifactDependency(internalLink.Link, false, ArtifactDependencyMode.Exist));
54+
}
55+
56+
//As this property editor already stores UDIs and not ints
57+
//We need to return the original JSON string as we have not modified or replaced the values
58+
return property.Value.ToString();
59+
}
60+
61+
62+
public void SetValue(IContentBase content, string alias, string value)
63+
{
64+
//Save the JSON on the env we are deploying to
65+
//We don't need to swap UDIs out back for int's so a simple setValue is all we need
66+
content.SetValue(alias, value);
67+
}
68+
69+
public virtual IEnumerable<string> PropertyEditorAliases => new[] { Constants.PropertyEditors.RelatedLinks2Alias };
70+
71+
/// <summary>
72+
/// This is a subset of the full JSON object
73+
/// As we only need to know if a link is internal & the value of the internal link UDI that was picked
74+
/// </summary>
75+
public class RelatedLinkUdiModel
76+
{
77+
[JsonProperty("internal")]
78+
public Udi Link { get; set; }
79+
80+
[JsonProperty("isInternal")]
81+
public bool IsInternal { get; set; }
82+
}
83+
}
84+
}
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Newtonsoft.Json;
5+
using Newtonsoft.Json.Linq;
6+
using Umbraco.Core;
7+
using Umbraco.Core.Deploy;
8+
using Umbraco.Core.Models;
9+
using Umbraco.Core.Services;
10+
11+
namespace Umbraco.Deploy.Contrib.Connectors.ValueConnectors
12+
{
13+
/*
14+
[
15+
{
16+
"caption": "Page B Internal Link made here",
17+
"link": 1059,
18+
"newWindow": false,
19+
"internal": 1059,
20+
"edit": false,
21+
"isInternal": true,
22+
"internalName": "Page B",
23+
"internalIcon": "icon-document",
24+
"type": "internal",
25+
"title": "Page B Internal Link made here"
26+
}
27+
]
28+
*/
29+
30+
/// <summary>
31+
/// Implements a value connector for the new related links editor (storing Udis).
32+
/// </summary>
33+
public class RelatedLinksValueConnector : IValueConnector
34+
{
35+
private readonly IEntityService _entityService;
36+
37+
public RelatedLinksValueConnector(IEntityService entityService)
38+
{
39+
if (entityService == null) throw new ArgumentNullException(nameof(entityService));
40+
_entityService = entityService;
41+
}
42+
43+
public string GetValue(Property property, ICollection<ArtifactDependency> dependencies)
44+
{
45+
var value = property.Value as string;
46+
47+
if (string.IsNullOrWhiteSpace(value))
48+
return null;
49+
50+
if (value.DetectIsJson() == false)
51+
return null;
52+
53+
var relatedLinks = JsonConvert.DeserializeObject<JArray>(value);
54+
55+
if (relatedLinks == null)
56+
return string.Empty;
57+
58+
foreach (var relatedLink in relatedLinks)
59+
{
60+
//Get the value from the JSON object
61+
var isInternal = Convert.ToBoolean(relatedLink["isInternal"]);
62+
63+
//We are only concerned about internal links
64+
if (!isInternal)
65+
continue;
66+
67+
var linkIntId = Convert.ToInt32(relatedLink["link"]);
68+
69+
//get the guid corresponding to the id
70+
//it *can* fail if eg the id points to a deleted content,
71+
//and then we use an empty guid
72+
var guidAttempt = _entityService.GetKeyForId(linkIntId, UmbracoObjectTypes.Document);
73+
if (guidAttempt.Success)
74+
{
75+
// replace the picked content id by the corresponding Udi as a dependancy
76+
var udi = new GuidUdi(Constants.UdiEntityType.Document, guidAttempt.Result);
77+
dependencies.Add(new ArtifactDependency(udi, false, ArtifactDependencyMode.Exist));
78+
79+
//Set the current relatedlink 'internal' & 'link' properties to UDIs & not int's
80+
relatedLink["link"] = udi.ToString();
81+
relatedLink["internal"] = udi.ToString();
82+
}
83+
}
84+
85+
//Serialise the new updated object with UDIs in it to JSON to transfer across the wire
86+
return JsonConvert.SerializeObject(relatedLinks);
87+
}
88+
89+
90+
public void SetValue(IContentBase content, string alias, string value)
91+
{
92+
if (string.IsNullOrWhiteSpace(value))
93+
{
94+
content.SetValue(alias, value);
95+
return;
96+
}
97+
98+
var relatedLinks = JsonConvert.DeserializeObject<JArray>(value);
99+
100+
foreach (var relatedLink in relatedLinks)
101+
{
102+
//Get the value from the JSON object
103+
var isInternal = Convert.ToBoolean(relatedLink["isInternal"]);
104+
105+
//We are only concerned about internal links
106+
if (!isInternal)
107+
continue;
108+
109+
//Get the UDI value in the JSON
110+
var pickedUdi = GuidUdi.Parse(relatedLink["link"].ToString());
111+
112+
//Lets use entitiy sevice to get the int ID for this item on the new environment
113+
//Get the Id corresponding to the Guid
114+
//it *should* succeed when deploying, due to dependencies management
115+
//nevertheless, assume it can fail, and then create an invalid localLink
116+
var idAttempt = _entityService.GetIdForKey(pickedUdi.Guid, UmbracoObjectTypes.Document);
117+
118+
//Update the JSON back to the int ids on this env
119+
relatedLink["link"] = idAttempt.Success ? idAttempt.Result : 0;
120+
relatedLink["internal"] = idAttempt.Success ? idAttempt.Result : 0;
121+
}
122+
123+
//Save the updated JSON with replaced UDIs for int IDs
124+
content.SetValue(alias, JsonConvert.SerializeObject(relatedLinks));
125+
}
126+
127+
public virtual IEnumerable<string> PropertyEditorAliases => new[] { Constants.PropertyEditors.RelatedLinksAlias };
128+
129+
}
130+
}

0 commit comments

Comments
 (0)