243 lines
9.7 KiB
C#
243 lines
9.7 KiB
C#
using Microsoft.AspNetCore.Mvc;
|
|
using Nop.Core;
|
|
using Nop.Core.Domain.Blogs;
|
|
using Nop.Core.Domain.Localization;
|
|
using Nop.Core.Domain.Security;
|
|
using Nop.Core.Events;
|
|
using Nop.Core.Rss;
|
|
using Nop.Services.Blogs;
|
|
using Nop.Services.Customers;
|
|
using Nop.Services.Localization;
|
|
using Nop.Services.Logging;
|
|
using Nop.Services.Messages;
|
|
using Nop.Services.Security;
|
|
using Nop.Services.Seo;
|
|
using Nop.Services.Stores;
|
|
using Nop.Web.Factories;
|
|
using Nop.Web.Framework;
|
|
using Nop.Web.Framework.Mvc;
|
|
using Nop.Web.Framework.Mvc.Filters;
|
|
using Nop.Web.Framework.Mvc.Routing;
|
|
using Nop.Web.Models.Blogs;
|
|
|
|
namespace Nop.Web.Controllers;
|
|
|
|
[AutoValidateAntiforgeryToken]
|
|
public partial class BlogController : BasePublicController
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly BlogSettings _blogSettings;
|
|
protected readonly CaptchaSettings _captchaSettings;
|
|
protected readonly IBlogModelFactory _blogModelFactory;
|
|
protected readonly IBlogService _blogService;
|
|
protected readonly ICustomerActivityService _customerActivityService;
|
|
protected readonly ICustomerService _customerService;
|
|
protected readonly IEventPublisher _eventPublisher;
|
|
protected readonly ILocalizationService _localizationService;
|
|
protected readonly INopUrlHelper _nopUrlHelper;
|
|
protected readonly IPermissionService _permissionService;
|
|
protected readonly IStoreContext _storeContext;
|
|
protected readonly IStoreMappingService _storeMappingService;
|
|
protected readonly IUrlRecordService _urlRecordService;
|
|
protected readonly IWebHelper _webHelper;
|
|
protected readonly IWorkContext _workContext;
|
|
protected readonly IWorkflowMessageService _workflowMessageService;
|
|
protected readonly LocalizationSettings _localizationSettings;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public BlogController(BlogSettings blogSettings,
|
|
CaptchaSettings captchaSettings,
|
|
IBlogModelFactory blogModelFactory,
|
|
IBlogService blogService,
|
|
ICustomerActivityService customerActivityService,
|
|
ICustomerService customerService,
|
|
IEventPublisher eventPublisher,
|
|
ILocalizationService localizationService,
|
|
INopUrlHelper nopUrlHelper,
|
|
IPermissionService permissionService,
|
|
IStoreContext storeContext,
|
|
IStoreMappingService storeMappingService,
|
|
IUrlRecordService urlRecordService,
|
|
IWebHelper webHelper,
|
|
IWorkContext workContext,
|
|
IWorkflowMessageService workflowMessageService,
|
|
LocalizationSettings localizationSettings)
|
|
{
|
|
_blogSettings = blogSettings;
|
|
_captchaSettings = captchaSettings;
|
|
_blogModelFactory = blogModelFactory;
|
|
_blogService = blogService;
|
|
_customerActivityService = customerActivityService;
|
|
_customerService = customerService;
|
|
_eventPublisher = eventPublisher;
|
|
_localizationService = localizationService;
|
|
_nopUrlHelper = nopUrlHelper;
|
|
_permissionService = permissionService;
|
|
_storeContext = storeContext;
|
|
_storeMappingService = storeMappingService;
|
|
_urlRecordService = urlRecordService;
|
|
_webHelper = webHelper;
|
|
_workContext = workContext;
|
|
_workflowMessageService = workflowMessageService;
|
|
_localizationSettings = localizationSettings;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
public virtual async Task<IActionResult> List(BlogPagingFilteringModel command)
|
|
{
|
|
if (!_blogSettings.Enabled)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var model = await _blogModelFactory.PrepareBlogPostListModelAsync(command);
|
|
return View("List", model);
|
|
}
|
|
|
|
public virtual async Task<IActionResult> BlogByTag(BlogPagingFilteringModel command)
|
|
{
|
|
if (!_blogSettings.Enabled)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var model = await _blogModelFactory.PrepareBlogPostListModelAsync(command);
|
|
return View("List", model);
|
|
}
|
|
|
|
public virtual async Task<IActionResult> BlogByMonth(BlogPagingFilteringModel command)
|
|
{
|
|
if (!_blogSettings.Enabled)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var model = await _blogModelFactory.PrepareBlogPostListModelAsync(command);
|
|
return View("List", model);
|
|
}
|
|
|
|
[CheckLanguageSeoCode(ignore: true)]
|
|
public virtual async Task<IActionResult> ListRss(int languageId)
|
|
{
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var feed = new RssFeed(
|
|
$"{await _localizationService.GetLocalizedAsync(store, x => x.Name)}: Blog",
|
|
"Blog",
|
|
new Uri(_webHelper.GetStoreLocation()),
|
|
DateTime.UtcNow);
|
|
|
|
if (!_blogSettings.Enabled)
|
|
return new RssActionResult(feed, _webHelper.GetThisPageUrl(false));
|
|
|
|
var items = new List<RssItem>();
|
|
var blogPosts = await _blogService.GetAllBlogPostsAsync(store.Id, languageId);
|
|
foreach (var blogPost in blogPosts)
|
|
{
|
|
var seName = await _urlRecordService.GetSeNameAsync(blogPost, blogPost.LanguageId, ensureTwoPublishedLanguages: false);
|
|
var blogPostUrl = await _nopUrlHelper.RouteGenericUrlAsync<BlogPost>(new { SeName = seName }, _webHelper.GetCurrentRequestProtocol());
|
|
items.Add(new RssItem(blogPost.Title, blogPost.Body, new Uri(blogPostUrl), $"urn:store:{store.Id}:blog:post:{blogPost.Id}", blogPost.CreatedOnUtc));
|
|
}
|
|
feed.Items = items;
|
|
return new RssActionResult(feed, _webHelper.GetThisPageUrl(false));
|
|
}
|
|
|
|
public virtual async Task<IActionResult> BlogPost(int blogPostId)
|
|
{
|
|
if (!_blogSettings.Enabled)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var blogPost = await _blogService.GetBlogPostByIdAsync(blogPostId);
|
|
if (blogPost == null)
|
|
return InvokeHttp404();
|
|
|
|
var notAvailable =
|
|
//availability dates
|
|
!_blogService.BlogPostIsAvailable(blogPost) ||
|
|
//Store mapping
|
|
!await _storeMappingService.AuthorizeAsync(blogPost);
|
|
//Check whether the current user has a "Manage blog" permission (usually a store owner)
|
|
//We should allows him (her) to use "Preview" functionality
|
|
var hasAdminAccess = await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL) && await _permissionService.AuthorizeAsync(StandardPermission.ContentManagement.BLOG_VIEW);
|
|
if (notAvailable && !hasAdminAccess)
|
|
return InvokeHttp404();
|
|
|
|
//display "edit" (manage) link
|
|
if (hasAdminAccess)
|
|
DisplayEditLink(Url.Action("BlogPostEdit", "Blog", new { id = blogPost.Id, area = AreaNames.ADMIN }));
|
|
|
|
var model = new BlogPostModel();
|
|
await _blogModelFactory.PrepareBlogPostModelAsync(model, blogPost, true);
|
|
|
|
return View(model);
|
|
}
|
|
|
|
[HttpPost]
|
|
[ValidateCaptcha]
|
|
public virtual async Task<IActionResult> BlogCommentAdd(int blogPostId, BlogPostModel model, bool captchaValid)
|
|
{
|
|
if (!_blogSettings.Enabled)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var blogPost = await _blogService.GetBlogPostByIdAsync(blogPostId);
|
|
if (blogPost == null || !blogPost.AllowComments)
|
|
return RedirectToRoute("Homepage");
|
|
|
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
|
if (await _customerService.IsGuestAsync(customer) && !_blogSettings.AllowNotRegisteredUsersToLeaveComments)
|
|
{
|
|
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Blog.Comments.OnlyRegisteredUsersLeaveComments"));
|
|
}
|
|
|
|
//validate CAPTCHA
|
|
if (_captchaSettings.Enabled && _captchaSettings.ShowOnBlogCommentPage && !captchaValid)
|
|
{
|
|
ModelState.AddModelError("", await _localizationService.GetResourceAsync("Common.WrongCaptchaMessage"));
|
|
}
|
|
|
|
if (ModelState.IsValid)
|
|
{
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var comment = new BlogComment
|
|
{
|
|
BlogPostId = blogPost.Id,
|
|
CustomerId = customer.Id,
|
|
CommentText = model.AddNewComment.CommentText,
|
|
IsApproved = !_blogSettings.BlogCommentsMustBeApproved,
|
|
StoreId = store.Id,
|
|
CreatedOnUtc = DateTime.UtcNow,
|
|
};
|
|
|
|
await _blogService.InsertBlogCommentAsync(comment);
|
|
|
|
//notify a store owner
|
|
if (_blogSettings.NotifyAboutNewBlogComments)
|
|
await _workflowMessageService.SendBlogCommentStoreOwnerNotificationMessageAsync(comment, _localizationSettings.DefaultAdminLanguageId);
|
|
|
|
//activity log
|
|
await _customerActivityService.InsertActivityAsync("PublicStore.AddBlogComment",
|
|
await _localizationService.GetResourceAsync("ActivityLog.PublicStore.AddBlogComment"), comment);
|
|
|
|
//raise event
|
|
if (comment.IsApproved)
|
|
await _eventPublisher.PublishAsync(new BlogCommentApprovedEvent(comment));
|
|
|
|
//The text boxes should be cleared after a comment has been posted
|
|
//That' why we reload the page
|
|
TempData["nop.blog.addcomment.result"] = comment.IsApproved
|
|
? await _localizationService.GetResourceAsync("Blog.Comments.SuccessfullyAdded")
|
|
: await _localizationService.GetResourceAsync("Blog.Comments.SeeAfterApproving");
|
|
|
|
var seName = await _urlRecordService.GetSeNameAsync(blogPost, blogPost.LanguageId, ensureTwoPublishedLanguages: false);
|
|
var blogPostUrl = await _nopUrlHelper.RouteGenericUrlAsync<BlogPost>(new { SeName = seName });
|
|
return LocalRedirect(blogPostUrl);
|
|
}
|
|
|
|
//If we got this far, something failed, redisplay form
|
|
RouteData.Values["action"] = "BlogPost";
|
|
await _blogModelFactory.PrepareBlogPostModelAsync(model, blogPost, true);
|
|
return View(model);
|
|
}
|
|
|
|
#endregion
|
|
} |