mirror of https://github.com/Squidex/squidex.git
212 changed files with 3824 additions and 1790 deletions
@ -0,0 +1,110 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Diagnostics.CodeAnalysis; |
||||
|
using System.Linq; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core.Assets |
||||
|
{ |
||||
|
public sealed class AssetMetadata : Dictionary<string, IJsonValue> |
||||
|
{ |
||||
|
private static readonly char[] PathSeparators = { '.', '[', ']' }; |
||||
|
|
||||
|
public AssetMetadata SetPixelWidth(int value) |
||||
|
{ |
||||
|
this["pixelWidth"] = JsonValue.Create(value); |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public AssetMetadata SetPixelHeight(int value) |
||||
|
{ |
||||
|
this["pixelHeight"] = JsonValue.Create(value); |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public int? GetPixelWidth() |
||||
|
{ |
||||
|
if (TryGetValue("pixelWidth", out var n) && n is JsonNumber number) |
||||
|
{ |
||||
|
return (int)number.Value; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public int? GetPixelHeight() |
||||
|
{ |
||||
|
if (TryGetValue("pixelHeight", out var n) && n is JsonNumber number) |
||||
|
{ |
||||
|
return (int)number.Value; |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
public bool TryGetNumber(string name, out double result) |
||||
|
{ |
||||
|
if (TryGetValue(name, out var v) && v is JsonNumber n) |
||||
|
{ |
||||
|
result = n.Value; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
result = 0; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool TryGetString(string name, [MaybeNullWhen(false)] out string result) |
||||
|
{ |
||||
|
if (TryGetValue(name, out var v) && v is JsonString s) |
||||
|
{ |
||||
|
result = s.Value; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
result = null!; |
||||
|
|
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
public bool TryGetByPath(string? path, [MaybeNullWhen(false)] out object result) |
||||
|
{ |
||||
|
return TryGetByPath(path?.Split(PathSeparators, StringSplitOptions.RemoveEmptyEntries), out result!); |
||||
|
} |
||||
|
|
||||
|
public bool TryGetByPath(IEnumerable<string>? path, [MaybeNullWhen(false)] out object result) |
||||
|
{ |
||||
|
result = this; |
||||
|
|
||||
|
if (path == null || !path.Any()) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
result = null!; |
||||
|
|
||||
|
if (!TryGetValue(path.First(), out var json)) |
||||
|
{ |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
json.TryGetByPath(path.Skip(1), out var temp); |
||||
|
|
||||
|
result = temp!; |
||||
|
|
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,14 +1,17 @@ |
|||||
// ==========================================================================
|
// ==========================================================================
|
||||
// Squidex Headless CMS
|
// Squidex Headless CMS
|
||||
// ==========================================================================
|
// ==========================================================================
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
// All rights reserved. Licensed under the MIT license.
|
// All rights reserved. Licensed under the MIT license.
|
||||
// ==========================================================================
|
// ==========================================================================
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities |
namespace Squidex.Domain.Apps.Core.Assets |
||||
{ |
{ |
||||
public interface IUpdateableEntityWithVersion |
public enum AssetType |
||||
{ |
{ |
||||
long Version { get; set; } |
Unknown, |
||||
|
Image, |
||||
|
Audio, |
||||
|
Video |
||||
} |
} |
||||
} |
} |
||||
@ -0,0 +1,31 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using DeepEqual.Syntax; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Core |
||||
|
{ |
||||
|
public sealed class DeepComparer<T> : IEqualityComparer<T> |
||||
|
{ |
||||
|
public static readonly DeepComparer<T> Instance = new DeepComparer<T>(); |
||||
|
|
||||
|
private DeepComparer() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public bool Equals(T x, T y) |
||||
|
{ |
||||
|
return x.IsDeepEqual(y); |
||||
|
} |
||||
|
|
||||
|
public int GetHashCode(T obj) |
||||
|
{ |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,30 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors |
||||
|
{ |
||||
|
public sealed class FirstPascalPathConverter<TValue> : TransformVisitor<TValue> |
||||
|
{ |
||||
|
private static readonly FirstPascalPathConverter<TValue> Instance = new FirstPascalPathConverter<TValue>(); |
||||
|
|
||||
|
private FirstPascalPathConverter() |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public static FilterNode<TValue>? Transform(FilterNode<TValue> node) |
||||
|
{ |
||||
|
return node.Accept(Instance); |
||||
|
} |
||||
|
|
||||
|
public override FilterNode<TValue>? Visit(CompareFilter<TValue> nodeIn) |
||||
|
{ |
||||
|
return new CompareFilter<TValue>(nodeIn.Path.ToFirstPascalCase(), nodeIn.Operator, nodeIn.Value); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Linq; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Queries; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.MongoDb.Assets.Visitors |
||||
|
{ |
||||
|
public static class FirstPascalPathExtension |
||||
|
{ |
||||
|
public static PropertyPath ToFirstPascalCase(this PropertyPath path) |
||||
|
{ |
||||
|
var result = path.ToList(); |
||||
|
|
||||
|
result[0] = result[0].ToPascalCase(); |
||||
|
|
||||
|
return new PropertyPath(result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,222 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Domain.Apps.Entities.Assets.Commands; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Assets; |
||||
|
using Squidex.Infrastructure.Json.Objects; |
||||
|
using Squidex.Infrastructure.Tasks; |
||||
|
using TagLib; |
||||
|
using TagLib.Image; |
||||
|
using static TagLib.File; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Assets |
||||
|
{ |
||||
|
public sealed class FileTagAssetMetadataSource : IAssetMetadataSource |
||||
|
{ |
||||
|
private sealed class FileAbstraction : IFileAbstraction |
||||
|
{ |
||||
|
private readonly AssetFile file; |
||||
|
|
||||
|
public string Name |
||||
|
{ |
||||
|
get { return file.FileName; } |
||||
|
} |
||||
|
|
||||
|
public Stream ReadStream |
||||
|
{ |
||||
|
get { return file.OpenRead(); } |
||||
|
} |
||||
|
|
||||
|
public Stream WriteStream |
||||
|
{ |
||||
|
get { throw new NotSupportedException(); } |
||||
|
} |
||||
|
|
||||
|
public FileAbstraction(AssetFile file) |
||||
|
{ |
||||
|
this.file = file; |
||||
|
} |
||||
|
|
||||
|
public void CloseStream(Stream stream) |
||||
|
{ |
||||
|
stream.Close(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public Task EnhanceAsync(UploadAssetCommand command, HashSet<string>? tags) |
||||
|
{ |
||||
|
Enhance(command, tags); |
||||
|
|
||||
|
return TaskHelper.Done; |
||||
|
} |
||||
|
|
||||
|
private void Enhance(UploadAssetCommand command, HashSet<string>? tags) |
||||
|
{ |
||||
|
try |
||||
|
{ |
||||
|
using (var file = Create(new FileAbstraction(command.File), ReadStyle.Average)) |
||||
|
{ |
||||
|
if (file.Properties == null) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
var type = file.Properties.MediaTypes; |
||||
|
|
||||
|
if (type == MediaTypes.Audio) |
||||
|
{ |
||||
|
command.Type = AssetType.Audio; |
||||
|
} |
||||
|
else if (type == MediaTypes.Photo) |
||||
|
{ |
||||
|
command.Type = AssetType.Image; |
||||
|
} |
||||
|
else if (type.HasFlag(MediaTypes.Video)) |
||||
|
{ |
||||
|
command.Type = AssetType.Video; |
||||
|
} |
||||
|
|
||||
|
var pw = file.Properties.PhotoWidth; |
||||
|
var ph = file.Properties.PhotoHeight; |
||||
|
|
||||
|
if (pw > 0 && pw > 0) |
||||
|
{ |
||||
|
command.Metadata.SetPixelWidth(pw); |
||||
|
command.Metadata.SetPixelHeight(ph); |
||||
|
|
||||
|
if (tags != null) |
||||
|
{ |
||||
|
tags.Add("image"); |
||||
|
|
||||
|
var wh = pw + ph; |
||||
|
|
||||
|
if (wh > 2000) |
||||
|
{ |
||||
|
tags.Add("image/large"); |
||||
|
} |
||||
|
else if (wh > 1000) |
||||
|
{ |
||||
|
tags.Add("image/medium"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
tags.Add("image/small"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TryAddString(string name, string? value) |
||||
|
{ |
||||
|
if (!string.IsNullOrWhiteSpace(value)) |
||||
|
{ |
||||
|
command.Metadata.Add(name, JsonValue.Create(value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TryAddInt(string name, int? value) |
||||
|
{ |
||||
|
if (value > 0) |
||||
|
{ |
||||
|
command.Metadata.Add(name, JsonValue.Create(value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TryAddDouble(string name, double? value) |
||||
|
{ |
||||
|
if (value > 0) |
||||
|
{ |
||||
|
command.Metadata.Add(name, JsonValue.Create(value)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void TryAddTimeSpan(string name, TimeSpan value) |
||||
|
{ |
||||
|
if (value != TimeSpan.Zero) |
||||
|
{ |
||||
|
command.Metadata.Add(name, JsonValue.Create(value.ToString())); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
if (file.Tag is ImageTag imageTag) |
||||
|
{ |
||||
|
TryAddDouble("locationLatitude", imageTag.Latitude); |
||||
|
TryAddDouble("locationLongitude", imageTag.Longitude); |
||||
|
|
||||
|
TryAddString("created", imageTag.DateTime?.ToIso8601()); |
||||
|
} |
||||
|
|
||||
|
TryAddTimeSpan("duration", file.Properties.Duration); |
||||
|
|
||||
|
TryAddInt("audioBitrate", file.Properties.AudioBitrate); |
||||
|
TryAddInt("audioChannels", file.Properties.AudioChannels); |
||||
|
TryAddInt("audioSampleRate", file.Properties.AudioSampleRate); |
||||
|
TryAddInt("bitsPerSample", file.Properties.BitsPerSample); |
||||
|
TryAddInt("imageQuality", file.Properties.PhotoQuality); |
||||
|
TryAddInt("videoWidth", file.Properties.VideoWidth); |
||||
|
TryAddInt("videoHeight", file.Properties.VideoHeight); |
||||
|
|
||||
|
TryAddString("description", file.Properties.Description); |
||||
|
} |
||||
|
} |
||||
|
catch |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public IEnumerable<string> Format(IAssetEntity asset) |
||||
|
{ |
||||
|
var metadata = asset.Metadata; |
||||
|
|
||||
|
switch (asset.Type) |
||||
|
{ |
||||
|
case AssetType.Image: |
||||
|
{ |
||||
|
if (metadata.TryGetNumber("pixelWidth", out var w) && |
||||
|
metadata.TryGetNumber("pixelHeight", out var h)) |
||||
|
{ |
||||
|
yield return $"{w}x{h}px"; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
case AssetType.Video: |
||||
|
{ |
||||
|
if (metadata.TryGetNumber("videoWidth", out var w) && |
||||
|
metadata.TryGetNumber("videoHeight", out var h)) |
||||
|
{ |
||||
|
yield return $"{w}x{h}pt"; |
||||
|
} |
||||
|
|
||||
|
if (metadata.TryGetString("duration", out var duration)) |
||||
|
{ |
||||
|
yield return duration; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
case AssetType.Audio: |
||||
|
{ |
||||
|
if (metadata.TryGetString("duration", out var duration)) |
||||
|
{ |
||||
|
yield return duration; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,20 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Entities.Assets.Commands; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Assets |
||||
|
{ |
||||
|
public interface IAssetMetadataSource |
||||
|
{ |
||||
|
Task EnhanceAsync(UploadAssetCommand command, HashSet<string>? tags); |
||||
|
|
||||
|
IEnumerable<string> Format(IAssetEntity asset); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,69 @@ |
|||||
|
// ==========================================================================
|
||||
|
// Squidex Headless CMS
|
||||
|
// ==========================================================================
|
||||
|
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
||||
|
// All rights reserved. Licensed under the MIT license.
|
||||
|
// ==========================================================================
|
||||
|
|
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Squidex.Domain.Apps.Core.Assets; |
||||
|
using Squidex.Domain.Apps.Entities.Assets.Commands; |
||||
|
using Squidex.Infrastructure; |
||||
|
using Squidex.Infrastructure.Assets; |
||||
|
|
||||
|
namespace Squidex.Domain.Apps.Entities.Assets |
||||
|
{ |
||||
|
public sealed class ImageMetadataSource : IAssetMetadataSource |
||||
|
{ |
||||
|
private readonly IAssetThumbnailGenerator assetThumbnailGenerator; |
||||
|
|
||||
|
public ImageMetadataSource(IAssetThumbnailGenerator assetThumbnailGenerator) |
||||
|
{ |
||||
|
Guard.NotNull(assetThumbnailGenerator); |
||||
|
|
||||
|
this.assetThumbnailGenerator = assetThumbnailGenerator; |
||||
|
} |
||||
|
|
||||
|
public async Task EnhanceAsync(UploadAssetCommand command, HashSet<string>? tags) |
||||
|
{ |
||||
|
var imageInfo = await assetThumbnailGenerator.GetImageInfoAsync(command.File.OpenRead()); |
||||
|
|
||||
|
if (imageInfo != null) |
||||
|
{ |
||||
|
command.Type = AssetType.Image; |
||||
|
|
||||
|
command.Metadata.SetPixelWidth(imageInfo.PixelWidth); |
||||
|
command.Metadata.SetPixelHeight(imageInfo.PixelHeight); |
||||
|
|
||||
|
if (tags != null) |
||||
|
{ |
||||
|
tags.Add("image"); |
||||
|
|
||||
|
var wh = imageInfo.PixelWidth + imageInfo.PixelHeight; |
||||
|
|
||||
|
if (wh > 2000) |
||||
|
{ |
||||
|
tags.Add("image/large"); |
||||
|
} |
||||
|
else if (wh > 1000) |
||||
|
{ |
||||
|
tags.Add("image/medium"); |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
tags.Add("image/small"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public IEnumerable<string> Format(IAssetEntity asset) |
||||
|
{ |
||||
|
if (asset.Type == AssetType.Image) |
||||
|
{ |
||||
|
yield return $"{asset.Metadata.GetPixelWidth()}x{asset.Metadata.GetPixelHeight()}px"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,39 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschraenkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System.Collections.Generic; |
|
||||
using Squidex.Domain.Apps.Entities.Assets.Commands; |
|
||||
using Squidex.Domain.Apps.Entities.Tags; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities.Assets |
|
||||
{ |
|
||||
public sealed class ImageTagGenerator : ITagGenerator<CreateAsset> |
|
||||
{ |
|
||||
public void GenerateTags(CreateAsset source, HashSet<string> tags) |
|
||||
{ |
|
||||
if (source.ImageInfo != null) |
|
||||
{ |
|
||||
tags.Add("image"); |
|
||||
|
|
||||
var wh = source.ImageInfo.PixelWidth + source.ImageInfo.PixelHeight; |
|
||||
|
|
||||
if (wh > 2000) |
|
||||
{ |
|
||||
tags.Add("image/large"); |
|
||||
} |
|
||||
else if (wh > 1000) |
|
||||
{ |
|
||||
tags.Add("image/medium"); |
|
||||
} |
|
||||
else |
|
||||
{ |
|
||||
tags.Add("image/small"); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,82 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using Squidex.Domain.Apps.Events; |
|
||||
using Squidex.Infrastructure.EventSourcing; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities |
|
||||
{ |
|
||||
public static class EntityMapper |
|
||||
{ |
|
||||
public static T Update<T>(this T entity, Envelope<IEvent> envelope, Action<SquidexEvent, T>? updater = null) where T : IEntity |
|
||||
{ |
|
||||
var @event = (SquidexEvent)envelope.Payload; |
|
||||
|
|
||||
var headers = envelope.Headers; |
|
||||
|
|
||||
SetId(entity, headers); |
|
||||
SetCreated(entity, headers); |
|
||||
SetCreatedBy(entity, @event); |
|
||||
SetLastModified(entity, headers); |
|
||||
SetLastModifiedBy(entity, @event); |
|
||||
SetVersion(entity, headers); |
|
||||
|
|
||||
updater?.Invoke(@event, entity); |
|
||||
|
|
||||
return entity; |
|
||||
} |
|
||||
|
|
||||
private static void SetId(IEntity entity, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntity updateable && updateable.Id == Guid.Empty) |
|
||||
{ |
|
||||
updateable.Id = headers.AggregateId(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetVersion(IEntity entity, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntityWithVersion updateable) |
|
||||
{ |
|
||||
updateable.Version = headers.EventStreamNumber(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetCreated(IEntity entity, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntity updateable && updateable.Created == default) |
|
||||
{ |
|
||||
updateable.Created = headers.Timestamp(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetCreatedBy(IEntity entity, SquidexEvent @event) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntityWithCreatedBy withCreatedBy && withCreatedBy.CreatedBy == null) |
|
||||
{ |
|
||||
withCreatedBy.CreatedBy = @event.Actor; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetLastModified(IEntity entity, EnvelopeHeaders headers) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntity updateable) |
|
||||
{ |
|
||||
updateable.LastModified = headers.Timestamp(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
private static void SetLastModifiedBy(IEntity entity, SquidexEvent @event) |
|
||||
{ |
|
||||
if (entity is IUpdateableEntityWithLastModifiedBy withModifiedBy) |
|
||||
{ |
|
||||
withModifiedBy.LastModifiedBy = @event.Actor; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,21 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using System; |
|
||||
using NodaTime; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities |
|
||||
{ |
|
||||
public interface IUpdateableEntity |
|
||||
{ |
|
||||
Guid Id { get; set; } |
|
||||
|
|
||||
Instant Created { get; set; } |
|
||||
|
|
||||
Instant LastModified { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,16 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities |
|
||||
{ |
|
||||
public interface IUpdateableEntityWithCreatedBy |
|
||||
{ |
|
||||
RefToken CreatedBy { get; set; } |
|
||||
} |
|
||||
} |
|
||||
@ -1,16 +0,0 @@ |
|||||
// ==========================================================================
|
|
||||
// Squidex Headless CMS
|
|
||||
// ==========================================================================
|
|
||||
// Copyright (c) Squidex UG (haftungsbeschränkt)
|
|
||||
// All rights reserved. Licensed under the MIT license.
|
|
||||
// ==========================================================================
|
|
||||
|
|
||||
using Squidex.Infrastructure; |
|
||||
|
|
||||
namespace Squidex.Domain.Apps.Entities |
|
||||
{ |
|
||||
public interface IUpdateableEntityWithLastModifiedBy |
|
||||
{ |
|
||||
RefToken LastModifiedBy { get; set; } |
|
||||
} |
|
||||
} |
|
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue