Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V10/merge 11.1 #487

Merged
merged 9 commits into from
Mar 29, 2023
7 changes: 6 additions & 1 deletion uSync.BackOffice/Configuration/uSyncSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,12 @@ public class uSyncSettings
/// </summary>
[DefaultValue(1000)]
public int SummaryLimit { get; set; } = 1000;


/// <summary>
/// list of addon (tabs) you don't want to show inside uSync dashboard.
/// </summary>
public string HideAddOns { get; set; } = "licence";

}

}
17 changes: 15 additions & 2 deletions uSync.BackOffice/Controllers/uSyncApiController_HandlerImports.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,22 @@ public void StartProcess([FromQuery]HandlerActions action)
/// <param name="actions"></param>
[HttpPost]
public void FinishProcess([FromQuery]HandlerActions action, IEnumerable<uSyncAction> actions)
=> _uSyncService.FinishBulkProcess(action, actions);

{
_uSyncService.FinishBulkProcess(action, actions);
_logger.LogInformation("{user} finished {action} process ({changes} changes)", GetCurrentUser(), action, actions.CountChanges());
}

private string GetCurrentUser()
{
try
{
return _backOfficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Name ?? "User";
}
catch
{
return "User";
}
}


private string GetValidImportFolder(string folder)
Expand Down
16 changes: 11 additions & 5 deletions uSync.BackOffice/Controllers/uSyncApiController_StatusChecks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;

Expand Down Expand Up @@ -101,20 +100,21 @@ private string GetLocal()
[HttpGet]
public AddOnInfo GetAddOns()
{
var addOnInfo = new AddOnInfo();

var isAdminUser = _backOfficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsAdmin();

var addOnInfo = new AddOnInfo();
var addOns = _typeFinder.FindClassesOfType<ISyncAddOn>();
foreach (var addOn in addOns)
{
var instance = Activator.CreateInstance(addOn) as ISyncAddOn;
if (instance != null)
{
addOnInfo.AddOns.Add(instance);
if (AddOnIsVisible(instance, isAdminUser)) {
addOnInfo.AddOns.Add(instance);
}
}
}


addOnInfo.Version = GetuSyncVersion();

addOnInfo.AddOns = addOnInfo.AddOns.OrderBy(x => x.SortOrder).ToList();
Expand All @@ -126,6 +126,12 @@ public AddOnInfo GetAddOns()
return addOnInfo;
}

/// <summary>
/// rules for how an Add on is displayed.
/// </summary>
private bool AddOnIsVisible(ISyncAddOn addOn, bool isAdmin)
=> isAdmin || !_uSyncConfig.Settings.HideAddOns.Contains(addOn.Alias, StringComparison.OrdinalIgnoreCase);

