public ActionResult Category(int categoryId, CatalogSearchQuery query) { var category = _categoryService.GetCategoryById(categoryId); if (category == null || category.Deleted) { return(HttpNotFound()); } // Check whether the current user has a "Manage catalog" permission // It allows him to preview a category before publishing if (!category.Published && !_services.Permissions.Authorize(StandardPermissionProvider.ManageCatalog)) { return(HttpNotFound()); } // ACL (access control list) if (!_aclService.Authorize(category)) { return(HttpNotFound()); } // Store mapping if (!_storeMappingService.Authorize(category)) { return(HttpNotFound()); } // 'Continue shopping' URL if (!_services.WorkContext.CurrentCustomer.IsSystemAccount) { _genericAttributeService.SaveAttribute(_services.WorkContext.CurrentCustomer, SystemCustomerAttributeNames.LastContinueShoppingPage, _services.WebHelper.GetThisPageUrl(false), _services.StoreContext.CurrentStore.Id); } var model = category.ToModel(); _services.DisplayControl.Announce(category); // Category breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { _helper.GetCategoryBreadCrumb(category.Id, 0).Select(x => x.Value).Each(x => _breadcrumb.Track(x)); } model.SubCategoryDisplayType = _catalogSettings.SubCategoryDisplayType; var customerRolesIds = _services.WorkContext.CurrentCustomer.CustomerRoles.Where(x => x.Active).Select(x => x.Id).ToList(); // subcategories model.SubCategories = _categoryService .GetAllCategoriesByParentCategoryId(categoryId) .Select(x => { var subCatName = x.GetLocalized(y => y.Name); var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = subCatName, SeName = x.GetSeName(), }; _services.DisplayControl.Announce(x); // prepare picture model int pictureSize = _mediaSettings.CategoryThumbPictureSize; var categoryPictureCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_PICTURE_MODEL_KEY, x.Id, pictureSize, true, _services.WorkContext.WorkingLanguage.Id, _services.StoreContext.CurrentStore.Id); subCatModel.PictureModel = _services.Cache.Get(categoryPictureCacheKey, () => { var picture = _pictureService.GetPictureById(x.PictureId.GetValueOrDefault()); var pictureModel = new PictureModel { PictureId = x.PictureId.GetValueOrDefault(), Size = pictureSize, FullSizeImageUrl = _pictureService.GetPictureUrl(picture), FullSizeImageWidth = picture?.Width, FullSizeImageHeight = picture?.Height, ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize, !_catalogSettings.HideCategoryDefaultPictures), Title = string.Format(T("Media.Category.ImageLinkTitleFormat"), subCatName), AlternateText = string.Format(T("Media.Category.ImageAlternateTextFormat"), subCatName) }; return(pictureModel); }, TimeSpan.FromHours(6)); return(subCatModel); }) .ToList(); // Featured Products if (!_catalogSettings.IgnoreFeaturedProducts) { CatalogSearchResult featuredProductsResult = null; string cacheKey = ModelCacheEventConsumer.CATEGORY_HAS_FEATURED_PRODUCTS_KEY.FormatInvariant(categoryId, string.Join(",", customerRolesIds), _services.StoreContext.CurrentStore.Id); var hasFeaturedProductsCache = _services.Cache.Get <bool?>(cacheKey); var featuredProductsQuery = new CatalogSearchQuery() .VisibleOnly(_services.WorkContext.CurrentCustomer) .VisibleIndividuallyOnly(true) .WithCategoryIds(true, categoryId) .HasStoreId(_services.StoreContext.CurrentStore.Id) .WithLanguage(_services.WorkContext.WorkingLanguage) .WithCurrency(_services.WorkContext.WorkingCurrency); if (!hasFeaturedProductsCache.HasValue) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); hasFeaturedProductsCache = featuredProductsResult.TotalHitsCount > 0; _services.Cache.Put(cacheKey, hasFeaturedProductsCache, TimeSpan.FromHours(6)); } if (hasFeaturedProductsCache.Value && featuredProductsResult == null) { featuredProductsResult = _catalogSearchService.Search(featuredProductsQuery); } if (featuredProductsResult != null) { var featuredProductsmappingSettings = _helper.GetBestFitProductSummaryMappingSettings(ProductSummaryViewMode.Grid); model.FeaturedProducts = _helper.MapProductSummaryModel(featuredProductsResult.Hits, featuredProductsmappingSettings); } } // Products int[] catIds = new int[] { categoryId }; if (_catalogSettings.ShowProductsFromSubcategories) { // Include subcategories catIds = catIds.Concat(_helper.GetChildCategoryIds(categoryId)).ToArray(); } query.WithCategoryIds(_catalogSettings.IncludeFeaturedProductsInNormalLists ? (bool?)null : false, catIds); var searchResult = _catalogSearchService.Search(query); model.SearchResult = searchResult; var mappingSettings = _helper.GetBestFitProductSummaryMappingSettings(query.GetViewMode()); model.Products = _helper.MapProductSummaryModel(searchResult.Hits, mappingSettings); // Prepare paging/sorting/mode stuff _helper.MapListActions(model.Products, category, _catalogSettings.DefaultPageSizeOptions); // template var templateCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId); var templateViewPath = _services.Cache.Get(templateCacheKey, () => { var template = _categoryTemplateService.GetCategoryTemplateById(category.CategoryTemplateId); if (template == null) { template = _categoryTemplateService.GetAllCategoryTemplates().FirstOrDefault(); } return(template.ViewPath); }); // Activity log _services.CustomerActivity.InsertActivity("PublicStore.ViewCategory", T("ActivityLog.PublicStore.ViewCategory"), category.Name); return(View(templateViewPath, model)); }
public async Task<CategoryModel> Handle(GetCategory request, CancellationToken cancellationToken) { var model = request.Category.ToModel(request.Language); var customer = request.Customer; var storeId = request.Store.Id; var languageId = request.Language.Id; var currency = request.Currency; if (request.Command != null && request.Command.OrderBy == null && request.Category.DefaultSort >= 0) request.Command.OrderBy = request.Category.DefaultSort; //view/sorting/page size var options = await _mediator.Send(new GetViewSortSizeOptions() { Command = request.Command, PagingFilteringModel = request.Command, Language = request.Language, AllowCustomersToSelectPageSize = request.Category.AllowCustomersToSelectPageSize, PageSizeOptions = request.Category.PageSizeOptions, PageSize = request.Category.PageSize }); model.PagingFilteringContext = options.command; //price ranges model.PagingFilteringContext.PriceRangeFilter.LoadPriceRangeFilters(request.Category.PriceRanges, _webHelper, _priceFormatter); var selectedPriceRange = model.PagingFilteringContext.PriceRangeFilter.GetSelectedPriceRange(_webHelper, request.Category.PriceRanges); decimal? minPriceConverted = null; decimal? maxPriceConverted = null; if (selectedPriceRange != null) { if (selectedPriceRange.From.HasValue) minPriceConverted = await _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.From.Value, currency); if (selectedPriceRange.To.HasValue) maxPriceConverted = await _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.To.Value, currency); } //category breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { model.DisplayCategoryBreadcrumb = true; string breadcrumbCacheKey = string.Format(ModelCacheEventConst.CATEGORY_BREADCRUMB_KEY, request.Category.Id, string.Join(",", customer.GetCustomerRoleIds()), storeId, languageId); model.CategoryBreadcrumb = await _cacheManager.GetAsync(breadcrumbCacheKey, async () => (await _categoryService.GetCategoryBreadCrumb(request.Category)) .Select(catBr => new CategoryModel { Id = catBr.Id, Name = catBr.GetLocalized(x => x.Name, languageId), SeName = catBr.GetSeName(languageId) }) .ToList() ); } //subcategories var subCategories = new List<CategoryModel.SubCategoryModel>(); foreach (var x in (await _categoryService.GetAllCategoriesByParentCategoryId(request.Category.Id)).Where(x => !x.HideOnCatalog)) { var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = x.GetLocalized(y => y.Name, languageId), SeName = x.GetSeName(languageId), Description = x.GetLocalized(y => y.Description, languageId), Flag = x.Flag, FlagStyle = x.FlagStyle }; //prepare picture model subCatModel.PictureModel = new PictureModel { Id = x.PictureId, FullSizeImageUrl = await _pictureService.GetPictureUrl(x.PictureId), ImageUrl = await _pictureService.GetPictureUrl(x.PictureId, _mediaSettings.CategoryThumbPictureSize), Title = string.Format(_localizationService.GetResource("Media.Category.ImageLinkTitleFormat"), subCatModel.Name), AlternateText = string.Format(_localizationService.GetResource("Media.Category.ImageAlternateTextFormat"), subCatModel.Name) }; subCategories.Add(subCatModel); }; model.SubCategories = subCategories; //featured products if (!_catalogSettings.IgnoreFeaturedProducts) { //We cache a value indicating whether we have featured products IPagedList<Product> featuredProducts = null; string cacheKey = string.Format(ModelCacheEventConst.CATEGORY_HAS_FEATURED_PRODUCTS_KEY, request.Category.Id, string.Join(",", customer.GetCustomerRoleIds()), storeId); var hasFeaturedProductsCache = await _cacheManager.GetAsync<bool?>(cacheKey); if (!hasFeaturedProductsCache.HasValue) { //no value in the cache yet //let's load products and cache the result (true/false) featuredProducts = (await _mediator.Send(new GetSearchProductsQuery() { PageSize = _catalogSettings.LimitOfFeaturedProducts, CategoryIds = new List<string> { request.Category.Id }, Customer = request.Customer, StoreId = storeId, VisibleIndividuallyOnly = true, FeaturedProducts = true })).products; hasFeaturedProductsCache = featuredProducts.Any(); await _cacheManager.SetAsync(cacheKey, hasFeaturedProductsCache, CommonHelper.CacheTimeMinutes); } if (hasFeaturedProductsCache.Value && featuredProducts == null) { //cache indicates that the category has featured products //let's load them featuredProducts = (await _mediator.Send(new GetSearchProductsQuery() { PageSize = _catalogSettings.LimitOfFeaturedProducts, CategoryIds = new List<string> { request.Category.Id }, Customer = request.Customer, StoreId = storeId, VisibleIndividuallyOnly = true, FeaturedProducts = true })).products; } if (featuredProducts != null && featuredProducts.Any()) { model.FeaturedProducts = (await _mediator.Send(new GetProductOverview() { Products = featuredProducts, })).ToList(); } } var categoryIds = new List<string>(); categoryIds.Add(request.Category.Id); if (_catalogSettings.ShowProductsFromSubcategories) { //include subcategories categoryIds.AddRange(await _mediator.Send(new GetChildCategoryIds() { ParentCategoryId = request.Category.Id, Customer = request.Customer, Store = request.Store })); } //products IList<string> alreadyFilteredSpecOptionIds = await model.PagingFilteringContext.SpecificationFilter.GetAlreadyFilteredSpecOptionIds(_httpContextAccessor, _specificationAttributeService); var products = (await _mediator.Send(new GetSearchProductsQuery() { LoadFilterableSpecificationAttributeOptionIds = !_catalogSettings.IgnoreFilterableSpecAttributeOption, CategoryIds = categoryIds, Customer = request.Customer, StoreId = storeId, VisibleIndividuallyOnly = true, FeaturedProducts = _catalogSettings.IncludeFeaturedProductsInNormalLists ? null : (bool?)false, PriceMin = minPriceConverted, PriceMax = maxPriceConverted, FilteredSpecs = alreadyFilteredSpecOptionIds, OrderBy = (ProductSortingEnum)request.Command.OrderBy, PageIndex = request.Command.PageNumber - 1, PageSize = request.Command.PageSize })); model.Products = (await _mediator.Send(new GetProductOverview() { PrepareSpecificationAttributes = _catalogSettings.ShowSpecAttributeOnCatalogPages, Products = products.products, })).ToList(); model.PagingFilteringContext.LoadPagedList(products.products); //specs await model.PagingFilteringContext.SpecificationFilter.PrepareSpecsFilters(alreadyFilteredSpecOptionIds, products.filterableSpecificationAttributeOptionIds, _specificationAttributeService, _webHelper, _cacheManager, request.Language.Id); return model; }
public virtual CategoryModel PrepareCategoryModel(Category category, CatalogPagingFilteringModel command) { if (category == null) { throw new ArgumentNullException("category"); } var model = new CategoryModel { Id = category.Id, Name = category.GetLocalized(x => x.Name), Description = category.GetLocalized(x => x.Description), MetaKeywords = category.GetLocalized(x => x.MetaKeywords), MetaDescription = category.GetLocalized(x => x.MetaDescription), MetaTitle = category.GetLocalized(x => x.MetaTitle), SeName = category.GetSeName(), }; //sorting PrepareSortingOptions(model.PagingFilteringContext, command); //view mode PrepareViewModes(model.PagingFilteringContext, command); //page size PreparePageSizeOptions(model.PagingFilteringContext, command, category.AllowCustomersToSelectPageSize, category.PageSizeOptions, category.PageSize); //category breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { model.DisplayCategoryBreadcrumb = true; string breadcrumbCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_BREADCRUMB_KEY, category.Id, string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id, _workContext.WorkingLanguage.Id); model.CategoryBreadcrumb = _cacheManager.Get(breadcrumbCacheKey, () => category .GetCategoryBreadCrumb(_categoryService, _aclService, _storeMappingService) .Select(catBr => new CategoryModel { Id = catBr.Id, Name = catBr.GetLocalized(x => x.Name), SeName = catBr.GetSeName() }) .ToList() ); } var pictureSize = _mediaSettings.CategoryThumbPictureSize; //subcategories string subCategoriesCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_SUBCATEGORIES_KEY, category.Id, pictureSize, string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured()); model.SubCategories = _cacheManager.Get(subCategoriesCacheKey, () => _categoryService.GetAllCategoriesByParentCategoryId(category.Id) .Select(x => { var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = x.GetLocalized(y => y.Name), SeName = x.GetSeName(), Description = x.GetLocalized(y => y.Description) }; //prepare picture model var categoryPictureCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_PICTURE_MODEL_KEY, x.Id, pictureSize, true, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured(), _storeContext.CurrentStore.Id); subCatModel.PictureModel = _cacheManager.Get(categoryPictureCacheKey, () => { var picture = _pictureService.GetPictureById(x.PictureId); var pictureModel = new PictureModel { FullSizeImageUrl = _pictureService.GetPictureUrl(picture), ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize), Title = string.Format(_localizationService.GetResource("Media.Category.ImageLinkTitleFormat"), subCatModel.Name), AlternateText = string.Format(_localizationService.GetResource("Media.Category.ImageAlternateTextFormat"), subCatModel.Name) }; return(pictureModel); }); return(subCatModel); }) .ToList() ); //featured products if (!_catalogSettings.IgnoreFeaturedProducts) { //We cache a value indicating whether we have featured products IPagedList <Product> featuredProducts = null; string cacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_HAS_FEATURED_PRODUCTS_KEY, category.Id, string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id); var hasFeaturedProductsCache = _cacheManager.Get <bool?>(cacheKey); if (!hasFeaturedProductsCache.HasValue) { //no value in the cache yet //let's load products and cache the result (true/false) featuredProducts = _productService.SearchProducts( categoryIds: new List <int> { category.Id }, storeId: _storeContext.CurrentStore.Id, visibleIndividuallyOnly: true, featuredProducts: true); hasFeaturedProductsCache = featuredProducts.TotalCount > 0; _cacheManager.Set(cacheKey, hasFeaturedProductsCache, 60); } if (hasFeaturedProductsCache.Value && featuredProducts == null) { //cache indicates that the category has featured products //let's load them featuredProducts = _productService.SearchProducts( categoryIds: new List <int> { category.Id }, storeId: _storeContext.CurrentStore.Id, visibleIndividuallyOnly: true, featuredProducts: true); } if (featuredProducts != null) { model.FeaturedProducts = _productModelFactory.PrepareProductOverviewModels(featuredProducts).ToList(); } } var categoryIds = new List <int>(); categoryIds.Add(category.Id); if (_catalogSettings.ShowProductsFromSubcategories) { //include subcategories categoryIds.AddRange(GetChildCategoryIds(category.Id)); } //products var products = _productService.SearchProducts( categoryIds: categoryIds, storeId: _storeContext.CurrentStore.Id, visibleIndividuallyOnly: true, featuredProducts: _catalogSettings.IncludeFeaturedProductsInNormalLists ? null : (bool?)false, orderBy: (ProductSortingEnum)command.OrderBy, pageIndex: command.PageNumber - 1, pageSize: command.PageSize); model.Products = _productModelFactory.PrepareProductOverviewModels(products).ToList(); model.PagingFilteringContext.LoadPagedList(products); return(model); }
public ActionResult Category(int categoryId, CatalogPagingFilteringModel command) { var category = _categoryService.GetCategoryById(categoryId); if (category == null || category.Deleted) { return(InvokeHttp404()); } var model = category.ToModel(); // сортировка PrepareSortingOptions(model.PagingFilteringContext, command); // размеры страницы PreparePageSizeOptions(model.PagingFilteringContext, command, category.PageSizeOptions, category.PageSize); // хлебные крошки категорий model.DisplayCategoryBreadcrumb = true; model.CategoryBreadcrumb = category.GetCategoryBreadCrumb(_categoryService) .Select(catBr => new CategoryModel { Id = catBr.Id, Name = catBr.Name, SeName = "SeName" }).ToList(); var pictureSize = 450; // подкатегории var categories = _categoryService.GetAllCategoriesByParentCategoryId(categoryId) .Select(x => { var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = x.Name, Description = x.Description }; var picture = _pictureService.GetPictureById(x.PictureId); var pictureModel = new PictureModel { FullSizeImgUrl = _pictureService.GetPictureUrl(picture), ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize), Title = subCatModel.Name, AlternateText = subCatModel.Name }; subCatModel.PictureModel = pictureModel; return(subCatModel); }).ToList(); model.SubCategories = categories; // избранные товары var categoryIds = new List <int>(); categoryIds.Add(category.Id); categoryIds.AddRange(GetChildCategoryIds(category.Id)); var items = _itemService.SearchItems( categoryIds: categoryIds, orderBy: (ItemSortingEnum)command.OrderBy, pageIndex: command.PageNumber - 1, pageSize: command.PageSize ); model.Items = PrepareItemOverviewModels(items).ToList(); model.PagingFilteringContext.LoadPagedList(items); return(View(model)); }
/// <summary> /// Prepare category model /// </summary> /// <param name="category">Category</param> /// <param name="command">Catalog paging filtering command</param> /// <returns>Category model</returns> public virtual CategoryModel PrepareCategoryModel(Category category, CatalogPagingFilteringModel command) { if (category == null) { throw new ArgumentNullException(nameof(category)); } var model = new CategoryModel { Id = category.Id, Name = _localizationService.GetLocalized(category, x => x.Name), Description = _localizationService.GetLocalized(category, x => x.Description), MetaKeywords = _localizationService.GetLocalized(category, x => x.MetaKeywords), MetaDescription = _localizationService.GetLocalized(category, x => x.MetaDescription), MetaTitle = _localizationService.GetLocalized(category, x => x.MetaTitle), SeName = _urlRecordService.GetSeName(category), }; //sorting PrepareSortingOptions(model.PagingFilteringContext, command); //view mode PrepareViewModes(model.PagingFilteringContext, command); //page size PreparePageSizeOptions(model.PagingFilteringContext, command, category.AllowCustomersToSelectPageSize, category.PageSizeOptions, category.PageSize); //price ranges var selectedPriceRange = model.PagingFilteringContext.PriceRangeFilter.GetSelectedPriceRange(_webHelper, category.PriceRanges); decimal?minPriceConverted = null; decimal?maxPriceConverted = null; if (selectedPriceRange != null) { if (selectedPriceRange.From.HasValue) { minPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.From.Value, _workContext.WorkingCurrency); } if (selectedPriceRange.To.HasValue) { maxPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.To.Value, _workContext.WorkingCurrency); } } //category breadcrumb if (_catalogSettings.CategoryBreadcrumbEnabled) { model.DisplayCategoryBreadcrumb = true; var breadcrumbCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_BREADCRUMB_KEY, category.Id, string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id, _workContext.WorkingLanguage.Id); model.CategoryBreadcrumb = _cacheManager.Get(breadcrumbCacheKey, () => _categoryService.GetCategoryBreadCrumb(category).Select(catBr => new CategoryModel { Id = catBr.Id, Name = _localizationService.GetLocalized(catBr, x => x.Name), SeName = _urlRecordService.GetSeName(catBr) }) .ToList() ); } var pictureSize = _mediaSettings.CategoryThumbPictureSize; //subcategories var subCategoriesCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_SUBCATEGORIES_KEY, category.Id, pictureSize, string.Join(",", _workContext.CurrentCustomer.GetCustomerRoleIds()), _storeContext.CurrentStore.Id, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured()); model.SubCategories = _cacheManager.Get(subCategoriesCacheKey, () => _categoryService.GetAllCategoriesByParentCategoryId(category.Id) .Select(x => { var subCatModel = new CategoryModel.SubCategoryModel { Id = x.Id, Name = _localizationService.GetLocalized(x, y => y.Name), SeName = _urlRecordService.GetSeName(x), Description = _localizationService.GetLocalized(x, y => y.Description) }; //prepare picture model var categoryPictureCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_PICTURE_MODEL_KEY, x.Id, pictureSize, true, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured(), _storeContext.CurrentStore.Id); subCatModel.PictureModel = _cacheManager.Get(categoryPictureCacheKey, () => { var picture = _pictureService.GetPictureById(x.PictureId); var pictureModel = new PictureModel { FullSizeImageUrl = _pictureService.GetPictureUrl(picture), ImageUrl = _pictureService.GetPictureUrl(picture, pictureSize), Title = string.Format(_localizationService.GetResource("Media.Category.ImageLinkTitleFormat"), subCatModel.Name), AlternateText = string.Format(_localizationService.GetResource("Media.Category.ImageAlternateTextFormat"), subCatModel.Name) }; return(pictureModel); }); return(subCatModel); }) .ToList() ); //featured products var categoryIds = new List <int>(); categoryIds.Add(category.Id); if (_catalogSettings.ShowProductsFromSubcategories) { //include subcategories categoryIds.AddRange(_categoryService.GetChildCategoryIds(category.Id, _storeContext.CurrentStore.Id)); } return(model); }
public ActionResult CategoryWithPagination(int categoryId, CatalogPagingFilteringModel command) { var category = _categoryService.GetCategoryById(categoryId); if (category == null || category.Deleted) { return(RedirectToRoute("HomePage")); } //Check whether the current user has a "Manage catalog" permission //It allows him to preview a category before publishing if (!category.Published && !_permissionService.Authorize(StandardPermissionProvider.ManageCatalog)) { return(RedirectToRoute("HomePage")); } //'Continue shopping' URL _genericAttributeService.SaveAttribute(_workContext.CurrentCustomer, SystemCustomerAttributeNames.LastContinueShoppingPage, _webHelper.GetThisPageUrl(false)); if (command.PageNumber <= 0) { command.PageNumber = 1; } var model = category.ToModel(); //sorting model.PagingFilteringContext.AllowProductSorting = _catalogSettings.AllowProductSorting; if (model.PagingFilteringContext.AllowProductSorting) { foreach (ProductSortingEnum enumValue in Enum.GetValues(typeof(ProductSortingEnum))) { var currentPageUrl = _webHelper.GetThisPageUrl(true); var sortUrl = _webHelper.ModifyQueryString(currentPageUrl, "orderby=" + ((int)enumValue).ToString(), null); var sortValue = enumValue.GetLocalizedEnum(_localizationService, _workContext); model.PagingFilteringContext.AvailableSortOptions.Add(new SelectListItem() { Text = sortValue, Value = sortUrl, Selected = enumValue == (ProductSortingEnum)command.OrderBy }); } } //view mode model.PagingFilteringContext.AllowProductViewModeChanging = _catalogSettings.AllowProductViewModeChanging; var viewMode = !string.IsNullOrEmpty(command.ViewMode) ? command.ViewMode : _catalogSettings.DefaultViewMode; if (model.PagingFilteringContext.AllowProductViewModeChanging) { var currentPageUrl = _webHelper.GetThisPageUrl(true); //grid model.PagingFilteringContext.AvailableViewModes.Add(new SelectListItem() { Text = _localizationService.GetResource("Categories.ViewMode.Grid"), Value = _webHelper.ModifyQueryString(currentPageUrl, "viewmode=grid", null), Selected = viewMode == "grid" }); //list model.PagingFilteringContext.AvailableViewModes.Add(new SelectListItem() { Text = _localizationService.GetResource("Categories.ViewMode.List"), Value = _webHelper.ModifyQueryString(currentPageUrl, "viewmode=list", null), Selected = viewMode == "list" }); } //page size model.PagingFilteringContext.AllowCustomersToSelectPageSize = false; if (category.AllowCustomersToSelectPageSize && category.PageSizeOptions != null) { var pageSizes = category.PageSizeOptions.Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries); if (pageSizes.Any()) { // get the first page size entry to use as the default (category page load) or if customer enters invalid value via query string if (command.PageSize <= 0 || !pageSizes.Contains(command.PageSize.ToString())) { int temp = 0; if (int.TryParse(pageSizes.FirstOrDefault(), out temp)) { if (temp > 0) { command.PageSize = temp; } } } var currentPageUrl = _webHelper.GetThisPageUrl(true); var sortUrl = _webHelper.ModifyQueryString(currentPageUrl, "pagesize={0}", null); sortUrl = _webHelper.RemoveQueryString(sortUrl, "pagenumber"); foreach (var pageSize in pageSizes) { int temp = 0; if (!int.TryParse(pageSize, out temp)) { continue; } if (temp <= 0) { continue; } model.PagingFilteringContext.PageSizeOptions.Add(new SelectListItem() { Text = pageSize, Value = String.Format(sortUrl, pageSize), Selected = pageSize.Equals(command.PageSize.ToString(), StringComparison.InvariantCultureIgnoreCase) }); } if (model.PagingFilteringContext.PageSizeOptions.Any()) { model.PagingFilteringContext.PageSizeOptions = model.PagingFilteringContext.PageSizeOptions.OrderBy(x => int.Parse(x.Text)).ToList(); model.PagingFilteringContext.AllowCustomersToSelectPageSize = true; if (command.PageSize <= 0) { command.PageSize = int.Parse(model.PagingFilteringContext.PageSizeOptions.FirstOrDefault().Text); } } } } else { //customer is not allowed to select a page size command.PageSize = category.PageSize; } if (command.PageSize <= 0) { command.PageSize = category.PageSize; } //price ranges model.PagingFilteringContext.PriceRangeFilter.LoadPriceRangeFilters(category.PriceRanges, _webHelper, _priceFormatter); var selectedPriceRange = model.PagingFilteringContext.PriceRangeFilter.GetSelectedPriceRange(_webHelper, category.PriceRanges); decimal?minPriceConverted = null; decimal?maxPriceConverted = null; if (selectedPriceRange != null) { if (selectedPriceRange.From.HasValue) { minPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.From.Value, _workContext.WorkingCurrency); } if (selectedPriceRange.To.HasValue) { maxPriceConverted = _currencyService.ConvertToPrimaryStoreCurrency(selectedPriceRange.To.Value, _workContext.WorkingCurrency); } } //category breadcrumb model.DisplayCategoryBreadcrumb = _catalogSettings.CategoryBreadcrumbEnabled; if (model.DisplayCategoryBreadcrumb) { foreach (var catBr in GetCategoryBreadCrumb(category)) { model.CategoryBreadcrumb.Add(new CategoryModel() { Id = catBr.Id, Name = catBr.GetLocalized(x => x.Name), SeName = catBr.GetSeName() }); } } //subcategories model.SubCategories = _categoryService .GetAllCategoriesByParentCategoryId(categoryId) .Select(x => { var subCatName = x.GetLocalized(y => y.Name); var subCatModel = new CategoryModel.SubCategoryModel() { Id = x.Id, Name = subCatName, SeName = x.GetSeName(), SubCategoryDescription = x.Description }; //prepare picture model int pictureSize = _mediaSettings.CategoryThumbPictureSize; var categoryPictureCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_PICTURE_MODEL_KEY, x.Id, pictureSize, true, _workContext.WorkingLanguage.Id, _webHelper.IsCurrentConnectionSecured()); subCatModel.PictureModel = _cacheManager.Get(categoryPictureCacheKey, () => { var pictureModel = new PictureModel() { FullSizeImageUrl = _pictureService.GetPictureUrl(x.PictureId), ImageUrl = _pictureService.GetPictureUrl(x.PictureId, pictureSize), Title = string.Format(_localizationService.GetResource("Media.Category.ImageLinkTitleFormat"), subCatName), AlternateText = string.Format(_localizationService.GetResource("Media.Category.ImageAlternateTextFormat"), subCatName) }; return(pictureModel); }); return(subCatModel); }) .ToList(); model.PagingFilteringContext.TotalItems = model.SubCategories.Count; // model.SubCategories = model.SubCategories.Skip(command.PageIndex * command.PageSize).Take(command.PageSize).ToList(); IPagedList <CategoryModel.SubCategoryModel> pagedCategories = new PagedList <CategoryModel.SubCategoryModel>(model.SubCategories, command.PageNumber - 1, command.PageSize); model.PagingFilteringContext.LoadPagedList(pagedCategories); model.SubCategories = model.SubCategories.Skip(command.PageIndex * command.PageSize).Take(command.PageSize).ToList(); if (model.SubCategories.Count == 0) { //featured products //Question: should we use '_catalogSettings.ShowProductsFromSubcategories' setting for displaying featured products? if (!_catalogSettings.IgnoreFeaturedProducts && _categoryService.GetTotalNumberOfFeaturedProducts(categoryId) > 0) { //We use the fast GetTotalNumberOfFeaturedProducts before invoking of the slow SearchProducts //to ensure that we have at least one featured product IList <int> filterableSpecificationAttributeOptionIdsFeatured = null; var featuredProducts = _productService.SearchProducts(category.Id, 0, true, null, null, 0, null, false, false, _workContext.WorkingLanguage.Id, null, ProductSortingEnum.Position, 0, int.MaxValue, false, out filterableSpecificationAttributeOptionIdsFeatured); model.FeaturedProducts = PrepareProductOverviewModels(featuredProducts).ToList(); } var categoryIds = new List <int>(); categoryIds.Add(category.Id); if (_catalogSettings.ShowProductsFromSubcategories) { //include subcategories categoryIds.AddRange(GetChildCategoryIds(category.Id)); } //products IList <int> alreadyFilteredSpecOptionIds = model.PagingFilteringContext.SpecificationFilter.GetAlreadyFilteredSpecOptionIds(_webHelper); IList <int> filterableSpecificationAttributeOptionIds = null; var products = _productService.SearchProducts(categoryIds, 0, _catalogSettings.IncludeFeaturedProductsInNormalLists ? null : (bool?)false, minPriceConverted, maxPriceConverted, 0, string.Empty, false, false, _workContext.WorkingLanguage.Id, alreadyFilteredSpecOptionIds, (ProductSortingEnum)command.OrderBy, command.PageNumber - 1, command.PageSize, true, out filterableSpecificationAttributeOptionIds); model.Products = PrepareProductOverviewModels(products).ToList(); model.PagingFilteringContext.LoadPagedList(products); model.PagingFilteringContext.ViewMode = viewMode; //specs model.PagingFilteringContext.SpecificationFilter.PrepareSpecsFilters(alreadyFilteredSpecOptionIds, filterableSpecificationAttributeOptionIds, _specificationAttributeService, _webHelper, _workContext); } //template var templateCacheKey = string.Format(ModelCacheEventConsumer.CATEGORY_TEMPLATE_MODEL_KEY, category.CategoryTemplateId); var templateViewPath = _cacheManager.Get(templateCacheKey, () => { var template = _categoryTemplateService.GetCategoryTemplateById(category.CategoryTemplateId); if (template == null) { template = _categoryTemplateService.GetAllCategoryTemplates().FirstOrDefault(); } return(template.ViewPath); }); //activity log _customerActivityService.InsertActivity("PublicStore.ViewCategory", _localizationService.GetResource("ActivityLog.PublicStore.ViewCategory"), category.Name); return(View(templateViewPath, model)); }