From 85cab4311d9123cff63816ace7bfb685727533c8 Mon Sep 17 00:00:00 2001 From: enisn Date: Tue, 2 Feb 2021 15:47:44 +0300 Subject: [PATCH 01/12] 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 02/12] 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 03/12] 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 04/12] 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 25d5df54864936c8aa496cf32e80b41beb5357ba Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 10:03:22 +0300 Subject: [PATCH 05/12] 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 9c742d7eac6f9aceccce51888e426c3f6182e375 Mon Sep 17 00:00:00 2001 From: enisn Date: Thu, 4 Feb 2021 14:54:08 +0300 Subject: [PATCH 06/12] 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 07/12] 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 08/12] 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 09/12] 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 10/12] 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 11/12] 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 12/12] 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,