Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 4 additions & 15 deletions uSync.Core/Serialization/Serializers/ContentSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -291,20 +291,9 @@ public int DeserializeWriterInfo(IContent item, XElement node, SyncSerializerOpt
public override async Task<SyncAttempt<IContent>> DeserializeSecondPassAsync(IContent item, XElement node, SyncSerializerOptions options)
{
var details = new List<uSyncChange>();
// move trashed state to second pass, as the item needs an Id for the relation to work.
details.AddNotNull(await DeserializeTrashed(node, item, Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias));

// move sort to second pass, as if we attempt to set this
// on a brand new item, it doesn't get set.
// doing it on second pass ensures it gets set on the item
// after it has been saved by umbraco.
if (!options.GetSetting<bool>(
uSyncConstants.DefaultSettings.IgnoreSortOrder,
uSyncConstants.DefaultSettings.IgnoreSortOrder_Default))
{
var sortOrder = node.Element(uSyncConstants.Xml.Info)?.Element(uSyncConstants.Xml.SortOrder).ValueOrDefault(-1) ?? -1;
details.AddNotNull(HandleSortOrder(item, sortOrder));
}

details.AddRange(await this.DeserializeSecondPassSharedAsync(item, node, options,
Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias));

var changes = await DeserializeSchedulesAsync(item, node, options);
if (changes.Count != 0)
Expand Down Expand Up @@ -444,7 +433,7 @@ protected virtual async Task<SyncContentUpdateResult> DoSaveOrPublishAsync(ICont
logger.LogDebug("Performing Save: {id} {name}", item.Id, item.Name);
var result = contentService.Save(item, options.UserId, scheduleCollection);
if (result.Success)
item = contentService.GetById(item.Id)!;
item = contentService.GetById(item.Id) ?? item;
else
{
// something went wrong saving. ???
Expand Down
27 changes: 27 additions & 0 deletions uSync.Core/Serialization/Serializers/ContentSerializerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,33 @@ protected async Task<Attempt<List<uSyncChange>, string>> DeserializePropertiesAs
return Attempt.SucceedWithStatus(errors, changes);
}

/// <summary>
/// Things most 'IContentBase' serializers need (ones that have trash anyway).
/// </summary>
protected async Task<List<uSyncChange>> DeserializeSecondPassSharedAsync(TObject item, XElement node, SyncSerializerOptions options,
string trashedRelationAlias)
{
var details = new List<uSyncChange>();

// move trashed state to second pass, as the item needs an Id for the relation to work.
details.AddNotNull(await DeserializeTrashed(node, item, trashedRelationAlias));

// move sort to second pass, as if we attempt to set this
// on a brand new item, it doesn't get set.
// doing it on second pass ensures it gets set on the item
// after it has been saved by umbraco.
if (!options.GetSetting<bool>(
uSyncConstants.DefaultSettings.IgnoreSortOrder,
uSyncConstants.DefaultSettings.IgnoreSortOrder_Default))
{
var sortOrder = node.Element(uSyncConstants.Xml.Info)?.Element(uSyncConstants.Xml.SortOrder).ValueOrDefault(-1) ?? -1;
details.AddNotNull(HandleSortOrder(item, sortOrder));
}

return details;
}


/// <summary>
/// compares to object values to see if they are the same.
/// </summary>
Expand Down
40 changes: 25 additions & 15 deletions uSync.Core/Serialization/Serializers/ContentTypeBaseSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,19 @@ protected async Task<XElement> SerializeStructureAsync(TObject item)
var allowedTypeOrdered = item.AllowedContentTypes?.OrderBy(x => x.SortOrder);
if (allowedTypeOrdered is null) return node;

int defaultSortOrder = 0;
foreach (var allowedType in allowedTypeOrdered)
{
var allowedItem = await FindItemAsync(allowedType.Key);
if (allowedItem != null)
{
var sortOrder = allowedType.SortOrder > 0 ? allowedType.SortOrder : defaultSortOrder;

node.Add(new XElement(ItemType,
new XAttribute(uSyncConstants.Xml.Key, allowedItem.Key),
new XAttribute(uSyncConstants.Xml.SortOrder, allowedType.SortOrder), allowedItem.Alias));
new XAttribute(uSyncConstants.Xml.SortOrder, sortOrder), allowedItem.Alias));

defaultSortOrder = sortOrder + 1;
}
}
return node;
Expand Down Expand Up @@ -346,7 +351,11 @@ protected async Task<IEnumerable<uSyncChange>> DeserializeStructureAsync(TObject

int sortOrder = 0;

foreach (var baseNode in structure.Elements(ItemType))
// do it in the sort order (if there is one).
// makes it more likely to 'work' first time.
var nodes = structure.Elements(ItemType).OrderBy(x => x.Attribute(uSyncConstants.Xml.SortOrder).ValueOrDefault(int.MinValue));

foreach (var baseNode in nodes)
{
logger.LogDebug("baseNode {base}", baseNode.ToString());
var alias = baseNode.Value;
Expand Down Expand Up @@ -375,34 +384,30 @@ protected async Task<IEnumerable<uSyncChange>> DeserializeStructureAsync(TObject

if (baseItem != null)
{
logger.LogDebug("Structure Found {alias}", baseItem.Alias);
allowed.Add(new ContentTypeSort(baseItem.Key, itemSortOrder, baseItem.Alias));
sortOrder = itemSortOrder + 1;
}
}

logger.LogDebug("Structure: {count} items", allowed.Count);


if (item.AllowedContentTypes is not null)
{
// compare the two lists (the equality compare fails because the id value is lazy)
var currentHash = string.Join(":", item.AllowedContentTypes.Select(x => $"{x.Key}-{x.SortOrder}").OrderBy(x => x));
var newHash = string.Join(":", allowed.Select(x => $"{x.Key}-{x.SortOrder}").OrderBy(x => x));
var currentHash = string.Join(":", item.AllowedContentTypes.Select(x => $"{x.Key}-{x.SortOrder}").OrderBy(x => x)).GetDeterministicHashCode();
var newHash = string.Join(":", allowed.Select(x => $"{x.Key}-{x.SortOrder}").OrderBy(x => x)).GetDeterministicHashCode();

if (!currentHash.Equals(newHash))
if (currentHash.Equals(newHash) is false)
{
changes.AddUpdate("Allowed",
string.Join(",", item.AllowedContentTypes.Select(x => x.Alias) ?? []),
string.Join(",", allowed.Select(x => x.Alias) ?? []), "/Structure");
string.Join("::", item.AllowedContentTypes.Select(x => x.Alias)?? []),
string.Join("::", allowed.Select(x => x.Alias) ?? []), "/Structure");

logger.LogDebug("Updating allowed content types {old}, {new}", currentHash, newHash);
item.AllowedContentTypes = allowed;
item.AllowedContentTypes = allowed.OrderBy(x => x.SortOrder);
}
}
else
{
item.AllowedContentTypes = allowed;
changes.AddNew("Allowed", string.Join("::", allowed.Select(x => x.Alias) ?? []), "/Structure");
item.AllowedContentTypes = allowed.OrderBy(x => x.SortOrder);
}

return changes;
Expand Down Expand Up @@ -1348,7 +1353,12 @@ protected virtual bool PropertyExistsOnComposite(TObject item, string alias, Lis

public override async Task SaveItemAsync(TObject item)
{
if (item.IsDirty() is false) return;
logger.LogDebug("Save Item {name} ({alias})", item.Name, item.Alias);
if (item.IsDirty() is false)
{
logger.LogDebug("Item not dirty, skipping save");
return;
}

if (item.Id <= 0)
{
Expand Down
4 changes: 2 additions & 2 deletions uSync.Core/Serialization/Serializers/MediaSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ protected override async Task<SyncAttempt<IMedia>> DeserializeCoreAsync(XElement

public override async Task<SyncAttempt<IMedia>> DeserializeSecondPassAsync(IMedia item, XElement node, SyncSerializerOptions options)
{
var details = new List<uSyncChange>();
details.AddNotNull(await DeserializeTrashed(node, item, Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias));
var details = await DeserializeSecondPassSharedAsync(item, node, options,
Constants.Conventions.RelationTypes.RelateParentMediaFolderOnDeleteAlias);

return SyncAttempt<IMedia>.Succeed(item.Name ?? item.Id.ToString(), item,
details.Count == 0 ? ChangeType.NoChange : ChangeType.Import, details);
Expand Down