Ejemplo n.º 1
0
        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));
        }
Ejemplo n.º 2
0
        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;
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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));
        }
Ejemplo n.º 5
0
        /// <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));
        }