Skip to content

Commit

Permalink
Blocking saves of things in root / Export only diffrences.
Browse files Browse the repository at this point in the history
  • Loading branch information
KevinJump committed Aug 1, 2023
1 parent dde417a commit 90a05ae
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 29 deletions.
6 changes: 6 additions & 0 deletions uSync.BackOffice/Configuration/uSyncSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ public class uSyncSettings
[DefaultValue("uSync/root/")]
public string BaseFolder { get; set; } = "uSync/root/";

/// <summary>
/// lock the items that come from base.
/// </summary>
[DefaultValue(true)]
public bool LockBase { get; set; } = true;

/// <summary>
/// The default handler set to use on all notification triggered events
/// </summary>
Expand Down
40 changes: 17 additions & 23 deletions uSync.BackOffice/Controllers/uSyncApiController_HandlerImports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,7 @@ public SyncActionResult ReportHandler(SyncActionOptions options)
{
Callbacks = hubClient.Callbacks(),
HandlerSet = handlerSet,
Folders = new[] {
GetValidImportFolder(options.BaseFolder, _uSyncConfig.GetBaseFolder()),
GetValidImportFolder(options.Folder),
}
Folders = GetValidFolders(options)
}).ToList();

if (_uSyncConfig.Settings.SummaryDashboard || actions.Count > _uSyncConfig.Settings.SummaryLimit)
Expand Down Expand Up @@ -97,10 +94,7 @@ public SyncActionResult ImportHandler(SyncActionOptions options)
{
Callbacks = hubClient.Callbacks(),
HandlerSet = handlerSet,
Folders = new[] {
GetValidImportFolder(options.BaseFolder, _uSyncConfig.GetBaseFolder()),
GetValidImportFolder(options.Folder)
},
Folders = GetValidFolders(options),
PauseDuringImport = true,
Flags = options.Force ? Core.Serialization.SerializerFlags.Force : Core.Serialization.SerializerFlags.None
}).ToList();
Expand All @@ -122,17 +116,9 @@ public SyncActionResult ImportPost(SyncActionOptions options)
var handlerSet = !string.IsNullOrWhiteSpace(options.Set)
? options.Set : _uSyncConfig.Settings.DefaultSet;

var folders = new List<string>
{
GetValidImportFolder(options.Folder),
};

if (!string.IsNullOrEmpty(options.BaseFolder))
folders.Add(GetValidImportFolder(options.BaseFolder, _uSyncConfig.GetBaseFolder()));
var folders = GetValidFolders(options);

var actions = _uSyncService.PerformPostImport(folders.ToArray(),
handlerSet,
options.Actions);
var actions = _uSyncService.PerformPostImport(folders, handlerSet, options.Actions);

hubClient.Callbacks()?.Update("Import Complete", 1, 1);

Expand Down Expand Up @@ -171,11 +157,7 @@ public SyncActionResult ExportHandler(SyncActionOptions options)
{
Callbacks = hubClient.Callbacks(),
HandlerSet = handlerSet,
Folders = new[]
{
GetValidImportFolder(options.BaseFolder, _uSyncConfig.GetBaseFolder()),
GetValidImportFolder(options.Folder)
}
Folders = GetValidFolders(options)
}).ToList();

if (_uSyncConfig.Settings.SummaryDashboard || actions.Count > _uSyncConfig.Settings.SummaryLimit)
Expand Down Expand Up @@ -216,6 +198,18 @@ private string GetCurrentUser()
}
}

private string[] GetValidFolders(SyncActionOptions options)
{
var folders = new List<string>
{
GetValidImportFolder(options.Folder, _uSyncConfig.GetRootFolder()),
};

if (!string.IsNullOrEmpty(options.BaseFolder))
folders.Add(GetValidImportFolder(options.BaseFolder, _uSyncConfig.GetBaseFolder()));

return folders.ToArray();
}

