240 lines
9.4 KiB
C#
240 lines
9.4 KiB
C#
using Nop.Core;
|
|
using Nop.Core.Caching;
|
|
using Nop.Core.Domain.Customers;
|
|
using Nop.Core.Domain.Media;
|
|
using Nop.Core.Domain.News;
|
|
using Nop.Core.Domain.Security;
|
|
using Nop.Services.Common;
|
|
using Nop.Services.Customers;
|
|
using Nop.Services.Helpers;
|
|
using Nop.Services.Media;
|
|
using Nop.Services.News;
|
|
using Nop.Services.Seo;
|
|
using Nop.Web.Infrastructure.Cache;
|
|
using Nop.Web.Models.News;
|
|
|
|
namespace Nop.Web.Factories;
|
|
|
|
/// <summary>
|
|
/// Represents the news model factory
|
|
/// </summary>
|
|
public partial class NewsModelFactory : INewsModelFactory
|
|
{
|
|
#region Fields
|
|
|
|
protected readonly CaptchaSettings _captchaSettings;
|
|
protected readonly CustomerSettings _customerSettings;
|
|
protected readonly ICustomerService _customerService;
|
|
protected readonly IDateTimeHelper _dateTimeHelper;
|
|
protected readonly IGenericAttributeService _genericAttributeService;
|
|
protected readonly INewsService _newsService;
|
|
protected readonly IPictureService _pictureService;
|
|
protected readonly IStaticCacheManager _staticCacheManager;
|
|
protected readonly IStoreContext _storeContext;
|
|
protected readonly IUrlRecordService _urlRecordService;
|
|
protected readonly IWorkContext _workContext;
|
|
protected readonly MediaSettings _mediaSettings;
|
|
protected readonly NewsSettings _newsSettings;
|
|
|
|
#endregion
|
|
|
|
#region Ctor
|
|
|
|
public NewsModelFactory(CaptchaSettings captchaSettings,
|
|
CustomerSettings customerSettings,
|
|
ICustomerService customerService,
|
|
IDateTimeHelper dateTimeHelper,
|
|
IGenericAttributeService genericAttributeService,
|
|
INewsService newsService,
|
|
IPictureService pictureService,
|
|
IStaticCacheManager staticCacheManager,
|
|
IStoreContext storeContext,
|
|
IUrlRecordService urlRecordService,
|
|
IWorkContext workContext,
|
|
MediaSettings mediaSettings,
|
|
NewsSettings newsSettings)
|
|
{
|
|
_captchaSettings = captchaSettings;
|
|
_customerSettings = customerSettings;
|
|
_customerService = customerService;
|
|
_dateTimeHelper = dateTimeHelper;
|
|
_genericAttributeService = genericAttributeService;
|
|
_newsService = newsService;
|
|
_pictureService = pictureService;
|
|
_staticCacheManager = staticCacheManager;
|
|
_storeContext = storeContext;
|
|
_urlRecordService = urlRecordService;
|
|
_workContext = workContext;
|
|
_mediaSettings = mediaSettings;
|
|
_newsSettings = newsSettings;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Methods
|
|
|
|
/// <summary>
|
|
/// Prepare the news item model
|
|
/// </summary>
|
|
/// <param name="model">News item model</param>
|
|
/// <param name="newsItem">News item</param>
|
|
/// <param name="prepareComments">Whether to prepare news comment models</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the news item model
|
|
/// </returns>
|
|
public virtual async Task<NewsItemModel> PrepareNewsItemModelAsync(NewsItemModel model, NewsItem newsItem, bool prepareComments)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(model);
|
|
|
|
ArgumentNullException.ThrowIfNull(newsItem);
|
|
|
|
model.Id = newsItem.Id;
|
|
model.MetaTitle = newsItem.MetaTitle;
|
|
model.MetaDescription = newsItem.MetaDescription;
|
|
model.MetaKeywords = newsItem.MetaKeywords;
|
|
model.SeName = await _urlRecordService.GetSeNameAsync(newsItem, newsItem.LanguageId, ensureTwoPublishedLanguages: false);
|
|
model.Title = newsItem.Title;
|
|
model.Short = newsItem.Short;
|
|
model.Full = newsItem.Full;
|
|
model.AllowComments = newsItem.AllowComments;
|
|
|
|
model.PreventNotRegisteredUsersToLeaveComments =
|
|
await _customerService.IsGuestAsync(await _workContext.GetCurrentCustomerAsync()) &&
|
|
!_newsSettings.AllowNotRegisteredUsersToLeaveComments;
|
|
|
|
model.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(newsItem.StartDateUtc ?? newsItem.CreatedOnUtc, DateTimeKind.Utc);
|
|
model.AddNewComment.DisplayCaptcha = _captchaSettings.Enabled && _captchaSettings.ShowOnNewsCommentPage;
|
|
|
|
//number of news comments
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var storeId = _newsSettings.ShowNewsCommentsPerStore ? store.Id : 0;
|
|
|
|
model.NumberOfComments = await _newsService.GetNewsCommentsCountAsync(newsItem, storeId, true);
|
|
|
|
if (prepareComments)
|
|
{
|
|
var newsComments = await _newsService.GetAllCommentsAsync(
|
|
newsItemId: newsItem.Id,
|
|
approved: true,
|
|
storeId: _newsSettings.ShowNewsCommentsPerStore ? store.Id : 0);
|
|
|
|
foreach (var nc in newsComments.OrderBy(comment => comment.CreatedOnUtc))
|
|
{
|
|
var commentModel = await PrepareNewsCommentModelAsync(nc);
|
|
model.Comments.Add(commentModel);
|
|
}
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare the home page news items model
|
|
/// </summary>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the home page news items model
|
|
/// </returns>
|
|
public virtual async Task<HomepageNewsItemsModel> PrepareHomepageNewsItemsModelAsync()
|
|
{
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var language = await _workContext.GetWorkingLanguageAsync();
|
|
var cacheKey = _staticCacheManager.PrepareKeyForDefaultCache(NopModelCacheDefaults.HomepageNewsModelKey, language, store);
|
|
var cachedModel = await _staticCacheManager.GetAsync(cacheKey, async () =>
|
|
{
|
|
var newsItems = await _newsService.GetAllNewsAsync(language.Id, store.Id, 0, _newsSettings.MainPageNewsCount);
|
|
|
|
return new HomepageNewsItemsModel
|
|
{
|
|
WorkingLanguageId = language.Id,
|
|
NewsItems = await newsItems.SelectAwait(async newsItem =>
|
|
{
|
|
var newsModel = new NewsItemModel();
|
|
await PrepareNewsItemModelAsync(newsModel, newsItem, false);
|
|
return newsModel;
|
|
}).ToListAsync()
|
|
};
|
|
});
|
|
|
|
//"Comments" property of "NewsItemModel" object depends on the current customer.
|
|
//Furthermore, we just don't need it for home page news. So let's reset it.
|
|
//But first we need to clone the cached model (the updated one should not be cached)
|
|
var model = cachedModel with { };
|
|
foreach (var newsItemModel in model.NewsItems)
|
|
newsItemModel.Comments.Clear();
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare the news item list model
|
|
/// </summary>
|
|
/// <param name="command">News paging filtering model</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the news item list model
|
|
/// </returns>
|
|
public virtual async Task<NewsItemListModel> PrepareNewsItemListModelAsync(NewsPagingFilteringModel command)
|
|
{
|
|
if (command.PageSize <= 0)
|
|
command.PageSize = _newsSettings.NewsArchivePageSize;
|
|
if (command.PageNumber <= 0)
|
|
command.PageNumber = 1;
|
|
|
|
var language = await _workContext.GetWorkingLanguageAsync();
|
|
var store = await _storeContext.GetCurrentStoreAsync();
|
|
var newsItems = await _newsService.GetAllNewsAsync(language.Id, store.Id, command.PageNumber - 1, command.PageSize);
|
|
|
|
var model = new NewsItemListModel
|
|
{
|
|
WorkingLanguageId = language.Id,
|
|
NewsItems = await newsItems.SelectAwait(async newsItem =>
|
|
{
|
|
var newsModel = new NewsItemModel();
|
|
await PrepareNewsItemModelAsync(newsModel, newsItem, false);
|
|
return newsModel;
|
|
}).ToListAsync()
|
|
};
|
|
model.PagingFilteringContext.LoadPagedList(newsItems);
|
|
|
|
return model;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Prepare the news comment model
|
|
/// </summary>
|
|
/// <param name="newsComment">News comment</param>
|
|
/// <returns>
|
|
/// A task that represents the asynchronous operation
|
|
/// The task result contains the news comment model
|
|
/// </returns>
|
|
public virtual async Task<NewsCommentModel> PrepareNewsCommentModelAsync(NewsComment newsComment)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(newsComment);
|
|
|
|
var customer = await _customerService.GetCustomerByIdAsync(newsComment.CustomerId);
|
|
|
|
var model = new NewsCommentModel
|
|
{
|
|
Id = newsComment.Id,
|
|
CustomerId = newsComment.CustomerId,
|
|
CustomerName = await _customerService.FormatUsernameAsync(customer),
|
|
CommentTitle = newsComment.CommentTitle,
|
|
CommentText = newsComment.CommentText,
|
|
CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(newsComment.CreatedOnUtc, DateTimeKind.Utc),
|
|
AllowViewingProfiles = _customerSettings.AllowViewingProfiles && newsComment.CustomerId != 0 && !await _customerService.IsGuestAsync(customer),
|
|
};
|
|
|
|
if (_customerSettings.AllowCustomersToUploadAvatars)
|
|
{
|
|
model.CustomerAvatarUrl = await _pictureService.GetPictureUrlAsync(
|
|
await _genericAttributeService.GetAttributeAsync<Customer, int>(newsComment.CustomerId, NopCustomerDefaults.AvatarPictureIdAttribute),
|
|
_mediaSettings.AvatarPictureSize, _customerSettings.DefaultAvatarEnabled, defaultPictureType: PictureType.Avatar);
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
#endregion
|
|
} |