using Microsoft.Extensions.Options; using Netina.Domain.Entities.Blogs; using System.Web; namespace Netina.Api.Controllers; public class BlogController : ICarterModule { public virtual void AddRoutes(IEndpointRouteBuilder app) { var group = app.NewVersionedApi("Blog") .MapGroup($"api/blog"); group.MapGet("", GetAllAsync) .WithDisplayName("GetAllBlogs") .HasApiVersion(1.0); group.MapGet("{id}", GetAsync) .WithDisplayName("GetBlog") .HasApiVersion(1.0); group.MapPost("", Post) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); group.MapPut("", Put) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); group.MapDelete("{id}", Delete) .RequireAuthorization(builder => builder.AddAuthenticationSchemes("Bearer").RequireAuthenticatedUser() .RequireClaim(CustomClaimType.Permission, ApplicationPermission.ManageBlogs)) .HasApiVersion(1.0); group.MapGet("/newlink", GetBlogNewLinkAsync) .WithDisplayName("GetBlogNewLink") .HasApiVersion(1.0); } private async Task GetBlogNewLinkAsync([FromQuery]string slug,IRepositoryWrapper repositoryWrapper,IOptionsSnapshot snapshot,CancellationToken cancellationToken) { var htmlSlug = HttpUtility.UrlEncode(slug); var blog = await repositoryWrapper.SetRepository() .TableNoTracking .FirstOrDefaultAsync(b => b.Slug== htmlSlug, cancellationToken); if (blog == null) throw new BaseApiException(ApiResultStatusCode.NotFound, "Blog not found"); var website = snapshot.Value.WebSiteUrl; var response = $"{website}/blogs/{blog.Id}/{blog.Slug}"; return TypedResults.Content(response); } // GET:Get All Entity public async Task GetAllAsync([FromQuery] int page, [FromQuery]int? count, [FromQuery] Guid? blogCategoryId, [FromQuery]string? blogName, IMediator mediator, CancellationToken cancellationToken) => TypedResults.Ok(await mediator.Send(new GetBlogsQuery(page,Count: count, CategoryId: blogCategoryId,BlogName: blogName), cancellationToken)); // GET:Get An Entity By Id public async Task GetAsync(Guid id, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) { var dto = await repositoryWrapper.SetRepository().TableNoTracking .Where(b => b.Id == id) .Select(BlogMapper.ProjectToLDto) .FirstOrDefaultAsync(cancellationToken); return TypedResults.Ok(dto); } // POST:Create Entity public async Task Post([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) { var ent = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested,dto.CategoryId); foreach (var file in dto.Files) { ent.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); } repositoryWrapper.SetRepository().Add(ent); await repositoryWrapper.SaveChangesAsync(cancellationToken); return TypedResults.Ok(ent.AdaptToSDto()); } // PUT:Update Entity public async Task Put([FromBody] BlogLDto dto, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) { var ent = await repositoryWrapper.SetRepository().TableNoTracking .FirstOrDefaultAsync(b => b.Id == dto.Id, cancellationToken); if (ent == null) throw new AppException("Blog not found"); var newEnt = Blog.Create(dto.Title, dto.Content, dto.Tags, dto.ReadingTime, dto.Summery, dto.IsSuggested, dto.CategoryId); newEnt.Id = ent.Id; newEnt.CreatedAt = ent.CreatedAt; newEnt.CreatedBy = ent.CreatedBy; var dbFiles = await repositoryWrapper.SetRepository().TableNoTracking .Where(s => s.BlogId == newEnt.Id).ToListAsync(cancellationToken); foreach (var dbFile in dbFiles) { if (dto.Files.FirstOrDefault(s => s.Id == dbFile.Id) == null) { repositoryWrapper.SetRepository().Delete(dbFile); await repositoryWrapper.SaveChangesAsync(cancellationToken); } } foreach (var file in dto.Files.Where(f => f.Id == default)) newEnt.AddFile(file.Name, file.FileLocation, file.FileName, file.IsHeader, file.IsPrimary, file.FileType); repositoryWrapper.SetRepository().Update(newEnt); await repositoryWrapper.SaveChangesAsync(cancellationToken); return TypedResults.Ok(); } // DELETE:Delete Entity public async Task Delete(Guid id, IRepositoryWrapper repositoryWrapper, CancellationToken cancellationToken) { var ent = await repositoryWrapper.SetRepository().TableNoTracking .FirstOrDefaultAsync(b => b.Id == id, cancellationToken); if (ent == null) throw new AppException("Blog not found"); repositoryWrapper.SetRepository().Delete(ent); await repositoryWrapper.SaveChangesAsync(cancellationToken); return TypedResults.Ok(); } }