private string GetValidImportFolder(string folder)
=> GetValidImportFolder(folder, _uSyncConfig.GetRootFolder());
Expand Down
3 changes: 2 additions & 1 deletion uSync.BackOffice/SyncHandlers/Handlers/ContentTypeHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public class ContentTypeHandler : SyncHandlerContainerBase<IContentType, IConten
INotificationHandler<DeletedNotification<IContentType>>,
INotificationHandler<MovedNotification<IContentType>>,
INotificationHandler<EntityContainerSavedNotification>,
INotificationHandler<EntityContainerRenamedNotification>
INotificationHandler<EntityContainerRenamedNotification>,
INotificationHandler<SavingNotification<IContentType>>
{
private readonly IContentTypeService contentTypeService;

Expand Down
78 changes: 73 additions & 5 deletions uSync.BackOffice/SyncHandlers/SyncHandlerRoot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -835,7 +835,11 @@ public IEnumerable<uSyncAction> Export(Udi udi, string folder, HandlerSettings s
/// <summary>
/// Export a given item to disk
/// </summary>
///
virtual public IEnumerable<uSyncAction> Export(TObject item, string folder, HandlerSettings config)
=> Export(item, folder, config, false);

virtual public IEnumerable<uSyncAction> Export(TObject item, string folder, HandlerSettings config, bool fromEvent)
{
if (item == null)
return uSyncAction.Fail(nameof(item), this.handlerType, this.ItemType, ChangeType.Fail, "Item not set",
Expand All @@ -849,17 +853,38 @@ virtual public IEnumerable<uSyncAction> Export(TObject item, string folder, Hand
.AsEnumerableOfOne();
}



var filename = GetPath(folder, item, config.GuidNames, config.UseFlatStructure)
.ToAppSafeFileName();

var attempt = SerializeItem(item, new SyncSerializerOptions(config.Settings));
var serializerOptions = new SyncSerializerOptions(config.Settings);
var attempt = SerializeItem(item, serializerOptions);
if (attempt.Success)
{
if (ShouldExport(attempt.Item, config))
{
// only write the file to disk if it should be exported.
syncFileService.SaveXElement(attempt.Item, filename);
}
if (ExistsInBase(item))
{
if (fromEvent && uSyncConfig.Settings.LockBase)
{
return uSyncAction.SetAction(true, nameof(item), type: this.handlerType, change: ChangeType.NoChange, message: "Item exists in base and will not be exported")
.AsEnumerableOfOne();
}

if (IsDifferentFromBase(attempt.Item, item, serializerOptions))
{
// if we are not locking the base, then
// when something is different it is exported to root.
syncFileService.SaveXElement(attempt.Item, filename);
}
}
else
{
// only write the file to disk if it should be exported.
syncFileService.SaveXElement(attempt.Item, filename);
}
}
else
{
return uSyncAction.SetAction(true, filename, type: typeof(TObject).ToString(), change: ChangeType.NoChange, message: "Not Exported (Based on configuration)", filename: filename).AsEnumerableOfOne();
Expand Down Expand Up @@ -1229,6 +1254,49 @@ public virtual void Handle(DeletedNotification<TObject> notification)
}
}

public virtual void Handle(SavingNotification<TObject> notification)
{
// if we are not locking base elements
if (!uSyncConfig.Settings.LockBase) return;

// standard, should we process this event check.
if (!ShouldProcessEvent()) return;

// if the base folder doesn't exist, exit
if (!syncFileService.DirectoryExists(uSyncConfig.GetBaseFolder())) return;

foreach (var item in notification.SavedEntities)
{
if (ExistsInBase(item))
{
// this file exists in the 'base' folder,
// so we should block the saving of it.
notification.CancelOperation(new EventMessage("error", "Base items are locked", EventMessageType.Error));
}
}
}

protected bool ExistsInBase(TObject item)
{
var folder = Path.Combine(uSyncConfig.GetBaseFolder(), this.DefaultFolder);
var path = GetPath(folder, item, DefaultConfig.GuidNames, DefaultConfig.UseFlatStructure)
.ToAppSafeFileName();

return syncFileService.FileExists(path);
}

protected bool IsDifferentFromBase(XElement element, TObject item, SyncSerializerOptions options)
{
var folder = Path.Combine(uSyncConfig.GetBaseFolder(), this.DefaultFolder);
var path = GetPath(folder, item, DefaultConfig.GuidNames, DefaultConfig.UseFlatStructure)
.ToAppSafeFileName();

if (!syncFileService.FileExists(path)) return true;

var baseXml = XElement.Load(path);
return serializer.IsCurrent(element, baseXml, options) != ChangeType.NoChange;
}

/// <summary>
/// Handle the Umbraco Saved notification for items.
/// </summary>
Expand All @@ -1241,7 +1309,7 @@ public virtual void Handle(SavedNotification<TObject> notification)
{
try
{
var attempts = Export(item, Path.Combine(rootFolder, this.DefaultFolder), DefaultConfig);
var attempts = Export(item, Path.Combine(rootFolder, this.DefaultFolder), DefaultConfig, !uSyncConfig.Settings.LockBase);
foreach (var attempt in attempts.Where(x => x.Success))
{
this.CleanUp(item, attempt.FileName, Path.Combine(rootFolder, this.DefaultFolder));
Expand Down
1 change: 1 addition & 0 deletions uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ internal static void AddHandlerNotifications(this IUmbracoBuilder builder)
builder.AddNotificationHandler<ContentTypeSavedNotification, ContentTypeHandler>();
builder.AddNotificationHandler<ContentTypeDeletedNotification, ContentTypeHandler>();
builder.AddNotificationHandler<ContentTypeMovedNotification, ContentTypeHandler>();
builder.AddNotificationHandler<ContentTypeSavingNotification, ContentTypeHandler>();
builder.AddNotificationHandler<EntityContainerSavedNotification, ContentTypeHandler>();
builder.AddNotificationHandler<EntityContainerRenamedNotification, ContentTypeHandler>();

Expand Down

0 comments on commit 90a05ae

Please sign in to comment.