Skip to content

Commit

Permalink
Fix #73 - Fix FileClash code, so we only check on level based items (…
Browse files Browse the repository at this point in the history
…content,media)
  • Loading branch information
Kevin Jump committed Jan 29, 2020
1 parent 9ef59ff commit 84c7579
Show file tree
Hide file tree
Showing 12 changed files with 209 additions and 47 deletions.
37 changes: 17 additions & 20 deletions uSync8.BackOffice/SyncHandlers/SyncHandlerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ virtual public IEnumerable<uSyncAction> Export(TObject item, string folder, Hand
}
else
{
return uSyncAction.SetAction(true, filename, type: typeof(TObject), change: ChangeType.NoChange, message: "Not Exported (Based on config)").AsEnumerableOfOne();
return uSyncAction.SetAction(true, filename, type: typeof(TObject), change: ChangeType.NoChange, message: "Not Exported (Based on config)", filename: filename).AsEnumerableOfOne();
}
}

Expand Down Expand Up @@ -685,31 +685,28 @@ virtual protected string GetPath(string folder, TObject item, bool GuidNames, bo
var path = $"{folder}/{this.GetItemPath(item, GuidNames, isFlat)}.config";

// if this is flat but not using guid filenames, then we check for clashes.
if (isFlat && !GuidNames) return CheckAndFixFileClash(path, GetItemKey(item));
if (isFlat && !GuidNames) return CheckAndFixFileClash(path, item);
return path;
}

virtual protected Guid GetItemKey(TObject item) => item.Key;

private string CheckAndFixFileClash(string path, Guid key)
{
if (syncFileService.FileExists(path))
{
var node = syncFileService.LoadXElement(path);
if (node != null && node.GetKey() != key)
{
// clash, we should append something
var append = key.ToShortKeyString(8); // (this is the shortened guid like media folders do)
return Path.Combine(Path.GetDirectoryName(path),
Path.GetFileNameWithoutExtension(path) + "_" + append + Path.GetExtension(path));
}

}
return path;
}


/// <summary>
/// clashes we want to resolve can only occur, when the
/// items can be called the same but in be in diffrent places (e.g content, media).
/// </summary>
/// <param name="path"></param>
/// <param name="key"></param>
/// <returns></returns>
virtual protected string CheckAndFixFileClash(string path, TObject item)
=> path;

/// <summary>
/// any class that overrides FixFileClash will need to get a match string
/// from the xml, so its on the base class to avoid duplication
/// </summary>
protected virtual string GetXmlMatchString(XElement node)
=> $"{node.GetAlias()}_{node.GetLevel()}".ToLower();

virtual public uSyncAction Rename(TObject item)
=> new uSyncAction();
Expand Down
5 changes: 2 additions & 3 deletions uSync8.ContentEdition/Handlers/ContentHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Xml.Linq;

using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
Expand All @@ -14,7 +15,6 @@
using uSync8.BackOffice.SyncHandlers;
using uSync8.Core.Dependency;
using uSync8.Core.Extensions;
using uSync8.Core.Models;
using uSync8.Core.Serialization;
using uSync8.Core.Tracking;

Expand All @@ -24,7 +24,7 @@ namespace uSync8.ContentEdition.Handlers
{
[SyncHandler("contentHandler", "Content", "Content", uSyncBackOfficeConstants.Priorites.Content
, Icon = "icon-document usync-addon-icon", IsTwoPass = true, EntityType = UdiEntityType.Document)]
public class ContentHandler : SyncHandlerTreeBase<IContent, IContentService>, ISyncHandler, ISyncExtendedHandler
public class ContentHandler : ContentHandlerBase<IContent, IContentService>, ISyncHandler, ISyncExtendedHandler
{
public override string Group => uSyncBackOfficeConstants.Groups.Content;

Expand Down Expand Up @@ -145,6 +145,5 @@ protected override bool ShouldExport(XElement node, HandlerSettings config)

return true;
}

}
}
82 changes: 82 additions & 0 deletions uSync8.ContentEdition/Handlers/ContentHandlerBase.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
using System.IO;

using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.Services;

using uSync8.BackOffice.Services;
using uSync8.BackOffice.SyncHandlers;
using uSync8.ContentEdition.Serializers;
using uSync8.Core;
using uSync8.Core.Dependency;
using uSync8.Core.Extensions;
using uSync8.Core.Serialization;
using uSync8.Core.Tracking;

