1
1
using System ;
2
2
using System . Collections . Generic ;
3
3
using System . Diagnostics . CodeAnalysis ;
4
- using System . Linq ;
5
4
using System . Text . Json ;
6
5
using System . Text . Json . Nodes ;
7
6
using System . Text . Json . Serialization ;
8
7
using System . Threading ;
9
8
using System . Threading . Tasks ;
9
+ using Microsoft . Extensions . DependencyInjection ;
10
10
using Microsoft . Extensions . Logging ;
11
- using Newtonsoft . Json ;
12
11
using Umbraco . Cms . Core ;
12
+ using Umbraco . Cms . Core . DependencyInjection ;
13
13
using Umbraco . Cms . Core . Deploy ;
14
14
using Umbraco . Cms . Core . Models ;
15
15
using Umbraco . Cms . Core . Models . Blocks ;
16
16
using Umbraco . Cms . Core . PropertyEditors ;
17
17
using Umbraco . Cms . Core . Serialization ;
18
18
using Umbraco . Cms . Core . Services ;
19
19
using Umbraco . Cms . Core . Strings ;
20
+ using Umbraco . Deploy . Core . Migrators ;
20
21
using Umbraco . Deploy . Infrastructure . Migrators ;
21
22
using Umbraco . Extensions ;
22
23
@@ -27,7 +28,10 @@ namespace Umbraco.Deploy.Contrib.Migrators;
27
28
/// </summary>
28
29
public class DocTypeGridEditorPropertyTypeMigrator : GridPropertyTypeMigrator
29
30
{
31
+ private readonly ILogger < GridPropertyTypeMigrator > _logger ;
30
32
private readonly IJsonSerializer _jsonSerializer ;
33
+ private readonly PropertyTypeMigratorCollection _propertyTypeMigrators ;
34
+ private IDictionary < string , string > ? _propertyEditorAliases ;
31
35
32
36
/// <summary>
33
37
/// Initializes a new instance of the <see cref="DocTypeGridEditorPropertyTypeMigrator" /> class.
@@ -38,9 +42,44 @@ public class DocTypeGridEditorPropertyTypeMigrator : GridPropertyTypeMigrator
38
42
/// <param name="shortStringHelper">The short string helper.</param>
39
43
/// <param name="contentTypeService">The content type service.</param>
40
44
/// <param name="mediaService">The media service.</param>
45
+ [ Obsolete ( "Use the constructor with all parameters. This will be removed in a future version." ) ]
41
46
public DocTypeGridEditorPropertyTypeMigrator ( ILogger < GridPropertyTypeMigrator > logger , IJsonSerializer jsonSerializer , IDataTypeService dataTypeService , IShortStringHelper shortStringHelper , IContentTypeService contentTypeService , IMediaService mediaService )
47
+ : this (
48
+ logger ,
49
+ jsonSerializer ,
50
+ dataTypeService ,
51
+ shortStringHelper ,
52
+ contentTypeService ,
53
+ mediaService ,
54
+ StaticServiceProvider . Instance . GetRequiredService < PropertyTypeMigratorCollection > ( ) )
55
+ { }
56
+
57
+ /// <summary>
58
+ /// Initializes a new instance of the <see cref="DocTypeGridEditorPropertyTypeMigrator" /> class.
59
+ /// </summary>
60
+ /// <param name="logger">The logger.</param>
61
+ /// <param name="jsonSerializer">The JSON serializer.</param>
62
+ /// <param name="dataTypeService">The data type service.</param>
63
+ /// <param name="shortStringHelper">The short string helper.</param>
64
+ /// <param name="contentTypeService">The content type service.</param>
65
+ /// <param name="mediaService">The media service.</param>
66
+ /// <param name="propertyTypeMigrators">The property type migrators.</param>
67
+ public DocTypeGridEditorPropertyTypeMigrator ( ILogger < GridPropertyTypeMigrator > logger , IJsonSerializer jsonSerializer , IDataTypeService dataTypeService , IShortStringHelper shortStringHelper , IContentTypeService contentTypeService , IMediaService mediaService , PropertyTypeMigratorCollection propertyTypeMigrators )
42
68
: base ( logger , jsonSerializer , dataTypeService , shortStringHelper , contentTypeService , mediaService )
43
- => _jsonSerializer = jsonSerializer ;
69
+ {
70
+ _logger = logger ;
71
+ _jsonSerializer = jsonSerializer ;
72
+ _propertyTypeMigrators = propertyTypeMigrators ;
73
+ }
74
+
75
+ /// <inheritdoc />
76
+ public override async Task < object ? > MigrateAsync ( IPropertyType propertyType , object ? value , IDictionary < string , string > propertyEditorAliases , IContextCache contextCache , CancellationToken cancellationToken = default )
77
+ {
78
+ // Workaround: store property editor aliases for use in MigrateGridControl
79
+ _propertyEditorAliases = propertyEditorAliases ;
80
+
81
+ return await base . MigrateAsync ( propertyType , value , propertyEditorAliases , contextCache , cancellationToken ) . ConfigureAwait ( false ) ;
82
+ }
44
83
45
84
/// <inheritdoc />
46
85
protected override async Task < BlockItemData ? > MigrateGridControlAsync ( GridValue . GridControl gridControl , BlockGridConfiguration configuration , IContextCache contextCache , CancellationToken cancellationToken = default )
@@ -62,20 +101,38 @@ public DocTypeGridEditorPropertyTypeMigrator(ILogger<GridPropertyTypeMigrator> l
62
101
/// <returns>
63
102
/// A task that represents the asynchronous operation. The task result contains the block item data, or <c>null</c> if migration should be skipped.
64
103
/// </returns>
65
- protected virtual async Task < BlockItemData ? > MigrateGridControlAsync ( DocTypeGridEditorValue value , BlockGridConfiguration configuration , IContextCache contextCache )
104
+ protected virtual async Task < BlockItemData ? > MigrateGridControlAsync ( DocTypeGridEditorValue value , BlockGridConfiguration configuration , IContextCache contextCache ) // TODO: Add cancellation token
66
105
{
67
106
IContentType contentType = await GetContentTypeAsync ( value . ContentTypeAlias , configuration , contextCache ) . ConfigureAwait ( false )
68
107
?? throw new InvalidOperationException ( $ "Migrating legacy grid failed, because content type with alias '{ value . ContentTypeAlias } ' could not be found (in the Block Grid configuration).") ;
69
108
109
+ var propertyValues = new List < BlockPropertyValue > ( value . Value . Count ) ;
110
+
111
+ foreach ( IPropertyType propertyType in contentType . CompositionPropertyTypes )
112
+ {
113
+ if ( value . Value . TryGetValue ( propertyType . Alias , out object ? propertyValue ) )
114
+ {
115
+ if ( _propertyEditorAliases is not null &&
116
+ await _propertyTypeMigrators . TryMigrateAsync ( propertyType , value , _propertyEditorAliases , contentType . Alias , contextCache ) . ConfigureAwait ( false ) is ( true , var migratedValue ) )
117
+ {
118
+ _logger . LogDebug ( "Migrated nested/recursive property {PropertyTypeAlias} on {ContentTypeAlias} to {PropertyEditorAlias}: {Value}." , propertyType . Alias , contentType . Alias , propertyType . PropertyEditorAlias , migratedValue ) ;
119
+
120
+ propertyValue = migratedValue ;
121
+ }
122
+
123
+ propertyValues . Add ( new BlockPropertyValue ( )
124
+ {
125
+ Alias = propertyType . Alias ,
126
+ Value = propertyValue ,
127
+ } ) ;
128
+ }
129
+ }
130
+
70
131
return new BlockItemData ( )
71
132
{
72
133
Key = value . Id ,
73
134
ContentTypeKey = contentType . Key ,
74
- Values = value . Value . Select ( x => new BlockPropertyValue ( )
75
- {
76
- Alias = x . Key ,
77
- Value = x . Value ,
78
- } ) . ToList ( ) ,
135
+ Values = propertyValues ,
79
136
} ;
80
137
}
81
138
@@ -92,9 +149,10 @@ JsonNode jsonNode when jsonNode.GetValue<string>() is string json && json.Detect
92
149
93
150
return ! string . IsNullOrEmpty ( docTypeGridEditorValue ? . ContentTypeAlias ) ;
94
151
}
95
- catch ( JsonSerializationException )
152
+ catch ( JsonException )
96
153
{
97
154
docTypeGridEditorValue = null ;
155
+
98
156
return false ;
99
157
}
100
158
}
0 commit comments