diff --git a/uSync.BackOffice/SyncHandlers/Handlers/LanguageHandler.cs b/uSync.BackOffice/SyncHandlers/Handlers/LanguageHandler.cs
index 87126e5f..2e0885a9 100644
--- a/uSync.BackOffice/SyncHandlers/Handlers/LanguageHandler.cs
+++ b/uSync.BackOffice/SyncHandlers/Handlers/LanguageHandler.cs
@@ -24,208 +24,218 @@
namespace uSync.BackOffice.SyncHandlers.Handlers
{
- ///
- /// Handler to mange language settings in uSync
- ///
- [SyncHandler(uSyncConstants.Handlers.LanguageHandler, "Languages", "Languages", uSyncConstants.Priorites.Languages,
- Icon = "icon-globe", EntityType = UdiEntityType.Language, IsTwoPass = true)]
- public class LanguageHandler : SyncHandlerBase, ISyncHandler,
- INotificationHandler>,
- INotificationHandler>,
- INotificationHandler>,
- INotificationHandler>
- {
- private readonly ILocalizationService localizationService;
-
- ///
- public LanguageHandler(
- ILogger logger,
- IEntityService entityService,
- ILocalizationService localizationService,
- AppCaches appCaches,
- IShortStringHelper shortStringHelper,
- SyncFileService syncFileService,
- uSyncEventService mutexService,
- uSyncConfigService uSyncConfig,
- ISyncItemFactory syncItemFactory)
- : base(logger, entityService, appCaches, shortStringHelper, syncFileService, mutexService, uSyncConfig, syncItemFactory)
- {
- this.localizationService = localizationService;
- }
-
- ///
- // language guids are not consistant (at least in alpha)
- // so we don't save by Guid we save by ISO name everytime.
- protected override string GetPath(string folder, ILanguage item, bool GuidNames, bool isFlat)
- {
- return Path.Combine(folder, $"{this.GetItemPath(item, GuidNames, isFlat)}.{this.uSyncConfig.Settings.DefaultExtension}");
- }
-
- ///
- protected override string GetItemPath(ILanguage item, bool useGuid, bool isFlat)
- => item.IsoCode.ToSafeFileName(shortStringHelper);
-
-
- ///
- /// ensure we import the 'default' language first, so we don't get errors doing it.
- ///
- protected override IEnumerable GetImportFiles(string folder)
- {
- var files = base.GetImportFiles(folder);
-
- try
- {
- Dictionary ordered = new Dictionary();
- foreach (var file in files)
- {
- var node = XElement.Load(file);
- var order = (node.Element("IsDefault").ValueOrDefault(false) ? "0" : "1") + Path.GetFileName(file);
- ordered[file] = order;
- }
-
- return ordered.OrderBy(x => x.Value).Select(x => x.Key).ToList();
- }
- catch
- {
- return files;
- }
-
- }
-
- ///
- protected override IEnumerable GetChildItems(int parent)
- {
- if (parent == -1)
- return localizationService.GetAllLanguages();
-
- return Enumerable.Empty();
- }
-
- ///
- protected override string GetItemName(ILanguage item) => item.IsoCode;
-
- ///
- protected override void CleanUp(ILanguage item, string newFile, string folder)
- {
- base.CleanUp(item, newFile, folder);
-
- // for languages we also clean up by id.
- // this happens when the language changes .
- var physicalFile = syncFileService.GetAbsPath(newFile);
- var installedLanguages = localizationService.GetAllLanguages()
- .Select(x => x.IsoCode).ToList();
-
- var files = syncFileService.GetFiles(folder, $"*.{this.uSyncConfig.Settings.DefaultExtension}");
-
- foreach (string file in files)
- {
- var node = syncFileService.LoadXElement(file);
- var IsoCode = node.Element("IsoCode").ValueOrDefault(string.Empty);
-
- if (!String.IsNullOrWhiteSpace(IsoCode))
- {
- if (!file.InvariantEquals(physicalFile))
- {
- // not the file we just saved, but matching IsoCode, we remove it.
- if (node.Element("IsoCode").ValueOrDefault(string.Empty) == item.IsoCode)
- {
- logger.LogDebug("Found Matching Lang File, cleaning");
- var attempt = serializer.SerializeEmpty(item, SyncActionType.Rename, node.GetAlias());
- if (attempt.Success)
- {
- syncFileService.SaveXElement(attempt.Item, file);
- }
- }
- }
-
- if (!installedLanguages.InvariantContains(IsoCode))
- {
- // language is no longer installed, make the file empty.
- logger.LogDebug("Language in file is not on the site, cleaning");
- var attempt = serializer.SerializeEmpty(item, SyncActionType.Delete, node.GetAlias());
- if (attempt.Success)
- {
- syncFileService.SaveXElement(attempt.Item, file);
- }
- }
- }
- }
- }
-
- private static ConcurrentDictionary newLanguages = new ConcurrentDictionary();
-
- ///
- public override void Handle(SavingNotification notification)
- {
- if (_mutexService.IsPaused) return;
-
- if (ShouldBlockRootChanges(notification.SavedEntities))
- {
- notification.Cancel = true;
- notification.Messages.Add(GetCancelMessageForRoots());
- return;
- }
-
- foreach (var item in notification.SavedEntities)
- {
- //
- if (item.Id == 0)
- {
- newLanguages[item.IsoCode] = item.CultureName;
- // is new, we want to set this as a flag, so we don't do the full content save.n
- // newLanguages.Add(item.IsoCode);
- }
- }
- }
-
- ///
- public override void Handle(SavedNotification notification)
- {
- if (_mutexService.IsPaused) return;
-
- foreach (var item in notification.SavedEntities)
- {
- bool newItem = false;
- if (newLanguages.Count > 0 && newLanguages.ContainsKey(item.IsoCode))
- {
- newItem = true;
- newLanguages.TryRemove(item.IsoCode, out string name);
- }
-
- var targetFolders = GetDefaultHandlerFolders();
-
- if (item.WasPropertyDirty("IsDefault"))
- {
- // changing, this change doesn't trigger a save of the other languages.
- // so we need to save all language files.
- this.ExportAll(targetFolders, DefaultConfig, null);
- }
-
-
- var attempts = Export(item,targetFolders, DefaultConfig);
-
- if (!newItem && item.WasPropertyDirty(nameof(ILanguage.IsoCode)))
- {
- // The language code changed, this can mean we need to do a full content export.
- // + we should export the languages again!
- uSyncTriggers.TriggerExport(targetFolders, new List() {
- UdiEntityType.Document, UdiEntityType.Language }, null);
- }
-
- // we always clean up languages, because of the way they are stored.
- foreach (var attempt in attempts.Where(x => x.Success))
- {
- this.CleanUp(item, attempt.FileName, targetFolders.Last());
- }
-
- }
- }
-
- ///
- /// we don't support language deletion (because the keys are unstable)
- ///
- protected override IEnumerable DeleteMissingItems(int parentId, IEnumerable keys, bool reportOnly)
- => Enumerable.Empty();
-
- }
+ ///
+ /// Handler to mange language settings in uSync
+ ///
+ [SyncHandler(uSyncConstants.Handlers.LanguageHandler, "Languages", "Languages", uSyncConstants.Priorites.Languages,
+ Icon = "icon-globe", EntityType = UdiEntityType.Language, IsTwoPass = true)]
+ public class LanguageHandler : SyncHandlerBase, ISyncHandler,
+ INotificationHandler>,
+ INotificationHandler>,
+ INotificationHandler>,
+ INotificationHandler>
+ {
+ private readonly ILocalizationService localizationService;
+
+ ///
+ public LanguageHandler(
+ ILogger logger,
+ IEntityService entityService,
+ ILocalizationService localizationService,
+ AppCaches appCaches,
+ IShortStringHelper shortStringHelper,
+ SyncFileService syncFileService,
+ uSyncEventService mutexService,
+ uSyncConfigService uSyncConfig,
+ ISyncItemFactory syncItemFactory)
+ : base(logger, entityService, appCaches, shortStringHelper, syncFileService, mutexService, uSyncConfig, syncItemFactory)
+ {
+ this.localizationService = localizationService;
+ }
+
+ ///
+ // language guids are not consistant (at least in alpha)
+ // so we don't save by Guid we save by ISO name everytime.
+ protected override string GetPath(string folder, ILanguage item, bool GuidNames, bool isFlat)
+ {
+ return Path.Combine(folder, $"{this.GetItemPath(item, GuidNames, isFlat)}.{this.uSyncConfig.Settings.DefaultExtension}");
+ }
+
+ ///
+ protected override string GetItemPath(ILanguage item, bool useGuid, bool isFlat)
+ => item.IsoCode.ToSafeFileName(shortStringHelper);
+
+ ///
+ /// order the merged items, making sure the default language is first.
+ ///
+ protected override IReadOnlyList GetMergedItems(string[] folders)
+ => base.GetMergedItems(folders)
+ .OrderBy(x => x.Node.Element("IsDefault").ValueOrDefault(false) ? 0 : 1)
+ .ToList();
+
+ ///
+ /// ensure we import the 'default' language first, so we don't get errors doing it.
+ ///
+ ///
+ /// prost v13.1 this method isn't used to determain the order for all options.
+ ///
+ protected override IEnumerable GetImportFiles(string folder)
+ {
+ var files = base.GetImportFiles(folder);
+
+ try
+ {
+ Dictionary ordered = new Dictionary();
+ foreach (var file in files)
+ {
+ var node = XElement.Load(file);
+ var order = (node.Element("IsDefault").ValueOrDefault(false) ? "0" : "1") + Path.GetFileName(file);
+ ordered[file] = order;
+ }
+
+ return ordered.OrderBy(x => x.Value).Select(x => x.Key).ToList();
+ }
+ catch
+ {
+ return files;
+ }
+
+ }
+
+ ///
+ protected override IEnumerable GetChildItems(int parent)
+ {
+ if (parent == -1)
+ return localizationService.GetAllLanguages();
+
+ return Enumerable.Empty();
+ }
+
+ ///
+ protected override string GetItemName(ILanguage item) => item.IsoCode;
+
+ ///
+ protected override void CleanUp(ILanguage item, string newFile, string folder)
+ {
+ base.CleanUp(item, newFile, folder);
+
+ // for languages we also clean up by id.
+ // this happens when the language changes .
+ var physicalFile = syncFileService.GetAbsPath(newFile);
+ var installedLanguages = localizationService.GetAllLanguages()
+ .Select(x => x.IsoCode).ToList();
+
+ var files = syncFileService.GetFiles(folder, $"*.{this.uSyncConfig.Settings.DefaultExtension}");
+
+ foreach (string file in files)
+ {
+ var node = syncFileService.LoadXElement(file);
+ var IsoCode = node.Element("IsoCode").ValueOrDefault(string.Empty);
+
+ if (!String.IsNullOrWhiteSpace(IsoCode))
+ {
+ if (!file.InvariantEquals(physicalFile))
+ {
+ // not the file we just saved, but matching IsoCode, we remove it.
+ if (node.Element("IsoCode").ValueOrDefault(string.Empty) == item.IsoCode)
+ {
+ logger.LogDebug("Found Matching Lang File, cleaning");
+ var attempt = serializer.SerializeEmpty(item, SyncActionType.Rename, node.GetAlias());
+ if (attempt.Success)
+ {
+ syncFileService.SaveXElement(attempt.Item, file);
+ }
+ }
+ }
+
+ if (!installedLanguages.InvariantContains(IsoCode))
+ {
+ // language is no longer installed, make the file empty.
+ logger.LogDebug("Language in file is not on the site, cleaning");
+ var attempt = serializer.SerializeEmpty(item, SyncActionType.Delete, node.GetAlias());
+ if (attempt.Success)
+ {
+ syncFileService.SaveXElement(attempt.Item, file);
+ }
+ }
+ }
+ }
+ }
+
+ private static ConcurrentDictionary newLanguages = new ConcurrentDictionary();
+
+ ///
+ public override void Handle(SavingNotification notification)
+ {
+ if (_mutexService.IsPaused) return;
+
+ if (ShouldBlockRootChanges(notification.SavedEntities))
+ {
+ notification.Cancel = true;
+ notification.Messages.Add(GetCancelMessageForRoots());
+ return;
+ }
+
+ foreach (var item in notification.SavedEntities)
+ {
+ //
+ if (item.Id == 0)
+ {
+ newLanguages[item.IsoCode] = item.CultureName;
+ // is new, we want to set this as a flag, so we don't do the full content save.n
+ // newLanguages.Add(item.IsoCode);
+ }
+ }
+ }
+
+ ///
+ public override void Handle(SavedNotification notification)
+ {
+ if (_mutexService.IsPaused) return;
+
+ foreach (var item in notification.SavedEntities)
+ {
+ bool newItem = false;
+ if (newLanguages.Count > 0 && newLanguages.ContainsKey(item.IsoCode))
+ {
+ newItem = true;
+ newLanguages.TryRemove(item.IsoCode, out string name);
+ }
+
+ var targetFolders = GetDefaultHandlerFolders();
+
+ if (item.WasPropertyDirty("IsDefault"))
+ {
+ // changing, this change doesn't trigger a save of the other languages.
+ // so we need to save all language files.
+ this.ExportAll(targetFolders, DefaultConfig, null);
+ }
+
+
+ var attempts = Export(item, targetFolders, DefaultConfig);
+
+ if (!newItem && item.WasPropertyDirty(nameof(ILanguage.IsoCode)))
+ {
+ // The language code changed, this can mean we need to do a full content export.
+ // + we should export the languages again!
+ uSyncTriggers.TriggerExport(targetFolders, new List() {
+ UdiEntityType.Document, UdiEntityType.Language }, null);
+ }
+
+ // we always clean up languages, because of the way they are stored.
+ foreach (var attempt in attempts.Where(x => x.Success))
+ {
+ this.CleanUp(item, attempt.FileName, targetFolders.Last());
+ }
+
+ }
+ }
+
+ ///
+ /// we don't support language deletion (because the keys are unstable)
+ ///
+ protected override IEnumerable DeleteMissingItems(int parentId, IEnumerable keys, bool reportOnly)
+ => Enumerable.Empty();
+
+ }
}