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 97b67416cf..2acd2cdeba 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 @@ -11,5 +11,11 @@ public static int MaxShortDescriptionLength { get; set; } = 256; public const string EntityType = "BlogPost"; + + public const string CommentsFeatureName = "Comments"; + + public const string ReactionsFeatureName = "Reactions"; + + public const string RatingsFeatureName = "Ratings"; } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeature.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeature.cs index 59a26fc1a1..eec8223d89 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeature.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeature.cs @@ -1,4 +1,6 @@ -using System; +using JetBrains.Annotations; +using System; +using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; namespace Volo.CmsKit.Blogs @@ -9,10 +11,10 @@ namespace Volo.CmsKit.Blogs { } - public BlogFeature(Guid blogId, string featureName, bool enabled = true) + public BlogFeature(Guid blogId, [NotNull] string featureName, bool enabled = true) { BlogId = blogId; - FeatureName = featureName; + FeatureName = Check.NotNullOrWhiteSpace(featureName, nameof(featureName)); Enabled = enabled; } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogFeatureRepository.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogFeatureRepository.cs index 622ac33338..b7ba075e92 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogFeatureRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/IBlogFeatureRepository.cs @@ -11,6 +11,8 @@ namespace Volo.CmsKit.Blogs { Task> GetListAsync(Guid blogId); + Task> GetListAsync(Guid blogId, string[] featureNames); + Task FindAsync(Guid blogId, string featureName); } } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogFeatureRepository.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogFeatureRepository.cs index 80b2cbcf12..ee3b7cc4a5 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogFeatureRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/Blogs/EfCoreBlogFeatureRepository.cs @@ -26,5 +26,12 @@ namespace Volo.CmsKit.Blogs .Where(x => x.BlogId == blogId) .ToListAsync(); } + + public async Task> GetListAsync(Guid blogId, string[] featureNames) + { + return await (await GetQueryableAsync()) + .Where(x => x.BlogId == blogId && featureNames.Contains(x.FeatureName)) + .ToListAsync(); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogFeatureRepository.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogFeatureRepository.cs index b369345890..69613c01f2 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogFeatureRepository.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/Blogs/MongoBlogFeatureRepository.cs @@ -28,5 +28,12 @@ namespace Volo.CmsKit.MongoDB.Blogs .Where(x => x.BlogId == blogId) .ToListAsync(); } + + public async Task> GetListAsync(Guid blogId, string[] featureNames) + { + return await (await GetMongoQueryableAsync()) + .Where(x => x.BlogId == blogId && featureNames.Contains(x.FeatureName)) + .ToListAsync(); + } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogFeatureDto.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogFeatureDto.cs new file mode 100644 index 0000000000..8fb4aa1fd5 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/BlogFeatureDto.cs @@ -0,0 +1,11 @@ +using System; +using Volo.Abp.Application.Dtos; + +namespace Volo.CmsKit.Public.Blogs +{ + public class BlogFeatureDto : EntityDto + { + public string FeatureName { get; set; } + public bool Enabled { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/GetBlogFeatureInput.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/GetBlogFeatureInput.cs new file mode 100644 index 0000000000..a98dfbc264 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/GetBlogFeatureInput.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Public.Blogs +{ + public class GetBlogFeatureInput + { + public string[] FeatureNames { get; set; } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogFeaturePublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogFeaturePublicAppService.cs new file mode 100644 index 0000000000..017da5d2d3 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application.Contracts/Volo/CmsKit/Public/Blogs/IBlogFeaturePublicAppService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Public.Blogs +{ + public interface IBlogFeaturePublicAppService + { + Task GetAsync(Guid blogId, string featureName); + + Task> GetManyAsync(Guid blogId, GetBlogFeatureInput input); + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj index 702523e3c6..5460e29406 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo.CmsKit.Public.Application.csproj @@ -11,6 +11,7 @@ + diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogFeaturePublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogFeaturePublicAppService.cs new file mode 100644 index 0000000000..7cc9088a81 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Blogs/BlogFeaturePublicAppService.cs @@ -0,0 +1,61 @@ +using Microsoft.Extensions.Caching.Distributed; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp.Caching; +using Volo.CmsKit.Blogs; + +namespace Volo.CmsKit.Public.Blogs +{ + public class BlogFeaturePublicAppService : CmsKitPublicAppServiceBase, IBlogFeaturePublicAppService + { + protected IBlogFeatureRepository BlogFeatureRepository { get; } + protected IDistributedCache Cache { get; } + + public BlogFeaturePublicAppService( + IBlogFeatureRepository blogFeatureRepository, + IDistributedCache cache) + { + BlogFeatureRepository = blogFeatureRepository; + Cache = cache; + } + + public async Task GetAsync(Guid blogId, string featureName) + { + return await Cache.GetOrAddAsync( + $"{blogId}_{featureName}", + () => GetFromDatabaseAsync(blogId, featureName), + () => new DistributedCacheEntryOptions + { + AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(1) + }); + } + + private async Task GetFromDatabaseAsync(Guid blogId, string featureName) + { + var feature = await BlogFeatureRepository.FindAsync(blogId, featureName); + if (feature == null) + { + feature = new BlogFeature(blogId, featureName); + } + + return ObjectMapper.Map(feature); + } + + public async Task> GetManyAsync(Guid blogId, GetBlogFeatureInput input) + { + var features = await BlogFeatureRepository.GetListAsync(blogId); + + var nonExistingFeatures = input.FeatureNames.Where(x => !features.Any(a => a.FeatureName == x)); + + foreach (var featureName in nonExistingFeatures) + { + features.Add(new BlogFeature(blogId, featureName)); + } + + return ObjectMapper.Map, List>(features); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/CmsKitPublicApplicationModule.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/CmsKitPublicApplicationModule.cs index c8cda19e68..ede4a7ef29 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/CmsKitPublicApplicationModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/CmsKitPublicApplicationModule.cs @@ -1,12 +1,14 @@ using Microsoft.Extensions.DependencyInjection; using Volo.Abp.AutoMapper; +using Volo.Abp.Caching; using Volo.Abp.Modularity; namespace Volo.CmsKit.Public { [DependsOn( typeof(CmsKitCommonApplicationModule), - typeof(CmsKitPublicApplicationContractsModule) + typeof(CmsKitPublicApplicationContractsModule), + typeof(AbpCachingModule) )] public class CmsKitPublicApplicationModule : AbpModule { 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 46dab5a9a1..ee8a09e8df 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 @@ -34,6 +34,8 @@ namespace Volo.CmsKit.Public CreateMap(); CreateMap(MemberList.None); + + CreateMap(); } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogFeaturePublicController.cs b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogFeaturePublicController.cs new file mode 100644 index 0000000000..2dd480b78f --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Public.HttpApi/Volo/CmsKit/Public/Blogs/BlogFeaturePublicController.cs @@ -0,0 +1,34 @@ +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.HttpApi.Volo.CmsKit.Public.Blogs +{ + public class BlogFeaturePublicController : CmsKitPublicControllerBase, IBlogFeaturePublicAppService + { + protected IBlogFeaturePublicAppService BlogFeaturePublicAppService { get; } + + public BlogFeaturePublicController(IBlogFeaturePublicAppService blogFeaturePublicAppService) + { + BlogFeaturePublicAppService = blogFeaturePublicAppService; + } + + [HttpGet] + [Route("{blogId}/{featureName}")] + public Task GetAsync(Guid blogId, string featureName) + { + return BlogFeaturePublicAppService.GetAsync(blogId, featureName); + } + + [HttpGet] + [Route("{blogId}")] + public Task> GetManyAsync(Guid blogId, GetBlogFeatureInput input) + { + return BlogFeaturePublicAppService.GetManyAsync(blogId, input); + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml index 51472ce7c1..763b5ac36b 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 @@ -35,29 +35,39 @@ @if (GlobalFeatureManager.Instance.IsEnabled()) { - @await Component.InvokeAsync(typeof(ReactionSelectionViewComponent), new + if (Model.ReactionsFeature?.Enabled == true) { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() - }) + @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 + if (Model.RatingsFeature?.Enabled == true) { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() - }) + @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 + if (Model.CommentsFeature?.Enabled == true) { - entityType = Volo.CmsKit.Blogs.BlogPostConsts.EntityType, - entityId = Model.BlogPost.Id.ToString() - }) + @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 index a3f31bb9a2..7c3fb4fa64 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Web/Pages/CmsKit/Blogs/BlogPost.cshtml.cs @@ -2,8 +2,12 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; +using Volo.Abp.GlobalFeatures; +using Volo.CmsKit.Blogs; +using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Public.Blogs; namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs @@ -18,16 +22,42 @@ namespace Volo.CmsKit.Public.Web.Pages.CmsKit.Blogs public BlogPostPublicDto BlogPost { get; private set; } + public BlogFeatureDto CommentsFeature { get; private set; } + + public BlogFeatureDto ReactionsFeature { get; private set; } + + public BlogFeatureDto RatingsFeature { get; private set; } + protected IBlogPostPublicAppService BlogPostPublicAppService { get; } - public BlogPostModel(IBlogPostPublicAppService blogPostPublicAppService) + protected IBlogFeaturePublicAppService BlogFeaturePublicAppService { get; } + + public BlogPostModel( + IBlogPostPublicAppService blogPostPublicAppService, + IBlogFeaturePublicAppService blogFeaturePublicAppService) { BlogPostPublicAppService = blogPostPublicAppService; + BlogFeaturePublicAppService = blogFeaturePublicAppService; } - public async Task OnGetAsync() + public virtual async Task OnGetAsync() { BlogPost = await BlogPostPublicAppService.GetAsync(BlogSlug, BlogPostSlug); + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + CommentsFeature = await BlogFeaturePublicAppService.GetAsync(BlogPost.Id, BlogPostConsts.CommentsFeatureName); + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + ReactionsFeature = await BlogFeaturePublicAppService.GetAsync(BlogPost.Id, BlogPostConsts.ReactionsFeatureName); + } + + if (GlobalFeatureManager.Instance.IsEnabled()) + { + RatingsFeature = await BlogFeaturePublicAppService.GetAsync(BlogPost.Id, BlogPostConsts.RatingsFeatureName); + } } } }