Skip to content

Commit 21a1baa

Browse files
authored
Fixes DTGE connector to handle complex property editors such as nested content. (#49)
* Fixes DTGE connector to handle complex property editors such as nested content. * Handled necesssary conversion between string and JToken in converting to and from artifacts for nested content complex properties. * Ensured serialziation with none formatting. * Used string.Empty.
1 parent 7ef049f commit 21a1baa

File tree

2 files changed

+32
-101
lines changed

2 files changed

+32
-101
lines changed

src/Umbraco.Deploy.Contrib.Connectors/GridCellValueConnectors/DocTypeGridEditorCellValueConnector.cs

Lines changed: 21 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public string GetValue(GridValue.GridControl gridControl, ICollection<ArtifactDe
6666
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - PropertyTypeAlias - {propertyType.Alias}");
6767

6868
// test if there's a value for the given property
69-
if (IsValueNull(docTypeGridEditorContent, propertyType, out var value))
69+
if (!TryGetValue(docTypeGridEditorContent, propertyType, out var value))
7070
{
7171
continue;
7272
}
@@ -77,46 +77,21 @@ public string GetValue(GridValue.GridControl gridControl, ICollection<ArtifactDe
7777
continue;
7878
}
7979

80-
JToken jtokenValue = null;
81-
var parsedValue = string.Empty;
82-
8380
// throws if not found - no need for a null check
8481
var propValueConnector = ValueConnectors.Get(propertyType);
8582

86-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - PropertyValueConnectorAlias - {propValueConnector.PropertyEditorAliases}");
83+
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - PropertyValueConnectorAlias - {string.Join(", ", propValueConnector.PropertyEditorAliases)}");
8784
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - propertyTypeValue - {value}");
8885

89-
//properties like MUP / Nested Content seems to be in json and it breaks, so pass it back as jtokenValue right away
90-
if (IsJson(value))
91-
{
92-
jtokenValue = GetJTokenValue(value);
93-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - Inner JtokenValue - Eg MUP/NestedContent {jtokenValue}");
94-
}
95-
else
96-
{
97-
parsedValue = propValueConnector.ToArtifact(value, propertyType, dependencies);
98-
99-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - ParsedValue - {parsedValue}");
86+
//properties like MUP / Nested Content are JSON, we need to convert to string for the conversion to artifact
87+
string parsedValue = propValueConnector.ToArtifact(IsJson(value) ? value.ToString() : value, propertyType, dependencies);
10088

101-
if (IsJson(parsedValue))
102-
{
103-
// if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
104-
jtokenValue = GetJTokenValue(parsedValue);
105-
}
106-
}
89+
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - ParsedValue - {parsedValue}");
10790

108-
if (jtokenValue != null)
109-
{
110-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - JtokenValue - {jtokenValue}");
111-
docTypeGridEditorContent.Value[propertyType.Alias] = jtokenValue;
112-
}
113-
else
114-
{
115-
docTypeGridEditorContent.Value[propertyType.Alias] = parsedValue;
116-
}
91+
docTypeGridEditorContent.Value[propertyType.Alias] = parsedValue;
11792
}
11893

119-
var resolvedValue = JsonConvert.SerializeObject(docTypeGridEditorContent);
94+
var resolvedValue = JsonConvert.SerializeObject(docTypeGridEditorContent, Formatting.None);
12095

12196
_logger.Debug<DocTypeGridEditorCellValueConnector>($"GetValue - ResolvedValue - {resolvedValue}");
12297

@@ -160,8 +135,6 @@ public void SetValue(GridValue.GridControl gridControl)
160135

161136
foreach (var propertyType in propertyTypes)
162137
{
163-
JToken jtokenValue = null;
164-
165138
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - PropertyEditorAlias -- {propertyType.PropertyEditorAlias}");
166139

167140
if (!docTypeGridEditorContent.Value.TryGetValue(propertyType.Alias, out object value) || value == null)
@@ -172,59 +145,25 @@ public void SetValue(GridValue.GridControl gridControl)
172145

173146
// throws if not found - no need for a null check
174147
var propValueConnector = ValueConnectors.Get(propertyType);
175-
propValueConnector.FromArtifact(value.ToString(), propertyType, "");
176-
177-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - PropertyValueConnecterType - {propValueConnector.GetType()}");
178-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - Value - {value}");
148+
var convertedValue = propValueConnector.FromArtifact(value.ToString(), propertyType, string.Empty);
179149

180-
// test if there's a value for the given property
181-
object convertedValue;
182-
//don't convert if it's json (MUP/Nested) / udi (Content/Media/Multi Pickers) / guid (form picker) / rte / textstring values
183-
if (IsJson(value) || IsUdi(value) || IsGuid(value) || IsText(propertyType.PropertyEditorAlias))
184-
{
185-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - IsJsonValue / IsUdiValue / IsGuidValue / IsTextValue - {value}");
186-
convertedValue = CleanValue(propertyType.PropertyEditorAlias, value);
187-
}
188-
else
150+
JToken jtokenValue = null;
151+
if (IsJson(convertedValue))
189152
{
190-
//using mockContent to get the converted values
191-
var mockProperty = new Property(propertyType);
192-
var mockContent = new Content("mockContentGrid", -1, new ContentType(-1), new PropertyCollection(new List<Property> { mockProperty }));
193-
convertedValue = mockContent.GetValue(mockProperty.Alias);
194-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - ConvertedValue - Before - {convertedValue}");
153+
// test if the value is a json object (thus could be a nested complex editor)
154+
// if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
155+
jtokenValue = GetJTokenValue(convertedValue);
195156
}
196157

197-
// integers needs to be converted into strings for DTGE to work
198-
if (convertedValue is int)
199-
{
200-
docTypeGridEditorContent.Value[propertyType.Alias] = convertedValue.ToString();
201-
}
202-
else if (convertedValue == null)
158+
if (jtokenValue != null)
203159
{
204-
//Assign the null back - otherwise the check for JSON will fail as we cant convert a null to a string
205-
//NOTE: LinkPicker2 for example if no link set is returning a null as opposed to empty string
206-
docTypeGridEditorContent.Value[propertyType.Alias] = null;
160+
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - jtokenValue - {jtokenValue}");
161+
docTypeGridEditorContent.Value[propertyType.Alias] = jtokenValue;
207162
}
208163
else
209164
{
210-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - ConvertedValue - After - {convertedValue}");
211-
212-
if (IsJson(convertedValue))
213-
{
214-
// test if the value is a json object (thus could be a nested complex editor)
215-
// if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
216-
jtokenValue = GetJTokenValue(convertedValue);
217-
}
218-
219-
if (jtokenValue != null)
220-
{
221-
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - jtokenValue - {jtokenValue}");
222-
docTypeGridEditorContent.Value[propertyType.Alias] = jtokenValue;
223-
}
224-
else
225-
{
226-
docTypeGridEditorContent.Value[propertyType.Alias] = convertedValue;
227-
}
165+
_logger.Debug<DocTypeGridEditorCellValueConnector>($"SetValue - convertedValue - {convertedValue}");
166+
docTypeGridEditorContent.Value[propertyType.Alias] = convertedValue;
228167
}
229168
}
230169

@@ -237,24 +176,6 @@ public void SetValue(GridValue.GridControl gridControl)
237176

238177
private bool IsJson(object value) => value != null && value.ToString().DetectIsJson();
239178

240-
private bool IsGuid(object value) => Guid.TryParse(value.ToString(), out _);
241-
242-
private bool IsUdi(object value) =>
243-
//for picker like content/media either single or multi, it comes with udi values
244-
value.ToString().Contains("umb://");
245-
246-
private bool IsText(string editorAlias) =>
247-
//if it's either RTE / Textstring data type
248-
IsRichtext(editorAlias) || IsTextstring(editorAlias);
249-
250-
private bool IsRichtext(string editorAlias) => editorAlias.InvariantEquals("Umbraco.TinyMCE");
251-
252-
private bool IsTextstring(string editorAlias) => editorAlias.InvariantEquals("Umbraco.TextBox");
253-
254-
private string CleanValue(string editorAlias, object value) =>
255-
//can't tell why textstring have got a weird character 's' in front coming from deploy? so removing first char if that's the case
256-
IsTextstring(editorAlias) ? value.ToString().Substring(1) : value.ToString();
257-
258179
private bool AddUdiDependency(ICollection<ArtifactDependency> dependencies, object value)
259180
{
260181
if (Udi.TryParse(value.ToString(), out var udi))
@@ -267,15 +188,15 @@ private bool AddUdiDependency(ICollection<ArtifactDependency> dependencies, obje
267188
return false;
268189
}
269190

270-
private bool IsValueNull(DocTypeGridEditorValue docTypeGridEditorContent, PropertyType propertyType, out object objVal)
191+
private bool TryGetValue(DocTypeGridEditorValue docTypeGridEditorContent, PropertyType propertyType, out object objVal)
271192
{
272193
if (!docTypeGridEditorContent.Value.TryGetValue(propertyType.Alias, out objVal) || objVal == null)
273194
{
274195
_logger.Debug<DocTypeGridEditorCellValueConnector>("GetValue - Value is null");
275-
return true;
196+
return false;
276197
}
277198

278-
return false;
199+
return true;
279200
}
280201

281202
private class DocTypeGridEditorValue

src/Umbraco.Deploy.Contrib.Connectors/ValueConnectors/NestedContentValueConnector.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,12 @@ public string ToArtifact(object value, PropertyType propertyType, ICollection<Ar
114114

115115
// pass the value, property type and the dependencies collection to the connector to get a "artifact" value
116116
var innerValue = row.PropertyValues[key];
117-
object parsedValue = propertyValueConnector.ToArtifact(innerValue, innerPropertyType, dependencies);
117+
118+
// connectors are expecting strings, not JTokens
119+
object preparedValue = innerValue is JToken
120+
? innerValue?.ToString()
121+
: innerValue;
122+
object parsedValue = propertyValueConnector.ToArtifact(preparedValue, innerPropertyType, dependencies);
118123

119124
// getting Map image value umb://media/43e7401fb3cd48ceaa421df511ec703c to (nothing) - why?!
120125
_logger.Debug<NestedContentValueConnector>("Mapped {Key} value '{PropertyValue}' to '{ParsedValue}' using {PropertyValueConnectorType} for {PropertyType}.", key, row.PropertyValues[key], parsedValue, propertyValueConnector.GetType(), innerPropertyType.Alias);
@@ -202,6 +207,11 @@ public object FromArtifact(string value, PropertyType propertyType, object curre
202207
{
203208
row.PropertyValues[key] = convertedValue.ToString();
204209
}
210+
// json strings need to be converted into JTokens
211+
else if (convertedValue is string convertedStringValue && convertedStringValue.DetectIsJson())
212+
{
213+
row.PropertyValues[key] = JToken.Parse(convertedStringValue);
214+
}
205215
else
206216
{
207217
row.PropertyValues[key] = convertedValue;

0 commit comments

Comments
 (0)