first commit
This commit is contained in:
@@ -0,0 +1,153 @@
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using DrSousan.Api.Data;
|
||||
using DrSousan.Api.Models;
|
||||
|
||||
namespace DrSousan.Api.Pages.Blog;
|
||||
|
||||
public class PostModel : PageModel
|
||||
{
|
||||
private readonly AppDbContext _db;
|
||||
|
||||
public PostModel(AppDbContext db) => _db = db;
|
||||
|
||||
public BlogPost? Post { get; private set; }
|
||||
public List<CommentVm> Comments { get; private set; } = new();
|
||||
public bool CommentSent { get; private set; } = false;
|
||||
|
||||
// Comment form binding
|
||||
[BindProperty]
|
||||
[Required(ErrorMessage = "نام الزامی است.")]
|
||||
[MaxLength(100)]
|
||||
public string CommentAuthor { get; set; } = "";
|
||||
|
||||
[BindProperty]
|
||||
[MaxLength(200)]
|
||||
[EmailAddress]
|
||||
public string CommentEmail { get; set; } = "";
|
||||
|
||||
[BindProperty]
|
||||
[Required(ErrorMessage = "متن نظر الزامی است.")]
|
||||
public string CommentBody { get; set; } = "";
|
||||
|
||||
public async Task<IActionResult> OnGetAsync(string slug)
|
||||
{
|
||||
var post = await _db.BlogPosts
|
||||
.Include(p => p.Category)
|
||||
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsPublished);
|
||||
|
||||
if (post is null) return NotFound();
|
||||
|
||||
// Increment view count
|
||||
post.ViewCount++;
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
Post = post;
|
||||
await LoadCommentsAsync(post.Id);
|
||||
await SetViewDataAsync(post);
|
||||
return Page();
|
||||
}
|
||||
|
||||
public async Task<IActionResult> OnPostAsync(string slug)
|
||||
{
|
||||
var post = await _db.BlogPosts
|
||||
.Include(p => p.Category)
|
||||
.FirstOrDefaultAsync(p => p.Slug == slug && p.IsPublished);
|
||||
|
||||
if (post is null) return NotFound();
|
||||
|
||||
Post = post;
|
||||
await LoadCommentsAsync(post.Id);
|
||||
await SetViewDataAsync(post);
|
||||
|
||||
if (!ModelState.IsValid) return Page();
|
||||
|
||||
// Sanitise
|
||||
var body = System.Text.RegularExpressions.Regex.Replace(CommentBody ?? "", "<[^>]*>", "").Trim();
|
||||
var authorName = System.Text.RegularExpressions.Regex.Replace(CommentAuthor ?? "", "<[^>]*>", "").Trim();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(body) || string.IsNullOrWhiteSpace(authorName))
|
||||
{
|
||||
ModelState.AddModelError("", "نام و متن نظر الزامی است.");
|
||||
return Page();
|
||||
}
|
||||
|
||||
_db.Comments.Add(new Comment
|
||||
{
|
||||
BlogPostId = post.Id,
|
||||
AuthorName = authorName,
|
||||
AuthorEmail = CommentEmail ?? "",
|
||||
Body = body,
|
||||
IsApproved = false,
|
||||
CreatedAt = DateTime.UtcNow
|
||||
});
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
CommentSent = true;
|
||||
// Clear form
|
||||
CommentAuthor = "";
|
||||
CommentEmail = "";
|
||||
CommentBody = "";
|
||||
ModelState.Clear();
|
||||
return Page();
|
||||
}
|
||||
|
||||
private async Task LoadCommentsAsync(int postId)
|
||||
{
|
||||
var raw = await _db.Comments
|
||||
.Where(c => c.BlogPostId == postId && c.IsApproved && c.ParentId == null)
|
||||
.OrderBy(c => c.CreatedAt)
|
||||
.Select(c => new
|
||||
{
|
||||
c.Id, c.AuthorName, c.Body, c.CreatedAt, c.IsAdminReply,
|
||||
Replies = _db.Comments
|
||||
.Where(r => r.ParentId == c.Id && r.IsApproved)
|
||||
.OrderBy(r => r.CreatedAt)
|
||||
.Select(r => new { r.Id, r.AuthorName, r.Body, r.CreatedAt, r.IsAdminReply })
|
||||
.ToList()
|
||||
}).ToListAsync();
|
||||
|
||||
Comments = raw.Select(c => new CommentVm
|
||||
{
|
||||
Id = c.Id, AuthorName = c.AuthorName, Body = c.Body,
|
||||
CreatedAt = c.CreatedAt, IsAdminReply = c.IsAdminReply,
|
||||
Replies = c.Replies.Select(r => new CommentVm
|
||||
{
|
||||
Id = r.Id, AuthorName = r.AuthorName, Body = r.Body,
|
||||
CreatedAt = r.CreatedAt, IsAdminReply = r.IsAdminReply
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
private async Task SetViewDataAsync(BlogPost post)
|
||||
{
|
||||
var metaTitle = string.IsNullOrEmpty(post.MetaTitle) ? post.Title : post.MetaTitle;
|
||||
var metaDesc = string.IsNullOrEmpty(post.MetaDescription) ? post.Excerpt : post.MetaDescription;
|
||||
|
||||
// Avoid duplicating the site name if MetaTitle already contains it
|
||||
var suffix = " | دکتر سوسن آلطه";
|
||||
ViewData["Title"] = metaTitle.Contains("دکتر سوسن") ? metaTitle : metaTitle + suffix;
|
||||
ViewData["MetaDesc"] = metaDesc;
|
||||
ViewData["Keywords"] = post.Keywords;
|
||||
ViewData["OgImage"] = string.IsNullOrEmpty(post.OgImage) ? post.FeaturedImage : post.OgImage;
|
||||
ViewData["ArticleType"] = post.ArticleType;
|
||||
ViewData["Slug"] = post.Slug;
|
||||
|
||||
var s = await _db.SiteSettings
|
||||
.FirstOrDefaultAsync(x => x.Section == "hero" && x.Key == "name");
|
||||
ViewData["SiteName"] = s?.Value ?? "دکتر سوسن آلطه";
|
||||
}
|
||||
|
||||
// View model for comments
|
||||
public class CommentVm
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public string AuthorName { get; set; } = "";
|
||||
public string Body { get; set; } = "";
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public bool IsAdminReply { get; set; }
|
||||
public List<CommentVm> Replies { get; set; } = new();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user