using Nop.Core; using Nop.Core.Caching; using Nop.Core.Domain.Blogs; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Media; using Nop.Core.Domain.Security; using Nop.Services.Blogs; using Nop.Services.Common; using Nop.Services.Customers; using Nop.Services.Helpers; using Nop.Services.Media; using Nop.Services.Seo; using Nop.Web.Infrastructure.Cache; using Nop.Web.Models.Blogs; namespace Nop.Web.Factories; /// /// Represents the blog model factory /// public partial class BlogModelFactory : IBlogModelFactory { #region Fields protected readonly BlogSettings _blogSettings; protected readonly CaptchaSettings _captchaSettings; protected readonly CustomerSettings _customerSettings; protected readonly IBlogService _blogService; protected readonly ICustomerService _customerService; protected readonly IDateTimeHelper _dateTimeHelper; protected readonly IGenericAttributeService _genericAttributeService; protected readonly IPictureService _pictureService; protected readonly IStaticCacheManager _staticCacheManager; protected readonly IStoreContext _storeContext; protected readonly IUrlRecordService _urlRecordService; protected readonly IWorkContext _workContext; protected readonly MediaSettings _mediaSettings; #endregion #region Ctor public BlogModelFactory(BlogSettings blogSettings, CaptchaSettings captchaSettings, CustomerSettings customerSettings, IBlogService blogService, ICustomerService customerService, IDateTimeHelper dateTimeHelper, IGenericAttributeService genericAttributeService, IPictureService pictureService, IStaticCacheManager staticCacheManager, IStoreContext storeContext, IUrlRecordService urlRecordService, IWorkContext workContext, MediaSettings mediaSettings) { _blogSettings = blogSettings; _captchaSettings = captchaSettings; _customerSettings = customerSettings; _blogService = blogService; _customerService = customerService; _dateTimeHelper = dateTimeHelper; _genericAttributeService = genericAttributeService; _pictureService = pictureService; _staticCacheManager = staticCacheManager; _storeContext = storeContext; _urlRecordService = urlRecordService; _workContext = workContext; _mediaSettings = mediaSettings; } #endregion #region Methods /// /// Prepare blog post model /// /// Blog post model /// Blog post entity /// Whether to prepare blog comments /// A task that represents the asynchronous operation public virtual async Task PrepareBlogPostModelAsync(BlogPostModel model, BlogPost blogPost, bool prepareComments) { ArgumentNullException.ThrowIfNull(model); ArgumentNullException.ThrowIfNull(blogPost); model.Id = blogPost.Id; model.MetaTitle = blogPost.MetaTitle; model.MetaDescription = blogPost.MetaDescription; model.MetaKeywords = blogPost.MetaKeywords; model.SeName = await _urlRecordService.GetSeNameAsync(blogPost, blogPost.LanguageId, ensureTwoPublishedLanguages: false); model.Title = blogPost.Title; model.Body = blogPost.Body; model.BodyOverview = blogPost.BodyOverview; model.AllowComments = blogPost.AllowComments; model.PreventNotRegisteredUsersToLeaveComments = await _customerService.IsGuestAsync(await _workContext.GetCurrentCustomerAsync()) && !_blogSettings.AllowNotRegisteredUsersToLeaveComments; model.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(blogPost.StartDateUtc ?? blogPost.CreatedOnUtc, DateTimeKind.Utc); model.Tags = await _blogService.ParseTagsAsync(blogPost); model.AddNewComment.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnBlogCommentPage; //number of blog comments var store = await _storeContext.GetCurrentStoreAsync(); var storeId = _blogSettings.ShowBlogCommentsPerStore ? store.Id : 0; model.NumberOfComments = await _blogService.GetBlogCommentsCountAsync(blogPost, storeId, true); if (prepareComments) { var blogComments = await _blogService.GetAllCommentsAsync( blogPostId: blogPost.Id, approved: true, storeId: storeId); foreach (var bc in blogComments) { var commentModel = await PrepareBlogPostCommentModelAsync(bc); model.Comments.Add(commentModel); } } } /// /// Prepare blog post list model /// /// Blog paging filtering model /// /// A task that represents the asynchronous operation /// The task result contains the blog post list model /// public virtual async Task PrepareBlogPostListModelAsync(BlogPagingFilteringModel command) { ArgumentNullException.ThrowIfNull(command); if (command.PageSize <= 0) command.PageSize = _blogSettings.PostsPageSize; if (command.PageNumber <= 0) command.PageNumber = 1; var dateFrom = command.GetFromMonth(); var dateTo = command.GetToMonth(); var language = await _workContext.GetWorkingLanguageAsync(); var store = await _storeContext.GetCurrentStoreAsync(); var blogPosts = string.IsNullOrEmpty(command.Tag) ? await _blogService.GetAllBlogPostsAsync(store.Id, language.Id, dateFrom, dateTo, command.PageNumber - 1, command.PageSize) : await _blogService.GetAllBlogPostsByTagAsync(store.Id, language.Id, command.Tag, command.PageNumber - 1, command.PageSize); var model = new BlogPostListModel { PagingFilteringContext = { Tag = command.Tag, Month = command.Month }, WorkingLanguageId = language.Id, BlogPosts = await blogPosts.SelectAwait(async blogPost => { var blogPostModel = new BlogPostModel(); await PrepareBlogPostModelAsync(blogPostModel, blogPost, false); return blogPostModel; }).ToListAsync() }; model.PagingFilteringContext.LoadPagedList(blogPosts); return model; } /// /// Prepare blog post tag list model /// /// /// A task that represents the asynchronous operation /// The task result contains the blog post tag list model /// public virtual async Task PrepareBlogPostTagListModelAsync() { var model = new BlogPostTagListModel(); var store = await _storeContext.GetCurrentStoreAsync(); //get tags var tags = (await _blogService .GetAllBlogPostTagsAsync(store.Id, (await _workContext.GetWorkingLanguageAsync()).Id)) .OrderByDescending(x => x.BlogPostCount) .Take(_blogSettings.NumberOfTags); //sorting and setting into the model model.Tags.AddRange(tags.OrderBy(x => x.Name).Select(tag => new BlogPostTagModel { Name = tag.Name, BlogPostCount = tag.BlogPostCount })); return model; } /// /// Prepare blog post year models /// /// /// A task that represents the asynchronous operation /// The task result contains the list of blog post year model /// public virtual async Task> PrepareBlogPostYearModelAsync() { var store = await _storeContext.GetCurrentStoreAsync(); var currentLanguage = await _workContext.GetWorkingLanguageAsync(); var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.BlogMonthsModelKey, currentLanguage, store); var cachedModel = await _staticCacheManager.GetAsync(cacheKey, async () => { var model = new List(); var blogPosts = await _blogService.GetAllBlogPostsAsync(store.Id, currentLanguage.Id); if (blogPosts.Any()) { var months = new SortedDictionary(); var blogPost = blogPosts[blogPosts.Count - 1]; var first = blogPost.StartDateUtc ?? blogPost.CreatedOnUtc; while (DateTime.SpecifyKind(first, DateTimeKind.Utc) <= DateTime.UtcNow.AddMonths(1)) { var list = await _blogService.GetPostsByDateAsync(blogPosts, new DateTime(first.Year, first.Month, 1), new DateTime(first.Year, first.Month, 1).AddMonths(1).AddSeconds(-1)); if (list.Any()) { var date = new DateTime(first.Year, first.Month, 1); months.Add(date, list.Count); } first = first.AddMonths(1); } var current = 0; foreach (var kvp in months) { var date = kvp.Key; var blogPostCount = kvp.Value; if (current == 0) current = date.Year; if (date.Year > current || !model.Any()) { var yearModel = new BlogPostYearModel { Year = date.Year }; model.Insert(0, yearModel); } model.First().Months.Insert(0, new BlogPostMonthModel { Month = date.Month, BlogPostCount = blogPostCount }); current = date.Year; } } return model; }); return cachedModel; } /// /// Prepare blog comment model /// /// Blog comment entity /// /// A task that represents the asynchronous operation /// The task result contains the blog comment model /// public virtual async Task PrepareBlogPostCommentModelAsync(BlogComment blogComment) { ArgumentNullException.ThrowIfNull(blogComment); var customer = await _customerService.GetCustomerByIdAsync(blogComment.CustomerId); var model = new BlogCommentModel { Id = blogComment.Id, CustomerId = blogComment.CustomerId, CustomerName = await _customerService.FormatUsernameAsync(customer), CommentText = blogComment.CommentText, CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(blogComment.CreatedOnUtc, DateTimeKind.Utc), AllowViewingProfiles = _customerSettings.AllowViewingProfiles && customer != null && !await _customerService.IsGuestAsync(customer) }; if (_customerSettings.AllowCustomersToUploadAvatars) { model.CustomerAvatarUrl = await _pictureService.GetPictureUrlAsync( await _genericAttributeService.GetAttributeAsync(customer, NopCustomerDefaults.AvatarPictureIdAttribute), _mediaSettings.AvatarPictureSize, _customerSettings.DefaultAvatarEnabled, defaultPictureType: PictureType.Avatar); } return model; } #endregion }