using Microsoft.AspNetCore.Routing; using Nop.Core; using Nop.Core.Caching; using Nop.Services.Cms; using Nop.Services.Customers; using Nop.Web.Framework.Models.Cms; using Nop.Web.Framework.Themes; namespace Nop.Web.Framework.Factories; /// /// Represents the widget model factory /// public partial class WidgetModelFactory : IWidgetModelFactory { #region Fields protected readonly ICustomerService _customerService; protected readonly IShortTermCacheManager _shortTermCacheManager; protected readonly IStaticCacheManager _staticCacheManager; protected readonly IStoreContext _storeContext; protected readonly IThemeContext _themeContext; protected readonly IWidgetPluginManager _widgetPluginManager; protected readonly IWorkContext _workContext; #endregion #region Ctor public WidgetModelFactory(ICustomerService customerService, IShortTermCacheManager shortTermCacheManager, IStaticCacheManager staticCacheManager, IStoreContext storeContext, IThemeContext themeContext, IWidgetPluginManager widgetPluginManager, IWorkContext workContext) { _customerService = customerService; _shortTermCacheManager = shortTermCacheManager; _staticCacheManager = staticCacheManager; _storeContext = storeContext; _themeContext = themeContext; _widgetPluginManager = widgetPluginManager; _workContext = workContext; } #endregion #region Methods /// /// Get the render widget models /// /// Name of widget zone /// Additional data object /// Value indicating whether to get widget models from cache /// /// A task that represents the asynchronous operation /// The task result contains the list of the render widget models /// public virtual async Task> PrepareRenderWidgetModelAsync(string widgetZone, object additionalData = null, bool useCache = true) { var theme = await _themeContext.GetWorkingThemeNameAsync(); var customer = await _workContext.GetCurrentCustomerAsync(); var customerRoleIds = await _customerService.GetCustomerRoleIdsAsync(customer); var store = await _storeContext.GetCurrentStoreAsync(); if (!useCache) return (await _widgetPluginManager.LoadActivePluginsAsync(customer, store.Id, widgetZone)) .Select(widget => new RenderWidgetModel { WidgetViewComponent = widget.GetWidgetViewComponent(widgetZone), WidgetViewComponentArguments = new RouteValueDictionary { ["widgetZone"] = widgetZone, ["additionalData"] = additionalData } }).ToList(); var widgetModels = await _shortTermCacheManager.GetAsync(async () => (await _widgetPluginManager.LoadActivePluginsAsync(customer, store.Id, widgetZone)) .Select(widget => new RenderWidgetModel { WidgetViewComponent = widget.GetWidgetViewComponent(widgetZone), WidgetViewComponentArguments = new RouteValueDictionary { ["widgetZone"] = widgetZone } }), WidgetModelDefaults.WidgetModelKey, customerRoleIds, store, widgetZone, theme); //"WidgetViewComponentArguments" property of widget models depends on "additionalData". //We need to clone the cached model before modifications (the updated one should not be cached) var models = widgetModels.Select(renderModel => new RenderWidgetModel { WidgetViewComponent = renderModel.WidgetViewComponent, WidgetViewComponentArguments = new RouteValueDictionary { ["widgetZone"] = widgetZone, ["additionalData"] = additionalData } }).ToList(); return models; } #endregion }