private string GetuSyncVersion()
{
var assembly = typeof(uSync).Assembly;
Expand Down
9 changes: 7 additions & 2 deletions uSync.BackOffice/Controllers/uSyncDashboardApiController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.BackOffice.Controllers;
using Umbraco.Cms.Web.Common.Attributes;
Expand Down Expand Up @@ -52,11 +53,12 @@ public partial class uSyncDashboardApiController : UmbracoAuthorizedJsonControll
private uSyncConfigService _uSyncConfig;

private readonly ITypeFinder _typeFinder;

private readonly IConfiguration _configuration;

private readonly string _uSyncTempPath;

private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor;

/// <summary>
/// Create a new uSyncDashboardApi Controller (via DI)
/// </summary>
Expand All @@ -73,7 +75,8 @@ public uSyncDashboardApiController(
SyncHandlerFactory syncHandlerFactory,
IHubContext<SyncHub> hubContext,
uSyncConfigService uSyncConfig,
SyncFileService syncFileService)
SyncFileService syncFileService,
IBackOfficeSecurityAccessor backOfficeSecurityAccessor)
{
_appCaches = appCaches;
_hostEnvironment = hostEnvironment;
Expand All @@ -91,6 +94,8 @@ public uSyncDashboardApiController(
_configuration = configuration;
_syncFileService = syncFileService;

_backOfficeSecurityAccessor = backOfficeSecurityAccessor;

if (hostingEnvironment != null)
{

Expand Down
12 changes: 10 additions & 2 deletions uSync.BackOffice/Hubs/uSyncHubRoutes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;

using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
Expand Down Expand Up @@ -36,8 +37,15 @@ public uSyncHubRoutes(
/// </summary>
public void CreateRoutes(IEndpointRouteBuilder endpoints)
{
if (_runtimeState.Level == Umbraco.Cms.Core.RuntimeLevel.Run)
endpoints.MapHub<SyncHub>(GetuSyncHubRoute());
switch (_runtimeState.Level)
{
case RuntimeLevel.Install:
case RuntimeLevel.Upgrade:
case RuntimeLevel.Run:
endpoints.MapHub<SyncHub>(GetuSyncHubRoute());
break;

}
}

/// <summary>
Expand Down
41 changes: 32 additions & 9 deletions uSync.Core/Serialization/Serializers/ContentSerializerBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
using System.Xml.Linq;

using Microsoft.Extensions.Logging;
Expand Down Expand Up @@ -206,14 +207,15 @@ protected virtual XElement SerializeProperties(TObject item, SyncSerializerOptio
|| options.GetSetting(uSyncConstants.DefaultsKey, false);

var excludedProperties = GetExcludedProperties(options);
var availableCultures = item.AvailableCultures.ToList();

var node = new XElement("Properties");

foreach (var property in item.Properties
.Where(x => !excludedProperties.InvariantContains(x.Alias))
.OrderBy(x => x.Alias))
{
var propertyNode = new XElement(property.Alias);
var elements = new List<XElement>();

// this can cause us false change readings
// but we need to preserve the values if they are blank
Expand Down Expand Up @@ -246,22 +248,43 @@ protected virtual XElement SerializeProperties(TObject item, SyncSerializerOptio
if (validNode)
{
valueNode.Add(new XCData(GetExportValue(GetPropertyValue(value), property.PropertyType, value.Culture, value.Segment)));
propertyNode.Add(valueNode);
elements.Add(valueNode);
}
}

if (property.Values == null || property.Values.Count == 0 && includeDefaults)

if (includeDefaults)
{
// add a blank one, for change clarity
// we do it like this because then it doesn't get collapsed in the XML serialization
var emptyValue = new XElement("Value");
emptyValue.Add(new XCData(string.Empty));
if (property.PropertyType.VariesByCulture())
{
foreach (var culture in availableCultures)
{
if (!cultures.IsValid(culture)) continue;

// add a blank value for any missing culture values.
if (!property.Values.Any(x => (x.Culture ?? "").Equals(culture, StringComparison.OrdinalIgnoreCase)))
{
elements.Add(new XElement("Value",
new XAttribute("Culture", culture),
new XCData(string.Empty)));
}
}
}
else if (property.Values == null || property.Values.Count == 0)
{
// add a blank one, for change clarity
// we do it like this because then it doesn't get collapsed in the XML serialization
elements.Add(new XElement("Value",
new XCData(string.Empty)));

propertyNode.Add(emptyValue);
}
}

if (propertyNode.HasElements)
if (elements.Count > 0)
{
// we sort them at the end because we might end up adding a blank culture value last.
var propertyNode = new XElement(property.Alias);
propertyNode.Add(elements.OrderBy(x => x.Attribute("Culture").ValueOrDefault("")));
node.Add(propertyNode);
}
}
Expand Down
83 changes: 82 additions & 1 deletion uSync.Core/Serialization/Serializers/DomainSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,26 @@ public class DomainSerializer : SyncSerializerBase<IDomain>, ISyncSerializer<IDo
private readonly IDomainService _domainService;
private readonly IContentService _contentService;
private readonly ILocalizationService _localizationService;
private readonly uSyncCapabilityChecker _capabilityChecker;

[Obsolete("Pass in the capablity checker (will be removed in v13)")]
public DomainSerializer(IEntityService entityService, ILogger<DomainSerializer> logger,
IDomainService domainService,
IContentService contentService,
ILocalizationService localizationService)
: this(entityService, logger, domainService, contentService, localizationService, null)
{ }
public DomainSerializer(IEntityService entityService, ILogger<DomainSerializer> logger,
IDomainService domainService,
IContentService contentService,
ILocalizationService localizationService,
uSyncCapabilityChecker capabilityChecker)
: base(entityService, logger)
{
this._domainService = domainService;
this._contentService = contentService;
this._localizationService = localizationService;
_capabilityChecker = capabilityChecker;
}

protected override SyncAttempt<IDomain> DeserializeCore(XElement node, SyncSerializerOptions options)
Expand Down Expand Up @@ -79,6 +89,17 @@ protected override SyncAttempt<IDomain> DeserializeCore(XElement node, SyncSeria
item.RootContentId = rootItem.Id;
}

if (_capabilityChecker?.HasSortableDomains == true)
{
var sortOrder = info.Element(_sortablePropertyName).ValueOrDefault(-2);
var existing = GetSortableValue(item);
if (sortOrder != -2 && sortOrder != existing)
{
changes.AddUpdate(_sortablePropertyName, sortOrder, existing);
SetSortableValue(item, sortOrder);
}
}

return SyncAttempt<IDomain>.Succeed(item.DomainName, item, ChangeType.Import, changes);

}
Expand Down Expand Up @@ -114,17 +135,77 @@ protected override SyncAttempt<XElement> SerializeCore(IDomain item, SyncSeriali
}
}

if (_capabilityChecker?.HasSortableDomains == true)
{
// domains can be sorted. we need to get the value via reflection.
info.Add(new XElement(_sortablePropertyName, GetSortableValue(item)));
}

node.Add(info);

return SyncAttempt<XElement>.SucceedIf(
node != null, item.DomainName, node, typeof(IDomain), ChangeType.Export);
}

private const string _sortablePropertyName = "SortOrder";

/// <summary>
/// Retreive the SortOrder value for the item
/// </summary>
/// <remarks>
/// 11.3.0+ sortable value got added to the IDomain interface.
/// </remarks>
private int GetSortableValue(IDomain item)
{
var property = item.GetType().GetProperty(_sortablePropertyName);
if (property == null) return 0;

var result = property.GetValue(item);

var attempt = result.TryConvertTo<int>();
return attempt.Success ? attempt.Result : 0;
}

/// <summary>
/// Set the SortOrder value for the item
/// </summary>
/// <remarks>
/// 11.3.0+ sortable value got added to the IDomain interface.
/// </remarks>
private void SetSortableValue(IDomain item, int sortOrder)
{
var property = item.GetType().GetProperty(_sortablePropertyName);
if (property == null) return;

property.SetValue(item, sortOrder);
}

/// <summary>
/// clean the xml of properties we don't want to compare
/// </summary>
/// <remarks>
/// in v11.3.0+ sort order got added, if we are running less than this, we want to
/// remove the sort order property from the xml so it doesn't get compared when it
/// can't be set.
/// </remarks>
protected override XElement CleanseNode(XElement node)
{
if (_capabilityChecker?.HasSortableDomains != true
&& node.Element(uSyncConstants.Xml.Info)?.Element(_sortablePropertyName) != null)
{
// doesn't have sortable domains, remove the sortable value from the XML
// so we don't get a false posistive when down syncing.
node.Element(uSyncConstants.Xml.Info).Element(_sortablePropertyName).Remove();
}

return base.CleanseNode(node);
}

public override IDomain FindItem(int id)
=> _domainService.GetById(id);

public override IDomain FindItem(Guid key)
=> null;
=> _domainService.GetAll(true).FirstOrDefault(x => x.Key == key);

public override IDomain FindItem(string alias)
=> _domainService.GetByName(alias);
Expand Down
9 changes: 5 additions & 4 deletions uSync.Core/uSyncCapabilityChecker.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Umbraco.Cms.Core.Configuration;

Expand Down Expand Up @@ -44,6 +40,11 @@ public bool HasRuntimeMode
/// User groups has Language Permissions - introduced in Umbraco 10.2.0
/// </summary>
public bool HasGroupLanguagePermissions => _version.Version >= new Version(10, 2, 0);

/// <summary>
/// Domains (Culture and Hostnames) can be sorted - introduced in v11.3.0
/// </summary>
public bool HasSortableDomains => _version.Version >= new Version(11, 3, 0);
}

}