Skip to content
Closed
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,8 @@ $RECYCLE.BIN/
# Nuget package Umbraco.Cms.StaticAssets will copy them in during dotnet build
**/wwwroot/umbraco/

**/SeoToolkit.Umbraco.Site/App_Plugins/
**/SeoToolkit.Umbraco.Site/App_Plugins/
**/uSync/
**/umbraco/Data/Umbraco.sqlite.db
**/umbraco/Data/Umbraco.sqlite.db-shm
**/umbraco/Data/Umbraco.sqlite.db-wal
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ namespace SeoToolkit.Umbraco.MetaFields.Core.Interfaces.Services
{
public interface IMetaFieldsValueService
{
Dictionary<string, object> GetUserValues(int nodeId);
void AddValues(int nodeId, Dictionary<string, object> values);
Dictionary<string, object> GetUserValues(int nodeId, string culture = null);
void AddValues(int nodeId, Dictionary<string, object> values, string culture = null);
void Delete(int nodeId, string fieldAlias);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,37 @@ public MetaFieldsValueService(IMetaFieldsValueRepository repository, IVariationC
_cache = appCaches.RuntimeCache;
}

public Dictionary<string, object> GetUserValues(int nodeId)
public Dictionary<string, object> GetUserValues(int nodeId, string culture = null)
{
var culture = GetCulture();
return _cache.GetCacheItem($"{BaseCacheKey}{nodeId}_{culture}", () => _repository.GetAllValues(nodeId, culture), TimeSpan.FromMinutes(30));
var iso = culture ?? GetCulture();
return _cache.GetCacheItem($"{BaseCacheKey}{nodeId}_{iso}", () => _repository.GetAllValues(nodeId, iso), TimeSpan.FromMinutes(30));
}

public void AddValues(int nodeId, Dictionary<string, object> values)
public void AddValues(int nodeId, Dictionary<string, object> values, string culture = null)
{
var iso = culture ?? GetCulture();
foreach (var (key, value) in values)
{
if (_repository.Exists(nodeId, key, GetCulture()))
_repository.Update(nodeId, key, GetCulture(), value);
if (_repository.Exists(nodeId, key, iso))
_repository.Update(nodeId, key, iso, value);
else
{
_repository.Add(nodeId, key, GetCulture(), value);
_repository.Add(nodeId, key, iso, value);
}
}
ClearCache(nodeId);
}



public void Delete(int nodeId, string fieldAlias)
{
_repository.Delete(nodeId, fieldAlias, GetCulture());
}

private string GetCulture()
{
return _variationContextAccessor.VariationContext.Culture;
return _variationContextAccessor.VariationContext?.Culture ?? string.Empty;
}

private void ClearCache(int nodeId)
Expand Down
1 change: 1 addition & 0 deletions src/SeoToolkit.Umbraco.Site/SeoToolkit.Umbraco.Site.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<Watch Remove="umbraco\**" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\SeoToolkit.Umbraco.uSync.Core\SeoToolkit.Umbraco.uSync.Core.csproj" />
<ProjectReference Include="..\SeoToolkit.Umbraco\SeoToolkit.Umbraco.csproj" />
</ItemGroup>

Expand Down
9 changes: 9 additions & 0 deletions src/SeoToolkit.Umbraco.sln
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeoToolkit.Umbraco.Redirect
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeoToolkit.Umbraco.Redirects.Core", "SeoToolkit.Umbraco.Redirects.Core\SeoToolkit.Umbraco.Redirects.Core.csproj", "{566D1DBF-EC21-405C-BB92-424C4A1C1B88}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "uSync", "uSync", "{0080FA37-4D4E-44E0-8235-740C3D557D77}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SeoToolkit.Umbraco.uSync.Core", "SeoToolkit.Umbraco.uSync.Core\SeoToolkit.Umbraco.uSync.Core.csproj", "{A509609B-306B-41ED-9115-C3319ED779D9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -123,6 +127,10 @@ Global
{566D1DBF-EC21-405C-BB92-424C4A1C1B88}.Debug|Any CPU.Build.0 = Debug|Any CPU
{566D1DBF-EC21-405C-BB92-424C4A1C1B88}.Release|Any CPU.ActiveCfg = Release|Any CPU
{566D1DBF-EC21-405C-BB92-424C4A1C1B88}.Release|Any CPU.Build.0 = Release|Any CPU
{A509609B-306B-41ED-9115-C3319ED779D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A509609B-306B-41ED-9115-C3319ED779D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A509609B-306B-41ED-9115-C3319ED779D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A509609B-306B-41ED-9115-C3319ED779D9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -140,6 +148,7 @@ Global
{5B460335-8786-4FA9-911B-AEC5A752B88C} = {5641B436-FCCB-4D1A-9D25-6A39B95031CB}
{7C9ABE0D-106C-48C0-B0CF-DBBCD8AF334E} = {B0B49325-8248-4DB8-889D-211D9408D7A5}
{566D1DBF-EC21-405C-BB92-424C4A1C1B88} = {B0B49325-8248-4DB8-889D-211D9408D7A5}
{A509609B-306B-41ED-9115-C3319ED779D9} = {0080FA37-4D4E-44E0-8235-740C3D557D77}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {551ADBA5-3DFB-4300-929C-2BE0DB346636}
Expand Down
18 changes: 18 additions & 0 deletions src/SeoToolkit.Umbraco.uSync.Core/Composers/USyncComposer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Microsoft.Extensions.DependencyInjection;
using SeoToolkit.Umbraco.uSync.Core.Serializers;
using SeoToolkit.Umbraco.uSync.Core.XmlTrackers;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using uSync.Core.Tracking;

namespace SeoToolkit.Umbraco.uSync.Core.Composers;

public class USyncComposer : IComposer
{
public void Compose(IUmbracoBuilder builder)
{
builder.Services.AddTransient<MetaFieldValuesSerializer, MetaFieldValuesSerializer>();
builder.Services.AddTransient<ISyncTrackerBase, SeoToolkitXmlTracker>();
}
}
9 changes: 9 additions & 0 deletions src/SeoToolkit.Umbraco.uSync.Core/Constants/Serialization.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace SeoToolkit.Umbraco.uSync.Core.Constants;

public static class Serialization
{
public const string DocumentTypeSettingsDto = "DocumentTypeSettingsDto";
public const string MetaFieldValues = "MetaFieldValues";

public const string RootName = "Content";
}
110 changes: 110 additions & 0 deletions src/SeoToolkit.Umbraco.uSync.Core/Handlers/MetaFieldValuesHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System.Xml.Linq;
using Microsoft.Extensions.Logging;
using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.Services;
using SeoToolkit.Umbraco.uSync.Core.Serializers;
using SeoToolkit.Umbraco.uSync.Core.XmlTrackers;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Extensions;
using uSync.BackOffice.Configuration;
using uSync.BackOffice.Services;
using uSync.Core;
using uSync.Core.Serialization;

namespace uSync.BackOffice.SyncHandlers.Handlers;

[SyncHandler("seoToolkitMetaFieldValuesHandler", "SeoToolkit Meta Fields", "SeoToolkitMetaFields", uSyncConstants.Priorites.Content
, Icon = "icon-list", IsTwoPass = true, EntityType = Constants.UdiEntityType.Document)]
public class MetaFieldValuesHandler : ContentHandlerBase<IContent, IContentService>, ISyncHandler
{
private readonly IMetaFieldsValueService _metaFieldsValueService;
private readonly MetaFieldValuesSerializer _metaFieldValuesSerializer;
private readonly IContentService _contentService;

/// <summary>
/// the default group for which events matter (content group)
/// </summary>
public override string Group => uSyncConstants.Groups.Content;

public MetaFieldValuesHandler(MetaFieldValuesSerializer metaFieldValuesSerializer,IContentService contentService, ILogger<MetaFieldValuesHandler> logger,
IEntityService entityService, AppCaches appCaches, IShortStringHelper shortStringHelper,
SyncFileService syncFileService, uSyncEventService mutexService, uSyncConfigService uSyncConfigService,
ISyncItemFactory syncItemFactory) : base(logger, entityService, appCaches, shortStringHelper, syncFileService,
mutexService, uSyncConfigService, syncItemFactory)
{

_metaFieldValuesSerializer = metaFieldValuesSerializer;
_contentService = contentService;

this.serializer = _metaFieldValuesSerializer as ISyncSerializer<IContent>;
}

public override IEnumerable<uSyncAction> Export(IContent? item, string folder, HandlerSettings config)
{
if (item == null)
return uSyncAction.Fail(nameof(item), typeof(IContent).ToString(), ChangeType.Fail, "Item not set",
new ArgumentNullException(nameof(item))).AsEnumerableOfOne();

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

var attempt = _metaFieldValuesSerializer.Serialize(item, new SyncSerializerOptions(config.Settings));
if (!attempt.Success)
return uSyncActionHelper<XElement>.SetAction(attempt, filename, GetItemKey(item), this.Alias)
.AsEnumerableOfOne();

if (ShouldExport(attempt.Item, config))
{
// only write the file to disk if it should be exported.
syncFileService.SaveXElement(attempt.Item, filename);
}
else
{
return uSyncAction.SetAction(true, filename, type: typeof(IContent).ToString(),
change: ChangeType.NoChange, message: "Not Exported (Based on config)", filename: filename)
.AsEnumerableOfOne();
}

return uSyncActionHelper<XElement>.SetAction(attempt, filename, GetItemKey(item), this.Alias)
.AsEnumerableOfOne();
}


public override IEnumerable<uSyncAction> Import(XElement node, string filename, HandlerSettings config, SerializerFlags flags)
{
if (ShouldImport(node, new HandlerSettings()))
{
var attempt = _metaFieldValuesSerializer.Deserialize(node, new SyncSerializerOptions(config.Settings));
return uSyncActionHelper<IContent>.SetAction(attempt, filename,node.GetKey(), this.Alias)
.AsEnumerableOfOne();
}

return uSyncAction.SetAction(true, filename, type: typeof(IContent).ToString(),
change: ChangeType.NoChange, message: "Not Imported (Based on config)", filename: filename)
.AsEnumerableOfOne();
}


public override IEnumerable<uSyncAction> ReportFolder(string folder, HandlerSettings config, SyncUpdateCallback callback)
{
var reportActions= base.ReportFolder(folder, config, callback).ToList();
reportActions = reportActions.Select(action =>
{
if (!action.Details.Any())
{
return action;
}

var details = action.Details.ToList();
//First item will always be an error since the default XmlTracker will have a xml schema mismatch error.
details.RemoveAt(0);
action.Details = details;
return action;
}).ToList();

return reportActions;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="uSync" Version="10.1.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SeoToolkit.Umbraco.MetaFields.Core\SeoToolkit.Umbraco.MetaFields.Core.csproj" />
</ItemGroup>

</Project>
Loading