From 243ee7229e53b930af34e36035d6380abfbdd907 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 12 Jan 2021 11:37:15 +0300 Subject: [PATCH 01/70] CmsKit - Add blog entities --- .../Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs | 10 ++++++++++ .../Volo/CmsKit/Blogs/BlogPost.cs | 13 +++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs new file mode 100644 index 0000000000..a7720d2a41 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public class Blog : FullAuditedAggregateRoot + { + public string Name { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs new file mode 100644 index 0000000000..f15dd87f75 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -0,0 +1,13 @@ +using System; +using Volo.Abp.Domain.Entities.Auditing; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public class BlogPost : FullAuditedEntity + { + public Guid BlogId { get; set; } + public string Title { get; set; } + public string CoverImageUrl { get; set; } + public bool IsPublished { get; set; } + } +} From 624c971e50744712e66f426e9e5ca26c2a3d549d Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 12 Jan 2021 11:37:31 +0300 Subject: [PATCH 02/70] CmsKit - Add BlogsFeature as global feature --- .../Volo/CmsKit/GlobalFeatures/BlogsFeature.cs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/BlogsFeature.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/BlogsFeature.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/BlogsFeature.cs new file mode 100644 index 0000000000..1b094ecf2d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/GlobalFeatures/BlogsFeature.cs @@ -0,0 +1,17 @@ +using JetBrains.Annotations; +using Volo.Abp.GlobalFeatures; + +namespace Volo.CmsKit.GlobalFeatures +{ + [GlobalFeatureName(Name)] + public class BlogsFeature : GlobalFeature + { + public const string Name = "CmsKit.Blogs"; + + internal BlogsFeature( + [NotNull] GlobalCmsKitFeatures cmsKit + ) : base(cmsKit) + { + } + } +} From 8f29f3c267acd02e19d4d5642708e1f7eb1294d3 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 12 Jan 2021 12:02:38 +0300 Subject: [PATCH 03/70] CmsKit - EfCore configuration of Blogs --- .../Volo/CmsKit/Blogs/BlogConsts.cs | 7 ++++ .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 9 ++++ .../EntityFrameworkCore/CmsKitDbContext.cs | 3 ++ .../CmsKitDbContextModelCreatingExtensions.cs | 41 +++++++++++++++---- 4 files changed, 52 insertions(+), 8 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs new file mode 100644 index 0000000000..e722d4656d --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs @@ -0,0 +1,7 @@ +namespace Volo.CmsKit.Blogs +{ + public class BlogConsts + { + public static int MaxNameLength { get; set; } = 64; + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs new file mode 100644 index 0000000000..1a4a657680 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -0,0 +1,9 @@ +namespace Volo.CmsKit.Blogs +{ + public class BlogPostConsts + { + public static int MaxTitleLength { get; set; } = 256; + + public static int MaxCoverImageUrlLength { get; set; } = 2048; + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs index 0a4213e1b4..87ad080af6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; @@ -22,6 +23,8 @@ namespace Volo.CmsKit.EntityFrameworkCore public DbSet Tags { get; set; } public DbSet EntityTags { get; set; } public DbSet Pages { get; set; } + public DbSet Blogs { get; set; } + public DbSet BlogPosts { get; set; } public CmsKitDbContext(DbContextOptions options) : base(options) diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 2cc5e8a52a..c7180fb098 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -13,6 +13,8 @@ using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Tags; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit.EntityFrameworkCore { @@ -58,8 +60,8 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(x => x.EntityId).IsRequired().HasMaxLength(UserReactionConsts.MaxEntityIdLength); b.Property(x => x.ReactionName).IsRequired().HasMaxLength(UserReactionConsts.MaxReactionNameLength); - b.HasIndex(x => new {x.TenantId, x.EntityType, x.EntityId, x.ReactionName}); - b.HasIndex(x => new {x.TenantId, x.CreatorId, x.EntityType, x.EntityId, x.ReactionName}); + b.HasIndex(x => new { x.TenantId, x.EntityType, x.EntityId, x.ReactionName }); + b.HasIndex(x => new { x.TenantId, x.CreatorId, x.EntityType, x.EntityId, x.ReactionName }); }); } @@ -76,8 +78,8 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(x => x.Text).IsRequired().HasMaxLength(CommentConsts.MaxTextLength); b.Property(x => x.RepliedCommentId); - b.HasIndex(x => new {x.TenantId, x.EntityType, x.EntityId}); - b.HasIndex(x => new {x.TenantId, x.RepliedCommentId}); + b.HasIndex(x => new { x.TenantId, x.EntityType, x.EntityId }); + b.HasIndex(x => new { x.TenantId, x.RepliedCommentId }); }); } @@ -173,7 +175,7 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(x => x.EntityType).IsRequired().HasMaxLength(TagConsts.MaxEntityTypeLength); b.Property(x => x.Name).IsRequired().HasMaxLength(TagConsts.MaxNameLength); - b.HasIndex(x => new {x.TenantId, x.Name}); + b.HasIndex(x => new { x.TenantId, x.Name }); }); builder.Entity(b => @@ -182,12 +184,12 @@ namespace Volo.CmsKit.EntityFrameworkCore b.ConfigureByConvention(); - b.HasKey(x => new {x.EntityId, x.TagId}); + b.HasKey(x => new { x.EntityId, x.TagId }); b.Property(x => x.EntityId).IsRequired(); b.Property(x => x.TagId).IsRequired(); - b.HasIndex(x => new {x.TenantId, x.EntityId, x.TagId}); + b.HasIndex(x => new { x.TenantId, x.EntityId, x.TagId }); }); } @@ -203,7 +205,30 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(x => x.Url).IsRequired().HasMaxLength(PageConsts.MaxUrlLength); b.Property(x => x.Description).HasMaxLength(PageConsts.MaxDescriptionLength); - b.HasIndex(x => new {x.TenantId, x.Url}); + b.HasIndex(x => new { x.TenantId, x.Url }); + }); + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "Blogs", options.Schema); + + b.ConfigureByConvention(); + + b.Property(p => p.Name).IsRequired().HasMaxLength(BlogConsts.MaxNameLength); + }); + + builder.Entity(b => + { + b.ToTable(options.TablePrefix + "BlogPosts", options.Schema); + + b.ConfigureByConvention(); + + b.Property(p => p.Title).IsRequired().HasMaxLength(BlogPostConsts.MaxTitleLength); + + b.Property(p => p.CoverImageUrl).HasMaxLength(BlogPostConsts.MaxCoverImageUrlLength); }); } } From 76cdea1e5802e52acd8204ba977c345df8e2397e Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 12 Jan 2021 12:09:38 +0300 Subject: [PATCH 04/70] CmsKit - Blog mongodb configuration --- .../Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs | 5 +++++ .../MongoDB/CmsKitMongoDbContextExtensions.cs | 11 +++++++++++ .../Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs | 15 ++++++++++----- 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index c61d8d9a13..45f3275acc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; @@ -31,6 +32,10 @@ namespace Volo.CmsKit.MongoDB public IMongoCollection Pages => Collection(); + public IMongoCollection Blogs => Collection(); + + public IMongoCollection BlogPosts => Collection(); + protected override void CreateModel(IMongoModelBuilder modelBuilder) { base.CreateModel(modelBuilder); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs index 7f6dcfecf3..3d718d6955 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs @@ -3,6 +3,7 @@ using Volo.Abp; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; @@ -64,6 +65,16 @@ namespace Volo.CmsKit.MongoDB { x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Pages"; }); + + builder.Entity(x => + { + x.CollectionName = CmsKitDbProperties.DbTablePrefix + "Blogs"; + }); + + builder.Entity(x => + { + x.CollectionName = CmsKitDbProperties.DbTablePrefix + "BlogPosts"; + }); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index d33a5ee371..4fcdea7d55 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -3,6 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; @@ -20,15 +21,19 @@ namespace Volo.CmsKit.MongoDB IMongoCollection Comments { get; } IMongoCollection CmsUsers { get; } - + IMongoCollection Ratings { get; } - + IMongoCollection Contents { get; } - + IMongoCollection Tags { get; } - + IMongoCollection EntityTags { get; } - + IMongoCollection Pages { get; } + + IMongoCollection Blogs { get; } + + IMongoCollection BlogPosts { get; } } } From f0310da95f10dedff6cb0739880e42a6cced494e Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 14 Jan 2021 14:52:59 +0300 Subject: [PATCH 05/70] CmsKit - Add BlogPost Domain logic --- .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 4 ++ .../Volo/CmsKit/CmsKitErrorCodes.cs | 5 ++ .../Volo/CmsKit/Blogs/BlogPost.cs | 56 +++++++++++++++++-- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 40 +++++++++++++ .../BlogPostUrlSlugAlreadyExistException.cs | 27 +++++++++ .../Volo/CmsKit/Blogs/IBlogPostManager.cs | 12 ++++ .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 14 +++++ .../CmsKit/Blogs/BlogPostEfCoreRepository.cs | 24 ++++++++ .../CmsKitDbContextModelCreatingExtensions.cs | 5 ++ .../MongoDB/Blogs/BlogPostMongoRepository.cs | 22 ++++++++ 10 files changed, 205 insertions(+), 4 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 1a4a657680..4f3ad07f7b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -5,5 +5,9 @@ public static int MaxTitleLength { get; set; } = 256; public static int MaxCoverImageUrlLength { get; set; } = 2048; + + public static int MaxUrlSlugLength { get; set; } = 256; + + public static int MinUrlSlugLength { get; set; } = 2; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index 67042b5cc6..4edf42dcf8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -10,5 +10,10 @@ { public const string UrlAlreadyExist = "CmsKit:Page:0001"; } + + public static class Blogs + { + public const string UrlSlugAlreadyExist = "CmsKit:BlogPost:0001"; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index f15dd87f75..ac7c1221c0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -1,13 +1,61 @@ -using System; +using JetBrains.Annotations; +using System; +using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs { public class BlogPost : FullAuditedEntity { - public Guid BlogId { get; set; } - public string Title { get; set; } + public Guid BlogId { get; protected set; } + + public string Title { get; protected set; } + + public string UrlSlug { get; protected set; } + public string CoverImageUrl { get; set; } - public bool IsPublished { get; set; } + + public bool IsPublished { get; protected set; } + + public DateTime? PublishDate { get; protected set; } + + protected BlogPost() + { + } + + public BlogPost( + Guid blogId, + [NotNull] string title, + [NotNull] string urlSlug, + [CanBeNull] string coverImageUrl = null, + bool isPublished = true) + { + BlogId = blogId; + SetTitle(title); + SetUrlSlug(urlSlug); + CoverImageUrl = coverImageUrl; + IsPublished = isPublished; + } + + public void SetTitle(string title) + { + Title = Check.NotNullOrWhiteSpace(title, nameof(title), BlogPostConsts.MaxTitleLength); + } + + public void SetUrlSlug(string urlSlug) + { + UrlSlug = Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); + } + + public void SetIsPublished(bool isPublished) + { + if (!IsPublished && isPublished) + { + this.PublishDate = DateTime.UtcNow; + } + + IsPublished = IsPublished; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs new file mode 100644 index 0000000000..f3a268e956 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public class BlogPostManager : IBlogPostManager + { + protected readonly IBlogPostRepository _blogPostRepository; + + public BlogPostManager(IBlogPostRepository blogPostRepository) + { + _blogPostRepository = blogPostRepository; + } + + public async Task CreateAsync(BlogPost blogPost) + { + await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); + + return await _blogPostRepository.InsertAsync(blogPost); + } + + public async Task UpdateAsync(BlogPost blogPost) + { + await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); + + await _blogPostRepository.UpdateAsync(blogPost); + } + + private async Task CheckUrlSlugExistenceAsync(string urlSlug) + { + if (await _blogPostRepository.SlugExistsAsync(urlSlug)) + { + throw new BlogPostUrlSlugAlreadyExistException(urlSlug); + } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs new file mode 100644 index 0000000000..bccffef418 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public class BlogPostUrlSlugAlreadyExistException : BusinessException + { + internal BlogPostUrlSlugAlreadyExistException(string code = null, string message = null, string details = null, Exception innerException = null, Microsoft.Extensions.Logging.LogLevel logLevel = Microsoft.Extensions.Logging.LogLevel.Warning) : base(code, message, details, innerException, logLevel) + { + } + + internal BlogPostUrlSlugAlreadyExistException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) + { + } + + public BlogPostUrlSlugAlreadyExistException(string urlSlug) + { + Code = CmsKitErrorCodes.Blogs.UrlSlugAlreadyExist; + + WithData(nameof(BlogPost.UrlSlug), urlSlug); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs new file mode 100644 index 0000000000..516e8f7835 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public interface IBlogPostManager + { + Task CreateAsync(BlogPost blogPost); + + Task UpdateAsync(BlogPost blogPost); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs new file mode 100644 index 0000000000..dfd0ec7977 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories; + +namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +{ + public interface IBlogPostRepository : IBasicRepository + { + Task SlugExistsAsync(string slug); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs new file mode 100644 index 0000000000..79a2bbe50f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore; +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Blogs +{ + public class BlogPostEfCoreRepository : EfCoreRepository, IBlogPostRepository + { + public BlogPostEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task SlugExistsAsync(string slug) + { + var dbSet = await GetDbSetAsync(); + + return await dbSet.AnyAsync(x => x.UrlSlug.ToLower() == slug); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index c7180fb098..79a245e693 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -15,6 +15,7 @@ using Volo.CmsKit.Ratings; using Volo.CmsKit.Tags; using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs; +using System.Security.Cryptography.X509Certificates; namespace Volo.CmsKit.EntityFrameworkCore { @@ -228,7 +229,11 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.Title).IsRequired().HasMaxLength(BlogPostConsts.MaxTitleLength); + b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogPostConsts.MaxUrlSlugLength); + b.Property(p => p.CoverImageUrl).HasMaxLength(BlogPostConsts.MaxCoverImageUrlLength); + + b.HasIndex(x => x.UrlSlug); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs new file mode 100644 index 0000000000..55eb84e1bb --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs @@ -0,0 +1,22 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.MongoDB.Blogs +{ + public class BlogPostMongoRepository : MongoDbRepository, IBlogPostRepository + { + public BlogPostMongoRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + + public async Task SlugExistsAsync(string slug) + { + var queryable = await GetQueryableAsync(); + + return await AsyncExecuter.AnyAsync(queryable, x => x.UrlSlug.ToLower() == slug); + } + } +} From 77c384a27dcc1a8593614520e723a4a13edc0b0e Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 15 Jan 2021 10:14:05 +0300 Subject: [PATCH 06/70] CmsKit - Normalization of url slug --- .../Volo/CmsKit/Blogs/BlogPost.cs | 27 ++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index ac7c1221c0..8b5ea4f8f9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -1,5 +1,6 @@ using JetBrains.Annotations; using System; +using System.Text.RegularExpressions; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.CmsKit.Blogs; @@ -45,7 +46,9 @@ namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs public void SetUrlSlug(string urlSlug) { - UrlSlug = Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); + Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); + + UrlSlug = NormalizeUrlSlug(urlSlug); } public void SetIsPublished(bool isPublished) @@ -57,5 +60,27 @@ namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs IsPublished = IsPublished; } + + private string NormalizeUrlSlug(string value) + { + value = value.ToLowerInvariant(); + + // TODO: Find best way to unidecode. + // value = value.Unidecode(); + + // Replace spaces + value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled); + + // Remove invalid chars + value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled); + + // Trim dashes from end & dots + value = value.Trim('-', '_', '.'); + + // Replace double occurences of - or _ + value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled); + + return value; + } } } From 80e556e1e84a7ba6a7908a77d208f121bdd34c05 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 15 Jan 2021 13:34:38 +0300 Subject: [PATCH 07/70] CmsKit - Add BlogAdminAppService --- .../Volo/CmsKit/Admin/Blogs/BlogDto.cs | 10 ++++++++++ .../Admin/Blogs/IBlogAdminAppService.cs | 9 +++++++++ .../Permissions/CmsKitAdminPermissions.cs | 8 ++++++++ .../CmsKit/Admin/Blogs/BlogAdminAppService.cs | 20 +++++++++++++++++++ 4 files changed, 47 insertions(+) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs new file mode 100644 index 0000000000..9c88a0ed01 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs @@ -0,0 +1,10 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Admin.Blogs +{ + public class BlogDto : EntityDto + { + public string Name { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs new file mode 100644 index 0000000000..dfc488b0a3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs @@ -0,0 +1,9 @@ +using System; +using Volo.Abp.Application.Services; + +namespace Volo.CmsKit.Admin.Blogs +{ + public interface IBlogAdminAppService : ICrudAppService + { + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index a08ba9d6c8..ffe716b13c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -29,5 +29,13 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } + + public static class Blogs + { + public const string Default = GroupName + ".Blogs"; + public const string Create = Default + ".Create"; + public const string Update = Default + ".Update"; + public const string Delete = Default + ".Delete"; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs new file mode 100644 index 0000000000..b66cf8b940 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -0,0 +1,20 @@ +using System; +using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Repositories; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Blogs +{ + public class BlogAdminAppService : CrudAppService, IBlogAdminAppService + { + public BlogAdminAppService(IRepository repository) : base(repository) + { + GetListPolicyName = CmsKitAdminPermissions.Blogs.Default; + GetPolicyName = CmsKitAdminPermissions.Blogs.Default; + CreatePolicyName = CmsKitAdminPermissions.Blogs.Create; + UpdatePolicyName = CmsKitAdminPermissions.Blogs.Update; + DeletePolicyName = CmsKitAdminPermissions.Blogs.Delete; + } + } +} From 93d4d441b874693177a01a8663e30190185e3399 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 15 Jan 2021 14:26:32 +0300 Subject: [PATCH 08/70] CmsKit - Add BlogPost Application Services --- .../Volo/CmsKit/Admin/Blogs/BlogPostDto.cs | 20 +++++ .../Admin/Blogs/CreateUpdateBlogPostDto.cs | 17 ++++ .../Admin/Blogs/IBlogPostAdminAppService.cs | 17 ++++ .../Permissions/CmsKitAdminPermissions.cs | 7 ++ .../CmsKit/Admin/Blogs/BlogAdminAppService.cs | 4 +- .../Admin/Blogs/BlogPostAdminAppService.cs | 80 +++++++++++++++++++ .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 + .../CmsKit/Blogs/BlogPostEfCoreRepository.cs | 5 ++ .../MongoDB/Blogs/BlogPostMongoRepository.cs | 5 ++ 9 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs new file mode 100644 index 0000000000..823efdfc4e --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs @@ -0,0 +1,20 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Admin.Blogs +{ + public class BlogPostDto : EntityDto + { + public Guid BlogId { get; protected set; } + + public string Title { get; protected set; } + + public string UrlSlug { get; protected set; } + + public string CoverImageUrl { get; set; } + + public bool IsPublished { get; protected set; } + + public DateTime? PublishDate { get; protected set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs new file mode 100644 index 0000000000..761eb15c55 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs @@ -0,0 +1,17 @@ +using System; + +namespace Volo.CmsKit.Admin.Blogs +{ + public class CreateUpdateBlogPostDto + { + public Guid BlogId { get; protected set; } + + public string Title { get; protected set; } + + public string UrlSlug { get; protected set; } + + public string CoverImageUrl { get; set; } + + public bool IsPublished { get; protected set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs new file mode 100644 index 0000000000..195778d92b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs @@ -0,0 +1,17 @@ +using System; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; + +namespace Volo.CmsKit.Admin.Blogs +{ + public interface IBlogPostAdminAppService + : ICrudAppService< + BlogPostDto, + Guid, + PagedAndSortedResultRequestDto, + CreateUpdateBlogPostDto> + { + Task GetByUrlSlugAsync(string urlSlug); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index ffe716b13c..2a70feefc5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -37,5 +37,12 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } + public static class BlogPosts + { + public const string Default = GroupName + ".BlogPosts"; + public const string Create = Default + ".Create"; + public const string Update = Default + ".Update"; + public const string Delete = Default + ".Delete"; + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index b66cf8b940..ba30b20814 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.AspNetCore.Authorization; +using System; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; @@ -6,6 +7,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { + [Authorize(CmsKitAdminPermissions.Blogs.Default)] public class BlogAdminAppService : CrudAppService, IBlogAdminAppService { public BlogAdminAppService(IRepository repository) : base(repository) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs new file mode 100644 index 0000000000..87c3f24fc1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -0,0 +1,80 @@ +using Microsoft.AspNetCore.Authorization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Application.Services; +using Volo.Abp.Domain.Repositories; +using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Blogs +{ + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] + public class BlogPostAdminAppService + : CrudAppService< + BlogPost, + BlogPostDto, + Guid, + PagedAndSortedResultRequestDto, + CreateUpdateBlogPostDto> + , IBlogPostAdminAppService + { + protected readonly IBlogPostManager _blogPostManager; + protected readonly IBlogPostRepository _blogPostRepository; + + protected BlogPostAdminAppService( + IRepository repository, + IBlogPostManager blogPostManager, + IBlogPostRepository blogPostRepository) : base(repository) + { + _blogPostManager = blogPostManager; + _blogPostRepository = blogPostRepository; + + + GetListPolicyName = CmsKitAdminPermissions.BlogPosts.Default; + GetPolicyName = CmsKitAdminPermissions.BlogPosts.Default; + CreatePolicyName = CmsKitAdminPermissions.BlogPosts.Create; + UpdatePolicyName = CmsKitAdminPermissions.BlogPosts.Update; + DeletePolicyName = CmsKitAdminPermissions.BlogPosts.Delete; + } + + public async Task GetByUrlSlugAsync(string urlSlug) + { + var blogPost = await _blogPostRepository.GetByUrlSlugAsync(urlSlug); + + return MapToGetOutputDto(blogPost); + } + + [Authorize(CmsKitAdminPermissions.BlogPosts.Create)] + public override async Task CreateAsync(CreateUpdateBlogPostDto input) + { + var entity = await _blogPostManager + .CreateAsync( + new BlogPost( + input.BlogId, + input.Title, + input.UrlSlug, + input.CoverImageUrl, + input.IsPublished)); + + return MapToGetOutputDto(entity); + } + + [Authorize(CmsKitAdminPermissions.BlogPosts.Update)] + public override async Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) + { + var entity = await _blogPostRepository.GetAsync(id); + + entity.SetTitle(input.Title); + entity.SetUrlSlug(input.UrlSlug); + entity.SetIsPublished(input.IsPublished); + + MapToEntity(input, entity); + + return MapToGetOutputDto(entity); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index dfd0ec7977..d354623891 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -10,5 +10,7 @@ namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs public interface IBlogPostRepository : IBasicRepository { Task SlugExistsAsync(string slug); + + Task GetByUrlSlugAsync(string urlSlug); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs index 79a2bbe50f..b6442dcf01 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs @@ -14,6 +14,11 @@ namespace Volo.CmsKit.Blogs { } + public Task GetByUrlSlugAsync(string urlSlug) + { + return GetAsync(x => x.UrlSlug.ToLower() == urlSlug); + } + public async Task SlugExistsAsync(string slug) { var dbSet = await GetDbSetAsync(); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs index 55eb84e1bb..a761c69895 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs @@ -12,6 +12,11 @@ namespace Volo.CmsKit.MongoDB.Blogs { } + public Task GetByUrlSlugAsync(string urlSlug) + { + return GetAsync(x => x.UrlSlug.ToLower() == urlSlug); + } + public async Task SlugExistsAsync(string slug) { var queryable = await GetQueryableAsync(); From 2ba8022f352fdfca4e6d71fb3883cc2e24adf188 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 18 Jan 2021 09:52:25 +0300 Subject: [PATCH 09/70] CmsKit - Refactor Blogs namespaces & types --- .../cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs | 2 +- .../src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs | 5 +++-- .../Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs | 2 +- .../CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs | 2 +- .../Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs | 2 +- .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index a7720d2a41..49b5bf9b43 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -1,7 +1,7 @@ using System; using Volo.Abp.Domain.Entities.Auditing; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { public class Blog : FullAuditedAggregateRoot { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 8b5ea4f8f9..af3931cbed 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -4,10 +4,11 @@ using System.Text.RegularExpressions; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Users; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { - public class BlogPost : FullAuditedEntity + public class BlogPost : FullAuditedAggregateRootWithUser { public Guid BlogId { get; protected set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index f3a268e956..06518cd29d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { public class BlogPostManager : IBlogPostManager { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs index bccffef418..22816c5d7e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { public class BlogPostUrlSlugAlreadyExistException : BusinessException { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs index 516e8f7835..eb5c0170e1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs @@ -1,7 +1,7 @@ using System; using System.Threading.Tasks; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { public interface IBlogPostManager { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index d354623891..a9e35e3794 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Blogs +namespace Volo.CmsKit.Blogs { public interface IBlogPostRepository : IBasicRepository { From f6286773930449df45117aa4209b54066e3596f9 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 18 Jan 2021 10:09:53 +0300 Subject: [PATCH 10/70] CmsKit - Refactor Blogs --- .../Volo/CmsKit/Blogs/Blog.cs | 5 ++++- .../Volo/CmsKit/Blogs/BlogPost.cs | 22 ++++++------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 49b5bf9b43..59354c8e59 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -1,10 +1,13 @@ using System; using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; namespace Volo.CmsKit.Blogs { - public class Blog : FullAuditedAggregateRoot + public class Blog : FullAuditedAggregateRoot, IMultiTenant { public string Name { get; set; } + + public Guid? TenantId { get; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index af3931cbed..3494cff31e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -3,24 +3,25 @@ using System; using System.Text.RegularExpressions; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; +using Volo.Abp.MultiTenancy; using Volo.CmsKit.Blogs; using Volo.CmsKit.Users; namespace Volo.CmsKit.Blogs { - public class BlogPost : FullAuditedAggregateRootWithUser + public class BlogPost : FullAuditedAggregateRootWithUser , IMultiTenant { public Guid BlogId { get; protected set; } public string Title { get; protected set; } + public string ShortDescription { get; set; } + public string UrlSlug { get; protected set; } public string CoverImageUrl { get; set; } - public bool IsPublished { get; protected set; } - - public DateTime? PublishDate { get; protected set; } + public Guid? TenantId { get; } protected BlogPost() { @@ -30,14 +31,15 @@ namespace Volo.CmsKit.Blogs Guid blogId, [NotNull] string title, [NotNull] string urlSlug, + [CanBeNull] string shortDescription = null, [CanBeNull] string coverImageUrl = null, bool isPublished = true) { BlogId = blogId; SetTitle(title); SetUrlSlug(urlSlug); + ShortDescription = shortDescription; CoverImageUrl = coverImageUrl; - IsPublished = isPublished; } public void SetTitle(string title) @@ -52,16 +54,6 @@ namespace Volo.CmsKit.Blogs UrlSlug = NormalizeUrlSlug(urlSlug); } - public void SetIsPublished(bool isPublished) - { - if (!IsPublished && isPublished) - { - this.PublishDate = DateTime.UtcNow; - } - - IsPublished = IsPublished; - } - private string NormalizeUrlSlug(string value) { value = value.ToLowerInvariant(); From 395c3354083d3bf8d01c08fd5ceac6a3fdee8e9d Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 13:53:14 +0300 Subject: [PATCH 11/70] CmsKit - Fix namespaces for Blogs --- .../Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs | 2 -- .../Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs | 2 +- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs | 6 ++---- .../Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs | 1 - .../Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs | 2 +- .../CmsKitDbContextModelCreatingExtensions.cs | 2 -- 6 files changed, 4 insertions(+), 11 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs index 761eb15c55..b013a9d397 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs @@ -11,7 +11,5 @@ namespace Volo.CmsKit.Admin.Blogs public string UrlSlug { get; protected set; } public string CoverImageUrl { get; set; } - - public bool IsPublished { get; protected set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index ba30b20814..e7075dcc22 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -2,7 +2,7 @@ using System; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 87c3f24fc1..17cfd74763 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs @@ -57,8 +57,7 @@ namespace Volo.CmsKit.Admin.Blogs input.BlogId, input.Title, input.UrlSlug, - input.CoverImageUrl, - input.IsPublished)); + input.CoverImageUrl)); return MapToGetOutputDto(entity); } @@ -70,7 +69,6 @@ namespace Volo.CmsKit.Admin.Blogs entity.SetTitle(input.Title); entity.SetUrlSlug(input.UrlSlug); - entity.SetIsPublished(input.IsPublished); MapToEntity(input, entity); diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs index b6442dcf01..96e80b7c90 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs @@ -3,7 +3,6 @@ using System; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.EntityFrameworkCore; namespace Volo.CmsKit.Blogs diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs index 87ad080af6..e7694574a9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContext.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 79a245e693..2b9b3cdde0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -13,9 +13,7 @@ using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Tags; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; using Volo.CmsKit.Blogs; -using System.Security.Cryptography.X509Certificates; namespace Volo.CmsKit.EntityFrameworkCore { From 4733aecc405d16bcb7e2eba6968340dfffdf91ef Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 15:59:42 +0300 Subject: [PATCH 12/70] CmsKit - Fix namespace problems --- .../Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs | 2 +- .../Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs | 2 +- .../Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs | 2 +- .../Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs index a761c69895..63bfc0044f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit.MongoDB.Blogs { diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index 45f3275acc..b61ad967cd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -3,7 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs index 3d718d6955..46eecd1077 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs @@ -3,7 +3,7 @@ using Volo.Abp; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index 4fcdea7d55..cc0faf912f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -3,7 +3,7 @@ using Volo.Abp.Data; using Volo.Abp.MongoDB; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; -using Volo.CmsKit.Domain.Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; using Volo.CmsKit.Reactions; From 982e5fe4ff4dd8221deb8a0fe791177a06fd009f Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 16:15:52 +0300 Subject: [PATCH 13/70] CmsKit - Refactor BlogPost --- .../src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 3494cff31e..de05a27167 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -32,8 +32,7 @@ namespace Volo.CmsKit.Blogs [NotNull] string title, [NotNull] string urlSlug, [CanBeNull] string shortDescription = null, - [CanBeNull] string coverImageUrl = null, - bool isPublished = true) + [CanBeNull] string coverImageUrl = null) { BlogId = blogId; SetTitle(title); From 7d2bd589bd182a242900fdf2cc94d01c46db0cb7 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 17:26:11 +0300 Subject: [PATCH 14/70] CmsKit - Implementation of CoverImage for Blogpost --- .../Admin/Blogs/IBlogAdminAppService.cs | 2 +- .../Admin/Blogs/IBlogPostAdminAppService.cs | 5 + .../Admin/Blogs/BlogPostAdminAppService.cs | 36 ++++++-- .../Admin/Blogs/BlogPostAdminController.cs | 92 +++++++++++++++++++ .../Volo.CmsKit.Domain.csproj | 1 + .../Volo/CmsKit/Blogs/BlogPost.cs | 6 +- .../Blogs/BlogPostCoverImageContainer.cs | 9 ++ .../Volo/CmsKit/Blogs/CmsKitBlogOptions.cs | 31 +++++++ .../Volo/CmsKit/CmsKitDomainModule.cs | 6 +- 9 files changed, 172 insertions(+), 16 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostCoverImageContainer.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs index dfc488b0a3..4072c9f847 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs @@ -3,7 +3,7 @@ using Volo.Abp.Application.Services; namespace Volo.CmsKit.Admin.Blogs { - public interface IBlogAdminAppService : ICrudAppService + public interface IBlogAdminAppService : ICrudAppService { } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs index 195778d92b..866c536b85 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.Abp.Content; namespace Volo.CmsKit.Admin.Blogs { @@ -13,5 +14,9 @@ namespace Volo.CmsKit.Admin.Blogs CreateUpdateBlogPostDto> { Task GetByUrlSlugAsync(string urlSlug); + + Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent); + + Task GetCoverImageAsync(Guid id); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 17cfd74763..2677b6c5ac 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -6,6 +6,8 @@ using System.Text; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.Abp.BlobStoring; +using Volo.Abp.Content; using Volo.Abp.Domain.Repositories; using Volo.CmsKit.Blogs; using Volo.CmsKit.Permissions; @@ -22,16 +24,17 @@ namespace Volo.CmsKit.Admin.Blogs CreateUpdateBlogPostDto> , IBlogPostAdminAppService { - protected readonly IBlogPostManager _blogPostManager; - protected readonly IBlogPostRepository _blogPostRepository; + protected readonly IBlogPostManager BlogPostManager; + protected readonly IBlogPostRepository BlogPostRepository; + protected readonly IBlobContainer BlobContainer; protected BlogPostAdminAppService( IRepository repository, IBlogPostManager blogPostManager, IBlogPostRepository blogPostRepository) : base(repository) { - _blogPostManager = blogPostManager; - _blogPostRepository = blogPostRepository; + BlogPostManager = blogPostManager; + BlogPostRepository = blogPostRepository; GetListPolicyName = CmsKitAdminPermissions.BlogPosts.Default; @@ -41,9 +44,9 @@ namespace Volo.CmsKit.Admin.Blogs DeletePolicyName = CmsKitAdminPermissions.BlogPosts.Delete; } - public async Task GetByUrlSlugAsync(string urlSlug) + public virtual async Task GetByUrlSlugAsync(string urlSlug) { - var blogPost = await _blogPostRepository.GetByUrlSlugAsync(urlSlug); + var blogPost = await BlogPostRepository.GetByUrlSlugAsync(urlSlug); return MapToGetOutputDto(blogPost); } @@ -51,7 +54,7 @@ namespace Volo.CmsKit.Admin.Blogs [Authorize(CmsKitAdminPermissions.BlogPosts.Create)] public override async Task CreateAsync(CreateUpdateBlogPostDto input) { - var entity = await _blogPostManager + var entity = await BlogPostManager .CreateAsync( new BlogPost( input.BlogId, @@ -65,7 +68,7 @@ namespace Volo.CmsKit.Admin.Blogs [Authorize(CmsKitAdminPermissions.BlogPosts.Update)] public override async Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) { - var entity = await _blogPostRepository.GetAsync(id); + var entity = await BlogPostRepository.GetAsync(id); entity.SetTitle(input.Title); entity.SetUrlSlug(input.UrlSlug); @@ -74,5 +77,22 @@ namespace Volo.CmsKit.Admin.Blogs return MapToGetOutputDto(entity); } + + public virtual async Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent) + { + await Repository.GetAsync(id); + + using (var stream = streamContent.GetStream()) + { + await BlobContainer.SaveAsync(id.ToString(), stream, overrideExisting: true); + } + } + + public virtual async Task GetCoverImageAsync(Guid id) + { + var stream = await BlobContainer.GetAsync(id.ToString()); + + return new RemoteStreamContent(stream); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs new file mode 100644 index 0000000000..554200b492 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -0,0 +1,92 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Content; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Blogs +{ + [RequiresGlobalFeature(typeof(BlogsFeature))] + [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] + [Route("api/cms-kit-admin/blogs/blog-posts")] + public class BlogPostAdminController : CmsKitAdminController, IBlogPostAdminAppService + { + protected readonly IBlogPostAdminAppService BlogPostAdminAppService; + + public BlogPostAdminController(IBlogPostAdminAppService blogPostAdminAppService) + { + BlogPostAdminAppService = blogPostAdminAppService; + } + + public virtual Task CreateAsync(CreateUpdateBlogPostDto input) + { + return BlogPostAdminAppService.CreateAsync(input); + } + + public virtual Task DeleteAsync(Guid id) + { + return BlogPostAdminAppService.DeleteAsync(id); + } + + public virtual Task GetAsync(Guid id) + { + return BlogPostAdminAppService.GetAsync(id); + } + + public virtual Task GetByUrlSlugAsync(string urlSlug) + { + return BlogPostAdminAppService.GetByUrlSlugAsync(urlSlug); + } + + public virtual Task GetCoverImageAsync(Guid id) + { + Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); + Response.Headers.Add("Accept-Ranges", "bytes"); + Response.Headers.Add("Cache-Control", "max-age=120"); + Response.ContentType = "image/*"; + + return BlogPostAdminAppService.GetCoverImageAsync(id); + } + + public virtual Task> GetListAsync(PagedAndSortedResultRequestDto input) + { + return BlogPostAdminAppService.GetListAsync(input); + } + + public virtual Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent) + { + return BlogPostAdminAppService.SetCoverImageAsync(id, streamContent); + } + + public virtual async Task UploadCoverImageAsync(Guid id, IFormFile file) + { + if (file == null) + { + return BadRequest(); + } + + using (var stream = file.OpenReadStream()) + { + await BlogPostAdminAppService.SetCoverImageAsync(id, new RemoteStreamContent(stream)); + } + + return StatusCode(201); + } + + public virtual Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) + { + return BlogPostAdminAppService.UpdateAsync(id, input); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj index ee064cbedc..0fc25899e9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj @@ -12,6 +12,7 @@ + diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index de05a27167..73fda09418 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -19,8 +19,6 @@ namespace Volo.CmsKit.Blogs public string UrlSlug { get; protected set; } - public string CoverImageUrl { get; set; } - public Guid? TenantId { get; } protected BlogPost() @@ -31,14 +29,12 @@ namespace Volo.CmsKit.Blogs Guid blogId, [NotNull] string title, [NotNull] string urlSlug, - [CanBeNull] string shortDescription = null, - [CanBeNull] string coverImageUrl = null) + [CanBeNull] string shortDescription = null) { BlogId = blogId; SetTitle(title); SetUrlSlug(urlSlug); ShortDescription = shortDescription; - CoverImageUrl = coverImageUrl; } public void SetTitle(string title) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostCoverImageContainer.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostCoverImageContainer.cs new file mode 100644 index 0000000000..824db4fe3a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostCoverImageContainer.cs @@ -0,0 +1,9 @@ +using Volo.Abp.BlobStoring; + +namespace Volo.CmsKit.Blogs +{ + [BlobContainerName("blog-post-cover-images")] + public class BlogPostCoverImageContainer + { + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs new file mode 100644 index 0000000000..bc3dd30435 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs @@ -0,0 +1,31 @@ +using System; + +namespace Volo.CmsKit.Blogs +{ + public class CmsKitBlogOptions + { + private string routePrefix = "blog"; + + /// + /// Gets or sets route prefix. Default value is 'blog'. + /// + /// + /// This parameter will be used while presenting blogposts. + /// + public string RoutePrefix + { + get => GetFormattedRoutePrefix(); + set => routePrefix = value; + } + + private string GetFormattedRoutePrefix() + { + if (string.IsNullOrWhiteSpace(routePrefix)) + { + return "/"; + } + + return routePrefix.EnsureEndsWith('/').EnsureStartsWith('/'); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs index b1937dd6e0..c16734c377 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Domain; +using Volo.Abp.BlobStoring; +using Volo.Abp.Domain; using Volo.Abp.Modularity; using Volo.Abp.Users; using Volo.CmsKit.Reactions; @@ -8,7 +9,8 @@ namespace Volo.CmsKit [DependsOn( typeof(CmsKitDomainSharedModule), typeof(AbpUsersDomainModule), - typeof(AbpDddDomainModule) + typeof(AbpDddDomainModule), + typeof(AbpBlobStoringModule) )] public class CmsKitDomainModule : AbpModule { From 3abd7483d990fe78d4f2314cae7799bce56f15cc Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 18:09:06 +0300 Subject: [PATCH 15/70] CmsKit - Blogs domain improvements --- .../Volo/CmsKit/Blogs/Blog.cs | 19 +++++++++++++++++-- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 3 ++- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 9 +++++++++ .../Volo/CmsKit/Contents/ContentManager.cs | 2 +- .../Volo/CmsKit/Contents/IContentManager.cs | 2 +- .../Volo/CmsKit/Blogs/BlogEfCoreRepository.cs | 14 ++++++++++++++ .../MongoDB/Blogs/BlogMongoRepository.cs | 14 ++++++++++++++ 7 files changed, 58 insertions(+), 5 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 59354c8e59..9ae19ff512 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -1,4 +1,6 @@ -using System; +using JetBrains.Annotations; +using System; +using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; @@ -6,8 +8,21 @@ namespace Volo.CmsKit.Blogs { public class Blog : FullAuditedAggregateRoot, IMultiTenant { - public string Name { get; set; } + public Blog( + [NotNull] string name, + [CanBeNull] Guid? tenantId = null) + { + SetName(name); + TenantId = tenantId; + } + + public string Name { get; protected set; } public Guid? TenantId { get; } + + public void SetName(string name) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: BlogConsts.MaxNameLength); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 06518cd29d..2b139fbdb6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -3,10 +3,11 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.Domain.Services; namespace Volo.CmsKit.Blogs { - public class BlogPostManager : IBlogPostManager + public class BlogPostManager : DomainService, IBlogPostManager { protected readonly IBlogPostRepository _blogPostRepository; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs new file mode 100644 index 0000000000..8ded8b2933 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -0,0 +1,9 @@ +using System; +using Volo.Abp.Domain.Repositories; + +namespace Volo.CmsKit.Blogs +{ + public interface IBlogRepository : IRepository + { + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs index 6eb2521ba2..047d923ad6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/ContentManager.cs @@ -7,7 +7,7 @@ using System.Threading.Tasks; using Volo.Abp.Domain.Services; using Volo.CmsKit.Contents; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Contents +namespace Volo.CmsKit.Contents { public class ContentManager : DomainService, IContentManager { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs index e795e7895c..d64bd0effe 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Contents/IContentManager.cs @@ -2,7 +2,7 @@ using System.Threading.Tasks; using Volo.CmsKit.Contents; -namespace Volo.CmsKit.Domain.Volo.CmsKit.Contents +namespace Volo.CmsKit.Contents { public interface IContentManager { diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs new file mode 100644 index 0000000000..db6d5258ca --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Blogs +{ + public class BlogEfCoreRepository : EfCoreRepository, IBlogRepository + { + public BlogEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs new file mode 100644 index 0000000000..50e900f989 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp.Domain.Repositories.MongoDB; +using Volo.Abp.MongoDB; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.MongoDB.Blogs +{ + public class BlogMongoRepository : MongoDbRepository, IBlogRepository + { + public BlogMongoRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + } +} From 69c42890a4df1dd5c6c9de61c4a25fb61f33035b Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 18:09:41 +0300 Subject: [PATCH 16/70] CmsKit - BlogPosts Domain tests --- .../Blogs/BlogPostAdminAppService_Tests.cs | 16 ++++ .../Blogs/BlogPostManager_Tests.cs | 75 +++++++++++++++++++ .../CmsKitDataSeedContributor.cs | 39 +++++++--- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 14 ++++ 4 files changed, 134 insertions(+), 10 deletions(-) create mode 100644 modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs new file mode 100644 index 0000000000..f0b3d595f4 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs @@ -0,0 +1,16 @@ +using System; +using Shouldly; +using Volo.CmsKit.Admin.Blogs; + +namespace Volo.CmsKit.Blogs +{ + public class BlogPostAdminAppService_Tests : CmsKitApplicationTestBase + { + private readonly IBlogPostAdminAppService blogPostAdminAppService; + + public BlogPostAdminAppService_Tests() + { + blogPostAdminAppService = GetRequiredService(); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs new file mode 100644 index 0000000000..5950fc1333 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs @@ -0,0 +1,75 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Guids; +using Volo.CmsKit.Tags; +using Xunit; + +namespace Volo.CmsKit.Blogs +{ + public class BlogPostManager_Tests : CmsKitDomainTestBase + { + private readonly IBlogPostManager blogPostManager; + private readonly IGuidGenerator guidGenerator; + private readonly IBlogPostRepository blogPostRepository; + private readonly CmsKitTestData cmsKitTestData; + + public BlogPostManager_Tests( + IBlogPostManager blogPostManager, + IGuidGenerator guidGenerator, + IBlogPostRepository blogPostRepository, + CmsKitTestData cmsKitTestData) + { + this.blogPostManager = blogPostManager; + this.guidGenerator = guidGenerator; + this.blogPostRepository = blogPostRepository; + this.cmsKitTestData = cmsKitTestData; + } + + [Fact] + public async Task CreateAsync_ShouldWorkProperly_WithCorrectData() + { + var title = "New blog post"; + var urlSlug = "new-blog-post"; + + var created = await blogPostManager.CreateAsync( + new BlogPost(guidGenerator.Create(), title, urlSlug)); + + created.Id.ShouldNotBe(Guid.Empty); + + var blogPost = await blogPostRepository.GetAsync(created.Id); + blogPost.Title.ShouldBe(title); + blogPost.UrlSlug.ShouldBe(urlSlug); + } + + [Fact] + public async Task CreateAsync_ShouldThrowException_WhenUrlSlugAlreadyExists() + { + var blogPost = new BlogPost(guidGenerator.Create(), "Any New Title", cmsKitTestData.Blog_1_UrlSlug); + + await Should.ThrowAsync(async () => + await blogPostManager.CreateAsync(blogPost)); + } + + [Fact] + public async Task UpdateAsync_ShoudlWorkProperly_WithCorrectData() + { + var newTitle = "Yet Another Post"; + var newUrlSlug = "yet-another-post"; + + var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.Blog_1_Id); + + blogPost.SetTitle(newTitle); + blogPost.SetUrlSlug(newUrlSlug); + + await blogPostManager.UpdateAsync(blogPost); + + var updated = await blogPostRepository.GetAsync(cmsKitTestData.Blog_1_Id); + updated.Title.ShouldBe(newTitle); + updated.UrlSlug.ShouldBe(newUrlSlug); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 46a552641b..8af99d512d 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -6,6 +6,7 @@ using Volo.Abp.DependencyInjection; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.Users; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; @@ -29,6 +30,9 @@ namespace Volo.CmsKit private readonly IEntityTagRepository _entityTagRepository; private readonly ITagManager _tagManager; private readonly IPageRepository _pageRepository; + private readonly IBlogRepository _blogRepository; + private readonly IBlogPostRepository _blogPostRepository; + public CmsKitDataSeedContributor( IGuidGenerator guidGenerator, ICmsUserRepository cmsUserRepository, @@ -36,11 +40,13 @@ namespace Volo.CmsKit ICommentRepository commentRepository, ReactionManager reactionManager, IRatingRepository ratingRepository, - ICurrentTenant currentTenant, + ICurrentTenant currentTenant, IContentRepository contentRepository, - ITagManager tagManager, - IEntityTagRepository entityTagRepository, - IPageRepository pageRepository) + ITagManager tagManager, + IEntityTagRepository entityTagRepository, + IPageRepository pageRepository, + IBlogRepository blogRepository, + IBlogPostRepository blogPostRepository) { _guidGenerator = guidGenerator; _cmsUserRepository = cmsUserRepository; @@ -53,6 +59,8 @@ namespace Volo.CmsKit _tagManager = tagManager; _entityTagRepository = entityTagRepository; _pageRepository = pageRepository; + _blogRepository = blogRepository; + _blogPostRepository = blogPostRepository; } public async Task SeedAsync(DataSeedContext context) @@ -72,6 +80,8 @@ namespace Volo.CmsKit await SeedTagsAsync(); await SeedPagesAsync(); + + await SeedBlogsAsync(); } } @@ -208,14 +218,14 @@ namespace Volo.CmsKit _cmsKitTestData.Content_1_EntityId, _cmsKitTestData.Content_1 ); - + var content2 = new Content( _cmsKitTestData.Content_2_Id, _cmsKitTestData.Content_2_EntityType, _cmsKitTestData.Content_2_EntityId, _cmsKitTestData.Content_2 ); - + var content3 = new Content( Guid.NewGuid(), "deleted_entity_type", @@ -239,11 +249,11 @@ namespace Volo.CmsKit await _entityTagRepository.InsertAsync(new EntityTag(tagEntity.Id, _cmsKitTestData.Content_1_EntityId)); } - + foreach (var tag in _cmsKitTestData.Content_2_Tags) { var tagEntity = await _tagManager.InsertAsync(_guidGenerator.Create(), _cmsKitTestData.Content_2_EntityType, tag); - + await _entityTagRepository.InsertAsync(new EntityTag(tagEntity.Id, _cmsKitTestData.Content_2_EntityId)); } } @@ -252,15 +262,24 @@ namespace Volo.CmsKit { var page1 = new Page(_cmsKitTestData.Page_1_Id, _cmsKitTestData.Page_1_Title, _cmsKitTestData.Page_1_Url, _cmsKitTestData.Page_1_Description); var page1Content = new Content(_guidGenerator.Create(), nameof(Page), page1.Id.ToString(), _cmsKitTestData.Page_1_Content); - + await _pageRepository.InsertAsync(page1); await _contentRepository.InsertAsync(page1Content); - + var page2 = new Page(_cmsKitTestData.Page_2_Id, _cmsKitTestData.Page_2_Title, _cmsKitTestData.Page_2_Url, _cmsKitTestData.Page_2_Description); var page2Content = new Content(_guidGenerator.Create(), nameof(Page), page2.Id.ToString(), _cmsKitTestData.Page_2_Content); await _pageRepository.InsertAsync(page2); await _contentRepository.InsertAsync(page2Content); } + + private async Task SeedBlogsAsync() + { + var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.BlogName)); + + await _blogPostRepository.InsertAsync(new BlogPost(blog.Id, _cmsKitTestData.Blog_1_Title, _cmsKitTestData.Blog_1_UrlSlug, "Short desc 1")); + + await _blogPostRepository.InsertAsync(new BlogPost(blog.Id, _cmsKitTestData.Blog_2_Title, _cmsKitTestData.Blog_2_UrlSlug, "Short desc 2")); + } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 7433759f40..e4b4fc89cb 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -59,5 +59,19 @@ namespace Volo.CmsKit public Guid Page_2_Id { get; } = Guid.NewGuid(); public string Page_2_Content => Content_2; + + public string BlogName => "Cms Blog"; + + public Guid Blog_1_Id { get; } = Guid.NewGuid(); + + public string Blog_1_Title => "How to install CmsKit?"; + + public string Blog_1_UrlSlug => "how-to-install-cms-kit"; + + public Guid Blog_2_Id { get; } = Guid.NewGuid(); + + public string Blog_2_Title => "How to use CmsKit?"; + + public string Blog_2_UrlSlug => "how-to-use-cms-kit?"; } } From 42c72d712e67d6632dd6e0fdcb6fcd93aa7a5642 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 18:15:02 +0300 Subject: [PATCH 17/70] CmsKit - Remove CoverImageUrl from BlogPost --- .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 4 +--- .../CmsKitDbContextModelCreatingExtensions.cs | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 4f3ad07f7b..a4388aa945 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -1,11 +1,9 @@ namespace Volo.CmsKit.Blogs { - public class BlogPostConsts + public static class BlogPostConsts { public static int MaxTitleLength { get; set; } = 256; - public static int MaxCoverImageUrlLength { get; set; } = 2048; - public static int MaxUrlSlugLength { get; set; } = 256; public static int MinUrlSlugLength { get; set; } = 2; diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 2b9b3cdde0..3322253205 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -229,8 +229,6 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogPostConsts.MaxUrlSlugLength); - b.Property(p => p.CoverImageUrl).HasMaxLength(BlogPostConsts.MaxCoverImageUrlLength); - b.HasIndex(x => x.UrlSlug); }); } From 888a01d1cfb05c019d2d7a19e244a3e5a6ec60f9 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 19 Jan 2021 18:15:24 +0300 Subject: [PATCH 18/70] CmsKit - namespace fix for ContentAdminAppService --- .../Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs index 4695339fd7..06145b2fca 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Contents/ContentAdminAppService.cs @@ -4,7 +4,6 @@ using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; using Volo.CmsKit.Contents; -using Volo.CmsKit.Domain.Volo.CmsKit.Contents; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Contents From 5121670195c1b2c41518ccd9e17c7a8b37dd6ca0 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 20 Jan 2021 16:35:20 +0300 Subject: [PATCH 19/70] CmsKit - Refactoring for BlogPosts --- .../CmsKit/Admin/Blogs/BlogPostAdminAppService.cs | 4 ++-- .../Volo/CmsKit/Blogs/BlogPost.cs | 5 +++-- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 2 +- .../Volo/CmsKit/Blogs/BlogEfCoreRepository.cs | 14 -------------- ...reRepository.cs => EfCoreBlogPostRepository.cs} | 4 ++-- .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 14 ++++++++++++++ .../CmsKitEntityFrameworkCoreModule.cs | 3 +++ .../CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs | 3 +++ ...ngoRepository.cs => MongoBlogPostRepository.cs} | 4 ++-- ...ogMongoRepository.cs => MongoBlogRepository.cs} | 4 ++-- .../Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs | 4 ++++ 11 files changed, 36 insertions(+), 25 deletions(-) delete mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs rename modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/{BlogPostEfCoreRepository.cs => EfCoreBlogPostRepository.cs} (85%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs rename modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/{BlogPostMongoRepository.cs => MongoBlogPostRepository.cs} (84%) rename modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/{BlogMongoRepository.cs => MongoBlogRepository.cs} (69%) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 2677b6c5ac..7ff775f376 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -28,7 +28,7 @@ namespace Volo.CmsKit.Admin.Blogs protected readonly IBlogPostRepository BlogPostRepository; protected readonly IBlobContainer BlobContainer; - protected BlogPostAdminAppService( + public BlogPostAdminAppService( IRepository repository, IBlogPostManager blogPostManager, IBlogPostRepository blogPostRepository) : base(repository) @@ -36,7 +36,6 @@ namespace Volo.CmsKit.Admin.Blogs BlogPostManager = blogPostManager; BlogPostRepository = blogPostRepository; - GetListPolicyName = CmsKitAdminPermissions.BlogPosts.Default; GetPolicyName = CmsKitAdminPermissions.BlogPosts.Default; CreatePolicyName = CmsKitAdminPermissions.BlogPosts.Create; @@ -57,6 +56,7 @@ namespace Volo.CmsKit.Admin.Blogs var entity = await BlogPostManager .CreateAsync( new BlogPost( + GuidGenerator.Create(), input.BlogId, input.Title, input.UrlSlug, diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 73fda09418..ac41adbe2a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -9,7 +9,7 @@ using Volo.CmsKit.Users; namespace Volo.CmsKit.Blogs { - public class BlogPost : FullAuditedAggregateRootWithUser , IMultiTenant + public class BlogPost : FullAuditedAggregateRootWithUser, IMultiTenant { public Guid BlogId { get; protected set; } @@ -26,10 +26,11 @@ namespace Volo.CmsKit.Blogs } public BlogPost( + Guid id, Guid blogId, [NotNull] string title, [NotNull] string urlSlug, - [CanBeNull] string shortDescription = null) + [CanBeNull] string shortDescription = null) : base(id) { BlogId = blogId; SetTitle(title); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index 8ded8b2933..90e59587a2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -3,7 +3,7 @@ using Volo.Abp.Domain.Repositories; namespace Volo.CmsKit.Blogs { - public interface IBlogRepository : IRepository + public interface IBlogRepository : IBasicRepository { } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs deleted file mode 100644 index db6d5258ca..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogEfCoreRepository.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Volo.Abp.Domain.Repositories.EntityFrameworkCore; -using Volo.Abp.EntityFrameworkCore; -using Volo.CmsKit.EntityFrameworkCore; - -namespace Volo.CmsKit.Blogs -{ - public class BlogEfCoreRepository : EfCoreRepository, IBlogRepository - { - public BlogEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) - { - } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs similarity index 85% rename from modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs rename to modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs index 96e80b7c90..09445da84d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/BlogPostEfCoreRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs @@ -7,9 +7,9 @@ using Volo.CmsKit.EntityFrameworkCore; namespace Volo.CmsKit.Blogs { - public class BlogPostEfCoreRepository : EfCoreRepository, IBlogPostRepository + public class EfCoreBlogPostRepository : EfCoreRepository, IBlogPostRepository { - public BlogPostEfCoreRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + public EfCoreBlogPostRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs new file mode 100644 index 0000000000..a43504642c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -0,0 +1,14 @@ +using System; +using Volo.Abp.Domain.Repositories.EntityFrameworkCore; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Blogs +{ + public class EfCoreBlogRepository : EfCoreRepository, IBlogRepository + { + public EfCoreBlogRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) + { + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs index c995c21dfb..61cd667aed 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs @@ -2,6 +2,7 @@ using Volo.Abp.EntityFrameworkCore; using Volo.Abp.Modularity; using Volo.Abp.Users.EntityFrameworkCore; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; @@ -31,6 +32,8 @@ namespace Volo.CmsKit.EntityFrameworkCore options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); + options.AddRepository(); }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs index a5981fd000..feb1a5aacd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/ICmsKitDbContext.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using Volo.Abp.Data; using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; @@ -22,5 +23,7 @@ namespace Volo.CmsKit.EntityFrameworkCore DbSet Tags { get; set; } DbSet EntityTags { get; set; } DbSet Pages { get; set; } + DbSet Blogs { get; set; } + DbSet BlogPosts { get; set; } } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs similarity index 84% rename from modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs rename to modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 63bfc0044f..166eda7f0d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogPostMongoRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -6,9 +6,9 @@ using Volo.CmsKit.Blogs; namespace Volo.CmsKit.MongoDB.Blogs { - public class BlogPostMongoRepository : MongoDbRepository, IBlogPostRepository + public class MongoBlogPostRepository : MongoDbRepository, IBlogPostRepository { - public BlogPostMongoRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + public MongoBlogPostRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs similarity index 69% rename from modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs rename to modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index 50e900f989..195c29f1f7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/BlogMongoRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -5,9 +5,9 @@ using Volo.CmsKit.Blogs; namespace Volo.CmsKit.MongoDB.Blogs { - public class BlogMongoRepository : MongoDbRepository, IBlogRepository + public class MongoBlogRepository : MongoDbRepository, IBlogRepository { - public BlogMongoRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) + public MongoBlogRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs index 898b1687a8..b5ef74ac34 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbModule.cs @@ -2,8 +2,10 @@ using Volo.Abp.Modularity; using Volo.Abp.MongoDB; using Volo.Abp.Users.MongoDB; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; +using Volo.CmsKit.MongoDB.Blogs; using Volo.CmsKit.MongoDB.Comments; using Volo.CmsKit.MongoDB.Contents; using Volo.CmsKit.MongoDB.Pages; @@ -38,6 +40,8 @@ namespace Volo.CmsKit.MongoDB options.AddRepository(); options.AddRepository(); options.AddRepository(); + options.AddRepository(); + options.AddRepository(); }); } } From 763e9af37611198897153d1a71f681991f7a6577 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 20 Jan 2021 16:35:34 +0300 Subject: [PATCH 20/70] CmsKit - Update Tests for BlogPosts --- .../Blogs/BlogPostManager_Tests.cs | 22 ++++---- .../CmsKitDataSeedContributor.cs | 5 +- .../CmsKitFakeCurrentUser.cs | 53 +++++++++++++++++++ .../CmsKitTestBaseModule.cs | 2 +- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 15 +++--- 5 files changed, 75 insertions(+), 22 deletions(-) create mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitFakeCurrentUser.cs diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs index 5950fc1333..a9d7aa2da7 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs @@ -17,16 +17,12 @@ namespace Volo.CmsKit.Blogs private readonly IBlogPostRepository blogPostRepository; private readonly CmsKitTestData cmsKitTestData; - public BlogPostManager_Tests( - IBlogPostManager blogPostManager, - IGuidGenerator guidGenerator, - IBlogPostRepository blogPostRepository, - CmsKitTestData cmsKitTestData) + public BlogPostManager_Tests() { - this.blogPostManager = blogPostManager; - this.guidGenerator = guidGenerator; - this.blogPostRepository = blogPostRepository; - this.cmsKitTestData = cmsKitTestData; + this.blogPostManager = GetRequiredService(); + this.guidGenerator = GetRequiredService(); + this.blogPostRepository = GetRequiredService(); + this.cmsKitTestData = GetRequiredService(); } [Fact] @@ -36,7 +32,7 @@ namespace Volo.CmsKit.Blogs var urlSlug = "new-blog-post"; var created = await blogPostManager.CreateAsync( - new BlogPost(guidGenerator.Create(), title, urlSlug)); + new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, title, urlSlug)); created.Id.ShouldNotBe(Guid.Empty); @@ -48,7 +44,7 @@ namespace Volo.CmsKit.Blogs [Fact] public async Task CreateAsync_ShouldThrowException_WhenUrlSlugAlreadyExists() { - var blogPost = new BlogPost(guidGenerator.Create(), "Any New Title", cmsKitTestData.Blog_1_UrlSlug); + var blogPost = new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, "Any New Title", cmsKitTestData.BlogPost_1_UrlSlug); await Should.ThrowAsync(async () => await blogPostManager.CreateAsync(blogPost)); @@ -60,14 +56,14 @@ namespace Volo.CmsKit.Blogs var newTitle = "Yet Another Post"; var newUrlSlug = "yet-another-post"; - var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.Blog_1_Id); + var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); blogPost.SetTitle(newTitle); blogPost.SetUrlSlug(newUrlSlug); await blogPostManager.UpdateAsync(blogPost); - var updated = await blogPostRepository.GetAsync(cmsKitTestData.Blog_1_Id); + var updated = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); updated.Title.ShouldBe(newTitle); updated.UrlSlug.ShouldBe(newUrlSlug); } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 8af99d512d..66489f80e8 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Volo.Abp.Data; using Volo.Abp.DependencyInjection; +using Volo.Abp.Domain.Repositories; using Volo.Abp.Guids; using Volo.Abp.MultiTenancy; using Volo.Abp.Users; @@ -277,9 +278,9 @@ namespace Volo.CmsKit { var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.BlogName)); - await _blogPostRepository.InsertAsync(new BlogPost(blog.Id, _cmsKitTestData.Blog_1_Title, _cmsKitTestData.Blog_1_UrlSlug, "Short desc 1")); + await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_UrlSlug, "Short desc 1")); - await _blogPostRepository.InsertAsync(new BlogPost(blog.Id, _cmsKitTestData.Blog_2_Title, _cmsKitTestData.Blog_2_UrlSlug, "Short desc 2")); + await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_2_Id, blog.Id, _cmsKitTestData.BlogPost_2_Title, _cmsKitTestData.BlogPost_2_UrlSlug, "Short desc 2")); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitFakeCurrentUser.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitFakeCurrentUser.cs new file mode 100644 index 0000000000..ba9c492889 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitFakeCurrentUser.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Claims; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.Users; + +namespace Volo.CmsKit +{ + public class CmsKitFakeCurrentUser : ITransientDependency, ICurrentUser + { + private readonly CmsKitTestData cmsKitTestData; + + public CmsKitFakeCurrentUser(CmsKitTestData cmsKitTestData) + { + this.cmsKitTestData = cmsKitTestData; + } + + public bool IsAuthenticated { get; } + public Guid? Id => cmsKitTestData.User1Id; + public string UserName => cmsKitTestData.User1UserName; + public string Name { get; } + public string SurName { get; } + public string PhoneNumber { get; } + public bool PhoneNumberVerified { get; } + public string Email { get; } + public bool EmailVerified { get; } + public Guid? TenantId { get; } + public string[] Roles { get; } + + public Claim FindClaim(string claimType) + { + throw new NotImplementedException(); + } + + public Claim[] FindClaims(string claimType) + { + throw new NotImplementedException(); + } + + public Claim[] GetAllClaims() + { + throw new NotImplementedException(); + } + + public bool IsInRole(string roleName) + { + throw new NotImplementedException(); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs index e12f3d31e8..afa4dbe47e 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestBaseModule.cs @@ -53,7 +53,7 @@ namespace Volo.CmsKit { using (var scope = context.ServiceProvider.CreateScope()) { - await scope.ServiceProvider + await scope.ServiceProvider .GetRequiredService() .SeedAsync(); } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index e4b4fc89cb..2da69a5ac6 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -7,6 +7,7 @@ namespace Volo.CmsKit public class CmsKitTestData : ISingletonDependency { public Guid User1Id { get; } = Guid.NewGuid(); + public string User1UserName => "fake.user"; public Guid User2Id { get; } = Guid.NewGuid(); @@ -60,18 +61,20 @@ namespace Volo.CmsKit public string Page_2_Content => Content_2; + public Guid Blog_Id { get; } = Guid.NewGuid(); + public string BlogName => "Cms Blog"; - public Guid Blog_1_Id { get; } = Guid.NewGuid(); + public Guid BlogPost_1_Id { get; } = Guid.NewGuid(); - public string Blog_1_Title => "How to install CmsKit?"; + public string BlogPost_1_Title => "How to install CmsKit?"; - public string Blog_1_UrlSlug => "how-to-install-cms-kit"; + public string BlogPost_1_UrlSlug => "how-to-install-cms-kit"; - public Guid Blog_2_Id { get; } = Guid.NewGuid(); + public Guid BlogPost_2_Id { get; } = Guid.NewGuid(); - public string Blog_2_Title => "How to use CmsKit?"; + public string BlogPost_2_Title => "How to use CmsKit?"; - public string Blog_2_UrlSlug => "how-to-use-cms-kit?"; + public string BlogPost_2_UrlSlug => "how-to-use-cms-kit?"; } } From 0b3cd00846c4318dcc0f867f888fe007978876c8 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 20 Jan 2021 16:44:23 +0300 Subject: [PATCH 21/70] CmsKit - Add missing Feature attributes to Blogs appservices --- .../Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs | 3 +++ .../Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs | 3 +++ 2 files changed, 6 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index e7075dcc22..b6c2195981 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -2,11 +2,14 @@ using System; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; +using Volo.Abp.GlobalFeatures; using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { + [RequiresGlobalFeature(typeof(BlogsFeature))] [Authorize(CmsKitAdminPermissions.Blogs.Default)] public class BlogAdminAppService : CrudAppService, IBlogAdminAppService { diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 7ff775f376..c714c6482b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -9,11 +9,14 @@ using Volo.Abp.Application.Services; using Volo.Abp.BlobStoring; using Volo.Abp.Content; using Volo.Abp.Domain.Repositories; +using Volo.Abp.GlobalFeatures; using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { + [RequiresGlobalFeature(typeof(BlogsFeature))] [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] public class BlogPostAdminAppService : CrudAppService< From e6db0a1efe4bb7c56906659c0168c4f21c24f2ff Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 20 Jan 2021 17:57:55 +0300 Subject: [PATCH 22/70] CmsKit - Add more test-cases for BlogPosts --- .../Volo/CmsKit/Admin/Blogs/BlogPostDto.cs | 12 +- .../Admin/Blogs/CreateUpdateBlogPostDto.cs | 8 +- .../Admin/Blogs/BlogPostAdminAppService.cs | 11 +- ...CmsKitAdminApplicationAutoMapperProfile.cs | 8 + .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 4 +- .../Volo/CmsKit/Blogs/Blog.cs | 3 +- .../Volo/CmsKit/Blogs/BlogPost.cs | 4 +- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 25 ++- .../BlogPostUrlSlugAlreadyExistException.cs | 6 +- .../CmsKitDbContextModelCreatingExtensions.cs | 2 + .../Blogs/BlogPostAdminAppService_Tests.cs | 199 ++++++++++++++++++ .../Data/BlogPostSample.png | Bin 0 -> 6932 bytes .../Volo.CmsKit.Application.Tests.csproj | 8 + .../CmsKitDataSeedContributor.cs | 2 +- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 1 + 15 files changed, 263 insertions(+), 30 deletions(-) create mode 100644 modules/cms-kit/test/Volo.CmsKit.Application.Tests/Data/BlogPostSample.png diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs index 823efdfc4e..2c3ff84d48 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs @@ -5,16 +5,10 @@ namespace Volo.CmsKit.Admin.Blogs { public class BlogPostDto : EntityDto { - public Guid BlogId { get; protected set; } + public Guid BlogId { get; set; } - public string Title { get; protected set; } + public string Title { get; set; } - public string UrlSlug { get; protected set; } - - public string CoverImageUrl { get; set; } - - public bool IsPublished { get; protected set; } - - public DateTime? PublishDate { get; protected set; } + public string UrlSlug { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs index b013a9d397..09d881189b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs @@ -4,12 +4,12 @@ namespace Volo.CmsKit.Admin.Blogs { public class CreateUpdateBlogPostDto { - public Guid BlogId { get; protected set; } + public Guid BlogId { get; set; } - public string Title { get; protected set; } + public string Title { get; set; } - public string UrlSlug { get; protected set; } + public string UrlSlug { get; set; } - public string CoverImageUrl { get; set; } + public string ShortDescription { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index c714c6482b..36ded2ba1f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -1,8 +1,5 @@ using Microsoft.AspNetCore.Authorization; using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; @@ -34,10 +31,12 @@ namespace Volo.CmsKit.Admin.Blogs public BlogPostAdminAppService( IRepository repository, IBlogPostManager blogPostManager, - IBlogPostRepository blogPostRepository) : base(repository) + IBlogPostRepository blogPostRepository, + IBlobContainer blobContainer) : base(repository) { BlogPostManager = blogPostManager; BlogPostRepository = blogPostRepository; + BlobContainer = blobContainer; GetListPolicyName = CmsKitAdminPermissions.BlogPosts.Default; GetPolicyName = CmsKitAdminPermissions.BlogPosts.Default; @@ -63,7 +62,7 @@ namespace Volo.CmsKit.Admin.Blogs input.BlogId, input.Title, input.UrlSlug, - input.CoverImageUrl)); + input.ShortDescription)); return MapToGetOutputDto(entity); } @@ -78,6 +77,8 @@ namespace Volo.CmsKit.Admin.Blogs MapToEntity(input, entity); + await BlogPostManager.UpdateAsync(entity); + return MapToGetOutputDto(entity); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs index 1524fe6299..e682e80d30 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs @@ -1,6 +1,8 @@ using AutoMapper; +using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Admin.Contents; using Volo.CmsKit.Admin.Pages; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; @@ -16,6 +18,12 @@ namespace Volo.CmsKit.Admin CreateMap(MemberList.Destination); CreateMap(MemberList.Source); CreateMap(MemberList.Source); + + CreateMap(MemberList.Destination); + CreateMap(MemberList.Source); + + CreateMap(MemberList.Destination) + .ReverseMap(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index a4388aa945..607effcebd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -2,10 +2,12 @@ { public static class BlogPostConsts { - public static int MaxTitleLength { get; set; } = 256; + public static int MaxTitleLength { get; set; } = 64; public static int MaxUrlSlugLength { get; set; } = 256; public static int MinUrlSlugLength { get; set; } = 2; + + public static int MaxShortDescriptionLength { get; set; } = 256; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 9ae19ff512..0ec587f52e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -9,8 +9,9 @@ namespace Volo.CmsKit.Blogs public class Blog : FullAuditedAggregateRoot, IMultiTenant { public Blog( + Guid id, [NotNull] string name, - [CanBeNull] Guid? tenantId = null) + [CanBeNull] Guid? tenantId = null) : base(id) { SetName(name); TenantId = tenantId; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index ac41adbe2a..62a73ec352 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -15,10 +15,10 @@ namespace Volo.CmsKit.Blogs public string Title { get; protected set; } - public string ShortDescription { get; set; } - public string UrlSlug { get; protected set; } + public string ShortDescription { get; set; } + public Guid? TenantId { get; } protected BlogPost() diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 2b139fbdb6..6bbb772072 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -9,33 +9,46 @@ namespace Volo.CmsKit.Blogs { public class BlogPostManager : DomainService, IBlogPostManager { - protected readonly IBlogPostRepository _blogPostRepository; + protected readonly IBlogPostRepository blogPostRepository; + protected readonly IBlogRepository blogRepository; - public BlogPostManager(IBlogPostRepository blogPostRepository) + public BlogPostManager( + IBlogPostRepository blogPostRepository, + IBlogRepository blogRepository) { - _blogPostRepository = blogPostRepository; + this.blogPostRepository = blogPostRepository; + this.blogRepository = blogRepository; } public async Task CreateAsync(BlogPost blogPost) { + await CheckBlogExistenceAsync(blogPost.BlogId); + await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); - return await _blogPostRepository.InsertAsync(blogPost); + return await blogPostRepository.InsertAsync(blogPost); } public async Task UpdateAsync(BlogPost blogPost) { + await CheckBlogExistenceAsync(blogPost.BlogId); + await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); - await _blogPostRepository.UpdateAsync(blogPost); + await blogPostRepository.UpdateAsync(blogPost); } private async Task CheckUrlSlugExistenceAsync(string urlSlug) { - if (await _blogPostRepository.SlugExistsAsync(urlSlug)) + if (await blogPostRepository.SlugExistsAsync(urlSlug)) { throw new BlogPostUrlSlugAlreadyExistException(urlSlug); } } + + private async Task CheckBlogExistenceAsync(Guid blogId) + { + await blogRepository.GetAsync(blogId); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs index 22816c5d7e..c21ccfa8e7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs @@ -19,9 +19,13 @@ namespace Volo.CmsKit.Blogs public BlogPostUrlSlugAlreadyExistException(string urlSlug) { + UrlSlug = urlSlug; + Code = CmsKitErrorCodes.Blogs.UrlSlugAlreadyExist; - WithData(nameof(BlogPost.UrlSlug), urlSlug); + WithData(nameof(UrlSlug), UrlSlug); } + + public string UrlSlug { get; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 3322253205..c868bde907 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -229,6 +229,8 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogPostConsts.MaxUrlSlugLength); + b.Property(p => p.ShortDescription).HasMaxLength(BlogPostConsts.MaxShortDescriptionLength); + b.HasIndex(x => x.UrlSlug); }); } diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs index f0b3d595f4..07897d0d5b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs @@ -1,16 +1,215 @@ using System; +using System.IO; +using System.Threading.Tasks; +using Castle.DynamicProxy.Generators; using Shouldly; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Content; +using Volo.Abp.Domain.Entities; using Volo.CmsKit.Admin.Blogs; +using Xunit; namespace Volo.CmsKit.Blogs { public class BlogPostAdminAppService_Tests : CmsKitApplicationTestBase { private readonly IBlogPostAdminAppService blogPostAdminAppService; + private readonly CmsKitTestData cmsKitTestData; + private readonly IBlogPostRepository blogPostRepository; public BlogPostAdminAppService_Tests() { blogPostAdminAppService = GetRequiredService(); + cmsKitTestData = GetRequiredService(); + blogPostRepository = GetRequiredService(); } + + [Fact] + public async Task CreateAsync_ShouldWorkProperly_WithCorrectData() + { + var title = "My awesome new Post"; + var urlSlug = "my-awesome-new-post"; + var shortDescription = "This blog is all about awesomeness 🤗!"; + + var created = await blogPostAdminAppService.CreateAsync(new CreateUpdateBlogPostDto + { + BlogId = cmsKitTestData.Blog_Id, + Title = title, + UrlSlug = urlSlug, + ShortDescription = shortDescription + }); + + created.Id.ShouldNotBe(Guid.Empty); + + var blogPost = await blogPostRepository.GetAsync(created.Id); + + blogPost.Title.ShouldBe(title); + blogPost.UrlSlug.ShouldBe(urlSlug); + blogPost.ShortDescription.ShouldBe(shortDescription); + } + + [Fact] + public async Task CreateAsync_ShouldThrowException_WithNonExistingBlogId() + { + var title = "Another My Awesome New Post"; + var urlSlug = "another-my-awesome-new-post"; + var shortDescription = "This blog is all about awesomeness 🤗!"; + + var dto = new CreateUpdateBlogPostDto + { + // Non-existing Id + BlogId = Guid.NewGuid(), + Title = title, + UrlSlug = urlSlug, + ShortDescription = shortDescription + }; + + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.CreateAsync(dto)); + + exception.EntityType.ShouldBe(typeof(Blog)); + } + + [Fact] + public async Task GetAsync_ShouldWorkProperly_WithExistingId() + { + var blogPost = await blogPostAdminAppService.GetAsync(cmsKitTestData.BlogPost_1_Id); + + blogPost.Title.ShouldBe(cmsKitTestData.BlogPost_1_Title); + blogPost.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_1_UrlSlug); + } + + [Fact] + public async Task GetAsync_ShouldThrowException_WithNonExistingId() + { + var nonExistingId = Guid.NewGuid(); + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.GetAsync(nonExistingId)); + + exception.EntityType.ShouldBe(typeof(BlogPost)); + exception.Id.ShouldBe(nonExistingId); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingUrlSlug() + { + var blogPost = await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogPost_1_UrlSlug); + + blogPost.Id.ShouldBe(cmsKitTestData.BlogPost_1_Id); + blogPost.Title.ShouldBe(cmsKitTestData.BlogPost_1_Title); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingUrlSlug() + { + var nonExistingUrlSlug = "any-other-url"; + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.Page_1_Url)); + + exception.EntityType.ShouldBe(typeof(BlogPost)); + } + + [Fact] + public async Task GetListAsync_ShouldWorkProperly_WithDefaultParameters() + { + var list = await blogPostAdminAppService.GetListAsync(new PagedAndSortedResultRequestDto()); + + list.ShouldNotBeNull(); + list.TotalCount.ShouldBe(2); + list.Items.ShouldNotBeEmpty(); + list.Items.Count.ShouldBe(2); + } + + [Fact] + public async Task UpdateAsync_ShouldWorkProperly_WithRegularDatas() + { + var shortDescription = "Another short description"; + var title = "[Solved] Another Blog Post"; + var urlSlug = "another-short-blog-post"; + + await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, new CreateUpdateBlogPostDto + { + BlogId = cmsKitTestData.Blog_Id, + ShortDescription = shortDescription, + Title = title, + UrlSlug = urlSlug, + }); + + var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_2_Id); + + blogPost.Title.ShouldBe(title); + blogPost.ShortDescription.ShouldBe(shortDescription); + blogPost.UrlSlug.ShouldBe(urlSlug); + } + + [Fact] + public async Task UpdateAsync_ShouldThrowException_WhileChangingWithNonExistingBlogId() + { + var nonExistingId = Guid.NewGuid(); + + var dto = new CreateUpdateBlogPostDto + { + BlogId = nonExistingId, + Title = cmsKitTestData.Page_2_Title, + UrlSlug = cmsKitTestData.BlogPost_2_UrlSlug + }; + + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, dto)); + + exception.EntityType.ShouldBe(typeof(Blog)); + exception.Id.ShouldBe(nonExistingId); + } + + [Fact] + public async Task UpdateAsync_ShouldThrowException_WhileUpdatingWithAlreadyExistingSlug() + { + var dto = new CreateUpdateBlogPostDto + { + BlogId = cmsKitTestData.Blog_Id, + Title = "Some new title", + UrlSlug = cmsKitTestData.BlogPost_1_UrlSlug + }; + + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, dto)); + + exception.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_1_UrlSlug); + } + + [Fact] + public async Task DeleteAsync_ShouldWorkProperly_WithExistingId() + { + await blogPostAdminAppService.DeleteAsync(cmsKitTestData.Page_2_Id); + + var exception = await Should.ThrowAsync(async () => + await blogPostRepository.GetAsync(cmsKitTestData.Page_2_Id)); + + exception.EntityType.ShouldBe(typeof(BlogPost)); + exception.Id.ShouldBe(cmsKitTestData.Page_2_Id); + } + + [Fact] + public async Task SetCoverImage_ShouldNotThrowException_WithCorrectData() + { + using (var imageStream = GetSampleImageStream()) + { + await WithUnitOfWorkAsync(async () => + { + await blogPostAdminAppService.SetCoverImageAsync( + cmsKitTestData.BlogPost_2_Id, + new RemoteStreamContent(imageStream)); + }); + } + } + + private Stream GetSampleImageStream() + { + var assembly = GetType().Assembly; + var resourceName = "Volo.CmsKit.Data.BlogPostSample.png"; + + return assembly.GetManifestResourceStream(resourceName); + } + // SetCoverImage } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Data/BlogPostSample.png b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Data/BlogPostSample.png new file mode 100644 index 0000000000000000000000000000000000000000..117bc57c3d3730c6ddc12346bb60c351716520c6 GIT binary patch literal 6932 zcmV+v8|&nWP)CMy6iA^<4*`1(2kKIPu#T0C7+DOG7o zYs0t0tDCIW&etITC*s}W%f!s~^7bA8B!Ovz8~`HZ+vL2jy|$~io{XUE=j>rYWX{6R z=m0|K07-UVc+9}fv!t{Z03Di%oag{dh;oXQftGJoa;~4RL>xy^E>vMXWIql=S1(#{ zQFG47&Pf?fmxY;7EK`ekjr-2sY*ugZZmFh5P<{Bm&O-o4>@92WW{Qr1knww*000S_QL3Q;02$m#L_t(|ob6rvU)wmg zPbxoT%TCC{0h0%D(uR}(O$(UN*zo#o6Gz?>_cnZ&ZTZ@%(Ocdg|x~!J395(oBpE-LiYD z$$b2_2v10^H*D&Tfl*aS2pf(yYQJrSCn3MJU7ZqB4Lv8#up5`2|JB7Qgz&{YSj;3!b@EyqAJOce4Y5Gy? zxd;CfklWB6hyP9)H@)W`{;Q{Nz(0~gM)%DYdMq8p_c!4mt$;p#=4tH7KjZY=V<|?* zwSx_*#((Gb62s6VKbT-s%d(D~b@0qniKu_7$7GS`9!nvb>mO6_kNjK%U9GQY!}j#- zY(Bi~HrEdtN%f1X<_p*Yb!J4M+H;Sk0QnQUYAf(ZrjD<|>50VAb#ETtVm)OII+N$t z0cxH@4DT&@1vK)kO5hdYf7v+<6yUEpM}ra)+@C5|09nJQ z8E+waJ@|L6Y65@LIcmv5Kj?d&_scK8cwSvz8h2hZq%GiFKKbBN>DA!h)vF2oH#jLd zyw+@V8`+`6uq>V6+STH^oivI3OF3$1&3?=r6!dEFZ<$- zK}sR~?GniCd*kzSuV3s*dHC18@%Vh)uYVWYEbyYCja6~UG#Z(@3V+W@z>j<3IQ=Pu z`_sg3!7B<+%Mo@)_wlofs6U--h!K%)7zA&whq+E&2L8cdyT%Zm`>$Shk>VkV!hu!smGx5{eENtD5X^GIuT|`9 zQ>H25?@p_7hE5>U9;Gg4lDuUnyGjsQtJFQPWB(ldkuGFTg5jiQ>tyeL5yP@;cT>1J zZdZ`?%-?N7_^h%U;A~YO21Qb)nZ(~46$q(da#KhT__GY&XYX}Fbq$VtyZdn_{)m8C zxr5M1_*)3;xCzaMAxwQSf42^8AahhHL%}3zi=|A{?y4|L;6KbiNwp_^QJ`*V{7@`7 ziK|N980?uf3x8ztaHcz7NLj5tna%<{zI_T`O#R(09B8Rbz{#d?0M@uw*c$@=e$&c& zfG{g9*Hyfb+@3T-)>h^XceIBy1Aj!gs5oEfsc+LPATZl-2k7x6T)1s;2_K-Pv@BA{ ztjazL!2e623aO+K>I}1o)-Al25m`-X0lb4y$iQD`Ea1+valj_e?_PBH=h{`Q7Uw_( zmk7g6m9l4d^4L_3N5fK zm$jZFbC|VFAKJBqh(?@VZ5ejM(Z;rQ$za3x;tudvhvB5+&&Eju?2%MhFQ4BtMPec9LA6{&0Cfc< z^k!->D+r-~ok%k)@h6+qY9#kU&;#1N!mq9i8rHM*9Y5XUvqmVM!3fL?=X*C(DEtx5te=Bb<$ z;oP$-U@l};$s)_0@h3v;Wy4;4Ll;JkzeNR~$b}{m+6x3{O>qS}ZTV+<9KLGS8D~# zrG5>J^pxug3IBZfcg_`9eJdgQX5fFMNI^jx0EC-|&p2Nz;t34Fz>ORQFaZiAY0|6715XDLjwJs2u*k!F;KDFfc%T5-J_Sqqwg5%vFqsQB zS{44(_z6HF4AoL$I0qIg3-2!&KWg!w@PORRDaGo8uNL)|p~CJlQ#FAfo6A9umCg#8h@#j_MuM;%p zhE9j+K8Ry+_K&8-Et#D(m;?7z!k;=!$DF6B+YoX8JAvNQ9l&`TJseou=hCZpU}9)a zS*Z~i5F3eJTxOD$K8K73&LI9q!9tpt0Axe@*)@Bd+06K9GX6N`IWC3K zBDQn?lYl>xLH|1Z$L9$aI(44!h>c!V%4ir(u0>@0>Cjn-h%2DKJ|*%0^zZmz6ZU&*+b^}`Cn0|=XDON15{gBM zLq8PRMa2FXx-uDcVzaDBv8BoxOYpvH*Ulm zaqBPO)n*BHE*zbb#eiILX^X=r0ROBdR}z=?Mr?kZFfJ~;n3ZeJ-)EIZ7XI<1U9M7T z1mHJ`{UZSstKb$>0909X1BeP<=vJlYR(m2lO;7@>mmda5Q-@w$VoErtk zuO{%*o60>Klmh?GVX}CQP3lgKv1!(Eb#BDRQtZ?`<@NaPZ5B%?|@PGH$;rBc) z$na;vlHw0iFxoObX~!j5=@YA5XBmf-4G4=mWgj+`CUBh;(#0uYQWf1l690+{e#-w| z2LDrK3-Mp4;?G?PmV_=$+yk>D{H?MN;{&16QWDZ72*fB=@`s<2NXP$g#RmBFzwux> zv&8y$F3Eq0e|qo=;D1qel3%|k{<2B&E%@{3;Ht8b@$VME|Bnwc{xk-}y#>ncHW0eMr?j>e{_@`&!xuviRm6Rf2e^UH; z7T}*HKY`z0vR?ss0mUD9fhDy`A0!E5(Z%sE9e?AC8EvKkJPr{*h$VY7@vr>)_xpGS zKE3}tj=fcU5ZR}xGHy^YT?^oGGAi1*;Z)WE21z7}|Cmp;qyxs)FWST(0sKog)9G^t z?FBG5#lrOruWbAy8T8w`_YuAOFVDb(azmDt=7tB`_yB)9BN)>Ho2gXHCIE-eDE=vE>70RAOegNI&rc5na-Mq=H<^BHZDXSUrc7~1N=daQ4!*1*xr`_@`w5seLDC8_>0uyt{tBvQ1R^I z368&(SvdwEtCncU;KEvAhCkSJoiY{>Xq(WZgMj##at?vO-wQ4fTc()`wnSy|Z@~i^ zv{(#OT=3+5yI}Yn)}NG!^TKj5jz8GzWsDYJzOk};0sl-9nj}z1OLmL-6&OI(_&LC)XYW3PK*Yu#bg5L;DY7gpGulWa}u!9TnA8d{BzIWL1AuQ<$gW5 zO^yxVUl{-s0pa`wfTyd`1_<0F{zZEFPT?_TRu}BUSI}m8hoioa#9u>9P5^gU(0CMo z#s%qAhYbtN^s^uFz^~*xH=wBi#R8&KYSei zc*U6X9K6ziDMX4tDUerhLv^ZUOO2K$cjFN7?+Zp+_H`&?vkOtg%lKExC{sELT~d(A zzY7JBb`&pS-F__oI`8iRPkYcZr~^^_jUpQLT6mjtooYF{GgX%q0sqQe@D0c+eE?G| z9t0Ik90mSWGh;vP@3RAw0H&M|H#jSdzce0&zt-XYtlIz+5YJA<_%n|?ll+y~f8aD_ znp3Q7&LZNUXqbUMPSmEOw-&9~#I+qN{G(Sj)XN#nJ__F#mBkEdIJ(PrT~SKokMw&G zSZTtOyGMd_jPWmcro~IxS30_piVlLdmeS8Hfxo**9K^G`lK12e)~6!CdZJ2Ijek|^ zt>yk3UbmNcrKt6wkHf?9Eh_{6l%AOnkTV74l{h*Y<8Kzc6S8H9Z$iXgTzEcfKizMK zozzZ}3H&R;Rk9yUr?zeJX4b)At0fzXk)*elg8vQ#YcdVk!~FA$`((#VZ6hv`3m?YM zl1)e|{_a92;sB6F@X;AuR-qS0lF<+N7tce<{g*V-*|lHVe!ZJ4G~3ANOO(XFa=c1@ z8)2(+Kl*(4bvqe-vE}=nh~!=Y$fT9Py8UGtMi09SH@YLSs)mw!T4>AJp@J@0^-|-X zt~Wcv7TGoI+BMqJtyS|<;BdDIS(ZzmF~q-+_N5D;VDH_lBT})Vd6ka8%1DhnhN*jo z8FJ4yjz3zYKP=f7Wz{pL3_`j?2 zI;K@&huh5dY0?t`yBF%ED#yIy{U@>6f(6Qo1he0i1X>y)TXjH$)O21pj0mBZh^)WpGXgY74Noy*g$ru zb`M1SE5W2lYdrlbt=7XA8qFtSNoDZ&FHl0^6E5YO7<2qf*DW2UnbUw#>&5NKa`CTJ zhE9$|L)I!Sv68^QQaNAcwUZ{wu01gc!67l!R04l*i<9OS;pP1odKKXRv2@+`{teAu z#vZ`E1qCepXvg$_sRc&C*2(BUANh0bRKO(scOCmOdT=Asn`P!`?uFkv5FCa5-&Rf2lq(HmKjJ_Y`fo48E6 zMe)P1j)pn;&J#fz3ND($|LvUOuzgPNstLS7yJ@K|lF+%|xKB$l{B>Nm1{sW})kFp{ zdDsf=Zuu}5)3V3v_T+U}#DHf1?qPT(M>qsh;vbnF!-jY@@~%B3spedbvZt9K3^9mi zyZ4l>Vf@D=)~Qw7kWn)|o`RuTbTZD|SVOJz7szSjInI zUW8I5D0$!(j^Eh-gyDZ(`F7gfKYzG>{yW?m<=4~ivR6<#{yTD`q3s`5@NTRWINAy}P*sOk=;7**68MuEkTC4_LDmHN zdyVT4l&_=bNTb@c?QL~)mpyDYvz@F9eZxPG!emeo*@_Ykf84s5EE`u3C~|-w8qMw5SpHIfnapy$;h#(HNQ%m0 zoPJ=|k0|9om%0>`$h%7G)zH)7pGch_wt%xNdsm~|M)JK_S@$@-E_y=zE0u|y8A_bD z$fIDm(q$Fxl-#@vlr($uvaFu$3Fo z>(58hd5j&IX6bzI3#KQ=zcQ|=@A%ehS@G=p$?V8fU(abQ9+hu=sr1zNM~+j{5r{W| zX5g#q_DM44UOzdTEozps7%lo$M|ooP_0p5$UvV$(w9Lxx$~EobYJEK$&d<(L1^cQ6v=hs0$4F8Hd-#m5&BJ_VY zy-Vo`Ycchn82??7*wtgC5Y~?dKbO%7C_JKc`{ejXD=-~d$}+uFLWE3mt}1=i@732lJcmb#u91FPq`);%qSf8QrX> arvC?iPWR;4_05R@0000Volo.CmsKit + + + + + + + + diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 66489f80e8..42b0605e5d 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -276,7 +276,7 @@ namespace Volo.CmsKit private async Task SeedBlogsAsync() { - var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.BlogName)); + var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName)); await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_UrlSlug, "Short desc 1")); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 2da69a5ac6..117cf49b11 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -7,6 +7,7 @@ namespace Volo.CmsKit public class CmsKitTestData : ISingletonDependency { public Guid User1Id { get; } = Guid.NewGuid(); + public string User1UserName => "fake.user"; public Guid User2Id { get; } = Guid.NewGuid(); From 8aef06bde3787e28161fbc38d1c5ec99154e89b5 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 12:25:46 +0300 Subject: [PATCH 23/70] CmsKit - Add Http Method bindings to BlogPostAdminController --- .../CmsKit/Admin/Blogs/BlogPostAdminController.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index 554200b492..e923cabf46 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -29,26 +29,35 @@ namespace Volo.CmsKit.Admin.Blogs BlogPostAdminAppService = blogPostAdminAppService; } + [HttpGet] public virtual Task CreateAsync(CreateUpdateBlogPostDto input) { return BlogPostAdminAppService.CreateAsync(input); } + [HttpDelete] + [Route("{id}")] public virtual Task DeleteAsync(Guid id) { return BlogPostAdminAppService.DeleteAsync(id); } + [HttpGet] + [Route("{id:Guid}")] public virtual Task GetAsync(Guid id) { return BlogPostAdminAppService.GetAsync(id); } + [HttpGet] + [Route("{urlSlug}")] public virtual Task GetByUrlSlugAsync(string urlSlug) { return BlogPostAdminAppService.GetByUrlSlugAsync(urlSlug); } + [HttpGet] + [Route("{id}/cover-image")] public virtual Task GetCoverImageAsync(Guid id) { Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); @@ -59,16 +68,20 @@ namespace Volo.CmsKit.Admin.Blogs return BlogPostAdminAppService.GetCoverImageAsync(id); } + [HttpGet] public virtual Task> GetListAsync(PagedAndSortedResultRequestDto input) { return BlogPostAdminAppService.GetListAsync(input); } + [NonAction] public virtual Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent) { return BlogPostAdminAppService.SetCoverImageAsync(id, streamContent); } + [HttpPost] + [Route("{id}/cover-image")] public virtual async Task UploadCoverImageAsync(Guid id, IFormFile file) { if (file == null) @@ -84,6 +97,8 @@ namespace Volo.CmsKit.Admin.Blogs return StatusCode(201); } + [HttpPut] + [Route("{id}")] public virtual Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) { return BlogPostAdminAppService.UpdateAsync(id, input); From 83b92083656c19b6b242035222a7a66a8512b15e Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 12:49:38 +0300 Subject: [PATCH 24/70] CmsKit - Add BlogAdminController --- .../Permissions/CmsKitAdminPermissions.cs | 1 + .../CmsKit/Admin/Blogs/BlogAdminController.cs | 68 +++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs index 2a70feefc5..38c95ed83d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissions.cs @@ -37,6 +37,7 @@ namespace Volo.CmsKit.Permissions public const string Update = Default + ".Update"; public const string Delete = Default + ".Delete"; } + public static class BlogPosts { public const string Default = GroupName + ".BlogPosts"; diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs new file mode 100644 index 0000000000..36cc6d9ef7 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs @@ -0,0 +1,68 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Blogs +{ + [RequiresGlobalFeature(typeof(BlogsFeature))] + [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Authorize(CmsKitAdminPermissions.Blogs.Default)] + [Route("api/cms-kit-admin/blogs/blogs")] + public class BlogAdminController : CmsKitAdminController, IBlogAdminAppService + { + protected IBlogAdminAppService BlogAdminAppService { get; } + + public BlogAdminController(IBlogAdminAppService blogAdminAppService) + { + BlogAdminAppService = blogAdminAppService; + } + + [HttpPost] + [Authorize(CmsKitAdminPermissions.Blogs.Create)] + public Task CreateAsync(BlogDto input) + { + return BlogAdminAppService.CreateAsync(input); + } + + [HttpDelete] + [Route("{id}")] + [Authorize(CmsKitAdminPermissions.Blogs.Delete)] + public Task DeleteAsync(Guid id) + { + return BlogAdminAppService.DeleteAsync(id); + } + + [HttpGet] + [Route("{id}")] + [Authorize(CmsKitAdminPermissions.Blogs.Default)] + public Task GetAsync(Guid id) + { + return BlogAdminAppService.GetAsync(id); + } + + [HttpGet] + [Authorize(CmsKitAdminPermissions.Blogs.Default)] + public Task> GetListAsync([FromQuery] PagedAndSortedResultRequestDto input) + { + return BlogAdminAppService.GetListAsync(input); + } + + [HttpPut] + [Route("{id}")] + [Authorize(CmsKitAdminPermissions.Blogs.Update)] + public Task UpdateAsync(Guid id, BlogDto input) + { + return BlogAdminAppService.UpdateAsync(id, input); + } + } +} From fd05d1404f4c90b97beb7ad8ddfe28b4dbc2f80c Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 12:56:31 +0300 Subject: [PATCH 25/70] CmsKit - Add missing authorize attributes to BlogPostAdminController --- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index e923cabf46..54550113fd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -30,6 +30,7 @@ namespace Volo.CmsKit.Admin.Blogs } [HttpGet] + [Authorize(CmsKitAdminPermissions.BlogPosts.Create)] public virtual Task CreateAsync(CreateUpdateBlogPostDto input) { return BlogPostAdminAppService.CreateAsync(input); @@ -37,6 +38,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpDelete] [Route("{id}")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Delete)] public virtual Task DeleteAsync(Guid id) { return BlogPostAdminAppService.DeleteAsync(id); @@ -44,6 +46,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpGet] [Route("{id:Guid}")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] public virtual Task GetAsync(Guid id) { return BlogPostAdminAppService.GetAsync(id); @@ -51,6 +54,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpGet] [Route("{urlSlug}")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] public virtual Task GetByUrlSlugAsync(string urlSlug) { return BlogPostAdminAppService.GetByUrlSlugAsync(urlSlug); @@ -58,6 +62,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpGet] [Route("{id}/cover-image")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] public virtual Task GetCoverImageAsync(Guid id) { Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); @@ -69,6 +74,7 @@ namespace Volo.CmsKit.Admin.Blogs } [HttpGet] + [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] public virtual Task> GetListAsync(PagedAndSortedResultRequestDto input) { return BlogPostAdminAppService.GetListAsync(input); @@ -82,6 +88,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpPost] [Route("{id}/cover-image")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Update)] public virtual async Task UploadCoverImageAsync(Guid id, IFormFile file) { if (file == null) @@ -99,6 +106,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpPut] [Route("{id}")] + [Authorize(CmsKitAdminPermissions.BlogPosts.Update)] public virtual Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) { return BlogPostAdminAppService.UpdateAsync(id, input); From 0555f99352ea50144fefcfeafdef69e89611e353 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 14:33:37 +0300 Subject: [PATCH 26/70] CmsKit - Add Blogs Permissions into PermissionDefinitionProvider --- .../CmsKitAdminPermissionDefinitionProvider.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs index bc55cc14e1..0303af762e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Permissions/CmsKitAdminPermissionDefinitionProvider.cs @@ -1,4 +1,5 @@ -using Volo.Abp.Authorization.Permissions; + +using Volo.Abp.Authorization.Permissions; using Volo.Abp.GlobalFeatures; using Volo.Abp.Localization; using Volo.CmsKit.GlobalFeatures; @@ -12,7 +13,6 @@ namespace Volo.CmsKit.Permissions { var cmsGroup = context.GetGroupOrNull(CmsKitAdminPermissions.GroupName) ?? context.AddGroup(CmsKitAdminPermissions.GroupName, L("Permission:CmsKit")); - if (GlobalFeatureManager.Instance.IsEnabled()) { var contentGroup = cmsGroup.AddPermission(CmsKitAdminPermissions.Contents.Default, L("Permission:Contents")); @@ -35,6 +35,19 @@ namespace Volo.CmsKit.Permissions pageManagement.AddChild(CmsKitAdminPermissions.Pages.Update, L("Permission:PageManagement:Update")); pageManagement.AddChild(CmsKitAdminPermissions.Pages.Delete, L("Permission:PageManagement:Delete")); } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + var blogManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.Blogs.Default, L("Permission:BlogManagement")); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Create, L("Permission:BlogManagement.Create")); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Update, L("Permission:BlogManagement.Update")); + blogManagement.AddChild(CmsKitAdminPermissions.Blogs.Delete, L("Permission:BlogManagement.Delete")); + + var blogPostManagement = cmsGroup.AddPermission(CmsKitAdminPermissions.BlogPosts.Default, L("Permission:BlogPostManagement")); + blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Create, L("Permission:BlogPostManagement.Create")); + blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Update, L("Permission:BlogPostManagement.Update")); + blogManagement.AddChild(CmsKitAdminPermissions.BlogPosts.Delete, L("Permission:BlogPostManagement.Delete")); + } } private static LocalizableString L(string name) From 4b23cb616addb4e653039c3d9e497c2e12377e5a Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 15:03:34 +0300 Subject: [PATCH 27/70] CmsKit - Add missing validations to BlogDto --- .../Volo/CmsKit/Admin/Blogs/BlogDto.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs index 9c88a0ed01..1b772c51e5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs @@ -1,10 +1,13 @@ using System; using Volo.Abp.Application.Dtos; +using Volo.Abp.Validation; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit.Admin.Blogs { public class BlogDto : EntityDto { + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] public string Name { get; set; } } } From 4290f3b93261b6a8fd8b9b0d54dbae58a9af3a0a Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 15:44:57 +0300 Subject: [PATCH 28/70] CmsKit - Add UrlSlug to Blog --- .../Volo/CmsKit/Admin/Blogs/BlogDto.cs | 6 + .../Volo/CmsKit/Blogs/BlogConsts.cs | 1 + .../Volo.CmsKit.Domain.csproj | 4 + .../Volo/CmsKit/Blogs/Blog.cs | 12 ++ .../Volo/CmsKit/Blogs/BlogPost.cs | 25 +--- .../Blogs/Extensions/UrlSlugExtensions.cs | 30 ++++ .../Blogs/UrlSlugExtensions_Tests.cs | 139 ++++++++++++++++++ .../CmsKitDataSeedContributor.cs | 2 +- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 2 + 9 files changed, 197 insertions(+), 24 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs index 1b772c51e5..0f112d15b8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel.DataAnnotations; using Volo.Abp.Application.Dtos; using Volo.Abp.Validation; using Volo.CmsKit.Blogs; @@ -7,7 +8,12 @@ namespace Volo.CmsKit.Admin.Blogs { public class BlogDto : EntityDto { + [Required] [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxNameLength))] public string Name { get; set; } + + [Required] + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxUrlSlugLength))] + public string UrlSlug { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs index e722d4656d..7d2467226d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs @@ -3,5 +3,6 @@ public class BlogConsts { public static int MaxNameLength { get; set; } = 64; + public static int MaxUrlSlugLength { get; set; } = 64; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj index 0fc25899e9..7355bc87d1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj @@ -8,6 +8,10 @@ + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 0ec587f52e..1dc571d69f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -3,6 +3,7 @@ using System; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; +using Volo.CmsKit.Blogs.Extensions; namespace Volo.CmsKit.Blogs { @@ -11,19 +12,30 @@ namespace Volo.CmsKit.Blogs public Blog( Guid id, [NotNull] string name, + [NotNull] string urlSlug, [CanBeNull] Guid? tenantId = null) : base(id) { SetName(name); + SetUrlSlug(urlSlug); TenantId = tenantId; } public string Name { get; protected set; } + public string UrlSlug { get; protected set; } + public Guid? TenantId { get; } public void SetName(string name) { Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: BlogConsts.MaxNameLength); } + + public void SetUrlSlug(string urlSlug) + { + Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), maxLength: BlogConsts.MaxNameLength); + + UrlSlug = urlSlug.NormalizeAsUrlSlug(); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 62a73ec352..db0d22b18a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -5,6 +5,7 @@ using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Blogs.Extensions; using Volo.CmsKit.Users; namespace Volo.CmsKit.Blogs @@ -47,29 +48,7 @@ namespace Volo.CmsKit.Blogs { Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); - UrlSlug = NormalizeUrlSlug(urlSlug); - } - - private string NormalizeUrlSlug(string value) - { - value = value.ToLowerInvariant(); - - // TODO: Find best way to unidecode. - // value = value.Unidecode(); - - // Replace spaces - value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled); - - // Remove invalid chars - value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled); - - // Trim dashes from end & dots - value = value.Trim('-', '_', '.'); - - // Replace double occurences of - or _ - value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled); - - return value; + UrlSlug = urlSlug.NormalizeAsUrlSlug(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs new file mode 100644 index 0000000000..45765c4a09 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs @@ -0,0 +1,30 @@ +using System.Text.RegularExpressions; +using Unidecode.NET; + +namespace Volo.CmsKit.Blogs.Extensions +{ + public static class UrlSlugExtensions + { + public static string NormalizeAsUrlSlug(this string value) + { + value = value.ToLowerInvariant(); + + // Unidecode for non-latin characters + value = value.Unidecode(); + + // Replace spaces + value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled); + + // Remove invalid chars + value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled); + + // Trim dashes & dots + value = value.Trim('-', '_', '.'); + + // Replace double occurences of - or _ + value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled); + + return value; + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs new file mode 100644 index 0000000000..0c32ab3285 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xunit; +using Volo.CmsKit.Blogs.Extensions; +using Shouldly; + +namespace Volo.CmsKit.Blogs +{ + public class UrlSlugExtensions_Tests + { + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly() + { + // Arrange + var name = "My awesome name"; + var expected = "my-awesome-name"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDot() + { + // Arrange + var name = "My Perfect Title v.2"; + var expected = "my-perfect-title-v2"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithQuestionMark() + { + // Arrange + var name = "Are you gonna die?"; + var expected = "are-you-gonna-die"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithAmpersand() + { + // Arrange + var name = "We & Machines Challenge"; + var expected = "we-machines-challenge"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDoubleDash() + { + // Arrange + var name = "Go and Code --part 2"; + var expected = "go-and-code-part-2"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithCyrillicChars() + { + // Arrange + var name = "Мое классное название"; + var expected = "moe-klassnoe-nazvanie"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithTurkishChars() + { + // Arrange + var name = "Özel Türkçe karakterler: ğüşiöç"; + var expected = "ozel-turkce-karakterler-gusioc"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithChineseChars() + { + // Arrange + var name = "我的挑战"; + var expected = "o-e-iao-han"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + + [Fact] + public void NormalizeAsUrlSlug_ShouldWorkProperly_WithEmoji() + { + // Arrange + var name = "Let's Rock 👊"; + var expected = "lets-rock"; + + // Act + var actual = name.NormalizeAsUrlSlug(); + + // Assert + actual.ShouldBe(expected); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index aaed5e3d16..9b1f820c23 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -308,7 +308,7 @@ namespace Volo.CmsKit private async Task SeedBlogsAsync() { - var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName)); + var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName, _cmsKitTestData.BlogUrlSlug)); await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_UrlSlug, "Short desc 1")); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 2a0cc0e8bf..99682fbbfb 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -77,6 +77,8 @@ namespace Volo.CmsKit public string BlogName => "Cms Blog"; + public string BlogUrlSlug => "cms-blog"; + public Guid BlogPost_1_Id { get; } = Guid.NewGuid(); public string BlogPost_1_Title => "How to install CmsKit?"; From 84ff2c3518cadb682f034d231f5c66700b32e6a6 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 15:47:19 +0300 Subject: [PATCH 29/70] CmsKit - Add missing ModelCreating constraints for Blog --- .../CmsKitDbContextModelCreatingExtensions.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index fff291d960..ca64253676 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -197,6 +197,8 @@ namespace Volo.CmsKit.EntityFrameworkCore b.ConfigureByConvention(); b.Property(p => p.Name).IsRequired().HasMaxLength(BlogConsts.MaxNameLength); + + b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogConsts.MaxUrlSlugLength); }); builder.Entity(b => From 5f561456372a1bcfa349e12bd32742a3f954841c Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 16:36:25 +0300 Subject: [PATCH 30/70] CmsKit - Add lookup endpoint for Blogs --- .../Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs | 16 ++++++++++++++++ .../CmsKit/Admin/Blogs/IBlogAdminAppService.cs | 4 ++++ .../CmsKit/Admin/Blogs/BlogAdminAppService.cs | 14 ++++++++++++++ .../CmsKit/Admin/Blogs/BlogAdminController.cs | 9 +++++++++ 4 files changed, 43 insertions(+) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs new file mode 100644 index 0000000000..74e63b9150 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs @@ -0,0 +1,16 @@ +using System; + +namespace Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs +{ + public class BlogLookupDto + { + public BlogLookupDto(Guid id, string name) + { + Id = id; + Name = name; + } + + public Guid Id { get; set; } + public string Name { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs index 4072c9f847..9f4d16c7f6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs @@ -1,9 +1,13 @@ using System; +using System.Collections.Generic; +using System.Threading.Tasks; using Volo.Abp.Application.Services; +using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs { public interface IBlogAdminAppService : ICrudAppService { + Task> GetLookupAsync(); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index b6c2195981..5c8ae8e26c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -1,8 +1,12 @@ using Microsoft.AspNetCore.Authorization; using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; @@ -21,5 +25,15 @@ namespace Volo.CmsKit.Admin.Blogs UpdatePolicyName = CmsKitAdminPermissions.Blogs.Update; DeletePolicyName = CmsKitAdminPermissions.Blogs.Delete; } + + [Authorize(CmsKitAdminPermissions.Blogs.Default)] + public async Task> GetLookupAsync() + { + var blogs = await Repository.GetListAsync(); + + return blogs + .Select(s => new BlogLookupDto(s.Id, s.Name)) + .ToList(); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs index 36cc6d9ef7..b12b4f83b1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs @@ -8,6 +8,7 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; @@ -64,5 +65,13 @@ namespace Volo.CmsKit.Admin.Blogs { return BlogAdminAppService.UpdateAsync(id, input); } + + [HttpGet] + [Route("lookup")] + [Authorize(CmsKitAdminPermissions.Blogs.Default)] + public Task> GetLookupAsync() + { + return BlogAdminAppService.GetLookupAsync(); + } } } From 80ad8a12239cfa5c7dadf97f10146389d39733ca Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 16:36:50 +0300 Subject: [PATCH 31/70] CmsKit - Add missing Validations for CreateUpdateBlogPostDto --- .../CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs index 09d881189b..71d091bfa4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs @@ -1,15 +1,27 @@ using System; +using System.ComponentModel.DataAnnotations; +using Volo.Abp.Validation; +using Volo.CmsKit.Blogs; namespace Volo.CmsKit.Admin.Blogs { public class CreateUpdateBlogPostDto { + [Required] public Guid BlogId { get; set; } + [Required] + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxTitleLength))] public string Title { get; set; } + [Required] + [DynamicStringLength( + typeof(BlogPostConsts), + nameof(BlogPostConsts.MaxUrlSlugLength), + nameof(BlogPostConsts.MinUrlSlugLength))] public string UrlSlug { get; set; } + [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] public string ShortDescription { get; set; } } } From 1ec3b2398072e80b946d03d3d75fd5bb73905f19 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 1 Feb 2021 17:37:31 +0300 Subject: [PATCH 32/70] CmsKit - Fix HttpMethod for Create Blog --- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index 54550113fd..0dc8d512ad 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -29,7 +29,7 @@ namespace Volo.CmsKit.Admin.Blogs BlogPostAdminAppService = blogPostAdminAppService; } - [HttpGet] + [HttpPost] [Authorize(CmsKitAdminPermissions.BlogPosts.Create)] public virtual Task CreateAsync(CreateUpdateBlogPostDto input) { From 9feeaf37d33932d754e39da75dfab7918720383a Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Feb 2021 11:48:19 +0300 Subject: [PATCH 33/70] CmsKit - Ensure CmsUser is created while creating BlogPost --- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 36ded2ba1f..3b3d323132 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -7,9 +7,11 @@ using Volo.Abp.BlobStoring; using Volo.Abp.Content; using Volo.Abp.Domain.Repositories; using Volo.Abp.GlobalFeatures; +using Volo.Abp.Users; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; +using Volo.CmsKit.Users; namespace Volo.CmsKit.Admin.Blogs { @@ -27,16 +29,19 @@ namespace Volo.CmsKit.Admin.Blogs protected readonly IBlogPostManager BlogPostManager; protected readonly IBlogPostRepository BlogPostRepository; protected readonly IBlobContainer BlobContainer; + protected readonly ICmsUserLookupService UserLookupService; public BlogPostAdminAppService( IRepository repository, IBlogPostManager blogPostManager, IBlogPostRepository blogPostRepository, - IBlobContainer blobContainer) : base(repository) + IBlobContainer blobContainer, + ICmsUserLookupService userLookupService) : base(repository) { BlogPostManager = blogPostManager; BlogPostRepository = blogPostRepository; BlobContainer = blobContainer; + UserLookupService = userLookupService; GetListPolicyName = CmsKitAdminPermissions.BlogPosts.Default; GetPolicyName = CmsKitAdminPermissions.BlogPosts.Default; @@ -55,6 +60,8 @@ namespace Volo.CmsKit.Admin.Blogs [Authorize(CmsKitAdminPermissions.BlogPosts.Create)] public override async Task CreateAsync(CreateUpdateBlogPostDto input) { + _ = await UserLookupService.GetByIdAsync(CurrentUser.GetId()); + var entity = await BlogPostManager .CreateAsync( new BlogPost( From 12f378c729f742b3207db4e13a8e2dc9d7a72f2d Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Feb 2021 11:48:35 +0300 Subject: [PATCH 34/70] CmsKit - Add missing ShortDescription to BlogPost --- .../Volo/CmsKit/Admin/Blogs/BlogPostDto.cs | 1 + .../src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs index 2c3ff84d48..e1463ceba3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs @@ -10,5 +10,6 @@ namespace Volo.CmsKit.Admin.Blogs public string Title { get; set; } public string UrlSlug { get; set; } + public string ShortDescription { get; protected set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index db0d22b18a..1ebe6d72d7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -18,7 +18,7 @@ namespace Volo.CmsKit.Blogs public string UrlSlug { get; protected set; } - public string ShortDescription { get; set; } + public string ShortDescription { get; protected set; } public Guid? TenantId { get; } @@ -50,5 +50,10 @@ namespace Volo.CmsKit.Blogs UrlSlug = urlSlug.NormalizeAsUrlSlug(); } + + public void SetShortDescription(string shortDescription) + { + ShortDescription = Check.Length(shortDescription, nameof(shortDescription), BlogPostConsts.MaxShortDescriptionLength); + } } } From 85cab4311d9123cff63816ace7bfb685727533c8 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Feb 2021 15:47:44 +0300 Subject: [PATCH 35/70] CmsKit - BlogPost Public logic in Repositories & AppServices --- .../Admin/Blogs/IBlogPostAdminAppService.cs | 8 +- .../Admin/Blogs/BlogPostAdminAppService.cs | 9 +- .../Admin/Blogs/BlogPostAdminController.cs | 6 +- .../Volo/CmsKit/Users/CmsUserDto.cs | 20 +++ ...msKitCommonApplicationAutoMapperProfile.cs | 3 + .../Volo/CmsKit/Blogs/Blog.cs | 2 +- .../Volo/CmsKit/Blogs/BlogPost.cs | 2 +- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 10 +- .../BlogPostUrlSlugAlreadyExistException.cs | 10 +- .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 7 +- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 2 + .../CmsKit/Blogs/EfCoreBlogPostRepository.cs | 32 ++++- .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 6 + .../CmsKitDbContextModelCreatingExtensions.cs | 2 +- .../MongoDB/Blogs/MongoBlogPostRepository.cs | 34 ++++- .../MongoDB/Blogs/MongoBlogRepository.cs | 6 + .../CmsKit/Public/Blogs/BlogPostPublicDto.cs | 17 +++ .../Public/Blogs/IBlogPostPublicAppService.cs | 13 ++ .../Public/Blogs/BlogPostPublicAppService.cs | 41 ++++++ .../PublicApplicationAutoMapperProfile.cs | 6 +- .../Blogs/BlogPostAdminAppService_Tests.cs | 16 ++- .../Blogs/BlogPostRepository_Test.cs | 14 ++ .../Blogs/BlogRepository_Test.cs | 14 ++ .../MongoDB/Blogs/BlogPostRepository_Test.cs | 16 +++ .../MongoDB/Blogs/BlogRepository_Test.cs | 16 +++ .../Blogs/BlogPostRepository_Test.cs | 125 ++++++++++++++++++ .../Blogs/BlogRepository_Test.cs | 47 +++++++ 27 files changed, 448 insertions(+), 36 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogPostRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogPostRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs index 866c536b85..902f31f025 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs @@ -6,14 +6,14 @@ using Volo.Abp.Content; namespace Volo.CmsKit.Admin.Blogs { - public interface IBlogPostAdminAppService + public interface IBlogPostAdminAppService : ICrudAppService< - BlogPostDto, - Guid, + BlogPostDto, + Guid, PagedAndSortedResultRequestDto, CreateUpdateBlogPostDto> { - Task GetByUrlSlugAsync(string urlSlug); + Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug); Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 3b3d323132..3034311d70 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -28,6 +28,7 @@ namespace Volo.CmsKit.Admin.Blogs { protected readonly IBlogPostManager BlogPostManager; protected readonly IBlogPostRepository BlogPostRepository; + protected readonly IBlogRepository BlogRepository; protected readonly IBlobContainer BlobContainer; protected readonly ICmsUserLookupService UserLookupService; @@ -35,11 +36,13 @@ namespace Volo.CmsKit.Admin.Blogs IRepository repository, IBlogPostManager blogPostManager, IBlogPostRepository blogPostRepository, + IBlogRepository blogRepository, IBlobContainer blobContainer, ICmsUserLookupService userLookupService) : base(repository) { BlogPostManager = blogPostManager; BlogPostRepository = blogPostRepository; + BlogRepository = blogRepository; BlobContainer = blobContainer; UserLookupService = userLookupService; @@ -50,9 +53,11 @@ namespace Volo.CmsKit.Admin.Blogs DeletePolicyName = CmsKitAdminPermissions.BlogPosts.Delete; } - public virtual async Task GetByUrlSlugAsync(string urlSlug) + public virtual async Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug) { - var blogPost = await BlogPostRepository.GetByUrlSlugAsync(urlSlug); + var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + + var blogPost = await BlogPostRepository.GetByUrlSlugAsync(blog.Id, urlSlug); return MapToGetOutputDto(blogPost); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index 0dc8d512ad..b71f731efd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -53,11 +53,11 @@ namespace Volo.CmsKit.Admin.Blogs } [HttpGet] - [Route("{urlSlug}")] + [Route("{blogUrlSlug}/{urlSlug}")] [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] - public virtual Task GetByUrlSlugAsync(string urlSlug) + public virtual Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug) { - return BlogPostAdminAppService.GetByUrlSlugAsync(urlSlug); + return BlogPostAdminAppService.GetByUrlSlugAsync(blogUrlSlug, urlSlug); } [HttpGet] diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs new file mode 100644 index 0000000000..3600688f4b --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Users/CmsUserDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Users +{ + public class CmsUserDto : EntityDto + { + public virtual Guid? TenantId { get; protected set; } + + public virtual string UserName { get; protected set; } + + public virtual string Name { get; set; } + + public virtual string Surname { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs index e5044dc200..9d89ddadeb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/CmsKitCommonApplicationAutoMapperProfile.cs @@ -2,6 +2,7 @@ using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; using Volo.CmsKit.Tags; +using Volo.CmsKit.Users; namespace Volo.CmsKit { @@ -10,6 +11,8 @@ namespace Volo.CmsKit public CmsKitCommonApplicationAutoMapperProfile() { CreateMap(); + + CreateMap(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 1dc571d69f..75d319b33b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -24,7 +24,7 @@ namespace Volo.CmsKit.Blogs public string UrlSlug { get; protected set; } - public Guid? TenantId { get; } + public Guid? TenantId { get; protected set; } public void SetName(string name) { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 1ebe6d72d7..2a9f6673f2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -20,7 +20,7 @@ namespace Volo.CmsKit.Blogs public string ShortDescription { get; protected set; } - public Guid? TenantId { get; } + public Guid? TenantId { get; protected set; } protected BlogPost() { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 6bbb772072..61198e0fad 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -24,7 +24,7 @@ namespace Volo.CmsKit.Blogs { await CheckBlogExistenceAsync(blogPost.BlogId); - await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); + await CheckUrlSlugExistenceAsync(blogPost.BlogId, blogPost.UrlSlug); return await blogPostRepository.InsertAsync(blogPost); } @@ -33,16 +33,16 @@ namespace Volo.CmsKit.Blogs { await CheckBlogExistenceAsync(blogPost.BlogId); - await CheckUrlSlugExistenceAsync(blogPost.UrlSlug); + await CheckUrlSlugExistenceAsync(blogPost.BlogId, blogPost.UrlSlug); await blogPostRepository.UpdateAsync(blogPost); } - private async Task CheckUrlSlugExistenceAsync(string urlSlug) + private async Task CheckUrlSlugExistenceAsync(Guid blogId, string urlSlug) { - if (await blogPostRepository.SlugExistsAsync(urlSlug)) + if (await blogPostRepository.SlugExistsAsync(blogId, urlSlug)) { - throw new BlogPostUrlSlugAlreadyExistException(urlSlug); + throw new BlogPostUrlSlugAlreadyExistException(blogId, urlSlug); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs index c21ccfa8e7..b000f5996d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using Volo.Abp; namespace Volo.CmsKit.Blogs @@ -17,15 +13,19 @@ namespace Volo.CmsKit.Blogs { } - public BlogPostUrlSlugAlreadyExistException(string urlSlug) + public BlogPostUrlSlugAlreadyExistException(Guid blogId, string urlSlug) { UrlSlug = urlSlug; + BlogId = blogId; Code = CmsKitErrorCodes.Blogs.UrlSlugAlreadyExist; WithData(nameof(UrlSlug), UrlSlug); + WithData(nameof(BlogId), BlogId); } public string UrlSlug { get; } + + public Guid BlogId { get; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index a9e35e3794..fdb721d8d8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; @@ -9,8 +10,10 @@ namespace Volo.CmsKit.Blogs { public interface IBlogPostRepository : IBasicRepository { - Task SlugExistsAsync(string slug); + Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default); - Task GetByUrlSlugAsync(string urlSlug); + Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default); + + Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index 90e59587a2..152c17d615 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -1,9 +1,11 @@ using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Volo.CmsKit.Blogs { public interface IBlogRepository : IBasicRepository { + public Task GetByUrlSlugAsync(string urlSlug); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs index 09445da84d..1a6546d5fc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs @@ -1,9 +1,15 @@ using Microsoft.EntityFrameworkCore; using System; +using System.Collections.Generic; +using System.Linq.Dynamic.Core; +using System.Security.Cryptography.X509Certificates; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore; +using System.Linq; +using System.Data.Common; namespace Volo.CmsKit.Blogs { @@ -13,16 +19,34 @@ namespace Volo.CmsKit.Blogs { } - public Task GetByUrlSlugAsync(string urlSlug) + public Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) { - return GetAsync(x => x.UrlSlug.ToLower() == urlSlug); + return GetAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug, cancellationToken: cancellationToken); } - public async Task SlugExistsAsync(string slug) + public async Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) + { + + var queryable = (await GetQueryableAsync()) + .Include(i => i.Creator) + .Where(x => x.BlogId == blogId); + + if (!sorting.IsNullOrWhiteSpace()) + { + queryable = queryable.OrderBy(sorting); + } + + return await queryable + .Skip(skipCount) + .Take(maxResultCount) + .ToListAsync(cancellationToken); + } + + public async Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default) { var dbSet = await GetDbSetAsync(); - return await dbSet.AnyAsync(x => x.UrlSlug.ToLower() == slug); + return await dbSet.AnyAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs index a43504642c..76211780f6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore; @@ -10,5 +11,10 @@ namespace Volo.CmsKit.Blogs public EfCoreBlogRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) { } + + public Task GetByUrlSlugAsync(string urlSlug) + { + return GetAsync(x => x.UrlSlug == urlSlug); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index ca64253676..57d1f5511c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -213,7 +213,7 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.ShortDescription).HasMaxLength(BlogPostConsts.MaxShortDescriptionLength); - b.HasIndex(x => x.UrlSlug); + b.HasIndex(x => new { x.UrlSlug, x.BlogId }); }); } else diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 166eda7f0d..638c219bb6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -1,4 +1,8 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Dynamic.Core; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; @@ -12,16 +16,38 @@ namespace Volo.CmsKit.MongoDB.Blogs { } - public Task GetByUrlSlugAsync(string urlSlug) + public Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) { - return GetAsync(x => x.UrlSlug.ToLower() == urlSlug); + return GetAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug, cancellationToken: cancellationToken); } - public async Task SlugExistsAsync(string slug) + public async Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) + { + var dbContext = await GetDbContextAsync(cancellationToken); + var blogPostQueryable = await GetQueryableAsync(); + + var queryable = blogPostQueryable + .Where(x => x.BlogId == blogId) + //.Join(dbContext.CmsUsers, outerKeySelector: x => x.CreatorId, innerKeySelector: x => x.Id, resultSelector: s => s) + ; + + if (!sorting.IsNullOrWhiteSpace()) + { + queryable = queryable.OrderBy(sorting); + } + + queryable = queryable + .Skip(skipCount) + .Take(maxResultCount); + + return await AsyncExecuter.ToListAsync(queryable, cancellationToken); + } + + public async Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default) { var queryable = await GetQueryableAsync(); - return await AsyncExecuter.AnyAsync(queryable, x => x.UrlSlug.ToLower() == slug); + return await AsyncExecuter.AnyAsync(queryable, x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index 195c29f1f7..998edf6e67 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Blogs; @@ -10,5 +11,10 @@ namespace Volo.CmsKit.MongoDB.Blogs public MongoBlogRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } + + public Task GetByUrlSlugAsync(string urlSlug) + { + return GetAsync(x => x.UrlSlug == urlSlug); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs new file mode 100644 index 0000000000..94d3f3fdbc --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs @@ -0,0 +1,17 @@ +using System; +using Volo.Abp.Application.Dtos; +using Volo.CmsKit.Users; + +namespace Volo.CmsKit.Public.Blogs +{ + public class BlogPostPublicDto : AuditedEntityWithUserDto + { + public Guid BlogId { get; set; } + + public string Title { get; set; } + + public string UrlSlug { get; set; } + + public string ShortDescription { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs new file mode 100644 index 0000000000..de460f0764 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs @@ -0,0 +1,13 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Public.Blogs +{ + public interface IBlogPostPublicAppService + { + Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); + + Task GetAsync(string blogUrlSlug, string blogPostUrlSlug); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs new file mode 100644 index 0000000000..907e7e7518 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Public.Blogs +{ + public class BlogPostPublicAppService : CmsKitPublicAppServiceBase, IBlogPostPublicAppService + { + protected IBlogRepository BlogRepository { get; } + + protected IBlogPostRepository BlogPostRepository { get; } + + public BlogPostPublicAppService( + IBlogRepository blogRepository, + IBlogPostRepository blogPostRepository) + { + BlogRepository = blogRepository; + BlogPostRepository = blogPostRepository; + } + + public async Task GetAsync(string blogUrlSlug, string blogPostUrlSlug) + { + var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + + var blogPost = await BlogPostRepository.GetByUrlSlugAsync(blog.Id, blogPostUrlSlug); + + return ObjectMapper.Map(blogPost); + } + + public async Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) + { + var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + + var blogPosts = await BlogPostRepository.GetPagedListAsync(blog.Id, input.SkipCount, input.MaxResultCount, input.Sorting); + + return ObjectMapper.Map, List>(blogPosts); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs index a45eaff0b2..46dab5a9a1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/PublicApplicationAutoMapperProfile.cs @@ -1,8 +1,10 @@ using AutoMapper; using Volo.Abp.AutoMapper; +using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; +using Volo.CmsKit.Public.Blogs; using Volo.CmsKit.Public.Comments; using Volo.CmsKit.Public.Contents; using Volo.CmsKit.Public.Pages; @@ -16,7 +18,7 @@ namespace Volo.CmsKit.Public { public PublicApplicationAutoMapperProfile() { - CreateMap(); + CreateMap(); CreateMap() .Ignore(x=> x.Author); @@ -30,6 +32,8 @@ namespace Volo.CmsKit.Public CreateMap(); CreateMap(); + + CreateMap(MemberList.None); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs index 07897d0d5b..71bb043ce8 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs @@ -93,22 +93,32 @@ namespace Volo.CmsKit.Blogs [Fact] public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingUrlSlug() { - var blogPost = await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogPost_1_UrlSlug); + var blogPost = await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogUrlSlug, cmsKitTestData.BlogPost_1_UrlSlug); blogPost.Id.ShouldBe(cmsKitTestData.BlogPost_1_Id); blogPost.Title.ShouldBe(cmsKitTestData.BlogPost_1_Title); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingUrlSlug() + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogPostUrlSlug() { var nonExistingUrlSlug = "any-other-url"; var exception = await Should.ThrowAsync(async () => - await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.Page_1_Url)); + await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogUrlSlug, nonExistingUrlSlug)); exception.EntityType.ShouldBe(typeof(BlogPost)); } + [Fact] + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogUrlSlug() + { + var nonExistingUrlSlug = "any-other-url"; + var exception = await Should.ThrowAsync(async () => + await blogPostAdminAppService.GetByUrlSlugAsync(nonExistingUrlSlug, cmsKitTestData.Page_1_Url)); + + exception.EntityType.ShouldBe(typeof(Blog)); + } + [Fact] public async Task GetListAsync_ShouldWorkProperly_WithDefaultParameters() { diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogPostRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogPostRepository_Test.cs new file mode 100644 index 0000000000..d393ef943e --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogPostRepository_Test.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Blogs; +using Volo.CmsKit.Pages; + +namespace Volo.CmsKit.EntityFrameworkCore.Blogs +{ + public class BlogPostRepository_Test : BlogPostRepository_Test + { + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogRepository_Test.cs new file mode 100644 index 0000000000..40b74d4064 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Blogs/BlogRepository_Test.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.EntityFrameworkCore.Blogs +{ + public class BlogRepository_Test : BlogRepository_Test + { + + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogPostRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogPostRepository_Test.cs new file mode 100644 index 0000000000..4bdec74132 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogPostRepository_Test.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Blogs; +using Xunit; + +namespace Volo.CmsKit.MongoDB.Blogs +{ + [Collection(MongoTestCollection.Name)] + public class BlogPostRepository_Test : BlogPostRepository_Test + { + + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogRepository_Test.cs new file mode 100644 index 0000000000..9cac7b473c --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Blogs/BlogRepository_Test.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Blogs; +using Xunit; + +namespace Volo.CmsKit.MongoDB.Blogs +{ + [Collection(MongoTestCollection.Name)] + public class BlogRepository_Test : BlogRepository_Test + { + + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs new file mode 100644 index 0000000000..efd07101cb --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs @@ -0,0 +1,125 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.CmsKit.Blogs +{ + public abstract class BlogPostRepository_Test : CmsKitTestBase + where TStartupModule : IAbpModule + { + private readonly CmsKitTestData testData; + private readonly IBlogPostRepository blogPostRepository; + + public BlogPostRepository_Test() + { + testData = GetRequiredService(); + blogPostRepository = GetRequiredService(); + } + + [Fact] + public async Task SlugExistsAsync_ShouldReturnTrue_WithExistingUrlSlug() + { + var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); + + result.ShouldBeTrue(); + } + + [Fact] + public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingUrlSlug() + { + var nonExistingSlug = "any-other-url-slug"; + + var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, nonExistingSlug); + + result.ShouldBeFalse(); + } + + [Fact] + public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingBlogId() + { + var nonExistingBlogId = Guid.NewGuid(); + + var result = await blogPostRepository.SlugExistsAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug); + + result.ShouldBeFalse(); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithCorrectParameters() + { + var blogPost = await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); + + blogPost.ShouldNotBeNull(); + blogPost.Id.ShouldBe(testData.BlogPost_1_Id); + blogPost.UrlSlug.ShouldBe(testData.BlogPost_1_UrlSlug); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogPostUrlSlug() + { + var nonExistingSlugUrl = "absolutely-non-existing-url"; + var exception = await Should.ThrowAsync( + async () => await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, nonExistingSlugUrl)); + + exception.ShouldNotBeNull(); + exception.EntityType.ShouldBe(typeof(BlogPost)); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogId() + { + var nonExistingBlogId = Guid.NewGuid(); + var exception = await Should.ThrowAsync( + async () => await blogPostRepository.GetByUrlSlugAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug)); + + exception.ShouldNotBeNull(); + exception.EntityType.ShouldBe(typeof(BlogPost)); + } + + [Fact] + public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting10_WithoutSorting() + { + var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, 0, 10, default); + + result.ShouldNotBeNull(); + result.ShouldNotBeEmpty(); + result.Count.ShouldBe(2); + } + + [Fact] + public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting1_WithoutSorting() + { + var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, default, 1, default); + + result.ShouldNotBeNull(); + result.ShouldNotBeEmpty(); + result.Count.ShouldBe(1); + } + + [Fact] + public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting1InPage2_WithoutSorting() + { + var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, 1, 1, default); + + result.ShouldNotBeNull(); + result.ShouldNotBeEmpty(); + result.Count.ShouldBe(1); + } + + [Fact] + public async Task GetPagedListAsync_ShouldWorkProperly_WithBlogId_WhileGetting10_WithSortingByTitle() + { + var result = await blogPostRepository.GetPagedListAsync(testData.Blog_Id, default, 10, nameof(BlogPost.Title)); + + result.ShouldNotBeNull(); + result.ShouldNotBeEmpty(); + result.Count.ShouldBe(2); + } + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs new file mode 100644 index 0000000000..1f425ff7f7 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs @@ -0,0 +1,47 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.CmsKit.Blogs +{ + public abstract class BlogRepository_Test : CmsKitTestBase + where TStartupModule : IAbpModule + { + private readonly CmsKitTestData testData; + private readonly IBlogRepository blogRepository; + + public BlogRepository_Test() + { + this.testData = GetRequiredService(); + this.blogRepository = GetRequiredService(); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingSlug() + { + var blog = await blogRepository.GetByUrlSlugAsync(testData.BlogUrlSlug); + + blog.ShouldNotBeNull(); + blog.UrlSlug.ShouldBe(testData.BlogUrlSlug); + blog.Id.ShouldBe(testData.Blog_Id); + } + + [Fact] + public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingSlug() + { + var nonExistingSlug = "some-blog-slug-that-doesnt-exist"; + + var exception = await Should.ThrowAsync( + async () => await blogRepository.GetByUrlSlugAsync(nonExistingSlug)); + + exception.ShouldNotBeNull(); + exception.EntityType.ShouldBe(typeof(Blog)); + } + } +} From ca9c92b895c76b16910b4699d3e07fcdce6435e4 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 14:29:40 +0300 Subject: [PATCH 36/70] CmsKit - Public Pages of BlogPosts --- .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 2 + .../CmsKit/Localization/Resources/en.json | 14 ++--- .../CmsKit/Localization/Resources/tr.json | 6 ++- .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 + .../CmsKit/Blogs/EfCoreBlogPostRepository.cs | 20 +++++-- .../MongoDB/Blogs/MongoBlogPostRepository.cs | 25 ++++++--- .../Public/Blogs/IBlogPostPublicAppService.cs | 2 +- .../Public/Blogs/BlogPostPublicAppService.cs | 6 ++- .../CmsKitPublicWebModule.cs | 8 +-- .../Pages/CmsKit/Blogs/BlogPost.cshtml | 53 +++++++++++++++++++ .../Pages/CmsKit/Blogs/BlogPost.cshtml.cs | 33 ++++++++++++ .../Pages/CmsKit/Blogs/Index.cshtml | 46 ++++++++++++++++ .../Pages/CmsKit/Blogs/Index.cshtml.cs | 45 ++++++++++++++++ .../Components/Blogs/BlogPost/Default.cshtml | 31 +++++++++++ .../BlogPost/DefaultBlogPostViewComponent.cs | 29 ++++++++++ .../Blogs/BlogPostComment/Default.cshtml | 22 ++++++++ .../DefaultBlogPostCommentViewComponent.cs | 39 ++++++++++++++ .../Pages/CmsKitPublicPageBase.cs | 26 +++++++++ 18 files changed, 385 insertions(+), 24 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/DefaultBlogPostCommentViewComponent.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPublicPageBase.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 607effcebd..28ca2d9141 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -9,5 +9,7 @@ public static int MinUrlSlugLength { get; set; } = 2; public static int MaxShortDescriptionLength { get; set; } = 256; + + public const string EntityType = "BlogPost"; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 00eccab1be..f59a5c981b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -3,10 +3,13 @@ "texts": { "CmsKit:0002": "Content already exists!", "CmsKit:0003": "The entity {0} is not taggable.", + "CmsKit:Page:0001": "The given url ({0}) already exists.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "Comments": "Comments", "Delete": "Delete", "Edit": "Edit", + "Read": "Read", + "LastModification": "Last Modification", "LoginToAddComment": "Login to add comment", "LoginToRate": "Login to rate", "LoginToReply": "Login to reply", @@ -17,14 +20,14 @@ "Permission:Contents.Create": "Create Content", "Permission:Contents.Delete": "Delete Content", "Permission:Contents.Update": "Update Content", - "Permission:TagManagement": "Tag Management", - "Permission:TagManagement.Create": "Create", - "Permission:TagManagement.Delete": "Delete", - "Permission:TagManagement.Update": "Update", "Permission:PageManagement": "Page Management", "Permission:PageManagement:Create": "Create", "Permission:PageManagement:Delete": "Delete", "Permission:PageManagement:Update": "Update", + "Permission:TagManagement": "Tag Management", + "Permission:TagManagement.Create": "Create", + "Permission:TagManagement.Delete": "Delete", + "Permission:TagManagement.Update": "Update", "PickYourReaction": "Pick your reaction", "RatingUndoMessage": "Your rating will be undo.", "Reply": "Reply", @@ -35,7 +38,6 @@ "Undo": "Undo", "Update": "Update", "YourComment": "Your comment", - "YourReply": "Your reply", - "CmsKit:Page:0001": "The given url ({0}) already exists." + "YourReply": "Your reply" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index 1ebb0c126b..77fe348ad6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -3,10 +3,13 @@ "texts": { "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", + "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır.", "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", "Comments": "Yorumlar", "Delete": "Sil", "Edit": "Düzenle", + "Read": "Oku", + "LastModification": "Son Güncellenme", "LoginToAddComment": "Yorum yapmak için giriş yap", "LoginToRate": "Oylamak için giriş yapın", "LoginToReply": "Cevap vermek için giriş yap", @@ -31,7 +34,6 @@ "Undo": "Geri al", "Update": "Güncelle", "YourComment": "Yorumunuz", - "YourReply": "Cevabınız", - "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır." + "YourReply": "Cevabınız" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index fdb721d8d8..c3cf64b44c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -15,5 +15,7 @@ namespace Volo.CmsKit.Blogs Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default); Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default); + + Task GetCountAsync(Guid blogId, CancellationToken cancellationToken = default); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs index 1a6546d5fc..df2893dd1e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs @@ -10,6 +10,7 @@ using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore; using System.Linq; using System.Data.Common; +using Volo.Abp.Domain.Entities; namespace Volo.CmsKit.Blogs { @@ -19,14 +20,27 @@ namespace Volo.CmsKit.Blogs { } - public Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) + public async Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) { - return GetAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug, cancellationToken: cancellationToken); + var dbSet = await GetDbSetAsync(); + + return await dbSet + .Include(i=> i.Creator) + .Where(x => + x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug) + .FirstOrDefaultAsync(cancellationToken: cancellationToken) + ?? throw new EntityNotFoundException(typeof(BlogPost)); } - public async Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) + public async Task GetCountAsync(Guid blogId, CancellationToken cancellationToken = default) { + return await (await GetQueryableAsync()).CountAsync( + x => x.BlogId == blogId, + cancellationToken); + } + public async Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) + { var queryable = (await GetQueryableAsync()) .Include(i => i.Creator) .Where(x => x.BlogId == blogId); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 638c219bb6..bcd6e33211 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -1,4 +1,6 @@ -using System; +using MongoDB.Driver; +using Nito.AsyncEx; +using System; using System.Collections.Generic; using System.Linq; using System.Linq.Dynamic.Core; @@ -7,6 +9,7 @@ using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Users; namespace Volo.CmsKit.MongoDB.Blogs { @@ -18,18 +21,28 @@ namespace Volo.CmsKit.MongoDB.Blogs public Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) { - return GetAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug, cancellationToken: cancellationToken); + return GetAsync(x => + x.BlogId == blogId && + x.UrlSlug.ToLower() == urlSlug, + includeDetails: true, + cancellationToken: cancellationToken); + } + + public async Task GetCountAsync(Guid blogId, CancellationToken cancellationToken = default) + { + return await AsyncExecuter.CountAsync( + await WithDetailsAsync(), + x => x.BlogId == blogId, + cancellationToken); } public async Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default) { var dbContext = await GetDbContextAsync(cancellationToken); - var blogPostQueryable = await GetQueryableAsync(); + var blogPostQueryable = await WithDetailsAsync(); var queryable = blogPostQueryable - .Where(x => x.BlogId == blogId) - //.Join(dbContext.CmsUsers, outerKeySelector: x => x.CreatorId, innerKeySelector: x => x.Id, resultSelector: s => s) - ; + .Where(x => x.BlogId == blogId); if (!sorting.IsNullOrWhiteSpace()) { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs index de460f0764..6771ae6adf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs @@ -6,7 +6,7 @@ namespace Volo.CmsKit.Public.Blogs { public interface IBlogPostPublicAppService { - Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); + Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); Task GetAsync(string blogUrlSlug, string blogPostUrlSlug); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index 907e7e7518..d9bb9ab281 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -29,13 +29,15 @@ namespace Volo.CmsKit.Public.Blogs return ObjectMapper.Map(blogPost); } - public async Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) + public async Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) { var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); var blogPosts = await BlogPostRepository.GetPagedListAsync(blog.Id, input.SkipCount, input.MaxResultCount, input.Sorting); - return ObjectMapper.Map, List>(blogPosts); + return new PagedResultDto( + await BlogPostRepository.GetCountAsync(blog.Id), + ObjectMapper.Map, List>(blogPosts)); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs index 953102aa79..d49ef63a85 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs @@ -61,10 +61,10 @@ namespace Volo.CmsKit.Public.Web { Configure(options => { - if (GlobalFeatureManager.Instance.IsEnabled()) - { - options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"{*pageUrl:minlength(1)}"); - } + //if (GlobalFeatureManager.Instance.IsEnabled()) + //{ + // options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"{*pageUrl:minlength(1)}"); + //} }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml new file mode 100644 index 0000000000..cf047d525c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml @@ -0,0 +1,53 @@ +@page "/b/{blogUrlSlug}/{blogPostUrlSlug}" + +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs +@using Volo.CmsKit.Public.Web.Pages +@using Volo.Abp.GlobalFeatures +@using Volo.CmsKit.GlobalFeatures +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating + +@inherits CmsKitPublicPageBase + +@model BlogPostModel + +@{ + PageLayout.Content.Title = Model.BlogPost.Title; +} + +@await Component.InvokeAsync(typeof(DefaultBlogPostViewComponent), new +{ + Model.BlogUrlSlug, + Model.BlogPostUrlSlug +}) + +@if (GlobalFeatureManager.Instance.IsEnabled()) +{ + @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) +} + +@if (GlobalFeatureManager.Instance.IsEnabled()) +{ + @await Component.InvokeAsync(typeof(RatingViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) +} + +
+ +@if (GlobalFeatureManager.Instance.IsEnabled()) +{ + @await Component.InvokeAsync(typeof(DefaultBlogPostCommentViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) +} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs new file mode 100644 index 0000000000..4a63ec1692 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Public.Blogs; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs +{ + public class BlogPostModel : CmsKitPublicPageModelBase + { + [BindProperty(SupportsGet = true)] + public string BlogUrlSlug { get; set; } + + [BindProperty(SupportsGet = true)] + public string BlogPostUrlSlug { get; set; } + + public BlogPostPublicDto BlogPost { get; private set; } + + protected IBlogPostPublicAppService BlogPostPublicAppService { get; } + + public BlogPostModel(IBlogPostPublicAppService blogPostPublicAppService) + { + BlogPostPublicAppService = blogPostPublicAppService; + } + + public async Task OnGetAsync() + { + BlogPost = await BlogPostPublicAppService.GetAsync(BlogUrlSlug, BlogPostUrlSlug); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml new file mode 100644 index 0000000000..06a20650c7 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -0,0 +1,46 @@ +@page "/b/{blogUrlSlug}" + +@using Volo.CmsKit.Public.Web.Pages + +@inherits CmsKitPublicPageBase + +@model Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs.IndexModel + + + @foreach (var blog in Model.Blogs.Items) + { + + + + + @blog.Title + + + @@@blog.Creator?.UserName + + + + + @blog.ShortDescription + + + + + + + + + + @blog.CreationTime + + + + + + } + + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs new file mode 100644 index 0000000000..d375efef61 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs @@ -0,0 +1,45 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Application.Dtos; +using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Pagination; +using Volo.CmsKit.Public.Blogs; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs +{ + public class IndexModel : CmsKitPublicPageModelBase + { + public const int PageSize = 12; + + [BindProperty(SupportsGet = true)] + public string BlogUrlSlug { get; set; } + + [BindProperty(SupportsGet = true)] + public int CurrentPage { get; set; } = 1; + + public PagedResultDto Blogs { get; private set; } + + public PagerModel PagerModel => new PagerModel(Blogs.TotalCount, Blogs.Items.Count, CurrentPage, PageSize, Request.Path.ToString()); + + protected IBlogPostPublicAppService BlogPostPublicAppService { get; } + + public IndexModel(IBlogPostPublicAppService blogPostPublicAppService) + { + BlogPostPublicAppService = blogPostPublicAppService; + } + + public async Task OnGetAsync() + { + Blogs = await BlogPostPublicAppService.GetListAsync( + BlogUrlSlug, + new PagedAndSortedResultRequestDto + { + SkipCount = PageSize * (CurrentPage - 1), + MaxResultCount = PageSize + }); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml new file mode 100644 index 0000000000..df409d6dde --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -0,0 +1,31 @@ +@model Volo.CmsKit.Public.Blogs.BlogPostPublicDto +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Contents +@using Volo.Abp.AspNetCore.Mvc.UI.Layout +@using Volo.CmsKit.Localization +@using Microsoft.Extensions.Localization + +@inject IStringLocalizer L + + + + + @Model.Title + @@@Model.Creator?.UserName + + + @await Component.InvokeAsync(typeof(ContentViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.Id.ToString() + }) + + + @Model.CreationTime + @if (Model.LastModificationTime != null) + { + @L["LastModification"].Value : @Model.LastModificationTime + } + + + + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs new file mode 100644 index 0000000000..4a055d6679 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs @@ -0,0 +1,29 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; +using Volo.CmsKit.Public.Blogs; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost +{ + [ViewComponent(Name = "CmsDefaultBlogPost")] + public class DefaultBlogPostViewComponent : AbpViewComponent + { + protected IBlogPostPublicAppService BlogPostPublicAppService { get; } + + public DefaultBlogPostViewComponent(IBlogPostPublicAppService blogPostPublicAppService) + { + BlogPostPublicAppService = blogPostPublicAppService; + } + + public virtual async Task InvokeAsync(string blogUrlSlug, string blogPostUrlSlug) + { + var blogPost = await BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); + + return View("~/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml", blogPost); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml new file mode 100644 index 0000000000..c34f64eb0c --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml @@ -0,0 +1,22 @@ +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Commenting +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment +@using Volo.CmsKit.Localization +@using Microsoft.Extensions.Localization + +@inject IStringLocalizer L + +@model DefaultBlogPostCommentViewComponent.DefaultBlogPostCommentViewModel + + + + + @L["Comments"] + + + @await Component.InvokeAsync(typeof(CommentingViewComponent), new + { + entityType = Model.EntityType, + entityId = Model.EntityId + }) + + \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/DefaultBlogPostCommentViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/DefaultBlogPostCommentViewComponent.cs new file mode 100644 index 0000000000..c551146f5f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/DefaultBlogPostCommentViewComponent.cs @@ -0,0 +1,39 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc; +using Volo.CmsKit.Public.Blogs; + +namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment +{ + [ViewComponent(Name = "CmsDefaultBlogPostComment")] + public class DefaultBlogPostCommentViewComponent : AbpViewComponent + { + protected IBlogPostPublicAppService BlogPostPublicAppService; + + public DefaultBlogPostCommentViewComponent(IBlogPostPublicAppService blogPostPublicAppService) + { + BlogPostPublicAppService = blogPostPublicAppService; + } + + public virtual async Task InvokeAsync(string entityType, string entityId) + { + return View( + "~/Pages/CmsKit/Shared/Components/Blogs/BlogPostComment/Default.cshtml", + new DefaultBlogPostCommentViewModel + { + EntityType = entityType, + EntityId = entityId + }); + } + + public class DefaultBlogPostCommentViewModel + { + public string EntityType { get; set; } + public string EntityId { get; set; } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPublicPageBase.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPublicPageBase.cs new file mode 100644 index 0000000000..879745bf24 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKitPublicPageBase.cs @@ -0,0 +1,26 @@ +using Microsoft.AspNetCore.Mvc.Razor.Internal; +using Microsoft.Extensions.Localization; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.AspNetCore.Mvc.UI.Layout; +using Volo.CmsKit.Localization; + +namespace Volo.CmsKit.Public.Web.Pages +{ + public class CmsKitPublicPageBase : Microsoft.AspNetCore.Mvc.RazorPages.Page + { + [RazorInject] + public IStringLocalizer L { get; set; } + + [RazorInject] + public IPageLayout PageLayout { get; set; } + + public override Task ExecuteAsync() + { + return Task.CompletedTask; // Will be overriden by razor pages. (.cshtml) + } + } +} From f228768ee804f9e7531b287ede1ffa48506c7375 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:01:42 +0300 Subject: [PATCH 37/70] CmsKit - Add Existence check for blog --- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 4 +++- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 1 + .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 9 ++++++++- .../MongoDB/Blogs/MongoBlogRepository.cs | 10 +++++++++- .../Blogs/BlogRepository_Test.cs | 18 ++++++++++++++++++ 5 files changed, 39 insertions(+), 3 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 61198e0fad..228d8eccbf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Services; namespace Volo.CmsKit.Blogs @@ -48,7 +49,8 @@ namespace Volo.CmsKit.Blogs private async Task CheckBlogExistenceAsync(Guid blogId) { - await blogRepository.GetAsync(blogId); + if (!await blogRepository.ExistsAsync(blogId)) + throw new EntityNotFoundException(typeof(Blog), blogId); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index 152c17d615..bbff825189 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -7,5 +7,6 @@ namespace Volo.CmsKit.Blogs public interface IBlogRepository : IBasicRepository { public Task GetByUrlSlugAsync(string urlSlug); + Task ExistsAsync(Guid blogId); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs index 76211780f6..677857d2b6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -1,4 +1,6 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; +using System.Security.Cryptography.X509Certificates; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; @@ -12,6 +14,11 @@ namespace Volo.CmsKit.Blogs { } + public async Task ExistsAsync(Guid blogId) + { + return await (await GetQueryableAsync()).AnyAsync(x => x.Id == blogId); + } + public Task GetByUrlSlugAsync(string urlSlug) { return GetAsync(x => x.UrlSlug == urlSlug); diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index 998edf6e67..b1d9d3167b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -1,4 +1,5 @@ -using System; +using MongoDB.Driver.Core.Operations; +using System; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; @@ -12,6 +13,13 @@ namespace Volo.CmsKit.MongoDB.Blogs { } + public async Task ExistsAsync(Guid blogId) + { + return await AsyncExecuter.AnyAsync( + await GetQueryableAsync(), + x => x.Id == blogId); + } + public Task GetByUrlSlugAsync(string urlSlug) { return GetAsync(x => x.UrlSlug == urlSlug); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs index 1f425ff7f7..5119dfd75b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs @@ -43,5 +43,23 @@ namespace Volo.CmsKit.Blogs exception.ShouldNotBeNull(); exception.EntityType.ShouldBe(typeof(Blog)); } + + [Fact] + public async Task ExistsAsync_ShouldReturnTrue_WithExistingId() + { + var result = await blogRepository.ExistsAsync(testData.Blog_Id); + + result.ShouldBeTrue(); + } + + [Fact] + public async Task ExistsAsync_ShouldReturnFalse_WithExistingId() + { + var nonExistingId = Guid.NewGuid(); + + var result = await blogRepository.ExistsAsync(nonExistingId); + + result.ShouldBeFalse(); + } } } From 07ec565b48adffed6f2cb5c7ba70717507d5b39c Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:12:04 +0300 Subject: [PATCH 38/70] CmsKit - Uncomment Pages Page initialization --- .../src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs index d49ef63a85..953102aa79 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs @@ -61,10 +61,10 @@ namespace Volo.CmsKit.Public.Web { Configure(options => { - //if (GlobalFeatureManager.Instance.IsEnabled()) - //{ - // options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"{*pageUrl:minlength(1)}"); - //} + if (GlobalFeatureManager.Instance.IsEnabled()) + { + options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"{*pageUrl:minlength(1)}"); + } }); } } From c330356f661992c1e5203abe404bb45b5fe202e5 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:01:42 +0300 Subject: [PATCH 39/70] CmsKit - Add Existence check for blog --- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 4 +++- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 1 + .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 9 ++++++++- .../Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs | 10 +++++++++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 6bbb772072..a419802b8e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Services; namespace Volo.CmsKit.Blogs @@ -48,7 +49,8 @@ namespace Volo.CmsKit.Blogs private async Task CheckBlogExistenceAsync(Guid blogId) { - await blogRepository.GetAsync(blogId); + if (!await blogRepository.ExistsAsync(blogId)) + throw new EntityNotFoundException(typeof(Blog), blogId); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index 90e59587a2..d6b2dc58b1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -5,5 +5,6 @@ namespace Volo.CmsKit.Blogs { public interface IBlogRepository : IBasicRepository { + Task ExistsAsync(Guid blogId); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs index a43504642c..0db324ebcf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -1,4 +1,6 @@ -using System; +using Microsoft.EntityFrameworkCore; +using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore; using Volo.CmsKit.EntityFrameworkCore; @@ -10,5 +12,10 @@ namespace Volo.CmsKit.Blogs public EfCoreBlogRepository(IDbContextProvider dbContextProvider) : base(dbContextProvider) { } + + public async Task ExistsAsync(Guid blogId) + { + return await (await GetQueryableAsync()).AnyAsync(x => x.Id == blogId); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index 195c29f1f7..e63f816bef 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -1,4 +1,5 @@ -using System; +using MongoDB.Driver.Core.Operations; +using System; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Blogs; @@ -10,5 +11,12 @@ namespace Volo.CmsKit.MongoDB.Blogs public MongoBlogRepository(IMongoDbContextProvider dbContextProvider) : base(dbContextProvider) { } + + public async Task ExistsAsync(Guid blogId) + { + return await AsyncExecuter.AnyAsync( + await GetQueryableAsync(), + x => x.Id == blogId); + } } } From ebe0a85a0047d9f12bc719cf894c1b4ba7853131 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:19:16 +0300 Subject: [PATCH 40/70] CmsKit - Remove unnecessary CmsKitBlogOptions --- .../Volo/CmsKit/Blogs/CmsKitBlogOptions.cs | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs deleted file mode 100644 index bc3dd30435..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/CmsKitBlogOptions.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; - -namespace Volo.CmsKit.Blogs -{ - public class CmsKitBlogOptions - { - private string routePrefix = "blog"; - - /// - /// Gets or sets route prefix. Default value is 'blog'. - /// - /// - /// This parameter will be used while presenting blogposts. - /// - public string RoutePrefix - { - get => GetFormattedRoutePrefix(); - set => routePrefix = value; - } - - private string GetFormattedRoutePrefix() - { - if (string.IsNullOrWhiteSpace(routePrefix)) - { - return "/"; - } - - return routePrefix.EnsureEndsWith('/').EnsureStartsWith('/'); - } - } -} From 0efd22e552d132f1bd0d57c6c6bcff4b330905d6 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:20:11 +0300 Subject: [PATCH 41/70] CmsKit - Convert mapping to AutoMapper for BlogLookupDto --- .../Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs | 8 +------- .../Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs | 5 +---- .../Admin/CmsKitAdminApplicationAutoMapperProfile.cs | 2 ++ 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs index 74e63b9150..ed514d839d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogLookupDto.cs @@ -1,15 +1,9 @@ using System; -namespace Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs +namespace Volo.CmsKit.Admin.Blogs { public class BlogLookupDto { - public BlogLookupDto(Guid id, string name) - { - Id = id; - Name = name; - } - public Guid Id { get; set; } public string Name { get; set; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index 5c8ae8e26c..0703bc94a4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -6,7 +6,6 @@ using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.Abp.Domain.Repositories; using Volo.Abp.GlobalFeatures; -using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; @@ -31,9 +30,7 @@ namespace Volo.CmsKit.Admin.Blogs { var blogs = await Repository.GetListAsync(); - return blogs - .Select(s => new BlogLookupDto(s.Id, s.Name)) - .ToList(); + return ObjectMapper.Map, List>(blogs); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs index 46afe04213..8fc2567093 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationAutoMapperProfile.cs @@ -27,6 +27,8 @@ namespace Volo.CmsKit.Admin CreateMap(MemberList.Destination) .ReverseMap(); + CreateMap(MemberList.Destination); + CreateMap(MemberList.Destination); } } From 29cd7ed4ccef4a410347b342e63f431160891d9d Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:20:35 +0300 Subject: [PATCH 42/70] CmsKit - Namespace fix --- .../Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs | 1 - .../src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs index 9f4d16c7f6..b6000be499 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Services; -using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; namespace Volo.CmsKit.Admin.Blogs { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index d6b2dc58b1..0061e1a397 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -1,4 +1,5 @@ using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories; namespace Volo.CmsKit.Blogs From 12ed6ae59152c40ad0f1af82240aaea2aa6a4ca3 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:26:59 +0300 Subject: [PATCH 43/70] CmsKit - Using fix at MongoBlogRepository --- .../Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index e63f816bef..23e0fe1436 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -1,5 +1,6 @@ using MongoDB.Driver.Core.Operations; using System; +using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; using Volo.Abp.MongoDB; using Volo.CmsKit.Blogs; From 094512ade0dd702a9af21220322dd68404fc45c6 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:27:36 +0300 Subject: [PATCH 44/70] CmsKit - Namespace fix at BlogAdminController --- .../Volo/CmsKit/Admin/Blogs/BlogAdminController.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs index b12b4f83b1..e6c4370df9 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs @@ -8,7 +8,6 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.GlobalFeatures; -using Volo.CmsKit.Admin.Application.Contracts.Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; From 42cf0238ba98f37ad89c866d69d9b2c712d9afa6 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 3 Feb 2021 16:51:17 +0300 Subject: [PATCH 45/70] CmsKit - Add missing error resources --- .../Volo/CmsKit/Localization/Resources/en.json | 13 +++++++------ .../Volo/CmsKit/Localization/Resources/tr.json | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index 00eccab1be..118344b626 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -3,6 +3,8 @@ "texts": { "CmsKit:0002": "Content already exists!", "CmsKit:0003": "The entity {0} is not taggable.", + "CmsKit:BlogPost:0001": "Same url slug already exists!", + "CmsKit:Page:0001": "The given url ({0}) already exists.", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "Comments": "Comments", "Delete": "Delete", @@ -17,14 +19,14 @@ "Permission:Contents.Create": "Create Content", "Permission:Contents.Delete": "Delete Content", "Permission:Contents.Update": "Update Content", - "Permission:TagManagement": "Tag Management", - "Permission:TagManagement.Create": "Create", - "Permission:TagManagement.Delete": "Delete", - "Permission:TagManagement.Update": "Update", "Permission:PageManagement": "Page Management", "Permission:PageManagement:Create": "Create", "Permission:PageManagement:Delete": "Delete", "Permission:PageManagement:Update": "Update", + "Permission:TagManagement": "Tag Management", + "Permission:TagManagement.Create": "Create", + "Permission:TagManagement.Delete": "Delete", + "Permission:TagManagement.Update": "Update", "PickYourReaction": "Pick your reaction", "RatingUndoMessage": "Your rating will be undo.", "Reply": "Reply", @@ -35,7 +37,6 @@ "Undo": "Undo", "Update": "Update", "YourComment": "Your comment", - "YourReply": "Your reply", - "CmsKit:Page:0001": "The given url ({0}) already exists." + "YourReply": "Your reply" } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index 1ebb0c126b..13d7bc7e37 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -3,6 +3,8 @@ "texts": { "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", + "CmsKit:BlogPost:0001": "Aynı url etiketi zaten mevcut.", + "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır.", "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", "Comments": "Yorumlar", "Delete": "Sil", @@ -31,7 +33,6 @@ "Undo": "Geri al", "Update": "Güncelle", "YourComment": "Yorumunuz", - "YourReply": "Cevabınız", - "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır." + "YourReply": "Cevabınız" } } From 25d5df54864936c8aa496cf32e80b41beb5357ba Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 10:03:22 +0300 Subject: [PATCH 46/70] CmsKit - Add TagComponent to BlogPost page --- .../Pages/CmsKit/Blogs/BlogPost.cshtml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml index cf047d525c..12aa1d4f05 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml @@ -8,6 +8,7 @@ @using Volo.CmsKit.GlobalFeatures @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.ReactionSelection @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Rating +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Tags @inherits CmsKitPublicPageBase @@ -23,6 +24,15 @@ Model.BlogPostUrlSlug }) +@if (GlobalFeatureManager.Instance.IsEnabled()) +{ + @await Component.InvokeAsync(typeof(TagViewComponent), new + { + entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, + entityId = Model.BlogPost.Id.ToString() + }) +} + @if (GlobalFeatureManager.Instance.IsEnabled()) { @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new From a5bf8ebe9ebbdab0ece73936408a3298fab2c957 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 11:24:41 +0300 Subject: [PATCH 47/70] CmsKit - Alternative way to handle pages --- .../CmsKitPublicWebModule.cs | 4 --- .../Controllers/PageController.cs | 34 +++++++++++++++++++ .../Pages/CmsKit/Pages/Index.cshtml | 13 ------- .../Pages/CmsKit/Pages/Index.cshtml.cs | 34 ------------------- .../Views/Page/Index.cshtml | 9 +++++ 5 files changed, 43 insertions(+), 51 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Views/Page/Index.cshtml diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs index 953102aa79..b5c7b9bb3f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/CmsKitPublicWebModule.cs @@ -61,10 +61,6 @@ namespace Volo.CmsKit.Public.Web { Configure(options => { - if (GlobalFeatureManager.Instance.IsEnabled()) - { - options.Conventions.AddPageRoute("/CmsKit/Pages/Index", @"{*pageUrl:minlength(1)}"); - } }); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs new file mode 100644 index 0000000000..1eed5857f1 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.ActionConstraints; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Public.Pages; + +namespace Volo.CmsKit.Public.Web.Controllers +{ + public class PageController : CmsKitPublicControllerBase + { + protected IPageAppService PageAppService { get; } + + public PageController(IPageAppService pageAppService) + { + PageAppService = pageAppService; + } + + [HttpGet("/{*url}", Order = int.MaxValue)] + public async Task Index(string url) + { + var page = await PageAppService.FindByUrlAsync(url); + + if (page == null) + { + return NotFound(); + } + + return View("~/Views/Page/Index.cshtml", page); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml deleted file mode 100644 index 73c7637b01..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml +++ /dev/null @@ -1,13 +0,0 @@ -@page "{*pageUrl}" -@using Microsoft.AspNetCore.Mvc.Localization -@using Volo.CmsKit.Localization -@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages -@model Volo.CmsKit.Public.Web.Pages.CmsKit.Pages.IndexModel -@inject IHtmlLocalizer L - -@await Component.InvokeAsync(typeof(DefaultPageViewComponent), - new - { - pageId = Model.Page.Id, - title = Model.Page.Title - }) \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs deleted file mode 100644 index 5443608845..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Pages/Index.cshtml.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Volo.CmsKit.Public.Pages; -using Volo.CmsKit.Web.Pages; - -namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Pages -{ - public class IndexModel : CommonPageModel - { - [BindProperty(SupportsGet = true)] - public string PageUrl { get; set; } - - protected readonly IPageAppService PageAppService; - - public PageDto Page; - - public IndexModel(IPageAppService pageAppService) - { - PageAppService = pageAppService; - } - - public async Task OnGetAsync() - { - Page = await PageAppService.FindByUrlAsync(PageUrl); - - if (Page == null) - { - return NotFound(); - } - - return Page(); - } - } -} \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Views/Page/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Views/Page/Index.cshtml new file mode 100644 index 0000000000..de094041e4 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Views/Page/Index.cshtml @@ -0,0 +1,9 @@ +@model Volo.CmsKit.Public.Pages.PageDto + +@using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Pages + +@await Component.InvokeAsync(typeof(DefaultPageViewComponent), new +{ + pageId = Model.Id, + title = Model.Title +}) \ No newline at end of file From ef3204c8bc026aa318c95347815f0be81e3ffdae Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 11:31:38 +0300 Subject: [PATCH 48/70] CmsKit - Method name fix for PageController --- .../src/Volo.CmsKit.Public.Web/Controllers/PageController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs index 1eed5857f1..a2124cbaff 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs @@ -19,7 +19,7 @@ namespace Volo.CmsKit.Public.Web.Controllers } [HttpGet("/{*url}", Order = int.MaxValue)] - public async Task Index(string url) + public async Task IndexAsync(string url) { var page = await PageAppService.FindByUrlAsync(url); From 9c742d7eac6f9aceccce51888e426c3f6182e375 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 14:54:08 +0300 Subject: [PATCH 49/70] CmsKit - BlogPost Tagging --- .../Volo/CmsKit/Admin/Tags/EntityTagSetDto.cs | 15 +++++++ .../Admin/Tags/IEntityTagAdminAppService.cs | 2 + .../Admin/CmsKitAdminApplicationModule.cs | 30 +++++++++++++ .../Admin/Tags/EntityTagAdminAppService.cs | 39 ++++++++++++++--- .../Admin/Tags/EntityTagAdminController.cs | 42 +++++++++++++++++++ .../Volo/CmsKit}/Tags/ITagAppService.cs | 2 +- .../Volo/CmsKit}/Tags/TagAppService.cs | 2 +- .../CmsKit/Localization/Resources/en.json | 3 +- .../CmsKit/Localization/Resources/tr.json | 3 +- .../Volo/CmsKit/Tags/IEntityTagRepository.cs | 2 + .../CmsKit/Tags/EfCoreEntityTagRepository.cs | 10 +++++ .../MongoDB/Tags/MongoEntityTagRepository.cs | 9 ++++ .../Pages/CmsKit/Blogs/BlogPost.cshtml | 2 +- .../Pages/CmsKit/Blogs/Index.cshtml | 4 +- .../Properties/launchSettings.json | 27 ++++++++++++ .../Tags/TagPublicAppService_Tests.cs | 2 +- .../Tags/EntityTagRepository_Test.cs | 14 +++++++ .../MongoDB/Tags/EntityTagRepository_Test.cs | 16 +++++++ .../Tags/EntityTagRepository_Test.cs | 38 +++++++++++++++++ 19 files changed, 249 insertions(+), 13 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagSetDto.cs create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs rename modules/cms-kit/src/{Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public => Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit}/Tags/ITagAppService.cs (89%) rename modules/cms-kit/src/{Volo.CmsKit.Public.Application/Volo/CmsKit/Public => Volo.CmsKit.Common.Application/Volo/CmsKit}/Tags/TagAppService.cs (95%) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.Web/Properties/launchSettings.json create mode 100644 modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Tags/EntityTagRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Tags/EntityTagRepository_Test.cs create mode 100644 modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/EntityTagRepository_Test.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagSetDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagSetDto.cs new file mode 100644 index 0000000000..d80c1aa62a --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/EntityTagSetDto.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Admin.Tags +{ + public class EntityTagSetDto + { + public string EntityId { get; set; } + public string EntityType { get; set; } + public List Tags { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs index aece4d5c00..a6660a324f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Tags/IEntityTagAdminAppService.cs @@ -7,5 +7,7 @@ namespace Volo.CmsKit.Admin.Tags Task AddTagToEntityAsync(EntityTagCreateDto input); Task RemoveTagFromEntityAsync(EntityTagRemoveDto input); + + Task SetEntityTagsAsync(EntityTagSetDto input); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs index b34e918058..2ad96af963 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/CmsKitAdminApplicationModule.cs @@ -1,6 +1,14 @@ using Microsoft.Extensions.DependencyInjection; +using System.Collections.Generic; using Volo.Abp.AutoMapper; +using Volo.Abp.GlobalFeatures; +using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Localization; +using Volo.CmsKit.Permissions; +using Volo.CmsKit.Tags; namespace Volo.CmsKit.Admin { @@ -11,6 +19,11 @@ namespace Volo.CmsKit.Admin )] public class CmsKitAdminApplicationModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + ConfigureTagOptions(); + } + public override void ConfigureServices(ServiceConfigurationContext context) { context.Services.AddAutoMapperObjectMapper(); @@ -20,5 +33,22 @@ namespace Volo.CmsKit.Admin options.AddMaps(validate: true); }); } + + private void ConfigureTagOptions() + { + Configure(opts => + { + if (GlobalFeatureManager.Instance.IsEnabled()) + { + opts.EntityTypes.AddIfNotContains( + new TagEntityTypeDefiniton( + BlogPostConsts.EntityType, + LocalizableString.Create("BlogPost"), + CmsKitAdminPermissions.BlogPosts.Update, + CmsKitAdminPermissions.BlogPosts.Update, + CmsKitAdminPermissions.BlogPosts.Update)); + } + }); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs index 1ef6a8bdf9..b36ffedbd2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Tags/EntityTagAdminAppService.cs @@ -1,24 +1,32 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.CmsKit.Admin.Tags; using Volo.CmsKit.Tags; -namespace Volo.CmsKit.Admin.Application.Volo.CmsKit.Admin.Tags +namespace Volo.CmsKit.Admin.Tags { public class EntityTagAdminAppService : CmsKitAdminAppServiceBase, IEntityTagAdminAppService { - protected ITagDefinitionStore _tagDefinitionStore; - protected IEntityTagManager _entityTagManager; - protected ITagManager _tagManager; + protected readonly ITagDefinitionStore _tagDefinitionStore; + protected readonly IEntityTagManager _entityTagManager; + protected readonly ITagManager _tagManager; + protected readonly ITagRepository _tagRepository; + protected readonly IEntityTagRepository _entityTagRepository; public EntityTagAdminAppService( ITagDefinitionStore tagDefinitionStore, IEntityTagManager entityTagManager, - ITagManager tagManager) + ITagManager tagManager, + ITagRepository tagRepository, + IEntityTagRepository entityTagRepository) { _tagDefinitionStore = tagDefinitionStore; _entityTagManager = entityTagManager; _tagManager = tagManager; + _tagRepository = tagRepository; + _entityTagRepository = entityTagRepository; } public async Task AddTagToEntityAsync(EntityTagCreateDto input) @@ -48,5 +56,26 @@ namespace Volo.CmsKit.Admin.Application.Volo.CmsKit.Admin.Tags input.EntityId, CurrentTenant?.Id); } + + public async Task SetEntityTagsAsync(EntityTagSetDto input) + { + var definition = await _tagDefinitionStore.GetTagEntityTypeDefinitionsAsync(input.EntityType); + + await CheckPolicyAsync(definition.UpdatePolicy); + + var existingTags = await _tagRepository.GetAllRelatedTagsAsync(input.EntityType, input.EntityId, CurrentTenant?.Id); + + var deletedTags = existingTags.Where(x => !input.Tags.Contains(x.Name)).ToList(); + var addedTags = input.Tags.Where(x => !existingTags.Any(a => a.Name == x)); + + await _entityTagRepository.DeleteManyAsync(deletedTags.Select(s => s.Id).ToArray()); + + foreach (var addedTag in addedTags) + { + var tag = await _tagManager.GetOrAddAsync(input.EntityType, addedTag, CurrentTenant?.Id); + + await _entityTagManager.AddTagToEntityAsync(tag.Id, input.EntityType, input.EntityId, CurrentTenant?.Id); + } + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs new file mode 100644 index 0000000000..532fae8554 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Tags/EntityTagAdminController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; +using Volo.CmsKit.Permissions; + +namespace Volo.CmsKit.Admin.Tags +{ + [RequiresGlobalFeature(typeof(TagsFeature))] + [RemoteService(Name = CmsKitCommonRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Route("api/cms-kit-admin/entity-tags")] + public class EntityTagAdminController : CmsKitAdminController, IEntityTagAdminAppService + { + protected IEntityTagAdminAppService EntityTagAdminAppService { get; } + + public EntityTagAdminController(IEntityTagAdminAppService entityTagAdminAppService) + { + EntityTagAdminAppService = entityTagAdminAppService; + } + + [HttpPost] + public Task AddTagToEntityAsync(EntityTagCreateDto input) + { + return EntityTagAdminAppService.AddTagToEntityAsync(input); + } + + [HttpDelete] + public Task RemoveTagFromEntityAsync(EntityTagRemoveDto input) + { + return EntityTagAdminAppService.RemoveTagFromEntityAsync(input); + } + + [HttpPut] + public Task SetEntityTagsAsync(EntityTagSetDto input) + { + return EntityTagAdminAppService.SetEntityTagsAsync(input); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Tags/ITagAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs similarity index 89% rename from modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Tags/ITagAppService.cs rename to modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs index 34d54b9006..5ab01940e1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Tags/ITagAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application.Contracts/Volo/CmsKit/Tags/ITagAppService.cs @@ -3,7 +3,7 @@ using System.Threading.Tasks; using Volo.Abp.Application.Services; using Volo.CmsKit.Tags; -namespace Volo.CmsKit.Public.Tags +namespace Volo.CmsKit.Tags { public interface ITagAppService : IApplicationService { diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Tags/TagAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs similarity index 95% rename from modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Tags/TagAppService.cs rename to modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs index 593f011b02..caa6dc4181 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Tags/TagAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Common.Application/Volo/CmsKit/Tags/TagAppService.cs @@ -5,7 +5,7 @@ using System.Text; using System.Threading.Tasks; using Volo.CmsKit.Tags; -namespace Volo.CmsKit.Public.Tags +namespace Volo.CmsKit.Tags { public class TagAppService : CmsKitAppServiceBase, ITagAppService { diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json index f59a5c981b..f0cfbc3f63 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/en.json @@ -4,11 +4,11 @@ "CmsKit:0002": "Content already exists!", "CmsKit:0003": "The entity {0} is not taggable.", "CmsKit:Page:0001": "The given url ({0}) already exists.", + "CmsKit:Tag:0002": "The entity is not taggable!", "CommentAuthorizationExceptionMessage": "Those comments are not allowed for public display.", "Comments": "Comments", "Delete": "Delete", "Edit": "Edit", - "Read": "Read", "LastModification": "Last Modification", "LoginToAddComment": "Login to add comment", "LoginToRate": "Login to rate", @@ -30,6 +30,7 @@ "Permission:TagManagement.Update": "Update", "PickYourReaction": "Pick your reaction", "RatingUndoMessage": "Your rating will be undo.", + "Read": "Read", "Reply": "Reply", "Send": "Send", "Star": "Star", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json index 77fe348ad6..cbe3c89182 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/tr.json @@ -4,11 +4,11 @@ "CmsKit:0002": "İçerik zaten mevcut!", "CmsKit:0003": "{0} ögesi etiketlenebilir değil.", "CmsKit:Page:0001": "Girilen url ({0}) kullanımdadır.", + "CmsKit:Tag:0002": "Bu öge etiketlenebilir değil.", "CommentAuthorizationExceptionMessage": "Bu yorumları görebilmek için yetki gerekir.", "Comments": "Yorumlar", "Delete": "Sil", "Edit": "Düzenle", - "Read": "Oku", "LastModification": "Son Güncellenme", "LoginToAddComment": "Yorum yapmak için giriş yap", "LoginToRate": "Oylamak için giriş yapın", @@ -26,6 +26,7 @@ "Permission:TagManagement.Update": "Etiket Güncelleme", "PickYourReaction": "Tepkinizi seçin", "RatingUndoMessage": "Oylamanız geri alınacak.", + "Read": "Oku", "Reply": "Cevapla", "Send": "Gönder", "Star": "Yıldız", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs index f2ed160671..6ea4f009a2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Tags/IEntityTagRepository.cs @@ -13,5 +13,7 @@ namespace Volo.CmsKit.Tags [NotNull] string entityId, [CanBeNull] Guid? tenantId, CancellationToken cancellationToken = default); + + Task DeleteManyAsync(Guid[] tagIds, CancellationToken cancellationToken = default); } } \ No newline at end of file diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs index a82fb7005a..f1d0119885 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Tags/EfCoreEntityTagRepository.cs @@ -1,5 +1,8 @@ using JetBrains.Annotations; +using Nito.Disposables; using System; +using System.Linq; +using System.Linq.Dynamic.Core; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; @@ -14,6 +17,13 @@ namespace Volo.CmsKit.Tags { } + public async Task DeleteManyAsync(Guid[] tagIds, CancellationToken cancellationToken = default) + { + var dbSet = await GetDbSetAsync(); + + dbSet.RemoveRange(dbSet.Where(x => tagIds.Contains(x.TagId))); + } + public Task FindAsync( [NotNull] Guid tagId, [NotNull] string entityId, diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs index 3f9e1814fc..c073f8206f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Tags/MongoEntityTagRepository.cs @@ -1,5 +1,7 @@ using JetBrains.Annotations; +using MongoDB.Driver; using System; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories.MongoDB; @@ -14,6 +16,13 @@ namespace Volo.CmsKit.MongoDB.Tags { } + public async Task DeleteManyAsync(Guid[] tagIds, CancellationToken cancellationToken = default) + { + var collection = await GetCollectionAsync(); + + await collection.DeleteManyAsync(Builders.Filter.In(x => x.TagId, tagIds)); + } + public Task FindAsync( [NotNull] Guid tagId, [NotNull] string entityId, diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml index 12aa1d4f05..e03bf06991 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml @@ -1,4 +1,4 @@ -@page "/b/{blogUrlSlug}/{blogPostUrlSlug}" +@page "/blogs/{blogUrlSlug}/{blogPostUrlSlug}" @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml index 06a20650c7..bd683fbc85 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -1,4 +1,4 @@ -@page "/b/{blogUrlSlug}" +@page "/blogs/{blogUrlSlug}" @using Volo.CmsKit.Public.Web.Pages @@ -24,7 +24,7 @@ @blog.ShortDescription - + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Properties/launchSettings.json b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Properties/launchSettings.json new file mode 100644 index 0000000000..60e2c66615 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:60873/", + "sslPort": 44300 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "Volo.CmsKit.Public.Web": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "https://localhost:5001;http://localhost:5000" + } + } +} \ No newline at end of file diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Tags/TagPublicAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Tags/TagPublicAppService_Tests.cs index 50eefd186b..26a7454a2b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Tags/TagPublicAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Tags/TagPublicAppService_Tests.cs @@ -3,7 +3,7 @@ using NSubstitute; using Shouldly; using System.Threading.Tasks; using Volo.Abp.Users; -using Volo.CmsKit.Public.Tags; +using Volo.CmsKit.Tags; using Xunit; namespace Volo.CmsKit.Tags diff --git a/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Tags/EntityTagRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Tags/EntityTagRepository_Test.cs new file mode 100644 index 0000000000..01464f46e8 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.EntityFrameworkCore.Tests/EntityFrameworkCore/Tags/EntityTagRepository_Test.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Tags; + +namespace Volo.CmsKit.EntityFrameworkCore.Tags +{ + public class EntityTagRepository_Test : EntityTagRepository_Test + { + + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Tags/EntityTagRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Tags/EntityTagRepository_Test.cs new file mode 100644 index 0000000000..919455b109 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.MongoDB.Tests/MongoDB/Tags/EntityTagRepository_Test.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.CmsKit.Tags; +using Xunit; + +namespace Volo.CmsKit.MongoDB.Tags +{ + [Collection(MongoTestCollection.Name)] + public class EntityTagRepository_Test : EntityTagRepository_Test + { + + } +} diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/EntityTagRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/EntityTagRepository_Test.cs new file mode 100644 index 0000000000..3d60ac0b6a --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Tags/EntityTagRepository_Test.cs @@ -0,0 +1,38 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Modularity; +using Xunit; + +namespace Volo.CmsKit.Tags +{ + public abstract class EntityTagRepository_Test : CmsKitTestBase + where TStartupModule : IAbpModule + { + private CmsKitTestData _cmsKitTestData; + private IEntityTagRepository _entityTagRepository; + private ITagRepository _tagRepository; + + public EntityTagRepository_Test() + { + _cmsKitTestData = GetRequiredService(); + _entityTagRepository = GetRequiredService(); + _tagRepository = GetRequiredService(); + } + + [Fact] + public async Task DeleteManyAsync_ShouldWorkProperly_WithExistingIds() + { + var relatedTags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_EntityId); + + await _entityTagRepository.DeleteManyAsync(relatedTags.Select(s => s.Id).ToArray()); + + relatedTags = await _tagRepository.GetAllRelatedTagsAsync(_cmsKitTestData.Content_1_EntityType, _cmsKitTestData.Content_1_EntityId); + + relatedTags.ShouldBeEmpty(); + } + } +} From b22ad8e2a199958f6b5834aff90263b81a576c47 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 14:57:16 +0300 Subject: [PATCH 50/70] CmsKit - Remove unnecessary lines in .csproj --- .../Volo.CmsKit.Application.Tests.csproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj index bd5f553367..3fac76bfd9 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Volo.CmsKit.Application.Tests.csproj @@ -5,10 +5,6 @@ Volo.CmsKit - - - - From 050cf07cfd27b77cd788498ec64789641ab6a6b5 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 12:40:14 +0300 Subject: [PATCH 51/70] CmsKit - Use Async method instead of AsyncExecuter in MongoBlogPostRepository --- .../Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index bcd6e33211..5c20165d11 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -1,4 +1,5 @@ using MongoDB.Driver; +using MongoDB.Driver.Linq; using Nito.AsyncEx; using System; using System.Collections.Generic; @@ -58,9 +59,9 @@ namespace Volo.CmsKit.MongoDB.Blogs public async Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default) { - var queryable = await GetQueryableAsync(); + var queryable = await GetMongoQueryableAsync(); - return await AsyncExecuter.AnyAsync(queryable, x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); + return await queryable.AnyAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); } } } From 8429f4366027d092a5f1d33fde58ac70b8cac326 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 12:40:49 +0300 Subject: [PATCH 52/70] CmsKit - Fix content-type of BlogPost Cover Image --- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index b71f731efd..e2c2f523b1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -68,7 +68,7 @@ namespace Volo.CmsKit.Admin.Blogs Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); Response.Headers.Add("Accept-Ranges", "bytes"); Response.Headers.Add("Cache-Control", "max-age=120"); - Response.ContentType = "image/*"; + Response.ContentType = "image"; return BlogPostAdminAppService.GetCoverImageAsync(id); } From 0831fa9c5d2c5655e7a7d7b700a30f0ca88507f4 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 13:14:27 +0300 Subject: [PATCH 53/70] CmsKit - Fix Public BlogPost Controller --- .../Public/Blogs/IBlogPostPublicAppService.cs | 6 ++- .../Public/Blogs/BlogPostPublicAppService.cs | 11 +++++ .../Public/Blogs/BlogPostPublicController.cs | 49 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs index 6771ae6adf..e6c5af3376 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs @@ -1,6 +1,8 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; +using Volo.Abp.Content; namespace Volo.CmsKit.Public.Blogs { @@ -9,5 +11,7 @@ namespace Volo.CmsKit.Public.Blogs Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); Task GetAsync(string blogUrlSlug, string blogPostUrlSlug); + + Task GetCoverImageAsync(Guid id); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index d9bb9ab281..a6eaa6e96d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -2,6 +2,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Application.Dtos; +using Volo.Abp.BlobStoring; +using Volo.Abp.Content; using Volo.CmsKit.Blogs; namespace Volo.CmsKit.Public.Blogs @@ -10,6 +12,8 @@ namespace Volo.CmsKit.Public.Blogs { protected IBlogRepository BlogRepository { get; } + protected IBlobContainer BlobContainer { get; } + protected IBlogPostRepository BlogPostRepository { get; } public BlogPostPublicAppService( @@ -39,5 +43,12 @@ namespace Volo.CmsKit.Public.Blogs await BlogPostRepository.GetCountAsync(blog.Id), ObjectMapper.Map, List>(blogPosts)); } + + public async Task GetCoverImageAsync(Guid id) + { + var stream = await BlobContainer.GetAsync(id.ToString()); + + return new RemoteStreamContent(stream); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs new file mode 100644 index 0000000000..c5dc7246ce --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Dtos; +using Volo.Abp.Content; +using Volo.CmsKit.Public.Blogs; + +namespace Volo.CmsKit.Public.HttpApi.Volo.CmsKit.Public.Blogs +{ + [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] + [Area("cms-kit")] + [Route("api/cms-kit-public/blog-posts")] + public class BlogPostPublicController : CmsKitPublicControllerBase, IBlogPostPublicAppService + { + protected IBlogPostPublicAppService BlogPostPublicAppService { get; } + + public BlogPostPublicController(IBlogPostPublicAppService blogPostPublicAppService) + { + BlogPostPublicAppService = blogPostPublicAppService; + } + + [HttpGet] + public Task GetAsync(string blogUrlSlug, string blogPostUrlSlug) + { + return BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); + } + + [HttpGet] + [Route("{id}/cover-image")] + public Task GetCoverImageAsync(Guid id) + { + Response.Headers.Add("Content-Disposition", $"inline;filename=\"{id}\""); + Response.Headers.Add("Accept-Ranges", "bytes"); + Response.Headers.Add("Cache-Control", "max-age=120"); + Response.ContentType = "image"; + return BlogPostPublicAppService.GetCoverImageAsync(id); + } + + [HttpGet] + public Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) + { + return BlogPostPublicAppService.GetListAsync(blogUrlSlug, input); + } + } +} From f356f1cf7b94f4ed3024719744ccbc6aff124681 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 13:42:58 +0300 Subject: [PATCH 54/70] CmsKit - Refactor BlogPostPublicController --- .../Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs index c5dc7246ce..091efcf183 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs @@ -7,10 +7,13 @@ using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Content; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Public.Blogs; -namespace Volo.CmsKit.Public.HttpApi.Volo.CmsKit.Public.Blogs +namespace Volo.CmsKit.Public.Blogs { + [RequiresGlobalFeature(typeof(BlogsFeature))] [RemoteService(Name = CmsKitPublicRemoteServiceConsts.RemoteServiceName)] [Area("cms-kit")] [Route("api/cms-kit-public/blog-posts")] @@ -37,6 +40,7 @@ namespace Volo.CmsKit.Public.HttpApi.Volo.CmsKit.Public.Blogs Response.Headers.Add("Accept-Ranges", "bytes"); Response.Headers.Add("Cache-Control", "max-age=120"); Response.ContentType = "image"; + return BlogPostPublicAppService.GetCoverImageAsync(id); } From dd00b6c2ef0ee7f5a202603d9267bb452c2ac17a Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 13:51:22 +0300 Subject: [PATCH 55/70] CmsKit - Add images to UI --- .../src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml | 1 + .../CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml | 2 ++ 2 files changed, 3 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml index bd683fbc85..7a3660dbf5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -20,6 +20,7 @@ + @blog.ShortDescription diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml index df409d6dde..ebb009448d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -12,7 +12,9 @@ @Model.Title @@@Model.Creator?.UserName + + @await Component.InvokeAsync(typeof(ContentViewComponent), new { entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, From 3b179f347f78291da2309552ab1b08d97ae0a157 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 13:56:07 +0300 Subject: [PATCH 56/70] CmsKit - merge issues fix --- .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs index 1f8fe1184b..677857d2b6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -23,10 +23,5 @@ namespace Volo.CmsKit.Blogs { return GetAsync(x => x.UrlSlug == urlSlug); } - - public async Task ExistsAsync(Guid blogId) - { - return await (await GetQueryableAsync()).AnyAsync(x => x.Id == blogId); - } } } From 3a80beab459b23bfae7bc46704d543d0952f401b Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 13:58:08 +0300 Subject: [PATCH 57/70] CmsKit - Fix public image displaying --- .../Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index a6eaa6e96d..497aad76c3 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -12,16 +12,18 @@ namespace Volo.CmsKit.Public.Blogs { protected IBlogRepository BlogRepository { get; } - protected IBlobContainer BlobContainer { get; } - protected IBlogPostRepository BlogPostRepository { get; } + protected IBlobContainer BlobContainer { get; } + public BlogPostPublicAppService( IBlogRepository blogRepository, - IBlogPostRepository blogPostRepository) + IBlogPostRepository blogPostRepository, + IBlobContainer blobContainer) { BlogRepository = blogRepository; BlogPostRepository = blogPostRepository; + BlobContainer = blobContainer; } public async Task GetAsync(string blogUrlSlug, string blogPostUrlSlug) From 8db321aa930146917ef4c652bcdabb9b4b75a45a Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 15:27:56 +0300 Subject: [PATCH 58/70] CmsKit - Fix merge issues --- .../Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs | 7 ------- 1 file changed, 7 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index f36ed3a666..b1d9d3167b 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -24,12 +24,5 @@ namespace Volo.CmsKit.MongoDB.Blogs { return GetAsync(x => x.UrlSlug == urlSlug); } - - public async Task ExistsAsync(Guid blogId) - { - return await AsyncExecuter.AnyAsync( - await GetQueryableAsync(), - x => x.Id == blogId); - } } } From a83c4f470cf6d6aae911494ebc4aa762add49fc7 Mon Sep 17 00:00:00 2001 From: enisn Date: Fri, 5 Feb 2021 16:25:37 +0300 Subject: [PATCH 59/70] CmsKit - Fix updating UrlSlug Check --- .../Admin/Blogs/BlogPostAdminAppService.cs | 16 ++++++----- .../Volo/CmsKit/Blogs/BlogPost.cs | 2 +- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 9 +++++-- .../Volo/CmsKit/Blogs/IBlogPostManager.cs | 2 ++ .../Blogs/BlogPostManager_Tests.cs | 27 ++++++++++++++++--- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 4 +-- 6 files changed, 46 insertions(+), 14 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index 3034311d70..cb95d1fe87 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -82,16 +82,20 @@ namespace Volo.CmsKit.Admin.Blogs [Authorize(CmsKitAdminPermissions.BlogPosts.Update)] public override async Task UpdateAsync(Guid id, CreateUpdateBlogPostDto input) { - var entity = await BlogPostRepository.GetAsync(id); + var blogPost = await BlogPostRepository.GetAsync(id); - entity.SetTitle(input.Title); - entity.SetUrlSlug(input.UrlSlug); + blogPost.SetTitle(input.Title); - MapToEntity(input, entity); + if (blogPost.UrlSlug != input.UrlSlug) + { + await BlogPostManager.SetSlugUrlAsync(blogPost, input.UrlSlug); + } - await BlogPostManager.UpdateAsync(entity); + MapToEntity(input, blogPost); - return MapToGetOutputDto(entity); + await BlogPostManager.UpdateAsync(blogPost); + + return MapToGetOutputDto(blogPost); } public virtual async Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 2a9f6673f2..53f44af35d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -44,7 +44,7 @@ namespace Volo.CmsKit.Blogs Title = Check.NotNullOrWhiteSpace(title, nameof(title), BlogPostConsts.MaxTitleLength); } - public void SetUrlSlug(string urlSlug) + internal void SetUrlSlug(string urlSlug) { Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index 228d8eccbf..b28e705191 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -34,11 +34,16 @@ namespace Volo.CmsKit.Blogs { await CheckBlogExistenceAsync(blogPost.BlogId); - await CheckUrlSlugExistenceAsync(blogPost.BlogId, blogPost.UrlSlug); - await blogPostRepository.UpdateAsync(blogPost); } + public async Task SetSlugUrlAsync(BlogPost blogPost, string newSlug) + { + await CheckUrlSlugExistenceAsync(blogPost.BlogId, newSlug); + + blogPost.SetUrlSlug(newSlug); + } + private async Task CheckUrlSlugExistenceAsync(Guid blogId, string urlSlug) { if (await blogPostRepository.SlugExistsAsync(blogId, urlSlug)) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs index eb5c0170e1..5027fa8e38 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostManager.cs @@ -8,5 +8,7 @@ namespace Volo.CmsKit.Blogs Task CreateAsync(BlogPost blogPost); Task UpdateAsync(BlogPost blogPost); + + Task SetSlugUrlAsync(BlogPost blogPost, string newSlug); } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs index a9d7aa2da7..84eddeec3c 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs @@ -54,18 +54,39 @@ namespace Volo.CmsKit.Blogs public async Task UpdateAsync_ShoudlWorkProperly_WithCorrectData() { var newTitle = "Yet Another Post"; - var newUrlSlug = "yet-another-post"; var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); blogPost.SetTitle(newTitle); - blogPost.SetUrlSlug(newUrlSlug); await blogPostManager.UpdateAsync(blogPost); var updated = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); updated.Title.ShouldBe(newTitle); - updated.UrlSlug.ShouldBe(newUrlSlug); + } + + [Fact] + public async Task SetUrlSlugAsync_ShouldWorkProperly_WithNonExistingSlug() + { + var newUrlSlug = "yet-another-post"; + + var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); + + await blogPostManager.SetSlugUrlAsync(blogPost, newUrlSlug); + + blogPost.UrlSlug.ShouldBe(newUrlSlug); + } + + [Fact] + public async Task SetUrlSlugAsync_ShouldThrowException_WithExistingSlug() + { + var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); + + var exception = await Should.ThrowAsync(async () => + await blogPostManager.SetSlugUrlAsync(blogPost, cmsKitTestData.BlogPost_2_UrlSlug)); + + exception.BlogId.ShouldBe(blogPost.BlogId); + exception.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_2_UrlSlug); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index 99682fbbfb..a212d8505d 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -87,8 +87,8 @@ namespace Volo.CmsKit public Guid BlogPost_2_Id { get; } = Guid.NewGuid(); - public string BlogPost_2_Title => "How to use CmsKit?"; + public string BlogPost_2_Title => "How to use CmsKit"; - public string BlogPost_2_UrlSlug => "how-to-use-cms-kit?"; + public string BlogPost_2_UrlSlug => "how-to-use-cms-kit"; } } From 5a3d52593357a1ec04cefeb4330332e827a0c49e Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 8 Feb 2021 10:14:15 +0300 Subject: [PATCH 60/70] CmsKit - Convert plain status code to CreadAtAction method --- .../Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index e2c2f523b1..b4c411f1dc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -101,7 +101,7 @@ namespace Volo.CmsKit.Admin.Blogs await BlogPostAdminAppService.SetCoverImageAsync(id, new RemoteStreamContent(stream)); } - return StatusCode(201); + return CreatedAtAction(nameof(GetCoverImageAsync), new { id }); } [HttpPut] From 31ba40c2549eb8b2aba9ca65b22e39b5db2a7801 Mon Sep 17 00:00:00 2001 From: Ilkay Ilknur Date: Mon, 8 Feb 2021 14:14:12 +0300 Subject: [PATCH 61/70] small design changes. --- .../Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml | 2 +- .../CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml index 7a3660dbf5..998bfa2881 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -20,7 +20,7 @@ - + @blog.ShortDescription diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml index ebb009448d..a6cef52512 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml @@ -10,11 +10,11 @@ @Model.Title - @@@Model.Creator?.UserName + @Model.Creator?.UserName - + @**@ @await Component.InvokeAsync(typeof(ContentViewComponent), new { entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, From 530dbb9506be655b0cbb3b02f58748c8e6faf2b3 Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 8 Feb 2021 15:28:01 +0300 Subject: [PATCH 62/70] CmsKit - Remove lookup from Blogs and add searching --- .../Volo/CmsKit/Admin/Blogs/BlogGetListInput.cs | 9 +++++++++ .../Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs | 3 +-- .../Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs | 13 +++++++------ .../Volo/CmsKit/Admin/Blogs/BlogAdminController.cs | 10 +--------- 4 files changed, 18 insertions(+), 17 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogGetListInput.cs diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogGetListInput.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogGetListInput.cs new file mode 100644 index 0000000000..e26307c6d0 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogGetListInput.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Admin.Blogs +{ + public class BlogGetListInput : PagedAndSortedResultRequestDto + { + public string Filter { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs index b6000be499..f0485cc344 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogAdminAppService.cs @@ -5,8 +5,7 @@ using Volo.Abp.Application.Services; namespace Volo.CmsKit.Admin.Blogs { - public interface IBlogAdminAppService : ICrudAppService + public interface IBlogAdminAppService : ICrudAppService { - Task> GetLookupAsync(); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index 0703bc94a4..5c833f5256 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -14,7 +14,7 @@ namespace Volo.CmsKit.Admin.Blogs { [RequiresGlobalFeature(typeof(BlogsFeature))] [Authorize(CmsKitAdminPermissions.Blogs.Default)] - public class BlogAdminAppService : CrudAppService, IBlogAdminAppService + public class BlogAdminAppService : CrudAppService, IBlogAdminAppService { public BlogAdminAppService(IRepository repository) : base(repository) { @@ -25,12 +25,13 @@ namespace Volo.CmsKit.Admin.Blogs DeletePolicyName = CmsKitAdminPermissions.Blogs.Delete; } - [Authorize(CmsKitAdminPermissions.Blogs.Default)] - public async Task> GetLookupAsync() + protected override async Task> CreateFilteredQueryAsync(BlogGetListInput input) { - var blogs = await Repository.GetListAsync(); - - return ObjectMapper.Map, List>(blogs); + var queryable = await base.CreateFilteredQueryAsync(input); + return queryable + .WhereIf( + !input.Filter.IsNullOrWhiteSpace(), + x => x.Name.ToLower().Contains(input.Filter)); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs index e6c4370df9..d63a3317ce 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogAdminController.cs @@ -52,7 +52,7 @@ namespace Volo.CmsKit.Admin.Blogs [HttpGet] [Authorize(CmsKitAdminPermissions.Blogs.Default)] - public Task> GetListAsync([FromQuery] PagedAndSortedResultRequestDto input) + public Task> GetListAsync([FromQuery] BlogGetListInput input) { return BlogAdminAppService.GetListAsync(input); } @@ -64,13 +64,5 @@ namespace Volo.CmsKit.Admin.Blogs { return BlogAdminAppService.UpdateAsync(id, input); } - - [HttpGet] - [Route("lookup")] - [Authorize(CmsKitAdminPermissions.Blogs.Default)] - public Task> GetLookupAsync() - { - return BlogAdminAppService.GetLookupAsync(); - } } } From bd97a9651252bdb7679e0c963aa1fdaf4986168b Mon Sep 17 00:00:00 2001 From: enisn Date: Mon, 8 Feb 2021 16:55:22 +0300 Subject: [PATCH 63/70] CmsKit - Disable Page feature temporarily --- .../cms-kit/host/Volo.CmsKit.Host.Shared/FeatureConfigurer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/host/Volo.CmsKit.Host.Shared/FeatureConfigurer.cs b/modules/cms-kit/host/Volo.CmsKit.Host.Shared/FeatureConfigurer.cs index 9046c60aca..b108d08b02 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Host.Shared/FeatureConfigurer.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Host.Shared/FeatureConfigurer.cs @@ -1,5 +1,6 @@ using Volo.Abp.GlobalFeatures; using Volo.Abp.Threading; +using Volo.CmsKit.GlobalFeatures; namespace Volo.CmsKit { @@ -12,6 +13,7 @@ namespace Volo.CmsKit OneTimeRunner.Run(() => { GlobalFeatureManager.Instance.Modules.CmsKit().EnableAll(); + GlobalFeatureManager.Instance.Modules.CmsKit().Disable(); }); } } From fca418fb3f128c494dd4a02487b75a7aeae85432 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 10:16:00 +0300 Subject: [PATCH 64/70] CmsKit - Slugify Implementation --- .../Volo.CmsKit.Domain.csproj | 2 +- .../Blogs/Extensions/UrlSlugExtensions.cs | 22 ++++--------------- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj index 7355bc87d1..8c5e630f78 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj @@ -9,7 +9,7 @@ - + diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs index 45765c4a09..991ae7eaac 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs @@ -1,4 +1,5 @@ -using System.Text.RegularExpressions; +using Slugify; +using System.Text.RegularExpressions; using Unidecode.NET; namespace Volo.CmsKit.Blogs.Extensions @@ -7,24 +8,9 @@ namespace Volo.CmsKit.Blogs.Extensions { public static string NormalizeAsUrlSlug(this string value) { - value = value.ToLowerInvariant(); + var slugHelper = new SlugHelper(); - // Unidecode for non-latin characters - value = value.Unidecode(); - - // Replace spaces - value = Regex.Replace(value, @"\s", "-", RegexOptions.Compiled); - - // Remove invalid chars - value = Regex.Replace(value, @"[^a-z0-9\s-_]", "", RegexOptions.Compiled); - - // Trim dashes & dots - value = value.Trim('-', '_', '.'); - - // Replace double occurences of - or _ - value = Regex.Replace(value, @"([-_]){2,}", "$1", RegexOptions.Compiled); - - return value; + return slugHelper.GenerateSlug(value); } } } From f27776430d2824e6f7151a70c1d649838f5cd21b Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 11:07:29 +0300 Subject: [PATCH 65/70] CmsKit - Rafactoring - Change naming UrlSlug to Slug --- .../Volo/CmsKit/Admin/Blogs/BlogDto.cs | 4 +- .../Volo/CmsKit/Admin/Blogs/BlogPostDto.cs | 2 +- .../Admin/Blogs/CreateUpdateBlogPostDto.cs | 6 +-- .../Admin/Blogs/IBlogPostAdminAppService.cs | 2 +- .../Admin/Blogs/BlogPostAdminAppService.cs | 12 +++--- .../Admin/Blogs/BlogPostAdminController.cs | 6 +-- .../Volo/CmsKit/Blogs/BlogConsts.cs | 2 +- .../Volo/CmsKit/Blogs/BlogPostConsts.cs | 4 +- .../Volo/CmsKit/CmsKitErrorCodes.cs | 2 +- .../Volo/CmsKit/Blogs/Blog.cs | 12 +++--- .../Volo/CmsKit/Blogs/BlogPost.cs | 12 +++--- .../Volo/CmsKit/Blogs/BlogPostManager.cs | 12 +++--- .../BlogPostSlugAlreadyExistException.cs | 31 ++++++++++++++ .../BlogPostUrlSlugAlreadyExistException.cs | 31 -------------- ...UrlSlugExtensions.cs => SlugExtensions.cs} | 6 +-- .../Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 +- .../Volo/CmsKit/Blogs/IBlogRepository.cs | 2 +- .../CmsKit/Blogs/EfCoreBlogPostRepository.cs | 6 +-- .../Volo/CmsKit/Blogs/EfCoreBlogRepository.cs | 4 +- .../CmsKitDbContextModelCreatingExtensions.cs | 6 +-- .../MongoDB/Blogs/MongoBlogPostRepository.cs | 6 +-- .../MongoDB/Blogs/MongoBlogRepository.cs | 4 +- .../CmsKit/Public/Blogs/BlogPostPublicDto.cs | 2 +- .../Public/Blogs/IBlogPostPublicAppService.cs | 4 +- .../Public/Blogs/BlogPostPublicAppService.cs | 10 ++--- .../Public/Blogs/BlogPostPublicController.cs | 8 ++-- .../Pages/CmsKit/Blogs/BlogPost.cshtml | 6 +-- .../Pages/CmsKit/Blogs/BlogPost.cshtml.cs | 6 +-- .../Pages/CmsKit/Blogs/Index.cshtml | 4 +- .../Pages/CmsKit/Blogs/Index.cshtml.cs | 4 +- .../BlogPost/DefaultBlogPostViewComponent.cs | 4 +- .../Blogs/BlogPostAdminAppService_Tests.cs | 42 +++++++++---------- .../Blogs/BlogPostManager_Tests.cs | 28 ++++++------- ...sions_Tests.cs => SlugExtensions_Tests.cs} | 38 ++++++++--------- .../Blogs/BlogPostRepository_Test.cs | 22 +++++----- .../Blogs/BlogRepository_Test.cs | 10 ++--- .../CmsKitDataSeedContributor.cs | 6 +-- .../Volo.CmsKit.TestBase/CmsKitTestData.cs | 6 +-- 38 files changed, 186 insertions(+), 188 deletions(-) create mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs delete mode 100644 modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs rename modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/{UrlSlugExtensions.cs => SlugExtensions.cs} (53%) rename modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/{UrlSlugExtensions_Tests.cs => SlugExtensions_Tests.cs} (67%) diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs index 0f112d15b8..6bf7adcfaa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogDto.cs @@ -13,7 +13,7 @@ namespace Volo.CmsKit.Admin.Blogs public string Name { get; set; } [Required] - [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxUrlSlugLength))] - public string UrlSlug { get; set; } + [DynamicMaxLength(typeof(BlogConsts), nameof(BlogConsts.MaxSlugLength))] + public string Slug { get; set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs index e1463ceba3..9d1e74a578 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/BlogPostDto.cs @@ -9,7 +9,7 @@ namespace Volo.CmsKit.Admin.Blogs public string Title { get; set; } - public string UrlSlug { get; set; } + public string Slug { get; set; } public string ShortDescription { get; protected set; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs index 71d091bfa4..4c0532129d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/CreateUpdateBlogPostDto.cs @@ -17,9 +17,9 @@ namespace Volo.CmsKit.Admin.Blogs [Required] [DynamicStringLength( typeof(BlogPostConsts), - nameof(BlogPostConsts.MaxUrlSlugLength), - nameof(BlogPostConsts.MinUrlSlugLength))] - public string UrlSlug { get; set; } + nameof(BlogPostConsts.MaxSlugLength), + nameof(BlogPostConsts.MinSlugLength))] + public string Slug { get; set; } [DynamicMaxLength(typeof(BlogPostConsts), nameof(BlogPostConsts.MaxShortDescriptionLength))] public string ShortDescription { get; set; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs index 902f31f025..28d614d289 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Blogs/IBlogPostAdminAppService.cs @@ -13,7 +13,7 @@ namespace Volo.CmsKit.Admin.Blogs PagedAndSortedResultRequestDto, CreateUpdateBlogPostDto> { - Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug); + Task GetBySlugAsync(string blogSlug, string slug); Task SetCoverImageAsync(Guid id, RemoteStreamContent streamContent); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs index cb95d1fe87..8fa6fb9ff7 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogPostAdminAppService.cs @@ -53,11 +53,11 @@ namespace Volo.CmsKit.Admin.Blogs DeletePolicyName = CmsKitAdminPermissions.BlogPosts.Delete; } - public virtual async Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug) + public virtual async Task GetBySlugAsync(string blogSlug, string blogPostSlug) { - var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + var blog = await BlogRepository.GetBySlugAsync(blogSlug); - var blogPost = await BlogPostRepository.GetByUrlSlugAsync(blog.Id, urlSlug); + var blogPost = await BlogPostRepository.GetBySlugAsync(blog.Id, blogPostSlug); return MapToGetOutputDto(blogPost); } @@ -73,7 +73,7 @@ namespace Volo.CmsKit.Admin.Blogs GuidGenerator.Create(), input.BlogId, input.Title, - input.UrlSlug, + input.Slug, input.ShortDescription)); return MapToGetOutputDto(entity); @@ -86,9 +86,9 @@ namespace Volo.CmsKit.Admin.Blogs blogPost.SetTitle(input.Title); - if (blogPost.UrlSlug != input.UrlSlug) + if (blogPost.Slug != input.Slug) { - await BlogPostManager.SetSlugUrlAsync(blogPost, input.UrlSlug); + await BlogPostManager.SetSlugUrlAsync(blogPost, input.Slug); } MapToEntity(input, blogPost); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs index b4c411f1dc..6c7e78de50 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.HttpApi/Volo/CmsKit/Admin/Blogs/BlogPostAdminController.cs @@ -53,11 +53,11 @@ namespace Volo.CmsKit.Admin.Blogs } [HttpGet] - [Route("{blogUrlSlug}/{urlSlug}")] + [Route("{blogSlug}/{blogPostSlug}")] [Authorize(CmsKitAdminPermissions.BlogPosts.Default)] - public virtual Task GetByUrlSlugAsync(string blogUrlSlug, string urlSlug) + public virtual Task GetBySlugAsync(string blogSlug, string blogPostSlug) { - return BlogPostAdminAppService.GetByUrlSlugAsync(blogUrlSlug, urlSlug); + return BlogPostAdminAppService.GetBySlugAsync(blogSlug, blogPostSlug); } [HttpGet] diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs index 7d2467226d..def370dca8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogConsts.cs @@ -3,6 +3,6 @@ public class BlogConsts { public static int MaxNameLength { get; set; } = 64; - public static int MaxUrlSlugLength { get; set; } = 64; + public static int MaxSlugLength { get; set; } = 64; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs index 28ca2d9141..97b67416cf 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Blogs/BlogPostConsts.cs @@ -4,9 +4,9 @@ { public static int MaxTitleLength { get; set; } = 64; - public static int MaxUrlSlugLength { get; set; } = 256; + public static int MaxSlugLength { get; set; } = 256; - public static int MinUrlSlugLength { get; set; } = 2; + public static int MinSlugLength { get; set; } = 2; public static int MaxShortDescriptionLength { get; set; } = 256; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index fa31692bfe..da6f2ae1a2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -17,7 +17,7 @@ public static class Blogs { - public const string UrlSlugAlreadyExist = "CmsKit:BlogPost:0001"; + public const string SlugAlreadyExist = "CmsKit:BlogPost:0001"; } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs index 75d319b33b..79c496970c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -12,17 +12,17 @@ namespace Volo.CmsKit.Blogs public Blog( Guid id, [NotNull] string name, - [NotNull] string urlSlug, + [NotNull] string slug, [CanBeNull] Guid? tenantId = null) : base(id) { SetName(name); - SetUrlSlug(urlSlug); + SetSlug(slug); TenantId = tenantId; } public string Name { get; protected set; } - public string UrlSlug { get; protected set; } + public string Slug { get; protected set; } public Guid? TenantId { get; protected set; } @@ -31,11 +31,11 @@ namespace Volo.CmsKit.Blogs Name = Check.NotNullOrWhiteSpace(name, nameof(name), maxLength: BlogConsts.MaxNameLength); } - public void SetUrlSlug(string urlSlug) + public void SetSlug(string slug) { - Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), maxLength: BlogConsts.MaxNameLength); + Check.NotNullOrWhiteSpace(slug, nameof(slug), maxLength: BlogConsts.MaxNameLength); - UrlSlug = urlSlug.NormalizeAsUrlSlug(); + Slug = slug.NormalizeSlug(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs index 53f44af35d..7a52fe0d9f 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -16,7 +16,7 @@ namespace Volo.CmsKit.Blogs public string Title { get; protected set; } - public string UrlSlug { get; protected set; } + public string Slug { get; protected set; } public string ShortDescription { get; protected set; } @@ -30,12 +30,12 @@ namespace Volo.CmsKit.Blogs Guid id, Guid blogId, [NotNull] string title, - [NotNull] string urlSlug, + [NotNull] string slug, [CanBeNull] string shortDescription = null) : base(id) { BlogId = blogId; SetTitle(title); - SetUrlSlug(urlSlug); + SetSlug(slug); ShortDescription = shortDescription; } @@ -44,11 +44,11 @@ namespace Volo.CmsKit.Blogs Title = Check.NotNullOrWhiteSpace(title, nameof(title), BlogPostConsts.MaxTitleLength); } - internal void SetUrlSlug(string urlSlug) + internal void SetSlug(string slug) { - Check.NotNullOrWhiteSpace(urlSlug, nameof(urlSlug), BlogPostConsts.MaxUrlSlugLength, BlogPostConsts.MinUrlSlugLength); + Check.NotNullOrWhiteSpace(slug, nameof(slug), BlogPostConsts.MaxSlugLength, BlogPostConsts.MinSlugLength); - UrlSlug = urlSlug.NormalizeAsUrlSlug(); + Slug = slug.NormalizeSlug(); } public void SetShortDescription(string shortDescription) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index b28e705191..aed2b9fffd 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs @@ -25,7 +25,7 @@ namespace Volo.CmsKit.Blogs { await CheckBlogExistenceAsync(blogPost.BlogId); - await CheckUrlSlugExistenceAsync(blogPost.BlogId, blogPost.UrlSlug); + await CheckSlugExistenceAsync(blogPost.BlogId, blogPost.Slug); return await blogPostRepository.InsertAsync(blogPost); } @@ -39,16 +39,16 @@ namespace Volo.CmsKit.Blogs public async Task SetSlugUrlAsync(BlogPost blogPost, string newSlug) { - await CheckUrlSlugExistenceAsync(blogPost.BlogId, newSlug); + await CheckSlugExistenceAsync(blogPost.BlogId, newSlug); - blogPost.SetUrlSlug(newSlug); + blogPost.SetSlug(newSlug); } - private async Task CheckUrlSlugExistenceAsync(Guid blogId, string urlSlug) + private async Task CheckSlugExistenceAsync(Guid blogId, string slug) { - if (await blogPostRepository.SlugExistsAsync(blogId, urlSlug)) + if (await blogPostRepository.SlugExistsAsync(blogId, slug)) { - throw new BlogPostUrlSlugAlreadyExistException(blogId, urlSlug); + throw new BlogPostSlugAlreadyExistException(blogId, slug); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs new file mode 100644 index 0000000000..8e59249299 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs @@ -0,0 +1,31 @@ +using System; +using Volo.Abp; + +namespace Volo.CmsKit.Blogs +{ + public class BlogPostSlugAlreadyExistException : BusinessException + { + internal BlogPostSlugAlreadyExistException(string code = null, string message = null, string details = null, Exception innerException = null, Microsoft.Extensions.Logging.LogLevel logLevel = Microsoft.Extensions.Logging.LogLevel.Warning) : base(code, message, details, innerException, logLevel) + { + } + + internal BlogPostSlugAlreadyExistException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) + { + } + + public BlogPostSlugAlreadyExistException(Guid blogId, string slug) + { + Slug = slug; + BlogId = blogId; + + Code = CmsKitErrorCodes.Blogs.SlugAlreadyExist; + + WithData(nameof(Slug), Slug); + WithData(nameof(BlogId), BlogId); + } + + public string Slug { get; } + + public Guid BlogId { get; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs deleted file mode 100644 index b000f5996d..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostUrlSlugAlreadyExistException.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using Volo.Abp; - -namespace Volo.CmsKit.Blogs -{ - public class BlogPostUrlSlugAlreadyExistException : BusinessException - { - internal BlogPostUrlSlugAlreadyExistException(string code = null, string message = null, string details = null, Exception innerException = null, Microsoft.Extensions.Logging.LogLevel logLevel = Microsoft.Extensions.Logging.LogLevel.Warning) : base(code, message, details, innerException, logLevel) - { - } - - internal BlogPostUrlSlugAlreadyExistException(System.Runtime.Serialization.SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) - { - } - - public BlogPostUrlSlugAlreadyExistException(Guid blogId, string urlSlug) - { - UrlSlug = urlSlug; - BlogId = blogId; - - Code = CmsKitErrorCodes.Blogs.UrlSlugAlreadyExist; - - WithData(nameof(UrlSlug), UrlSlug); - WithData(nameof(BlogId), BlogId); - } - - public string UrlSlug { get; } - - public Guid BlogId { get; } - } -} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs similarity index 53% rename from modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs rename to modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs index 991ae7eaac..15d3017ffc 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/UrlSlugExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs @@ -1,12 +1,10 @@ using Slugify; -using System.Text.RegularExpressions; -using Unidecode.NET; namespace Volo.CmsKit.Blogs.Extensions { - public static class UrlSlugExtensions + public static class SlugExtensions { - public static string NormalizeAsUrlSlug(this string value) + public static string NormalizeSlug(this string value) { var slugHelper = new SlugHelper(); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index c3cf64b44c..3b87fb6522 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -12,7 +12,7 @@ namespace Volo.CmsKit.Blogs { Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default); - Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default); + Task GetBySlugAsync(Guid blogId, string Slug, CancellationToken cancellationToken = default); Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default); diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs index bbff825189..4213884057 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogRepository.cs @@ -6,7 +6,7 @@ namespace Volo.CmsKit.Blogs { public interface IBlogRepository : IBasicRepository { - public Task GetByUrlSlugAsync(string urlSlug); + public Task GetBySlugAsync(string slug); Task ExistsAsync(Guid blogId); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs index df2893dd1e..5a9c5d526a 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogPostRepository.cs @@ -20,14 +20,14 @@ namespace Volo.CmsKit.Blogs { } - public async Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) + public async Task GetBySlugAsync(Guid blogId, string slug, CancellationToken cancellationToken = default) { var dbSet = await GetDbSetAsync(); return await dbSet .Include(i=> i.Creator) .Where(x => - x.BlogId == blogId && x.UrlSlug.ToLower() == urlSlug) + x.BlogId == blogId && x.Slug.ToLower() == slug) .FirstOrDefaultAsync(cancellationToken: cancellationToken) ?? throw new EntityNotFoundException(typeof(BlogPost)); } @@ -60,7 +60,7 @@ namespace Volo.CmsKit.Blogs { var dbSet = await GetDbSetAsync(); - return await dbSet.AnyAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); + return await dbSet.AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug, cancellationToken); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs index 677857d2b6..d2ddbf35aa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogRepository.cs @@ -19,9 +19,9 @@ namespace Volo.CmsKit.Blogs return await (await GetQueryableAsync()).AnyAsync(x => x.Id == blogId); } - public Task GetByUrlSlugAsync(string urlSlug) + public Task GetBySlugAsync(string slug) { - return GetAsync(x => x.UrlSlug == urlSlug); + return GetAsync(x => x.Slug == slug); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs index 57d1f5511c..d3f40afeed 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitDbContextModelCreatingExtensions.cs @@ -198,7 +198,7 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.Name).IsRequired().HasMaxLength(BlogConsts.MaxNameLength); - b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogConsts.MaxUrlSlugLength); + b.Property(p => p.Slug).IsRequired().HasMaxLength(BlogConsts.MaxSlugLength); }); builder.Entity(b => @@ -209,11 +209,11 @@ namespace Volo.CmsKit.EntityFrameworkCore b.Property(p => p.Title).IsRequired().HasMaxLength(BlogPostConsts.MaxTitleLength); - b.Property(p => p.UrlSlug).IsRequired().HasMaxLength(BlogPostConsts.MaxUrlSlugLength); + b.Property(p => p.Slug).IsRequired().HasMaxLength(BlogPostConsts.MaxSlugLength); b.Property(p => p.ShortDescription).HasMaxLength(BlogPostConsts.MaxShortDescriptionLength); - b.HasIndex(x => new { x.UrlSlug, x.BlogId }); + b.HasIndex(x => new { x.Slug, x.BlogId }); }); } else diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs index 5c20165d11..85dc1b86e0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogPostRepository.cs @@ -20,11 +20,11 @@ namespace Volo.CmsKit.MongoDB.Blogs { } - public Task GetByUrlSlugAsync(Guid blogId, string urlSlug, CancellationToken cancellationToken = default) + public Task GetBySlugAsync(Guid blogId, string slug, CancellationToken cancellationToken = default) { return GetAsync(x => x.BlogId == blogId && - x.UrlSlug.ToLower() == urlSlug, + x.Slug.ToLower() == slug, includeDetails: true, cancellationToken: cancellationToken); } @@ -61,7 +61,7 @@ namespace Volo.CmsKit.MongoDB.Blogs { var queryable = await GetMongoQueryableAsync(); - return await queryable.AnyAsync(x => x.BlogId == blogId && x.UrlSlug.ToLower() == slug, cancellationToken); + return await queryable.AnyAsync(x => x.BlogId == blogId && x.Slug.ToLower() == slug, cancellationToken); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs index b1d9d3167b..d733f82bf6 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogRepository.cs @@ -20,9 +20,9 @@ namespace Volo.CmsKit.MongoDB.Blogs x => x.Id == blogId); } - public Task GetByUrlSlugAsync(string urlSlug) + public Task GetBySlugAsync(string slug) { - return GetAsync(x => x.UrlSlug == urlSlug); + return GetAsync(x => x.Slug == slug); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs index 94d3f3fdbc..5cbbda938e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogPostPublicDto.cs @@ -10,7 +10,7 @@ namespace Volo.CmsKit.Public.Blogs public string Title { get; set; } - public string UrlSlug { get; set; } + public string Slug { get; set; } public string ShortDescription { get; set; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs index e6c5af3376..0c9079ee7e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogPostPublicAppService.cs @@ -8,9 +8,9 @@ namespace Volo.CmsKit.Public.Blogs { public interface IBlogPostPublicAppService { - Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input); + Task> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input); - Task GetAsync(string blogUrlSlug, string blogPostUrlSlug); + Task GetAsync(string blogSlug, string blogPostSlug); Task GetCoverImageAsync(Guid id); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs index 497aad76c3..3994720d73 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogPostPublicAppService.cs @@ -26,18 +26,18 @@ namespace Volo.CmsKit.Public.Blogs BlobContainer = blobContainer; } - public async Task GetAsync(string blogUrlSlug, string blogPostUrlSlug) + public async Task GetAsync(string blogSlug, string blogPostSlug) { - var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + var blog = await BlogRepository.GetBySlugAsync(blogSlug); - var blogPost = await BlogPostRepository.GetByUrlSlugAsync(blog.Id, blogPostUrlSlug); + var blogPost = await BlogPostRepository.GetBySlugAsync(blog.Id, blogPostSlug); return ObjectMapper.Map(blogPost); } - public async Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) + public async Task> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input) { - var blog = await BlogRepository.GetByUrlSlugAsync(blogUrlSlug); + var blog = await BlogRepository.GetBySlugAsync(blogSlug); var blogPosts = await BlogPostRepository.GetPagedListAsync(blog.Id, input.SkipCount, input.MaxResultCount, input.Sorting); diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs index 091efcf183..4e14ca31ec 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs @@ -27,9 +27,9 @@ namespace Volo.CmsKit.Public.Blogs } [HttpGet] - public Task GetAsync(string blogUrlSlug, string blogPostUrlSlug) + public Task GetAsync(string blogSlug, string blogPostSlug) { - return BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); + return BlogPostPublicAppService.GetAsync(blogSlug, blogPostSlug); } [HttpGet] @@ -45,9 +45,9 @@ namespace Volo.CmsKit.Public.Blogs } [HttpGet] - public Task> GetListAsync(string blogUrlSlug, PagedAndSortedResultRequestDto input) + public Task> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input) { - return BlogPostPublicAppService.GetListAsync(blogUrlSlug, input); + return BlogPostPublicAppService.GetListAsync(blogSlug, input); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml index e03bf06991..51472ce7c1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml @@ -1,4 +1,4 @@ -@page "/blogs/{blogUrlSlug}/{blogPostUrlSlug}" +@page "/blogs/{blogSlug}/{blogPostSlug}" @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost @using Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPostComment @@ -20,8 +20,8 @@ @await Component.InvokeAsync(typeof(DefaultBlogPostViewComponent), new { - Model.BlogUrlSlug, - Model.BlogPostUrlSlug + Model.BlogSlug, + Model.BlogPostSlug }) @if (GlobalFeatureManager.Instance.IsEnabled()) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs index 4a63ec1692..a3f31bb9a2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs @@ -11,10 +11,10 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs public class BlogPostModel : CmsKitPublicPageModelBase { [BindProperty(SupportsGet = true)] - public string BlogUrlSlug { get; set; } + public string BlogSlug { get; set; } [BindProperty(SupportsGet = true)] - public string BlogPostUrlSlug { get; set; } + public string BlogPostSlug { get; set; } public BlogPostPublicDto BlogPost { get; private set; } @@ -27,7 +27,7 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs public async Task OnGetAsync() { - BlogPost = await BlogPostPublicAppService.GetAsync(BlogUrlSlug, BlogPostUrlSlug); + BlogPost = await BlogPostPublicAppService.GetAsync(BlogSlug, BlogPostSlug); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml index 998bfa2881..066e4dd7c2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml @@ -1,4 +1,4 @@ -@page "/blogs/{blogUrlSlug}" +@page "/blogs/{blogSlug}" @using Volo.CmsKit.Public.Web.Pages @@ -25,7 +25,7 @@ @blog.ShortDescription - + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs index d375efef61..9f44d9beaa 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/Index.cshtml.cs @@ -15,7 +15,7 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs public const int PageSize = 12; [BindProperty(SupportsGet = true)] - public string BlogUrlSlug { get; set; } + public string BlogSlug { get; set; } [BindProperty(SupportsGet = true)] public int CurrentPage { get; set; } = 1; @@ -34,7 +34,7 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs public async Task OnGetAsync() { Blogs = await BlogPostPublicAppService.GetListAsync( - BlogUrlSlug, + BlogSlug, new PagedAndSortedResultRequestDto { SkipCount = PageSize * (CurrentPage - 1), diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs index 4a055d6679..90dc2a6ab0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Shared/Components/Blogs/BlogPost/DefaultBlogPostViewComponent.cs @@ -19,9 +19,9 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Shared.Components.Blogs.BlogPost BlogPostPublicAppService = blogPostPublicAppService; } - public virtual async Task InvokeAsync(string blogUrlSlug, string blogPostUrlSlug) + public virtual async Task InvokeAsync(string blogSlug, string blogPostSlug) { - var blogPost = await BlogPostPublicAppService.GetAsync(blogUrlSlug, blogPostUrlSlug); + var blogPost = await BlogPostPublicAppService.GetAsync(blogSlug, blogPostSlug); return View("~/Pages/CmsKit/Shared/Components/Blogs/BlogPost/Default.cshtml", blogPost); } diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs index 71bb043ce8..efef70cb9b 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogPostAdminAppService_Tests.cs @@ -28,14 +28,14 @@ namespace Volo.CmsKit.Blogs public async Task CreateAsync_ShouldWorkProperly_WithCorrectData() { var title = "My awesome new Post"; - var urlSlug = "my-awesome-new-post"; + var slug = "my-awesome-new-post"; var shortDescription = "This blog is all about awesomeness 🤗!"; var created = await blogPostAdminAppService.CreateAsync(new CreateUpdateBlogPostDto { BlogId = cmsKitTestData.Blog_Id, Title = title, - UrlSlug = urlSlug, + Slug = slug, ShortDescription = shortDescription }); @@ -44,7 +44,7 @@ namespace Volo.CmsKit.Blogs var blogPost = await blogPostRepository.GetAsync(created.Id); blogPost.Title.ShouldBe(title); - blogPost.UrlSlug.ShouldBe(urlSlug); + blogPost.Slug.ShouldBe(slug); blogPost.ShortDescription.ShouldBe(shortDescription); } @@ -52,7 +52,7 @@ namespace Volo.CmsKit.Blogs public async Task CreateAsync_ShouldThrowException_WithNonExistingBlogId() { var title = "Another My Awesome New Post"; - var urlSlug = "another-my-awesome-new-post"; + var slug = "another-my-awesome-new-post"; var shortDescription = "This blog is all about awesomeness 🤗!"; var dto = new CreateUpdateBlogPostDto @@ -60,7 +60,7 @@ namespace Volo.CmsKit.Blogs // Non-existing Id BlogId = Guid.NewGuid(), Title = title, - UrlSlug = urlSlug, + Slug = slug, ShortDescription = shortDescription }; @@ -76,7 +76,7 @@ namespace Volo.CmsKit.Blogs var blogPost = await blogPostAdminAppService.GetAsync(cmsKitTestData.BlogPost_1_Id); blogPost.Title.ShouldBe(cmsKitTestData.BlogPost_1_Title); - blogPost.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_1_UrlSlug); + blogPost.Slug.ShouldBe(cmsKitTestData.BlogPost_1_Slug); } [Fact] @@ -91,30 +91,30 @@ namespace Volo.CmsKit.Blogs } [Fact] - public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingUrlSlug() + public async Task GetBySlugAsync_ShouldWorkProperly_WithExistingSlug() { - var blogPost = await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogUrlSlug, cmsKitTestData.BlogPost_1_UrlSlug); + var blogPost = await blogPostAdminAppService.GetBySlugAsync(cmsKitTestData.BlogSlug, cmsKitTestData.BlogPost_1_Slug); blogPost.Id.ShouldBe(cmsKitTestData.BlogPost_1_Id); blogPost.Title.ShouldBe(cmsKitTestData.BlogPost_1_Title); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogPostUrlSlug() + public async Task GetBySlugAsync_ShouldThrowException_WithNonExistingBlogPostSlug() { - var nonExistingUrlSlug = "any-other-url"; + var nonExistingSlug = "any-other-url"; var exception = await Should.ThrowAsync(async () => - await blogPostAdminAppService.GetByUrlSlugAsync(cmsKitTestData.BlogUrlSlug, nonExistingUrlSlug)); + await blogPostAdminAppService.GetBySlugAsync(cmsKitTestData.BlogSlug, nonExistingSlug)); exception.EntityType.ShouldBe(typeof(BlogPost)); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogUrlSlug() + public async Task GetBySlugAsync_ShouldThrowException_WithNonExistingBlogSlug() { - var nonExistingUrlSlug = "any-other-url"; + var nonExistingSlug = "any-other-url"; var exception = await Should.ThrowAsync(async () => - await blogPostAdminAppService.GetByUrlSlugAsync(nonExistingUrlSlug, cmsKitTestData.Page_1_Url)); + await blogPostAdminAppService.GetBySlugAsync(nonExistingSlug, cmsKitTestData.Page_1_Url)); exception.EntityType.ShouldBe(typeof(Blog)); } @@ -135,21 +135,21 @@ namespace Volo.CmsKit.Blogs { var shortDescription = "Another short description"; var title = "[Solved] Another Blog Post"; - var urlSlug = "another-short-blog-post"; + var slug = "another-short-blog-post"; await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, new CreateUpdateBlogPostDto { BlogId = cmsKitTestData.Blog_Id, ShortDescription = shortDescription, Title = title, - UrlSlug = urlSlug, + Slug = slug, }); var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_2_Id); blogPost.Title.ShouldBe(title); blogPost.ShortDescription.ShouldBe(shortDescription); - blogPost.UrlSlug.ShouldBe(urlSlug); + blogPost.Slug.ShouldBe(slug); } [Fact] @@ -161,7 +161,7 @@ namespace Volo.CmsKit.Blogs { BlogId = nonExistingId, Title = cmsKitTestData.Page_2_Title, - UrlSlug = cmsKitTestData.BlogPost_2_UrlSlug + Slug = cmsKitTestData.BlogPost_2_Slug }; var exception = await Should.ThrowAsync(async () => @@ -178,13 +178,13 @@ namespace Volo.CmsKit.Blogs { BlogId = cmsKitTestData.Blog_Id, Title = "Some new title", - UrlSlug = cmsKitTestData.BlogPost_1_UrlSlug + Slug = cmsKitTestData.BlogPost_1_Slug }; - var exception = await Should.ThrowAsync(async () => + var exception = await Should.ThrowAsync(async () => await blogPostAdminAppService.UpdateAsync(cmsKitTestData.BlogPost_2_Id, dto)); - exception.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_1_UrlSlug); + exception.Slug.ShouldBe(cmsKitTestData.BlogPost_1_Slug); } [Fact] diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs index 84eddeec3c..2da60c8bff 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/BlogPostManager_Tests.cs @@ -29,24 +29,24 @@ namespace Volo.CmsKit.Blogs public async Task CreateAsync_ShouldWorkProperly_WithCorrectData() { var title = "New blog post"; - var urlSlug = "new-blog-post"; + var slug = "new-blog-post"; var created = await blogPostManager.CreateAsync( - new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, title, urlSlug)); + new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, title, slug)); created.Id.ShouldNotBe(Guid.Empty); var blogPost = await blogPostRepository.GetAsync(created.Id); blogPost.Title.ShouldBe(title); - blogPost.UrlSlug.ShouldBe(urlSlug); + blogPost.Slug.ShouldBe(slug); } [Fact] - public async Task CreateAsync_ShouldThrowException_WhenUrlSlugAlreadyExists() + public async Task CreateAsync_ShouldThrowException_WhenSlugAlreadyExists() { - var blogPost = new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, "Any New Title", cmsKitTestData.BlogPost_1_UrlSlug); + var blogPost = new BlogPost(guidGenerator.Create(), cmsKitTestData.Blog_Id, "Any New Title", cmsKitTestData.BlogPost_1_Slug); - await Should.ThrowAsync(async () => + await Should.ThrowAsync(async () => await blogPostManager.CreateAsync(blogPost)); } @@ -66,27 +66,27 @@ namespace Volo.CmsKit.Blogs } [Fact] - public async Task SetUrlSlugAsync_ShouldWorkProperly_WithNonExistingSlug() + public async Task SetSlugAsync_ShouldWorkProperly_WithNonExistingSlug() { - var newUrlSlug = "yet-another-post"; + var newSlug = "yet-another-post"; var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); - await blogPostManager.SetSlugUrlAsync(blogPost, newUrlSlug); + await blogPostManager.SetSlugUrlAsync(blogPost, newSlug); - blogPost.UrlSlug.ShouldBe(newUrlSlug); + blogPost.Slug.ShouldBe(newSlug); } [Fact] - public async Task SetUrlSlugAsync_ShouldThrowException_WithExistingSlug() + public async Task SetSlugAsync_ShouldThrowException_WithExistingSlug() { var blogPost = await blogPostRepository.GetAsync(cmsKitTestData.BlogPost_1_Id); - var exception = await Should.ThrowAsync(async () => - await blogPostManager.SetSlugUrlAsync(blogPost, cmsKitTestData.BlogPost_2_UrlSlug)); + var exception = await Should.ThrowAsync(async () => + await blogPostManager.SetSlugUrlAsync(blogPost, cmsKitTestData.BlogPost_2_Slug)); exception.BlogId.ShouldBe(blogPost.BlogId); - exception.UrlSlug.ShouldBe(cmsKitTestData.BlogPost_2_UrlSlug); + exception.Slug.ShouldBe(cmsKitTestData.BlogPost_2_Slug); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs similarity index 67% rename from modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs rename to modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs index 0c32ab3285..725d693148 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/UrlSlugExtensions_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs @@ -9,128 +9,128 @@ using Shouldly; namespace Volo.CmsKit.Blogs { - public class UrlSlugExtensions_Tests + public class SlugExtensions_Tests { [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly() + public void NormalizeSlug_ShouldWorkProperly() { // Arrange var name = "My awesome name"; var expected = "my-awesome-name"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDot() + public void NormalizeSlug_ShouldWorkProperly_WithDot() { // Arrange var name = "My Perfect Title v.2"; var expected = "my-perfect-title-v2"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithQuestionMark() + public void NormalizeSlug_ShouldWorkProperly_WithQuestionMark() { // Arrange var name = "Are you gonna die?"; var expected = "are-you-gonna-die"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithAmpersand() + public void NormalizeSlug_ShouldWorkProperly_WithAmpersand() { // Arrange var name = "We & Machines Challenge"; var expected = "we-machines-challenge"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithDoubleDash() + public void NormalizeSlug_ShouldWorkProperly_WithDoubleDash() { // Arrange var name = "Go and Code --part 2"; var expected = "go-and-code-part-2"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithCyrillicChars() + public void NormalizeSlug_ShouldWorkProperly_WithCyrillicChars() { // Arrange var name = "Мое классное название"; var expected = "moe-klassnoe-nazvanie"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithTurkishChars() + public void NormalizeSlug_ShouldWorkProperly_WithTurkishChars() { // Arrange var name = "Özel Türkçe karakterler: ğüşiöç"; var expected = "ozel-turkce-karakterler-gusioc"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithChineseChars() + public void NormalizeSlug_ShouldWorkProperly_WithChineseChars() { // Arrange var name = "我的挑战"; var expected = "o-e-iao-han"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); } [Fact] - public void NormalizeAsUrlSlug_ShouldWorkProperly_WithEmoji() + public void NormalizeSlug_ShouldWorkProperly_WithEmoji() { // Arrange var name = "Let's Rock 👊"; var expected = "lets-rock"; // Act - var actual = name.NormalizeAsUrlSlug(); + var actual = name.NormalizeSlug(); // Assert actual.ShouldBe(expected); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs index efd07101cb..1b44e3c5b6 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogPostRepository_Test.cs @@ -23,15 +23,15 @@ namespace Volo.CmsKit.Blogs } [Fact] - public async Task SlugExistsAsync_ShouldReturnTrue_WithExistingUrlSlug() + public async Task SlugExistsAsync_ShouldReturnTrue_WithExistingSlug() { - var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); + var result = await blogPostRepository.SlugExistsAsync(testData.Blog_Id, testData.BlogPost_1_Slug); result.ShouldBeTrue(); } [Fact] - public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingUrlSlug() + public async Task SlugExistsAsync_ShouldReturnFalse_WithNonExistingSlug() { var nonExistingSlug = "any-other-url-slug"; @@ -45,38 +45,38 @@ namespace Volo.CmsKit.Blogs { var nonExistingBlogId = Guid.NewGuid(); - var result = await blogPostRepository.SlugExistsAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug); + var result = await blogPostRepository.SlugExistsAsync(nonExistingBlogId, testData.BlogPost_1_Slug); result.ShouldBeFalse(); } [Fact] - public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithCorrectParameters() + public async Task GetBySlugAsync_ShouldWorkProperly_WithCorrectParameters() { - var blogPost = await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, testData.BlogPost_1_UrlSlug); + var blogPost = await blogPostRepository.GetBySlugAsync(testData.Blog_Id, testData.BlogPost_1_Slug); blogPost.ShouldNotBeNull(); blogPost.Id.ShouldBe(testData.BlogPost_1_Id); - blogPost.UrlSlug.ShouldBe(testData.BlogPost_1_UrlSlug); + blogPost.Slug.ShouldBe(testData.BlogPost_1_Slug); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogPostUrlSlug() + public async Task GetBySlugAsync_ShouldThrowException_WithNonExistingBlogPostSlug() { var nonExistingSlugUrl = "absolutely-non-existing-url"; var exception = await Should.ThrowAsync( - async () => await blogPostRepository.GetByUrlSlugAsync(testData.Blog_Id, nonExistingSlugUrl)); + async () => await blogPostRepository.GetBySlugAsync(testData.Blog_Id, nonExistingSlugUrl)); exception.ShouldNotBeNull(); exception.EntityType.ShouldBe(typeof(BlogPost)); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingBlogId() + public async Task GetBySlugAsync_ShouldThrowException_WithNonExistingBlogId() { var nonExistingBlogId = Guid.NewGuid(); var exception = await Should.ThrowAsync( - async () => await blogPostRepository.GetByUrlSlugAsync(nonExistingBlogId, testData.BlogPost_1_UrlSlug)); + async () => await blogPostRepository.GetBySlugAsync(nonExistingBlogId, testData.BlogPost_1_Slug)); exception.ShouldNotBeNull(); exception.EntityType.ShouldBe(typeof(BlogPost)); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs index 5119dfd75b..50a99519eb 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/Blogs/BlogRepository_Test.cs @@ -23,22 +23,22 @@ namespace Volo.CmsKit.Blogs } [Fact] - public async Task GetByUrlSlugAsync_ShouldWorkProperly_WithExistingSlug() + public async Task GetBySlugAsync_ShouldWorkProperly_WithExistingSlug() { - var blog = await blogRepository.GetByUrlSlugAsync(testData.BlogUrlSlug); + var blog = await blogRepository.GetBySlugAsync(testData.BlogSlug); blog.ShouldNotBeNull(); - blog.UrlSlug.ShouldBe(testData.BlogUrlSlug); + blog.Slug.ShouldBe(testData.BlogSlug); blog.Id.ShouldBe(testData.Blog_Id); } [Fact] - public async Task GetByUrlSlugAsync_ShouldThrowException_WithNonExistingSlug() + public async Task GetBySlugAsync_ShouldThrowException_WithNonExistingSlug() { var nonExistingSlug = "some-blog-slug-that-doesnt-exist"; var exception = await Should.ThrowAsync( - async () => await blogRepository.GetByUrlSlugAsync(nonExistingSlug)); + async () => await blogRepository.GetBySlugAsync(nonExistingSlug)); exception.ShouldNotBeNull(); exception.EntityType.ShouldBe(typeof(Blog)); diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs index 9b1f820c23..2ac4a23171 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitDataSeedContributor.cs @@ -308,11 +308,11 @@ namespace Volo.CmsKit private async Task SeedBlogsAsync() { - var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName, _cmsKitTestData.BlogUrlSlug)); + var blog = await _blogRepository.InsertAsync(new Blog(_cmsKitTestData.Blog_Id, _cmsKitTestData.BlogName, _cmsKitTestData.BlogSlug)); - await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_UrlSlug, "Short desc 1")); + await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_1_Id, blog.Id, _cmsKitTestData.BlogPost_1_Title, _cmsKitTestData.BlogPost_1_Slug, "Short desc 1")); - await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_2_Id, blog.Id, _cmsKitTestData.BlogPost_2_Title, _cmsKitTestData.BlogPost_2_UrlSlug, "Short desc 2")); + await _blogPostRepository.InsertAsync(new BlogPost(_cmsKitTestData.BlogPost_2_Id, blog.Id, _cmsKitTestData.BlogPost_2_Title, _cmsKitTestData.BlogPost_2_Slug, "Short desc 2")); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs index a212d8505d..2d6bf30da6 100644 --- a/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs +++ b/modules/cms-kit/test/Volo.CmsKit.TestBase/CmsKitTestData.cs @@ -77,18 +77,18 @@ namespace Volo.CmsKit public string BlogName => "Cms Blog"; - public string BlogUrlSlug => "cms-blog"; + public string BlogSlug => "cms-blog"; public Guid BlogPost_1_Id { get; } = Guid.NewGuid(); public string BlogPost_1_Title => "How to install CmsKit?"; - public string BlogPost_1_UrlSlug => "how-to-install-cms-kit"; + public string BlogPost_1_Slug => "how-to-install-cms-kit"; public Guid BlogPost_2_Id { get; } = Guid.NewGuid(); public string BlogPost_2_Title => "How to use CmsKit"; - public string BlogPost_2_UrlSlug => "how-to-use-cms-kit"; + public string BlogPost_2_Slug => "how-to-use-cms-kit"; } } From a58101d65f6ccc8c3f203268c1e617fca6edbb4c Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 11:22:29 +0300 Subject: [PATCH 66/70] CmsKit - Add migration to Unified as sample --- .../20210209082122_UrlSlugToSlug.Designer.cs | 1891 +++++++++++++++++ .../20210209082122_UrlSlugToSlug.cs | 106 + .../UnifiedDbContextModelSnapshot.cs | 168 +- 3 files changed, 2164 insertions(+), 1 deletion(-) create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.Designer.cs create mode 100644 modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.cs diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.Designer.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.Designer.cs new file mode 100644 index 0000000000..ef06bb2fd9 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.Designer.cs @@ -0,0 +1,1891 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Volo.Abp.EntityFrameworkCore; +using Volo.CmsKit.EntityFrameworkCore; + +namespace Volo.CmsKit.Migrations +{ + [DbContext(typeof(UnifiedDbContext))] + [Migration("20210209082122_UrlSlugToSlug")] + partial class UrlSlugToSlug + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .UseIdentityColumns() + .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("ProductVersion", "5.0.2"); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)") + .HasColumnName("ApplicationName"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("BrowserInfo"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientId"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("ClientIpAddress"); + + b.Property("ClientName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("ClientName"); + + b.Property("Comments") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Comments"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("CorrelationId"); + + b.Property("Exceptions") + .HasMaxLength(4000) + .HasColumnType("nvarchar(4000)") + .HasColumnName("Exceptions"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("HttpMethod") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("HttpMethod"); + + b.Property("HttpStatusCode") + .HasColumnType("int") + .HasColumnName("HttpStatusCode"); + + b.Property("ImpersonatorTenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorTenantId"); + + b.Property("ImpersonatorUserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("ImpersonatorUserId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasColumnType("nvarchar(max)"); + + b.Property("Url") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Url"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier") + .HasColumnName("UserId"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "ExecutionTime"); + + b.HasIndex("TenantId", "UserId", "ExecutionTime"); + + b.ToTable("AbpAuditLogs"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ExecutionDuration") + .HasColumnType("int") + .HasColumnName("ExecutionDuration"); + + b.Property("ExecutionTime") + .HasColumnType("datetime2") + .HasColumnName("ExecutionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("MethodName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("MethodName"); + + b.Property("Parameters") + .HasMaxLength(2000) + .HasColumnType("nvarchar(2000)") + .HasColumnName("Parameters"); + + b.Property("ServiceName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("ServiceName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime"); + + b.ToTable("AbpAuditLogActions"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AuditLogId") + .HasColumnType("uniqueidentifier") + .HasColumnName("AuditLogId"); + + b.Property("ChangeTime") + .HasColumnType("datetime2") + .HasColumnName("ChangeTime"); + + b.Property("ChangeType") + .HasColumnType("tinyint") + .HasColumnName("ChangeType"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityId"); + + b.Property("EntityTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("EntityTypeFullName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("EntityTypeFullName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("AuditLogId"); + + b.HasIndex("TenantId", "EntityTypeFullName", "EntityId"); + + b.ToTable("AbpEntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("EntityChangeId") + .HasColumnType("uniqueidentifier"); + + b.Property("NewValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("NewValue"); + + b.Property("OriginalValue") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)") + .HasColumnName("OriginalValue"); + + b.Property("PropertyName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("PropertyName"); + + b.Property("PropertyTypeFullName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("PropertyTypeFullName"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("EntityChangeId"); + + b.ToTable("AbpEntityPropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ContainerId") + .HasColumnType("uniqueidentifier"); + + b.Property("Content") + .HasMaxLength(2147483647) + .HasColumnType("varbinary(max)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("ContainerId"); + + b.HasIndex("TenantId", "ContainerId", "Name"); + + b.ToTable("AbpBlobs"); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("AbpBlobContainers"); + }); + + modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpFeatureValues"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Description") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsStatic") + .HasColumnType("bit"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Regex") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("RegexDescription") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("Required") + .HasColumnType("bit"); + + b.Property("ValueType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("AbpClaimTypes"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("SourceTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("SourceUserId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetTenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("TargetUserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId") + .IsUnique() + .HasFilter("[SourceTenantId] IS NOT NULL AND [TargetTenantId] IS NOT NULL"); + + b.ToTable("AbpLinkUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDefault") + .HasColumnType("bit") + .HasColumnName("IsDefault"); + + b.Property("IsPublic") + .HasColumnType("bit") + .HasColumnName("IsPublic"); + + b.Property("IsStatic") + .HasColumnType("bit") + .HasColumnName("IsStatic"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("NormalizedName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName"); + + b.ToTable("AbpRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AbpRoleClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Action") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("ApplicationName") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("BrowserInfo") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ClientId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ClientIpAddress") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CorrelationId") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("CreationTime") + .HasColumnType("datetime2"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Identity") + .HasMaxLength(96) + .HasColumnType("nvarchar(96)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TenantName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Action"); + + b.HasIndex("TenantId", "ApplicationName"); + + b.HasIndex("TenantId", "Identity"); + + b.HasIndex("TenantId", "UserId"); + + b.ToTable("AbpSecurityLogs"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("AccessFailedCount") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasDefaultValue(0) + .HasColumnName("AccessFailedCount"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("IsExternal") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsExternal"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("LockoutEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("LockoutEnabled"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("NormalizedEmail") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedEmail"); + + b.Property("NormalizedUserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("NormalizedUserName"); + + b.Property("PasswordHash") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("PasswordHash"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("SecurityStamp") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("SecurityStamp"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("TwoFactorEnabled") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("TwoFactorEnabled"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("Email"); + + b.HasIndex("NormalizedEmail"); + + b.HasIndex("NormalizedUserName"); + + b.HasIndex("UserName"); + + b.ToTable("AbpUsers"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .HasColumnType("uniqueidentifier"); + + b.Property("ClaimType") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("ClaimValue") + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AbpUserClaims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderDisplayName") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(196) + .HasColumnType("nvarchar(196)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "LoginProvider"); + + b.HasIndex("LoginProvider", "ProviderKey"); + + b.ToTable("AbpUserLogins"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "UserId"); + + b.HasIndex("UserId", "OrganizationUnitId"); + + b.ToTable("AbpUserOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId", "UserId"); + + b.ToTable("AbpUserRoles"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("uniqueidentifier"); + + b.Property("LoginProvider") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Name") + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AbpUserTokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Code") + .IsRequired() + .HasMaxLength(95) + .HasColumnType("nvarchar(95)") + .HasColumnName("Code"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("DisplayName") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)") + .HasColumnName("DisplayName"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ParentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Code"); + + b.HasIndex("ParentId"); + + b.ToTable("AbpOrganizationUnits"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.Property("OrganizationUnitId") + .HasColumnType("uniqueidentifier"); + + b.Property("RoleId") + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("OrganizationUnitId", "RoleId"); + + b.HasIndex("RoleId", "OrganizationUnitId"); + + b.ToTable("AbpOrganizationUnitRoles"); + }); + + modelBuilder.Entity("Volo.Abp.PermissionManagement.PermissionGrant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpPermissionGrants"); + }); + + modelBuilder.Entity("Volo.Abp.SettingManagement.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("nvarchar(128)"); + + b.Property("ProviderKey") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ProviderName") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2048) + .HasColumnType("nvarchar(2048)"); + + b.HasKey("Id"); + + b.HasIndex("Name", "ProviderName", "ProviderKey"); + + b.ToTable("AbpSettings"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("Name"); + + b.ToTable("AbpTenants"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("nvarchar(1024)"); + + b.HasKey("TenantId", "Name"); + + b.ToTable("AbpTenantConnectionStrings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("DeleterId"); + + b.HasIndex("LastModifierId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("RepliedCommentId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Text") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "RepliedCommentId"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsComments"); + }); + + modelBuilder.Entity("Volo.CmsKit.Contents.Content", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Value") + .IsRequired() + .HasMaxLength(2147483647) + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId"); + + b.ToTable("CmsContents"); + }); + + modelBuilder.Entity("Volo.CmsKit.Pages.Page", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("nvarchar(512)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Url") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Url"); + + b.ToTable("CmsPages"); + }); + + modelBuilder.Entity("Volo.CmsKit.Ratings.Rating", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("StarCount") + .HasColumnType("smallint"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "CreatorId"); + + b.ToTable("CmsRatings"); + }); + + modelBuilder.Entity("Volo.CmsKit.Reactions.UserReaction", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("EntityId") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ReactionName") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "EntityType", "EntityId", "ReactionName"); + + b.HasIndex("TenantId", "CreatorId", "EntityType", "EntityId", "ReactionName"); + + b.ToTable("CmsUserReactions"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.EntityTag", b => + { + b.Property("EntityId") + .HasColumnType("nvarchar(450)"); + + b.Property("TagId") + .HasColumnType("uniqueidentifier"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("EntityId", "TagId"); + + b.HasIndex("TenantId", "EntityId", "TagId"); + + b.ToTable("CmsEntityTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Tags.Tag", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("EntityType") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(32) + .HasColumnType("nvarchar(32)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Name"); + + b.ToTable("CmsTags"); + }); + + modelBuilder.Entity("Volo.CmsKit.Users.CmsUser", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("Email") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("Email"); + + b.Property("EmailConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("EmailConfirmed"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("Name") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Name"); + + b.Property("PhoneNumber") + .HasMaxLength(16) + .HasColumnType("nvarchar(16)") + .HasColumnName("PhoneNumber"); + + b.Property("PhoneNumberConfirmed") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("PhoneNumberConfirmed"); + + b.Property("Surname") + .HasMaxLength(64) + .HasColumnType("nvarchar(64)") + .HasColumnName("Surname"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("UserName") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)") + .HasColumnName("UserName"); + + b.HasKey("Id"); + + b.HasIndex("TenantId", "Email"); + + b.HasIndex("TenantId", "UserName"); + + b.ToTable("CmsUsers"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("Actions") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.AuditLog", null) + .WithMany("EntityChanges") + .HasForeignKey("AuditLogId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b => + { + b.HasOne("Volo.Abp.AuditLogging.EntityChange", null) + .WithMany("PropertyChanges") + .HasForeignKey("EntityChangeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.BlobStoring.Database.DatabaseBlob", b => + { + b.HasOne("Volo.Abp.BlobStoring.Database.DatabaseBlobContainer", null) + .WithMany() + .HasForeignKey("ContainerId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany("Claims") + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserClaim", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Claims") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserLogin", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Logins") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserOrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("OrganizationUnits") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserRole", b => + { + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Roles") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUserToken", b => + { + b.HasOne("Volo.Abp.Identity.IdentityUser", null) + .WithMany("Tokens") + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany() + .HasForeignKey("ParentId"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnitRole", b => + { + b.HasOne("Volo.Abp.Identity.OrganizationUnit", null) + .WithMany("Roles") + .HasForeignKey("OrganizationUnitId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Volo.Abp.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.TenantConnectionString", b => + { + b.HasOne("Volo.Abp.TenantManagement.Tenant", null) + .WithMany("ConnectionStrings") + .HasForeignKey("TenantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.HasOne("Volo.CmsKit.Users.CmsUser", "Deleter") + .WithMany() + .HasForeignKey("DeleterId"); + + b.HasOne("Volo.CmsKit.Users.CmsUser", "LastModifier") + .WithMany() + .HasForeignKey("LastModifierId"); + + b.Navigation("Creator"); + + b.Navigation("Deleter"); + + b.Navigation("LastModifier"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => + { + b.Navigation("Actions"); + + b.Navigation("EntityChanges"); + }); + + modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b => + { + b.Navigation("PropertyChanges"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b => + { + b.Navigation("Claims"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b => + { + b.Navigation("Claims"); + + b.Navigation("Logins"); + + b.Navigation("OrganizationUnits"); + + b.Navigation("Roles"); + + b.Navigation("Tokens"); + }); + + modelBuilder.Entity("Volo.Abp.Identity.OrganizationUnit", b => + { + b.Navigation("Roles"); + }); + + modelBuilder.Entity("Volo.Abp.TenantManagement.Tenant", b => + { + b.Navigation("ConnectionStrings"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.cs new file mode 100644 index 0000000000..d4ee6baf56 --- /dev/null +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/20210209082122_UrlSlugToSlug.cs @@ -0,0 +1,106 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Volo.CmsKit.Migrations +{ + public partial class UrlSlugToSlug : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CmsBlogPosts", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + BlogId = table.Column(type: "uniqueidentifier", nullable: false), + Title = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Slug = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: false), + ShortDescription = table.Column(type: "nvarchar(256)", maxLength: 256, nullable: true), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsBlogPosts", x => x.Id); + table.ForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_CreatorId", + column: x => x.CreatorId, + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_DeleterId", + column: x => x.DeleterId, + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + table.ForeignKey( + name: "FK_CmsBlogPosts_CmsUsers_LastModifierId", + column: x => x.LastModifierId, + principalTable: "CmsUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "CmsBlogs", + columns: table => new + { + Id = table.Column(type: "uniqueidentifier", nullable: false), + Name = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + Slug = table.Column(type: "nvarchar(64)", maxLength: 64, nullable: false), + TenantId = table.Column(type: "uniqueidentifier", nullable: true), + ExtraProperties = table.Column(type: "nvarchar(max)", nullable: true), + ConcurrencyStamp = table.Column(type: "nvarchar(40)", maxLength: 40, nullable: true), + CreationTime = table.Column(type: "datetime2", nullable: false), + CreatorId = table.Column(type: "uniqueidentifier", nullable: true), + LastModificationTime = table.Column(type: "datetime2", nullable: true), + LastModifierId = table.Column(type: "uniqueidentifier", nullable: true), + IsDeleted = table.Column(type: "bit", nullable: false, defaultValue: false), + DeleterId = table.Column(type: "uniqueidentifier", nullable: true), + DeletionTime = table.Column(type: "datetime2", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_CmsBlogs", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_CreatorId", + table: "CmsBlogPosts", + column: "CreatorId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_DeleterId", + table: "CmsBlogPosts", + column: "DeleterId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_LastModifierId", + table: "CmsBlogPosts", + column: "LastModifierId"); + + migrationBuilder.CreateIndex( + name: "IX_CmsBlogPosts_Slug_BlogId", + table: "CmsBlogPosts", + columns: new[] { "Slug", "BlogId" }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CmsBlogPosts"); + + migrationBuilder.DropTable( + name: "CmsBlogs"); + } + } +} diff --git a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs index 074d655f16..bdfc4be963 100644 --- a/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs +++ b/modules/cms-kit/host/Volo.CmsKit.Web.Unified/Migrations/UnifiedDbContextModelSnapshot.cs @@ -19,7 +19,7 @@ namespace Volo.CmsKit.Migrations .UseIdentityColumns() .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.SqlServer) .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("ProductVersion", "5.0.1"); + .HasAnnotation("ProductVersion", "5.0.2"); modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => { @@ -1124,6 +1124,151 @@ namespace Volo.CmsKit.Migrations b.ToTable("AbpTenantConnectionStrings"); }); + modelBuilder.Entity("Volo.CmsKit.Blogs.Blog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.HasKey("Id"); + + b.ToTable("CmsBlogs"); + }); + + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uniqueidentifier"); + + b.Property("BlogId") + .HasColumnType("uniqueidentifier"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasMaxLength(40) + .HasColumnType("nvarchar(40)") + .HasColumnName("ConcurrencyStamp"); + + b.Property("CreationTime") + .HasColumnType("datetime2") + .HasColumnName("CreationTime"); + + b.Property("CreatorId") + .HasColumnType("uniqueidentifier") + .HasColumnName("CreatorId"); + + b.Property("DeleterId") + .HasColumnType("uniqueidentifier") + .HasColumnName("DeleterId"); + + b.Property("DeletionTime") + .HasColumnType("datetime2") + .HasColumnName("DeletionTime"); + + b.Property("ExtraProperties") + .HasColumnType("nvarchar(max)") + .HasColumnName("ExtraProperties"); + + b.Property("IsDeleted") + .ValueGeneratedOnAdd() + .HasColumnType("bit") + .HasDefaultValue(false) + .HasColumnName("IsDeleted"); + + b.Property("LastModificationTime") + .HasColumnType("datetime2") + .HasColumnName("LastModificationTime"); + + b.Property("LastModifierId") + .HasColumnType("uniqueidentifier") + .HasColumnName("LastModifierId"); + + b.Property("ShortDescription") + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(256) + .HasColumnType("nvarchar(256)"); + + b.Property("TenantId") + .HasColumnType("uniqueidentifier") + .HasColumnName("TenantId"); + + b.Property("Title") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("nvarchar(64)"); + + b.HasKey("Id"); + + b.HasIndex("CreatorId"); + + b.HasIndex("DeleterId"); + + b.HasIndex("LastModifierId"); + + b.HasIndex("Slug", "BlogId"); + + b.ToTable("CmsBlogPosts"); + }); + modelBuilder.Entity("Volo.CmsKit.Comments.Comment", b => { b.Property("Id") @@ -1678,6 +1823,27 @@ namespace Volo.CmsKit.Migrations .IsRequired(); }); + modelBuilder.Entity("Volo.CmsKit.Blogs.BlogPost", b => + { + b.HasOne("Volo.CmsKit.Users.CmsUser", "Creator") + .WithMany() + .HasForeignKey("CreatorId"); + + b.HasOne("Volo.CmsKit.Users.CmsUser", "Deleter") + .WithMany() + .HasForeignKey("DeleterId"); + + b.HasOne("Volo.CmsKit.Users.CmsUser", "LastModifier") + .WithMany() + .HasForeignKey("LastModifierId"); + + b.Navigation("Creator"); + + b.Navigation("Deleter"); + + b.Navigation("LastModifier"); + }); + modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b => { b.Navigation("Actions"); From 01077d02be883c43275ffb6605e4b1e346d1f769 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 11:42:24 +0300 Subject: [PATCH 67/70] CmsKit - Reconsider Unidecode at slugs --- .../src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj | 3 ++- .../Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs | 3 ++- .../Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj index 8c5e630f78..f6d895a98d 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo.CmsKit.Domain.csproj @@ -1,4 +1,4 @@ - + @@ -10,6 +10,7 @@ + diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs index 15d3017ffc..9b3908d8cb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs @@ -1,4 +1,5 @@ using Slugify; +using Unidecode.NET; namespace Volo.CmsKit.Blogs.Extensions { @@ -8,7 +9,7 @@ namespace Volo.CmsKit.Blogs.Extensions { var slugHelper = new SlugHelper(); - return slugHelper.GenerateSlug(value); + return slugHelper.GenerateSlug(value?.Unidecode()); } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs index 725d693148..3eb7ee52f7 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using Xunit; using Volo.CmsKit.Blogs.Extensions; using Shouldly; +using Unidecode.NET; namespace Volo.CmsKit.Blogs { @@ -29,7 +30,7 @@ namespace Volo.CmsKit.Blogs { // Arrange var name = "My Perfect Title v.2"; - var expected = "my-perfect-title-v2"; + var expected = "my-perfect-title-v.2"; // Act var actual = name.NormalizeSlug(); @@ -112,8 +113,8 @@ namespace Volo.CmsKit.Blogs public void NormalizeSlug_ShouldWorkProperly_WithChineseChars() { // Arrange - var name = "我的挑战"; - var expected = "o-e-iao-han"; + var name = "我的真棒头衔"; + var expected = "wo-de-zhen-bang-tou-xian"; // Act var actual = name.NormalizeSlug(); From 2fba507644f08e896311de844b0d3607b3e09396 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 16:15:49 +0300 Subject: [PATCH 68/70] CmsKit - Disable PageController temporarily --- .../src/Volo.CmsKit.Public.Web/Controllers/PageController.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs index a2124cbaff..5d3d5acc9c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Controllers/PageController.cs @@ -5,10 +5,13 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Public.Pages; namespace Volo.CmsKit.Public.Web.Controllers { + [RequiresGlobalFeature(typeof(PagesFeature))] public class PageController : CmsKitPublicControllerBase { protected IPageAppService PageAppService { get; } @@ -18,7 +21,7 @@ namespace Volo.CmsKit.Public.Web.Controllers PageAppService = pageAppService; } - [HttpGet("/{*url}", Order = int.MaxValue)] + //[HttpGet("/{*url}", Order = int.MaxValue)] public async Task IndexAsync(string url) { var page = await PageAppService.FindByUrlAsync(url); From 78fe343f06ca3d3532edd6cd751cd37cc5b2a11e Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 9 Feb 2021 16:17:04 +0300 Subject: [PATCH 69/70] CmsKit - Fix typo at IBlogPostRepository.cs --- .../Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs index 3b87fb6522..198cfca104 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogPostRepository.cs @@ -12,7 +12,7 @@ namespace Volo.CmsKit.Blogs { Task SlugExistsAsync(Guid blogId, string slug, CancellationToken cancellationToken = default); - Task GetBySlugAsync(Guid blogId, string Slug, CancellationToken cancellationToken = default); + Task GetBySlugAsync(Guid blogId, string slug, CancellationToken cancellationToken = default); Task> GetPagedListAsync(Guid blogId, int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default); From fb9e8220cbfc62088231c53edc398f37c47c0fb6 Mon Sep 17 00:00:00 2001 From: enisn Date: Wed, 10 Feb 2021 11:17:05 +0300 Subject: [PATCH 70/70] CmsKit - Add missing route in BlogPostPublicController --- .../Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs index 4e14ca31ec..7f3545ad9c 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogPostPublicController.cs @@ -27,6 +27,7 @@ namespace Volo.CmsKit.Public.Blogs } [HttpGet] + [Route("{blogSlug}/{blogPostSlug}")] public Task GetAsync(string blogSlug, string blogPostSlug) { return BlogPostPublicAppService.GetAsync(blogSlug, blogPostSlug); @@ -45,6 +46,7 @@ namespace Volo.CmsKit.Public.Blogs } [HttpGet] + [Route("{blogSlug}")] public Task> GetListAsync(string blogSlug, PagedAndSortedResultRequestDto input) { return BlogPostPublicAppService.GetListAsync(blogSlug, input);