namespace uSync8.ContentEdition.Handlers
{
/// <summary>
/// base for all content based handlers
/// </summary>
/// <remarks>
/// Content based handlers can have the same name in diffrent
/// places around the tree, so we have to check for file name
/// clashes.
/// </remarks>
public abstract class ContentHandlerBase<TObject, TService> : SyncHandlerTreeBase<TObject, TService>
where TObject : IContentBase
where TService : IService
{
protected ContentHandlerBase(
IEntityService entityService,
IProfilingLogger logger,
ISyncSerializer<TObject> serializer,
ISyncTracker<TObject> tracker,
SyncFileService syncFileService)
: base(entityService, logger, serializer, tracker, syncFileService)
{ }

protected ContentHandlerBase(
IEntityService entityService,
IProfilingLogger logger,
ISyncSerializer<TObject> serializer,
ISyncTracker<TObject> tracker,
ISyncDependencyChecker<TObject> checker,
SyncFileService syncFileService)
: base(entityService, logger, serializer, tracker, checker, syncFileService)
{ }



protected override string CheckAndFixFileClash(string path, TObject item)
{
if (syncFileService.FileExists(path))
{
var itemKey = item.Key;
var node = syncFileService.LoadXElement(path);

if (node == null) return path;
if (item.Key == node.GetKey()) return path;
if (GetXmlMatchString(node) == GetItemMatchString(item)) return path;

// get here we have a clash, we should append something
var append = item.Key.ToShortKeyString(8); // (this is the shortened guid like media folders do)
return Path.Combine(Path.GetDirectoryName(path),
Path.GetFileNameWithoutExtension(path) + "_" + append + Path.GetExtension(path));
}

return path;
}

protected virtual string GetItemMatchString(TObject item)
{
var level = item.Level;
if (item.Trashed && serializer is ISyncContentSerializer<TObject> contentSerializer)
{
level = contentSerializer.GetLevel(item);
}
return $"{item.Name}_{level}".ToLower();
}

}
}
2 changes: 1 addition & 1 deletion uSync8.ContentEdition/Handlers/ContentTemplateHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace uSync8.ContentEdition.Handlers
{
[SyncHandler("contentTemplateHandler", "Blueprints", "Blueprints", uSyncBackOfficeConstants.Priorites.ContentTemplate
, Icon = "icon-document-dashed-line usync-addon-icon", IsTwoPass = true, EntityType = UdiEntityType.DocumentBlueprint)]
public class ContentTemplateHandler : SyncHandlerTreeBase<IContent, IContentService>, ISyncHandler, ISyncExtendedHandler
public class ContentTemplateHandler : ContentHandlerBase<IContent, IContentService>, ISyncHandler, ISyncExtendedHandler
{
public override string Group => uSyncBackOfficeConstants.Groups.Content;

Expand Down
3 changes: 2 additions & 1 deletion uSync8.ContentEdition/Handlers/MediaHandler.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Xml.Linq;

using Umbraco.Core;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
Expand All @@ -23,7 +24,7 @@ namespace uSync8.ContentEdition.Handlers
{
[SyncHandler("mediaHandler", "Media", "Media", uSyncBackOfficeConstants.Priorites.Media,
Icon = "icon-picture usync-addon-icon", IsTwoPass = true, EntityType = UdiEntityType.Media)]
public class MediaHandler : SyncHandlerTreeBase<IMedia, IMediaService>, ISyncHandler, ISyncExtendedHandler
public class MediaHandler : ContentHandlerBase<IMedia, IMediaService>, ISyncHandler, ISyncExtendedHandler
{
public override string Group => uSyncBackOfficeConstants.Groups.Content;

Expand Down
5 changes: 4 additions & 1 deletion uSync8.ContentEdition/Serializers/ContentSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,18 @@ public class ContentSerializer : ContentSerializerBase<IContent>, ISyncSerialize
public ContentSerializer(
IEntityService entityService,
ILocalizationService localizationService,
IRelationService relationService,
ILogger logger,
IContentService contentService,
IFileService fileService,
SyncValueMapperCollection syncMappers)
: base(entityService, localizationService, logger, UmbracoObjectTypes.Document, syncMappers)
: base(entityService, localizationService, relationService, logger, UmbracoObjectTypes.Document, syncMappers)
{
this.contentService = contentService;
this.fileService = fileService;

this.relationAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias;

performDoubleLookup = UmbracoVersion.LocalVersion.Major != 8 || UmbracoVersion.LocalVersion.Minor < 4;
}

Expand Down
Loading

0 comments on commit 84c7579

Please sign in to comment.