diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs index 174278d829..24d5c1d894 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/CreatePageInputDto.cs @@ -1,7 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; using Volo.Abp.Validation; -using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; namespace Volo.CmsKit.Admin.Pages diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs index eff3cb2919..58dbd71516 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application.Contracts/Volo/CmsKit/Admin/Pages/UpdatePageInputDto.cs @@ -1,7 +1,6 @@ using System; using System.ComponentModel.DataAnnotations; using Volo.Abp.Validation; -using Volo.CmsKit.Contents; using Volo.CmsKit.Pages; namespace Volo.CmsKit.Admin.Pages diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs index 574f6f737a..a803ea8695 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogAdminAppService.cs @@ -16,13 +16,18 @@ namespace Volo.CmsKit.Admin.Blogs { protected IBlogRepository BlogRepository { get; } protected BlogManager BlogManager { get; } - - public BlogAdminAppService(IBlogRepository blogRepository, BlogManager blogManager) + protected BlogFeatureManager BlogFeatureManager{ get; } + + public BlogAdminAppService( + IBlogRepository blogRepository, + BlogManager blogManager, + BlogFeatureManager blogFeatureManager = null) { BlogRepository = blogRepository; BlogManager = blogManager; + BlogFeatureManager = blogFeatureManager; } - + public virtual async Task GetAsync(Guid id) { var blog = await BlogRepository.GetAsync(id); @@ -48,7 +53,9 @@ namespace Volo.CmsKit.Admin.Blogs { var blog = await BlogManager.CreateAsync(input.Name, input.Slug); - await BlogRepository.InsertAsync(blog); + await BlogRepository.InsertAsync(blog, autoSave: true); + + await BlogFeatureManager.SetDefaultsAsync(blog.Id); return ObjectMapper.Map(blog); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminAppService.cs index d074d1f455..a0ba1c460e 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Blogs/BlogFeatureAdminAppService.cs @@ -1,12 +1,9 @@ using Microsoft.AspNetCore.Authorization; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Volo.Abp.EventBus.Distributed; using Volo.Abp.GlobalFeatures; -using Volo.CmsKit.Admin.Blogs; using Volo.CmsKit.Blogs; using Volo.CmsKit.GlobalFeatures; using Volo.CmsKit.Permissions; @@ -14,6 +11,7 @@ using Volo.CmsKit.Permissions; namespace Volo.CmsKit.Admin.Blogs { [RequiresGlobalFeature(typeof(BlogsFeature))] + [Authorize(CmsKitAdminPermissions.Blogs.Features)] public class BlogFeatureAdminAppService : CmsKitAdminAppServiceBase, IBlogFeatureAdminAppService { protected IBlogFeatureRepository BlogFeatureRepository { get; } @@ -32,15 +30,13 @@ namespace Volo.CmsKit.Admin.Blogs EventBus = eventBus; } - [Authorize(CmsKitAdminPermissions.Blogs.Features)] public virtual async Task> GetListAsync(Guid blogId) { - var blogFeatures = await BlogFeatureManager.GetListAsync(blogId); + var blogFeatures = await BlogFeatureRepository.GetListAsync(blogId); return ObjectMapper.Map, List>(blogFeatures); } - [Authorize(CmsKitAdminPermissions.Blogs.Features)] public virtual Task SetAsync(Guid blogId, BlogFeatureInputDto dto) { return BlogFeatureManager.SetAsync(blogId, dto.FeatureName, dto.IsEnabled); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs index ab7d841cad..8ea11bd3c8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/MediaDescriptors/MediaDescriptorAdminAppService.cs @@ -33,6 +33,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors { var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(inputStream.EntityType); + /* TODO: Shouldn't CreatePolicies be a dictionary and we check for inputStream.EntityType? */ await CheckAnyOfPoliciesAsync(definition.CreatePolicies); using (var stream = inputStream.GetStream()) @@ -52,6 +53,7 @@ namespace Volo.CmsKit.Admin.MediaDescriptors var definition = await MediaDescriptorDefinitionStore.GetDefinitionAsync(mediaDescriptor.EntityType); + /* TODO: Shouldn't DeletePolicies be a dictionary and we check for inputStream.EntityType? */ await CheckAnyOfPoliciesAsync(definition.DeletePolicies); await MediaContainer.DeleteAsync(id.ToString()); diff --git a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs index 102b2a6afd..3d025d1463 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Admin.Application/Volo/CmsKit/Admin/Pages/PageAdminAppService.cs @@ -16,10 +16,15 @@ namespace Volo.CmsKit.Admin.Pages public class PageAdminAppService : CmsKitAdminAppServiceBase, IPageAdminAppService { protected IPageRepository PageRepository { get; } - - public PageAdminAppService(IPageRepository pageRepository) + + protected PageManager PageManager { get; } + + public PageAdminAppService( + IPageRepository pageRepository, + PageManager pageManager) { PageRepository = pageRepository; + PageManager = pageManager; } public virtual async Task GetAsync(Guid id) @@ -48,9 +53,7 @@ namespace Volo.CmsKit.Admin.Pages [Authorize(CmsKitAdminPermissions.Pages.Create)] public virtual async Task CreateAsync(CreatePageInputDto input) { - await CheckPageSlugAsync(input.Slug); - - var page = new Page(GuidGenerator.Create(), input.Title, input.Slug, input.Content, CurrentTenant.Id); + var page = await PageManager.CreateAsync(input.Title, input.Slug, input.Content); await PageRepository.InsertAsync(page); @@ -62,13 +65,9 @@ namespace Volo.CmsKit.Admin.Pages { var page = await PageRepository.GetAsync(id); - if (page.Slug != input.Slug) - { - await CheckPageSlugAsync(input.Slug); - } + await PageManager.SetSlugAsync(page, input.Slug); page.SetTitle(input.Title); - page.SetSlug(input.Slug); page.SetContent(input.Content); await PageRepository.UpdateAsync(page); @@ -81,13 +80,5 @@ namespace Volo.CmsKit.Admin.Pages { await PageRepository.DeleteAsync(id); } - - protected virtual async Task CheckPageSlugAsync(string slug) - { - if (await PageRepository.ExistsAsync(slug)) - { - throw new PageSlugAlreadyExistsException(slug); - } - } } } 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 976a3d0e4e..aff12d05c1 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 @@ -1,7 +1,5 @@ using AutoMapper; using Volo.CmsKit.Blogs; -using Volo.CmsKit.Contents; -using Volo.CmsKit.Pages; using Volo.CmsKit.Tags; using Volo.CmsKit.Users; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs index 064c504fb4..39e9ba4784 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/CmsKitErrorCodes.cs @@ -8,8 +8,6 @@ public const string EntityNotTaggable = "CmsKit:Tag:0002"; } - public const string ContentAlreadyExist = "CmsKit:0002"; - public static class Pages { public const string SlugAlreadyExist = "CmsKit:Page:0001"; diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Contents/ContentConsts.cs b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Contents/ContentConsts.cs deleted file mode 100644 index d6d69a6a39..0000000000 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Contents/ContentConsts.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using Volo.CmsKit.Entities; - -namespace Volo.CmsKit.Contents -{ - public static class ContentConsts - { - public static int MaxEntityTypeLength { get; set; } = CmsEntityConsts.MaxEntityTypeLength; - - public static int MaxEntityIdLength { get; set; } = CmsEntityConsts.MaxEntityIdLength; - - // TODO: consider - public static int MaxValueLength { get; set; } = int.MaxValue; - } -} \ No newline at end of file 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 313b282a1f..9d800abbdb 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Blog.cs @@ -3,7 +3,6 @@ using System; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; -using Volo.CmsKit.Blogs.Extensions; namespace Volo.CmsKit.Blogs { @@ -17,7 +16,12 @@ namespace Volo.CmsKit.Blogs public virtual Guid? TenantId { get; protected set; } - protected internal Blog(Guid id, [NotNull] string name, [NotNull] string slug, [CanBeNull] Guid? tenantId = null) : base(id) + protected internal Blog( + Guid id, + [NotNull] string name, + [NotNull] string slug, + [CanBeNull] Guid? tenantId = null + ) : base(id) { SetName(name); SetSlug(slug); @@ -33,7 +37,7 @@ namespace Volo.CmsKit.Blogs { Check.NotNullOrWhiteSpace(slug, nameof(slug), BlogConsts.MaxNameLength); - Slug = slug.NormalizeSlug(); + Slug = SlugNormalizer.Normalize(slug); } } } 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 8ec02a1875..e1bb05fa3f 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 @@ -5,13 +5,13 @@ using Volo.Abp.Domain.Entities.Auditing; namespace Volo.CmsKit.Blogs { - public class BlogFeature : FullAuditedAggregateRoot, IEquatable + public class BlogFeature : FullAuditedAggregateRoot { public Guid BlogId { get; protected set; } public string FeatureName { get; protected set; } - public bool IsEnabled { get; set; } = true; + public bool IsEnabled { get; protected internal set; } public BlogFeature(Guid blogId, [NotNull] string featureName, bool isEnabled = true) { @@ -19,10 +19,5 @@ namespace Volo.CmsKit.Blogs FeatureName = Check.NotNullOrWhiteSpace(featureName, nameof(featureName)); IsEnabled = isEnabled; } - - public bool Equals(BlogFeature other) - { - return BlogId == other?.BlogId && FeatureName == other?.FeatureName; - } } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeatureManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeatureManager.cs index 809a7ab9d2..cea6d894f0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeatureManager.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogFeatureManager.cs @@ -1,10 +1,8 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Volo.Abp.Domain.Services; -using Volo.Abp.EventBus.Distributed; -using Volo.Abp.EventBus.Local; -using Volo.Abp.Uow; namespace Volo.CmsKit.Blogs { @@ -22,17 +20,6 @@ namespace Volo.CmsKit.Blogs DefaultBlogFeatureProvider = defaultBlogFeatureProvider; } - public async Task> GetListAsync(Guid blogId) - { - var blogFeatures = await BlogFeatureRepository.GetListAsync(blogId); - - var defaultFeatures = await DefaultBlogFeatureProvider.GetDefaultFeaturesAsync(blogId); - - defaultFeatures.ForEach(x => blogFeatures.AddIfNotContains(x)); - - return blogFeatures; - } - public async Task SetAsync(Guid blogId, string featureName, bool isEnabled) { var blogFeature = await BlogFeatureRepository.FindAsync(blogId, featureName); @@ -47,5 +34,15 @@ namespace Volo.CmsKit.Blogs await BlogFeatureRepository.UpdateAsync(blogFeature); } } + + public async Task SetDefaultsAsync(Guid blogId) + { + var defaultFeatures = await DefaultBlogFeatureProvider.GetDefaultFeaturesAsync(blogId); + + foreach (var feature in defaultFeatures) + { + await SetAsync(blogId, feature.FeatureName, isEnabled: true); + } + } } } 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 7dda50ca9a..4d81a322be 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPost.cs @@ -3,7 +3,6 @@ using System; using Volo.Abp; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; -using Volo.CmsKit.Blogs.Extensions; using Volo.CmsKit.Users; namespace Volo.CmsKit.Blogs @@ -65,7 +64,7 @@ namespace Volo.CmsKit.Blogs { Check.NotNullOrWhiteSpace(slug, nameof(slug), BlogPostConsts.MaxSlugLength, BlogPostConsts.MinSlugLength); - Slug = slug.NormalizeSlug(); + Slug = SlugNormalizer.Normalize(slug); } public virtual void SetShortDescription(string shortDescription) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostManager.cs index cce076b74b..e51108fc9a 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 @@ -12,13 +12,17 @@ namespace Volo.CmsKit.Blogs { protected IBlogPostRepository BlogPostRepository { get; } protected IBlogRepository BlogRepository { get; } + protected IDefaultBlogFeatureProvider BlogFeatureProvider { get; } + public BlogPostManager( IBlogPostRepository blogPostRepository, - IBlogRepository blogRepository) + IBlogRepository blogRepository, + IDefaultBlogFeatureProvider blogFeatureProvider) { BlogPostRepository = blogPostRepository; BlogRepository = blogRepository; + BlogFeatureProvider = blogFeatureProvider; } public virtual async Task CreateAsync( @@ -35,8 +39,6 @@ namespace Volo.CmsKit.Blogs Check.NotNullOrEmpty(title, nameof(title)); Check.NotNullOrEmpty(slug, nameof(slug)); - await CheckBlogExistenceAsync(blog.Id); - var blogPost = new BlogPost( GuidGenerator.Create(), blog.Id, diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs index a2cdf68f39..16fae16735 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogPostSlugAlreadyExistException.cs @@ -6,11 +6,8 @@ namespace Volo.CmsKit.Blogs { public class BlogPostSlugAlreadyExistException : BusinessException { - internal BlogPostSlugAlreadyExistException(string code = null, string message = null, string details = null, Exception innerException = null, Microsoft.Extensions.Logging.LogLevel logLevel = Microsoft.Extensions.Logging.LogLevel.Warning) : base(code, message, details, innerException, logLevel) - { - } - - internal BlogPostSlugAlreadyExistException(SerializationInfo serializationInfo, System.Runtime.Serialization.StreamingContext context) : base(serializationInfo, context) + public BlogPostSlugAlreadyExistException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) { } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogSlugAlreadyExistException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogSlugAlreadyExistException.cs index e50f2f623c..1adb95ac33 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogSlugAlreadyExistException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/BlogSlugAlreadyExistException.cs @@ -8,14 +8,13 @@ namespace Volo.CmsKit.Blogs public class BlogSlugAlreadyExistException : BusinessException { public BlogSlugAlreadyExistException(string slug) + : base(code: CmsKitErrorCodes.Blogs.SlugAlreadyExists) { - Code = CmsKitErrorCodes.Blogs.SlugAlreadyExists; - WithData(nameof(Blog.Slug), slug); } - public BlogSlugAlreadyExistException( - SerializationInfo serializationInfo, StreamingContext context) : base(serializationInfo, context) + public BlogSlugAlreadyExistException(SerializationInfo serializationInfo, StreamingContext context) + : base(serializationInfo, context) { } } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs index cb189571f7..5779106a94 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/CmsKitDomainModule.cs @@ -39,11 +39,6 @@ namespace Volo.CmsKit options.Reactions.AddOrReplace(StandardReactions.Pray); }); - - if (GlobalFeatureManager.Instance.IsEnabled()) - { - // TODO: Configure TagEntityTypes here... - } } private static LocalizableString L(string name) diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs index 752f921da7..e3caed9904 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/DefaultMediaDescriptorDefinitionStore.cs @@ -29,17 +29,20 @@ namespace Volo.CmsKit.MediaDescriptors { Check.NotNullOrWhiteSpace(entityType, nameof(entityType)); - var result = Options.EntityTypes.SingleOrDefault(x => x.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase)) ?? - throw new EntityCantHaveMediaException(entityType); + var definition = Options.EntityTypes.SingleOrDefault( + x => x.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase) + ) ?? throw new EntityCantHaveMediaException(entityType); - return Task.FromResult(result); + return Task.FromResult(definition); } public virtual Task IsDefinedAsync([NotNull] string entityType) { Check.NotNullOrEmpty(entityType, nameof(entityType)); - var isDefined = Options.EntityTypes.Any(a => a.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase)); + var isDefined = Options.EntityTypes.Any( + a => a.EntityType.Equals(entityType, StringComparison.InvariantCultureIgnoreCase) + ); return Task.FromResult(isDefined); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs index 29d60126a1..911e8d2366 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/MediaDescriptors/EntityCantHaveMediaException.cs @@ -9,10 +9,10 @@ namespace Volo.CmsKit.MediaDescriptors { } - public EntityCantHaveMediaException(string entityType) + public EntityCantHaveMediaException(string entityType) + : base(code: CmsKitErrorCodes.MediaDescriptors.EntityTypeDoesntExist) { EntityType = entityType; - Code = CmsKitErrorCodes.MediaDescriptors.EntityTypeDoesntExist; WithData(nameof(entityType), EntityType); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs index dd759ebd08..409d504952 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/Page.cs @@ -20,7 +20,7 @@ namespace Volo.CmsKit.Pages { } - public Page(Guid id, [NotNull] string title, [NotNull] string slug, string content = null, Guid? tenantId = null) : base(id) + internal Page(Guid id, [NotNull] string title, [NotNull] string slug, string content = null, Guid? tenantId = null) : base(id) { TenantId = tenantId; @@ -34,7 +34,7 @@ namespace Volo.CmsKit.Pages Title = Check.NotNullOrEmpty(title, nameof(title), PageConsts.MaxTitleLength); } - public virtual void SetSlug(string slug) + internal virtual void SetSlug(string slug) { Slug = Check.NotNullOrEmpty(slug, nameof(slug), PageConsts.MaxSlugLength); } diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs new file mode 100644 index 0000000000..c150e69e52 --- /dev/null +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Pages/PageManager.cs @@ -0,0 +1,56 @@ +using JetBrains.Annotations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Domain.Services; + +namespace Volo.CmsKit.Pages +{ + public class PageManager : DomainService + { + protected IPageRepository PageRepository { get; } + + public PageManager(IPageRepository pageRepository) + { + PageRepository = pageRepository; + } + + public virtual async Task CreateAsync( + [NotNull] string title, + [NotNull] string slug, + [CanBeNull] string content = null) + { + Check.NotNullOrEmpty(title, nameof(title)); + Check.NotNullOrEmpty(slug, nameof(slug)); + + await CheckPageSlugAsync(slug); + + return new Page( + GuidGenerator.Create(), + title, + slug, + content, + CurrentTenant.Id); + } + + public virtual async Task SetSlugAsync(Page page, string newSlug) + { + if (page.Slug != newSlug) + { + await CheckPageSlugAsync(newSlug); + page.SetSlug(newSlug); + } + } + + protected virtual async Task CheckPageSlugAsync(string slug) + { + if (await PageRepository.ExistsAsync(slug)) + { + throw new PageSlugAlreadyExistsException(slug); + } + } + } +} diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/SlugNormalizer.cs similarity index 58% rename from modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs rename to modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/SlugNormalizer.cs index a625d4687f..30b23e4ba4 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/Blogs/Extensions/SlugExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Domain/Volo/CmsKit/SlugNormalizer.cs @@ -1,12 +1,12 @@ using Slugify; using Unidecode.NET; -namespace Volo.CmsKit.Blogs.Extensions +namespace Volo.CmsKit { - public static class SlugExtensions + public static class SlugNormalizer { static readonly SlugHelper SlugHelper = new (); - public static string NormalizeSlug(this string value) + public static string Normalize(string value) { return SlugHelper.GenerateSlug(value?.Unidecode()); } 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 81cc527800..e6e35720f6 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 @@ -33,7 +33,7 @@ namespace Volo.CmsKit.Blogs blogPost.Author = await (await GetDbContextAsync()) .Set() - .FirstOrDefaultAsync(x =>x.Id == blogPost.AuthorId); + .FirstOrDefaultAsync(x =>x.Id == blogPost.AuthorId, GetCancellationToken(cancellationToken)); return blogPost; } diff --git a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs index 0bbb9ea58b..dd8e11f1f0 100644 --- a/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs +++ b/modules/cms-kit/src/Volo.CmsKit.EntityFrameworkCore/Volo/CmsKit/EntityFrameworkCore/CmsKitEntityFrameworkCoreModule.cs @@ -4,7 +4,6 @@ using Volo.Abp.Modularity; using Volo.Abp.Users.EntityFrameworkCore; using Volo.CmsKit.Blogs; using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs index 4d8f86b823..7034b37f98 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContext.cs @@ -1,9 +1,8 @@ using MongoDB.Driver; using Volo.Abp.Data; using Volo.Abp.MongoDB; -using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Comments; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs index 8585f988f9..e96ed841a8 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/CmsKitMongoDbContextExtensions.cs @@ -1,9 +1,8 @@ using System; using Volo.Abp; using Volo.Abp.MongoDB; -using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Comments; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; diff --git a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs index 5110bca501..1dbbfc0f98 100644 --- a/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs +++ b/modules/cms-kit/src/Volo.CmsKit.MongoDB/Volo/CmsKit/MongoDB/ICmsKitMongoDbContext.cs @@ -1,9 +1,8 @@ using MongoDB.Driver; using Volo.Abp.Data; using Volo.Abp.MongoDB; -using Volo.CmsKit.Comments; -using Volo.CmsKit.Contents; using Volo.CmsKit.Blogs; +using Volo.CmsKit.Comments; using Volo.CmsKit.MediaDescriptors; using Volo.CmsKit.Pages; using Volo.CmsKit.Ratings; diff --git a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs index d5dd555b71..f716660d23 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs +++ b/modules/cms-kit/src/Volo.CmsKit.Public.Application/Volo/CmsKit/Public/Comments/CommentPublicAppService.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Options; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Application.Services; +using Volo.Abp.Authorization; using Volo.Abp.EventBus.Distributed; using Volo.Abp.Uow; using Volo.Abp.Users; @@ -85,7 +86,7 @@ namespace Volo.CmsKit.Public.Comments if (comment.CreatorId != CurrentUser.GetId()) { - throw new BusinessException(); //TODO: AbpAuthorizationException! + throw new AbpAuthorizationException(); } comment.SetText(input.Text); @@ -102,7 +103,7 @@ namespace Volo.CmsKit.Public.Comments if (comment.CreatorId != CurrentUser.GetId()) { - throw new BusinessException(); //TODO: AbpAuthorizationException! + throw new AbpAuthorizationException(); } await CommentRepository.DeleteWithRepliesAsync(comment); diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogFeatureAdminAppService_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogFeatureAdminAppService_Test.cs index 54ce2d6de5..56bf3d2cd3 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogFeatureAdminAppService_Test.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Blogs/BlogFeatureAdminAppService_Test.cs @@ -61,7 +61,7 @@ namespace Volo.CmsKit.Blogs result.ShouldNotBeNull(); result.ShouldNotBeEmpty(); - result.Count.ShouldBeGreaterThan(2); // 2 are seeded and there are built-in Features. + result.Count.ShouldBeGreaterThanOrEqualTo(2); // 2 are seeded and there are built-in Features. } } } diff --git a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs index 766c482ddd..60ee25f28d 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Application.Tests/Pages/PageAdminAppService_Tests.cs @@ -1,10 +1,8 @@ -using System; +using Shouldly; +using System; using System.Linq; using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Uow; using Volo.CmsKit.Admin.Pages; -using Volo.CmsKit.Contents; using Xunit; namespace Volo.CmsKit.Pages diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs index 3eb7ee52f7..268cfbab71 100644 --- a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Blogs/SlugExtensions_Tests.cs @@ -1,12 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using Shouldly; using Xunit; -using Volo.CmsKit.Blogs.Extensions; -using Shouldly; -using Unidecode.NET; namespace Volo.CmsKit.Blogs { @@ -20,7 +13,7 @@ namespace Volo.CmsKit.Blogs var expected = "my-awesome-name"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -33,7 +26,7 @@ namespace Volo.CmsKit.Blogs var expected = "my-perfect-title-v.2"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -47,7 +40,7 @@ namespace Volo.CmsKit.Blogs var expected = "are-you-gonna-die"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -61,7 +54,7 @@ namespace Volo.CmsKit.Blogs var expected = "we-machines-challenge"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -75,7 +68,7 @@ namespace Volo.CmsKit.Blogs var expected = "go-and-code-part-2"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -89,7 +82,7 @@ namespace Volo.CmsKit.Blogs var expected = "moe-klassnoe-nazvanie"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -103,7 +96,7 @@ namespace Volo.CmsKit.Blogs var expected = "ozel-turkce-karakterler-gusioc"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -117,7 +110,7 @@ namespace Volo.CmsKit.Blogs var expected = "wo-de-zhen-bang-tou-xian"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); @@ -131,7 +124,7 @@ namespace Volo.CmsKit.Blogs var expected = "lets-rock"; // Act - var actual = name.NormalizeSlug(); + var actual = SlugNormalizer.Normalize(name); // Assert actual.ShouldBe(expected); diff --git a/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs new file mode 100644 index 0000000000..10dc874399 --- /dev/null +++ b/modules/cms-kit/test/Volo.CmsKit.Domain.Tests/Pages/PageManager_Test.cs @@ -0,0 +1,70 @@ +using Shouldly; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Volo.CmsKit.Pages +{ + public class PageManager_Test : CmsKitDomainTestBase + { + private readonly PageManager pageManager; + private readonly CmsKitTestData testData; + private readonly IPageRepository pageRepository; + + public PageManager_Test() + { + pageManager = GetRequiredService(); + testData = GetRequiredService(); + pageRepository = GetRequiredService(); + } + + public async Task CreateAsync_ShouldWorkProperly_WithNonExistingSlug() + { + var title = "My awesome page"; + var slug = "my-awesome-page"; + var content = "

My Awesome Page

This is my awesome page content!

"; + + var page = await pageManager.CreateAsync(title, slug, content); + + page.ShouldNotBeNull(); + page.Title.ShouldBe(title); + page.Slug.ShouldBe(slug); + page.Content.ShouldBe(content); + } + + public async Task CreateAsync_ShouldThrowException_WithExistingSlug() + { + var title = "My awesome page"; + var slug = testData.Page_1_Slug; + var content = "

My Awesome Page

This is my awesome page content!

"; + + var exception = await Should.ThrowAsync(async () => + await pageManager.CreateAsync(title, slug, content)); + + exception.ShouldNotBeNull(); + } + + public async Task SetSlugAsync_ShouldWorkProperly_WithNonExistingSlug() + { + var newSlug = "freshly-generated-new-slug"; + var page = await pageRepository.GetAsync(testData.Page_1_Id); + + await pageManager.SetSlugAsync(page, newSlug); + + page.Slug.ShouldBe(newSlug); + } + + public async Task SetSlugAsync_ShouldThrowException_WithExistingSlug() + { + var newSlug = testData.Page_2_Slug; + var page = await pageRepository.GetAsync(testData.Page_1_Id); + + var exception = await Should.ThrowAsync(async () => + await pageManager.SetSlugAsync(page, newSlug)); + + exception.ShouldNotBeNull(); + } + } +}